const http = require('http') const BASE = { host: 'localhost', port: 5054, headers: { 'X-Mp-Timeassistant': 'mp_node_smoke_ok', 'Content-Type': 'application/json; charset=utf-8', 'Accept': 'application/json; charset=utf-8' } } function req(method, path, bodyObj) { return new Promise((resolve, reject) => { const bodyBuf = bodyObj ? Buffer.from(JSON.stringify(bodyObj), 'utf8') : null const req = http.request({ ...BASE, method, path, headers: { ...BASE.headers, 'Content-Length': bodyBuf ? bodyBuf.length : 0 } }, (res) => { let data = [] res.on('data', (c) => data.push(c)) res.on('end', () => { const text = Buffer.concat(data).toString('utf8') try { resolve({ status: res.statusCode, headers: res.headers, body: text ? JSON.parse(text) : null, text }) } catch (e) { resolve({ status: res.statusCode, headers: res.headers, text }) } }) }) req.on('error', reject) if (bodyBuf) req.write(bodyBuf) req.end() }) } ;(async () => { console.log('\n=== 1. GET /api/mp_time_assistant/meta (kits应=2 不应有hub_only中转) ===') const r1 = await req('GET', '/api/mp_time_assistant/meta') console.log('status', r1.status, 'CT', r1.headers['content-type']) console.log('ok=', r1.body.ok, 'kits.Count=', r1.body.kits ? r1.body.kits.length : 0) if (r1.body.kits) r1.body.kits.forEach((k) => console.log(' kit:', JSON.stringify(k))) console.log('\n=== 2. POST /cards 新建中文卡 title="今天练背日" (UTF-8 JSON) ===') const r2 = await req('POST', '/api/mp_rep_clock/kits/rep_clock/cards', { title: '今天练背日', loopMode: 'loop_n_times', loopCount: 3, steps: [ { name: '高位下拉', durationSec: 60, restSec: 20, type: 'action' }, { name: '坐姿划船', durationSec: 60, restSec: 20, type: 'action' }, ], }) console.log('status', r2.status, 'CT=', r2.headers['content-type']) const c = r2.body.card console.log('card.id=', c.id) console.log('card.title (JSON)=', JSON.stringify(c.title), ' codePoints=', Array.from(c.title).map((ch) => ch.charCodeAt(0).toString(16)).join(' ')) console.log('card.loopMode=', c.loopMode, 'loopTimes=', c.loopTimes, 'voice=', c.voice, 'ttsReady=', c.ttsReady) console.log('card.steps[0]: name=', JSON.stringify(c.steps[0].name), 'restSec=', c.steps[0].restSec) console.log('card.steps[1]: name=', JSON.stringify(c.steps[1].name), 'restSec=', c.steps[1].restSec) const id = c.id console.log('\n=== 3. GET /cards 再查回刚写入的中文卡 ===') const r3 = await req('GET', '/api/mp_rep_clock/kits/rep_clock/cards') const found = (r3.body.cards || r3.body.data || []).find((x) => x.id === id) console.log('found=', !!found) if (found) { console.log('title=', JSON.stringify(found.title)) console.log('loopTimes=', found.loopTimes, ' voice=', found.voice, ' ttsReady=', found.ttsReady) found.steps.forEach((s, i) => console.log(` step[${i}] name=${JSON.stringify(s.name)} restSec=${s.restSec}`)) } console.log('\n=== 4. GET personal_collect 独立前缀 独立DB是否联通 ===') const r4 = await req('GET', '/api/mp_personal_collect/kits/personal_collect/items') console.log('status', r4.status, 'ok=', r4.body.ok, 'items/data.Count=', (r4.body.items || r4.body.data || []).length) console.log('\n=== ALL SMOKE PASSED if title=中文正常显示 ===') })().catch((e) => { console.error('ERR', e); process.exit(1) })