StoreServiceServices.php 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace app\services\message\service;
  12. use app\dao\service\StoreServiceDao;
  13. use app\services\BaseServices;
  14. use app\services\user\UserServices;
  15. use crmeb\exceptions\AdminException;
  16. use crmeb\services\FormBuilder;
  17. use crmeb\traits\ServicesTrait;
  18. use think\exception\ValidateException;
  19. /**
  20. * 客服
  21. * Class StoreServiceServices
  22. * @package app\services\message\service
  23. * @method getStoreServiceOrderNotice() 获取接受通知的客服
  24. */
  25. class StoreServiceServices extends BaseServices
  26. {
  27. use ServicesTrait;
  28. /**
  29. * 创建form表单
  30. * @var Form
  31. */
  32. protected $builder;
  33. /**
  34. * 构造方法
  35. * StoreServiceServices constructor.
  36. * @param StoreServiceDao $dao
  37. */
  38. public function __construct(StoreServiceDao $dao, FormBuilder $builder)
  39. {
  40. $this->dao = $dao;
  41. $this->builder = $builder;
  42. }
  43. /**
  44. * 获取客服列表
  45. * @param array $where
  46. * @return array
  47. * @throws \think\db\exception\DataNotFoundException
  48. * @throws \think\db\exception\DbException
  49. * @throws \think\db\exception\ModelNotFoundException
  50. */
  51. public function getServiceList(array $where)
  52. {
  53. [$page, $limit] = $this->getPageValue();
  54. $list = $this->dao->getServiceList($where, $page, $limit);
  55. $this->updateNonExistentService(array_column($list, 'uid'));
  56. $count = $this->dao->count($where);
  57. return compact('list', 'count');
  58. }
  59. /**
  60. * @param array $uids
  61. * @return bool
  62. */
  63. public function updateNonExistentService(array $uids = [])
  64. {
  65. if (!$uids) {
  66. return true;
  67. }
  68. /** @var UserServices $services */
  69. $services = app()->make(UserServices::class);
  70. $userUids = $services->getColumn([['uid', 'in', $uids]], 'uid');
  71. $unUids = array_diff($uids, $userUids);
  72. return $this->dao->deleteNonExistentService($unUids);
  73. }
  74. /**
  75. * 创建客服表单
  76. * @param array $formData
  77. * @return mixed
  78. * @throws \FormBuilder\Exception\FormBuilderException
  79. */
  80. public function createServiceForm(array $formData = [])
  81. {
  82. if ($formData) {
  83. $field[] = $this->builder->frameImage('avatar', '客服头像', $this->url('admin/widget.images/index', ['fodder' => 'avatar'], true), $formData['avatar'] ?? '')->icon('ios-add')->width('950px')->height('505px')->modal(['footer-hide' => true]);
  84. } else {
  85. $field[] = $this->builder->frameImage('image', '选择用户', $this->url('admin/system.user/list', ['fodder' => 'image'], true))->icon('ios-add')->width('950px')->height('505px')->modal(['footer-hide' => true])->Props(['srcKey' => 'image']);
  86. $field[] = $this->builder->hidden('uid', 0);
  87. $field[] = $this->builder->hidden('avatar', '');
  88. }
  89. $field[] = $this->builder->input('nickname', '客服名称', $formData['nickname'] ?? '')->col(24)->required();
  90. $field[] = $this->builder->input('phone', '手机号码', $formData['phone'] ?? '')->col(24)->required();
  91. if ($formData) {
  92. $field[] = $this->builder->input('account', '登录账号', $formData['account'] ?? '')->col(24)->required();
  93. $field[] = $this->builder->input('password', '登录密码')->type('password')->col(24)->placeholder('不修改密码请留空');
  94. $field[] = $this->builder->input('true_password', '确认密码')->type('password')->col(24)->placeholder('不修改密码请留空');
  95. } else {
  96. $field[] = $this->builder->input('account', '登录账号')->col(24)->required();
  97. $field[] = $this->builder->input('password', '登录密码')->type('password')->col(24)->required();
  98. $field[] = $this->builder->input('true_password', '确认密码')->type('password')->col(24)->required();
  99. }
  100. $field[] = $this->builder->switches('status', '客服状态', (int)($formData['status'] ?? 1))->appendControl(1, [
  101. // $this->builder->switches('customer', '手机订单管理', $formData['customer'] ?? 0)->falseValue(0)->trueValue(1)->openStr('打开')->closeStr('关闭')->size('large'),
  102. $this->builder->switches('notify', '订单通知', $formData['notify'] ?? 0)->falseValue(0)->trueValue(1)->openStr('打开')->closeStr('关闭')->size('large'),
  103. ])->falseValue(0)->trueValue(1)->openStr('开启')->closeStr('关闭')->size('large');
  104. return $field;
  105. }
  106. /**
  107. * 创建客服获取表单
  108. * @return array
  109. * @throws \FormBuilder\Exception\FormBuilderException
  110. */
  111. public function create()
  112. {
  113. return create_form('添加客服', $this->createServiceForm(), $this->url('/app/wechat/kefu'), 'POST');
  114. }
  115. /**
  116. * 编辑获取表单
  117. * @param int $id
  118. * @return array
  119. * @throws \FormBuilder\Exception\FormBuilderException
  120. */
  121. public function edit(int $id)
  122. {
  123. $serviceInfo = $this->dao->get($id);
  124. if (!$serviceInfo) {
  125. throw new AdminException('数据不存在!');
  126. }
  127. return create_form('编辑客服', $this->createServiceForm($serviceInfo->toArray()), $this->url('/app/wechat/kefu/' . $id), 'PUT');
  128. }
  129. /**
  130. * 获取某人的聊天记录用户列表
  131. * @param int $uid
  132. * @return array|array[]
  133. * @throws \think\db\exception\DataNotFoundException
  134. * @throws \think\db\exception\DbException
  135. * @throws \think\db\exception\ModelNotFoundException
  136. */
  137. public function getChatUser(int $uid)
  138. {
  139. /** @var StoreServiceLogServices $serviceLog */
  140. $serviceLog = app()->make(StoreServiceLogServices::class);
  141. /** @var UserServices $serviceUser */
  142. $serviceUser = app()->make(UserServices::class);
  143. $uids = $serviceLog->getChatUserIds($uid);
  144. if (!$uids) {
  145. return [];
  146. }
  147. return $serviceUser->getUserList(['uid' => $uids], 'nickname,uid,avatar as headimgurl');
  148. }
  149. /**
  150. * 检查用户是否是客服
  151. * @param array $where
  152. * @return bool
  153. * @throws \think\db\exception\DataNotFoundException
  154. * @throws \think\db\exception\DbException
  155. * @throws \think\db\exception\ModelNotFoundException
  156. */
  157. public function checkoutIsService(array $where)
  158. {
  159. return $this->dao->count($where) ? true : false;
  160. }
  161. /**
  162. * 查询聊天记录和获取客服uid
  163. * @param int $uid 当前用户uid
  164. * @param int $uidTo 上翻页id
  165. * @param int $limit 展示条数
  166. * @param int $toUid 客服uid
  167. * @return array
  168. * @throws \think\db\exception\DataNotFoundException
  169. * @throws \think\db\exception\DbException
  170. * @throws \think\db\exception\ModelNotFoundException
  171. */
  172. public function getRecord(int $uid, int $uidTo, int $limit = 10, int $toUid = 0)
  173. {
  174. if (!$toUid) {
  175. $serviceInfoList = $this->getServiceList(['status' => 1, 'online' => 1]);
  176. if (!count($serviceInfoList)) {
  177. throw new ValidateException('暂无客服人员在线,请稍后联系');
  178. }
  179. $uids = array_column($serviceInfoList['list'], 'uid');
  180. if (!$uids) {
  181. throw new ValidateException('暂无客服人员在线,请稍后联系');
  182. }
  183. /** @var StoreServiceRecordServices $recordServices */
  184. $recordServices = app()->make(StoreServiceRecordServices::class);
  185. //上次聊天客服优先对话
  186. $toUid = $recordServices->getLatelyMsgUid(['to_uid' => $uid], 'user_id');
  187. //如果上次聊天的客不在当前客服中从新
  188. if (!in_array($toUid, $uids)) {
  189. $toUid = 0;
  190. }
  191. if (!$toUid) {
  192. $toUid = $uids[array_rand($uids)] ?? 0;
  193. }
  194. if (!$toUid) {
  195. throw new ValidateException('暂无客服人员在线,请稍后联系');
  196. }
  197. }
  198. $userInfo = $this->dao->get(['uid' => $toUid], ['nickname', 'avatar']);
  199. if (!$userInfo) {
  200. /** @var UserServices $userServices */
  201. $userServices = app()->make(UserServices::class);
  202. $userInfo = $userServices->get(['uid' => $toUid], ['nickname', 'avatar']);
  203. if (!$userInfo) {
  204. $userInfo['nickname'] = '';
  205. $userInfo['avatar'] = '';
  206. }
  207. }
  208. /** @var StoreServiceLogServices $logServices */
  209. $logServices = app()->make(StoreServiceLogServices::class);
  210. $result = ['serviceList' => [], 'uid' => $toUid, 'nickname' => $userInfo['nickname'], 'avatar' => $userInfo['avatar']];
  211. $serviceLogList = $logServices->getServiceChatList(['chat' => [$uid, $toUid], 'is_tourist' => 0], $limit, $uidTo);
  212. $result['serviceList'] = array_reverse($logServices->tidyChat($serviceLogList));
  213. return $result;
  214. }
  215. }