Browse Source

通知相关

liuzejian 2 years ago
parent
commit
bc4500eb92

+ 17 - 0
modules/System/Exceptions/ContentBusinessException.php

@@ -0,0 +1,17 @@
+<?php
+
+namespace Modules\ContentManage\Exceptions;
+
+use Throwable;
+
+class ContentBusinessException extends \RuntimeException
+{
+    public function __construct($message = "", $code = 0, Throwable $previous = null)
+    {
+        parent::__construct($message, $code, $previous);
+    }
+
+    public static function throwError($error, Throwable $previous = null) {
+        throw (new static($error[1], $error[0], $previous));
+    }
+}

+ 20 - 0
modules/System/Exceptions/ContentManageForbidden.php

@@ -0,0 +1,20 @@
+<?php
+
+namespace Modules\ContentManage\Exceptions;
+
+use Catch\Enums\Code;
+use Catch\Exceptions\CatchException;
+use Symfony\Component\HttpFoundation\Response;
+
+class ContentManageForbidden extends CatchException
+{
+    protected $message = 'permission forbidden';
+
+    protected $code = Code::PERMISSION_FORBIDDEN;
+
+
+    public function statusCode(): int
+    {
+        return Response::HTTP_FORBIDDEN;
+    }
+}

+ 9 - 0
modules/System/Exceptions/Errors.php

@@ -0,0 +1,9 @@
+<?php
+
+namespace Modules\ContentManage\Exceptions;
+
+class Errors
+{
+    public const REQUEST_HTTP_STATUS_ERROR = [500001, '请求上游接口返回http状态码有误'];
+    public const REQUEST_CODE_STATUS_ERROR = [500002, '请求上游接口返回code状态码有误'];
+}

+ 54 - 0
modules/System/Http/Controllers/NoticeTypesController.php

@@ -0,0 +1,54 @@
+<?php
+/**
+ * ${CARET}
+ * @file:NoticeTypesController.php
+ * @Created by gnitif
+ * @Date: 2023/3/27
+ * @Time: 11:52
+ */
+
+
+namespace Modules\System\Http\Controllers;
+
+use Catch\Base\CatchController as Controller;
+
+use Illuminate\Http\Request;
+use Modules\System\Http\Requests\NoticeTypeRequest;
+use Modules\System\Services\Notice\NoitceTypeService;
+
+class NoticeTypesController extends Controller
+{
+
+    /**
+     * 获取通知分类列表
+     * name: list
+     * @param Request $request
+     * date 2023/03/27 18:20
+     */
+    public function  list(Request $request)
+    {
+        $param  =  $request->all();
+        $list =  NoitceTypeService::list($param, $request->input('is_all',false) == true);
+        return $list;
+    }
+
+    /**
+     *  添加分类
+     * name: add
+     * @param NoticeTypeRequest $request
+     * @return mixed
+     * date 2023/03/28 18:03
+     */
+    public function  add(NoticeTypeRequest $request)
+    {
+        $param = $request->all();
+        return  NoitceTypeService::store($param);
+    }
+
+    public function  delete($id)
+    {
+        return  NoitceTypeService::del($id);
+    }
+
+
+}

+ 163 - 0
modules/System/Http/Controllers/NoticesController.php

@@ -0,0 +1,163 @@
+<?php
+/**
+ * ${CARET}
+ * @file:NoticesController.php
+ * @Created by gnitif
+ * @Date: 2023/3/27
+ * @Time: 11:18
+ */
+
+
+namespace Modules\System\Http\Controllers;
+
+
+use Catch\Base\CatchController as Controller;
+use Catch\Exceptions\FailedException;
+use Illuminate\Contracts\Pagination\LengthAwarePaginator;
+use Illuminate\Http\Request;
+use Modules\ContentManage\Http\Requests\NoticeRequest;
+use Modules\ContentManage\Models\NoticeTypes;
+use Modules\ContentManage\Services\Notice\NoticesService;
+
+class NoticesController extends Controller
+{
+    public function list(Request $request)
+    {
+        return NoticesService::list();
+
+    }
+
+    /**
+     *  添加通知
+     * name: addNotice
+     * @param NoticeRequest $request
+     * @return mixed
+     * date 2023/03/29 14:47
+     */
+    public function addNotice(NoticeRequest $request)
+    {
+        return NoticesService::addNotice($request->all());
+    }
+
+    /**
+     *  删除通知
+     * name: delete
+     * @param $id
+     * date 2023/03/29 14:48
+     */
+    public function delete($id)
+    {
+        return NoticesService::delete($id);
+    }
+
+    /**
+     *  获取通知详情
+     * name: info
+     * @param $id
+     * @return mixed
+     * date 2023/03/29 14:59
+     */
+    public function info($id)
+    {
+        return NoticesService::getDetail($id);
+    }
+
+    public function edit($id, Request $request)
+    {
+        $title = $request->input('title', '');
+        $content = $request->input('content', '');
+        $notice_type_id = $request->input('notice_type_id', 0);
+
+        if (empty($title)) {
+            throw new FailedException('通知标题不能为空!');
+        }
+        if (empty($content)) {
+            throw new FailedException('通知内容不能为空!');
+        }
+        if (empty($notice_type_id)) {
+            throw new FailedException('通知类型必填!');
+        }
+        $tye = NoticeTypes::where('id', $notice_type_id)->where('is_deleted', 0)->value('id');
+        if (empty($tye)) {
+            throw new FailedException('通知类型不正确!');
+        }
+        $param = [
+            'title' => $title,
+            'content' => $content,
+            'notice_type_id' => $notice_type_id,
+            'sort' => $request->input('sort',0),
+        ];
+        NoticesService::update($id, $param);
+    }
+
+    /**
+     *  我的通知
+     * name: myNotices
+     * @param Request $request
+     * @return LengthAwarePaginator
+     * date 2023/03/29 23:48
+     */
+    public function myNotices(Request $request)
+    {
+        return NoticesService::myNoticesList($request->all());
+    }
+
+    /**
+     *  已读
+     * name: setRead
+     * @param $id
+     * date 2023/03/29 23:51
+     */
+    public function setRead($id): mixed
+    {
+         NoticesService::setRead($id);
+         return response()->json(['code' => 10000, "message" => "操作成功",'data' => []]);
+    }
+
+    /**
+     *  用户删除
+     * name: userDel
+     * @param $id
+     * @return mixed
+     * date 2023/03/29 23:55
+     */
+    public function userDel($id): mixed
+    {
+        return NoticesService::userDel($id);
+    }
+
+    /**
+     *  阅读详情
+     * name: detail
+     * @param $id
+     * date 2023/03/30 00:06
+     */
+    public function detail($id)
+    {
+        return NoticesService::detail($id);
+    }
+
+    /**
+     *  获取通知人群选项
+     * name: objOption
+     * @param Request $request
+     * date 2023/03/30 10:20
+     */
+    public function objOption(Request $request)
+    {
+        $type = $request->input('type', '2');
+        $name = $request->input('name', '');
+        $type = $type == "3" ? "role" : "user";
+        return NoticesService::objOption($type, $name);
+    }
+
+    /**
+     *  home页弹窗公告
+     * name: getPopup
+     * date 2023/03/30 16:41
+     */
+    public function getPopup(){
+        return  NoticesService:: getPopup();
+    }
+
+}

+ 56 - 0
modules/System/Http/Controllers/UserTrait.php

@@ -0,0 +1,56 @@
+<?php
+
+namespace Modules\ContentManage\Http\Controllers;
+
+use Catch\Base\CatchController;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\DB;
+use Modules\User\Models\User;
+
+trait UserTrait
+{
+    // 当前登录用户
+    protected $currentUser;
+
+    /**
+     * 获取当前登录用户
+     * @return User
+     */
+    protected function getCurrentUser(): User {
+        if(!$this->currentUser) {
+            $this->currentUser = $this->getLoginUser();
+        }
+        return $this->currentUser;
+    }
+    /**
+     * 当前用户的所有的角色标识的结合
+     * @return Collection
+     */
+    protected function listUserRoles():Collection {
+        return $this->getCurrentUser()->roles->pluck('identify');
+    }
+
+    /**
+     * 当前用户是否是cp角色
+     * @return bool
+     */
+    public function userIsCp():bool {
+        return $this->listUserRoles()->contains('cp');
+    }
+
+    /**
+     * 如果当前用户是cp角色,返回cp_name,否则返回null
+     * @return string
+     */
+    public function getUserCpName():string|null {
+        if($this->userIsCp()) {
+            return DB::table('user_belong_to_cp')
+                ->where([
+                    'is_enabled' => 1,
+                    'user_id' => $this->getCurrentUser()->id,
+                ])->value('cp_name');
+        } else {
+            return null;
+        }
+    }
+}

+ 61 - 0
modules/System/Http/Requests/NoticeRequest.php

@@ -0,0 +1,61 @@
+<?php
+/**
+ * ${CARET}
+ * @file:CpRequest.php
+ * @Created by gnitif
+ * @Date: 2023/3/22
+ * @Time: 17:06
+ */
+
+
+namespace Modules\System\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+use Modules\System\Models\NoticeTypes;
+
+
+class NoticeRequest extends FormRequest
+{
+
+    /**
+     * rules
+     *
+     * @return array
+     */
+    public function rules(): array
+    {
+        return [
+            'title' => "required|string",
+            'notice_type_id' => [
+                'required',
+                function ($attribute, $value, $fail) {
+                    $has = NoticeTypes::where('is_deleted', 0)->where('id', $value)->value('id');
+                    if (empty($has)) {
+                        $fail("所选分类不存在!");
+                    }
+                }
+            ],
+            'type'=> "required|Integer|in:1,2,3", // 通知人群 1全部 2,指定人,3指定角色
+            'is_popup' => "required|Integer|in:0,1",
+            'content' => "required|string",
+        ];
+    }
+
+    /**
+     * messages
+     *
+     * @return string[]
+     */
+    public function messages(): array
+    {
+        return [
+            'title' => '通知标题必填',
+            'notice_type_id.required' => '通知分类必填',
+            'type.required' => '通知展示人类型必填',
+            'type' => '通知展示人类型不正确',
+            'is_popup' => '展示类型不正确',
+            'content' => '通知内容必填',
+            'notice_obj' => "通知对象必填",
+        ];
+    }
+}

+ 50 - 0
modules/System/Http/Requests/NoticeTypeRequest.php

@@ -0,0 +1,50 @@
+<?php
+/**
+ * ${CARET}
+ * @file:CpRequest.php
+ * @Created by gnitif
+ * @Date: 2023/3/22
+ * @Time: 17:06
+ */
+
+
+namespace Modules\System\Http\Requests;
+
+use Illuminate\Foundation\Http\FormRequest;
+use Modules\System\Models\NoticeTypes;
+
+
+class NoticeTypeRequest extends  FormRequest
+{
+
+    /**
+     * rules
+     *
+     * @return array
+     */
+    public function rules(): array
+    {
+        return [
+                'name' => [
+                'required',
+                function ($attribute, $value, $fail) {
+                    $has = NoticeTypes::where('is_deleted', 0)->where('name', $value)->value('id');
+                    if (!empty($has)) {
+                        $fail("分类已存在!");
+                    }
+                }
+            ]
+        ];
+    }
+    /**
+     * messages
+     *
+     * @return string[]
+     */
+    public function messages(): array
+    {
+        return [
+            'name.required' => '分类名称必须填写',
+        ];
+    }
+}

+ 32 - 0
modules/System/Installer.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace Modules\ContentManage;
+
+use Catch\Support\Module\Installer as ModuleInstaller;
+use Modules\ContentManage\Providers\ContentManageServiceProvider;
+
+class Installer extends ModuleInstaller
+{
+    protected function info(): array
+    {
+        // TODO: Implement info() method.
+        return [
+            'title' => '内容中台',
+            'name' => 'contentManage',
+            'path' => 'contentManage',
+            'keywords' => '内容中台',
+            'description' => '内容中台管理模块',
+            'provider' => ContentManageServiceProvider::class
+        ];
+    }
+
+    protected function requirePackages(): void
+    {
+        // TODO: Implement requirePackages() method.
+    }
+
+    protected function removePackages(): void
+    {
+        // TODO: Implement removePackages() method.
+    }
+}

+ 26 - 0
modules/System/Middlewares/ContentManageGate.php

@@ -0,0 +1,26 @@
+<?php
+
+namespace Modules\ContentManage\Middlewares;
+
+use Illuminate\Http\Request;
+use Modules\ContentManage\Exceptions\PermissionForbidden;
+use Modules\User\Models\User;
+
+class ContentManageGate
+{
+    public function handle(Request $request, \Closure $next)
+    {
+        if ($request->isMethod('get')) {
+            return $next($request);
+        }
+
+        /* @var User $user */
+        $user = $request->user(getGuardName());
+
+        if (! $user->can()) {
+            throw new PermissionForbidden();
+        }
+
+        return $next($request);
+    }
+}

+ 30 - 0
modules/System/Models/BaseModel.php

@@ -0,0 +1,30 @@
+<?php
+
+namespace Modules\ContentManage\Models;
+
+use Catch\Base\CatchModel as Model;
+use Illuminate\Database\Eloquent\Builder;
+
+
+abstract class BaseModel extends Model
+{
+
+    protected array $defaultHidden = [];
+
+    protected array $defaultCasts = [
+        'created_at' => 'datetime:Y-m-d H:i:s',
+
+        'updated_at' => 'datetime:Y-m-d H:i:s',
+    ];
+    protected $dateFormat = '';
+
+    public static function bootSoftDeletes(): void{
+
+    }
+
+
+    public function scopeActive(Builder $query): void
+    {
+        $query->where($this->table.'.is_enabled', 1);
+    }
+}

+ 15 - 0
modules/System/Models/NoticeTypes.php

@@ -0,0 +1,15 @@
+<?php
+
+namespace Modules\System\Models;
+
+
+
+class NoticeTypes extends BaseModel
+{
+    protected $table = 'notice_types';
+
+    protected $fillable = [
+        'id', 'name', 'is_deleted', 'created_at', 'updated_at', 'deleted_at',
+    ];
+
+}

+ 73 - 0
modules/System/Models/Notices.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace Modules\System\Models;
+
+
+class Notices extends BaseModel
+{
+    protected $table = 'notices';
+
+    protected $fillable = [
+        'id', 'title', 'content', 'notice_type_id', "sort", 'type', 'notice_obj', 'is_popup', 'is_deleted', 'created_at', 'updated_at', 'deleted_at',
+    ];
+
+    /**
+     * @var array
+     */
+    protected array $fields = ['id', 'title', 'content', "sort", 'notice_type_id', 'type', 'notice_obj', 'is_popup', 'created_at', 'updated_at'];
+
+    /**
+     * @var array
+     */
+    protected array $form = ['title', 'content', 'notice_type_id',"sort", 'type', 'notice_obj', 'is_popup'];
+
+
+    protected $casts = ['notice_obj' => 'array'];
+
+    public array $searchable = [
+        'title' => 'like',
+        'notice_type_id' => '=',
+        'type' => '=',
+
+    ];
+
+    protected string $sortField = 'sort';
+
+
+
+    /**
+     *  添加通知
+     * @param array $data
+     * @return bool
+     * @throws \ReflectionException
+     */
+    public function storeBy(array $data): mixed
+    {
+        $result = '';
+        $this->beginTransaction();
+        try {
+            $result = $this->create($this->filterData($data));
+            if (isset($data['user_ids']) && !empty($data['user_ids'])) {
+                $this->addUserNotice($data['user_ids'], $result->id);
+            }
+            $this->commit();
+        } catch (\Exception $exception) {
+            $this->rollback();
+        }
+        return $result->id ?? 0;
+    }
+
+    private function addUserNotice(mixed $userIds, mixed $id)
+    {
+        $list = [];
+        foreach ($userIds as $val) {
+            $list[] = ['user_id' => $val, 'notice_id' => $id];
+        }
+        if (!empty($list)) {
+            UserNotice::insert($list);
+        }
+        return true;
+    }
+
+
+}

+ 14 - 0
modules/System/Models/UserNotice.php

@@ -0,0 +1,14 @@
+<?php
+
+namespace Modules\System\Models;
+
+
+class UserNotice extends BaseModel
+{
+    protected $table = 'user_notice';
+
+    protected $fillable = [
+        'id', 'user_id', 'notice_id', 'is_deleted', 'is_read', 'created_at', 'updated_at', 'deleted_at',
+    ];
+
+}

+ 31 - 0
modules/System/Providers/ContentManageServiceProvider.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace Modules\System\Providers;
+
+use Catch\CatchAdmin;
+use Catch\Providers\CatchModuleServiceProvider;
+use Modules\ContentManage\Middlewares\ContentManageGate;
+
+class ContentManageServiceProvider extends CatchModuleServiceProvider
+{
+    /**
+     * middlewares
+     *
+     * @return string[]
+     */
+    protected function middlewares(): array
+    {
+       return [ContentManageGate::class];
+    }
+
+    /**
+     * route path
+     *
+     * @return string|array
+     */
+    public function moduleName(): string|array
+    {
+        // TODO: Implement path() method.
+        return 'contentManage';
+    }
+}

+ 10 - 0
modules/System/README.md

@@ -0,0 +1,10 @@
+#内容中台管理模块
+关于内容中台 相关的后台接口,对外api接口,都写在这里
+配置文件放在: config目录下,读取配置文件示例:config('contentManage.zhushuyunpublicapi.public_domain');
+config("模块名.配置文件名.配置项");
+
+数据库模型文件放在:Models 目录下面
+服务层文件放在:Services 目录下面
+控制器放在:modules/ContentManage/Http/Controllers 目录下面
+中间件放在:modules/ContentManage/Middlewares 目录下面
+路由只能现在 modules/ContentManage/rout/route.php 文件里

+ 88 - 0
modules/System/Services/Notice/NoitceTypeService.php

@@ -0,0 +1,88 @@
+<?php
+/**
+ * ${CARET}
+ * @file:NoitceTypeService.php
+ * @Created by gnitif
+ * @Date: 2023/3/27
+ * @Time: 11:54
+ */
+
+
+namespace Modules\System\Services\Notice;
+
+use Illuminate\Support\Facades\DB;
+use Modules\ContentManage\Models\NoticeTypes;
+
+class NoitceTypeService
+{
+
+    /**
+     *  添加分类
+     * name: store
+     * @param array $param
+     * $param [
+     *      'name' => "平台通知"
+     * ];
+     * date 2023/03/27 18:14
+     */
+    public static function store(array $param)
+    {
+        return self::getModel()->storeBy($param);
+    }
+
+    protected static function getModel(){
+         return new NoticeTypes();
+    }
+
+    /**
+     *  获取通知分类列表分类
+     * name: list
+     * @param mixed $param
+     *  $param = [
+     *      'name' => '系统通知', // 分类名称模糊搜索
+     *      'page' => 1, //  页码
+     *      'limit' => 15, //  每页条数
+     * ]
+     * @param mixed $isAll // 是否获取所有数据 默认否
+     * date 2023/03/28 17:05
+     */
+    public static function list($param = [], $isAll = false)
+    {
+        $where = self::getCondition($param);
+        if ($isAll){
+            return   NoticeTypes::where($where)->select('id','name')->get();
+        }else {
+            $pageSize = $param['limit'] ?? 15;
+            return   NoticeTypes::where($where)->select('id', 'name', 'created_at')->paginate($pageSize);
+        }
+
+    }
+
+    /**
+     *  拼接查询条件
+     * name: getCondition
+     * @param mixed $param
+     * @return \string[][]
+     * date 2023/03/28 17:19
+     */
+    private static function getCondition(mixed $param)
+    {
+        $where = [['is_deleted', '=', '0']];
+        if (isset($param['name']) && !empty($param['name'])) {
+            $where[] = ['name', 'like', "%" . $param['name'] . "%"];
+        }
+        return $where;
+    }
+
+    /**
+     *  删除分类,软删除
+     * name: del
+     * @param $id
+     * @return mixed
+     * date 2023/03/29 11:05
+     */
+    public static function del($id)
+    {
+        return self::getModel()->updateBy($id,['is_deleted' => 1,'deleted_at' => date("Y-m-d H:i:s")]);
+    }
+}

+ 248 - 0
modules/System/Services/Notice/NoticesService.php

@@ -0,0 +1,248 @@
+<?php
+/**
+ * ${CARET}
+ * @file:NoitceService.php
+ * @Created by gnitif
+ * @Date: 2023/3/27
+ * @Time: 11:54
+ */
+
+
+namespace Modules\System\Services\Notice;
+
+use Catch\Exceptions\FailedException;
+use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Support\Facades\DB;
+use Modules\System\Models\Notices;
+use Modules\System\Models\UserNotice;
+use Modules\Permissions\Models\Roles;
+use Modules\User\Models\User;
+use PharIo\Manifest\Author;
+
+class NoticesService
+{
+
+    protected static function getModel()
+    {
+        return new Notices();
+    }
+
+    /**
+     *  添加通知
+     * name: addNotice
+     * @param array $param
+     *  $param = [
+     *      'title' => '测试', // 通知标题
+     *      'notice_type_id' =>  2, // 通知分类id
+     *      'type' => '2', // 通知人群 1全部 2,指定人,3指定角色
+     *      'notice_obj' => [['id' =>  1,'name' => "超管"]] , // 通知对象
+     *      'is_popup' => '1', // 是否是弹窗 1弹窗  0 普通
+     *       'content' => '312312', // 通知内容
+     * ];
+     *
+     * date 2023/03/29 14:25
+     */
+    public static function addNotice(array $param)
+    {
+
+        if ($param['type'] != 1 && (!isset($param['notice_obj']) || empty($param['notice_obj']))) {
+            throw new FailedException('通知对象不能为空!');
+        }
+
+        if ($param['type'] == 3) {
+            $roleIds = array_column($param['notice_obj'], 'id');
+            $userIds = DB::table('user_has_roles')->whereIn('role_id', $roleIds)->pluck('user_id')->toArray();
+        } else if ($param['type'] == 2) {
+            $userIds = array_column($param['notice_obj'], 'id');
+        } else {
+            $userIds = User::pluck('id')->toArray();
+            $param['notice_obj'] = [];
+        }
+        $param['user_ids'] = $userIds;
+        return self::getModel()->storeBy($param);
+    }
+
+    public static function delete($id)
+    {
+        return self::getModel()->updateBy($id, ['is_deleted' => 1, 'deleted_at' => get_date()]);
+    }
+
+    /**
+     *  获取通知详情
+     * name: getDetail
+     * @param $id
+     * @return \Illuminate\Database\Eloquent\Collection|\Illuminate\Support\Collection|Notices[]
+     * date 2023/03/29 15:12
+     */
+    public static function getDetail($id)
+    {
+        $info = Notices::leftJoin('notice_types', 'notice_types.id', 'notices.notice_type_id')
+            ->select('notices.*', 'notice_types.name as notice_type_name')->where('notices.id', $id)->first();
+        return $info;
+    }
+
+    /**
+     *  更新
+     * name: update
+     * @param $id
+     * @param array $param
+     * date 2023/03/29 18:32
+     */
+    public static function update($id, array $param)
+    {
+       return  self::getModel()->updateBy($id, $param);
+    }
+
+    /**
+     *  管理员操作通知列表
+     * name: list
+     * @return mixed
+     * date 2023/03/29 22:49
+     */
+    public static function  list()
+    {
+        $list = self::getModel()->setBeforeGetList(function ($query) {
+            return $query->where('is_deleted', 0)->orderBy('created_at','desc');
+        })->getList();
+        if (!$list->isEmpty()) {
+            $cate = NoitceTypeService::list([], true);
+            if ($cate->isEmpty()) {
+                $cate = [];
+            } else {
+                $cate = array_column($cate->toArray(), null, 'id');
+            }
+
+            foreach ($list as $value) {
+                $value->notice_type_txt = $cate[$value->notice_type_id]['name'] ?? "";
+                $value->type_txt = $value->type == 1 ? "全部" : ($value->type == 2 ? "指定用户" : "指定角色");
+            }
+        }
+        return $list;
+    }
+
+    /**
+     * 我的通知
+     * name: myNoticesList
+     * date 2023/03/29 22:49
+     */
+    public static function myNoticesList($param = [])
+    {
+        $type = $param['type'] ?? "";
+        $noticeTypeId = $param['notice_type_id'] ?? 0;
+        $title = $param['title'] ?? "";
+        $pageSize = $param['limit'] ?? 0;
+        $pageSize = $pageSize < 1 ? 15 : $pageSize;
+        $userId = Auth::guard(getGuardName())->id();
+        $where = [
+            ['user_notice.is_deleted', '=', 0],
+            ['user_notice.user_id', '=', $userId],
+            ['notices.is_deleted', '=', 0],
+            ['user_notice.is_deleted', '=', 0],
+        ];
+        if ($type) {
+            $where[] = ['notices.type', '=', $type];
+        }
+        if ($noticeTypeId) {
+            $where[] = ['notices.notice_type_id', '=', $noticeTypeId];
+        }
+        if ($title) {
+            $where[] = ['notices.title', 'like', "%" . $title . "%"];
+        }
+
+        $list = UserNotice::leftJoin('notices', 'notices.id', "user_notice.notice_id")->where($where)->select('notices.id', 'notices.title', 'notices.is_popup', "user_notice.is_read", 'notices.created_at')
+            ->orderBy('notices.created_at', 'desc')->orderBy('sort', 'desc')->paginate($pageSize);
+        if (!$list->isEmpty()) {
+            foreach ($list as $val) {
+                $val->is_read_txt = $val->is_read == 1 ? "已读" : "未读";
+            }
+        }
+        return $list;
+    }
+
+    /**
+     *  设置已读
+     * name: setRead
+     * @param $id
+     * date 2023/03/29 23:51
+     */
+    public static function setRead($id)
+    {
+        $userId = Auth::guard(getGuardName())->id();
+        return UserNotice::where('user_id', $userId)->where('notice_id', $id)->update(['is_read' => 1, 'read_at' => get_date()]);
+    }
+
+    /**
+     *  用户删除
+     * name: userDel
+     * @param $id
+     * date 2023/03/29 23:55
+     */
+    public static function userDel($id)
+    {
+        $userId = Auth::guard(getGuardName())->id();
+        return UserNotice::where('user_id', $userId)->where('notice_id', $id)->update(['is_deleted' => 1, 'deleted_at' => get_date()]);
+    }
+
+    /**
+     *  阅读详情
+     * name: detail
+     * @param $id
+     * @return Notices
+     * date 2023/03/30 00:09
+     */
+    public static function detail($id)
+    {
+        return Notices::where('id', $id)->where('is_deleted', 0)->select('title', 'id', 'is_popup', 'content')->first();
+    }
+
+    /**
+     *  获取指定对象选择项
+     * name: objOption
+     * @param $type
+     * @param string $name
+     * @return array
+     * date 2023/03/30 10:23
+     */
+    public static function objOption($type, $name = ""): mixed
+    {
+        if ($type == 'user') {
+            if ($name) {
+                return  User::where("username", 'like', "%" . $name . "%")->without(['roles','jobs'])->select('id','username as name')->get();
+            }
+            return User::select('id','username as name')->without(['roles','jobs'])->get();
+        } else if ($type == "role") {
+            if ($name) {
+                return Roles::where("role_name", 'like', "%" . $name . "%")->select('id','role_name as name')->get();
+            }
+            return Roles::select('id','role_name as name')->get();
+        }
+        return [];
+    }
+
+    /**
+     *  一条获取弹窗信息
+     * name: getPopup
+     * @return Model|UserNotice|object|null
+     * date 2023/03/30 16:45
+     */
+    public static function getPopup()
+    {
+        $where = [
+            ['user_notice.is_deleted', '=', 0],
+            ['user_notice.user_id', '=',  Auth::guard(getGuardName())->id()],
+            ['notices.is_deleted', '=', 0],
+            ['notices.is_popup', '=', 1],
+            ['user_notice.is_read', '=', 0],
+        ];
+
+         $info =  UserNotice::leftJoin('notices', 'notices.id', "user_notice.notice_id")->where($where)->select('notices.id', 'notices.title', 'notices.content')
+             ->orderBy('notices.created_at', 'desc')->orderBy('sort', 'desc')->first();
+         if (empty($info)){
+             return  [];
+         }
+         return  $info;
+    }
+
+
+}

+ 56 - 0
modules/System/routes/route.php

@@ -0,0 +1,56 @@
+<?php
+
+use Illuminate\Support\Facades\Route;
+use Modules\System\Http\Controllers\NoticesController;
+use Modules\System\Http\Controllers\NoticeTypesController;
+
+Route::prefix('system')->group(function () {
+    // 通知管理
+    Route::prefix('notices')->group(function(){
+        // 通知分类
+        Route::prefix('types')->group(function (){
+            // 添加通知分类
+            Route::post('add',[NoticeTypesController::class, 'add']);
+            // 通知分类列表
+            Route::any('list',[NoticeTypesController::class, 'list']);
+            //  删除通知分类
+            Route::post('del/{id}',[NoticeTypesController::class, 'delete']);
+        });
+        // 通知管理
+        Route::prefix('notice')->group(function(){
+            // 添加通知
+            Route::post('add',[NoticesController::class, 'addNotice']);
+            // 通知列表
+            Route::any('list',[NoticesController::class, 'list']);
+            //  删除通知
+            Route::post('del/{id}',[NoticesController::class, 'delete']);
+            //   修改通知状态
+            Route::post('enable/{id}',[NoticesController::class, 'enable']);
+            // 获取编辑信息
+            Route::get('edit/{id}',[NoticesController::class, 'info']);
+            // 保存编辑
+            Route::post('edit/{id}',[NoticesController::class, 'edit']);
+
+            // 不判断权限
+            Route::prefix("")->group(function (){
+                // 通知对象接口
+                Route::any('obj_option',[NoticesController::class, 'objOption'])->withoutMiddleware(config('catch.route.middlewares'));
+                // 我的通知
+                Route::any('mine',[NoticesController::class, 'myNotices'])->withoutMiddleware(config('catch.route.middlewares'));
+                //  已读
+                Route::get('read/{id}',[NoticesController::class, 'setRead'])->withoutMiddleware(config('catch.route.middlewares'));
+                // 用户删除
+                Route::get('user_del/{id}',[NoticesController::class, 'userDel'])->withoutMiddleware(config('catch.route.middlewares'));
+                // 查看通知信息
+                Route::any('detail/{id}',[NoticesController::class, 'detail'])->withoutMiddleware(config('catch.route.middlewares'));
+                // 获取首页弹窗消息
+                Route::any('popup',[NoticesController::class, 'getPopup'])->withoutMiddleware(config('catch.route.middlewares'));
+
+            });
+
+        });
+
+    });
+
+});
+