// +---------------------------------------------------------------------- namespace app\kefu\services; use app\kefu\controller\AuthController; use app\kefu\model\KefuModel; use service\FormBuilder as Form; use service\JsonService as Json; use service\UploadService as Upload; use think\exception\ValidateException; use think\Request; use think\Url; use app\admin\model\article\ArticleCategory as ArticleCategoryModel; use app\admin\model\article\Article as ArticleModel; use think\Session; use service\JwtService; use app\kefu\model\KefuChatLogModel; use app\kefu\model\KefuUserRecordModel; use app\admin\model\user\User as UserModel; use app\admin\model\special\Special as SpecialModel; use app\admin\model\special\SpecialTask; use app\admin\model\store\StoreProduct; use app\admin\model\download\DataDownload; use app\wap\model\material\DataDownloadOrder; use service\BaseService; use app\admin\model\order\StoreOrder as StoreOrderModel; use app\admin\model\order\StoreOrderCartInfo; use think\Log; class KefuChatService extends BaseService { const MSN_TYPE_TEXT = 1; const MSN_TYPE_EMOJI = 2; const MSN_TYPE_IMG = 3; const MSN_TYPE_VOICE = 4; const MSN_TYPE_GOOD = 5; const MSN_TYPE_ORDER = 21; const MSN_TYPE_TRANSFER = 24; private $model; public function __construct() { $this->model = new KefuChatLogModel; } public function getServiceList($where) { return (new KefuModel)->where($where)->select()->toArray(); } public function tidyChat(array $list) { $guestUserInfo = null; $kefuUserInfo = null; $specialModel = (new SpecialModel); $specialTaskModel = (new SpecialTask); $storeProductModel = (new StoreProduct); $dataDownloadModel = (new DataDownload); $storeOrderModel = (new StoreOrderModel); $storeOrderInfoModel = (new StoreOrderCartInfo); $dataDownloadOrderModel = (new DataDownloadOrder); foreach ($list as &$item) { if ($item['is_kefu_send']) { // 客服发送的消息 if (is_null($kefuUserInfo)) { $kefuUserInfo = KefuModel::get($item['uid']); } if (!is_null($kefuUserInfo)) { $item['avatar'] = $kefuUserInfo->avatar; } } else { // 用户发送的消息 if (is_null($guestUserInfo)) { $guestUserInfo = UserModel::get($item['uid']); } if (!is_null($guestUserInfo)) { $item['avatar'] = $guestUserInfo->avatar; } } if ($item['msn_type'] == self::MSN_TYPE_GOOD && $item['good_type'] > 0) { // 商品类型消息 $type = $item['good_type']; if ($type == 1) { // 课程商品 $info = $specialModel->field('id, fake_sales as sales, image, banner as slider_image, abstract as description, title as store_name, money as price, member_money as vip_price')->find($item['msn']); $info->type_name = "课程"; $info->stock = "0"; $item['productInfo'] = $info; } else if ($type == 2) { // 商城商品 $info = $storeProductModel->field('id, sales, stock, image, slider_image, description, store_name, price, ot_price, vip_price')->find($item['msn']); $info->slider_image = json_decode($info->slider_image); $info->type_name = "商品"; $item['productInfo'] = $info; } else if ($type == 3) { // 会员商品 } else if ($type == 4) { // 报名商品 } else if ($type == 5) { // 资料商品 $info = $dataDownloadModel->field('id, sales, image, abstract as description, title as store_name, money as price, member_money as vip_price')->find($item['msn']); $info->slider_image = [$info->image]; $info->type_name = "资料"; $info->stock = "0"; $item['productInfo'] = $info; } else if ($type == 6) { // 考试商品 } else if ($type == 7) { // 充值商品 } else if ($type == 8) { // 素材类型 $info = $specialTaskModel->field('id, image, detail as description, title as store_name')->find($item['msn']); $info->slider_image = [$info->image]; $info->sales = 0; $info->price = 0; $info->vip_price = 0; $info->type_name = "资料"; $info->stock = "0"; $item['productInfo'] = $info; } } else if ($item['msn_type'] == self::MSN_TYPE_ORDER && $item['order_type'] > 0) { // 订单类型消息 $type = $item['order_type']; if ($type == 1) { // 课程订单 $orderInfo = $storeOrderModel->field('id, order_id, real_name, user_phone, user_address, cart_id, total_num, total_price, total_postage, pay_price, paid, pay_time, pay_type, add_time, status, refund_status ,delivery_type, delivery_id, coupon_price, pay_postage, spread_uid')->find($item['msn']); $specialInfo = $specialModel->find($orderInfo->cart_id); $orderInfo->cartInfo = [ [ 'productInfo' => [ 'image' => $specialInfo->image, 'id' => $specialInfo->id, 'store_name' => $specialInfo->title, 'price' => $specialInfo->money ] ] ]; $orderInfo->type_name = "课程"; $item['orderInfo'] = $orderInfo; } else if ($type == 2) { // 商城商品订单 $orderInfo = $storeOrderModel->field('id, order_id, real_name, user_phone, user_address, cart_id, total_num, total_price, total_postage, pay_price, paid, pay_time, pay_type, add_time, status, refund_status, delivery_type, delivery_id, coupon_price, pay_postage, spread_uid')->find($item['msn']); $orderCartInfo = $storeOrderInfoModel->where('oid', $item['msn'])->select()->each(function ($item) { $item->cart_info = json_decode($item->cart_info); })->toArray(); $orderInfo->cartInfo = array_column($orderCartInfo, "cart_info"); $orderInfo->type_name = "商城商品"; $item['orderInfo'] = $orderInfo; } else if ($type == 3) { // 会员商品订单 } else if ($type == 4) { // 报名商品订单 } else if ($type == 5) { // 资料订单 $orderInfo = $dataDownloadOrderModel->field("id, order_id, data_id, total_num, total_price, pay_price, paid, pay_time, pay_type,status, refund_status, add_time")->find($item['msn']); $dataInfo = $dataDownloadModel->find($orderInfo->data_id); $orderInfo->cartInfo = [ [ 'productInfo' => [ 'image' => $dataInfo->image, 'id' => $dataInfo->id, 'store_name' => $dataInfo->title, 'price' => $dataInfo->money ] ] ]; $orderInfo->type_name = "资料"; $item['orderInfo'] = $orderInfo; } else if ($type == 6) { // 考试订单 } else if ($type == 7) { // 充值订单 } $item['orderInfo']->add_time = date("Y/m/d H:i:s", $item['orderInfo']->add_time); $item['orderInfo']->pay_time = date("Y/m/d H:i:s", $item['orderInfo']->pay_time); if (isset($item['spread_uid']) && $item['spread_uid']) { $spreadUserInfo = UserModel::get($item['spread_uid']); if ($spreadUserInfo) { $item['spread_name'] = $spreadUserInfo->nickname; } } } else if ($item['msn_type'] == self::MSN_TYPE_TRANSFER && $item['msn']) { $kefuInfo = (new KefuModel)->field('id, avatar, nickname')->find($item['msn']); if ($kefuInfo) { $item['kefu_info'] = $kefuInfo; } } } return $list; } public function getChatList($uid, $toUid, $upperId, $is_tourist = 0, $is_kefu_send = 1) { [$page, $limit] = $this->getPageValue(); $result = $this ->model ->where( function ($q) use ($uid, $toUid, $is_tourist, $upperId, $is_kefu_send) { $q->where('is_tourist', $is_tourist); if ($upperId) { $q->where('id', '<', $upperId); } $q->where(function ($q) use ($uid, $toUid, $is_kefu_send) { $q ->where(function ($q) use ($uid, $toUid, $is_kefu_send) { $q->where('uid', $uid) ->where('to_uid', $toUid) ->where('is_kefu_send', $is_kefu_send); }) ->whereOr(function ($q) use ($uid, $toUid, $is_kefu_send) { $q->where('uid', $toUid) ->where('to_uid', $uid) ->where('is_kefu_send', $is_kefu_send ? 0 : 1); }); }); } ) ->limit($limit) ->order('id DESC') ->select() ->toArray(); return array_reverse($this->tidyChat($result)); } public function saveChatLog($msn, $uid, $to_uid, $is_tourist, $is_kefu_send, $msn_type = self::MSN_TYPE_TEXT, $type = 0, $attach_type = 0) { $saveData = compact("msn", "uid", "to_uid", "is_tourist", "is_kefu_send", "msn_type", "type"); $saveData = array_merge($saveData, [ 'add_time' => time() ]); if ($msn_type == self::MSN_TYPE_GOOD) { $saveData['good_type'] = $attach_type; } else if ($msn_type == self::MSN_TYPE_ORDER) { $saveData['order_type'] = $attach_type; } $record = KefuChatLogModel::create($saveData); $record = $this->tidyChat([$record])[0]; $this->saveChatUser($uid, $to_uid, $is_tourist, $msn_type, $msn, $is_kefu_send); return $record; } public function saveChatUser($uid, $to_uid, $is_tourist, $msn_type, $msn, $is_kefu_send) { $where = [ 'user_id' => $uid, 'to_uid' => $to_uid ]; $record = (new KefuUserRecordModel)->where($where)->find(); $avatar = ""; $nickname = ""; if (!$is_kefu_send) { $user = KefuModel::get($to_uid); if ($user) { $avatar = $user->avatar; $nickname = $user->nickname; } } else { $user = UserModel::get($to_uid); if ($user) { $avatar = $user->avatar; $nickname = $user->nickname; } } if ($record) { // 更新 $record->update([ 'message' => $msn, 'message_type' => $msn_type, 'update_time' => time(), 'avatar' => $avatar, 'nickname' => $nickname ], $where); } else { // 保存 KefuUserRecordModel::create([ 'user_id' => $uid, 'to_uid' => $to_uid, 'nickname' => $nickname, 'avatar' => $avatar, 'is_tourist' => $is_tourist, 'add_time' => time(), 'update_time' => time(), 'message' => $msn, 'message_type' => $msn_type, 'is_kefu_send' => $is_kefu_send ]); } } public function getUserSupportInfo($uidTo, $limit, $toUid, $uid,$mer_id) { if (!$toUid && !$mer_id) { // 没有指定客服人员 $serviceInfoList = $this->getServiceList(['status' => 1, 'online' => 1]); if (!count($serviceInfoList)) throw new ValidateException("暂无客服人员在线,请稍后联系"); $kefuIds = array_column($serviceInfoList, "id"); $toUid = (new KefuRecordService)->getLatelyMsgByUid($uid); //如果上次聊天的客不在当前在线客服中,则随机选择一个客服 if (!in_array($toUid, $kefuIds)) { $toUid = 0; } if (!$toUid) { $toUid = $kefuIds[array_rand($kefuIds)] ?: 0; } if (!$toUid) { throw new ValidateException('暂无客服人员在线,请稍后联系'); } } $kefuInfo = KefuModel::get($toUid ? $toUid : $mer_id); if($kefuInfo['online'] == 0){ throw new ValidateException('暂无客服人员在线,请稍后联系'); } $result = [ 'uid' => $toUid ? $toUid : $mer_id, 'nickname' => $kefuInfo->nickname, 'avatar' => $kefuInfo->avatar, 'serviceList' => $this->getChatList($uid, $toUid ? $toUid : $mer_id, $uidTo, 0, 0) ]; return $result; } }