Files
Toolbox/dev_test_scripts/debug/debug_repclock_encoding.js
yangxiangyuan d4bf3627fd feat: 新增运动节拍训练工具套件与子工具页面
新增运动节拍RepClock全套小程序页面、后端API与数据库服务,新增subhub子工具汇总页面,优化全局主页样式与配置,为web静态资源添加版本缓存参数,补充配套调试脚本
2026-09-09 14:43:06 +08:00

59 lines
3.3 KiB
JavaScript

const http = require('http')
const BASE = { host: 'localhost', port: 5053, headers: { 'Content-Type': 'application/json; charset=utf-8', 'X-Mp-Timeassistant': 'mp_node_client_enc_test_xxx' } }
const post = (path, obj) => new Promise((res, rej) => {
const body = Buffer.from(JSON.stringify(obj), 'utf8')
const req = http.request({ ...BASE, method: 'POST', path, headers: { ...BASE.headers, 'Content-Length': body.length } }, (r) => {
let data = []
r.on('data', (c) => data.push(c))
r.on('end', () => { try { res({ status: r.statusCode, headers: r.headers, body: JSON.parse(Buffer.concat(data).toString('utf8')) }) } catch (e) { rej(e) } })
})
req.on('error', rej)
req.write(body); req.end()
})
const get = (path) => new Promise((res, rej) => {
http.get({ ...BASE, path }, (r) => {
let data = []
r.on('data', (c) => data.push(c))
r.on('end', () => { try { res({ status: r.statusCode, body: JSON.parse(Buffer.concat(data).toString('utf8')) }) } catch (e) { rej(e) } })
}).on('error', rej)
})
;(async () => {
console.log('=== Step1: POST /cards via UTF-8 JSON (like WeChat mini-program) ===')
const body = {
title: '瑜伽垫上腰部运动',
loopMode: 'loop_n_times',
loopCount: 2,
steps: [
{ name: '热身动作', durationSec: 30, restSec: 10, type: 'action' },
{ name: '平板支撑', durationSec: 45, restSec: 15, type: 'action' },
],
}
const pr = await post('/api/mp_rep_clock/kits/rep_clock/cards', body)
console.log('POST status=', pr.status)
const c = pr.body.card
console.log('card.id:', c.id)
console.log('card.title (JSON.stringify):', JSON.stringify(c.title), ' chars:', Array.from(c.title).map((ch) => ch.charCodeAt(0).toString(16).padStart(4, '0')).join(' '))
console.log('card.loopTimes:', c.loopTimes, ' voice:', c.voice, ' ttsReady:', c.ttsReady)
console.log('card.steps:')
c.steps.forEach((s, i) => console.log(` [${i}] name=${JSON.stringify(s.name)} durationSec=${s.durationSec} restSec=${s.restSec} type=${s.type}`))
console.log('\n=== Step2: GET /cards ===')
const gr = await get('/api/mp_rep_clock/kits/rep_clock/cards')
const c0 = gr.body.cards[0]
console.log('cards[0].title=', JSON.stringify(c0.title))
console.log('cards[0].ttsReady=', c0.ttsReady, ' loopTimes=', c0.loopTimes, ' voice=', c0.voice)
c0.steps.forEach((s, i) => console.log(` [${i}] name=${JSON.stringify(s.name)} restSec=${s.restSec}`))
console.log('\n=== Step3: HEX dump directly from DB to prove storage ===')
const Database = require('better-sqlite3')
const path = require('path')
const db = new Database(path.join(process.cwd(), 'data', 'mp_rep_clock.db'))
const row = db.prepare(`SELECT id, hex(title) ht, hex(steps_json) hsj FROM rc_cards WHERE id=? ORDER BY rowid DESC LIMIT 1`).get(c.id)
console.log('DB hex(title):', row.ht.substring(0, 200))
const titleFromDb = Buffer.from(row.ht, 'hex').toString('utf8')
console.log('DB decoded title:', JSON.stringify(titleFromDb))
const stepsParsed = JSON.parse(Buffer.from(row.hsj, 'hex').toString('utf8'))
stepsParsed.forEach((s, i) => console.log(` DB steps[${i}] name=${JSON.stringify(s.name)} restSec=${s.restSec}`))
console.log('\n=== ALL ENCODING CHECKS PASSED if title decoded correctly above ===')
})().catch((e) => { console.error('ERR', e); process.exit(1) })