276 lines
8.6 KiB
PHP
276 lines
8.6 KiB
PHP
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\common\logic\MessageNotificationsLogic;
|
|
use app\common\validate\MessageNotificationsValidate;
|
|
use app\common\traits\crud\CrudServiceTrait;
|
|
use app\common\model\MessageNotifications;
|
|
use app\common\model\MessageUserStatus;
|
|
use app\common\model\User;
|
|
use support\Db;
|
|
use support\Request;
|
|
|
|
class MessageNotificationsService
|
|
{
|
|
|
|
use CrudServiceTrait;
|
|
|
|
/**
|
|
* 指定当前要操作的模型
|
|
*/
|
|
protected string $modelClass = MessageNotifications::class;
|
|
|
|
/**
|
|
* 验证器
|
|
*/
|
|
protected $validator = MessageNotificationsValidate::class;
|
|
|
|
/**
|
|
* 获取验证器
|
|
*/
|
|
public function getValidator()
|
|
{
|
|
return new $this->validator;
|
|
}
|
|
|
|
protected function buildQueryConfig(Request $request, string $scene = 'default'): array
|
|
{
|
|
$p = $request->all();
|
|
|
|
$config = [];
|
|
$config['model'] = $this->modelClass;
|
|
switch ($scene) {
|
|
case 'index':
|
|
$config['order']['id'] = 'desc';
|
|
break;
|
|
case 'show':
|
|
$config['where']['id'] = $p['id'];
|
|
break;
|
|
case 'store':
|
|
break;
|
|
case 'update':
|
|
$config['where']['id'] = $p['id'];
|
|
break;
|
|
case 'destroy':
|
|
$config['where']['id'] = $p['id'];
|
|
break;
|
|
}
|
|
|
|
return $config;
|
|
}
|
|
|
|
|
|
public function serviceDestroy(Request $request)
|
|
{
|
|
$config = $this->buildQueryConfig($request, 'destroy');
|
|
$deleted = (new MessageNotificationsLogic())->logicDeleteBy($config);
|
|
return $this->postProcess('Destroy', $deleted);
|
|
}
|
|
|
|
/**
|
|
* 添加前置处理
|
|
*/
|
|
public function servicePush(Request $request, $data)
|
|
{
|
|
$pushData = [
|
|
'sender_id' => $request->user->uid,
|
|
'sender_type' => 'admin',
|
|
'title' => $data['title'],
|
|
'content' => $data['content'],
|
|
'scene' => 1,
|
|
'recipient' => $data['recipient'],
|
|
'push_method' => 1
|
|
];
|
|
$msgId = (new MessageNotificationsService())->pushNotice($pushData);
|
|
return ['msg_id' => $msgId];
|
|
}
|
|
|
|
public function afterServiceList($data)
|
|
{
|
|
$data->each(function (&$item) {
|
|
$temp = explode(',', $item->recipient);
|
|
$item->recipient_list = User::whereIn('id', $temp)->pluck('name')->toArray();
|
|
$item->scene_name = MessageNotifications::SCENE[$item->scene];
|
|
$item->push_method_name = MessageNotifications::PUSH_METHOD[$item->push_method];
|
|
});
|
|
unset($item);
|
|
return $data;
|
|
}
|
|
|
|
public function afterServiceShow($data)
|
|
{
|
|
$temp = explode(',', $data->recipient);
|
|
$data->recipient_list = User::whereIn('id', $temp)->pluck('name')->toArray();
|
|
$data->scene_name = MessageNotifications::SCENE[$data->scene];
|
|
$data->push_method_name = MessageNotifications::PUSH_METHOD[$data->push_method];
|
|
return $data;
|
|
}
|
|
|
|
|
|
|
|
// ====== ====== ====== 通知操作的处理 ====== ====== ======
|
|
/**
|
|
* 推送消息
|
|
*/
|
|
public function pushNotice(array $data = [], string $scene = "Default"): int
|
|
{
|
|
// 拼装数据(可能需要处理 消息标题、内容等等数据,可自行处理)
|
|
$pushData = $this->assemblyProcess($scene, $data);
|
|
// 写入消息
|
|
$msgId = $this->insertMessage($pushData);
|
|
// 推送
|
|
$this->pushWs($msgId, $pushData);
|
|
return $msgId;
|
|
}
|
|
|
|
/**
|
|
* 执行推送
|
|
*/
|
|
public function pushWs(int $msgId, array $pushData)
|
|
{
|
|
foreach ($pushData['recipient'] as $userId) {
|
|
// 查询消息数据
|
|
$config['model'] = MessageUserStatus::class;
|
|
$config['order']['id'] = 'desc';
|
|
$config['with']['message'] = ['sender_id', 'sender_type', 'msg_no', 'title', 'content', 'scene', 'created_at'];
|
|
$config['where']['uid'] = $userId;
|
|
$config['where']['msg_id'] = $msgId;
|
|
$config['where']['status'] = 0;
|
|
$wsData = (new MessageUserStatusService())->logicShow($config)->toArray();
|
|
|
|
// 组装数据
|
|
if (isset($wsData['message']) && $wsData['message']) {
|
|
$wsData['message']['sender_name'] = User::where('id', $wsData['message']['sender_id'])->value('name') ?: '系统';
|
|
$wsData['message']['scene_name'] = MessageNotifications::SCENE[$wsData['message']['scene']];
|
|
$wsData['message']['created_at'] = date('Y-m-d H:i:s', $wsData['message']['created_at']);
|
|
}
|
|
|
|
// 获取未读消息数
|
|
$counts = MessageUserStatus::where('uid', $userId)->where('status', 0)->count('id');
|
|
$data = [
|
|
'notice_data' => $wsData,
|
|
'unread_counts' => $counts
|
|
];
|
|
|
|
// 执行推送
|
|
(new \app\common\utils\WsEvents())->pushWsNotice($data, $userId);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* 插入消息
|
|
* @param array $data
|
|
* @return int
|
|
*/
|
|
public function insertMessage(array $data): int
|
|
{
|
|
// 写消息
|
|
$msgId = $this->createMessage([
|
|
'sender_id' => $data['sender_id'],
|
|
'sender_type' => $data['sender_type'],
|
|
'title' => $data['title'],
|
|
'content' => $data['content'],
|
|
'scene' => $data['scene'],
|
|
'recipient' => implode(',', $data['recipient']),
|
|
'push_method' => $data['push_method'],
|
|
]);
|
|
// 写用户状态
|
|
$this->addUserStatus($msgId, $data['recipient']);
|
|
return $msgId;
|
|
}
|
|
|
|
/**
|
|
* 数据拼装方法调用
|
|
*/
|
|
protected function assemblyProcess(string $op, mixed $data): mixed
|
|
{
|
|
$hook = "assembly{$op}";
|
|
return method_exists($this, $hook)
|
|
? $this->{$hook}($data)
|
|
: $data;
|
|
}
|
|
|
|
/**
|
|
* 默认数据拼装
|
|
*/
|
|
public function assemblyDefault(array $data)
|
|
{
|
|
return [
|
|
'sender_id' => isset($data['sender_id']) && $data['sender_id'] ? $data['sender_id'] : 0,
|
|
'sender_type' => isset($data['sender_type']) && $data['sender_type'] ? $data['sender_type'] : 'system',
|
|
'title' => isset($data['title']) && $data['title'] ? $data['title'] : '系统通知',
|
|
'content' => isset($data['content']) && $data['content'] ? $data['content'] : '系统通知-默认',
|
|
'scene' => isset($data['scene']) && $data['scene'] ? $data['scene'] : 1,
|
|
'recipient' => isset($data['recipient']) && count($data['recipient']) > 0 ? $data['recipient'] : $this->getAllUserIds(),
|
|
'push_method' => isset($data['push_method']) && $data['push_method'] ? $data['push_method'] : 0,
|
|
];
|
|
}
|
|
|
|
// *** *** 可以扩展数据组拼装方法 *** ***
|
|
|
|
// ====== ====== ====== 通知操作的基础方法 ====== ====== ======
|
|
|
|
/**
|
|
* 创建一条消息
|
|
*/
|
|
public function createMessage(array $data): int
|
|
{
|
|
$msgId = Db::table('message_notifications')->insertGetId([
|
|
'msg_no' => generateMsgId(),
|
|
'sender_id' => $data['sender_id'],
|
|
'sender_type' => $data['sender_type'],
|
|
'title' => $data['title'],
|
|
'content' => $data['content'],
|
|
'scene' => $data['scene'],
|
|
'recipient' => $data['recipient'],
|
|
'push_method' => $data['push_method'],
|
|
'created_at' => time(),
|
|
]);
|
|
|
|
return $msgId;
|
|
}
|
|
|
|
/**
|
|
* 批量插入用户消息状态
|
|
*/
|
|
public function addUserStatus(int $msgId, array $uids)
|
|
{
|
|
$rows = [];
|
|
foreach ($uids as $uid) {
|
|
$rows[] = [
|
|
'msg_id' => $msgId,
|
|
'uid' => $uid,
|
|
'status' => 0,
|
|
'read_at' => null
|
|
];
|
|
}
|
|
if ($rows) {
|
|
Db::table('message_user_status')->insert($rows);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 标记消息已读
|
|
*/
|
|
public function markAsRead(array|string $msgIds, int $uid)
|
|
{
|
|
$query = Db::table('message_user_status')->where('uid', $uid)->where('status', 0);
|
|
if (is_array($msgIds)) {
|
|
$query->whereIn('msg_id', $msgIds);
|
|
}
|
|
return $query->update([
|
|
'status' => 1,
|
|
'read_at' => time()
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 获取所有用户ID
|
|
*/
|
|
public function getAllUserIds(): array
|
|
{
|
|
return User::where('status', 1)->pluck('id')->toArray();
|
|
}
|
|
} |