>[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 的配置文件里配置项...