System.php 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  1. <?php
  2. namespace app\admin\controller;
  3. use app\admin\model\Office;
  4. use think\cache\driver\Redis;
  5. /**
  6. * 管理系统系统设置类
  7. */
  8. class System extends Base
  9. {
  10. /**
  11. * 基础设置
  12. *
  13. * @access public
  14. */
  15. public function basics()
  16. {
  17. $settings = db('settings')->find();
  18. // 表单提交.
  19. if (request()->isPost()) {
  20. $param = input('post.');
  21. try {
  22. // 修改系统欢迎语.
  23. if (empty($param['advertisement_img']) === false) {
  24. $updateAstData['advertisement_img'] = $param['advertisement_img'];
  25. }
  26. if (empty($param['logo_img']) === false) {
  27. $updateinfo['logo'] = $param['logo_img'];
  28. }
  29. $updateinfo['enterprise_name'] = $param['enterprise_name'];
  30. $updateinfo['visitor_url'] = $param['visitor_url'];
  31. $updateinfo['customer_url'] = $param['customer_url'];
  32. $updateinfo['backend_url'] = $param['backend_url'];
  33. $updateAstData['advertisement_url'] = $param['advertisementUrl'];
  34. $updateAstData['advertisement_status'] = $param['status'];
  35. model('Advertisement')->updateAst($updateAstData);
  36. /*// 修改系统欢迎语.
  37. $updateSysData['word'] = $param['systemWord'];
  38. $updateSysWhere['id'] = 1;
  39. model('Reply')->updateReply($updateSysWhere, $updateSysData);*/
  40. // 修改客服欢迎语.
  41. $updateSevData['word'] = $param['serverWord'];
  42. $updateSevWhere['id'] = 2;
  43. model('Reply')->updateReply($updateSevWhere, $updateSevData);
  44. if(!empty($updateinfo)){
  45. db('settings')->where('id',1)->update($updateinfo);
  46. $err=$this->updateJsTmpl($updateinfo);
  47. if($err==-20003){
  48. return json(['code' => -2, 'data' => '', 'msg' => 'JS调用模板路径不可以写']);
  49. }
  50. }
  51. return json(['code' => 1, 'data' => '', 'msg' => '设置成功']);
  52. } catch (\Exception $e) {
  53. return json(['code' => -2, 'data' => '', 'msg' => $e->getMessage()]);
  54. }//end try
  55. }//end if
  56. // 获取广告.
  57. $advertisement = model('Advertisement')->findAst();
  58. /*// 获取系统欢迎语.
  59. $replySystemWhere['id'] = 1;
  60. $replySystem = model('Reply')->findReply($replySystemWhere);*/
  61. // 获取客服欢迎语.
  62. $replyServerWhere['id'] = 2;
  63. $replyServer = model('Reply')->findReply($replyServerWhere);
  64. // 获取logo.
  65. $this->assign(
  66. [
  67. 'advertisement' => $advertisement,
  68. //'replySystem' => $replySystem,
  69. 'replyServer' => $replyServer,
  70. 'settings' => $settings,
  71. 'socket' => config('socket'),
  72. 'status' => config('kf_status'),
  73. ]
  74. );
  75. return $this->fetch();
  76. }//end basics()
  77. public function updateJsTmpl($settings){
  78. $src=ROOT_PATH.'public/entranceJs/jstmpl.js';
  79. $tar=ROOT_PATH.'public/entranceJs/FloatingButton.js';
  80. if(is_readable($src)){
  81. $content=file_get_contents($src);
  82. $content=str_replace('{VISITOR_DOMAIN}',$settings['visitor_url'],$content);
  83. $content=str_replace('{CUSTOMER_DOMAIN}',$settings['customer_url'],$content);
  84. $content=str_replace('{ADMIN_DOMAIN}',$settings['backend_url'],$content);
  85. file_put_contents($tar,$content);
  86. }else{
  87. return -20003;
  88. }
  89. }
  90. /**
  91. * 系统欢迎语
  92. *
  93. * @access public
  94. */
  95. public function welcoming()
  96. {
  97. if (request()->isAjax()) {
  98. $replySystemWhere['type'] = 1;
  99. $result = model('Reply')->selectReply($replySystemWhere);
  100. foreach($result as $key=>$vo){
  101. // 生成操作按钮
  102. $result[$key]['operate'] = $this->makeBotton($vo['id']);
  103. $result[$key]['word'] = htmlspecialchars_decode($vo['word']);
  104. }
  105. $return['rows'] = $result;
  106. return json($return);
  107. }
  108. $this->assign([
  109. 'socket' => config('socket'),
  110. ]);
  111. return $this->fetch();
  112. }//end welcoming()
  113. /**
  114. * 修改系统欢迎语
  115. *
  116. * @access public
  117. */
  118. public function editWelcome()
  119. {
  120. if(request()->isAjax()){
  121. $param = input('post.');
  122. $where['id'] = $param['id'];
  123. $data['sort'] = $param['sort'];
  124. $data['word'] = htmlspecialchars($param['word']);
  125. try{
  126. model('Reply')->updateReply($where, $data);
  127. }catch(\Exception $e){
  128. return json(['code' => -2, 'data' => '', 'msg' => $e->getMessage()]);
  129. }
  130. return json(['code' => 1, 'data' => '', 'msg' => '编辑成功']);
  131. }
  132. $id = input('param.id');
  133. $replySystemWhere['id'] = $id;
  134. $replySystem = model('Reply')->findReply($replySystemWhere);
  135. $this->assign([
  136. 'replySystem' => $replySystem,
  137. 'socket' => config('socket'),
  138. ]);
  139. return $this->fetch('editwelcome');
  140. }//end editWelcome()
  141. /**
  142. * 新增系统欢迎语
  143. *
  144. * @access public
  145. */
  146. public function delWelcome()
  147. {
  148. if (request()->isAjax()) {
  149. $id = input('param.id');
  150. $where['id'] = $id;
  151. try {
  152. model('Reply')->delReply($where);
  153. } catch (\Exception $e) {
  154. return json(['code' => -1, 'data' => '', 'msg' => $e->getMessage()]);
  155. }
  156. return json(['code' => 1, 'data' => '', 'msg' => '删除成功']);
  157. }
  158. }
  159. /**
  160. * 新增系统欢迎语
  161. *
  162. * @access public
  163. */
  164. public function addWelcome()
  165. {
  166. if(request()->isAjax()){
  167. $param = input('post.');
  168. $data['sort'] = $param['sort'];
  169. $data['word'] = htmlspecialchars($param['word']);
  170. $data['status'] = 1;
  171. $data['type'] = 1;
  172. try{
  173. model('Reply')->addReply($data);
  174. }catch(\Exception $e){
  175. return json(['code' => -2, 'data' => '', 'msg' => $e->getMessage()]);
  176. }
  177. return json(['code' => 1, 'data' => '', 'msg' => '新增成功']);
  178. }
  179. $this->assign([
  180. 'socket' => config('socket'),
  181. ]);
  182. return $this->fetch('addwelcome');
  183. }//end addWelcome()
  184. /**
  185. * 会话设置
  186. *
  187. * @access public
  188. */
  189. public function conversation()
  190. {
  191. // 表单提交.
  192. if (request()->isPost()) {
  193. $param = input('post.');
  194. try {
  195. // 修改会话超时.
  196. $updateOvertimeData['systemconfig_data'] = $param['overtime'];
  197. $updateOvertimeData['systemconfig_content'] = $param['overtimeInfo'];
  198. $updateOvertimeWhere['systemconfig_id'] = 1;
  199. model('Systemconfig')->updateSystemconfig($updateOvertimeWhere, $updateOvertimeData);
  200. // 修改访客静默.
  201. $upUptdData['systemconfig_data'] = $param['unoperated'];
  202. $upUptdData['systemconfig_content'] = $param['unoperatedInfo'];
  203. $upUptdWhere['systemconfig_id'] = 2;
  204. model('Systemconfig')->updateSystemconfig($upUptdWhere, $upUptdData);
  205. // 质检会话时长设置.
  206. $upAllTimeData['systemconfig_data'] = $param['verifyAllTime'];
  207. $upAllTimeWhere['systemconfig_id'] = 3;
  208. model('Systemconfig')->updateSystemconfig($upAllTimeWhere, $upAllTimeData);
  209. // 质检会话响应时长设置.
  210. $upReturnTimeData['systemconfig_data'] = $param['verifyReturnTime'];
  211. $upReturnTimeWhere['systemconfig_id'] = 4;
  212. model('Systemconfig')->updateSystemconfig($upReturnTimeWhere, $upReturnTimeData);
  213. // 满意度评价回合限制.
  214. $upRoundData['systemconfig_data'] = $param['round'];
  215. $upRoundWhere['systemconfig_id'] = 5;
  216. model('Systemconfig')->updateSystemconfig($upRoundWhere, $upRoundData);
  217. // 客服接待人数设置.
  218. $upMSWhere['systemconfig_enName'] = 'KFMaxServices';
  219. $upMSData['systemconfig_data'] = $param['max_service'];
  220. model('Systemconfig')->updateSystemconfig($upMSWhere, $upMSData);
  221. // 最大排队人数设置.
  222. $upMWWhere['systemconfig_enName'] = 'maxWait';
  223. $upMWData['systemconfig_data'] = $param['kfConfig_maxWait'];
  224. model('Systemconfig')->updateSystemconfig($upMWWhere, $upMWData);
  225. return json(['code' => 1, 'data' => '', 'msg' => '设置成功']);
  226. } catch (\Exception $e) {
  227. return json(['code' => -2, 'data' => '', 'msg' => $e->getMessage()]);
  228. }//end try
  229. }//end if
  230. // 获取设置.
  231. $systemconfig = model('Systemconfig')->selectSystemconfig();
  232. $this->assign(
  233. [
  234. 'systemconfig' => $systemconfig,
  235. 'status' => config('kf_status'),
  236. 'socket' => config('socket'),
  237. ]
  238. );
  239. return $this->fetch();
  240. }//end conversation()
  241. // 自动回复设置
  242. public function reply()
  243. {
  244. if(request()->isPost()){
  245. $param = input('post.');
  246. if(empty($param['word'])){
  247. return json(['code' => -1, 'data' => '', 'msg' => '回复内容不能为空']);
  248. }
  249. try{
  250. db('reply')->where('id', 1)->update($param);
  251. }catch(\Exception $e){
  252. return json(['code' => -2, 'data' => '', 'msg' => $e->getMessage()]);
  253. }
  254. return json(['code' => 1, 'data' => '', 'msg' => '设置成功']);
  255. }
  256. $info = db('reply')->where('id', 1)->find();
  257. $this->assign([
  258. 'info' => $info,
  259. 'socket' => config('socket'),
  260. 'status' => config('kf_status')
  261. ]);
  262. return $this->fetch();
  263. }
  264. // 历史会话记录
  265. public function wordsLog()
  266. {
  267. // $toExcel = input('param.toExcel', 0);
  268. if(request()->isAjax()){
  269. $param = input('param.');
  270. $limit = $param['pageSize'];
  271. $offset = ($param['pageNumber'] - 1) * $limit;
  272. // 默认显示最近7天
  273. $start = input('param.start');
  274. $end = input('param.end');
  275. $user_id = input('param.user_id');
  276. $group_id = input('param.group_id');
  277. $temp = db('service_log');
  278. $countTmp = db('service_log');
  279. if(strlen($param['searchText'])){
  280. $temp = $temp->whereLike('user_name', '%'.$param['searchText'].'%');
  281. $countTmp = $countTmp->whereLike('user_name', '%'.$param['searchText'].'%');
  282. }
  283. //日期
  284. if(!empty($start) && !empty($end) && $start <= $end){
  285. $temp = $temp->whereBetween('start_time', [strtotime($start), strtotime($end . ' 23:59:59')]);
  286. $countTmp = $countTmp->whereBetween('start_time', [strtotime($start), strtotime($end . ' 23:59:59')]);
  287. }
  288. //结束时间为空
  289. if(!empty($start) && empty($end)){
  290. $temp = $temp->where('start_time','>',strtotime($start));
  291. $countTmp = $countTmp->where('start_time','>',strtotime($start));
  292. }
  293. //开始时间为空
  294. if(empty($start) && !empty($end)){
  295. $temp = $temp->where('start_time','<',strtotime($end . ' 23:59:59'));
  296. $countTmp = $countTmp->where('start_time','<',strtotime($end . ' 23:59:59'));
  297. }
  298. //客服
  299. if($user_id != 0){
  300. $temp = $temp->where('kf_id', $user_id);
  301. $countTmp = $countTmp->where('kf_id', $user_id);
  302. }
  303. //客服组
  304. if($group_id != 0){
  305. $temp = $temp->where('group_id', $group_id);
  306. $countTmp = $countTmp->where('group_id', $group_id);
  307. }
  308. $result = $temp->limit($offset, $limit)->order('start_time', 'desc')->select();
  309. //所有客服
  310. $users = db('users')->select();
  311. //所有客服组
  312. $groups = db('groups')->select();
  313. //满意度
  314. $evaluate = db('evaluate')->select();
  315. //$alarm报警信息
  316. $alarm = db('alarm')->select();
  317. foreach($result as $key=>$vo){
  318. if($result[$key]['intime'] != 0){
  319. $result[$key]['intime'] = date('Y-m-d H:i:s', $vo['intime']);
  320. $date = explode(' ',$result[$key]['intime']);
  321. $year = explode('-',$result[$key]['intime']);
  322. if($date[0] == date('Y-m-d',time())){
  323. $result[$key]['intime'] = '<span style="float: right;">'.$date[1].'</span>';
  324. }else if($date[0] == date('Y-m-d',strtotime("-1 day"))){
  325. $result[$key]['intime'] = '<span style="float: right;">'.'昨天 '.$date[1].'</span>';
  326. }else{
  327. if($year[0] == date('Y',time())){
  328. $result[$key]['intime'] = '<span style="float: right;">'.date('m-d H:i:s',strtotime($result[$key]['intime'])).'</span>';
  329. }
  330. }
  331. }else{
  332. $result[$key]['intime'] = '-';
  333. }
  334. if($result[$key]['start_time'] != 0){
  335. $result[$key]['start_time'] = date('Y-m-d H:i:s', $vo['start_time']);
  336. $date = explode(' ',$result[$key]['start_time']);
  337. $year = explode('-',$result[$key]['start_time']);
  338. if($date[0] == date('Y-m-d',time())){
  339. $result[$key]['start_time'] = '<span style="float: right;">'.$date[1].'</span>';
  340. }else if($date[0] == date('Y-m-d',strtotime("-1 day"))){
  341. $result[$key]['start_time'] = '<span style="float: right;">'.'昨天 '.$date[1].'</span>';
  342. }else{
  343. if($year[0] == date('Y',time())){
  344. $result[$key]['start_time'] = '<span style="float: right;">'.date('m-d H:i:s',strtotime($result[$key]['start_time'])).'</span>';
  345. }
  346. }
  347. }else{
  348. $result[$key]['start_time'] = '-';
  349. }
  350. if($result[$key]['end_time'] != 0){
  351. $result[$key]['end_time'] = date('Y-m-d H:i:s', $vo['end_time']);
  352. $date = explode(' ',$result[$key]['end_time']);
  353. $year = explode('-',$result[$key]['end_time']);
  354. if($date[0] == date('Y-m-d',time())){
  355. $result[$key]['end_time'] = '<span style="float: right;">'.$date[1].'</span>';
  356. }else if($date[0] == date('Y-m-d',strtotime("-1 day"))){
  357. $result[$key]['end_time'] = '<span style="float: right;">'.'昨天 '.$date[1].'</span>';
  358. }else{
  359. if($year[0] == date('Y',time())){
  360. $result[$key]['end_time'] = '<span style="float: right;">'.date('m-d H:i:s',strtotime($result[$key]['end_time'])).'</span>';
  361. }
  362. }
  363. }else{
  364. $result[$key]['end_time'] = '-';
  365. }
  366. //客服名称
  367. for($i=0;$i<count($users);$i++){
  368. if($result[$key]['kf_id'] == $users[$i]['id']){
  369. $result[$key]['kefu_name'] = $users[$i]['user_name'];
  370. }
  371. }
  372. //满意度
  373. for($j=0;$j<count($evaluate);$j++){
  374. if($result[$key]['evaluate_id'] == $evaluate[$j]['evaluate_id']){
  375. $result[$key]['evaluate_name'] = $evaluate[$j]['evaluate_name'];
  376. }
  377. }
  378. //客服所在组
  379. for($a=0;$a<count($groups);$a++){
  380. if($result[$key]['group_id'] == $groups[$a]['id']){
  381. $result[$key]['group_name'] = $groups[$a]['name'];
  382. }
  383. }
  384. //会话时长/响应时长
  385. for($b=0;$b<count($alarm);$b++){
  386. if($result[$key]['servicelog_id'] == $alarm[$b]['servicelog_id']){
  387. //会话时长
  388. $conversation_min = intval($alarm[$b]['alarm_cvtOvertime']/60);
  389. $conversation_s = $alarm[$b]['alarm_cvtOvertime']%60;
  390. $result[$key]['conversation'] = $conversation_min.'分'.$conversation_s.'秒';
  391. //响应时长
  392. $response_min = intval($alarm[$b]['alarm_corresponding']/60);
  393. $response_s = $alarm[$b]['alarm_corresponding']%60;
  394. $result[$key]['response'] = $response_min.'分'.$response_s.'秒';
  395. }
  396. }
  397. if($vo['servicelog_close_type'] == 0){
  398. $result[$key]['servicelog_close_type'] = '未知';
  399. }
  400. if($vo['servicelog_close_type'] == 1){
  401. $result[$key]['servicelog_close_type'] = '无效会话';
  402. }
  403. if($vo['servicelog_close_type'] == 2){
  404. $result[$key]['servicelog_close_type'] = '双方静默';
  405. }
  406. if($vo['servicelog_close_type'] == 3){
  407. $result[$key]['servicelog_close_type'] = '客服关闭';
  408. }
  409. if($vo['servicelog_close_type'] == 4){
  410. $result[$key]['servicelog_close_type'] = '客服掉线';
  411. }
  412. if($vo['servicelog_close_type'] == 5){
  413. $result[$key]['servicelog_close_type'] = '转出';
  414. }
  415. if($vo['servicelog_close_type'] == 6){
  416. $result[$key]['servicelog_close_type'] = '用户关闭';
  417. }
  418. // 生成操作按钮
  419. if(0 != $vo['servicelog_id']){
  420. $result[$key]['operate'] = $this->makeBtn($vo['servicelog_id']);
  421. }
  422. }
  423. $return['total'] = $countTmp->count(); //总数据
  424. $return['rows'] = $result;
  425. // if (!$toExcel) {
  426. // return json($return);
  427. // } else {
  428. // $head = ['工单id', '访客进线时间', '接待客服', '所在组', '访客账号', '开始时间', '结束时间', '会话时长', '响应时长', '关闭原因', '满意度'];
  429. // $key = ['servicelog_id', 'intime', 'kefu_name', 'group_name', 'user_name', 'start_time', 'end_time', 'conversation', 'response', 'servicelog_close_type', 'evaluate_name'];
  430. // (new Office())->outdata('工作报表数据导出', $result, $head, $key);
  431. // return true;
  432. // }
  433. return json($return);
  434. }
  435. //所有客服
  436. $users = db('users')->select();
  437. $useroption = '';
  438. if(!empty($users)){
  439. $option = '<option value="0">全部客服</option>';
  440. for($i=0;$i<count($users);$i++){
  441. $option = $option.'<option value="'.$users[$i]['id'].'">'.$users[$i]['user_name'].'</option>';
  442. }
  443. $useroption = '<select class="selector_user" lay-verify="required" lay-filter="user_id" style="height: 30px;">'.$option.'</select>';
  444. }
  445. //所有客服组
  446. $groups = db('groups')->select();
  447. $groupoption = '';
  448. if(!empty($groups)){
  449. $option = '<option value="0">全部客服组</option>';
  450. for($j=0;$j<count($groups);$j++){
  451. $option = $option.'<option value="'.$groups[$j]['id'].'">'.$groups[$j]['name'].'</option>';
  452. }
  453. $groupoption = '<select class="selector_group" lay-verify="required" lay-filter="group_id" style="height: 30px;">'.$option.'</select>';
  454. }
  455. $this->assign([
  456. 'useroption' => $useroption,
  457. 'groupoption' => $groupoption
  458. ]);
  459. return $this->fetch('wordslog');
  460. }
  461. function matching($str, $a, $b)
  462. {
  463. $pattern = '/('.$a.')(.*)(?)('.$b.')/'; //正则规则匹配支付串中任何一个位置字符串
  464. //$pattern = '/(#\[)(.*)(?)(\]\/)/';
  465. preg_match_all($pattern,$str,$m);
  466. //preg_match_all($pattern, $str, $m); //返回一个匹配结果
  467. //print_r($m);die; //到时候在这里书写返回值就好了 .die;
  468. }
  469. // 历史会话记录详情
  470. public function detail($id, $type='')
  471. {
  472. $chat = db('chat_log')->where('servicelog_id',$id)->order('time_line')->select();
  473. $html = '';
  474. for($i=0;$i<count($chat);$i++){
  475. $content = json_decode($chat[$i]['content'], true);
  476. $chat[$i]['time_line'] = date('H:i',$chat[$i]['time_line']);
  477. if(!empty($content['text'])){
  478. $content['content'] = '&nbsp&nbsp'.$content['text'].'&nbsp&nbsp';
  479. }
  480. if(!empty($content['img'])){
  481. $content['content'] = '<img width="100%" src="'.$content['img'].'"/>';
  482. }
  483. if(!empty(strstr($chat[$i]['to_id'], 'KF'))){
  484. /*$preg1 = "/^#[*]$/";
  485. $preg= '/xue[\s\S]*?om/i';
  486. preg_match_all($preg1,"#[哈哈]/",$res);
  487. var_dump($res);*/
  488. $this->matching("#[哈哈]/","#\[","\]\/");
  489. //$this->getFacesIcon();
  490. $html = $html . '<div style="margin-top:15px;width:75%"><div>'.$chat[$i]['from_name'].'&nbsp&nbsp&nbsp'.$chat[$i]['time_line'].'</div>';
  491. $html = $html . '<div style="margin-top:5px;display:inline-block;*display:inline;*zoom:1;word-break:break-all;word-wrap:break-word" class="form-content">'.$content['content'].'</div></div>';
  492. }else{
  493. $html = $html . '<div style="margin-top:15px;width:75%;margin-left:25%;text-align:right;"><div>'.$chat[$i]['from_name'].'&nbsp&nbsp&nbsp'.$chat[$i]['time_line'].'</div>';
  494. $html = $html . '<div style="margin-top:5px;display:inline-block;*display:inline;*zoom:1;text-align:left;word-break:break-all;word-wrap:break-word" class="form-content">'.$content['content'].'</div></div>';
  495. }
  496. }
  497. $redis = new Redis;
  498. if ($type === 'onLine') {
  499. $servicelog = json_decode($redis->handler()->Hget('SERVICELOG', $id), true);
  500. } else {
  501. $servicelog = db('service_log')->where('servicelog_id',$id)->find();
  502. }
  503. //满意度
  504. $evaluate = db('evaluate')->where('evaluate_id',$servicelog['evaluate_id'])->find();
  505. $evaluate = '<img width="40px" style="margin-top:15px;" src="'.$evaluate['evaluate_url'].'"/>';
  506. //$alarm报警信息
  507. if ($type === 'onLine') {
  508. $alarm = json_decode($redis->handler()->Hget('SERVICELOG', $id), true);
  509. } else {
  510. $alarm = db('alarm')->where('servicelog_id',$id)->find();
  511. }
  512. //会话超时标准
  513. $verifyAllTime = db('systemconfig')->where('systemconfig_name','质检会话时长设置')->find();
  514. //会话响应时长标准
  515. $verifyReturnTime = db('systemconfig')->where('systemconfig_name','质检会话响应时长设置')->find();
  516. $span = '';
  517. if(!empty($alarm)){
  518. if($alarm['alarm_userSensitive'] != 0){
  519. $span = $span . '<span class="alarm_info">访客敏感词</span>';
  520. }
  521. if($alarm['alarm_serverSensitive'] != 0){
  522. $span = $span . '<span class="alarm_info">客服敏感词</span>';
  523. }
  524. if($alarm['alarm_corresponding'] > $verifyReturnTime['systemconfig_data']){
  525. $span = $span . '<span class="alarm_info">响应超时</span>';
  526. }
  527. if($alarm['alarm_cvtOvertime'] > $verifyAllTime['systemconfig_data']){
  528. $span = $span . '<span class="alarm_info">会话超时</span>';
  529. }
  530. if($alarm['alarm_respond'] == 1){
  531. $span = $span . '<span class="alarm_info">客服未回应</span>';
  532. }
  533. if($alarm['alarm_count'] == 0 && $type !== 'onLine'){
  534. $span = $span . '<span class="alarm_info">会话无内容</span>';
  535. }
  536. }
  537. //用户信息
  538. $account = db('accounts')->where('id',$servicelog['user_id'])->find();
  539. $label = db('accountslabel')->where('id', $account['label_id'])->find();
  540. $account['label'] = $label['name'];
  541. $this->assign([
  542. 'html' => $html,
  543. 'span' => $span,
  544. 'evaluate' => $evaluate,
  545. 'servicelog' => $servicelog,
  546. 'account' => $account
  547. ]);
  548. return $this->fetch();
  549. }
  550. // 生成按钮
  551. private function makeBtn($id)
  552. {
  553. $operate = '<a href="' . url('system/detail', ['id' => $id]) . '">';
  554. // $operate .= '<button type="button" class="btn btn-primary btn-sm"><i class="fa fa-paste"></i> 详情</button></a> ';
  555. $operate .= '<button type="button" class="btn btn-primary btn-sm"> 详情</button></a> ';
  556. return $operate;
  557. }
  558. public function getFacesIcon($facesIcon) {
  559. $data = ["[微笑]", "[嘻嘻]", "[哈哈]", "[可爱]", "[可怜]", "[挖鼻]", "[吃惊]", "[害羞]", "[挤眼]", "[闭嘴]", "[鄙视]",
  560. "[爱你]", "[泪]", "[偷笑]", "[亲亲]", "[生病]", "[太开心]", "[白眼]", "[右哼哼]", "[左哼哼]", "[嘘]", "[衰]",
  561. "[委屈]", "[吐]", "[哈欠]", "[抱抱]", "[怒]", "[疑问]", "[馋嘴]", "[拜拜]", "[思考]", "[汗]", "[困]", "[睡]",
  562. "[钱]", "[失望]", "[酷]", "[色]", "[哼]", "[鼓掌]", "[晕]", "[悲伤]", "[抓狂]", "[黑线]", "[阴险]", "[怒骂]",
  563. "[互粉]", "[心]", "[伤心]", "[猪头]", "[熊猫]", "[兔子]", "[ok]", "[耶]", "[good]", "[NO]", "[赞]", "[来]",
  564. "[弱]", "[草泥马]", "[神马]", "[囧]", "[浮云]", "[给力]", "[围观]", "[威武]", "[奥特曼]", "[礼物]", "[钟]",
  565. "[话筒]", "[蜡烛]", "[蛋糕]"];
  566. $key = array_search($facesIcon, $data);
  567. return $key;
  568. }
  569. //导出数据
  570. public function toexcel()
  571. {
  572. $param = input('param.');
  573. $limit = $param['pageSize'];
  574. $offset = ($param['pageNumber'] - 1) * $limit;
  575. $start = $param['start'];
  576. $end = $param['end'];
  577. $where = [];
  578. if($param['user_id'] != 0){
  579. $where['kf_id'] = $param['user_id'];
  580. }
  581. if($param['group_id'] != 0){
  582. $where['group_id'] = $param['group_id'];
  583. }
  584. if(!empty($param['username'])){
  585. $where['user_name'] = $param['username'];
  586. }
  587. $result = db('service_log')->whereBetween('start_time', [strtotime($start), strtotime($end . ' 23:59:59')])->where($where)->order('start_time', 'desc')->select();
  588. //所有客服
  589. $users = db('users')->select();
  590. //所有客服组
  591. $groups = db('groups')->select();
  592. //满意度
  593. $evaluate = db('evaluate')->select();
  594. //$alarm报警信息
  595. $alarm = db('alarm')->select();
  596. //会话超时标准
  597. $verifyAllTime = db('systemconfig')->where('systemconfig_name','质检会话时长设置')->find();
  598. //会话响应时长标准
  599. $verifyReturnTime = db('systemconfig')->where('systemconfig_name','质检会话响应时长设置')->find();
  600. for($c=0;$c<count($alarm);$c++){
  601. $alarm[$c]['alarminfo'] = '';
  602. if($alarm[$c]['alarm_userSensitive'] != 0){
  603. $alarm[$c]['alarminfo'] .= '访客敏感词/';
  604. }
  605. if($alarm[$c]['alarm_serverSensitive'] != 0){
  606. $alarm[$c]['alarminfo'] .= '客服敏感词/';
  607. }
  608. if($alarm[$c]['alarm_corresponding'] > $verifyReturnTime['systemconfig_data']){
  609. $alarm[$c]['alarminfo'] .= '响应超时/';
  610. }
  611. if($alarm[$c]['alarm_cvtOvertime'] > $verifyAllTime['systemconfig_data']){
  612. $alarm[$c]['alarminfo'] .= '会话超时/';
  613. }
  614. if($alarm[$c]['alarm_respond'] == 1){
  615. $alarm[$c]['alarminfo'] .= '客服未回应/';
  616. }
  617. if($alarm[$c]['alarm_count'] == 0){
  618. $alarm[$c]['alarminfo'] .= '会话无内容';
  619. }
  620. }
  621. foreach($result as $key=>$vo){
  622. if($result[$key]['intime'] != 0){
  623. $result[$key]['intime'] = date('Y-m-d H:i:s', $vo['intime']);
  624. }else{
  625. $result[$key]['intime'] = '-';
  626. }
  627. if($result[$key]['start_time'] != 0){
  628. $result[$key]['start_time'] = date('Y-m-d H:i:s', $vo['start_time']);
  629. }else{
  630. $result[$key]['start_time'] = '-';
  631. }
  632. if($result[$key]['end_time'] != 0){
  633. $result[$key]['end_time'] = date('Y-m-d H:i:s', $vo['end_time']);
  634. }else{
  635. $result[$key]['end_time'] = '-';
  636. }
  637. //客服昵称
  638. for($i=0;$i<count($users);$i++){
  639. $result[$key]['kefu_name'] = '-';
  640. if($result[$key]['kf_id'] == $users[$i]['id']){
  641. $result[$key]['kefu_name'] = $users[$i]['user_name'];
  642. }
  643. }
  644. //满意度
  645. $result[$key]['evaluate_name'] = '';
  646. for($j=0;$j<count($evaluate);$j++){
  647. if($result[$key]['evaluate_id'] == $evaluate[$j]['evaluate_id']){
  648. $result[$key]['evaluate_name'] = $evaluate[$j]['evaluate_name'];
  649. }
  650. }
  651. //客服所在组
  652. for($a=0;$a<count($groups);$a++){
  653. if($result[$key]['group_id'] == $groups[$a]['id']){
  654. $result[$key]['group_name'] = $groups[$a]['name'];
  655. }
  656. }
  657. //会话时长/响应时长/报警信息
  658. $result[$key]['conversation'] = '';
  659. $result[$key]['response'] = '';
  660. $result[$key]['alarm'] = '';
  661. for($b=0;$b<count($alarm);$b++){
  662. if($result[$key]['servicelog_id'] == $alarm[$b]['servicelog_id']){
  663. //会话时长
  664. $conversation_min = intval($alarm[$b]['alarm_cvtOvertime']/60);
  665. $conversation_s = $alarm[$b]['alarm_cvtOvertime']%60;
  666. $result[$key]['conversation'] = $conversation_min.'分'.$conversation_s.'秒';
  667. //响应时长
  668. $response_min = intval($alarm[$b]['alarm_corresponding']/60);
  669. $response_s = $alarm[$b]['alarm_corresponding']%60;
  670. $result[$key]['response'] = $response_min.'分'.$response_s.'秒';
  671. //报警信息
  672. $result[$key]['alarminfo'] = $alarm[$b]['alarminfo'];
  673. }
  674. }
  675. if($vo['servicelog_close_type'] == 0){
  676. $result[$key]['servicelog_close_type'] = '未知';
  677. }
  678. if($vo['servicelog_close_type'] == 1){
  679. $result[$key]['servicelog_close_type'] = '无效会话';
  680. }
  681. if($vo['servicelog_close_type'] == 2){
  682. $result[$key]['servicelog_close_type'] = '双方静默';
  683. }
  684. if($vo['servicelog_close_type'] == 3){
  685. $result[$key]['servicelog_close_type'] = '客服关闭';
  686. }
  687. if($vo['servicelog_close_type'] == 4){
  688. $result[$key]['servicelog_close_type'] = '客服掉线';
  689. }
  690. if($vo['servicelog_close_type'] == 5){
  691. $result[$key]['servicelog_close_type'] = '转出';
  692. }
  693. if($vo['servicelog_close_type'] == 6){
  694. $result[$key]['servicelog_close_type'] = '用户关闭';
  695. }
  696. //工单聊天详情
  697. $chat_log = db('chat_log')->where('servicelog_id',$vo['servicelog_id'])->order('time_line', 'desc')->select();
  698. $result[$key]['detail'] = '';
  699. for($c=0;$c<count($chat_log);$c++){
  700. $content = json_decode($chat_log[$c]['content'], true);
  701. $chat_log[$c]['time_line'] = date('Y-m-d H:i:s',$chat_log[$c]['time_line']);
  702. $result[$key]['detail'] = $result[$key]['detail'].' '.$chat_log[$c]['time_line'].' '.$chat_log[$c]['from_name'];
  703. $content['content'] = '';
  704. if(!empty($content['text'])){
  705. $content['content'] = $content['text'];
  706. }
  707. if(!empty($content['img'])){
  708. $content['content'] = '<img width="100%" src="'.$content['img'].'"/>';
  709. }
  710. $result[$key]['detail'] = $result[$key]['detail'].' '.$content['content'];
  711. }
  712. }
  713. $head = ['工单id', '访客进线时间', '接待客服', '所在组', '访客账号', '开始时间', '结束时间', '会话时长', '响应时长', '关闭原因', '满意度','来源ip','来源网站','来源系统','来源浏览器','报警信息','聊天详情'];
  714. $key = ['servicelog_id', 'intime', 'kefu_name', 'group_name', 'user_name', 'start_time', 'end_time', 'conversation', 'response', 'servicelog_close_type', 'evaluate_name','user_ip','website','system','browse','alarminfo','detail'];
  715. (new Office())->outdata('工单数据导出', $result, $head, $key);
  716. return true;
  717. }
  718. // 生成按钮
  719. private function makeBotton($id)
  720. {
  721. $operate = '<a href="' . url('editWelcome', ['id' => $id]) . '">';
  722. $operate .= '<button type="button" class="btn btn-primary btn-sm"><i class="fa fa-paste"></i> 编辑</button></a> ';
  723. $operate .= '<a href="javascript:delWelcome(' . $id . ')"><button type="button" class="btn btn-danger btn-sm">';
  724. $operate .= '<i class="fa fa-trash-o"></i> 删除</button></a> ';
  725. return $operate;
  726. }
  727. /**
  728. * 验证平台设置
  729. *
  730. * @access public
  731. */
  732. public function platform()
  733. {
  734. // 表单提交.
  735. if (request()->isPost()) {
  736. $param = input('post.');
  737. try {
  738. $updateWhere['platform_code'] = 'Customer-Service';
  739. $updateData = [
  740. 'platform_url_token' => $param['urlToken'],
  741. 'platform_url_code' => $param['urlToken'],
  742. ];
  743. db('platform')->where($updateWhere)->update($updateData);
  744. return json(['code' => 1, 'data' => '', 'msg' => '设置成功']);
  745. } catch (\Exception $e) {
  746. return json(['code' => -2, 'data' => '', 'msg' => $e->getMessage()]);
  747. }//end try
  748. }//end if
  749. // 信息.
  750. $settings = db('platform')->find();
  751. $this->assign(
  752. [
  753. 'urlToken' => $settings['platform_url_token'],
  754. 'urlCode' => $settings['platform_url_code'],
  755. ]
  756. );
  757. return $this->fetch();
  758. }//end basics()
  759. }