$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 页码 * @param int $limit 每页数量 * @return array */ public static function getChatRecords(int $userId, int $toUserId, int $page = 1, int $limit = 20): array { $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); }); }; $data = self::where($where) ->order('create_time desc') ->page($page, $limit) ->select(); $total = self::where($where)->count(); // 标记为已读 self::markAsRead($userId, $toUserId); return [ 'list' => $data ? array_reverse($data->toArray()) : [], 'total' => $total, 'page' => $page, 'limit' => $limit, ]; } /** * 标记消息为已读 * @param int $userId 当前用户ID * @param int $fromUserId 发送者ID * @return bool */ public static function markAsRead(int $userId, int $fromUserId): bool { return self::where('user_id', $fromUserId) ->where('to_user_id', $userId) ->where('is_read', self::UNREAD) ->update(['is_read' => self::READ]) !== false; } /** * 获取未读消息数 * @param int $userId 用户ID * @param int|null $fromUserId 指定发送者(可选) * @return int */ public static function getUnreadCount(int $userId, ?int $fromUserId = null): int { $where = [ 'to_user_id' => $userId, 'is_read' => self::UNREAD, ]; if ($fromUserId !== null) { $where['user_id'] = $fromUserId; } return self::where($where)->count(); } /** * 获取所有未读消息数 * @param int $userId 用户ID * @return int */ public static function getTotalUnreadCount(int $userId): int { return self::where('to_user_id', $userId) ->where('is_read', self::UNREAD) ->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] ?? '未知'; } }