621 Commits

Author SHA1 Message Date
小鱼开发 5547844aa3 chore(docker): api/scheduler 容器增加 TZ=Asia/Shanghai 时区配置 2026-05-08 16:26:10 +08:00
小鱼开发 2fd279075d fix(ui): toast 增加去重和数量上限,避免相同消息堆积
- 相同消息和类型的 toast 已存在时,移除旧的再添加新的(刷新计时器)
- 限制同时显示的 toast 最多 5 个,超出时移除最早的
2026-05-08 16:18:13 +08:00
小鱼开发 834c28613f fix(ui): 登录过程中不再切换整个表单为 loading 状态,修复页面跳动
- authStore.login() 原来设置了 isLoading=true,导致 Login.tsx 把
  整个表单替换为 loading-state,请求返回后又切回表单,高度变化导致跳动
- 去掉 login 中的 isLoading 状态变更,登录过程只通过按钮的局部
  logging 状态显示 loading 动画,表单始终保持显示
2026-05-08 16:15:34 +08:00
小鱼开发 4fc409b226 fix(ui): 登录按钮 transition 去掉 transform,修复点击时抖动
- .login-btn 的 transition: all 导致 hover 的 translateY(-1px) 到
  disabled 的 transform:none 之间有过渡动画,视觉上按钮往下跳
- 限制 transition 只过渡 opacity 和 box-shadow,transform 变化瞬时不抖动
2026-05-08 16:09:00 +08:00
小鱼开发 8b9f983d8f fix(ui): 登录按钮增加 flex 居中,修复点击时内容抖动
- .login-btn 原来没有 display:flex,纯文本和 inline-flex loading
  切换时基线对齐方式不同导致内容跳动
- 统一用 flex + align-items/justify-content: center 保持居中稳定
2026-05-08 16:06:25 +08:00
小鱼开发 bc3bd45d18 fix(toast): ToastContainer 移到全局挂载,修复登录页错误提示不显示
- ToastContainer 原来放在 isAuthenticated 条件渲染的 div 内,
  未登录时 display:none 导致 toast 不可见
- 移到 App 最外层,登录/已登录状态都能正常显示
2026-05-08 16:00:44 +08:00
小鱼开发 4a0e7d37eb fix(docker): 将 scripts/ 目录复制到镜像中 2026-05-08 15:17:09 +08:00
小鱼开发 5f5dc2242c feat(cli): 添加 create_user 脚本,绕过短信直接创建用户
用法:
    python -m scripts.create_user --mobile 13800138000 --nickname 测试用户
    python -m scripts.create_user --mobile 13800138001 --device-id dev-001

自动创建关联的 user_points 记录,可选创建 user_devices 记录。
2026-05-08 14:51:53 +08:00
小鱼开发 fbef15ba7e chore(alembic): 重建单一初始迁移脚本
- 合并为单一初始全量迁移,覆盖 users/user_devices/user_points/point_batches/point_transactions/point_recharge_orders
- 去掉所有 ForeignKey 约束(业务层软删除,不依赖数据库级联)
- 去掉不必要的索引,仅保留 Unique 约束自带索引
- 修复 mjk_users.id 为 UUID 类型(非 String(36))
- 修复 user_device.last_active_at 时区类型一致性(添加 timezone=True)
2026-05-08 14:40:22 +08:00
小鱼开发 d1ab7b8866 fix(alembic): mjk_users/mjk_user_devices id 和 user_id 改为 UUID 类型
与模型定义(BaseModel.id = UUID)和积分表外键保持一致。
2026-05-08 14:16:07 +08:00
小鱼开发 71086bd912 fix(alembic): 第一个迁移脚本兼容新数据库
32ec168f2552 原设计为增量迁移(假设 mjk_users 表已存在),
但新数据库从零开始时表不存在,导致 ALTER TABLE 失败。

修改:upgrade() 中先检查 mjk_users 表是否存在:
- 不存在 → 用 create_table 创建完整表(含所有字段)
- 存在 → 保持原有 add_column 行为

downgrade() 保持不变。
2026-05-08 14:02:09 +08:00
小鱼开发 2d9538c324 fix(docker): Dockerfile 复制 alembic.ini 和 alembic/ 目录到镜像
api 服务启动命令包含 alembic upgrade head,
需要在镜像中包含 alembic 配置文件和迁移脚本。
2026-05-08 13:51:08 +08:00
小鱼开发 f1a4e34ac7 feat(docker): 测试环境 compose 添加自动迁移 + healthcheck
- api 服务启动时自动执行 alembic upgrade head,再启动 uvicorn
- api 添加 healthcheck(/health 端点检查)
- scheduler 添加 healthcheck(导入检查)
2026-05-08 13:43:15 +08:00
小鱼开发 eeb5b0bd47 chore: 升级 FastAPI 0.135.3 → 0.136.1
同时更新 requirements.lock 中相关依赖:
- starlette 1.0.0
- urllib3 2.7.0
- volcengine-python-sdk 5.0.25 → 5.0.26

注:auth.py 中 Request 参数保持 Request = None 写法,
因为 FastAPI 不支持 Request | None 作为注入参数类型注解
(FastAPI 用 lenient_issubclass 检查,Union 类型无法通过)。
2026-05-08 12:10:29 +08:00
小鱼开发 43bbb4ea22 fix: FastAPI Request 参数类型回退,修复 Docker 启动失败
FastAPI 0.135.3 无法正确识别 Request | None Union 类型作为注入参数,
回退为 Request = None(运行时 FastAPI 会自动注入 Request 对象)。
2026-05-08 11:34:47 +08:00
小鱼开发 b597d715c8 fix: 认证流程修复 + alembic 迁移补全 + 前端僵尸代码清理
后端:
- 修复 get_current_user 未校验 is_active,被封禁用户仍可用旧 Token
- auth.py 捕获 ValueError 转 HTTPException(验证码错误、账号被封、Token 无效等不再返回 500)
- 修正 SMS 每日上限注释(3次 → 10次)
- 修复迁移脚本外键引用错误:users.id → mjk_users.id
- 新建积分系统 4 张表的迁移(mjk_user_points/batches/transactions/recharge_orders)
- pyproject.toml 补充 alembic + psycopg2-binary 依赖
- ruff 格式修复(import 排序等)

前端:
- 修复 doRefreshToken 成功后不持久化新 Token 的严重 bug
- 修复应用重启后 SSE 不自动重连(收不到踢人通知)
- 修复 App.tsx handleLogout 未 await
- client.ts 统一从 utils/env 导入 isTauri,默认 base URL 兜底 localhost:8000
- 清理 ~20 个未使用的 hooks/utils/api 模块/组件导出
- 修复所有 ESLint 警告(206 → 0)和 TSC 错误
- 测试通过(5/5)

其他:
- 更新 requirements.lock 和 uv.lock
2026-05-08 11:10:48 +08:00
小鱼开发 ec5638cef9 fix(auth): 修复联调阻塞性编译错误
- login 参数 _code → code,修正 TypeScript 编译报错
- 删除 loginWithDevice(后端无对应接口,会导致 422)
- 同步更新 authStore 测试用例字段名(token → accessToken/refreshToken)
2026-05-07 21:41:51 +08:00
小鱼开发 836721b98d feat(auth): client.ts 自动 Token 刷新(主动检查 + 401 兜底)
- 请求前检查 Access Token 是否即将过期(< 5min),主动刷新
- 收到 401 时用 Refresh Token 被动刷新并重试原请求
- 并发控制:多个请求同时触发刷新时只执行一次,其余排队等待
- Refresh Token 失效时自动抛异常,由调用方处理跳转登录
2026-05-07 21:32:19 +08:00
小鱼开发 6835d74aee feat(auth): 联调 login/logout/SSE — 双Token + 单设备踢人
- login 传完整参数(mobile/code/deviceId/deviceName/osInfo/appVersion)
- 存双 Token(accessToken + refreshToken)到状态和持久化存储
- client.ts 缓存结构改为 { accessToken, refreshToken }
- logout 先调后端 /auth/logout 再清状态
- 登录成功后自动建立 SSE 连接,接收 kick 消息
- loadFromStorage 恢复后也自动重连 SSE
- SSE 断线 3 秒后自动重连
2026-05-07 21:16:59 +08:00
小鱼开发 5080f992d9 feat(auth): SMS 日限 10 次 + 前端 send-code 联调后端 API 2026-05-07 21:10:05 +08:00
小鱼开发 530d60eb01 feat(frontend): 积分充值页面 + Rust 默认指向测试环境
- Rust storage/config.rs 默认指向 dev.tapi.meijiaka.cn
- Profile 页面增加积分余额显示
- UsageDetail 页面增加充值入口
- 新增 RechargeModal 充值弹窗组件
- 新增 points API 模块
2026-05-07 18:43:12 +08:00
小鱼开发 51521fc0dd feat(payment): 微信支付 APIv2 + 积分充值 + SMS 短信 + 双 Token 认证
- 微信支付从 APIv3 降级为 APIv2(MD5/XML)
- 积分系统:充值下单、微信回调、消费冻结/结算/退款
- SMS B2M 短信验证码服务
- 双 Token 认证(Access 30min + Refresh 30days)
- SSE 单设备踢人
- 用户设备管理、积分账户模型
- Alembic 迁移脚本
2026-05-07 18:43:02 +08:00
小鱼开发 755ecc9abe refactor(config): 统一配置体系,禁用热重载,清理兼容层
- 删除 .gitlab-ci.yml
- 删除 runtime_config.py 兼容层
- Pydantic Settings + YAML 三层配置分离
- 统一 PlatformConfigLoader 加载器
- docker-compose 移除重复 environment 覆盖
- volcengine base_url 从 YAML 读取
- 微信支付/SMS 空值启动时拦截
- 日志仅输出控制台,不写文件
- 更新 model_router 注释
2026-05-07 18:42:47 +08:00
小鱼开发 258143938c feat(works): 成品卡片增加视频时长显示
- 后端: ProductItem 新增 duration 字段,通过 ffmpeg -i 解析视频时长
- 修复: ffprobe sidecar 实际是 ffmpeg 副本,改用 ffmpeg 获取时长
- 前端: MyWorks 新增 formatDuration 格式化,卡片 meta 显示时长
- 前端: works-card-name 显示 basename(去掉 .mp4 扩展名)
2026-05-06 23:40:35 +08:00
小鱼开发 c45cb02385 fix: 七牛云 SDK 同步 I/O 阻塞事件循环
- QiniuService 新增 async 包装方法(upload_stream_async 等)
- upload.py / voice.py 上传路由改为 await async 版本
- voice.py 改用 get_qiniu_service() 单例
2026-05-06 22:56:23 +08:00
小鱼开发 d9f1a3a0ad feat: 步骤校验完善 + 封面副标题多行 + UI 微调
- VideoCreation: 各步骤下一步按钮增加前置校验(字幕/封面/合成)
- CoverDesign: 副标题改为 textarea 支持两行输入
- useCoverFabric: wrapTextByWidth 正确处理手动换行符,副标题行高加大
- ContentManagement: 成片卡片标题改回单行,底部留白压缩
- CoverDesign.css: 左侧操作区间距压缩
2026-05-06 22:05:58 +08:00
小鱼开发 e7dcb017c6 chore: update prompt files 2026-05-06 21:33:11 +08:00
小鱼开发 bb875bd127 feat: 成片卡片布局自适应 + 合成文件名使用封面主标题
- 我的作品:成片网格改为 auto-fill 自适应,封面比例修正为 9:16
- 视频合成:成品文件名从 final_projId_timestamp 改为 封面主标题_时间戳
2026-05-06 18:19:01 +08:00
小鱼开发 3059083cd4 refactor: 清理 meta.json 字段并修复素材匹配死循环
- 删除 subtitlePreset,重命名为 captionPreset 并恢复持久化
- VideoGeneration: 素材匹配结果改为视频生成成功后统一写入 segments.json,
  匹配阶段只做本地 state,解决 useEffect 无限循环导致时长一直变的问题
- 添加 macOS Info.plist 中文本地化及 Windows NSIS 安装程序中文配置
2026-05-06 16:09:03 +08:00
小鱼开发 3f58c4aff4 refactor: 删除 dubbingVoiceId,统一用 selectedVoiceId
配音音色不再重复记录:
- 删除 dubbingVoiceId 字段及相关序列化、恢复逻辑
- VoiceDubbing 配音完成后不再单独保存 dubbingVoiceId
- 统一用 selectedVoiceId 表示当前选中的/实际使用的音色

减少冗余字段,简化模型
2026-05-06 14:33:20 +08:00
小鱼开发 ea9720394d refactor: 删除历史遗留的 selectedHumanId/selectedElementId 字段
这两个字段是早期数字人方案的遗留,当前业务已完全不使用:
- types/project.ts: 删除字段定义
- store/projectStore.ts: 删除 setSelectedHumanId/setSelectedAvatarInfo action
- api/modules/localStorage.ts: 删除序列化
- VideoCreation/index.tsx: 删除加载恢复逻辑
- utils/projectMeta.ts: 删除默认值

当前素材选择实际只有:
- 人物素材: avatarMaterialPath/Name/Duration(对口型用)
- 空镜素材: userUploadedMaterials + emptyShotMaterial
2026-05-06 14:25:12 +08:00
小鱼开发 bd2f7b9afe feat: title 与 topic 解耦 + 草稿列表支持重命名项目
title/topic 职责分离:
- topic: 创作主题分类标签
- title: 用户自定义项目名称,独立保存

数据层:
- buildTitle 不再截断,优先保留已有 title
- MetaOverrides 允许覆盖 title
- projectStore 新增 setTitle action
- VideoCreation 加载时恢复 title

UI:
- 草稿列表项 hover 显示编辑按钮,点击可重命名
- 直接修改 meta.json,无需进入项目

后端:
- script_handler 返回中文分类名称作为 title
2026-05-06 14:03:15 +08:00
小鱼开发 c79b2323f4 refactor: 删除脚本生成未使用的 duration/style/scriptType/scriptDuration 参数
前端:
- 删除 scriptType 字段及相关 store action、持久化、API 类型
- 删除 scriptDuration 字段及相关 store action、持久化、加载逻辑
- ScriptCreation 不再传 duration/style 参数给后端

后端:
- ScriptParams 删除 duration/style 字段
- ScriptHandler 删除 duration/style 参数读取和传递
- ScriptService.generate_script 签名删除 duration/script_type
- load_script_user_prompt 删除 duration 参数

影响:无,duration/style 在 prompt 模板中未被实际使用
2026-05-06 13:30:40 +08:00
小鱼开发 001de1fc8e refactor: 删除 scriptType 字段及相关逻辑
scriptType 始终为 'default',无实际业务用途,清理冗余字段:
- ProjectMeta 类型定义
- projectStore setScriptType action
- localStorage 序列化
- project API 模块(Project/Create/Update)
- projectMeta 工具函数默认值
- VideoCreation 页面加载/保存逻辑
2026-05-06 13:14:37 +08:00
小鱼开发 a0562a21e3 fix: 补全 Method.CLONE_VOICE 常量 2026-05-06 11:14:20 +08:00
小鱼开发 8f8256ddfb fix: 声音克隆暴露原始错误 + 脚本生成去掉中间进度提示
- voice.py: 异常处理不再吞掉原始错误,直接暴露具体原因
- vidu_service.py: clone_voice 错误消息包含 Vidu 返回的 error_message
- ScriptCreation.tsx: 去掉一闪而过的'任务已创建,等待执行...'中间状态
2026-05-06 11:04:26 +08:00
小鱼开发 4d2a432f93 fix: 补全 localStorage 序列化字段 + VoiceDubbing 保存校验
- saveMeta orderedMeta: 补漏 version、userUploadedMaterials
- saveSegments orderedSegments: 补漏 voiceVolume、bgmVolume、audioPath、audioUrl、emptyShotMaterial
- ProjectSegment 接口: 同步补全上述字段
- VoiceDubbing.tsx: 保存 segments.json 后检查返回值,失败时 toast 报错并终止
2026-05-06 10:21:47 +08:00
小鱼开发 838207d0b9 feat: 前端进度条百分比 + 中间产物清理 + 空镜素材持久化
- ProgressStore/ProgressModal: 支持 determinate 百分比进度条(0-100%)
- SubtitleBurning: 监听 ffmpeg-progress,按 Phase 分段显示进度(overlay 50% + burn 50%)
- VideoComposite: 用 ProgressStore.setProgress() 替代本地 progress state
- 封面信息卡片: 标签改为 主标题/副标题,内容动态读取 coverConfig
- fix(localStorage.saveMeta): 补全 orderedMeta 中遗漏的 mainTitle/subTitle/preset 字段
- 新增 delete_project_file Rust 命令,支持绝对路径 + 路径遍历安全检查
- VideoGeneration: 视频生成完成后统一清理 segment/lipsync/empty_shot 中间视频
- ScriptShot: 新增 emptyShotMaterial 字段,空镜素材随 segments.json 持久化
2026-05-06 09:23:58 +08:00
小鱼开发 3ed37b6c27 fix(adapter): Vidu 状态映射补全 created/queueing,错误字段改为 err_code
- 文档中 state 包含 created/queueing,原映射表缺失导致 normalize_state 默认返回 failed
- parse_callback 错误信息从 message 改为 err_code(与文档一致)
2026-05-05 23:20:04 +08:00
小鱼开发 761deb1156 fix(scheduler): VideoHandler 轮询阶段 fallback 主动查询 Vidu API
- 之前完全依赖 Vidu callback,一旦 callback 未到达任务就永远卡住
- 现在轮询时如果 callback 未到,主动调用 Vidu API 查询任务状态
- 查询到 success 时自动更新 Redis 并移除 running set
- 查询到 failed 时标记失败
2026-05-05 23:10:46 +08:00
小鱼开发 5aafabf88f feat(log): Vidu 对口型提交请求增加完整参数日志
- VideoHandler 提交前记录 callback_url 和 video_url
- ViduProvider.lip_sync() 发送前记录完整请求体 body
- 部署后可从日志直接确认 callback_url 是否传给 Vidu API
2026-05-05 23:05:56 +08:00
小鱼开发 a2106cbfb3 feat(log): Vidu 回调增加详细日志
- 记录回调请求体(前500字符,防日志过大)
- 记录 handle_webhook 解析结果(state/result/error)
- 记录反查 internal_task_id 前后的 platform_task_id 和结果
- 更新成功时记录 video_url
2026-05-05 23:03:45 +08:00
小鱼开发 f5268d6077 fix(api): 从 VideoParams 移除 callback_url,不再暴露给前端
- callback_url 是后端和 Vidu 之间的内部配置,不应由前端传入
- VideoHandler 已自动兜底构建(基于 ENV 推断 app_base_url)
2026-05-05 22:57:12 +08:00
小鱼开发 676c54b6ba fix(scheduler): VideoHandler 自动构建 Vidu 回调地址
- 前端提交 video 任务时不传 callback_url,导致 Vidu 不发送回调
- 任务永远停留在 running 状态,前端无限轮询
- VideoHandler 现在会自动用 app_base_url 构建回调地址兜底
- ENV=staging 时 base_url 自动推断为 https://dev.tapi.meijiaka.cn
2026-05-05 22:55:06 +08:00
小鱼开发 28033feca7 fix(frontend): 对口型接口从 /vidu/lip-sync 迁移到 /tasks/video
- 后端已废弃 /vidu/lip-sync 和 /vidu/tasks/*,统一为 /tasks/video + /tasks/{id}
- submitLipSync 改为 POST /tasks/video,请求体 { taskType, params }
- queryLipSyncStatus 改为 GET /tasks/{taskId},并做 status→state 字段映射
- 移除未使用的 queryLipSyncTask
2026-05-05 22:27:24 +08:00
小鱼开发 26f9096e2e fix(provider): ViduProvider 外部 client 补 Authorization header
- main.py / scheduler/main.py 均使用外部 httpx.AsyncClient 注入 ViduProvider
- 外部 client 创建时未带 Authorization header,导致所有 Vidu API 请求 401
- 在 ViduProvider.__init__ 中统一补 header,无论自建还是外部 client
2026-05-05 22:08:38 +08:00
小鱼开发 8f7f0ac9cf fix(scheduler): 缩短脚本任务等待时间
- 移除 ScriptHandler 中无意义的 asyncio.sleep(2) 假延迟
- Engine 轮询间隔从 10s/2s 缩短到 5s/1s,任务创建后最多等 5s 即被处理
- 去掉 script_handler.py 中不再使用的 asyncio import
2026-05-05 22:01:35 +08:00
小鱼开发 bd6681c454 fix(adapter): VolcengineArkAdapter 转发 reasoning_effort,移除 temperature 传参
- Adapter 之前漏传 reasoning_effort,platform-config.yaml 里配置的
  minimal 未生效,可能导致脚本生成走完整推理链变慢
- 豆包 Seed 2.0 Pro 强制固定 temperature=1,传参无效,全部移除
- 移除 script_service.generate_script/polish_content 和 script.py
  generate_title 中的 temperature 硬编码
2026-05-05 21:52:09 +08:00
小鱼开发 43f13cf394 fix(provider): VolcengineProvider 自动从 Settings 读取 API Key / Base URL
- VolcengineProvider 无参调用时 api_key 为 None,导致 scheduler/main.py 中
  volcengine_ark adapter 注册失败,脚本生成报'未注册的平台: volcengine_ark'
- 参照 ViduProvider 做法,__init__ 中自动兜底读取 get_settings()
- 补充 Settings.VOLCENGINE_BASE_URL 字段(.env 中已有但 Pydantic 未定义)
- 顺手清理 volcengine_provider.py 中的 unused import / variable
2026-05-05 21:42:39 +08:00
小鱼开发 7bd0e2877e fix(scheduler): Scheduler 进程初始化 ModelRouter gateway
- scheduler/main.py 新增火山方舟链路初始化(VolcengineProvider + VolcengineArkAdapter)
- scheduler/main.py 调用 get_model_router(gateway=platform_gateway)
- 修复 ScriptHandler 在 Scheduler 进程中运行时报 'PlatformGateway 未初始化'

根因:Scheduler 是独立进程,没有 FastAPI lifespan,从未初始化 ModelRouter 的 gateway。
ScriptService.generate_script() 调用 get_model_router() 时,gateway 为 None。
2026-05-05 21:20:23 +08:00