CustomerService.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. <?php
  2. /**
  3. * Created by PhpStorm.
  4. * User: Administrator
  5. * Date: 2018/11/1
  6. * Time: 14:02
  7. */
  8. namespace app\admin\controller;
  9. use app\common\controller\Base;
  10. use app\common\model\Kefu;
  11. use think\Cache;
  12. use think\Db;
  13. use think\Env;
  14. class CustomerService extends Admin
  15. {
  16. private $_status = [
  17. '0' => '未审核',
  18. '1' => '成功',
  19. '2' => '失败',
  20. '3' => '成功改完密码',
  21. '4' => '已驳回'
  22. ];
  23. protected function _initialize()
  24. {
  25. parent::_initialize(); // TODO: Change the autogenerated stub
  26. $this->settingModel = model('CscSetting');
  27. $this->appealModel = model('Common/CscAppeal');
  28. $this->kefuModel = model('Common/Kefu');
  29. }
  30. /**
  31. *客服系统配置列表
  32. */
  33. public function customerDeploy()
  34. {
  35. $cscList = $this->settingModel->getList();
  36. $this->assign('list',$cscList);
  37. $this->assign('page',$cscList);
  38. return $this->fetch('customer_deploy');
  39. }
  40. /**
  41. * 新增客服系统配置列表
  42. * @return mixed
  43. */
  44. public function addCustomer()
  45. {
  46. if ($this->request->isPost()) {
  47. $data = $this->getCustomerParam();
  48. $result = $this->validate($data, [
  49. ['name', 'require', '字段名不能为空'],
  50. ['title', 'require', '备注不能为空'],
  51. ]);
  52. if (true !== $result) {
  53. $this->error($result);
  54. }
  55. if ($this->settingModel->where(['name'=>$data['name']])->find()) {
  56. $this->error('字段名不能重复');
  57. }
  58. if ($this->settingModel->allowField(true)->save($data)) {
  59. $this->success('添加成功',url('customerdeploy'));
  60. }
  61. $this->error($this->settingModel->getError() ?: '添加失败');
  62. }
  63. return $this->fetch('add_customer');
  64. }
  65. /*
  66. *客服系统配置列表修改
  67. */
  68. public function editCustomer()
  69. {
  70. $id = $this->request->param('id', 0, 'intval');
  71. if ($this->request->isPost()) {
  72. $data = $this->getCustomerParam();
  73. $result = $this->validate($data, [
  74. ['name', 'require', '字段名不能为空'],
  75. ['title', 'require', '备注不能为空'],
  76. ]);
  77. if (true !== $result) {
  78. $this->error($result);
  79. }
  80. if ($this->settingModel->allowField(true)->save($data, ['id' => $id]) !== false ) {
  81. // 重新计算未发放的申诉单
  82. $this->setAppealScore();
  83. $this->success('编辑成功',url('customerdeploy'));
  84. }
  85. $this->error($this->settingModel->getError() ?: '编辑失败');
  86. }
  87. $data = $this->settingModel->where('id',$id)->find();
  88. $this->assign('data', $data);
  89. return $this->fetch('edit_customer');
  90. }
  91. /*
  92. *客服配置编辑、新增字段
  93. */
  94. public function getCustomerParam()
  95. {
  96. $data = [
  97. 'name' => input('post.name'),
  98. 'value' => input('post.value'),
  99. 'title' => input('post.title'),
  100. ];
  101. return $data;
  102. }
  103. protected function getAppealParam(){
  104. $condition = [];
  105. $username = $this->request->get('username','','trim');
  106. $code = $this->request->get('code','','trim');
  107. $status = $this->request->get('status','','trim');
  108. $reason = $this->request->get('reason',0,'intval');
  109. !empty($username) && $condition['username'] = $username;
  110. !empty($code) && $condition['code'] = $code;
  111. if ($status != '') $condition['status'] = $status;
  112. !empty($reason) && $condition['reason'] = $reason;
  113. $start_time = input('request.cr_start');
  114. //开始时间和结束时间不为空时
  115. if ($start_time != '' && input('request.cr_end') != '') {
  116. $condition['create_time'] = [
  117. ['>=', strtotime($start_time)],
  118. ['<=', strtotime(input('request.cr_end').' 23:59:59')],
  119. ];
  120. } //开始时间不为空时
  121. elseif ($start_time!= '') {
  122. $condition['create_time'] = ['>=', strtotime($start_time)];
  123. } //结束时间不为空时
  124. elseif (input('request.cr_end') != '') {
  125. $condition['create_time'] = ['<=', strtotime(input('request.cr_end').' 23:59:59')];
  126. }
  127. return $condition;
  128. }
  129. /**
  130. *客服管理申诉列表
  131. */
  132. public function appeal()
  133. {
  134. $condition = $this->getAppealParam();
  135. //获取后台通过申诉分数的值
  136. $score = $this->settingModel->where('name','MARK_APPEAL')->value('value');
  137. $AppealList = $this->appealModel
  138. ->where($condition)
  139. ->field('id,username,mobile,mail,code,status,reason,score,create_time,notice_time,remark,operate_time,operate_id')
  140. ->order('status asc,create_time desc')
  141. ->paginate(15, false, array('query' => input('get.')));
  142. foreach ($AppealList as $key => &$v) {
  143. $v['username'] = stringObfuscation($v['username'],3);
  144. $v['operator'] = '';
  145. if (!empty($v['operate_id'])){
  146. $v['operator'] = model('Admin')->where('id',$v['operate_id'])->value('username');
  147. }
  148. }
  149. $this->assign('score',$score);
  150. $this->assign('list',$AppealList);
  151. $this->assign('page',$AppealList);
  152. return $this->fetch();
  153. }
  154. /**
  155. *被盗嫌疑列表
  156. */
  157. public function stolenList()
  158. {
  159. $username = $this->request->get('username','','trim');
  160. $code = $this->request->get('code','','trim');
  161. !empty($username) && $Where['username'] = $username;
  162. !empty($code) && $Where['code'] = $code;
  163. //获取配置分数
  164. $score = $this->settingModel->where('name','MARK_APPEAL')->value('value');
  165. $Where['reason'] = 2;
  166. $Where['score'] = ['egt',$score];
  167. $AppealList = $this->appealModel
  168. ->where($Where)
  169. ->field('id,username,mobile,mail,code,status,reason,score,create_time,notice_time')
  170. ->order('status asc,create_time desc')
  171. ->paginate(15, false, array('query' => input('get.')));
  172. foreach ($AppealList as $key => $v) {
  173. $v['username'] = stringObfuscation($v['username'],3);
  174. }
  175. $this->assign('list', $AppealList);
  176. $this->assign('page', $AppealList->render());
  177. return $this->fetch('stolen_list');
  178. }
  179. /**
  180. *客服QQ列表
  181. */
  182. public function customerQq()
  183. {
  184. $qqList = $this->kefuModel->getList();
  185. $gameLit = model('Common/Game')->getAllByCondition('id,name', [],'','self');
  186. $newGameList = array_column($gameLit, 'name', 'id');
  187. $this->assign('list',$qqList);
  188. $this->assign('page',$qqList);
  189. $this->assign('game_list',$newGameList);
  190. return $this->fetch('customer_qq');
  191. }
  192. /*
  193. * 新增客服QQ
  194. */
  195. public function addQq()
  196. {
  197. if ($this->request->isPost()) {
  198. $data = $this->getQqParam();
  199. $result = $this->validate($data, [
  200. ['qq', 'require|number|min:5|max:11', 'qq不能为空|qq要数字哦|qq不能小于五位数|qq不能大于11位'],
  201. ]);
  202. if (true !== $result) {
  203. $this->error($result);
  204. }
  205. if ($this->kefuModel->allowField(true)->save($data)) {
  206. $this->success('添加成功',url('customerqq'));
  207. }
  208. $this->error($this->kefuModel->getError() ?: '添加失败');
  209. }
  210. $gameLit = model('Common/Game')->getAllByCondition('id,name', [],'','self');
  211. $this->assign('game_list',$gameLit);
  212. return $this->fetch('add_qq');
  213. }
  214. /*
  215. * 编辑客服qq
  216. */
  217. public function editQq()
  218. {
  219. $id = $this->request->param('id', 0, 'intval');
  220. if ($this->request->isPost()) {
  221. $data = $this->getQqParam();
  222. $result = $this->validate($data, [
  223. ['qq', 'require|min:5|max:11|number', 'qq不能为空|qq不能小于五位数|qq不能大于11位|qq要数字哦'],
  224. ]);
  225. if (true !== $result) {
  226. $this->error($result);
  227. }
  228. if ($res = model('common/Kefu')->allowField(true)->save($data, ['id' => $id]) !== false ) {
  229. // Cache::rm(Kefu::CACHE_KEY);
  230. // if(!empty($data['game_id'])){
  231. // Cache::rm(Kefu::CACHE_KEY . ':' . $data['game_id']);
  232. // }
  233. $this->success('编辑成功',url('customerqq'));
  234. }
  235. $this->error($this->kefuModel->getError() ?: '编辑失败');
  236. }
  237. $data = model('common/Kefu')->where('id',$id)->find();
  238. $this->assign('data', $data);
  239. $gameLit = model('Common/Game')->getAllByCondition('id,name', [],'','self');
  240. $this->assign('game_list',$gameLit);
  241. return $this->fetch('edit_qq');
  242. }
  243. /*
  244. * 删除客服qq
  245. */
  246. public function delQq()
  247. {
  248. $id = $this->request->param('id', 0, 'intval');
  249. if (empty($id) || !($data = $this->kefuModel->find($id))) {
  250. $this->error('参数错误,不存在改客服qq的');
  251. }
  252. if ($data->delete()) {
  253. $this->success('删除成功!');
  254. }
  255. $this->error('删除失败');
  256. }
  257. /*
  258. * 客服qq编辑、新增字段
  259. */
  260. public function getQqParam()
  261. {
  262. $data = [
  263. 'qq' => input('post.qq'),
  264. 'nickname' => input('post.nickname'),
  265. 'game_id' => input('post.game_id'),
  266. ];
  267. return $data;
  268. }
  269. /**
  270. * 用户申诉信息页面
  271. */
  272. public function appealInfo()
  273. {
  274. if ($this->request->isPost()) {
  275. $username = $this->request->post('username','','trim');
  276. $code = $this->request->post('code','','trim');
  277. !empty($username) && $condition['username'] = $username;
  278. !empty($code) && $condition['code'] = $code;
  279. }else{
  280. $id = $this->request->param('id', 0, 'intval');
  281. !empty($id) && $condition['id'] = $id;
  282. }
  283. if (!isset($condition) || empty($condition)) {
  284. $this->error('查询条件不能为空');
  285. }
  286. $array = $this->appealModel->getAppealResult($condition);
  287. if (empty($array)) {
  288. $this->error('暂无数据');
  289. }
  290. $data = $array['data'];
  291. $result = $array['result'];
  292. $oldpwd = $this->getOldPwd($data,$result);
  293. $oldmail = $this->getOldMail($data,$result);
  294. $oldmobile = $this->getOldMobile($data,$result);
  295. $boundgame = $this->getBoundgame($data,$result);
  296. foreach ($array['recharge'] as $key => &$value) {
  297. $value['result'] = isset($array['result']['recharge'][$key])? $array['result']['recharge'][$key] : 0;
  298. }
  299. $array['oldpwd'] = $oldpwd;
  300. $array['oldmail'] = $oldmail;
  301. $array['oldmobile'] = $oldmobile;
  302. $array['boundgame'] = $boundgame;
  303. // 多选分数合并显示操作
  304. /*$recharge_1 = array_column($array['recharge'],'result');*/
  305. $oldpwd_1 = array_column($array['oldpwd'],'result');
  306. $oldmail_1 = array_column($array['oldmail'],'result');
  307. $oldmobile_1 = array_column($array['oldmobile'],'result');
  308. $boundgame_1 = array_column($array['boundgame'],'result');
  309. $array['recharge_1'] = ['num'=>count($array['recharge']),'isscore'=>0];
  310. $array['oldpwd_1'] = ['num'=>count($array['oldpwd']),'isscore'=>0];
  311. $array['oldmail_1'] = ['num'=>count($array['oldmail']),'isscore'=>0];
  312. $array['oldmobile_1'] = ['num'=>count($array['oldmobile']),'isscore'=>0];
  313. $array['boundgame_1'] = ['num'=>count($array['boundgame']),'isscore'=>0];
  314. /*if (in_array(1,$recharge_1)){
  315. $array['recharge_1']['isscore'] = 1;
  316. }*/
  317. if (in_array(1,$oldpwd_1)){
  318. $array['oldpwd_1']['isscore'] = 1;
  319. }
  320. if (in_array(1,$oldmail_1)){
  321. $array['oldmail_1']['isscore'] = 1;
  322. }
  323. if (in_array(1,$oldmobile_1)){
  324. $array['oldmobile_1']['isscore'] = 1;
  325. }
  326. if (in_array(1,$boundgame_1)){
  327. $array['boundgame_1']['isscore'] = 1;
  328. }
  329. $this->assign('array',$array);
  330. return $this->fetch('appeal_info');
  331. }
  332. //获取历史密码数据结果
  333. public function getOldPwd($data,$result)
  334. {
  335. $oldpwd = [];
  336. $data['oldpwd'] = array_values($data['oldpwd']);
  337. foreach ($data['oldpwd'] as $key => $pwd){
  338. $oldpwd[$key] = array(
  339. 'oldpwd' => $pwd,
  340. 'result' => isset($result['oldpwd'][$key]) ? $result['oldpwd'][$key] : 0,
  341. );
  342. }
  343. return $oldpwd;
  344. }
  345. //获取历史邮箱数据结果
  346. public function getOldMail($data,$result)
  347. {
  348. $oldmail = [];
  349. $data['oldmail'] = array_values($data['oldmail']);
  350. foreach ($data['oldmail'] as $key => $mail){
  351. $oldmail[$key] = array(
  352. 'oldmail' => $mail,
  353. 'result' => isset($result['oldmail'][$key]) ? $result['oldmail'][$key] : 0,
  354. );
  355. }
  356. return $oldmail;
  357. }
  358. //获取历史手机数据结果
  359. public function getOldMobile($data,$result)
  360. {
  361. $oldmobile = [];
  362. $data['oldmobile'] = array_values($data['oldmobile']);
  363. foreach ($data['oldmobile'] as $key => $mobile){
  364. $oldmobile[$key] = array(
  365. 'oldmobile' => $mobile,
  366. 'result' => isset($result['oldmobile'][$key]) ? $result['oldmobile'][$key] : 0,
  367. );
  368. }
  369. return $oldmobile;
  370. }
  371. //获取绑定游戏数据结果
  372. public function getBoundgame($data, $result)
  373. {
  374. $boundgame = [];
  375. $data['boundgameid'] = array_values($data['boundgameid']);
  376. foreach ($data['boundgameid'] as $key => $id){
  377. $boundgame[$key] = array(
  378. 'boundgameid' => $id,
  379. 'result' => isset($result['boundgameid'][$key]) ? $result['boundgameid'][$key] : 0,
  380. 'name' => $this->appealModel->getGameName($id)
  381. );
  382. }
  383. return $boundgame;
  384. }
  385. /**
  386. * 手动校验用户提供给客服的密码是否正确
  387. */
  388. public function md5Password(){
  389. if($this->request->isAjax()){
  390. $status = 0;
  391. $uid = (int)input('post.uid');
  392. $password = input('post.password');
  393. $password = auth_code($password, 'ENCODE');
  394. $historyinfo = model('Common/MemberHistory')->where('userid',$uid)->field('password')->select(); //历史信息
  395. foreach ($historyinfo as $history){
  396. if($password == $history['password']){
  397. $status = 1;
  398. }
  399. }
  400. if ($status == 1) {
  401. $this->success('密码正确');
  402. }else{
  403. $this->error('密码错误');
  404. }
  405. }
  406. }
  407. //发送申诉结果信息
  408. public function send(){
  409. $id = (int)$this->request->param('id', 0, 'intval');
  410. if ( ! $id ) {
  411. $this->error('数据不存在');
  412. }
  413. $status = (int)$this->request->param('status', 0, 'intval');
  414. $systemScore = $this->settingModel->where('name','MARK_APPEAL')->value('value');
  415. $info = $this->appealModel->where(['id' => $id])->find();
  416. if (!$info) {
  417. $this->error('未查询到该申诉信息');
  418. }
  419. $certificate = '';
  420. $code = $info['code'];
  421. $mail = $info['mail'];
  422. $mobile = $info['mobile'];
  423. $username = $info['username'];
  424. $score = $info['score'];
  425. $condition['code'] = $code;
  426. $time = $info['notice_time'];
  427. $is_finish = $info['is_finish'];
  428. if(!empty($is_finish)){
  429. $this->error('通知已发送');
  430. }
  431. if(NOW_TIMESTAMP < $time){
  432. $this->error('未到可通知时间');
  433. }
  434. if($status == 0 || $status == 4){
  435. $data['operate_time'] = NOW_TIMESTAMP;
  436. $data['operate_id'] = session('ADMIN_ID');
  437. }
  438. if(empty($status)){
  439. if($score >= $systemScore){
  440. $certificate = rand(111111, 999999);
  441. $status = 1;
  442. }else{
  443. $status = 2;
  444. }
  445. }
  446. if($status == 2 || $status == 4){
  447. $data['is_finish'] = 1;
  448. }
  449. if ($status == 4){
  450. $remark = $this->request->param('remark', '', 'trim');
  451. if (!empty($remark)) $data['remark'] = $remark;
  452. }
  453. $data['operate_id'] = mg_get_current_admin_id();
  454. $data['status'] = $status;
  455. if (isset($certificate)) {
  456. $data['certificate'] = $certificate;
  457. }
  458. if (model('Common/CscAppeal')->updateAppeal($data, $info['id']) === false ) {
  459. $this->error('操作失败');
  460. }
  461. if($mail){
  462. $reg = '/^\w+([\.-]?\w+)*@\w+([\.-]?w+)*(\.\w{2,3})+$/';
  463. if(0 == preg_match($reg, $mail)) {
  464. $this->error('邮箱格式不正确');
  465. }else{
  466. $result = (new \app\common\library\Mail)->sendAppealCodeMail($username, $code, $mail, '', $certificate, $status);
  467. }
  468. }
  469. if($mobile){
  470. $preg = '/^1[345789]{1}\d{9}$/';
  471. if (0 == preg_match($preg, $mobile)) {
  472. $this->error('手机格式错误');
  473. }else{
  474. $result = (new \app\common\library\Sms)->sendAppealCode($username, $code, $mobile, '', $certificate, $status);
  475. }
  476. }
  477. if(isset($result) && $result['status']){
  478. $this->success('操作成功');
  479. $message = '玩家'.$username.'账号申诉成功';
  480. }else{
  481. $this->error($result['msg'], url('appeal'));
  482. $message = '玩家'.$username.'账号申诉失败';
  483. }
  484. }
  485. // 驳回
  486. public function reject(){
  487. $this->send();
  488. }
  489. // 重新计算未发送状态下的申诉总得分
  490. public function setAppealScore()
  491. {
  492. $data = $this->appealModel->where(['status'=>0,'score'=>['gt',0],'reason'=>['in','1,2']])->select();
  493. foreach ($data as $key => $value) {
  494. $score = $this->appealModel->getAppealScore($value);
  495. $result = $this->appealModel->where('id',$value['id'])->setField('score', $score);
  496. }
  497. }
  498. //查看用户名
  499. public function checkUsername($id,$code)
  500. {
  501. /*$id = $this->request->param('id', 0, 'intval');
  502. $code = $this->request->param('code', 0, 'intval');*/
  503. if (empty($id) || empty($code)){
  504. $this->result('',0,'参数错误!');
  505. }
  506. $info = $this->appealModel->field('username,code')->where(['id'=>$id])->find();
  507. // 记录操作日志
  508. $this->insertLog($this->current_node,'查看账号:'.$info['username'].',申诉编号:'.$info['code'],$code);
  509. $this->result($info['username'],1,$info['username']);
  510. }
  511. // 申诉列表 - 查看用户名
  512. public function checkUsername_1($id){
  513. $this->checkUsername($id,111);
  514. }
  515. // 被盗嫌疑列表 - 查看用户名
  516. public function checkUsername_2($id){
  517. $this->checkUsername($id,112);
  518. }
  519. /**
  520. * 修改申诉驳回备注
  521. */
  522. public function changeAppealRemark(){
  523. $remark = $this->request->param('remark', '', 'trim');
  524. $id = (int)$this->request->param('id', '0', 'intval');
  525. if (!$id) $this->error('参数错误!');
  526. if (empty($remark)) $this->success('');
  527. if (model('Common/CscAppeal')->updateAppeal(['remark'=>$remark], $id) === false ) {
  528. $this->error('操作失败');
  529. }
  530. $this->success('操作成功');
  531. }
  532. // ## 渠道客服 ##
  533. public function channelKefu(){
  534. $this->assign('upload_url',Env::get('mubao.upload_url'));
  535. return $this->fetch();
  536. }
  537. public function getChannelKefuList()
  538. {
  539. $input = input();
  540. $where = [
  541. 'kf.type' => 2,
  542. ];
  543. // $type = $this->request->get('type',0,'trim'); // 客服类型:0=正常客服(游戏客服),1=渠道客服
  544. // if($type == 1){
  545. // $where['kf.channel_id'] = ['gt', 0];
  546. // }
  547. $status = $this->request->get('status',""); // 状态:0=禁用,1=启用
  548. if($status !== ""){
  549. $where['kf.status'] = $status;
  550. }
  551. if(empty($input['game_id']) === false){
  552. $where[] = function($query) use ($input){
  553. $query->whereOr('FIND_IN_SET('.intval($input['game_id']).', kf.game_id)');
  554. };
  555. }
  556. if(empty($input['channel_id']) === false){
  557. $where[] = function($query) use ($input){
  558. $query->whereOr('FIND_IN_SET('.intval($input['channel_id']).', kf.channel_id)');
  559. };
  560. }
  561. if(empty($input['remark']) === false){
  562. $where['kf.remark'] = ['like', '%' . trim($input['remark']) . '%'];
  563. }
  564. $data = model('kefu')->alias('kf')
  565. ->join('nw_channel nc', 'kf.channel_id = nc.id', 'left')
  566. ->join('nw_channel nc_p', 'nc.parent_id = nc_p.id', 'left')
  567. ->where($where)
  568. ->order('is_default desc,id desc')
  569. ->field('kf.*, nc.name as channel_name, nc_p.name as channel_parent_name')->select();
  570. $count = model('kefu')->alias('kf')
  571. ->join('nw_channel nc', 'kf.channel_id = nc.id', 'left')
  572. ->join('nw_channel nc_p', 'nc.parent_id = nc_p.id', 'left')
  573. ->where($where)->count();
  574. // 渠道信息
  575. $channels = array_column($data, 'channel_id');
  576. $all_channel_ids = [];
  577. $channelDataItem = [];
  578. foreach ($channels as $v) {
  579. $tmp = explode(',', $v);
  580. $channelDataItem[] = $tmp;
  581. $all_channel_ids = array_merge($all_channel_ids, $tmp);
  582. }
  583. $channelList = model('channel')->where(['id' => ['in', $all_channel_ids]])->column('id,name');
  584. // 游戏信息
  585. $gameIds = array_column($data, 'game_id');
  586. $all_game_ids = [];
  587. $gameDataItem = [];
  588. foreach ($gameIds as $v) {
  589. $tmp = explode(',', $v);
  590. $gameDataItem[] = $tmp;
  591. $all_game_ids = array_merge($all_game_ids, $tmp);
  592. }
  593. $gameList = Db::table('cy_game')->where(['id' => ['in', $all_game_ids]])->column('id,name');
  594. // 处理数据
  595. foreach ($data as $key => &$value) {
  596. // 渠道名称处理
  597. $channel_names = [];
  598. if($value['channel_id']){
  599. foreach ($channelDataItem[$key] as $v) {
  600. if(isset($channelList[$v])){
  601. $channel_names[] = $channelList[$v];
  602. }
  603. }
  604. }
  605. if (count($channel_names) > 3) {
  606. $count = count($channel_names);
  607. $value['channel_name'] = implode(', ', array_slice($channel_names, 0, 3)) . ", ... 共{$count}个";
  608. } else {
  609. $value['channel_name'] = implode(', ', $channel_names);
  610. }
  611. // 游戏名称处理
  612. $games_names = [];
  613. if($value['game_id']){
  614. foreach ($gameDataItem[$key] as $v) {
  615. if(isset($gameList[$v])){
  616. $games_names[] = $gameList[$v];
  617. }
  618. }
  619. }
  620. if (count($games_names) > 3) {
  621. $count = count($games_names);
  622. $value['game_name'] = implode(', ', array_slice($games_names, 0, 3)) . ", ... 共{$count}个";
  623. } else {
  624. $value['game_name'] = implode(', ', $games_names);
  625. }
  626. }
  627. return json([
  628. 'code' => 200,
  629. 'msg' => '',
  630. 'count' => $count,
  631. 'data' => $data
  632. ]);
  633. }
  634. // 渠道数据(四级:商务-会长-子会长-推广员)
  635. public function getChannelList(){
  636. $input = input();
  637. $level = $this->request->get('level',0,'trim'); // 类型
  638. $where = ['level' => $level, 'status' => 1];
  639. // if(!empty($input['handle'])){
  640. // $kefuDataIds = model('kefu')->where(['type' => 2])->column('channel_id');
  641. // $channelIds = [];
  642. // foreach ($kefuDataIds as $ids) {
  643. // if (empty($ids)) continue; // 跳过空值
  644. //
  645. // $parts = explode(',', $ids);
  646. // foreach ($parts as $id) {
  647. // $id = trim($id); // 去除空格
  648. // if ($id !== '') { // 过滤空字符串
  649. // $channelIds[$id] = true; // 利用键去重
  650. // }
  651. // }
  652. // }
  653. // $channelIds = array_keys($channelIds); // 转为索引数组
  654. // if (!empty($channelIds)) {
  655. // $where['id'] = ['not in', $channelIds];
  656. // }
  657. // }
  658. $list = model('channel')->field('id as value,name')->where($where)->select();
  659. if($level === 0){
  660. foreach ($list as $k1 => $v1) {
  661. $subsetList = model('channel')->field('id as value,name')->where(['parent_id' => $v1['value'], 'level' => 1, 'status' => 1])->select();
  662. if($subsetList){
  663. foreach ($subsetList as $k2 => $v2) {
  664. $subsetThreeList = model('channel')->field('id as value,name')->where(['parent_id' => $v2['value'], 'level' => ['in', "2,3"], 'status' => 1])->select();
  665. if($subsetThreeList){
  666. foreach ($subsetThreeList as $k3 => $v3) {
  667. $subsetFourList = model('channel')->field('id as value,name')->where(['parent_id' => $v3['value'], 'level' => 3, 'status' => 1])->select();
  668. if($subsetFourList){
  669. $subsetThreeList[$k3]['children'] = $subsetFourList;
  670. }
  671. }
  672. $subsetList[$k2]['children'] = $subsetThreeList;
  673. }
  674. }
  675. $list[$k1]['children'] = $subsetList;
  676. }
  677. }
  678. }
  679. return json([
  680. 'code' => 200,
  681. 'msg' => '',
  682. 'data' => $list
  683. ]);
  684. }
  685. // 游戏数据
  686. public function getGameList(){
  687. $input = input();
  688. $where['cooperation_status'] = ['in', [0,1,2]];
  689. // if(!empty($input['handle'])){
  690. // $kefuDataIds = model('kefu')->where(['type' => 2])->column('game_id');
  691. // $gameIds = [];
  692. // foreach ($kefuDataIds as $ids) {
  693. // if (empty($ids)) continue; // 跳过空值
  694. //
  695. // $parts = explode(',', $ids);
  696. // foreach ($parts as $id) {
  697. // $id = trim($id); // 去除空格
  698. // if ($id !== '') { // 过滤空字符串
  699. // $gameIds[$id] = true; // 利用键去重
  700. // }
  701. // }
  702. // }
  703. // $gameIds = array_keys($gameIds); // 转为索引数组
  704. // if (!empty($gameIds)) {
  705. // $where['id'] = ['not in', $gameIds];
  706. // }
  707. // }
  708. $list = Db::table('cy_game')->field('id as value,name')->where($where)->order('id desc')->select();
  709. return json([
  710. 'code' => 200,
  711. 'msg' => '',
  712. 'data' => $list
  713. ]);
  714. }
  715. // 处理客服数据
  716. public function saveChannel(){
  717. $id = input('id','');
  718. $input = input('post.');
  719. $validate = [
  720. ['channel_ids|渠道', 'require', '请选择渠道'],
  721. // ['game_ids|渠道', 'require', '请选择游戏'],
  722. ['notice|说明', 'require|max:50', '请填写文案|文案最大不能超过50个字符'],
  723. // ['wx_qr_code|二维码', 'require', '请选择二维码'],
  724. ['status|状态', 'require', '请选择状态'],
  725. ];
  726. if($input['is_default'] == 2){
  727. $validate = [
  728. ['notice|说明', 'require|max:50', '请填写文案|文案最大不能超过50个字符'],
  729. ['status|状态', 'require', '请选择状态'],
  730. ];
  731. }
  732. $validRes = $this->validate($input, $validate);
  733. if($validRes !== true){
  734. return json([
  735. 'code' => -100,
  736. 'msg' => $validRes,
  737. 'data' => []
  738. ]);
  739. }
  740. $channel_ids = rtrim($input['channel_ids'], ',');
  741. $game_ids = 0;
  742. if(!empty($input['game_ids'])){
  743. $game_ids = rtrim($input['game_ids'], ',');
  744. }
  745. $data = [
  746. 'type' => 2,
  747. 'channel_id' => $channel_ids,
  748. 'game_id' => $game_ids,
  749. 'notice' => $input['notice'],
  750. 'wx_qr_code' => $input['wx_qr_code']??'',
  751. 'wx_kefu_url' => $input['wx_kefu_url']??'',
  752. 'remark' => $input['remark']??'',
  753. 'status' => $input['status'],
  754. ];
  755. /* —— 真正支持“多 id 交集”查重(提示展示渠道名/游戏名)—— */
  756. $postChannelArr = array_values(array_filter(explode(',', $channel_ids)));
  757. $postGameArr = array_values(array_filter(explode(',', $game_ids)));
  758. $existsList = Db::table('cy_kefu')
  759. ->where('type', 2)
  760. ->where('channel_id', '>', 0)
  761. ->field('id, channel_id, game_id')
  762. ->select();
  763. // 判断是否存在交集
  764. $allChannelIds = $postChannelArr;
  765. $allGameIds = $postGameArr;
  766. foreach ($existsList as $row) {
  767. $allChannelIds = array_merge($allChannelIds, array_filter(explode(',', $row['channel_id'])));
  768. $allGameIds = array_merge($allGameIds, array_filter(explode(',', $row['game_id'])));
  769. }
  770. $allChannelIds = array_values(array_unique($allChannelIds));
  771. $allGameIds = array_values(array_unique($allGameIds));
  772. $channelMap = [];
  773. if (!empty($allChannelIds)) {
  774. $channelMap = model('channel')->where(['id' => ['in', $allChannelIds]])->column('name', 'id');
  775. }
  776. $gameMap = [];
  777. if (!empty($allGameIds)) {
  778. $gameMap = Db::table('cy_game')->where(['id' => ['in', $allGameIds]])->column('name', 'id');
  779. }
  780. foreach ($existsList as $row) {
  781. if (!empty($id) && (string)$row['id'] === (string)$id) {
  782. continue;
  783. }
  784. $dbChannelArr = array_values(array_filter(explode(',', $row['channel_id'])));
  785. $dbGameArr = array_values(array_filter(explode(',', $row['game_id'])));
  786. $channelIntersect = array_values(array_intersect($postChannelArr, $dbChannelArr));
  787. $gameIntersect = array_values(array_intersect($postGameArr, $dbGameArr));
  788. if (!$channelIntersect || !$gameIntersect) {
  789. continue;
  790. }
  791. $msg = '';
  792. if($channelIntersect){
  793. $channelNames = implode('、', array_map(function ($cid) use ($channelMap) {
  794. return isset($channelMap[$cid]) ? $channelMap[$cid] : ('未知渠道(' . $cid . ')');
  795. }, $channelIntersect));
  796. $msg = "【{$channelNames}】";
  797. }
  798. if($gameIntersect){
  799. $gameNames = implode('、', array_map(function ($gid) use ($gameMap) {
  800. return isset($gameMap[$gid]) ? $gameMap[$gid] : ('未知游戏(' . $gid . ')');
  801. }, $gameIntersect));
  802. $msg .= "+【{$gameNames}】";
  803. }
  804. $msg .= "已存在,不可重复添加!";
  805. return json([
  806. 'code' => -100,
  807. 'msg' => $msg,
  808. 'data' => []
  809. ]);
  810. }
  811. if($id){
  812. $data['update_time'] = time();
  813. $res = model('kefu')->where(['id' => $id])->update($data);
  814. }else{
  815. $data['create_time'] = time();
  816. $res = model('kefu')->insert($data);
  817. }
  818. if(!$res){
  819. return json([
  820. 'code' => -100,
  821. 'msg' => "操作失败!",
  822. 'data' => []
  823. ]);
  824. }
  825. return json([
  826. 'code' => 200,
  827. 'msg' => '操作成功!',
  828. 'data' => []
  829. ]);
  830. }
  831. // 删除客服数据
  832. public function delChannel(){
  833. $id = input('id','');
  834. if(!$id){
  835. return json([
  836. 'code' => -100,
  837. 'msg' => "非法操作!",
  838. 'data' => []
  839. ]);
  840. }
  841. $res = model('kefu')->where(['id' => $id])->delete();
  842. if(!$res){
  843. return json([
  844. 'code' => -100,
  845. 'msg' => "操作失败!",
  846. 'data' => []
  847. ]);
  848. }
  849. return json([
  850. 'code' => 200,
  851. 'msg' => '操作成功!',
  852. 'data' => []
  853. ]);
  854. }
  855. }