diff --git a/app/common/controller/MessageNotificationsController.php b/app/common/controller/MessageNotificationsController.php index 4e475eb..19341fc 100644 --- a/app/common/controller/MessageNotificationsController.php +++ b/app/common/controller/MessageNotificationsController.php @@ -4,6 +4,8 @@ namespace app\common\controller; use app\common\controller\BaseController; use app\common\traits\crud\CrudControllerTrait; use app\common\service\MessageNotificationsService; +use app\common\model\MessageNotifications; +use support\Request; class MessageNotificationsController extends BaseController { @@ -22,12 +24,29 @@ class MessageNotificationsController extends BaseController * @param array $data * @return array */ - // protected function indexFormat($data) - // { - // if (isset($data['created_at'])) - // $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); - // if (isset($data['updated_at'])) - // $data['updated_at'] = date('Y-m-d H:i:s', $data['updated_at']); - // return $data; - // } + protected function indexFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + return $data; + } + + protected function showFormat($data) + { + if (isset($data['created_at'])) + $data['created_at'] = date('Y-m-d H:i:s', $data['created_at']); + return $data; + } + + + public function push(Request $request) + { + try { + $data = $this->validate($this->service->getValidator(), $request->post(), 'store'); + $res = $this->service->servicePush($request, $data); + return $this->success($res, '推送成功'); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/common/logic/MessageNotificationsLogic.php b/app/common/logic/MessageNotificationsLogic.php index b0a1429..594bb96 100644 --- a/app/common/logic/MessageNotificationsLogic.php +++ b/app/common/logic/MessageNotificationsLogic.php @@ -14,4 +14,16 @@ class MessageNotificationsLogic */ protected string $modelClass = MessageNotifications::class; + + public function logicDeleteBy($config) + { + $msg = $this->logicShow($config); + if ($msg) { + // 删除关联的用户状态记录 + $msg->userStatuses()->delete(); + // 删除消息本身 + $msg->delete(); + } + return true; + } } \ No newline at end of file diff --git a/app/common/model/MessageNotifications.php b/app/common/model/MessageNotifications.php index 9ee9b77..ef1b418 100644 --- a/app/common/model/MessageNotifications.php +++ b/app/common/model/MessageNotifications.php @@ -32,15 +32,16 @@ class MessageNotifications extends Model * * @var bool */ - public $timestamps = true; + public $timestamps = false; + // const UPDATED_AT = false; - protected $dateFormat = 'U'; + // protected $dateFormat = 'U'; /** * 允许自动填充模型字段 */ - protected $fillable = ['id', 'msg_no', 'sender_id', 'sender_type', 'recipient', 'title', 'content', 'scene', 'created_at']; + protected $fillable = ['id', 'msg_no', 'sender_id', 'sender_type', 'recipient', 'title', 'content', 'scene', 'push_method', 'created_at']; /** * 不允许自动填充模型字段 @@ -54,4 +55,39 @@ class MessageNotifications extends Model ]; const SCENE0 = 0; const SCENE1 = 1; + + // 推送方式 + const PUSH_METHOD = [ + self::PUSH_METHOD0 => '系统推送', + self::PUSH_METHOD1 => '手动推送' + ]; + const PUSH_METHOD0 = 0; + const PUSH_METHOD1 = 1; + + + /** + * 关联用户消息状态 (一对多) + */ + public function userStatuses() + { + return $this->hasMany(MessageUserStatus::class, 'msg_id', 'id'); + } + + /** + * 获取已读用户状态 + */ + public function readUsers() + { + return $this->hasMany(MessageUserStatus::class, 'msg_id', 'id') + ->where('status', 1); + } + + /** + * 获取未读用户状态 + */ + public function unreadUsers() + { + return $this->hasMany(MessageUserStatus::class, 'msg_id', 'id') + ->where('status', 0); + } } \ No newline at end of file diff --git a/app/common/model/MessageUserStatus.php b/app/common/model/MessageUserStatus.php index e1e1f74..70ff44e 100644 --- a/app/common/model/MessageUserStatus.php +++ b/app/common/model/MessageUserStatus.php @@ -46,4 +46,21 @@ class MessageUserStatus extends Model * 不允许自动填充模型字段 */ protected $guarded = []; + + + /** + * 关联消息 (多对一) + */ + public function message() + { + return $this->belongsTo(MessageNotifications::class, 'msg_id', 'id'); + } + + /** + * 关联用户 (假设你有 User 模型) + */ + public function user() + { + return $this->belongsTo(User::class, 'uid', 'id'); + } } \ No newline at end of file diff --git a/app/common/service/MessageNotificationsService.php b/app/common/service/MessageNotificationsService.php index 720fec2..4e8162c 100644 --- a/app/common/service/MessageNotificationsService.php +++ b/app/common/service/MessageNotificationsService.php @@ -2,11 +2,13 @@ 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\User; use support\Db; +use support\Request; class MessageNotificationsService { @@ -31,6 +33,78 @@ class MessageNotificationsService 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; + } /** * 创建一条消息 @@ -45,6 +119,7 @@ class MessageNotificationsService 'content' => $data['content'], 'scene' => $data['scene'], 'recipient' => $data['recipient'], + 'push_method' => $data['push_method'], 'created_at' => time(), ]); @@ -116,6 +191,7 @@ class MessageNotificationsService 'content' => $data['content'], 'scene' => $data['scene'], 'recipient' => $data['recipient'] ? implode(',', $data['recipient']) : '', + 'push_method' => $data['push_method'], ]); // 写用户状态 diff --git a/app/common/utils/WsEvents.php b/app/common/utils/WsEvents.php index cded7a0..50f82bb 100644 --- a/app/common/utils/WsEvents.php +++ b/app/common/utils/WsEvents.php @@ -146,9 +146,9 @@ class WsEvents if (!$title || !$content) { Gateway::sendToClient($this->clientId, WsResponse::error( - 'notify.push', + 'notify.push.result', 400, - 'title and content are required', + '标题和内容不能为空', $traceId )); return; @@ -163,13 +163,14 @@ class WsEvents 'content' => $content, 'scene' => $this->eventData['scene'] ?? 0, 'recipient' => $this->eventData['to_uids'] ? implode(',', $this->eventData['to_uids']) : '', + 'push_method' => isset($this->eventData['push_method']) ? $this->eventData['push_method'] : 0 ]); // 写用户状态 $uids = !empty($toUids) ? $toUids : $msgService->getAllUserIds(); $msgService->addUserStatus($msgId, $uids); - $payload = WsResponse::success('notify.push', [ + $payload = WsResponse::success('notify.receive', [ 'msg_id' => $msgId, 'title' => $title, 'content' => $content, @@ -203,9 +204,9 @@ class WsEvents $msgIds = $this->eventData['msg_ids']; if (!is_array($msgIds) && $msgIds !== 'all') { Gateway::sendToClient($this->clientId, WsResponse::error( - 'notify.read', + 'notify.read.result', 400, - 'msg_ids required', + '消息ID不能为空', $traceId )); return; @@ -227,7 +228,7 @@ class WsEvents */ public function pushNotice(int $msgId, string $title, string $content, array $recipient) { - $payload = WsResponse::success('notify.push', [ + $payload = WsResponse::success('notify.receive', [ 'msg_id' => $msgId, 'title' => $title, 'content' => $content, diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index b12be98..c8427cd 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -122,6 +122,15 @@ class IndexController // // 异步推送 // \Webman\RedisQueue\Redis::send('notice', $data); - return json($data); + // return json($data); + + $phone = ''; + $email = ''; + + $userByPhone = User::where('corp_id', 2)->where('phone', $phone)->where('phone', '!=', '')->first(); + $userByEmail = User::where('corp_id', 2)->where('email', $email)->where('email', '!=', '')->first(); + $user = $userByPhone ?: $userByEmail; + + return json($user); } } \ No newline at end of file diff --git a/config/route.php b/config/route.php index 9c33c32..99837b0 100644 --- a/config/route.php +++ b/config/route.php @@ -68,6 +68,15 @@ Route::group('/common', function () { // 后台管理 Route::group('/admin', function () { + // 消息通知 + Route::group('/notice', function () { + Route::any('/list', [app\common\controller\MessageNotificationsController::class, 'index']); + Route::any('/show', [app\common\controller\MessageNotificationsController::class, 'show']); + Route::any('/push', [app\common\controller\MessageNotificationsController::class, 'push']); + // Route::any('/update', [app\common\controller\MessageNotificationsController::class, 'update']); + Route::any('/destroy', [app\common\controller\MessageNotificationsController::class, 'destroy']); + }); + // 角色 Route::group('/role', function () { Route::any('/list', [app\admin\controller\RoleController::class, 'index']);