Rodger-Wang
|
ed73e96376
|
fix(console):固件和产品图按产品绑定的应用分目录,不再写死 EAIMAR
Co-authored-by: Cursor <cursoragent@cursor.com>
|
7 days ago |
Rodger-Wang
|
2cf260eb05
|
服务端:音乐模块与腾讯云 COS 整体下线;新增分发桶(App 安装包与录音/固件分开放)
音乐:sys/music、sys/musicobj、modules/music、mcp/tool_music.go 全部删除,home 的
模块列表与 musicobj 初始化、两份 yaml 模板里的 musicobj 段一并去掉。起因是它的
ApiBaseUrl 指向上一代品牌域名;客户端的音乐模块本来就早已删除。
⚠️ 咪咕音乐(tool_migu_music + migu 服务)没有动,别一起当成音乐链路删了。
腾讯云 COS:sys/tencentyun 整个删除,home/api 的 cos.OnInit 与配置段、
comm.svcRuntimeSections 的 cos 托管一并去掉。头像上传改走阿里云 OSS(与
user_getuploadurl、console 后台直传同一个桶)。modules/api/api_getcostoken.go 是
孤儿(后台调的其实是 console 那个同名路由,客户端从不调),删除。后台两处的
腾讯云 COS 卡片/模板与巡检探针也删——服务端读存储配置的唯一入口只认
provider=aliyun_oss,留着是「配得上却不生效」的陷阱。存量 tencent_cos 行不动。
⚠️ 老客户端仍读业务库 config 表的 COS_* 直传腾讯云,那 5 个键别删;历史录音的
audiourl 是 COS 绝对地址,不会自动搬家。
分发桶:comm.AliyunOSSConf 加 DistBucket/DistDomain(留空用 ymai-dl /
dl.ymaikj.com),凭据与主桶共用。后台「上传 APK」走 api_getcostoken 带
target:"dist":key 不加 EAIMAR 根前缀(分发桶直接挂在 dl.ymaikj.com 上)、目录走
白名单、按应用分子目录(一个桶放多个应用,不分目录会静默互相覆盖)。
⚠️ Content-Type 由服务端按扩展名强制并回带给前端:浏览器对 .apk 给出的 File.type
往往是空串,前端照它发 PUT 会与预签名不符、OSS 回 403,而报错里完全看不出是类型
对不上。⚠️ 分发桶必须单独配 CORS(来源 console.ymaikj.com、方法 PUT),
浏览器直传打的是桶的 OSS endpoint 而不是自定义域名。
另含下载落地页 deploy/dl(含 OSS 部署教程)与各 deploy 脚本/README 的同步更新。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
3 weeks ago |
Rodger-Wang
|
3709aa6e3b
|
services: 语音纪要 ASR 按优先级自动回退;翻译区分「语种不支持」与瞬时失败;OSS 配置在作用域归一后可兜底定位
- echomeet: SubmitTranscribeTask 首选 ASR 失败时按 Priority 依次尝试其它启用的识别服务,
并把 AsrSvcId 写回任务,回调才能找到对的服务;原先一次失败就 TranscribeFail
- user_translate: 阿里 10005/10033(语向不支持/语种拼写错)不再当成瞬时错误,
直接回「该语言暂不支持翻译」;挪威语 nb-NO/nn-NO/no-NO 映射到 no
- model_translate: 「跳过未接入 MT 服务」的告警去重,不再刷满日志
- ossconf: appName 为空时按指纹唯一匹配(作用域归一后全局行已不存在)
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
4 weeks ago |
Rodger-Wang
|
8d580a545d
|
文件上传改走服务端签发预签名 URL,客户端直传阿里云 OSS
客户端不再持有对象存储的长期密钥。
旧实现用腾讯云 COS SDK 直连,bucket 与 SecretId/SecretKey 明文随
user_getappconfig 的 env 下发给每一个 App 用户(config 表的 COS_* 那几个键)。
抓包或反编译就能拿到这对长期密钥,而它对整个桶有读写权限——不只是自己那部分,
User/ 下所有人的录音都能被拉走或删掉。
现在:新增 user_getuploadurl,服务端签发 15 分钟有效、且只对某一个 object key
生效的阿里云 OSS 预签名 PUT URL,客户端拿着它直传。存储与 console 后台传固件/
产品图同一个桶(ymaioss),不再是两个云厂商两套存储。
服务端
- 新接口 modules/user/api_getuploadurl.go:
· object key 由服务端拼死 EAIMAR/User/<uid>/<scene>/<yyyy/MM/dd>/<12位随机>.<ext>,
uid 取自会话不采信客户端,客户端连自己传到谁的目录下都决定不了;
· scene 白名单 LocalAudio / TranslatAudio / ExternalAudio / ChatImages
——加新场景前要把客户端 addUpload 与 UploadOss.upload 的调用点全捞一遍,
少一个值就是那条链路整条报错,且只在真机跑到才发现;
· 扩展名白名单决定 Content-Type,不在表里直接拒,不回退成
application/octet-stream(那等于把桶变成任人上传的网盘);
· 随机名用 crypto/rand 而非 math/rand:key 可枚举就等于别人能猜到录音地址。
- 抽出 comm/ossconf.go:OSS 配置读取、上传根前缀、publicURL 拼接从 console 挪来,
console 改为调用它。两边必须落同一个桶,各写一份迟早漂移。
解密用 ${FIELD_ENCRYPT_KEY},console 与业务服务本就必须配同一把。
客户端
- upload_oss.dart 重写为「要 URL → dio 流式 PUT」,upload() 签名与返回值不变,
MeetingUploadService 不用改。用独立 Dio 实例:项目那个挂着 AuthInterceptor,
会加 token 与业务签名头、还会把响应按业务 JSON 解析,直传 OSS 时全是多余,
签名头还可能与预签名冲突。
- Content-Type 必须用服务端回带的值,它计入了签名,写别的会 403。
- agent 图片的 rootDir 从 'User/<uid>/ChatImages' 改成 'ChatImages':
前缀由服务端加,客户端再拼一层就是重复路径。
真机验证:录音落到
https://oss.ymaikj.com/EAIMAR/User/<uid>/LocalAudio/2026/09/04/howXMScPdsNP.wav,
下载 212524B 与库里 size 逐字节一致,Content-Type=audio/wav,文件头 RIFF/WAVE。
其余三个 scene 走同一段代码但尚未实跑。
⚠️ 新老客户端并存:老包仍读 COS_* 直传腾讯云,config 表里那 5 个键先别删;
历史录音的 audiourl 是 COS 绝对地址,不会自动搬家。
⚠️ 录音目前仍是公共可读的(bucket 公共读,实测匿名 GET 206、不存在的 key 404),
只靠 12 位随机 key 不可猜测来保护。要锁住得转私有桶 + 播放时也签临时读 URL,未做。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
1 month ago |