You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
zhishifufei_php/application/kefu/services/KefuChatService.php

383 lines
14 KiB

10 months ago
<?php
// +----------------------------------------------------------------------
// | 天诚科技 [ 刘海东 17600099397赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.tczxkj.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 该系统并不是自由软件,未经许可不能去掉相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
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;
}
}