hasMany(WebSocketDialogUser::class, 'dialog_id', 'id'); } /** * 删除会话 * @return bool */ public function deleteDialog() { AbstractModel::transaction(function () { WebSocketDialogMsgRead::whereDialogId($this->id)->whereNull('read_at')->update([ 'read_at' => Carbon::now() ]); $this->delete(); }); return true; } /** * 获取对话(同时检验对话身份) * @param $dialog_id * @return self */ public static function checkDialog($dialog_id) { $dialog = WebSocketDialog::find($dialog_id); if (empty($dialog)) { throw new ApiException('对话不存在或已被删除', ['dialog_id' => $dialog_id], -4003); } // $userid = User::userid(); if ($dialog->type === 'group' && $dialog->group_type === 'task') { // 任务群对话校验是否在项目内 $project_id = intval(ProjectTask::whereDialogId($dialog->id)->value('project_id')); if ($project_id > 0) { if (ProjectUser::whereProjectId($project_id)->whereUserid($userid)->exists()) { return $dialog; } } } if (!WebSocketDialogUser::whereDialogId($dialog->id)->whereUserid($userid)->exists()) { throw new ApiException('不在成员列表内'); } return $dialog; } /** * 格式化对话 * @param WebSocketDialog $dialog * @param int $userid 会员ID * @return self|null */ public static function formatData(WebSocketDialog $dialog, $userid) { if (empty($dialog)) { return null; } // 最后消息 $last_msg = WebSocketDialogMsg::whereDialogId($dialog->id)->orderByDesc('id')->first(); $dialog->last_msg = $last_msg; // 未读信息 $dialog->unread = WebSocketDialogMsgRead::whereDialogId($dialog->id)->whereUserid($userid)->whereReadAt(null)->count(); // 对话人数 $builder = WebSocketDialogUser::whereDialogId($dialog->id); $dialog->people = $builder->count(); // 对方信息 $dialog->dialog_user = null; $dialog->group_info = null; switch ($dialog->type) { case "user": $dialog_user = $builder->where('userid', '!=', $userid)->first(); $dialog->name = User::userid2nickname($dialog_user->userid); $dialog->dialog_user = $dialog_user; break; case "group": if ($dialog->group_type === 'project') { $dialog->group_info = Project::withTrashed()->select(['id', 'name', 'archived_at', 'deleted_at'])->whereDialogId($dialog->id)->first()?->cancelAppend()->cancelHidden(); $dialog->name = $dialog->group_info ? $dialog->group_info->name : ''; } elseif ($dialog->group_type === 'task') { $dialog->group_info = ProjectTask::withTrashed()->select(['id', 'name', 'complete_at', 'archived_at', 'deleted_at'])->whereDialogId($dialog->id)->first()?->cancelAppend()->cancelHidden(); $dialog->name = $dialog->group_info ? $dialog->group_info->name : ''; } break; } return $dialog; } /** * 创建聊天室 * @param string $name 聊天室名称 * @param int|array $userid 加入的会员ID或会员ID组 * @param string $group_type 聊天室类型 * @return self|null */ public static function createGroup($name, $userid, $group_type = '') { return AbstractModel::transaction(function () use ($userid, $group_type, $name) { $dialog = self::createInstance([ 'type' => 'group', 'name' => $name ?: '', 'group_type' => $group_type, ]); $dialog->save(); foreach (is_array($userid) ? $userid : [$userid] as $value) { if ($value > 0) { WebSocketDialogUser::createInstance([ 'dialog_id' => $dialog->id, 'userid' => $value, ])->save(); } } return $dialog; }); } /** * 加入聊天室 * @param int $dialog_id 会话ID(即 聊天室ID) * @param int|array $userid 加入的会员ID或会员ID组 * @return bool */ public static function joinGroup($dialog_id, $userid) { $dialog = self::whereId($dialog_id)->whereType('group')->first(); if (empty($dialog)) { return false; } AbstractModel::transaction(function () use ($dialog, $userid) { foreach (is_array($userid) ? $userid : [$userid] as $value) { if ($value > 0) { WebSocketDialogUser::createInstance([ 'dialog_id' => $dialog->id, 'userid' => $value, ])->save(); } } }); return true; } /** * 退出聊天室 * @param int $dialog_id 会话ID(即 聊天室ID) * @param int|array $userid 加入的会员ID或会员ID组 * @return bool */ public static function exitGroup($dialog_id, $userid) { if (is_array($userid)) { WebSocketDialogUser::whereDialogId($dialog_id)->whereIn('userid', $userid)->delete(); } else { WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($userid)->delete(); } return true; } /** * 获取会员对话(没有自动创建) * @param int $userid 会员ID * @param int $userid2 另一个会员ID * @return self|null */ public static function checkUserDialog($userid, $userid2) { $dialogUser = self::select(['web_socket_dialogs.*']) ->join('web_socket_dialog_users as u1', 'web_socket_dialogs.id', '=', 'u1.dialog_id') ->join('web_socket_dialog_users as u2', 'web_socket_dialogs.id', '=', 'u2.dialog_id') ->where('u1.userid', $userid) ->where('u2.userid', $userid2) ->where('web_socket_dialogs.type', 'user') ->first(); if ($dialogUser) { return $dialogUser; } return AbstractModel::transaction(function () use ($userid2, $userid) { $dialog = self::createInstance([ 'type' => 'user', ]); $dialog->save(); WebSocketDialogUser::createInstance([ 'dialog_id' => $dialog->id, 'userid' => $userid, ])->save(); WebSocketDialogUser::createInstance([ 'dialog_id' => $dialog->id, 'userid' => $userid2, ])->save(); return $dialog; }); } }