Files
crmchat/crmchat/app/services/chat/ChatServiceDialogueRecordServices.php
T
feng0207 9e8186e5d3 修复客服嵌入问题并更新前端构建产物
- 管理端前端设备判定改为按宽高比(嵌入竖屏容器时正确使用手机版布局)
- 统计上报跨源读取 parent.location 报错防护(降级用 referrer)
- 续接会话时校验客服在线,离线不再误入聊天页
- 聊天记录整理与消息发送的用户资料缺失空值防护,避免接口 400
- entrypoint 数据库导入加空库守卫,容器重启/线上更新不再重置数据
2026-09-25 22:15:01 +08:00

236 lines
8.2 KiB
PHP

<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2020 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
namespace app\services\chat;
use app\dao\chat\ChatServiceDialogueRecordDao;
use crmeb\basic\BaseServices;
use think\App;
use think\db\exception\DataNotFoundException;
use think\db\exception\DbException;
use think\db\exception\ModelNotFoundException;
use think\facade\Cache;
/**
* Class ChatServiceDialogueRecordServices
* @package app\services\chat
* @method whereByCount(array $where) 根据条件获取条数
* @method getServiceList(array $where, int $page, int $limit, array $field = ['*']) 获取聊天记录并分页
* @method saveAll(array $data) 插入数据
* @method getMessageNum(array $where) 获取聊天记录条数
* @method getMessageList(array $where, int $page, int $limit) 获取聊天记录列表
* @method getMessageCount(array $where) 获取聊天记录总条数
* @method getMessageOne(array $where) 获取最新的一条数据
* @method int chatCount(string $appid, int $userId) 获取是否用户的聊天记录条数
*/
class ChatServiceDialogueRecordServices extends BaseServices
{
//文本消息类型
const MSN_TYPE_TXT = 1;
//表情消息类型
const MSN_TYPE_EMOT = 2;
//图片消息类型
const MSN_TYPE_IME = 3;
//音频消息类型
const MSN_TYPE_VOICE = 4;
//商品链接消息类型
const MSN_TYPE_GOODS = 5;
//订单信息消息类型
const MSN_TYPE_ORDER = 6;
/**
* 消息类型
* @var array 1=文字 2=表情 3=图片 4=语音 5 = 商品链接 6 = 订单类型
*/
const MSN_TYPE = [
self::MSN_TYPE_TXT,
self::MSN_TYPE_EMOT,
self::MSN_TYPE_IME,
self::MSN_TYPE_VOICE,
self::MSN_TYPE_GOODS,
self::MSN_TYPE_ORDER
];
/**
* ChatServiceDialogueRecordServices constructor.
* @param ChatServiceDialogueRecordDao $dao
*/
public function __construct(ChatServiceDialogueRecordDao $dao)
{
$this->dao = $dao;
}
/**
* @param App $app
* @return $this
*/
public function setApp(App $app)
{
$this->dao->setApp($app);
return $this;
}
/**
* @param array $where
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getDialogueRecord(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getDialogueRecord($where)->with(['user', 'userThis'])->page($page, $limit)->select()->toArray();
$count = $this->dao->getDialogueRecord($where)->count();
/** @var ChatServiceRecordServices $service */
$service = app()->make(ChatServiceRecordServices::class);
/** @var ChatUserServices $userService */
$userService = app()->make(ChatUserServices::class);
$data = [
'record' => $service->count(),
'tourist' => $userService->count(['is_tourist' => 1]),
'user' => $userService->count(['is_tourist' => 0]),
'count' => $this->dao->getDialogueRecord()->count()
];
return compact('list', 'count', 'data');
}
/**
* 获取聊天记录中的uid和to_uid
* @param int $userId
* @return array
*/
public function getChatUserIds(int $userId)
{
$list = $this->dao->getServiceUserUids($userId);
$arr_user = $arr_to_user = [];
foreach ($list as $key => $value) {
array_push($arr_user, $value["user_id"]);
array_push($arr_to_user, $value["to_user_id"]);
}
$userids = array_merge($arr_user, $arr_to_user);
$userids = array_flip(array_flip($userids));
$userids = array_flip($userids);
unset($userids[$userId]);
return array_flip($userids);
}
/**
* 获取某个用户的客服聊天记录
* @param array $where
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getChatLogList(array $where)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getServiceList($where, $page, $limit);
$count = $this->dao->count($where);
return compact('list', 'count');
}
/**
* 获取聊天记录列表
* @param array $where
* @param int $uid
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getChatList(array $where, int $userId)
{
[$page, $limit] = $this->getPageValue();
$list = $this->dao->getServiceList($where, $page, $limit);
return $this->tidyChat($list);
}
/**
* 聊天列表格式化
* @param array $list
* @param int $uid
* @return array
*/
public function tidyChat(array $list)
{
foreach ($list as &$item) {
$item['_add_time'] = $item['add_time'];
$item['add_time'] = strtotime($item['_add_time']);
$item['msn_type'] = (int)$item['msn_type'];
if (!isset($item['nickname'])) {
$item['nickname'] = '';
}
if (!isset($item['avatar'])) {
$item['avatar'] = '';
}
if (!$item['avatar'] && !$item['nickname']) {
// isset 空值防护:chat_user 行缺失时关联为 null,直接取 ['id'] 会抛异常导致整个接口 400
if (isset($item['userThis']['id']) && $item['userThis']['id'] == $item['user_id']) {
$item['nickname'] = $item['userThis']['nickname'] ?? '';
$item['avatar'] = $item['userThis']['avatar'] ?? '';
} else if (isset($item['userTO']['id']) && $item['userTO']['id'] == $item['user_id']) {
$item['nickname'] = $item['userTO']['nickname'] ?? '';
$item['avatar'] = $item['userTO']['avatar'] ?? '';
} else if (isset($item['userTO']['id']) && $item['userTO']['id'] == $item['to_user_id']) {
$item['nickname'] = $item['userTO']['nickname'] ?? '';
$item['avatar'] = $item['userTO']['avatar'] ?? '';
} else if (isset($item['userThis']['id']) && $item['userThis']['id'] == $item['to_user_id']) {
$item['nickname'] = $item['userThis']['nickname'] ?? '';
$item['avatar'] = $item['userThis']['avatar'] ?? '';
}
}
}
return $list;
}
/**
* 获取聊天记录
* @param array $where
* @param int $page
* @param int $limit
* @param bool $isUp
* @return array
* @throws DataNotFoundException
* @throws DbException
* @throws ModelNotFoundException
*/
public function getServiceChatList(array $where, int $limit, int $upperId)
{
return $this->dao->getChatList($where, $limit, $upperId, ['userThis', 'userTO']);
}
/**
* 获取唯一id
* @return float|int|string
* @throws \Exception
*/
public function getSendId()
{
$snowflake = new \Godruoyi\Snowflake\Snowflake();
$is_callable = function ($currentTime) {
$redis = Cache::store('redis');
$swooleSequenceResolver = new \Godruoyi\Snowflake\RedisSequenceResolver($redis->handler());
return $swooleSequenceResolver->sequence($currentTime);
};
//32位
if (PHP_INT_SIZE == 4) {
$id = abs($snowflake->setSequenceResolver($is_callable)->id());
} else {
$id = $snowflake->setStartTimeStamp(strtotime('2020-06-05') * 1000)->setSequenceResolver($is_callable)->id();
}
return $id;
}
}