多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
>[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('&amp;', '&', $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 的配置文件里配置项...