| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- <?php
- namespace bizMall\message\services;
- use bizHd\custom\classes\HdClass;
- use bizMall\base\services\BaseService;
- use bizMall\message\classes\ChatClass;
- use bizMall\shop\classes\ShopClass;
- use bizMall\user\services\UserService;
- use common\components\arrayUtil;
- use common\components\imgUtil;
- use Yii;
- use yii\helpers\ArrayHelper;
- 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($sjId)
- {
- $userIdList = [12536630, 12536631, 12536632, 12536633, 12536634, 12536635];
- $userId = $userIdList[array_rand($userIdList)];
- self::addRecentlyUser($sjId, $userId);
-
- $cacheKey = ChatClass::getRecentlyUserKey($sjId);
- //返回有序集合,从高分到低分排序
- $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 getChatHistory($roomName)
- {
- if (empty($roomName)) {
- return [];
- }
- try {
- $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 $userId
- * @return array|\yii\db\ActiveRecord[]
- */
- public static function getLatestUsers($userId)
- {
- $cacheKey = ChatClass::getLatestUsersKey($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]['shopId'] = $val;
- } else {
- $arr[$i]['time'] = $val;
- $i++;
- }
- }
- $userData = [];
- //组合出最后聊天时间和未读消息数
- foreach ($arr as $val) {
- $shopId = $val['shopId'];
- $float = floatval($val['time']);
- $decimalPart = $float - floor($float);
- $unReadNum = intval($decimalPart * 10000 + 0.5); // 加0.5 -- 使用四舍五入来处理浮点数精度问题
- $time = intval($val['time']);
- $date = date("Y-m-d H:i", $time);
- $userData[$shopId] = ['time' => $date, 'unReadNum' => $unReadNum];
- }
- $ids = array_column($arr, 'shopId');
- $where = [];
- $where['userId'] = $userId;
- $where['delStatus'] = 0;
- $hdList = HdClass::getAllByCondition($where,'inTurn DESC, addTime DESC', 'id, customId, shopId');
- // 生成以 shopId 为键的新数组
- $hdListByShopId = ArrayHelper::index($hdList, 'shopId');
- $shopList = ShopClass::getByIds($ids, null, null, 'id, avatar, shopName, merchantName');
- foreach ($shopList as $key => $shop) {
- $shopId = $shop['id'];
- $shopList[$key]['unReadNum'] = isset($userData[$shopId]['unReadNum']) ? $userData[$shop['id']]['unReadNum'] : 0;
- $shopList[$key]['chatTime'] = isset($userData[$shopId]['time']) ? $userData[$shop['id']]['time'] : 0;
- $shopList[$key]['customId'] = isset($hdListByShopId[$shopId]['customId']) ? $hdListByShopId[$shop['id']]['customId'] : 0;
- $shopList[$key]['hdId'] = $hdListByShopId[$shopId]['id'];
- $shopList[$key]['avatar'] = imgUtil::groupImg($shop['avatar']) . "?x-oss-process=image/resize,m_fill,h_130,w_130";
- }
- $shopList = arrayUtil::arraySort($shopList, 'chatTime', SORT_DESC);
- return array_values($shopList);
- }
- /**
- * @param int $userId 用户id
- * @param string $unit 单位分:个数(person)消息(message)
- * @return int
- */
- public static function getUnReadMsgCount($userId, $unit='person')
- {
- $cacheKey = ChatClass::getLatestUsersKey($userId);
- //返回有序集合,从高分到低分排序
- $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]['sId'] = $val;//shopId
- } else {
- $arr[$i]['score'] = $val;
- $i++;
- }
- }
- $msgCount = 0;
- foreach ($arr as $val) {
- $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;
- }
- }
|