$userId, 'to_user_id' => $toUserId, 'content' => $content, 'type' => $type, 'form_type' => $formType, 'is_read' => self::UNREAD, 'create_time' => time(), ]); } /** * 获取与某用户的聊天记录(分页,按时间正序返回) * @param int $userId 当前用户ID * @param int $toUserId 对方用户ID * @param int $page 页码,第1页为最新消息 * @param int $limit 每页数量 * @return array */ public static function getChatRecords(int $userId, int $toUserId, int $page = 1, int $limit = 20): array { $db = \think\facade\Db::name('chat_record'); $where = function ($query) use ($userId, $toUserId) { $query->where(function ($q) use ($userId, $toUserId) { $q->where('user_id', $userId)->where('to_user_id', $toUserId); })->whereOr(function ($q) use ($userId, $toUserId) { $q->where('user_id', $toUserId)->where('to_user_id', $userId); }); }; // 总记录数 $total = $db->where($where)->count(); // 分页参数矫正 $page = max(1, $page); $limit = max(1, min($limit, 100)); // 限制每页最大100条 // 按时间倒序查最新的一批,拿到后在 PHP 层面反转成正序返回给前端 $data = $db->where($where) ->order('create_time desc') ->page($page, $limit) ->select(); $list = $data ? array_reverse($data->toArray()) : []; // 标记为已读 self::markAsRead($userId, $toUserId); $totalPages = (int)ceil($total / $limit); $hasMore = $page < $totalPages; return [ 'list' => $list, 'total' => $total, 'page' => $page, 'limit' => $limit, 'total_pages' => $totalPages, 'has_more' => $hasMore, ]; } /** * 标记消息为已读 * @param int $userId 当前用户ID * @param int $fromUserId 发送者ID * @return bool */ public static function markAsRead(int $userId, int $fromUserId): bool { $affected = Db::name('chat_record') ->where('user_id', $fromUserId) ->where('to_user_id', $userId) ->where('is_read', 0) ->update(['is_read' => 1]); // @file_put_contents('quanju.txt', $affected."-何意啊333\r\n", 8); // 调试:记录执行的SQL和影响行数 // $sql = Db::name('chat_record')->getLastSql(); // trace('【markAsRead】SQL: ' . $sql . ' | 影响行数: ' . $affected, 'chat_debug'); // return $affected > 0; } /** * 获取未读消息数 * @param int $userId 用户ID * @param int|null $fromUserId 指定发送者(可选) * @return int */ public static function getUnreadCount(int $userId, ?int $fromUserId = null): int { $query = Db::name('chat_record') ->where('to_user_id', $userId) ->where('is_read', 0); if ($fromUserId !== null && $fromUserId > 0) { $query->where('user_id', $fromUserId); } $count = $query->count(); // // 调试:记录执行的SQL和结果 // $sql = Db::name('chat_record')->getLastSql(); // trace('【getUnreadCount】SQL: ' . $sql . ' | 结果: ' . $count, 'chat_debug'); // return $count; } /** * 获取所有未读消息数 * @param int $userId 用户ID * @return int */ public static function getTotalUnreadCount(int $userId): int { $count = Db::name('chat_record') ->where('to_user_id', $userId) ->where('is_read', 0) ->count(); // // 调试:记录执行的SQL和结果 // $sql = Db::name('chat_record')->getLastSql(); // trace('【getTotalUnreadCount】SQL: ' . $sql . ' | 结果: ' . $count, 'chat_debug'); // return $count; } /** * 获取消息类型文本 * @param int $type 类型 * @return string */ public static function getTypeText(int $type): string { $typeMap = [ self::TYPE_TEXT => '文字', self::TYPE_VOICE => '语音', self::TYPE_IMAGE => '图片', ]; return $typeMap[$type] ?? '未知'; } /** * 获取来源类型文本 * @param int $formType 来源类型 * @return string */ public static function getFormTypeText(int $formType): string { $formTypeMap = [ self::FROM_PC => 'PC端', self::FROM_WECHAT => '微信', self::FROM_MINIAPP => '小程序', self::FROM_H5 => 'H5', ]; return $formTypeMap[$formType] ?? '未知'; } }