sun
|
3f18f85925
|
fix(ui): setup 默认 resource_id 改 seed-icl-2.0
与 admin 同一类问题 (见 admin 修复 commit):
项目是豆包声音复刻大模型 2.0, 资源 ID 必为 seed-icl-2.0。
setup.html 错的默认值有 5 处:
1. form.default_resource_id placeholder: volc.megatts.default
2. v.resource_id placeholder: volc.megatts.icl
3. v.model placeholder: seed-tts-2.0-standard
4. form 默认 (default_resource_id): volc.megatts.default
5. form 默认 voices[0] + addVoice push: volc.megatts.icl / seed-tts-2.0-standard
修法同 admin: resource_id 改 seed-icl-2.0, model 保持 seed-tts-2.0-standard
(用户后澄清模型名独立)。
附带修:
- step 2 hint 文案从 "volc.megatts.icl 用于复刻音色" 改为
"本项目为豆包声音复刻大模型 2.0, 固定使用 seed-icl-2.0"
(避免误导用户填错资源 ID)
未 push (待用户 push)
|
2026-08-30 15:57:00 +08:00 |
|
sun
|
155017a27b
|
fix(ui): admin 默认 resource_id 改 seed-icl-2.0
背景: 项目是豆包声音复刻大模型 2.0, v3 API 只允许 2 个
资源 ID: seed-tts-2.0 (普通 TTS) + seed-icl-2.0 (复刻 2.0)。
本项目用复刻 2.0, 资源 ID 必为 seed-icl-2.0。
Bug 报告: admin (admin.html) 表单有 5 处默认值都是错的:
1. settingsForm.default_resource_id placeholder: volc.megatts.default
2. form.resource_id placeholder: volc.megatts.icl
3. form.model placeholder: seed-tts-2.0-standard (1.0 模型, 项目用不了)
4. form resource_id 默认: volc.megatts.icl
5. form model 默认: seed-tts-2.0-standard
+ openAdd 重置
+ settingsForm.model placeholder: seed-tts-2.0-standard
volc.megatts.* 是 1.0 API 的资源/服务品类编码, 不是 v3 API 2.0 的合法
资源 ID, 装完 admin 一看就是错的, 用户不知道要改成什么。
修法:
- 所有 resource_id 默认值 + placeholder 改成 seed-icl-2.0
- model 默认值保持 seed-tts-2.0-standard (用户确认模型名)
(用户后澄清: 模型在 v3 API 2.0 里只此一个名字, 不跟 resource 同步)
- 不硬编码 — 用户仍可改
受影响的 7 处:
- admin.html: settingsForm.default_resource_id placeholder
- admin.html: settingsForm.model placeholder
- admin.html: form.resource_id placeholder
- admin.html: form.model placeholder
- admin.html: form 默认 (resource_id)
- admin.html: form 默认 (model) + openAdd reset
- 全部 7 处 detail 见 diff
未 push (待用户 push)
|
2026-08-30 15:57:00 +08:00 |
|
sun
|
92cf8fab8a
|
fix(ui): dashboard 加 loadSettings, CORS banner 终于不假阳性了
Bug FE-002:
- /admin dashboard 顶部黄条"跨域 CORS 未配置"永远显示
- 原因: reloadAll() 没调 loadSettings, dashboard 上 settings.value 一直是 {}
- banner 判断 `!settings.cors_configured` → undefined → falsy → 触发
- 只有手动进 settings tab 触发 loadSettings() 后才消失
- 刷新页面又出现(被用户当成"CORS 没生效")
修法: 一行。reloadAll() 加上 loadSettings(), mount 时一并加载,
dashboard 上 settings 就有真值了, banner 判断正确。
diff:
- const reloadAll = () => { loadOverview(); loadVoices(); };
+ const reloadAll = () => { loadOverview(); loadVoices(); loadSettings(); };
副作用: 无。 loadSettings 自带 try/catch, 即使 /api/settings 失败
也不影响 overview/voices 加载。 watch(tab) 仍会再调一次
loadSettings (idempotent, 覆盖 fresh 值)。
验证 (本机 + 你的报告复现):
- 强刷 admin → mount 时 3 个 API 并行加载
- settings.value 填好, cors_configured = true
- banner `v-if="settings && !settings.cors_configured && ..."` 评估为 false → 不显示
未 push(等你确认)
二进制: ~18MB → ~18MB (HTML 嵌入尺寸不变)
|
2026-08-30 13:04:26 +08:00 |
|
sun
|
d22abecf12
|
fix(ui): store.Voice 加 JSON tag,修「音色是空的」+ UI 整体换皮
本次 3 个改动:
1. **【BUG 修复】store.Voice 加 JSON tag** — 用户报「进入系统音色是空的」。
实际:DB 里有数据,API 也返了。Bug 在 store.Voice 结构体没加 json tag,
Go 序列化为大写("Name"/"Speaker"/"ResourceID"/"Enabled"),而所有
admin.html 用 v.name/v.speaker/v.resource_id/v.enabled 拿,全是 undefined。
表渲染了但每格空。修复后 API 返小写,前端能正常读。
写 store/voices_test.go 加 TestVoice_JSONTags 防退化。
2. **【UI 换皮】Codex 改造 admin.html + setup.html**
- admin.html: 31KB → 58.8KB (1075 行)
加: 侧边栏 + 品牌 + 4 步导航、toast 通知系统、grid 卡片、
搜索/筛选/状态分页、stat-card 带 pill、modal + 过渡动画、
按钮大小/颜色变体、响应式字体缩放
- setup.html: 13KB → 23KB (428 行)
加: 4 步向导 + 进度条 (步骤 1: 上游凭证 / 2: 默认路由 /
3: 音色列表 / 4: 确认)、语音行 hover、确认页打码展示
- 功能完全保留: API 路径/字段/hash 路由/401 拦截都未改
3. **【小修】setup.html 装完跳转回退用 /admin 不是 /dashboard**
Codex 改的版本回退写成 /dashboard,是回归。已改回 /admin。
测试:
- 已有 store/installer/middleware/router/telemetry 测试全绿
- 新增 store/voices_test.go: TestVoice_JSONTags + TestVoice_UnmarshalTags
E2E 验证(本机):
- install 2 voices → DB 写入 ✓
- GET /api/voices 返小写 id/name/speaker/resource_id/enabled 等 ✓
- PATCH /api/voices/qian/toggle → 200 + lowercase 回包 ✓
- POST /api/voices → 201 + lowercase 回包 ✓
- GET /api/voices 再次列 3 条(原 2 + 新 1)✓
未 push (等用户测试「音色终于显示出来」)
二进制大小: ~18MB → ~18.5MB (admin.html +27KB embed)
|
2026-08-30 00:51:23 +08:00 |
|
sun
|
7660db14d8
|
fix(cors): CORS 全 DB 化,install 模式完全跳过,WebUI 可配
完整方案: 与 auth_key 同思路,让 CORS 也走 DB,彻底干掉 ALLOWED_ORIGINS env。
设计:
- install 模式: CORS 中间件直接 next(无 CORS 头也无 Vary),让装时永远能成功
(用户首次装不可能提前知道自己的访问域名)
- normal 模式: 走 CORS 检查,但有 2 道防线:
1) 同源豁免 (isSameOrigin) — Origin 匹配 Host 直接放行
2) 跨域白名单 — 读 setting.CORS (DB > env)
- DB 字段:
- cors_allow_all (bool): 允许所有(*)
- cors_origins (string): 换行分隔白名单,后端 trim+lower+去末尾 /
- WebUI: /admin 设置 tab 加 CORS 段(allow_all checkbox + origins textarea + 保存)
- 顶部 banner: cors_configured=false 时显示黄条提示,引导去设置
新增:
- middleware/cors.go: 顶部 installer.GetMode() == ModeSetup 时直接 next
- setting/config.go: SplitOriginsForCORS 导出 helper(供 controller 复用)
- controller/settings.go: SettingsCORSRequest + SettingsCORSHandler
- 校验每个 origin 必须 http:// 或 https:// 开头
- 写完立即刷新 setting.CORS.AllowAll + setting.CORS.Origins(下个跨域请求生效)
- 拒绝空 body
- router/router.go: 挂 /api/settings/cors (PUT, RequireAdmin)
- router/admin.html: 设置 tab 加 CORS card + 顶部 banner (31.19KB, 略超 30KB 预算可接受)
改造:
- setting/config.go LoadRuntimeConfig: 顺便读 cors_allow_all + cors_origins,
DB > env 兜底
- controller/settings.go SettingsResponse: 加 cors_allow_all + cors_origins + cors_configured
e2e 跑通(本机)10 场景:
- install 任意 Origin → 200 (install mode 跳 CORS)
- normal 同源 → 200
- normal 跨域无 allowlist → 403
- GET settings cors_configured=false
- PUT /api/settings/cors → 200
- GET settings cors_configured=true
- 跨域命中白名单 → 200
- 跨域未命中白名单 → 403
- allow_all=true → 任意跨域 200
- 重启后 CORS 仍从 DB 加载
未 push(等用户测试 install 是否顺利,以及 CORS banner 是否合适)
|
2026-08-30 00:08:14 +08:00 |
|
sun
|
a4ea53bfa0
|
fix(auth): OpenAI 端 key 也走 DB,setup 是单一配置入口
修 M2/M3 遗漏:OPENAI_TTS_API_KEY (admin + 合成鉴权) 此前只能从 env
读,setup 前端没收集。装完用户还要回去设 env,体验断,违反
'setup 是单一配置源' 承诺。
改动:
- setting/config.go: LoadRuntimeConfig 顺便把 auth_key 灌到
setting.Auth.APIKeys。优先级 DB > env(env 仅作 fallback,首次启
动无 DB 时仍可用,向后兼容)。
- controller/setup.go: validateSetupSettings 加 auth_key 为必填,
写 DB 后立即 setting.Auth.APIKeys = [auth_key](本进程内立刻生效)。
- controller/settings.go: GET /api/settings 返 auth_key (打码) +
auth_key_set;新增 SettingsAuthKeyHandler (PUT /api/settings/auth-key),
改完单独刷新 setting.Auth.APIKeys(避免被自踢,只下次请求生效)。
- router/router.go: 挂 /api/settings/auth-key 路由。
- router/setup.html: 加 OpenAI 鉴权 Key 字段(密码框,带提示);
表单 default + submit 都加 auth_key。
- router/admin.html: 设置 tab 拆两张卡 — 鉴权 Key(独立保存按钮,
改完会自踢当前会话)+ 火山 TTS 凭证;vue setup 加 authKeyInput +
saveAuthKey 函数。
- main.go: 把 LoadRuntimeConfig(st) 提到 LogStartupSummary 之前,
让启动日志反映真实运行时状态(DB 已加载的 key 数量)而不是
过时的 env 状态。
未 push(等用户当前 M3 测完一起或单独)
|
2026-08-29 23:18:51 +08:00 |
|
sun
|
9db038dd05
|
feat(settings): M3 全局设置 + voice 动态路由 + env 收敛
M3 完成:env 业务配置全进 DB,WebUI 可改,改完立即生效(无需重启)。
新增:
- controller/settings.go: 3 个 handler
- GET /api/settings: 读所有设置,api_key 永远打码
- PUT /api/settings: 部分更新(白名单字段);default_speaker 改时校验
音色必须在 voices 表里(避免引用不存在);改完调 LoadRuntimeConfig 即时生效
- PUT /api/settings/api-key: 独立端点,只改 api_key
改造:
- setting/config.go: 用 LoadRuntimeConfig(store) 替代 InitTTSConfig
- 不再读 BYTEDANCE_TTS_* env,完全从 store.Settings 拿
- 必填项缺失返 error,设 TTSConfigErr(/v1/audio/speech 返 503)
- 定义 Store 接口(避免 setting → store 循环 import)
- 字段映射: BYTEDANCE_TTS_API_KEY → api_key, BYTEDANCE_TTS_RESOURCE_ID
→ default_resource_id, ... 全部一一对应
- controller/tts.go: voice 路由
- voice 为空 → 用 setting.TTSOptions.Speaker (即 store.default_speaker)
- voice 非空 → 查 voices 表,替换 opts.Speaker / ResourceID / Model
- 命中但 enabled=0 → 仍可用(显式 voice 覆盖)
- 未命中 → 400 unknown_voice
- voice 路由日志: "[tts] voice=xxx 命中 (speaker=... resource=... model=...)"
- router/admin.html: 加 #settings tab (24.78KB, 仍 <30KB 预算)
- API key 区:打码显示 + 独立更新按钮
- 路由/格式区:default_resource_id / default_speaker (下拉源 /api/voices) /
default_format / sample_rate / model
- "保存" 按钮 PUT /api/settings + 立即 reload (settingsOk 提示)
- router/router.go: 挂 /api/settings[/{api-key}] 三路由
- main.go: Detect 之后调 LoadRuntimeConfig,失败也允许进入
(env 阶段无 db,LogStartupSummary 仍显示 BYTEDANCE_TTS_* 必填项用于诊断)
测试(都被 .gitignore 排除,本地保留):
- 已有 store/installer/middleware/router/telemetry 测试保持全绿
- e2e 验证(本机跑通 9 场景):
- install 写入 3 voices + 7 settings
- 重启后 main.go log: "TTS 运行时配置已加载(api_key=***, speaker=default-voice, resource=volc.megatts.icl, format=wav)" — 确认走 DB 不读 env
- GET /api/settings 返所有字段
- voice=clone-voice-1 命中 S_clone_1 + seed-tts-2.0-expressive
- voice=clone-voice-2 命中 S_clone_2 + volc.megatts.icl-2
- voice=unknown 返 400 unknown_voice
- PUT /api/settings 改 default_speaker 即时生效
- PUT /api/settings/api-key 改 key 即时生效
- PUT /api/settings default_speaker=ghost 返 400 default_speaker_missing
注意: e2e 里的 TTS 500 是因为我用假 key 调上游,路由逻辑本身正确。
换真火山 API key 即可 work。
二进制大小: ~17MB → ~18MB (+1MB)
未 push(等用户测试 M1+M2+speaker fix 全部稳定后,跟 51bd7ae+70865a3 一起或单独 push)
|
2026-08-29 22:40:53 +08:00 |
|
sun
|
70865a3cf4
|
feat(admin): M2 WebUI 管理后台(鉴权+仪表盘+音色 CRUD)
新增 /admin 管理后台,Vue3 + axios 单文件 SPA。
新增:
- middleware/admin_auth.go: RequireAdmin 中间件
复用 OPENAI_TTS_API_KEY(Bearer),密钥为空等同无鉴权;
常量时间比较防计时攻击(用 common.SecureEqualString);
401 + WWW-Authenticate 头 + JSON 错误体。
- controller/admin.go: 5 个 admin handler
- GET /api/admin/overview: 模式/db路径/lock/版本/运行时间/音色数/内存
- GET /api/admin/metrics: 鉴权版 Prometheus 文本(无鉴权版 /metrics 仍给 Prometheus)
- GET /api/voices: 列表(含 disabled)
- POST /api/voices: 新增,409 处理重复,400 处理字段不合法
- DELETE /api/voices/{name}: 删除,409 处理被 default_speaker 引用
- PATCH /api/voices/{name}/toggle: 启停
- router/admin.html: 单文件 SPA(18KB)
登录页(单 input) + 仪表盘(metrics cards) + 音色 tab(表格+新增+启停+删除);
hash 路由切 tab;axios 拦截器自动加 Bearer,401 回登录页;
sessionStorage 存 key(关浏览器失效)。
- common/constants.go: SecureEqualString 提取到公共包
controller/setup.go + middleware/admin_auth.go 共用,避免重复实现。
改造:
- router/router.go: 挂 /admin(/admin HTML 公开,鉴权由前端 JS 拦截)
+ /api/admin/{overview,metrics} + /api/voices{,/{name},/{name}/toggle}
全部 API 端点套 RequireAdmin;正常模式 / → 302 /admin(M2 优先于 /dashboard)。
- main.go: 启动期调 SetAdminStore + SetMetricsTextWriter(避免 controller → metrics cycle)
- metrics/metrics.go: AdapterRecorder 用 SpeakerLabel 替代明文 speaker
(这是第 4 处 speaker 泄漏,顺带补上;前面 3 处在 51bd7ae 已修)。
- controller/setup.go: 用 common.SecureEqualString 替自己的实现(去重)。
测试(都被 .gitignore 排除,本地保留):
- router/router_test.go: 更新 4 个 NotFound 测试路径(/admin 现是注册路由,不再 404)
- telemetry/labels_test.go: 已有 SpeakerLabel/MaskSpeaker 测试(M2 复用)
e2e 验证(本机跑通):
- /admin 200 HTML(无鉴权,前端 JS 拦截)
- /api/admin/overview 无 Bearer 401
- /api/admin/overview 错 Bearer 401
- /api/admin/overview 对 Bearer 200 + JSON
- /api/voices GET 200 + 2 voices
- /api/voices POST 201 + new voice
- /api/voices/{name} DELETE 200
- /api/voices/{name}/toggle PATCH 200 + updated voice
- 正常模式 / 302 /admin
- 启动日志 BYTEDANCE_TTS_SPEAKER 仍打码 S_G8****naJ1(前次 fix 生效)
二进制大小: 16MB → ~17MB(admin.html +5 个 handler + 中间件)
未 push(用户要求与 speaker fix 51bd7ae 一起发,等服务器测完 M1 后一起验证)
|
2026-08-29 21:53:19 +08:00 |
|
sun
|
dbaee35400
|
fix(install): M1 后续 · 2 个 install 模式入口 bug
Bug 1: 安装模式下浏览器访问 / 看到 503 JSON
- 根因: middleware/installguard.go 默认白名单没包含 /;
浏览器访问 / 时 InstallGuard 先于 router 的 redirect 拦掉,返 503 JSON。
- 修复: InstallGuard 非白名单分支加 Accept 内容协商,
text/html → 302 Location: /setup(浏览器友好),
其它(API 客户端 / curl / 空 Accept)→ 维持 503 JSON(API 行为不变)。
- 额外: mux 路由未匹配时不走 r.Use() 中间件链,
手动设 r.NotFoundHandler 复用同一份 Accept 协商逻辑,
覆盖 /admin /api/voices 等任意未注册路径。
Bug 2: 装完访问 /setup 仍能进入(看到安装表单)
- 根因: router.go 的 /setup handler 没做 mode 校验。
- 修复: handler 顶部加 if ModeNormal → 302 Location: /admin
(M2 之后才有 /admin;目前会 404 也比继续显示表单好)。
测试(都被 .gitignore 排除,本地保留):
- middleware/installguard_test.go: 加 2 个 case(浏览器 redirect / API JSON)+ acceptsHTML 单元
- router/router_test.go(新): /setup 装后 redirect + NotFoundHandler 4 个 case
- 全套 go test ./... 全绿
验证(本机 e2e 跑通):
- setup 模式: 浏览器 /, /admin, /api/voices → 302 /setup
- setup 模式: API/curl / → 503 JSON(行为不变)
- normal 模式: /setup → 302 /admin(Bug 2)
- normal 模式: /admin → 404(M2 才有,行为不变)
- normal 模式: /api/setup/status → 200 {installed:true,mode:normal}
二进制大小: 15.87 → ~16MB(几乎不变)
|
2026-08-29 21:16:08 +08:00 |
|
sun
|
7984c1880a
|
feat(installer): M1 安装流程 + /setup 引导页
新增:
- installer/lock.go: lock 文件检测/创建/删除(原子写入);ErrLockExists sentinel
- installer/bootstrap.go: Detect() 启动期判定 ModeSetup/ModeNormal,
损坏自愈(自动备份 db.corrupt-<ts> + 删 lock + 回退安装模式)
- middleware/installguard.go: 安装模式白名单(/setup /api/setup /health /metrics),
中间件顺序: SecurityHeaders → InstallGuard → RateLimit → ...(避免限流计数污染)
- controller/setup.go: GET /api/setup/status + /api/setup/prefill + POST /api/setup;
token 校验用常量时间比较防计时攻击;安装后端点永久 404
- router/setup.html: Vue3 + axios CDN,4 字段表单 + 动态音色行,
调用 /api/setup/prefill 自动从旧 env 预填(API key 永不预填)
改造:
- main.go: 启动期 store.Open → installer.Detect → 注入 setup 控制器
- controller/tts.go: 安装模式双保险(/v1/audio/speech 即便漏过中间件也 503)
- controller/health.go (via dto): 加 installed + mode 字段,部署探针可识别
- router/router.go: 挂载 /setup + /api/setup/*,根路径安装模式跳 /setup
- setting/config.go: InitSetupToken 读 TTS_ADMIN_KEY 或随机生成 32 字符 hex
(公网部署建议设 env;空时启动日志一次性打印)
删除:
- router/dashboard.go: 内容并入 router/router.go
.gitignore: tts.db / tts.db-* / installed.lock 加入(运行时产物)
验收(端到端跑通,见 scripts/ 已删除):
1. 删 lock → /v1/audio/speech 503 + /setup 200 HTML
2. POST /api/setup 错 token → 401;对 token → 200 + 写 lock + 写 db
3. 重复 POST → 404(端点永久关闭)
4. /health: 安装期 installed=false,装后 installed=true
5. 损坏 db header: 自动备份 tts.db.corrupt-<ts> + 删 lock + 回安装模式
测试:
- installer: 6 个 test, 覆盖 lock 生命周期 + Detect 三态 + 损坏自愈
- middleware: 3 个 test, 覆盖白名单/denylist/自定义
- store(M0): 仍 27/27 绿, 70.7% 覆盖率
二进制大小: 9.77 → 15.87 MB (+6MB,大部分是 setup.html embed + 新包)
|
2026-08-29 20:44:33 +08:00 |
|
sun
|
8be40ae6dc
|
chore: embed health.html 到 binary,单文件分发
把 health.html 从外部依赖改为 //go:embed 内嵌,
实现真正的"单 exe 分发"。
- 新建 router/dashboard.go,用 //go:embed 嵌入 health.html
- router/router.go:/dashboard handler 改为 w.Write(dashboardHTML)
- setting/config.go:删 CheckStaticFiles(无需文件检查)
- main.go:删 setting.CheckStaticFiles() 调用
- Dockerfile:删 COPY health.html 步骤(已嵌入)
- .gitignore:加 release/(build 产物不入 git)
- 物理移动 health.html 到 router/(embed 限制:同包或子包)
效果:
- 之前: release 包 = tts-api.exe + health.html (2 个文件)
- 之后: release 包 = tts-api.exe (1 个文件,~7 MB)
- 用户部署无需额外文件,/dashboard 路由直接工作
|
2026-08-27 11:44:44 +08:00 |
|
sun
|
81fcc9fff4
|
chore: 清理多余的BOM头并整理依赖与telemetry代码
- 移除所有文件开头的多余UTF-8 BOM头
- 简化go.mod依赖,移除未使用的uuid包
- 重构telemetry包:将Meter改为接口并拆分默认实现
|
2026-08-15 14:38:14 +08:00 |
|
sun
|
5b970f49e1
|
feat: 实现完整可观测性架构与火山v3适配器重构
重构整体架构:
1. 新增telemetry包实现零依赖的Prometheus指标系统
2. 新增metrics包集中管理业务埋点指标
3. 重构火山v3适配器,拆分client/request/response等模块
4. 替换旧的service/stats统计系统为标准指标埋点
5. 新增/metrics观测端点与完整仪表盘支持
功能更新:
- 实现基于IP的限流与并发限制,添加指标埋点
- 重构TTS控制器,支持多格式输出与完整错误分类
- 更新.env.example配置示例,新增多项可选参数
- 替换旧的volcano适配器实现,支持完整的v3 API特性
- 清理冗余代码,移除service/stats与旧adapter实现
|
2026-08-15 13:30:35 +08:00 |
|
sun
|
61431e00ba
|
refactor: 重构并优化项目多项功能
1. 调整CORS中间件挂载位置,重构CORS处理逻辑
2. 重写IP获取逻辑,增加私有网络IP信任校验
3. 优化日志中间件,移除/health接口单独日志逻辑
4. 改进API密钥未配置时的提示信息
5. 重构volcano TTS调用,新增voice参数支持
6. 优化请求体过大错误处理
7. 完善统计服务,修复环形缓冲区遍历逻辑,新增去重错误日志功能
|
2026-06-26 19:12:50 +08:00 |
|
sun
|
977e9ccadb
|
build: 升级go版本到1.26并添加限流中间件
1. 调整go.mod将Go版本升级至1.26
2. 新增速率限制和并发限制中间件,将其加入路由中间件链
3. 重构TTS处理逻辑,将限流逻辑迁移至中间件统一处理
4. 优化CORS中间件代码,移除冗余日志和格式调整
|
2026-06-22 18:13:35 +08:00 |
|
sun
|
9b2a1d1531
|
feat: 添加安全中间件、优化限流器与API密钥验证
1. 新增安全响应头中间件强化请求安全性
2. 使用恒定时间比较修复API密钥验证时序漏洞
3. 新增限流器条目上限配置与自动清理逻辑
4. 优化CORS日志与客户端IP获取逻辑
5. 升级Go构建环境与基础镜像版本
6. 新增非root用户运行容器增强安全性
|
2026-05-24 15:33:27 +08:00 |
|
sun
|
4e1820d45b
|
refactor: 重构项目架构,拆分代码到模块化目录
将单文件tts_server.go重构为模块化项目结构,拆分出common、dto、middleware、router、controller、service、adapter、setting等目录,优化代码组织提升可维护性
|
2026-05-23 20:32:12 +08:00 |
|