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; } }