feat: 新增运动节拍训练工具套件与子工具页面
新增运动节拍RepClock全套小程序页面、后端API与数据库服务,新增subhub子工具汇总页面,优化全局主页样式与配置,为web静态资源添加版本缓存参数,补充配套调试脚本
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
const path = require('path')
|
||||
process.chdir('d:/Trae_Files/TRAE-Toolbox')
|
||||
const http = require('http')
|
||||
const db = require(path.join(process.cwd(), 'src/server/mp_rep_clock/db'))
|
||||
const locks = require(path.join(process.cwd(), 'src/server/mp_rep_clock/locks'))
|
||||
const store = require(path.join(process.cwd(), 'src/server/mp_rep_clock/kits/rep_clock/store'))
|
||||
|
||||
// 清锁先
|
||||
locks.resetRunningLock()
|
||||
const nowIso = () => new Date().toISOString()
|
||||
db.getDb().prepare(`UPDATE rc_sessions SET status='abandoned', ended_at=?, updated_at=?, manual_stopped=1 WHERE status='running' AND deleted=0`).run(nowIso(), nowIso())
|
||||
|
||||
const cardId = 'rc_card_c6aebdfb-7330-43c1-b42c-a6a856a715f2'
|
||||
|
||||
// 1. 直接 Node 层 reserve + createSession,模拟"第一发start成功"
|
||||
const s1 = store.createSession({ cardId })
|
||||
const r1 = locks.reserveRunningLock(s1.id)
|
||||
console.log('== 1st createSession OK ==')
|
||||
console.log('session1 id:', s1.id, 'status=', s1.status)
|
||||
console.log('lock reserve1:', JSON.stringify(r1))
|
||||
|
||||
// 2. 再调用一次 createSession(第二发 start 模拟冲突),但不清锁
|
||||
const s2 = store.createSession({ cardId })
|
||||
const r2 = locks.reserveRunningLock(s2.id)
|
||||
console.log('\n== 2nd 故意冲突 ==')
|
||||
console.log('session2 id:', s2.id)
|
||||
console.log('lock reserve2:', JSON.stringify(r2))
|
||||
console.log('字段检查:expiresInMs 存在?', typeof r2.expiresInMs, r2.expiresInMs, '秒=', Math.ceil(r2.expiresInMs/1000))
|
||||
|
||||
// 3. 再用 HTTP 调 sessions/start 直接看 409 body(等价于用户 curl)
|
||||
console.log('\n== 3rd HTTP POST sessions/start ==')
|
||||
const payload = JSON.stringify({ cardId })
|
||||
const req = http.request({
|
||||
hostname: '127.0.0.1', port: 8976,
|
||||
path: '/api/mp_rep_clock/kits/rep_clock/sessions/start',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json; charset=utf-8',
|
||||
'Content-Length': Buffer.byteLength(payload),
|
||||
'X-Mp-Timeassistant': 'probe_v1',
|
||||
}
|
||||
}, (res) => {
|
||||
let buf = ''
|
||||
res.on('data', c => buf += c)
|
||||
res.on('end', () => {
|
||||
console.log('HTTP', res.statusCode)
|
||||
console.log('BODY:', buf)
|
||||
try {
|
||||
const j = JSON.parse(buf)
|
||||
console.log('字段检查 expiresInMs =', j.expiresInMs, '秒=', Math.ceil(j.expiresInMs/1000))
|
||||
console.log('字段检查 conflictSessionId =', j.conflictSessionId)
|
||||
console.log('字段检查 expiredLockCleared =', j.expiredLockCleared)
|
||||
} catch(e){ console.log('not json:', e.message) }
|
||||
})
|
||||
})
|
||||
req.on('error', e => console.log('err', e.message))
|
||||
req.write(payload)
|
||||
req.end()
|
||||
Reference in New Issue
Block a user