### 任务状态轮询 - 新增 useTaskPolling hook:批量轮询非终态任务,递归 setTimeout + next_poll_ms 自适应间隔 - TaskHistory 集成批量轮询,OutputPreview 移除独立轮询改为状态转换监听 - batchTaskStatus 修复数组参数序列化(GET + 逗号拼接,避免 bracket 格式) - 统一 POLLING_STATUSES 常量管理非终态状态 ### Token 刷新容错 - 双轨刷新:主动续期(JWT exp 75% 时间点 setTimeout)+ 被动兜底(handle401) - 刷新失败分级:永久失败(throw RefreshTokenExpiredError)→清token弹登录;临时失败(return null)→仅拒绝当前请求 - AppProvider 登录/自动登录/退出 启停主动刷新定时器 ### 提交按钮防抖 - 2s 节流防抖("你点击的太快了")+ 二次确认弹窗("您已提交,确认要再次提交吗?") - 修复 useAsyncMutation.execute 返回值判空(原 try/catch 死代码) ### 文件上传 Hook - 新增 useFileUpload hook:封装 request.upload() 为 antd Upload 兼容 customRequest - ImageInput/ImageListInput/AudioListInput 集成 customRequest - uploadValidation beforeUpload 返回值修正(false→true) ### 其他 - AnnouncementDrawer 接入公告 API + EnumResolver - billing/announcement/banner 服务模块完善 - CLAUDE.md 补充架构约定文档
3.0 KiB
3.0 KiB
基本交代
- 所有交互、解释、代码注释与生成内容均使用简体中文,专有技术名词可保留英文,但需附带中文说明;
- 有需要请自行调用MCP服务;
业务设计思路
- 进行任务时都需要考虑安全、性能、主题切换、业务自定义错误、事件总线驱动方式以及日志记录;
- 进行系统级别的操作时,需要考虑系统差异,并处理兼容性。如WINDOWS、MAC OS;
- 处理业务时,需要同时考虑兜底机制和业务自定义错误捕获;
- 所有设计思路、代码实现均需要考虑以上三个条件。
架构约定
任务状态轮询
- 两层轮询 + Context 桥接:
useTaskPolling(批量轮询batchTaskStatus)负责广度覆盖,OutputPreview通过selectedTask.status变化检测终态转换后触发refetch()获取详情——二者通过 Context 同步,避免重复请求。 - 非终态统一管理:
POLLING_STATUSES = ['pending', 'submitted', 'processing']定义在task.ts,所有轮询逻辑引用此常量。 - 自适应间隔:递归
setTimeout(非setInterval)+ 服务端next_poll_ms,本地 clamp 2s~30s,出错 10s 重试。 - useRef 打破闭包陷阱:
mergedRef.current确保递归回调读到最新任务列表。
Token 刷新
- 双轨刷新:主动刷新(
scheduleProactiveRefresh)在 JWTexp的 75% 时间点通过setTimeout提前续期;被动刷新(handle401→refreshHandler)兜底。 - 失败分级处理:
refreshHandler永久失败(RefreshTokenExpiredError)→ throw →handle401清 token + 弹登录;临时失败(网络超时)→ return null → 仅拒绝当前请求,不登出。 - JWT 解码驱动定时器:从
atob(token.split('.')[1])取exp声明,无需额外持久化expires_in。 - 刷新接口隔离:
/api/v1/auth/refresh在request.ts中特殊处理(isRefreshRequest),防止 401→刷新→401 死循环。
文件上传
- customRequest 集成模式:
useFileUploadhook 封装request.upload(),返回 antd Upload 兼容的customRequest——避免直接设action导致 Token 缺失,复用全局拦截器的认证和错误处理。 - beforeUpload 语义修正:校验通过返回
true(放行至customRequest),失败返回Upload.LIST_IGNORE。
表单提交
- 两级防护:防抖(2s 节流,"你点击的太快了")+ 二次确认(
Modal.confirm,"您已提交,确认要再次提交吗?")。 - useRef 存储时序状态:
lastClickTimeRef/submitCountRef避免不必要的重渲染。 - useAsyncMutation 返回值判空:
execute()内部 catch 所有错误返回undefined,调用方应检查返回值而非 try/catch。
GET 数组参数
- 逗号拼接优于 bracket 序列化:
task_ids=a,b,c比task_ids[]=a&task_ids[]=b更具跨框架兼容性,避免 axios 默认paramsSerializer的 PHP/Rack 风格。