'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('未做变更'); } }