dootask/app/Models/WebSocketDialog.php
2021-12-13 12:22:35 +08:00

240 lines
8.9 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace App\Models;
use App\Exceptions\ApiException;
use Carbon\Carbon;
use Illuminate\Database\Eloquent\SoftDeletes;
/**
* Class WebSocketDialog
*
* @package App\Models
* @property int $id
* @property string|null $type 对话类型
* @property string|null $group_type 聊天室类型
* @property string|null $name 对话名称
* @property string|null $last_at 最后消息时间
* @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_at
* @property \Illuminate\Support\Carbon|null $deleted_at
* @property-read \Illuminate\Database\Eloquent\Collection|\App\Models\WebSocketDialogUser[] $dialogUser
* @property-read int|null $dialog_user_count
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog newQuery()
* @method static \Illuminate\Database\Query\Builder|WebSocketDialog onlyTrashed()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog query()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereDeletedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereGroupType($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereLastAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereUpdatedAt($value)
* @method static \Illuminate\Database\Query\Builder|WebSocketDialog withTrashed()
* @method static \Illuminate\Database\Query\Builder|WebSocketDialog withoutTrashed()
* @mixin \Eloquent
*/
class WebSocketDialog extends AbstractModel
{
use SoftDeletes;
/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function dialogUser(): \Illuminate\Database\Eloquent\Relations\HasMany
{
return $this->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'])->whereDialogId($dialog->id)->first();
$dialog->name = $dialog->group_info ? $dialog->group_info->name : '';
} elseif ($dialog->group_type === 'task') {
$dialog->group_info = ProjectTask::withTrashed()->select(['id', 'name'])->whereDialogId($dialog->id)->first();
$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;
});
}
}