feat(voice): 大神语音介绍真实落地(录制/上传/试听)

- DB: companions.voice_intro_url;仓储 updateCompanionVoice;详情与 /api/expert/me 返回 voiceIntroUrl/voiceDuration
- 后端: POST /api/companions/:id/voice(音频白名单 mp3/m4a/aac/wav/ogg、5MB、≤60s、限流、仅本人或管理员)
- 小程序: api.uploadVoiceIntro(uni.uploadFile + 用户令牌);工作台新增「语音介绍」卡片(录制/重录/试听,60s mp3);详情页改为 uni.createInnerAudioContext 真实播放,卸载销毁
- 修复 uploadImage 未携带用户令牌(生产 fail-closed 后会导致上传失败)
- 新增 voice-intro.spec.ts(104 套件/701 用例全绿);冒烟 7/7
这个提交包含在:
xcbyy
2026-10-20 18:25:11 +08:00
父节点 d9fe43302b
当前提交 720cb97877
共有 7 个文件被更改,包括 346 次插入 和 11 次删除

查看文件

@@ -95,6 +95,7 @@ export async function initDatabase(): Promise<void> {
hourly_rate INT NOT NULL,
voice_duration INT DEFAULT 15,
voice_title VARCHAR(128),
voice_intro_url VARCHAR(255) DEFAULT '',
rating DECIMAL(3,2) DEFAULT 4.90,
order_count INT DEFAULT 0,
status VARCHAR(32) DEFAULT '接单中',
@@ -115,6 +116,9 @@ export async function initDatabase(): Promise<void> {
try {
await conn.query("ALTER TABLE companions ADD COLUMN reject_reason VARCHAR(255) DEFAULT '' AFTER audit_status");
} catch (_) {}
try {
await conn.query("ALTER TABLE companions ADD COLUMN voice_intro_url VARCHAR(255) NOT NULL DEFAULT '' AFTER voice_title");
} catch (_) {}
// 4. 订单表
await conn.query(`