From 12031aca33f418a461096bb53a8d9307f01cd05d Mon Sep 17 00:00:00 2001 From: kuaifan Date: Fri, 18 Jun 2021 15:36:31 +0800 Subject: [PATCH] no message --- app/Http/Controllers/Api/DialogController.php | 24 +----- app/Http/Controllers/Api/UsersController.php | 5 -- app/Models/AbstractModel.php | 24 +++--- app/Models/User.php | 12 +-- app/Models/WebSocket.php | 18 ----- app/Models/WebSocketDialog.php | 62 ++++++++++----- app/Models/WebSocketDialogMsg.php | 22 +++--- app/Models/WebSocketDialogMsgRead.php | 2 + app/Services/WebSocketService.php | 8 +- app/Tasks/WebSocketDialogMsgTask.php | 76 ++++++++----------- resources/assets/js/store/actions.js | 4 +- 11 files changed, 112 insertions(+), 145 deletions(-) diff --git a/app/Http/Controllers/Api/DialogController.php b/app/Http/Controllers/Api/DialogController.php index 9b432ceb..876c8b70 100755 --- a/app/Http/Controllers/Api/DialogController.php +++ b/app/Http/Controllers/Api/DialogController.php @@ -103,13 +103,7 @@ class DialogController extends AbstractController // $dialog_id = intval(Request::input('dialog_id')); // - if (!WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($user->userid)->exists()) { - return Base::retError('不在成员列表内'); - } - $dialog = WebSocketDialog::whereId($dialog_id)->first(); - if (empty($dialog)) { - return Base::retError('对话不存在或已被删除'); - } + $dialog = WebSocketDialog::checkDialog($dialog_id); // $list = WebSocketDialogMsg::whereDialogId($dialog_id)->orderByDesc('id')->paginate(Base::getPaginate(100, 50)); $list->transform(function (WebSocketDialogMsg $item) use ($user) { @@ -153,13 +147,7 @@ class DialogController extends AbstractController return Base::retError('消息内容最大不能超过20000字'); } // - if (!WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($user->userid)->exists()) { - return Base::retError('不在成员列表内'); - } - $dialog = WebSocketDialog::whereId($dialog_id)->first(); - if (empty($dialog)) { - return Base::retError('对话不存在或已被删除'); - } + WebSocketDialog::checkDialog($dialog_id); // $msg = [ 'text' => $text @@ -182,13 +170,7 @@ class DialogController extends AbstractController // $dialog_id = Base::getPostInt('dialog_id'); // - if (!WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($user->userid)->exists()) { - return Base::retError('不在成员列表内'); - } - $dialog = WebSocketDialog::whereId($dialog_id)->first(); - if (empty($dialog)) { - return Base::retError('对话不存在或已被删除'); - } + $dialog = WebSocketDialog::checkDialog($dialog_id); // $path = "uploads/chat/" . $user->userid . "/"; $image64 = Base::getPostValue('image64'); diff --git a/app/Http/Controllers/Api/UsersController.php b/app/Http/Controllers/Api/UsersController.php index 4f1759e6..2ee252b9 100755 --- a/app/Http/Controllers/Api/UsersController.php +++ b/app/Http/Controllers/Api/UsersController.php @@ -47,11 +47,6 @@ class UsersController extends AbstractController return Base::retError('未开放注册'); } $user = User::reg($email, $password); - if (Base::isError($user)) { - return $user; - } else { - $user = User::IDE($user['data']); - } } else { $needCode = !Base::isError(User::needCode($email)); if ($needCode) { diff --git a/app/Models/AbstractModel.php b/app/Models/AbstractModel.php index c6fa2030..01287c51 100644 --- a/app/Models/AbstractModel.php +++ b/app/Models/AbstractModel.php @@ -14,6 +14,7 @@ use Illuminate\Support\Facades\DB; * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newQuery() * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel query() + * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel saveOrIgnore() * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel getKeyValue() * @method static \Illuminate\Database\Eloquent\Builder|static with($relations) * @method static \Illuminate\Database\Query\Builder|static select($columns = []) @@ -32,6 +33,19 @@ class AbstractModel extends Model 'deleted_at', ]; + /** + * 保存数据忽略错误 + * @return bool + */ + protected function scopeSaveOrIgnore() + { + try { + return $this->save(); + } catch (\Exception $e) { + return false; + } + } + /** * 获取模型主键的值(如果没有则先保存) * @return mixed @@ -134,16 +148,6 @@ class AbstractModel extends Model return $row; } - /** - * 定义变量为对象(IDE高亮) - * @param $value - * @return static - */ - public static function IDE($value) - { - return $value; - } - /** * 用于Model的事务处理 * @param \Closure $closure diff --git a/app/Models/User.php b/app/Models/User.php index a162325e..9aee35d8 100644 --- a/app/Models/User.php +++ b/app/Models/User.php @@ -149,22 +149,22 @@ class User extends AbstractModel * @param $email * @param $password * @param array $other - * @return array + * @return self */ public static function reg($email, $password, $other = []) { //邮箱 if (!Base::isMail($email)) { - return Base::retError('请输入正确的邮箱地址'); + throw new ApiException('请输入正确的邮箱地址'); } if (User::email2userid($email) > 0) { - return Base::retError('邮箱地址已存在'); + throw new ApiException('邮箱地址已存在'); } //密码 if (strlen($password) < 6) { - return Base::retError(['密码设置不能小于%位数', 6]); + throw new ApiException('密码设置不能小于6位数'); } elseif (strlen($password) > 32) { - return Base::retError(['密码最多只能设置%位数', 32]); + throw new ApiException('密码最多只能设置32位数'); } //开始注册 $encrypt = Base::generatePassword(6); @@ -180,7 +180,7 @@ class User extends AbstractModel $user = User::createInstance($inArray); $user->save(); User::AZUpdate($user->userid); - return Base::retSuccess('success', $user); + return $user->find($user->userid); } /** diff --git a/app/Models/WebSocket.php b/app/Models/WebSocket.php index 49827d7e..7ebca1cf 100644 --- a/app/Models/WebSocket.php +++ b/app/Models/WebSocket.php @@ -3,8 +3,6 @@ namespace App\Models; -use Request; - /** * Class WebSocket * @@ -28,20 +26,4 @@ use Request; */ class WebSocket extends AbstractModel { - - /** - * 获取其他fd(获取其他设备) - * @return array - */ - public static function getOtherFd($fd) - { - if (empty($fd)) { - return []; - } - $row = self::whereFd($fd)->first(); - if ($row) { - return self::whereUserid($row->userid)->where('id', '!=', $row->id)->pluck('fd')->toArray(); - } - return []; - } } diff --git a/app/Models/WebSocketDialog.php b/app/Models/WebSocketDialog.php index aea99089..d15a5592 100644 --- a/app/Models/WebSocketDialog.php +++ b/app/Models/WebSocketDialog.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Exceptions\ApiException; use App\Module\Base; /** @@ -15,10 +16,14 @@ use App\Module\Base; * @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\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) @@ -26,11 +31,45 @@ use App\Module\Base; * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereType($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereUpdatedAt($value) * @mixin \Eloquent - * @property \Illuminate\Support\Carbon|null $deleted_at - * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereDeletedAt($value) */ class WebSocketDialog extends AbstractModel { + /** + * @return \Illuminate\Database\Eloquent\Relations\HasMany + */ + public function dialogUser(): \Illuminate\Database\Eloquent\Relations\HasMany + { + return $this->hasMany(WebSocketDialogUser::class, 'dialog_id', 'id'); + } + + /** + * 获取对话(同时检验对话身份) + * @param $id + * @return self + */ + public static function checkDialog($id) + { + $dialog = WebSocketDialog::whereId($id)->first(); + if (empty($dialog)) { + throw new ApiException('对话不存在或已被删除'); + } + // + $userid = User::token2userid(); + 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 @@ -142,25 +181,6 @@ class WebSocketDialog extends AbstractModel return true; } - /** - * 获取对话 - * @param int $userid 会员ID - * @param int $dialog_id 会话ID - * @return self - */ - public static function checkDialog($userid, $dialog_id) - { - if ($userid == 0) { - return self::whereId($dialog_id)->first(); - } else { - return self::select(['web_socket_dialogs.*']) - ->join('web_socket_dialog_users', 'web_socket_dialog_users.dialog_id', '=', 'web_socket_dialogs.id') - ->where('web_socket_dialogs.id', $dialog_id) - ->where('web_socket_dialog_users.userid', $userid) - ->first(); - } - } - /** * 获取会员对话(没有自动创建) * @param int $userid 会员ID diff --git a/app/Models/WebSocketDialogMsg.php b/app/Models/WebSocketDialogMsg.php index 4dfd0758..3a14cd27 100644 --- a/app/Models/WebSocketDialogMsg.php +++ b/app/Models/WebSocketDialogMsg.php @@ -98,16 +98,15 @@ class WebSocketDialogMsg extends AbstractModel 'dialog_id' => $this->dialog_id, 'msg_id' => $this->id, 'userid' => $userid, + 'after' => 1, ]); - try { - $msgRead->saveOrFail(); - $this->send = WebSocketDialogMsgRead::whereMsgId($this->id)->count(); - $this->save(); - } catch (\Throwable $e) { - $msgRead = $msgRead->first(); + if ($msgRead->saveOrIgnore()) { + $this->increment('send'); + } else { + return; } } - if ($msgRead && !$msgRead->read_at) { + if (!$msgRead->read_at) { $msgRead->read_at = Carbon::now(); $msgRead->save(); $this->increment('read'); @@ -115,7 +114,7 @@ class WebSocketDialogMsg extends AbstractModel 'userid' => $this->userid, 'msg' => [ 'type' => 'dialog', - 'mode' => 'up', + 'mode' => 'update', 'data' => $this->toArray(), ] ]); @@ -141,19 +140,16 @@ class WebSocketDialogMsg extends AbstractModel 'read' => 0, ]); return AbstractModel::transaction(function () use ($dialog_id, $msg, $dialogMsg) { - $dialog = WebSocketDialog::checkDialog($dialogMsg->userid, $dialog_id); + $dialog = WebSocketDialog::find($dialog_id); if (empty($dialog)) { return Base::retError('获取会话失败'); } $dialog->last_at = Carbon::now(); $dialog->save(); - $userids = WebSocketDialogUser::whereDialogId($dialog->id)->where('userid', '!=', $dialogMsg->userid)->pluck('userid')->toArray(); - $dialogMsg->send = count($userids); $dialogMsg->dialog_id = $dialog->id; $dialogMsg->save(); // - $task = new WebSocketDialogMsgTask($userids, $dialogMsg->toArray()); - Task::deliver($task); + Task::deliver(new WebSocketDialogMsgTask($dialogMsg->id)); // return Base::retSuccess('发送成功', $dialogMsg->toArray()); }); diff --git a/app/Models/WebSocketDialogMsgRead.php b/app/Models/WebSocketDialogMsgRead.php index 45cf0a21..f474393c 100644 --- a/app/Models/WebSocketDialogMsgRead.php +++ b/app/Models/WebSocketDialogMsgRead.php @@ -10,10 +10,12 @@ namespace App\Models; * @property int|null $dialog_id 对话ID * @property int|null $msg_id 消息ID * @property int|null $userid 发送会员ID + * @property int|null $after 在阅读之后才添加的记录 * @property string|null $read_at 阅读时间 * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead query() + * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereAfter($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereDialogId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMsgId($value) diff --git a/app/Services/WebSocketService.php b/app/Services/WebSocketService.php index 9ba4eeca..498805f5 100644 --- a/app/Services/WebSocketService.php +++ b/app/Services/WebSocketService.php @@ -128,11 +128,9 @@ class WebSocketService implements WebSocketHandlerInterface $ids = is_array($data['id']) ? $data['id'] : [$data['id']]; $userid = $this->getUserid($frame->fd); $list = WebSocketDialogMsg::whereIn('id', $ids)->get(); - if ($list->isNotEmpty()) { - foreach ($list as $item) { - $item->readSuccess($userid); - } - } + $list->transform(function(WebSocketDialogMsg $item) use ($userid) { + $item->readSuccess($userid); + }); return; } // diff --git a/app/Tasks/WebSocketDialogMsgTask.php b/app/Tasks/WebSocketDialogMsgTask.php index a49aa827..7b996867 100644 --- a/app/Tasks/WebSocketDialogMsgTask.php +++ b/app/Tasks/WebSocketDialogMsgTask.php @@ -2,7 +2,7 @@ namespace App\Tasks; -use App\Models\WebSocket; +use App\Models\WebSocketDialog; use App\Models\WebSocketDialogMsg; use App\Models\WebSocketDialogMsgRead; use Request; @@ -17,65 +17,53 @@ use Request; */ class WebSocketDialogMsgTask extends AbstractTask { - protected $userid; - protected $dialogMsgArray; - protected $currentFd; + protected $id; + protected $ignoreFd; /** * WebSocketDialogMsgTask constructor. - * @param int|array $userid 发送对象ID 或 ID组 - * @param array $dialogMsgArray 发送的内容 - * @param null $currentFd 当前发送会员的 websocket fd (用于给其他设备发送消息,留空通过header获取) + * @param int $id 消息ID */ - public function __construct($userid, array $dialogMsgArray, $currentFd = null) + public function __construct($id) { - $this->userid = $userid; - $this->dialogMsgArray = $dialogMsgArray; - $this->currentFd = $currentFd ?: Request::header('fd'); + $this->id = $id; + $this->ignoreFd = Request::header('fd'); } public function start() { - $userids = is_array($this->userid) ? $this->userid : [$this->userid]; - $msgId = intval($this->dialogMsgArray['id']); - $send = intval($this->dialogMsgArray['send']); - $dialogId = intval($this->dialogMsgArray['dialog_id']); - if (empty($userids) || empty($msgId)) { + $msg = WebSocketDialogMsg::find($this->id); + if (empty($msg)) { + return; + } + $dialog = WebSocketDialog::find($msg->dialog_id); + if (empty($dialog)) { return; } // 推送目标 - $pushIds = []; + $userids = $dialog->dialogUser->pluck('userid')->toArray(); foreach ($userids AS $userid) { - $msgRead = WebSocketDialogMsgRead::createInstance([ - 'dialog_id' => $dialogId, - 'msg_id' => $msgId, - 'userid' => $userid, - ]); - try { - $msgRead->saveOrFail(); - $pushIds[] = $userid; - } catch (\Throwable $e) { - // + if ($userid == $msg->userid) { + continue; } + WebSocketDialogMsgRead::createInstance([ + 'dialog_id' => $msg->dialog_id, + 'msg_id' => $msg->id, + 'userid' => $userid, + ])->saveOrIgnore(); } - $fd = WebSocket::getOtherFd($this->currentFd); // 更新已发送数量 - if ($send != count($pushIds)) { - $send = WebSocketDialogMsgRead::whereMsgId($msgId)->count(); - WebSocketDialogMsg::whereId($msgId)->update([ 'send' => $send ]); - $this->dialogMsgArray['send'] = $send; - } + $msg->send = WebSocketDialogMsgRead::whereMsgId($msg->id)->count(); + $msg->save(); // 开始推送消息 - if ($pushIds || $fd) { - PushTask::push([ - 'userid' => $pushIds, - 'fd' => $fd, - 'msg' => [ - 'type' => 'dialog', - 'mode' => 'add', - 'data' => $this->dialogMsgArray, - ] - ]); - } + PushTask::push([ + 'userid' => $userids, + 'ignoreFd' => $this->ignoreFd, + 'msg' => [ + 'type' => 'dialog', + 'mode' => 'add', + 'data' => $msg->toArray(), + ] + ]); } } diff --git a/resources/assets/js/store/actions.js b/resources/assets/js/store/actions.js index b8558a83..1fe0b642 100644 --- a/resources/assets/js/store/actions.js +++ b/resources/assets/js/store/actions.js @@ -971,7 +971,7 @@ export default { */ dialogMsgRead({state, dispatch}, msgData) { if (msgData.userid == state.userId) return; - if (typeof msgData.r === "undefined") msgData.r = {}; + if (!state.method.isJson(msgData.r)) msgData.r = {}; // const {id, dialog_id, r} = msgData; if (!r.read_at) { @@ -993,7 +993,7 @@ export default { } }); state.wsReadWaitList = []; - }, 10); + }, 20); }, /**