fix: data-action buttons, sources enabled, email notify, ticket detail single-page

- app.js: mount page objects via inline script (CSP blocks eval → data-action buttons dead)
- app.js: add tickets list entry to sidebar nav (admin could not find claimed tickets)
- sources: GET /sources?manage=1 returns enabled field for admin view
- mailer: sendNotifyEmail consumes email-type notification_configs (webhook_url = recipients)
- tickets: trigger notify on created/claimed/transferred/updated/status-change
- notifications: email type shows recipient field, validates email list
- ticket-detail: single-page chat flow (player/staff bubbles) + processing log timeline
- css: chat bubble styles
This commit is contained in:
2026-08-22 20:00:12 +08:00
parent e5a1d693f1
commit c5ceba7cf0
9 changed files with 120 additions and 37 deletions

View File

@@ -19,14 +19,19 @@
const express = require('express');
const { query, getRow } = require('../db');
const { authenticate, requireRole } = require('../middleware/auth');
const { authenticate, optionalAuth, requireRole } = require('../middleware/auth');
const { logSystem } = require('../logger');
const router = express.Router();
// ---- 来源列表(公开: 注册页/绑定身份页需要) ----
router.get('/', async (req, res) => {
// ---- 来源列表 ----
// 公开(注册页/绑定身份页): 仅启用项, 不含 enabled
// ?manage=1(authenticate owner/admin): 全量含 enabled, 供来源管理页显示/切换状态
router.get('/', optionalAuth, async (req, res) => {
try {
if (req.query.manage === '1' && req.user && ['owner','admin'].includes(req.user.role)) {
return res.json(await query('SELECT code, label, sort_order, enabled FROM sources ORDER BY sort_order, id'));
}
const rows = await query('SELECT code, label, sort_order FROM sources WHERE enabled = 1 ORDER BY sort_order, id');
res.json(rows);
} catch (e) { res.status(500).json({ error: e.message }); }