>[info] 請記得熟悉下 增量包和項目的目錄,以免替換 文件/代碼 錯誤。替換文件比較簡單,此步驟不做贅述。
>[danger] 請仔細核對 IM 需要的代碼 區域 ,除非你有十足的把握,我們講解是根據 增量包的 目錄結構 `由上而下逐級、由外到內逐層` 解剖,所以再次強調,你要對目錄結構足夠熟悉,別笑,理解的人也是從不理解開始的...
### 邏輯層
為了安全起見,shop的用戶信息需要通過COOKIE傳輸至IM,所以要解決 跨域 存儲cookie 【實則同一個主域名下】
即目的:登錄存儲cookie,退出清除cookie
$_COOKIE['yuanfeng_im_username']
$_COOKIE['yuanfeng_im_seller']
>[success] `模型層` 目錄文件 shop>shop>models>Perm.php
##### line:29
/**
* 初始化登錄的用戶信息cookie
*
* @access public
*
* @return Array $user_row;
*/
public static function getUserByCookie()
{
$user_key = null;
$user_row_default = [];
if (array_key_exists(self::$cookieId, $_COOKIE)) {
$id = $_COOKIE[self::$cookieId];
//獲取用戶信息
//改成文本存儲, 不連接數據庫
$userModel = new User_BaseModel();
$user_rows = $userModel->getBase($id);
$user_row_default = array_pop($user_rows);
if ($user_row_default) {
$user_key = $user_row_default['user_key'];
}
}
//設置當前用戶的Key
Yf_Hash::setKey($user_key);
$user_row = [];
if (array_key_exists(self::$cookieName, $_COOKIE)) {
$encrypt_str = $_COOKIE[self::$cookieName];
$user_row = self::decryptUserInfo($encrypt_str);
if ($user_key && @$user_row['user_id'] == $user_row_default['user_id']) {
Perm::$row = $user_row_default;
}
}
$user_id = $id ? :$user_row['user_id'];
$userBaseModel = new User_BaseModel();
$user_data = $userBaseModel->getOne($user_id);
$user_name = $_COOKIE['user_account'] ? :$user_data['user_account'];
// 刷新頁面 也要有些動作
Perm::addOrRemoveImCookie(true, time() + 86400 * 365, $user_name, @$user_row['shop_id']);
return $user_row;
}
##### line:69
/**
* 用戶數組信息編碼成字符串, 設置cookie
*
* @param array $user_row 用戶信息
*
* @access public
*
* @return string $encrypt_str;
*/
public static function encryptUserInfo($user_row = null, $user_key = null)
{
$user_name = $user_row['user_account'];
//user_account 這個COOKIE IM是需要的。by sunkang
if ($user_row['user_account']) {
setcookie('user_account', $user_row['user_account']);
//解決cookie第一次生成,取不到的問題。
$_COOKIE['user_account'] = $user_row['user_account'];
unset($user_row['user_account']);
}
$user_str = http_build_query($user_row);
$user_str = str_replace('&', '&', $user_str);
if ($user_key) {
Yf_Hash::setKey($user_key);
}
$encrypt_str = Yf_Hash::encrypt($user_str);
$expires = time() + 86400*365*10;
setcookie(self::$cookieName, $encrypt_str);
setcookie(self::$cookieId, $user_row['user_id']);
$_COOKIE[self::$cookieName] = $encrypt_str;
$_COOKIE[self::$cookieId] = $user_row['user_id'];
//im cookie、shop_id
self::addOrRemoveImCookie(true,$expires,$user_name,$user_row['shop_id']);
return $encrypt_str;
}
##### line:112
/**
* IM的COOKIE
*
* @dateTime 2018-08-13
* @author Sun
* @link https://github.com/mustify
* @copyright https://www.yuanfeng.cn
* @license 僅限本公司授權用戶使用。
*/
public static function addOrRemoveImCookie($add = TRUE,$expires = 0,$user_name = null,$shop_id = null){
//沒有開啟IM,是不需要走這里的。
if(!Yf_Registry::get('im_statu')){
return false;
}
/**
* 向IM寫COOKIE
*
* @var [type]
*/
$domain = Yf_Registry::get('im_url');
$domain = str_replace('http://', '', $domain);
$domain = str_replace('https://', '', $domain);
$domain = substr($domain,strpos($domain,'.')+1);
if(strpos($domain,'/')!==false){
$domain = substr($domain,0,strpos($domain,'/'));
}
if($add == true){
setcookie('yuanfeng_im_username', $user_name, $expires, '/', $domain);
$_COOKIE['yuanfeng_im_username'] = $user_name;
if($shop_id){
setcookie('yuanfeng_im_seller', $shop_id, $expires, '/', $domain);
$_COOKIE['yuanfeng_im_seller'] = $shop_id;
}
}else{
setcookie('yuanfeng_im_username', NULL, -100, '/', $domain);
setcookie('yuanfeng_im_seller', NULL, -100, '/', $domain);
}
usleep(300);
}
##### line:153
/**
* 用戶logout
*
* @access public
*
* @return bool true/false;
*/
public static function removeUserInfo()
{
$expires = time() - 3600;
setcookie(self::$cookieName, null, $expires);
setcookie(self::$cookieId, null, $expires);
//退出
self::addOrRemoveImCookie(false);
return true;
}
>[success] `控制層` 目錄文件 shop>shop>controllers>LoginCtl.php
##### line:946
/*
* 用戶退出
* IM
*
*/
public function loginout()
{
if ($_REQUEST['met'] == 'loginout')
{
if (isset($_COOKIE['key']) || isset($_COOKIE['id'])) {
echo "<script>parent.location.href='index.php';</script>";
setcookie("key", null, time() - 3600 * 24 * 365);
setcookie("id", null, time() - 3600 * 24 * 365);
setcookie("user_account", null, time() - 3600 * 24 * 365);
setcookie("key", null, time() - 3600 * 24 * 365,'/');
setcookie("id", null, time() - 3600 * 24 * 365,'/');
setcookie("user_account", null, time() - 3600 * 24 * 365,'/');
Perm::removeUserInfo();
}
$login_url = Yf_Registry::get('ucenter_api_url') . '?ctl=Login&met=logout&typ=e';
$callback = Yf_Registry::get('url') . '?redirect=' . urlencode(Yf_Registry::get('url')) . '&type=ucenter';
$login_url = $login_url . '&from=shop&callback=' . urlencode($callback);
header('location:' . $login_url);
exit();
}
}
至此,所有的業務邏輯層,你已經完成,是不是很簡單?
加油,把視圖層修修改改,你就可以完全體驗IM了~
### 視圖層
你打開這個目錄的時候,看見的就是這 5個 php文件,對的,我們來個 三元歸一 大法,在一處修改即可,
你會發現有一個文件在你的項目目錄里并不存在,即`yf_im_config.php`.
這個文件,你可以毫無顧慮的復制粘貼到 shop>shop>views>default 根目錄下即可
>[success]目錄文件:shop>shop>views>default>buyer_footer.php [買家中心底部文件]
##### line:43
刪除:
<iframe id='imbuiler' scrolling="no" frameborder="0" class="im-show" src=''></iframe>
添加:
<?php include $this->view->getTplPath() . '/' . 'yf_im_config.php'; ?>
>[success]目錄文件:shop>shop>views>default>chain_footer.php [供應商管理底部文件]
##### line:57
添加:
<?php include $this->view->getTplPath() . '/' . 'yf_im_config.php'; ?>
>[success]目錄文件:shop>shop>views>default>footer.php [首頁底部文件]
##### line:68
刪除:
<iframe id='imbuiler' scrolling="no" frameborder="0" class="im-show" src=''></iframe>
添加:
<?php include $this->view->getTplPath() . '/' . 'yf_im_config.php'; ?>
>[success]目錄文件:shop>shop>views>default>seller_footer.php [賣家中心底部文件]
##### line:61
刪除:
<?php if(Yf_Registry::get('im_statu')){ ?>
<iframe id='imbuiler' scrolling="no" frameborder="0" class="im-show" src='<?=Yf_Registry::get('base_url').'/im/index.php'?>'></iframe>
<?php } ?>
<script type="text/javascript" src="<?= $this->view->js ?>/im.js"></script>
添加:
<?php include $this->view->getTplPath() . '/' . 'yf_im_config.php'; ?>
>[success] 目錄文件:shop>shop>views>default>Goods>GoodsCtl>goods.php [商品詳情文件]
##### line:656
給a標簽追加一個 class `yf_chat` 即可
<?php if (Web_ConfigModel::value('im_statu') && Yf_Registry::get('im_statu')) { ?>
<a href="javascript:;" class="chat-enter yf_chat" rel="<?= $shop_detail['shop_self_support'] == 'true' && Web_ConfigModel::value('self_shop_im') ? Web_ConfigModel::value('self_shop_im') : $shop_detail['user_name']; ?>">
<i class="iconfont icon-btncomment"></i>
</a>
<?php } ?>
>[success] 目錄文件:shop>shop>views>default>IndexCtl>toolbar.php
##### line:308
給div標簽追加一個class `yf_im_icon` 即可
<?php if (Web_ConfigModel::value('im_statu') && Yf_Registry::get('im_statu')) { ?>
<div class="tbar-tab-online-contact yf_im_icon">
<i class="tab-ico iconfont icon-logo_im nav_icon"></i>
<em class="tab-text"><?= __('在線聯系') ?></em>
<span class="tab-sub J-count hide"></span>
</div>
<?php } ?>
刪除:
//im
if(IM_STATU == 1){
$.get(SITE_URL+'/index.php?ctl=Api_IM_Im&met=index',function(h){
$('#imbuiler').attr('src',h);
im_builder_ch();
iconbtncomment();
});
getUserAccount();
}
function getUserAccount(){
$.ajax({
type: "GET",
url: SITE_URL + "?ctl=Index&met=getUserLoginInfo&typ=json",
data: {},
dataType: "json",
success: function(data){
if(data.data.status == 200 && typeof data.data.user_account != 'undefined'){
var user_account_log = data.data.user_account;
if(getCookie('user_account') == null || getCookie('user_account') != user_account_log){
delCookie('user_account');
addCookie('user_account',user_account_log,24*365*10);
}
}
}
});
}
function iconbtncomment(){
$('.icon-btncomment').click(function(){
if(!getCookie('user_account') || getCookie('user_account') == 'undefined'){
$("#login_content").show();
load_goodseval(SITE_URL + '?ctl=Index&met=fastLogin','login_content');
}
var ch_u = $('.chat-enter').attr('rel');
if(ch_u == getCookie('user_account')){
alert_box('不能跟自己聊天');
return ;
}
var inner = $('#imbuiler')[0].contentWindow;
$('#imbuiler').show();
//查看聊天右側的用戶列表有沒有,沒有就點一下最下面的就出來了。
var dis = $('#imbuiler').contents().find('.chat-list').css('display');
if(dis!='block'){
$('#imbuiler').contents().find('.bottom-bar a').click();
}
inner.chat(ch_u);
$('#imbuiler')[0].contentWindow.bottom_bar();
return false;
});
}
function im_builder_ch(){
var onl = $(".tbar-tab-online-contact");
onl.show();
onl.click(function(){
if(!getCookie('user_account') || getCookie('user_account') == 'undefined'){
getUserAccount();
$("#login_content").show();
load_goodseval(SITE_URL + '?ctl=Index&met=fastLogin','login_content');
return;
}
else
{
$('#imbuiler').show();
$('#imbuiler')[0].contentWindow.bottom_bar();
$('#imbuiler').contents().find('.bottom-bar a').click();
return;
}
});
}
替換為:
/*IM icon控制顯示的方法*/
function im_show() {
if ($(".yf_im_icon").html()) {
var onl = $(".tbar-tab-online-contact");
onl.show();
}
}
im_show();
/*加載 快捷登錄的彈框內容 */
function load_page(url, div) {
$("#" + div).load(url, function (html) {
$(this).html(html).show();
return false;
});
}
添加:
<!-- 側邊快捷工具欄 不緩存cookie,可以使用 php 取cookie START-->
<?php if (!$_COOKIE['user_account']) { ?>
<script type="text/javascript">
$(function () {
$(".tbar-tab-online-contact,.icon-btncomment").click(function () {
// console.log("click chat");
if (getCookie("user_account")) {
window.location.reload();
return false;
}
load_page(SITE_URL + "?ctl=Index&met=fastLogin", "login_content");
return false;
});
});
</script>
<?php } ?>
<!-- 側邊快捷工具欄 不緩存cookie,可以使用 php 取cookie END-->
至此,還有最后一個文件了~·~有沒有看到IM正在向你招手,這也是商家配置客服的關鍵文件,請往下看:
>[success] 目錄文件: shop>shop>views>default>Seller>Supplier>SupplierCtl>index.php
##### line:6
刪除:
<script type="text/javascript">
var IM_URL = "<?=Yf_Registry::get('im_api_url')?>";
var IM_STATU = "<?=Yf_Registry::get('im_statu')?>";
</script>
<?php if(Web_ConfigModel::value('im_statu')==1 ){?>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/chat.js"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/chat/user.js"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/ytx-web-im-min-new.js"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/jquery.ui.js"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/perfect-scrollbar.min.js"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/jquery.mousewheel.js"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/jquery.charCount.js" charset="utf-8"></script>
<script type="text/javascript" src="<?= $this->view->js ?>/im_pc/emoji.js" charset="utf-8"></script>
<?php }?>
<div id="chat"></div>
>[success] 目錄文件:shop>shop>controllers>Supplier>IndexCtl.php
>[success] 目錄文件:shop>shop>controllers>IndexCtl.php
刪除chat()方法:
public function chat()
{
$this->initData();
if (Perm::checkUserPerm()) {
$user_name = Perm::$row['user_account'];
include $this->view->getView();
}
}
>[success] 目錄文件:shop>shop>static>default>js>common.js
刪除:
function chat(ch_u){
if(ch_u == getCookie('user_account')){
alert_box('不能跟自己聊天');
return ;
}
var inner = $('#imbuiler')[0].contentWindow;
inner.bottom_bar();
$('#imbuiler').show();
//查看聊天右側的用戶列表有沒有,沒有就點一下最下面的就出來了。
var dis = $('#imbuiler').contents().find('.chat-list').css('display');
if(dis!='block'){
$('#imbuiler').contents().find('.bottom-bar a').click();
}
inner.chat(ch_u);
}
//用戶登錄 - 加載聊天窗口
if(typeof(IM_STATU)!=='undefined' && IM_STATU==1 && data.data[3]) {
$.ajax({
type: "GET",
url: "index.php?ctl=Im&met=im&typ=json",
data: {},
dataType: "json",
success: function(data) {
console.info(data);
if (data.status == 200) {
window.im_appId = data.data.im_appId;
window.im_appToken = data.data.im_appToken;
url = 'index.php?ctl=Index&met=chat';
$("#chat").load(url, function(){});
}
}
});
}
>[success]目錄文件:shop>shop>static>default>js>supplier_index.js
刪除:
//用戶登錄 - 加載聊天窗口
if(typeof(IM_STATU)!=='undefined' && IM_STATU==1) {
url = 'index.php?ctl=Index&met=chat';
$("#chat").load(url, function(){});
}
>[success] 目錄文件:shop>shop>views>default>Seller>MessageCtl>index.php
##### line:14
在form表單域內添加:
<!-- YF_IM 設置客服入口 shop的布局,layui的樣式,IM的接口START -->
<dl>
<dt><?= __('IM客服:'); ?></dt>
<dd>
<a class="layui-btn layui-btn-warm" id="setkefu"><?= __('前往設置'); ?></a>
<a class="layui-btn" href="<?= Yf_Registry::get('im_url') ?>/kefu" target="_blank"><?= __('客服登錄'); ?></a>
</dd>
</dl>
<!-- YF_IM 設置客服入口 END -->
刪除:三處
倆處:
<option <?php if($val['tool'] == 3){?>selected="selected"<?php }?> value="3">IM</option>
一處:
<?php if(Yf_Registry::get('im_statu') ==1){?><option value="3">IM</option><?php }?>
好了,整個shop的代碼嵌入工作 都被你操作完成了
~是不是很簡單?~
你以為就可以點擊 icon 來體驗IM了嗎?
并不是這樣的,請繼續操作 shop_admin 的配置文件里配置項...