diff --git a/app/admin/controller/system/Notice.php b/app/admin/controller/system/Notice.php new file mode 100644 index 0000000..c01299e --- /dev/null +++ b/app/admin/controller/system/Notice.php @@ -0,0 +1,14 @@ + 'desc', + ]; + + /** + * 行内属性修改允许的字段(通知主体由系统流程生成,暂不开放字段; + * 保留标准白名单结构,下游可按需放开). + * @var array + */ + protected $allowModifyFields = []; + + public function __construct(App $app) + { + parent::__construct($app); + + $this->model = new SystemNotice(); + + // 场景标题映射(scene 等值搜索下拉与列表徽章共用;data_brage 通道下发) + $sceneOptions = []; + foreach (NoticeService::scenes() as $scene => $item) { + $sceneOptions[$scene] = $item['title']; + } + $this->assign('select_list_scene', $sceneOptions, true); + } + + /** + * @NodeAnotation(title="列表") + */ + public function index() + { + if ($this->request->isAjax()) { + if (input('selectFields')) { + return $this->selectList(); + } + list($page, $limit, $where) = $this->buildTableParames(); + $count = $this->model + ->where($where) + ->count(); + $list = $this->model + ->where($where) + ->page($page, $limit) + ->order($this->sort) + ->select(); + + // 发送者昵称:system_admin 与主表存在同名字段,禁用 withJoin 预载; + // 单查昵称缓存后循环附加 + $senderIds = array_values(array_filter(array_unique($list->column('send_admin_id')))); + $nicknames = []; + if (!empty($senderIds)) { + $nicknames = SystemAdmin::whereIn('id', $senderIds)->column('nickname', 'id'); + } + foreach ($list as $row) { + $row['send_admin_nickname'] = $nicknames[$row['send_admin_id']] ?? ''; + } + + $data = [ + 'code' => 0, + 'msg' => '', + 'count' => $count, + 'data' => $list, + ]; + + return json($data); + } + + return $this->fetch(); + } + + /** + * @NodeAnotation(title="详情") + */ + public function read($id) + { + $row = $this->model->find($id); + empty($row) && $this->error('数据不存在'); + + // 发送者昵称(单查,勿 withJoin,同列表口径) + $senderNickname = ''; + if (!empty($row->send_admin_id)) { + $senderNickname = SystemAdmin::where('id', $row->send_admin_id)->value('nickname') ?: ''; + } + + // 投递汇总:channel × status 聚合计数(一条 group 查询) + $groups = SystemNoticeTarget::where('notice_id', $id) + ->field('channel,status,count(*) as cnt') + ->group('channel,status') + ->select(); + $statusCount = []; + foreach ($groups as $group) { + $statusCount[$group['channel']][$group['status']] = (int) $group['cnt']; + } + + $channelNames = [ + NoticeService::CHANNEL_INMAIL => '站内信', + NoticeService::CHANNEL_EMAIL => '邮件', + NoticeService::CHANNEL_SMS => '短信', + NoticeService::CHANNEL_WECHAT => '公众号', + ]; + $delivery = []; + foreach ($statusCount as $channel => $counts) { + $delivery[] = [ + 'channel' => $channel, + 'channel_name' => $channelNames[$channel] ?? $channel, + 'pending' => $counts[SystemNoticeTarget::STATUS_PENDING] ?? 0, + 'sending' => $counts[SystemNoticeTarget::STATUS_SENDING] ?? 0, + 'success' => $counts[SystemNoticeTarget::STATUS_SUCCESS] ?? 0, + 'failed' => $counts[SystemNoticeTarget::STATUS_FAILED] ?? 0, + ]; + } + + // 场景标题(scenes() 动态映射,未注册场景回退原值) + $sceneTitle = NoticeService::scenes()[$row->scene]['title'] ?? $row->scene; + + $this->assign('row', $row); + $this->assign('title', $row->title); + $this->assign('sender_nickname', $senderNickname); + $this->assign('scene_title', $sceneTitle); + $this->assign('delivery', $delivery); + + return $this->fetch(); + } + + /** + * @NodeAnotation(title="删除") + */ + public function delete($id) + { + $this->checkPostRequest(); + $row = $this->model->whereIn('id', $id)->select(); + $row->isEmpty() && $this->error('数据不存在'); + try { + // 模型启用软删(delete_time),delete 即软删;投递行保留不级联 + $save = $row->delete(); + } catch (\Exception $e) { + $this->error('删除失败:' . $e->getMessage()); + } + $save ? $this->success('删除成功') : $this->error('删除失败'); + } + + /** + * @NodeAnotation(title="属性修改") + */ + public function modify() + { + $this->checkPostRequest(); + $post = $this->request->post(); + $rule = [ + 'id|ID' => 'require', + 'field|字段' => 'require', + 'value|值' => 'require', + ]; + $this->validate($post, $rule); + if (!in_array($post['field'], $this->allowModifyFields)) { + $this->error('该字段不允许修改:' . $post['field']); + } + $row = $this->model->find($post['id']); + empty($row) && $this->error('数据不存在'); + try { + $save = $row->save([$post['field'] => $post['value']]); + } catch (\Exception $e) { + $this->error($e->getMessage()); + } + $save ? $this->success('保存成功') : $this->error('未做变更'); + } +} diff --git a/extend/base/admin/view/system/notice/_common.js b/extend/base/admin/view/system/notice/_common.js new file mode 100644 index 0000000..f0e296c --- /dev/null +++ b/extend/base/admin/view/system/notice/_common.js @@ -0,0 +1,11 @@ +var init = { + tableElem: '#currentTable', + tableRenderId: 'currentTableRenderId', + indexUrl: 'system.notice/index', + addUrl: '', + editUrl: '', + readUrl: 'system.notice/read', + deleteUrl: 'system.notice/delete', + exportUrl: '', + modifyUrl: 'system.notice/modify', +}; diff --git a/extend/base/admin/view/system/notice/index.html b/extend/base/admin/view/system/notice/index.html new file mode 100644 index 0000000..9475165 --- /dev/null +++ b/extend/base/admin/view/system/notice/index.html @@ -0,0 +1,7 @@ +