| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176 |
- <?php
- declare (strict_types = 1);
- namespace app\model\api;
- use library\basic\BaseModel;
- use library\traits\ModelTrait;
- use think\Model;
- /**
- * 用户会话关系模型
- * @mixin \think\Model
- */
- class ChatUserRelation extends BaseModel
- {
- use ModelTrait;
-
- protected $name = 'chat_user_relation';
-
- // 未扣次数
- const NOT_DEDUCT = 0;
- // 已扣次数
- const IS_DEDUCT = 1;
-
- /**
- * 获取或创建会话关系
- * @param int $userId 用户ID
- * @param int $toUserId 对方用户ID
- * @return self|null
- */
- public static function getOrCreate(int $userId, int $toUserId): ?self
- {
- // 确保 userId < toUserId,保持一致性
- if ($userId > $toUserId) {
- [$userId, $toUserId] = [$toUserId, $userId];
- }
-
- $relation = self::where('user_id', $userId)
- ->where('to_user_id', $toUserId)
- ->find();
-
- if (!$relation) {
- $relation = self::create([
- 'user_id' => $userId,
- 'to_user_id' => $toUserId,
- 'is_deduct' => self::NOT_DEDUCT,
- 'create_time' => time(),
- 'update_time' => time(),
- ]);
- }
-
- return $relation;
- }
-
- /**
- * 检查是否已扣次数
- * @param int $userId 用户ID
- * @param int $toUserId 对方用户ID
- * @return bool
- */
- public static function isDeducted(int $userId, int $toUserId): bool
- {
- // 确保 userId < toUserId
- if ($userId > $toUserId) {
- [$userId, $toUserId] = [$toUserId, $userId];
- }
-
- $relation = self::where('user_id', $userId)
- ->where('to_user_id', $toUserId)
- ->find();
-
- return $relation && $relation->is_deduct == self::IS_DEDUCT;
- }
-
- /**
- * 标记已扣次数
- * @param int $userId 用户ID
- * @param int $toUserId 对方用户ID
- * @return bool
- */
- public static function markDeducted(int $userId, int $toUserId): bool
- {
- // 确保 userId < toUserId
- if ($userId > $toUserId) {
- [$userId, $toUserId] = [$toUserId, $userId];
- }
-
- return self::where('user_id', $userId)
- ->where('to_user_id', $toUserId)
- ->update([
- 'is_deduct' => self::IS_DEDUCT,
- 'update_time' => time(),
- ]) !== false;
- }
-
- /**
- * 获取用户的所有会话列表
- * @param int $userId 用户ID
- * @return array
- */
- public static function getUserSessions(int $userId): array
- {
- $relations = self::where('user_id', $userId)
- ->whereOr('to_user_id', $userId)
- ->order('update_time desc')
- ->select();
-
- $sessions = [];
- foreach ($relations ?: [] as $relation) {
- // 确定对方用户ID
- $otherUserId = $relation->user_id == $userId ? $relation->to_user_id : $relation->user_id;
-
- // 获取对方用户信息
- $user = User::find($otherUserId);
- if (!$user) continue;
-
- // 获取最新一条聊天记录
- $lastRecord = self::getLastRecord($userId, $otherUserId);
-
- // 获取未读消息数
- $unreadCount = ChatRecord::getUnreadCount($userId, $otherUserId);
-
- $sessions[] = [
- 'id' => $relation->id,
- 'user_id' => $otherUserId,
- 'nickname' => $user->nickname ?? '',
- 'avatar' => $user->avatar ?? '',
- 'last_message' => $lastRecord['content'] ?? '',
- 'last_message_time' => $lastRecord['create_time'] ?? $relation->update_time,
- 'unread_count' => $unreadCount,
- 'is_deduct' => $relation->is_deduct,
- ];
- }
-
- return $sessions;
- }
-
- /**
- * 获取最新聊天记录
- * @param int $userId 用户ID
- * @param int $toUserId 对方用户ID
- * @return array|null
- */
- protected static function getLastRecord(int $userId, int $toUserId): ?array
- {
- $record = ChatRecord::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);
- });
- })
- ->order('create_time desc')
- ->find();
-
- return $record ? $record->toArray() : null;
- }
-
- /**
- * 删除会话关系
- * @param int $userId 用户ID
- * @param int $toUserId 对方用户ID
- * @return bool
- */
- public static function deleteSession(int $userId, int $toUserId): bool
- {
- // 确保 userId < toUserId
- if ($userId > $toUserId) {
- [$userId, $toUserId] = [$toUserId, $userId];
- }
-
- return self::where('user_id', $userId)
- ->where('to_user_id', $toUserId)
- ->delete() !== false;
- }
- }
|