[ [ 'title' => '启用模板', 'value' => (int)Db::name('message_templates')->where('is_enabled', 1)->count(), 'desc' => '当前已启用的消息模板数量', ], [ 'title' => '触发规则', 'value' => (int)Db::name('message_rules')->where('is_enabled', 1)->count(), 'desc' => '当前启用的消息触发规则数量', ], [ 'title' => '发送日志', 'value' => (int)Db::name('message_logs')->count(), 'desc' => '消息发送记录总数', ], [ 'title' => '站内消息', 'value' => (int)Db::name('user_messages')->count(), 'desc' => '当前已生成的站内消息数量', ], ], ]); } public function templates(Request $request) { $rows = Db::name('message_templates') ->field([ 'id', 'template_name', 'template_code', 'channel', 'event_code', 'title', 'content', 'is_enabled', ]) ->order('id', 'asc') ->select() ->toArray(); $list = array_map(function (array $item) { return [ 'id' => (int)$item['id'], 'template_name' => $item['template_name'], 'template_code' => $item['template_code'], 'channel' => $item['channel'], 'channel_text' => $this->channelText($item['channel']), 'event_code' => $item['event_code'], 'title' => $item['title'], 'content' => $item['content'], 'is_enabled' => (bool)$item['is_enabled'], ]; }, $rows); return api_success(['list' => $list]); } public function saveTemplate(Request $request) { $id = (int)$request->input('id', 0); $templateName = trim((string)$request->input('template_name', '')); $templateCode = trim((string)$request->input('template_code', '')); $channel = trim((string)$request->input('channel', '')); $eventCode = trim((string)$request->input('event_code', '')); if ($templateName === '' || $templateCode === '' || $channel === '' || $eventCode === '') { return api_error('模板名称、模板编码、发送渠道和触发事件不能为空', 422); } $payload = [ 'template_name' => $templateName, 'template_code' => $templateCode, 'channel' => $channel, 'event_code' => $eventCode, 'title' => trim((string)$request->input('title', '')), 'content' => trim((string)$request->input('content', '')), 'is_enabled' => $request->input('is_enabled', true) ? 1 : 0, 'updated_at' => date('Y-m-d H:i:s'), ]; if ($id > 0) { Db::name('message_templates')->where('id', $id)->update($payload); return api_success(['id' => $id], '更新成功'); } $payload['created_at'] = date('Y-m-d H:i:s'); $newId = Db::name('message_templates')->insertGetId($payload); return api_success(['id' => (int)$newId], '创建成功'); } public function logs(Request $request) { $rows = Db::name('message_logs') ->field([ 'id', 'user_id', 'template_id', 'biz_type', 'biz_id', 'channel', 'status', 'fail_reason', 'sent_at', 'created_at', ]) ->order('id', 'desc') ->select() ->toArray(); $templates = Db::name('message_templates')->column('template_name', 'id'); $list = array_map(function (array $item) use ($templates) { return [ 'id' => (int)$item['id'], 'user_id' => (int)($item['user_id'] ?? 0), 'template_name' => $templates[$item['template_id']] ?? '未知模板', 'biz_type' => $item['biz_type'], 'biz_id' => (int)($item['biz_id'] ?? 0), 'channel' => $item['channel'], 'channel_text' => $this->channelText($item['channel']), 'status' => $item['status'], 'status_text' => $this->logStatusText($item['status']), 'fail_reason' => $item['fail_reason'] ?: '', 'sent_at' => $item['sent_at'], 'created_at' => $item['created_at'], ]; }, $rows); return api_success(['list' => $list]); } private function channelText(string $channel): string { return match ($channel) { 'inbox' => '站内消息', 'sms' => '短信', 'wechat_subscribe' => '微信订阅消息', default => $channel, }; } private function logStatusText(string $status): string { return match ($status) { 'pending' => '待发送', 'sent' => '已发送', 'failed' => '发送失败', default => $status, }; } }