Servicer.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. <?php
  2. namespace addon\servicer\model;
  3. use app\model\BaseModel;
  4. use app\model\shop\Shop as ShopModel;
  5. use app\model\system\User as UserModel;
  6. use app\model\web\WebSite as WebsiteModel;
  7. use think\db\exception\DataNotFoundException;
  8. use think\db\exception\DbException;
  9. use think\db\exception\ModelNotFoundException;
  10. use think\Exception;
  11. /**
  12. * 客服
  13. */
  14. class Servicer extends BaseModel
  15. {
  16. /**
  17. * 表名称
  18. */
  19. const TABLE_NAME = 'servicer';
  20. /**
  21. * 新建客服
  22. * @param $isPlatform
  23. * @param $siteId
  24. * @param $userId
  25. * @param int $online
  26. * @return array
  27. * @throws DataNotFoundException
  28. * @throws DbException
  29. * @throws ModelNotFoundException
  30. */
  31. public function createServicer($isPlatform, $siteId, $userId, $online = 0)
  32. {
  33. // 客服与会员一对一绑定。也就是说,一个用户只能关联一个客服数据
  34. $servicerExists = model('servicer')->getInfo(['user_id' => $userId]);
  35. if ($servicerExists) {
  36. return $this->success($servicerExists);
  37. }
  38. $model = model('servicer')->add([
  39. 'is_platform' => $isPlatform, // 此处一定为平台客服
  40. 'shop_id' => $siteId,
  41. 'user_id' => $userId,
  42. 'create_time' => time(),
  43. 'last_online_time' => time(),
  44. 'delete_time' => 0,
  45. 'client_id' => '',
  46. 'online' => $online,
  47. ]);
  48. return $this->success($model);
  49. }
  50. /**
  51. * 获取在线客服列表
  52. * @param $site_id
  53. * @return array
  54. * @throws DataNotFoundException
  55. * @throws DbException
  56. * @throws ModelNotFoundException
  57. */
  58. public function getOnlineServicers($site_id)
  59. {
  60. $list = model('servicer')->getList(['shop_id' => $site_id, 'online' => 1]);
  61. // if (empty($list) || count($list) == 0) {
  62. // return $this->error('没有在线客服');
  63. // }
  64. return $this->success($list);
  65. }
  66. /**
  67. * 获取会员信息
  68. * @param $where
  69. * @param bool $field
  70. * @return array|\think\Model|null
  71. * @throws DataNotFoundException
  72. * @throws DbException
  73. * @throws ModelNotFoundException
  74. */
  75. public function getServicer($where, $field = true)
  76. {
  77. return model('servicer')->getInfo($where, $field);
  78. }
  79. /**
  80. * 设置客服在线状态
  81. * @param $servicerId
  82. * @param $clientId
  83. * @param bool $online
  84. * @return int
  85. * @throws DbException
  86. */
  87. public function setServicerOnlineStatus($servicerId, $clientId, $online = true)
  88. {
  89. if (!$online) {
  90. model('servicer_member')->update(
  91. ['client_id' => '', 'online' => $online],
  92. [['servicer_id', '=', $servicerId]]
  93. );
  94. }
  95. return model('servicer')->update(
  96. ['client_id' => $online?$clientId:'', 'online' => $online, 'last_online_time' => time()],
  97. [['user_id', '=', $servicerId]]
  98. );
  99. }
  100. /**
  101. * 获取客服列表
  102. * @param array $condition
  103. * @return array
  104. * @throws DataNotFoundException
  105. * @throws DbException
  106. * @throws ModelNotFoundException
  107. */
  108. public function getServicerList($condition = [])
  109. {
  110. $alias = 'sm';
  111. $field = ['id'];
  112. return model('servicer')->getList($condition, $field, '', $alias);
  113. }
  114. /**
  115. * 获取当前客服服务的会员列表
  116. * @param $user_id
  117. * @param int $page
  118. * @param int $limit
  119. * @return mixed|null
  120. * @throws DataNotFoundException
  121. * @throws DbException
  122. * @throws ModelNotFoundException
  123. */
  124. public function getCurrentUserChatMembers($user_id, $page = 1, $limit = 10)
  125. {
  126. $servicer_ids = model('servicer')->getColumn(['user_id' => $user_id], 'id');
  127. if (empty($servicer_ids)) {
  128. return null;
  129. }
  130. $alias = 'sm';
  131. $field = ['sm.id', 'sm.member_id', 'sm.servicer_id', 'sm.member_name', 'sm.online', 'sm.create_time', 'sm.headimg'];
  132. $condition = ['sm.servicer_id', 'in', $servicer_ids];
  133. $order = ['id' => 'desc'];
  134. return model('servicer')->pageList($condition, $field, $order, $page, 10, $alias, [], null, $limit);
  135. }
  136. /**
  137. * 删除客服
  138. * @param $servicerId
  139. * @return array
  140. * @throws DbException
  141. */
  142. public function delServicer($servicerId)
  143. {
  144. $del = model('servicer')->delete(['id' => $servicerId]);
  145. if ($del) {
  146. return $this->success();
  147. }
  148. return $this->error();
  149. }
  150. /**
  151. * 为当前会员匹配一个客服人员
  152. * @param $site_id
  153. * @param $member_id
  154. * @return array
  155. * @throws DataNotFoundException
  156. * @throws DbException
  157. * @throws ModelNotFoundException
  158. */
  159. public function getUsefulServicer($site_id, $member_id)
  160. {
  161. /**
  162. * 目前采用的是最闲优先匹配原则
  163. */
  164. $condition = [['online', '=', 1], ['shop_id', '=', $site_id]];
  165. $list = model('servicer')->getList($condition, 'user_id');
  166. if(!empty($list)){
  167. foreach ($list as &$item){
  168. $item_condition = [
  169. ['servicer_id', '=', $item['user_id']],
  170. ['online', '=', 1]
  171. ];
  172. $item_count = model('servicer_member')->getCount($item_condition);
  173. $item['chat_count'] = $item_count;//正在聊天的会员数
  174. $condition_sd = [['member_id', '=', $member_id], ['type', '=', 1], ['servicer_id', 'in', array_column($list, 'user_id')]];
  175. $info = model('servicer_dialogue')->getFirstData($condition_sd, 'servicer_id', 'create_time desc');
  176. $item['last_count'] = !empty($info['servicer_id']) && $info['servicer_id']==$item['user_id'] ? 1:0;
  177. }
  178. }
  179. array_multisort(array_column($list,'last_count'),SORT_ASC,$list);
  180. array_multisort(array_column($list,'chat_count'),SORT_ASC,$list);
  181. return $list;
  182. }
  183. /**
  184. * 获取客服列表
  185. * @param array $condition
  186. * @param int $page
  187. * @param int $page_size
  188. * @param string $order
  189. * @param bool $field
  190. * @param string $alias
  191. * @param array $join
  192. * @return array
  193. */
  194. public function getPageList(array $condition = [], $page = 1, $page_size = PAGE_LIST_ROWS, $order = 'id desc', $field = true, $alias = '', $join = [])
  195. {
  196. $res = model(self::TABLE_NAME)->pageList($condition, $field, $order, $page, $page_size, $alias, $join);
  197. return $this->success($res);
  198. }
  199. /**
  200. * 添加客服
  201. * @param array $data
  202. * @param array $params
  203. * @return array
  204. */
  205. public function add(array $data, array $params)
  206. {
  207. if (empty($data) || empty($params)) {
  208. return $this->error('', 'PARAMETER_ERROR');
  209. }
  210. model(self::TABLE_NAME)->startTrans();
  211. try {
  212. $user_model = new UserModel();
  213. $res = $user_model->addUser($data, 1);
  214. if ($res['code'] < 0) {
  215. model(self::TABLE_NAME)->rollback();
  216. return $res;
  217. }
  218. $user_info = $res['data'];
  219. $res = model(self::TABLE_NAME)->add(array_merge($params, [
  220. 'shop_id' => 1,
  221. 'user_id' => $user_info,
  222. 'create_time' => time(),
  223. ]));
  224. model(self::TABLE_NAME)->commit();
  225. return $this->success($res);
  226. } catch (\Exception $e) {
  227. model(self::TABLE_NAME)->rollback();
  228. return $this->error('', '操作异常:' . $e->getMessage());
  229. }
  230. }
  231. /**
  232. * 编辑客服
  233. * @param array $data
  234. * @param array $condition
  235. * @param array $params
  236. * @return array
  237. */
  238. public function edit(array $data, array $condition, array $params = [])
  239. {
  240. if (empty($data)) {
  241. return $this->error('', 'PARAMETER_ERROR');
  242. }
  243. $user_model = new UserModel();
  244. $user_info = $user_model->getUserInfo($condition)['data'];
  245. if (empty($user_info)) {
  246. return $this->error('', '客服不存在');
  247. }
  248. model(self::TABLE_NAME)->startTrans();
  249. try {
  250. $res = $user_model->editUser($data, $condition);
  251. if ($res['code'] < 0) {
  252. model(self::TABLE_NAME)->rollback();
  253. return $res;
  254. }
  255. if (!empty($params)) {
  256. model(self::TABLE_NAME)->update($params, [['shop_id', '=', $user_info['site_id']], ['user_id', '=', $user_info['uid']]]);
  257. }
  258. model(self::TABLE_NAME)->commit();
  259. return $this->success($res);
  260. } catch (\Exception $e) {
  261. model(self::TABLE_NAME)->rollback();
  262. return $this->error('', '操作异常:' . $e->getMessage());
  263. }
  264. }
  265. /**
  266. * 删除客服
  267. * @param $site_id
  268. * @param $uid
  269. * @return array
  270. */
  271. public function delete($site_id, $uid)
  272. {
  273. $condition = [
  274. ['site_id', '=', $site_id],
  275. ['uid', '=', $uid],
  276. ['app_module', '=', 'servicer']
  277. ];
  278. $user_model = new UserModel();
  279. $user_info = $user_model->getUserInfo($condition)['data'];
  280. if (empty($user_info)) {
  281. return $this->error('', '客服不存在');
  282. }
  283. model(self::TABLE_NAME)->startTrans();
  284. try {
  285. $res = $user_model->deleteUser($condition);
  286. if ($res['code'] < 0) {
  287. model(self::TABLE_NAME)->rollback();
  288. return $res;
  289. }
  290. $res = model(self::TABLE_NAME)->delete([['shop_id', '=', $site_id], ['user_id', '=', $uid]]);
  291. model(self::TABLE_NAME)->commit();
  292. return $this->success($res);
  293. } catch (\Exception $e) {
  294. model(self::TABLE_NAME)->rollback();
  295. return $this->error('', '操作异常:' . $e->getMessage());
  296. }
  297. }
  298. /**
  299. * 获取信息
  300. * @param array $condition
  301. * @param bool $field
  302. * @return array
  303. */
  304. public function getInfo($condition = [], $field = true)
  305. {
  306. $info = model(self::TABLE_NAME)->getInfo($condition, $field);
  307. return $this->success($info);
  308. }
  309. /**
  310. * 获取客服详情
  311. * @param array $condition
  312. * @param bool $field
  313. * @return array
  314. */
  315. public function getDetail($condition = [], $field = true)
  316. {
  317. $info = $this->getInfo($condition, $field)['data'];
  318. if (!empty($info)) {
  319. $user_model = new UserModel();
  320. $info['user_info'] = $user_model->getUserInfo([['uid', '=', $info['user_id']]])['data'];
  321. }
  322. return $this->success($info);
  323. }
  324. /**
  325. * 处理客服信息
  326. * @param array $condition
  327. * @param $site_id
  328. * @return array
  329. */
  330. public function handleServicerInfo(array $condition, $site_id)
  331. {
  332. $res = [
  333. 'nickname' => '',
  334. 'avatar' => '',
  335. ];
  336. if (empty($condition)) {
  337. $info = [];
  338. } else {
  339. $info = $this->getInfo($condition, 'nickname,avatar')['data'];
  340. }
  341. return $info;
  342. }
  343. /**
  344. * 获取列表
  345. * @param array $condition
  346. * @param bool $field
  347. * @param string $order
  348. * @param string $alias
  349. * @param array $join
  350. * @param string $group
  351. * @param null $limit
  352. * @return array
  353. */
  354. public function getList($condition = [], $field = true, $order = 'id desc', $alias = '', $join = [], $group = '', $limit = null)
  355. {
  356. $res = model(self::TABLE_NAME)->getList($condition, $field, $order, $alias, $join, $group, $limit);
  357. return $this->success($res);
  358. }
  359. /**
  360. * 获取在线客服列表
  361. * @param array $condition
  362. * @param string $field
  363. * @param string $order
  364. * @return array
  365. */
  366. public function getOnlineList(array $condition, $field = 'user_id', $order = 'id desc')
  367. {
  368. $res = $this->getList(array_merge($condition, [['online', '=', 1]]), $field, $order);
  369. return $res;
  370. }
  371. /**
  372. * 分配客服
  373. * @param array $condition
  374. * @return array
  375. */
  376. public function assigning(array $condition)
  377. {
  378. $servicer_list = $this->getOnlineList($condition)['data'];
  379. $data = [];
  380. foreach ($servicer_list as $val) {
  381. $data[] = [
  382. 'user_id' => $val['user_id'],
  383. 'chat_count' => model('servicer_member')->getCount([
  384. ['servicer_id', '=', $val['user_id']],
  385. ['online', '=', 1],
  386. ])
  387. ];
  388. }
  389. if (!empty($data)) {
  390. // 按照服务的会员人数最少的优先分配
  391. $sort_data = array_column($data, 'chat_count');
  392. array_multisort($sort_data, SORT_ASC, $data);
  393. }
  394. return $data;
  395. }
  396. }