From cc7857e00905a8a3bb33522a822c7e7dce0be231 Mon Sep 17 00:00:00 2001 From: Trae Assistant Date: Mon, 5 Oct 2026 13:55:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E7=9B=B4=E6=8E=A5=E5=8A=A0=E4=B9=89?= =?UTF-8?q?=E5=B7=A5=E6=97=B6=E7=9A=84=E8=A1=A5=E5=BD=95=E6=B4=BB=E5=8A=A8?= =?UTF-8?q?=E6=97=B6=E9=97=B4=E6=94=B9=E4=B8=BA=E7=9C=9F=E5=AE=9E=E6=8F=90?= =?UTF-8?q?=E4=BA=A4=E5=BD=93=E5=A4=A9=EF=BC=88=E4=B8=8D=E5=86=8D=E6=98=AF?= =?UTF-8?q?=202024-01-01=20=E5=81=87=E6=97=B6=E9=97=B4=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - hours.ts POST /direct-add: · 不再复用单一『【补录】直接加义工时长』活动(之前 start_time 硬编码 2024-01-01 00:00 会在所有活动列表/详情里显示错时间) · 改为每次提交取 SQLite datetime('now','+8 hours') 真实 UTC+8 时刻, 活动标题按日期拼接:『【补录】YYYY-MM-DD 直接加义工时长』 · start_time / end_time 都设为提交这一刻的 YYYY-MM-DD HH:MM, 同一日内多次提交会复用同日期活动;不同日期自动建独立活动 · 响应额外返回 direct_add_activity_title / direct_add_activity_time 便于前端以后 toast 里显示 - 新增容错:last_insert_rowid() 取不到活动就 ROLLBACK + 返回 500, 防止 hours 行悬挂到无效 activity_id --- server/src/routes/hours.ts | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/server/src/routes/hours.ts b/server/src/routes/hours.ts index c8aa058..af576ad 100644 --- a/server/src/routes/hours.ts +++ b/server/src/routes/hours.ts @@ -36,7 +36,7 @@ router.post('/batch', authMiddleware, (req: AuthRequest, res: Response) => { } }); -const DIRECT_ADD_TITLE = '【补录】直接加义工时长'; +const DIRECT_ADD_TITLE_PREFIX = '【补录】'; router.post('/direct-add', authMiddleware, (req: AuthRequest, res: Response) => { const { items } = req.body || {}; @@ -68,13 +68,21 @@ router.post('/direct-add', authMiddleware, (req: AuthRequest, res: Response) => return res.status(400).json({ error: errors.join(';') }); } db.execCompat('BEGIN'); - let act = db.prepareCompat('SELECT * FROM activities WHERE title = ?').get(DIRECT_ADD_TITLE) as any; + const nowLocal = (db.prepareCompat(`SELECT datetime('now','+8 hours') AS ts`).get() as any)?.ts || new Date().toISOString().slice(0, 19).replace('T', ' '); + const dayStr = String(nowLocal).slice(0, 10); + const actTitle = `${DIRECT_ADD_TITLE_PREFIX}${dayStr} 直接加义工时长`; + let act = db.prepareCompat('SELECT * FROM activities WHERE title = ? AND DATE(start_time) = ?').get(actTitle, dayStr) as any; if (!act) { + const timeStr = String(nowLocal).slice(0, 16); db.prepareCompat(` INSERT INTO activities (title, content, start_time, end_time) VALUES (?, ?, ?, ?) - `).run(DIRECT_ADD_TITLE, '管理台直接补录义工时长,不绑定真实活动', '2024-01-01 00:00', '2099-12-31 23:59'); - act = db.prepareCompat('SELECT * FROM activities WHERE title = ?').get(DIRECT_ADD_TITLE) as any; + `).run(actTitle, `管理台于 ${timeStr} 直接补录义工时长,不绑定真实活动`, timeStr, timeStr); + act = db.prepareCompat('SELECT * FROM activities WHERE id = last_insert_rowid()').get() as any; + } + if (!act) { + db.execCompat('ROLLBACK'); + return res.status(500).json({ error: '无法创建补录活动记录' }); } const insert = db.prepareCompat(` INSERT INTO hours (activity_id, user_id, hours, remark) @@ -100,6 +108,8 @@ router.post('/direct-add', authMiddleware, (req: AuthRequest, res: Response) => total_hours: results.reduce((s, r) => s + r.hours, 0), results, direct_add_activity_id: act.id, + direct_add_activity_title: act.title, + direct_add_activity_time: act.start_time, }); } catch (e: any) { try { db.execCompat('ROLLBACK'); } catch {}