no message

This commit is contained in:
kuaifan 2021-06-18 15:36:31 +08:00
parent 4799c10858
commit 12031aca33
11 changed files with 112 additions and 145 deletions

View File

@ -103,13 +103,7 @@ class DialogController extends AbstractController
// //
$dialog_id = intval(Request::input('dialog_id')); $dialog_id = intval(Request::input('dialog_id'));
// //
if (!WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($user->userid)->exists()) { $dialog = WebSocketDialog::checkDialog($dialog_id);
return Base::retError('不在成员列表内');
}
$dialog = WebSocketDialog::whereId($dialog_id)->first();
if (empty($dialog)) {
return Base::retError('对话不存在或已被删除');
}
// //
$list = WebSocketDialogMsg::whereDialogId($dialog_id)->orderByDesc('id')->paginate(Base::getPaginate(100, 50)); $list = WebSocketDialogMsg::whereDialogId($dialog_id)->orderByDesc('id')->paginate(Base::getPaginate(100, 50));
$list->transform(function (WebSocketDialogMsg $item) use ($user) { $list->transform(function (WebSocketDialogMsg $item) use ($user) {
@ -153,13 +147,7 @@ class DialogController extends AbstractController
return Base::retError('消息内容最大不能超过20000字'); return Base::retError('消息内容最大不能超过20000字');
} }
// //
if (!WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($user->userid)->exists()) { WebSocketDialog::checkDialog($dialog_id);
return Base::retError('不在成员列表内');
}
$dialog = WebSocketDialog::whereId($dialog_id)->first();
if (empty($dialog)) {
return Base::retError('对话不存在或已被删除');
}
// //
$msg = [ $msg = [
'text' => $text 'text' => $text
@ -182,13 +170,7 @@ class DialogController extends AbstractController
// //
$dialog_id = Base::getPostInt('dialog_id'); $dialog_id = Base::getPostInt('dialog_id');
// //
if (!WebSocketDialogUser::whereDialogId($dialog_id)->whereUserid($user->userid)->exists()) { $dialog = WebSocketDialog::checkDialog($dialog_id);
return Base::retError('不在成员列表内');
}
$dialog = WebSocketDialog::whereId($dialog_id)->first();
if (empty($dialog)) {
return Base::retError('对话不存在或已被删除');
}
// //
$path = "uploads/chat/" . $user->userid . "/"; $path = "uploads/chat/" . $user->userid . "/";
$image64 = Base::getPostValue('image64'); $image64 = Base::getPostValue('image64');

View File

@ -47,11 +47,6 @@ class UsersController extends AbstractController
return Base::retError('未开放注册'); return Base::retError('未开放注册');
} }
$user = User::reg($email, $password); $user = User::reg($email, $password);
if (Base::isError($user)) {
return $user;
} else {
$user = User::IDE($user['data']);
}
} else { } else {
$needCode = !Base::isError(User::needCode($email)); $needCode = !Base::isError(User::needCode($email));
if ($needCode) { if ($needCode) {

View File

@ -14,6 +14,7 @@ use Illuminate\Support\Facades\DB;
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newQuery() * @method static \Illuminate\Database\Eloquent\Builder|AbstractModel newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|AbstractModel query() * @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|AbstractModel getKeyValue()
* @method static \Illuminate\Database\Eloquent\Builder|static with($relations) * @method static \Illuminate\Database\Eloquent\Builder|static with($relations)
* @method static \Illuminate\Database\Query\Builder|static select($columns = []) * @method static \Illuminate\Database\Query\Builder|static select($columns = [])
@ -32,6 +33,19 @@ class AbstractModel extends Model
'deleted_at', 'deleted_at',
]; ];
/**
* 保存数据忽略错误
* @return bool
*/
protected function scopeSaveOrIgnore()
{
try {
return $this->save();
} catch (\Exception $e) {
return false;
}
}
/** /**
* 获取模型主键的值(如果没有则先保存) * 获取模型主键的值(如果没有则先保存)
* @return mixed * @return mixed
@ -134,16 +148,6 @@ class AbstractModel extends Model
return $row; return $row;
} }
/**
* 定义变量为对象IDE高亮
* @param $value
* @return static
*/
public static function IDE($value)
{
return $value;
}
/** /**
* 用于Model的事务处理 * 用于Model的事务处理
* @param \Closure $closure * @param \Closure $closure

View File

@ -149,22 +149,22 @@ class User extends AbstractModel
* @param $email * @param $email
* @param $password * @param $password
* @param array $other * @param array $other
* @return array * @return self
*/ */
public static function reg($email, $password, $other = []) public static function reg($email, $password, $other = [])
{ {
//邮箱 //邮箱
if (!Base::isMail($email)) { if (!Base::isMail($email)) {
return Base::retError('请输入正确的邮箱地址'); throw new ApiException('请输入正确的邮箱地址');
} }
if (User::email2userid($email) > 0) { if (User::email2userid($email) > 0) {
return Base::retError('邮箱地址已存在'); throw new ApiException('邮箱地址已存在');
} }
//密码 //密码
if (strlen($password) < 6) { if (strlen($password) < 6) {
return Base::retError(['密码设置不能小于%位数', 6]); throw new ApiException('密码设置不能小于6位数');
} elseif (strlen($password) > 32) { } elseif (strlen($password) > 32) {
return Base::retError(['密码最多只能设置%位数', 32]); throw new ApiException('密码最多只能设置32位数');
} }
//开始注册 //开始注册
$encrypt = Base::generatePassword(6); $encrypt = Base::generatePassword(6);
@ -180,7 +180,7 @@ class User extends AbstractModel
$user = User::createInstance($inArray); $user = User::createInstance($inArray);
$user->save(); $user->save();
User::AZUpdate($user->userid); User::AZUpdate($user->userid);
return Base::retSuccess('success', $user); return $user->find($user->userid);
} }
/** /**

View File

@ -3,8 +3,6 @@
namespace App\Models; namespace App\Models;
use Request;
/** /**
* Class WebSocket * Class WebSocket
* *
@ -28,20 +26,4 @@ use Request;
*/ */
class WebSocket extends AbstractModel 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 [];
}
} }

View File

@ -2,6 +2,7 @@
namespace App\Models; namespace App\Models;
use App\Exceptions\ApiException;
use App\Module\Base; use App\Module\Base;
/** /**
@ -15,10 +16,14 @@ use App\Module\Base;
* @property string|null $last_at 最后消息时间 * @property string|null $last_at 最后消息时间
* @property \Illuminate\Support\Carbon|null $created_at * @property \Illuminate\Support\Carbon|null $created_at
* @property \Illuminate\Support\Carbon|null $updated_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 newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog newQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog query() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog query()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereCreatedAt($value) * @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 whereGroupType($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereId($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 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 whereType($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereUpdatedAt($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereUpdatedAt($value)
* @mixin \Eloquent * @mixin \Eloquent
* @property \Illuminate\Support\Carbon|null $deleted_at
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialog whereDeletedAt($value)
*/ */
class WebSocketDialog extends AbstractModel 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 * @param WebSocketDialog $dialog
@ -142,25 +181,6 @@ class WebSocketDialog extends AbstractModel
return true; 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 * @param int $userid 会员ID

View File

@ -98,16 +98,15 @@ class WebSocketDialogMsg extends AbstractModel
'dialog_id' => $this->dialog_id, 'dialog_id' => $this->dialog_id,
'msg_id' => $this->id, 'msg_id' => $this->id,
'userid' => $userid, 'userid' => $userid,
'after' => 1,
]); ]);
try { if ($msgRead->saveOrIgnore()) {
$msgRead->saveOrFail(); $this->increment('send');
$this->send = WebSocketDialogMsgRead::whereMsgId($this->id)->count(); } else {
$this->save(); return;
} catch (\Throwable $e) {
$msgRead = $msgRead->first();
} }
} }
if ($msgRead && !$msgRead->read_at) { if (!$msgRead->read_at) {
$msgRead->read_at = Carbon::now(); $msgRead->read_at = Carbon::now();
$msgRead->save(); $msgRead->save();
$this->increment('read'); $this->increment('read');
@ -115,7 +114,7 @@ class WebSocketDialogMsg extends AbstractModel
'userid' => $this->userid, 'userid' => $this->userid,
'msg' => [ 'msg' => [
'type' => 'dialog', 'type' => 'dialog',
'mode' => 'up', 'mode' => 'update',
'data' => $this->toArray(), 'data' => $this->toArray(),
] ]
]); ]);
@ -141,19 +140,16 @@ class WebSocketDialogMsg extends AbstractModel
'read' => 0, 'read' => 0,
]); ]);
return AbstractModel::transaction(function () use ($dialog_id, $msg, $dialogMsg) { return AbstractModel::transaction(function () use ($dialog_id, $msg, $dialogMsg) {
$dialog = WebSocketDialog::checkDialog($dialogMsg->userid, $dialog_id); $dialog = WebSocketDialog::find($dialog_id);
if (empty($dialog)) { if (empty($dialog)) {
return Base::retError('获取会话失败'); return Base::retError('获取会话失败');
} }
$dialog->last_at = Carbon::now(); $dialog->last_at = Carbon::now();
$dialog->save(); $dialog->save();
$userids = WebSocketDialogUser::whereDialogId($dialog->id)->where('userid', '!=', $dialogMsg->userid)->pluck('userid')->toArray();
$dialogMsg->send = count($userids);
$dialogMsg->dialog_id = $dialog->id; $dialogMsg->dialog_id = $dialog->id;
$dialogMsg->save(); $dialogMsg->save();
// //
$task = new WebSocketDialogMsgTask($userids, $dialogMsg->toArray()); Task::deliver(new WebSocketDialogMsgTask($dialogMsg->id));
Task::deliver($task);
// //
return Base::retSuccess('发送成功', $dialogMsg->toArray()); return Base::retSuccess('发送成功', $dialogMsg->toArray());
}); });

View File

@ -10,10 +10,12 @@ namespace App\Models;
* @property int|null $dialog_id 对话ID * @property int|null $dialog_id 对话ID
* @property int|null $msg_id 消息ID * @property int|null $msg_id 消息ID
* @property int|null $userid 发送会员ID * @property int|null $userid 发送会员ID
* @property int|null $after 在阅读之后才添加的记录
* @property string|null $read_at 阅读时间 * @property string|null $read_at 阅读时间
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newModelQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newQuery() * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead query() * @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 whereDialogId($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMsgId($value) * @method static \Illuminate\Database\Eloquent\Builder|WebSocketDialogMsgRead whereMsgId($value)

View File

@ -128,11 +128,9 @@ class WebSocketService implements WebSocketHandlerInterface
$ids = is_array($data['id']) ? $data['id'] : [$data['id']]; $ids = is_array($data['id']) ? $data['id'] : [$data['id']];
$userid = $this->getUserid($frame->fd); $userid = $this->getUserid($frame->fd);
$list = WebSocketDialogMsg::whereIn('id', $ids)->get(); $list = WebSocketDialogMsg::whereIn('id', $ids)->get();
if ($list->isNotEmpty()) { $list->transform(function(WebSocketDialogMsg $item) use ($userid) {
foreach ($list as $item) { $item->readSuccess($userid);
$item->readSuccess($userid); });
}
}
return; return;
} }
// //

View File

@ -2,7 +2,7 @@
namespace App\Tasks; namespace App\Tasks;
use App\Models\WebSocket; use App\Models\WebSocketDialog;
use App\Models\WebSocketDialogMsg; use App\Models\WebSocketDialogMsg;
use App\Models\WebSocketDialogMsgRead; use App\Models\WebSocketDialogMsgRead;
use Request; use Request;
@ -17,65 +17,53 @@ use Request;
*/ */
class WebSocketDialogMsgTask extends AbstractTask class WebSocketDialogMsgTask extends AbstractTask
{ {
protected $userid; protected $id;
protected $dialogMsgArray; protected $ignoreFd;
protected $currentFd;
/** /**
* WebSocketDialogMsgTask constructor. * WebSocketDialogMsgTask constructor.
* @param int|array $userid 发送对象ID ID组 * @param int $id 消息ID
* @param array $dialogMsgArray 发送的内容
* @param null $currentFd 当前发送会员的 websocket fd 用于给其他设备发送消息留空通过header获取
*/ */
public function __construct($userid, array $dialogMsgArray, $currentFd = null) public function __construct($id)
{ {
$this->userid = $userid; $this->id = $id;
$this->dialogMsgArray = $dialogMsgArray; $this->ignoreFd = Request::header('fd');
$this->currentFd = $currentFd ?: Request::header('fd');
} }
public function start() public function start()
{ {
$userids = is_array($this->userid) ? $this->userid : [$this->userid]; $msg = WebSocketDialogMsg::find($this->id);
$msgId = intval($this->dialogMsgArray['id']); if (empty($msg)) {
$send = intval($this->dialogMsgArray['send']); return;
$dialogId = intval($this->dialogMsgArray['dialog_id']); }
if (empty($userids) || empty($msgId)) { $dialog = WebSocketDialog::find($msg->dialog_id);
if (empty($dialog)) {
return; return;
} }
// 推送目标 // 推送目标
$pushIds = []; $userids = $dialog->dialogUser->pluck('userid')->toArray();
foreach ($userids AS $userid) { foreach ($userids AS $userid) {
$msgRead = WebSocketDialogMsgRead::createInstance([ if ($userid == $msg->userid) {
'dialog_id' => $dialogId, continue;
'msg_id' => $msgId,
'userid' => $userid,
]);
try {
$msgRead->saveOrFail();
$pushIds[] = $userid;
} catch (\Throwable $e) {
//
} }
WebSocketDialogMsgRead::createInstance([
'dialog_id' => $msg->dialog_id,
'msg_id' => $msg->id,
'userid' => $userid,
])->saveOrIgnore();
} }
$fd = WebSocket::getOtherFd($this->currentFd);
// 更新已发送数量 // 更新已发送数量
if ($send != count($pushIds)) { $msg->send = WebSocketDialogMsgRead::whereMsgId($msg->id)->count();
$send = WebSocketDialogMsgRead::whereMsgId($msgId)->count(); $msg->save();
WebSocketDialogMsg::whereId($msgId)->update([ 'send' => $send ]);
$this->dialogMsgArray['send'] = $send;
}
// 开始推送消息 // 开始推送消息
if ($pushIds || $fd) { PushTask::push([
PushTask::push([ 'userid' => $userids,
'userid' => $pushIds, 'ignoreFd' => $this->ignoreFd,
'fd' => $fd, 'msg' => [
'msg' => [ 'type' => 'dialog',
'type' => 'dialog', 'mode' => 'add',
'mode' => 'add', 'data' => $msg->toArray(),
'data' => $this->dialogMsgArray, ]
] ]);
]);
}
} }
} }

View File

@ -971,7 +971,7 @@ export default {
*/ */
dialogMsgRead({state, dispatch}, msgData) { dialogMsgRead({state, dispatch}, msgData) {
if (msgData.userid == state.userId) return; 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; const {id, dialog_id, r} = msgData;
if (!r.read_at) { if (!r.read_at) {
@ -993,7 +993,7 @@ export default {
} }
}); });
state.wsReadWaitList = []; state.wsReadWaitList = [];
}, 10); }, 20);
}, },
/** /**