| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273 |
- <?php
- namespace bizHd\message\services;
- use bizHd\base\services\BaseService;
- use bizHd\custom\classes\CustomClass;
- use bizHd\message\classes\ChatClass;
- use bizHd\user\classes\UserClass;
- use bizHd\user\services\UserService;
- use common\components\arrayUtil;
- use common\components\imgUtil;
- use Yii;
- class ChatService extends BaseService
- {
- //新增未读消息数
- public static function addUnreadNum($userId)
- {
- $key = ChatClass::getUnreadNumKey($userId);
- Yii::$app->redis->executeCommand('INCRBY', [$key, 1]);
- }
- //新增未回复客户 ssh 2019.12.29
- public static function addUnReplyUser($sjId, $userId)
- {
- $now = time();
- $cacheKey = ChatClass::getUnReplyUserKey($sjId);
- Yii::$app->redis->executeCommand('ZADD', [$cacheKey, $now, "{$userId}"]);
- }
- //取未回复客户列表 ssh 2019.12.29
- public static function getUnReplyUserList($sjId)
- {
- $cacheKey = ChatClass::getUnReplyUserKey($sjId);
- $return = Yii::$app->redis->executeCommand('ZREVRANGE', [$cacheKey, 0, -1, 'WITHSCORES']);//返回有序集合,从高分到低分排序
- if (empty($return)) {
- return [];
- }
- $list = [];
- $i = 0;
- $arr = [];
- foreach ($return as $key => $val) {
- if ($key % 2 == 0) {
- $arr[$i]['value'] = $val;
- } else {
- $arr[$i]['key'] = $val;
- $i++;
- }
- }
- foreach ($arr as $key => $val) {
- $list[$val['key']] = $val['value'];
- }
- return $list;
- }
- //新增最近联系人
- public static function addRecentlyUser($sjId, $userId)
- {
- $now = time();
- $cacheKey = ChatClass::getRecentlyUserKey($sjId);
- //删除10天前的联系人
- $max = $now - 86400 * 10;
- Yii::$app->redis->executeCommand('ZREMRANGEBYSCORE', [$cacheKey, 0, $max]);
- Yii::$app->redis->executeCommand('ZADD', [$cacheKey, $now, "{$userId}"]);
- }
- //取最近联系人 ssh 2019.12.29
- public static function getRecentlyUserList($mainId)
- {
- $userIdList = [12536630, 12536631, 12536632, 12536633, 12536634, 12536635];
- $userId = $userIdList[array_rand($userIdList)];
- self::addRecentlyUser($mainId, $userId);
- $cacheKey = ChatClass::getRecentlyUserKey($mainId);
- //返回有序集合,从高分到低分排序
- $return = Yii::$app->redis->executeCommand('ZREVRANGE', [$cacheKey, 0, -1, 'WITHSCORES']);
- if (empty($return)) {
- return [];
- }
- $i = 0;
- $arr = [];
- foreach ($return as $key => $val) {
- if ($key % 2 == 0) {
- $arr[$i]['userId'] = $val;
- } else {
- $arr[$i]['time'] = $val;
- $i++;
- }
- }
- $userData = [];
- //组合出最后聊天时间和未读消息数
- foreach ($arr as $val) {
- $userId = $val['userId'];
- $time = $val['time'];
- $num = ChatClass::getUnreadNum($userId);
- $date = date("m-d H:i", $time);
- if (date("Ymd") == date("Ymd", $time)) {
- $date = date("H:i", $time);
- }
- $userData[$userId] = ['time' => $date, 'unReadNum' => $num];
- }
- $ids = array_column($arr, 'userId');
- $infoList = UserService::getUserByIds($ids);
- foreach ($infoList as $userId => $info) {
- $infoList[$userId]['unReadNum'] = isset($userData[$userId]['unReadNum']) ? $userData[$userId]['unReadNum'] : 0;
- $infoList[$userId]['chatTime'] = isset($userData[$userId]['time']) ? $userData[$userId]['time'] : date("m-d H:i", $info['visitTime']);
- }
- return array_values($infoList);
- }
- //保存消息记录 ssh 2019.12.29
- public static function saveMessage($messageList, $userId)
- {
- //商家的消息,ourSelf表示自己的消息 themSelf表示对方的消息
- $now = time();
- $cacheKey = ChatClass::getMessageKey($userId);
- //删除15天前的已读消息
- $max = $now - 86400 * 16;
- Yii::$app->redis->executeCommand('ZREMRANGEBYSCORE', [$cacheKey, 0, $max]);
- foreach ($messageList as $message) {
- Yii::$app->redis->executeCommand('ZADD', [$cacheKey, $now, json_encode($message)]);
- }
- //self::getMessageList($userId);
- }
- //取消息记录 ssh 2019.12.29
- public static function getMessageList($userId)
- {
- $cacheKey = ChatClass::getMessageKey($userId);
- //返回有序集合,从高分到低分排序
- $return = Yii::$app->redis->executeCommand('ZREVRANGE', [$cacheKey, 0, -1, 'WITHSCORES']);
- if (empty($return)) {
- return [];
- }
- $i = 0;
- $arr = [];
- foreach ($return as $key => $val) {
- if ($key % 2 == 0) {
- $arr[$i]['message'] = $val;
- } else {
- $arr[$i]['time'] = $val;
- $i++;
- }
- }
- $arr = arrayUtil::arraySort($arr, 'time');
- $data = [];
- foreach ($arr as $val) {
- $message = $val['message'];
- $data[] = json_decode($message);
- }
- return $data;
- }
- // ------------------------------------------------ 以下是新增的聊天方法 ------------------------------------------------
- //最近聊天人(人:可能是客户,也可能是商家)
- public static function getLatestUsers($shopId)
- {
- $cacheKey = ChatClass::getLatestUsersKey($shopId);
- //返回有序集合,从高分到低分排序
- $return = Yii::$app->redis->executeCommand('ZREVRANGE', [$cacheKey, 0, -1, 'WITHSCORES']);
- if (empty($return)) {
- return [];
- }
- $i = 0;
- $arr = [];
- foreach ($return as $key => $val) {
- if ($key % 2 == 0) {
- $arr[$i]['cId'] = $val;
- } else {
- $arr[$i]['score'] = $val;
- $i++;
- }
- }
- $userData = [];
- //组合出最后聊天时间和未读消息数
- foreach ($arr as $val) {
- $customId = $val['cId'];
- $score = floatval($val['score']);
- $decimalPart = $score - floor($score);
- $unReadNum = intval($decimalPart * 10000 + 0.5);// 加0.5 -- 使用四舍五入来处理浮点数精度问题
- $time = intval($val['score']);
- $date = date("Y-m-d H:i", $time);
- $userData[$customId] = ['time' => $date, 'unReadNum' => $unReadNum];
- }
- $ids = array_column($arr, 'cId');
- $infoList = CustomClass::getByIds($ids, null, null, 'id,name,mobile,avatar,shopId,userId');
- foreach ($infoList as $customId => $info) {
- $infoList[$customId]['unReadNum'] = $userData[$info['id']]['unReadNum'] ?? 0;
- $infoList[$customId]['chatTime'] = $userData[$info['id']]['time'] ?? 0;
- //头像
- $shortAvatar = $info['avatar'] ?? '';
- $smallAvatar = imgUtil::groupImg($shortAvatar) . "?x-oss-process=image/resize,m_fill,h_130,w_130";
- $infoList[$customId]['shortAvatar'] = $shortAvatar;
- $infoList[$customId]['smallAvatar'] = $smallAvatar;
- }
- $infoList = arrayUtil::arraySort($infoList, 'chatTime', SORT_DESC);
- return array_values($infoList);
- }
- public static function getChatHistory($roomName)
- {
- if (empty($roomName)) {
- return [];
- }
- try {
- $re = Yii::$app->redis;
- $list = Yii::$app->redis->executeCommand('LRANGE', [$roomName, 0, -1]);
- if (empty($list)) {
- return [];
- }
- $result = [];
- foreach ($list as $item) {
- $decoded = json_decode($item, true);
- $struct = (json_last_error() === JSON_ERROR_NONE) ? $decoded : $item;
- $content = $struct['content'];
- $message = json_decode($content, true);
- $result[] = json_decode($message['message'], true);
- }
- return $result;
- } catch (\Throwable $e) {
- Yii::error('getChatHistory redis error: ' . $e->getMessage(), __METHOD__);
- return [];
- }
- }
- /**
- * @param int $shopId 门店id
- * @param string $unit 单位分:个数(person)消息(message)
- * @return int
- */
- public static function getUnReadMsgCount($shopId, $unit = 'person')
- {
- $cacheKey = ChatClass::getLatestUsersKey($shopId);
- //返回有序集合,从高分到低分排序
- $return = Yii::$app->redis->executeCommand('ZREVRANGE', [$cacheKey, 0, -1, 'WITHSCORES']);
- if (empty($return)) {
- return 0;
- }
- $i = 0;
- $arr = [];
- foreach ($return as $key => $val) {
- if ($key % 2 == 0) {
- $arr[$i]['cId'] = $val;//customerId
- } else {
- $arr[$i]['score'] = $val;
- $i++;
- }
- }
- $msgCount = 0;
- foreach ($arr as $val) {
- //$customId = $val['cId'];
- $score = floatval($val['score']);
- $decimalPart = $score - floor($score);
- $unReadNum = intval($decimalPart * 10000 + 0.5); // 加0.5 -- 使用四舍五入来处理浮点数精度问题
- //根据未读消息数的单位进行计算总数
- if ($unit == 'person') {
- $msgCount += ($unReadNum >= 1 ? 1 : 0);
- } else if ($unit == 'message') {
- $msgCount += $unReadNum;
- }
- }
- return $msgCount;
- }
- }
|