Commit Graph

25 Commits

Author SHA1 Message Date
4237dcbaf6 feat: 数据获取架构重构 + Mac指纹采集 + Token刷新容错 + 账单页面 (0.0.19)
## 架构重构
  - useAsyncData 集成 AbortController:cleanup 时真正中断 HTTP 请求,
    不再仅丢弃响应(解决 StrictMode 双重请求问题)
  - API 模块统一 signal?: AbortSignal 参数,透传 axios config
  - use-api.ts 成为数据 Hook 集中管理中心,新增 useAccountInfo、
    useBillingBalance、useBillingLedger
  - 页面组件改为纯渲染:const {data,loading,error,refetch} = useXxx()

  ## 新功能
  - Mac 硬件指纹采集(electron/preload/device.ts):
    ioreg(UUID) + sysctl(CPU) + system_profiler(HDD三级回退)
  - 账单页面 BillingInfo(余额卡片 + 账单表格 + 分页)
  - PageDispatcher 注册 /billing 页面(FloatingPanel 960×680)
  - 共享工具函数 centToYuan / formatDate(src/utils/display.ts)

  ## Bug 修复
  - Token 刷新容错:网络错误时保留 refresh_token,等网络恢复后重试;
    仅 RefreshError(token 过期)时清除(auth-token.ts)
  - AppProvider 自动登录时 nullable 字段默认值(email→''、admin_permissions→[])
  - AccountInfo 重构消除 ~40 行手写状态管理代码

  ## 代码质量
  - AccountInfo 消除 centToYuan/formatDate 重复定义
  - BillingInfo 标题层级精简(移除冗余页面/Card标题)
  - antd Table align 字面量类型修正('left' as const)
  - billing.ts signal 参数位置修复(params→config)
  - modelFirstFetchDone 模块级变量移除(StrictMode 不安全)
2026-06-11 20:08:44 +08:00
95019316b2 feat: 前后端联调 — 任务创建 + 账户信息 + 预估花费 (0.0.18)
- task: device_id 改为必填参数,API 层 Omit 封装 + getDeviceId() 自动注入
- pricing.ts: Python 后端 calculate_cost 完整移植,六种定价模式 + 6 个 Bug 修复
  (浮点冗余/维度匹配不一致/null 守卫/matrix 数据提取/unit_scale 等)
- ModelInputForm: 三层兜底预估消费展示 + React Hooks 顺序修复
- AccountInfo: VIP 等级列表匹配,套餐详情展示(说明/周期/席位/到期)
- 模型列表加密缓存 (safe-storage, stale-while-revalidate)
- VIP API 模块 (激活码/等级/订单/模拟支付)
- device_id 统一使用 UUID v4 持久化 (与 login/register 对齐)
2026-06-10 19:38:26 +08:00
848fdeca3d fix: 修复接口重复调用 — StrictMode 清理 + useModelList 去重
AppProvider useEffect 增加 aborted 标志,防止 React StrictMode
挂载→卸载→重新挂载时 refreshToken/getUserInfo 各调两次。

useModelList 提升到 LeftPanel 单例调用,通过 props 分发给
ModelSelector 和 TaskHistory,消除 /api/v1/models 重复请求。

DevTools 中显示「已停止」的请求即 StrictMode 第一轮挂载被丢弃的请求。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 19:24:34 +08:00
d95d155ab5 chore: 文档更新 + 代码去重 + ESLint 修复,准备 0.0.16
- CHANGELOG: 新增 0.0.16 版本条目(模型输入栏重构/统一页面调度/依赖联动)
- TODO: 标记账户信息页为已完成,拆分未完成页面项
- ARCHITECTURE: 新增 PageDispatcher 叠加层说明 + OPEN_PAGE 事件
- 代码去重:runFieldChecks(validators) + createImageBeforeUpload(uploadValidation)
- ESLint: DependentFormItem 中 Form.useWatch 移到组件顶层(修复 rules-of-hooks)
- ESLint: message.success / async handleSubmit 加 void(修复 no-floating-promises)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 19:12:37 +08:00
1c27283b56 docs:重命名文件、变量名称 2026-06-09 18:54:01 +08:00
c18d9c8404 feat: 统一页面调度体系 — 全局互斥 + 动态尺寸 + 账户信息页
PageDispatcher 重构:
- singleton + floatingPanels[] 双状态 → 单一 activePanel 状态
- 全局互斥:已打开面板时禁止打开新面板(保留拖拽/图片拖放等互操作)
- 占位组件预计算为模块级 Map,消除 ESLint static-components 误报
- PAGE_MAP 支持 width/height 配置,动态函数计算(视口比例自适应)
- 容器默认尺寸改为动态:Modal=min(w*0.55,720) Drawer=min(w*0.38,520)
- 修复 FloatingPanel 未接收 width/height 配置的问题

Test2 账户信息页:
- AuthAPI.getUserInfo() → 三卡片布局(积分/套餐/今日统计)
- 加载态 Skeleton / 错误态 Result+重试
- centToYuan 积分转换、formatDate 日期格式化

目录调整:wechat-work/ → headers/

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 18:43:50 +08:00
0c7b33aac1 feat: constraints_config.requires 联动控制 — enable_switch 开关同步启用/禁用依赖字段
- DependentFormItem: 透传 disabled 为顶层 prop(之前藏在 config.disabled 中,widget 组件读取不到)
- ImageInput: 值语义分层 — undefined(开关关) / [](开关开但空) / [{...}](已上传)
- isValueEmpty: 空数组[] 不再视为空,配合 enable_switch 语义
- handleFileWidgetValue: 兼容 Upload DOM事件 和 enable_switch 裸值两种 onChange 形态

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 17:36:53 +08:00
4261915679 fix: 修复模型默认值不加载 + DependentFormItem prop 透传断裂
- DependentFormItem 透传 Form.Item 注入的 value/onChange/disabled prop
- 稳定化 constraintsConfig 空对象引用(EMPTY_OBJ),避免 useMemo 失效导致无限重渲染
- useLayoutEffect 手动 setFieldsValue(initialValues)替代 antd 被忽略的 initialValues prop
- handleReset 使用 resetFields + setFieldsValue 组合确保默认值归位

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 17:00:44 +08:00
d5ba7e63cd refactor: 中间栏三层架构 — useUI 组件体系 + useModelUI Hook
- 新建 useUI/ 目录:12 个文件,10 个 Qt 控件 → antd 组件封装 + 类型 + 注册表
- 新建 useModelUI Hook:param_schema → UIFieldConfig[] 自动映射
- ModelInputForm 瘦身 ~160 行:删除 buildParamDescriptors/renderParamControl/文件状态管理
- WIDGET_MAP: Record<string, ComponentType<WidgetProps>> — 零 any,完全类型安全
- 新增控件只需两步:创建组件文件 + 在 WIDGET_MAP 加一行
- 删除旧 widgets/ 目录

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 15:32:17 +08:00
76e66a37c8 refactor: 消除占位页面 + 删除 barrel 导出 — 页面集中注册 + 直接导入
- 删除 8 个占位页面文件(Account/Vip/Recharge/Billing/Orders/Projects/Quota/ComplianceAssets)
- PageDispatcher: PAGE_MAP 支持无组件页面自动渲染 PlaceholderPage
- 新增页面只需在 PAGE_MAP 加一行配置,无需创建独立文件
- 删除 services/modules/index.ts barrel,13 个文件改为直接导入
- IDE 跳转到定义一步到位,import 自文档化
- TypeScript 编译零错误

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:32:14 +08:00
7982b69219 refactor: CSS 拆分 + auth 持久化提取 + 目录整理
- globals.css 拆分为 4 文件:tokens.css(颜色)/ transitions.css(过渡)/ base.css(重置)/ globals.css(入口)
- 提取 auth-persistence.ts 到 services/,解除 AppProvider→pages/login/hooks 反向依赖
- use-auth-state.ts 精简为纯 React Hook,持久化逻辑委托给 services/auth-persistence.ts
- components/common/ → components/ui/(目录名语义更清晰)
- TypeScript + Vite 构建通过

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:20:07 +08:00
53df926973 refactor: Context 与 Provider 合并 — 消除 contexts/ 目录,一文件一状态单元
- ThemeContext + useTheme → ThemeProvider.tsx(原 hooks/use-theme.ts 删除)
- AppContext + useAppContext → AppProvider.tsx(原 contexts/app-context.ts 删除)
- SettingsContext + useSettings → SettingsProvider.tsx(原 contexts/settings-context.ts 删除)
- HomeContext + useHomeContext → HomeContent.tsx(原 contexts/home-context.ts 删除)
- 删除空的 contexts/ 目录,20+ 导入路径同步更新
- TypeScript 编译通过(npx tsc --noEmit 零错误)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-09 14:02:48 +08:00
eb12248a62 feat: 主题切换性能优化 — View Transitions API + 0.15s 统一过渡 + 设置页增强
【问题】
  桌面端(Electron)切换主题时颜色变化速度不一致、明显卡顿。
  根因分析(4 轮迭代):
    1. 过渡时长不统一(body 0.3s / 组件 0.15s)→ 统一到 0.2s
    2. antd CSS-in-JS 标签替换导致瞬间变色 → 尝试 cssVar(无效,仍走标签替换)
    3. applyHtmlTheme 在 updater 回调中执行,与 antd CSS 变更不同帧 → 移入 useLayoutEffect
    4. html * 全局过渡在 Electron 中为数千 DOM 节点同步插值 → 合成器掉帧
  终极方案:View Transitions API(GPU 合成器 1 次 cross-fade 替代 N 个 CSS 过渡)
   + 精准 CSS 过渡覆盖 ~80 个 antd 容器类(回退方案)

  【修改】

  ThemeProvider.tsx — 核心重构
    - applyHtmlTheme 从 setIsDark updater → useLayoutEffect([isDark])
      确保自定义 CSS 变量与 antd CSS-in-JS 在同一次 React 提交中生效
    - View Transitions API:document.startViewTransition + flushSync
      GPU 合成器截取旧/新两帧做单次 cross-fade,消除多元素插值卡顿
    - 浏览器不支持时自动回退到 CSS transition 方案

  globals.css — 过渡策略
    - body: 0.3s ease → 0.15s linear
    - View Transitions 动画:::view-transition-old/new(root) 0.15s linear
    - ~80 个 antd 容器类精准过渡(Layout/Card/Modal/Table/Input/
      Select/Picker/Menu/Tabs/Tag/Alert/Empty/Result/Skeleton 等)
      按功能分组:布局 → 表格 → 表单 → 导航 → 反馈
      不覆盖交互组件自有 transition(Button/Switch/Slider 等)
      linear 替代 ease — 匀速插值,桌面应用更利落

  Layout.tsx / HomeContent.tsx / LeftPanel.tsx / ModelSelector.tsx
    - 过渡参数对齐:全部 0.2s → 0.15s linear

  SettingsPage.tsx — 用户体验
    - Modal 取消 keyboard={false},Esc 键可关闭
    - macOS:关闭按钮移至标题左侧(遵循 macOS HIG)
    - afterClose 中 blur 当前焦点元素,防止聚焦跳到导航栏

  【文档】
  CHANGELOG.md — 新增 0.0.15 版本记录
  CLAUDE.md — 新增主题系统架构章节(双轨颜色体系 / 时序 / 过渡策略)
2026-06-09 11:02:40 +08:00
59059caae7 feat: 重构模型列表UI + 修复后端数据格式适配
模型列表 UI 重构:
- ModelSelector 从 Menu 折叠分组改为 Tabs 标签页 + 平铺列表
- 新增「全部模型」Tab + 各分类由 MODEL_CATEGORIES 数组控制顺序
- ModelItem 新增 hover 高亮效果 + 维护中模型禁用 + toast 提示
- 新增错误态(Result + 重试按钮)

后端数据格式适配:
- param_schema 类型从 string[] 改为 ParamSchemaItem[]({id, map_to, spec, ui})
- 修复 Form.Item 重复 key 报错(item.id 作 React key,item.map_to 作表单字段名)
- ModelsListResponseBody 字段类型收紧(model_type / category_name / quota_config)

数据层重构:
- useModelList 从 4 次并行请求改为 1 次全量拉取(后端 category 参数不可用)
- 分组键从 category_name 改为 model_type
- page_size 提升至 200

类型体系增强:
- type 别名改为 as const 数组推导(MODEL_CATEGORIES 单一数据源)
- 新增 CATEGORY_SLUG_MAP + resolveCategoryLabel + toCategorySlug 映射层
- 类型重命名 ModelCategory → ModelCategoryStringEnum
2026-06-08 19:02:32 +08:00
a2741edf01 feat: 企业微信改为 Modal 展示二维码,修复 PageDispatcher hooks 错误
将"企业微信"导航项从 external(跳转浏览器)改为 page(Modal 展示),
  二维码图片数据来源于 Banner API(/api/v1/creatives,category=promotion)。

  - 新增 WechatWorkPage:调用 fetchBanners,筛选 category==='promotion',
    展示 image_url 二维码 + 扫码提示 + 刷新按钮,加载/空态/错误三态覆盖
  - nav-config:wechat-work 从 action:'external' 改为 action:'page',
    modalType:'modal',target:'/wechat-work'
  - PageDispatcher:注册 /wechat-work 映射,Modal 新增 centered 居中
  - 修复 PageDispatcher 致命 bug:PAGE_MAP[...]() 函数调用改为
    JSX <SingletonPage />,避免子组件 hooks 误跑在父组件链上导致崩溃
  - PAGE_MAP 类型从 Record<string, () => ReactNode> 修正为
    Record<string, ComponentType>
2026-06-08 17:27:24 +08:00
ada915f298 feat: 去 React Router 化 + 实现三种窗口类型的页面调度体系
移除 react-router-dom 依赖,将导航从 URL 路由切换为事件总线驱动,
  新增 Modal / Drawer / FloatingPanel 三种窗口类型支持。

  架构变更:
  - 删除 src/router/(唯一路由 /* → HomePage,无实际用途)
  - App.tsx 移除 HashRouter,直接渲染 Layout > HomePage
  - Layout 从 useLocation + Outlet 改为 children prop
  - NavBar 移除 useNavigate,所有页面导航改为 emit(OPEN_PAGE)
  - NavAction 精简:'navigate'|'spa' 合并为 'page'

  新增组件:
  - FloatingPanel:纯手写非模态浮动面板(可拖拽、无遮罩、多面板共存、
    暗色主题适配、边界约束),对应 QT 非模态窗口的 Web 映射
    Modal(居中模态)| Drawer(侧滑)| FloatingPanel(浮动可拖拽)
  - 8 个页面占位组件(compliance-assets/account/vip/recharge/
    billing/orders/projects/quota),各显示导航栏名称作为占位

  配置扩展:
  - NavItemConfig 新增 modalType?: 'modal' | 'drawer' | 'floating'
  - nav-config 所有 page 项补齐 modalType(支付类→modal,浏览类→floating)
  - event-bus 新增 OPEN_PAGE 事件,payload 携带 {target, modalType, label}
  - 卸载 react-router-dom@^7.16.0(连带移除 4 个包)

  设计原则:
  - 页面组件不感知窗口类型(内容与容器分离),切换窗口类型只需改配置
  - Modal/Drawer 单实例(模态含义=独占注意力),Floating 多实例共存
  - 主页面始终挂载不卸载,所有子页面为叠加层(对应 QT 多窗口模型)
2026-06-08 16:33:47 +08:00
7032d1c3f2 feat: 忘记密码/修改密码 + 设置页结构重组 + barrel cleanup + LoginPage 版本统一
新增:
  - ForgotPasswordModal — 手机号+短信验证码重置密码 (AuthAPI.resetPassword)
  - ChangePasswordModal — 当前密码验证后修改密码 (AuthAPI.changePassword)
  - useSmsCooldown Hook — 通用短信发送冷却逻辑,供注册/忘记密码复用
  - PasswordSetting — 设置页账号安全区块,双选项:修改密码 / 短信验证码重置

  修改:
  - LoginForm \"忘记密码?\" 链接接入 ForgotPasswordModal(替换 TODO)
  - LoginPage 移除 edition 业务版本 UI 区分,登录/注册 Tab 全局统一
  - 设置页 Section 组件移入 blocks/ 子目录(git mv 保留历史)
  - auth.ts sendSms URL 修正: /sms/send → /send-sms

  清理:
  - settings/index.ts 移除 4 个未使用 re-export,精简为仅 SettingsPage
  - navbar/index.ts 移除未使用 re-export,精简为仅 NavBar

  文档:
  - WORKLOG.md 新增 2026-06-08 工作日志
  - ARCHITECTURE.md / PROJECT.md 更新设置页目录结构与新组件
  - TODO.md 忘记密码流程标记已完成 + 短信人机验证列入后期优化
2026-06-08 11:57:35 +08:00
952a723448 fix: 修复首页三栏布局拖拽溢出 — 分隔条最大宽度约束 + 视口缩小自动收窄
问题:切换视口大小或拖拽分隔条时,右侧预览面板甚至中右两栏被挤出视口。

  根因:flex 布局左/右列 flexShrink:0,拖拽无上限约束,视口缩小时不自动收窄,
  总宽度超出容器后 overflow:hidden 裁剪。

  修复(HomeContent.tsx):
  - 拖拽时计算 maxLeft / maxRight 动态上限,确保中列≥300px、三栏均在视口内
  - ResizeObserver 监听容器缩小,优先收右侧面板→不够再收左侧,拖拽中自动跳过
  - leftWidthRef / rightWidthRef / draggingRef 避免闭包读到过期值

  变更:CHANGELOG.md / TODO.md / WORKLOG.md 同步更新

  影响文件:3 个(+60 -3)
  - src/pages/home/HomeContent.tsx
  - CHANGELOG.md
  - TODO.md
2026-06-07 05:56:00 +08:00
72ec1a5459 fix: 修复主题切换后首页状态重置 + 首页 UX 优化 + 文档同步
## 根因
  设置页 `navigate('/settings')` 导致 React Router `/*` 的 index
  路由不匹配,HomePage 被卸载重挂载,所有 useState 回到默认值。

  ## 修复(6 文件)
  - event-bus.ts: 新增 OPEN_SETTINGS 事件
  - nav-config.ts: 设置按钮 action: 'navigate' → 'button',去路由化
  - NavBar.tsx: button case 中 emit(OPEN_SETTINGS)
  - SettingsPage.tsx: 去路由化,改为 Modal 居中叠加 + open/onClose props,
    使用 antd 6.x 正确 API destroyOnHidden(非废弃的 destroyOnClose),
    mask={{ closable: false }} + keyboard={false} 仅允许 X 按钮关闭
  - router/index.tsx: 移除 SettingsPage 渲染
  - App.tsx: 添加 SettingsPage Modal,事件驱动(与 LoginPage 模式一致)

  ## UX 优化(2 文件)
  - HomeContent.tsx: 右侧分隔条移除多余 marginLeft,左右视觉对称
  - BannerCarousel.tsx: 新增关闭按钮,session 级别 useState 隐藏,
    不做 localStorage 持久化,确保每次启动重新展示

  ## 架构原则
  确立 QT 多窗口模型 → Web 映射:叠加层走 Modal/Drawer + 事件总线,
  主页面不卸载;真正的视图切换才用 React Router。

  ## 文档同步
  - TODO.md: 移除已完成项详细记录,精简为未完成待办
  - WORKLOG.md: 追加 2026-06-07 完整工作日志
  - PROJECT.md: 更新路由/叠加层架构说明
  - CHANGELOG.md: 追加 v0.0.13 条目
  - ARCHITECTURE.md: 更新日期 + 新增叠加层模式章节
2026-06-07 05:21:47 +08:00
a8ace232a4 feat: 任务列表UI重构 + 分页器/登录错误/请求拦截修复
【任务列表 UI 重构】(TaskHistory.tsx)
  - 列重新排序:任务ID(固定) → 创建时间 → 模型 → 输出类型 → 状态 → 提示词 → 时长 → 费用 → 供应商(隐藏) → 帧率/文件大小/标签/错误信息(隐藏) → 用户
  - 斑马纹行样式 + hover 增强 + 选中行高亮 + 暗色主题适配
  - 列可见性选择器(齿轮图标 Popover),持久化到 localStorage
  - 视频时长通过 VideoUiParams.duration 计算,非视频显示 "-"
  - 未知状态降级处理(resolveStatus → 显示原始 key)
  - 分页器固定预留 48px,避免 >20 条时分页器溢出可视区
  - 提示词搜索图标颜色用 CSS class 承载,避免 columns 依赖 token.colorPrimary 导致主题切换时 Table 重建

  【分页器修复】(antd-theme.ts)
  - Pagination 组件 token 添加 itemActiveColor: '#fff'
  - 激活页码数字与 #6366F1 主题背景形成对比,亮色/暗色均可见
  - 替代之前的 CSS !important hack

  【登录错误信息修复】(request.ts)
  - HTTP 401 拦截改为双重校验:status === 401 && data?.code === 401
  - 仅业务码也为 401 时才走 token 刷新流程
  - 其他业务码(如密码错误)透传后端 data.message,不再被 RefreshError 覆盖

  【全局中文 locale】(ThemeProvider.tsx)
  - ConfigProvider 添加 locale={zhCN},分页器显示"条/页"等中文
  - 避免逐个 Table 设置不完整 locale 导致 Pagination Select 退化为 Input

  【上下文稳定性】(HomeContent.tsx)
  - contextValue 用 useMemo 包裹,避免每次 render 新建对象导致无关重渲染
  - 配合 columns 依赖清理,减少主题切换时的级联更新

  【其他】
  - index.html CSP 策略增加 COS 域名白名单
  - OutputTypeMap 枚举值修复为 image='图片', video='视频', audio='音频'
  - TaskStatusMap STATUS_CONFIG 类型放宽为 Record<string,...> 兼容未知状态
  - 移除 computeDuration,替换为 getVideoDuration + formatDuration
  - LoginPage 移除未使用的 authState 依赖
2026-06-05 20:49:23 +08:00
af85d31035 feat :修改文件结构 2026-06-05 19:24:06 +08:00
1da95eaef3 feat: 实现业务首页(三栏布局 + 轮播图)
## 首页整体架构
  - 新增 src/pages/home/ — 完整首页模块(10 个组件)
    - HomePage / HomeContent:三栏弹性布局,拖动分隔条调整列宽
    - BannerCarousel:顶部轮播图(antd Carousel,2280×90 长条图片适配)
    - LeftPanel:模型选择器(Menu 分组) + 任务记录(Table 分页),纵向拖拽调整比例
    - CenterPanel / ModelInputForm:动态表单,根据模型 param_schema/ui_config 渲染控件
    - RightPanel / OutputPreview:任务输出预览(Image/Video)
  - 新增 Layout 组件:h-screen flex 布局,首页 Banner + NavBar + Outlet

  ## 数据层(数据与视图分离)
  - 新增 src/services/modules/ — API 模块(banner/models/task/auth)
    - TaskAPI 静态方法,TaskInfoItemResponseBody 判别联合类型
    - ModelAPI / BannerAPI,const 断言路由常量
  - 新增 src/hooks/use-async.ts — 通用异步 Hook
    - useAsyncData:竞态处理、条件请求(enabled)、自动错误日志
    - useAsyncMutation:数据变更,onSuccess/onError
    - getErrorMessage():RequestErrorType → 可读错误信息
  - 新增 src/hooks/use-api.ts — 业务 Hook
    - useBannerList / useModelList / useTaskList / useTaskDetail / useSubmitTask

  ## 主题与交互
  - 重写暗色令牌:科技感蓝紫(#080C24 底 / #0F1340 面板 / #2A3278 边框)
  - 三栏分隔线:token.colorBorderSecondary 常驻 + 手柄竖线 hover 高亮
  - 左面板纵向拖拽:模型区/任务区可调比例,ResizeObserver 自适应
  - 暗色/亮色同步:tokens.ts + antd-theme.ts + globals.css 三处一致

  ## 基础设施
  - EventBus 新增 TASK_SUBMITTED 事件(替代 Context 数字递增 hack)
  - HomeContext 状态管理(选中模型、任务分页、折叠状态)
  - 所有组件边框使用 token.colorBorderSecondary(主题自适应)
  - Table 滚动高度 ResizeObserver 动态计算(修复分页器遮挡)
2026-06-05 16:24:17 +08:00
6204c14b88 feat: 重构更新流程 — 无更新不抛异常、用户决定下载、更新详情展示(md文件中的)
【核心重构】
  - getLatestVersion() 不再 throw Error,无更新时返回 { version: APP_VERSION }
  - checkForUpdates() 先自行预检 → 无更新直发 IPC,有更新才交 electron-updater
  - 移除 NO_UPDATE_MESSAGE 常量及所有字符串匹配拦截代码
  - HeiXiuProvider 增加 500ms TTL 缓存,避免预检+electron-updater 重复请求 API

  【用户体验】
  - 检查到新版本后不再自动下载,展示更新内容供用户决定
  - 新增"下载更新"按钮(与"安装更新"分离为两步操作)
  - 设置页新增"查看详情"弹窗,Markdown 格式化渲染更新日志
  - available / downloading / downloaded 三个状态 UI 独立展示

  【Bug 修复】
  - 测试服务器版本排序:字符串序 → 语义版本序(_version_key),0.0.10 正确 > 0.0.9
  - 版本比较:!= → <(_version_key),防止高版本误判为有更新
  - get_best_release fallback 同样改为语义版本排序
  - Windows cmd set 命令尾部空格 → Invalid URL(.trim() 修复)
  - electron-updater 'error' 事件中拦截 NO_UPDATE_MESSAGE → UPDATE_NOT_AVAILABLE

  【文档更新】
  - CHANGELOG.md、PROJECT.md、UpdateA.md 同步更新架构图和流程说明
2026-06-04 18:31:52 +08:00
3becdb85d4 feat: 实现设置页面 + 路由系统 + JWT认证体系 + 公告优化 + 错误类型系统
## 新增功能

### 设置页面(Router + Modal 叠加)
- HashRouter 路由系统,Electron file:// 协议兼容
- 设置页以居中 Modal 叠加首页,仅 X 按钮关闭
- 主题切换 Segmented 控件(与首页 Switch 共享 Context)
- 大模型产物存储仓库路径配置(原生文件夹选择对话框)
- 企业版额外:团队创作存储仓库路径
- 系统信息展示(平台/版本/版本类型/环境)
- 版本更新检查(状态机:idle→checking→no-update/available→downloading→downloaded→error)

### JWT 认证体系
- 双 Token 机制:access_token + refresh_token
- Axios 拦截器 401 自动刷新 + 并发请求去重队列
- 启动时 refresh_token 静默续期(自动登录)
- 记住密码:Base64 编码存储,表单自动回填
- setTokenRefreshHandler 解耦模式:request.ts 不知晓 auth

### 自定义错误类型系统
- RefreshError 继承 RequestError,type = AUTH_EXPIRED
- 全局拦截器捕获 RefreshError → 自动 clearToken + AUTH_REQUIRED
- 任何位置 throw new RefreshError() 即可触发登录 Modal

### 公告卡片优化
- 长文本 Tooltip 悬浮预览
- 点击卡片弹出详情 Modal(全文保留换行)

### SettingsContext(类似 Vue Pinia)
- 集中式设置状态管理
- localStorage 持久化:ele-heixiu-output-path / ele-heixiu-team-repo-path
- useSettings() 全局消费

## 架构变更
- App.tsx → HashRouter + AppRoutes + LoginPage 弹层
- Layout.tsx = NavBar + <Outlet /> 页面壳
- HomePage.tsx 从 App.tsx 提取
- NavBar 使用 useNavigate() 真实路由导航
- useUpdater 改为模块级单例 IPC 监听器(修复 MaxListenersExceededWarning)
- electron/main.ts 新增 FILE_DIALOG IPC handler

## 依赖
- 新增 react-router-dom
2026-06-03 19:25:15 +08:00
767bb8b297 feat: 初始化船长·HeiXiu 桌面应用项目(错误是svg的问题)
Electron + React 19 + TypeScript + Ant Design 6 + Tailwind CSS 4

  【核心架构】
  - Electron 主进程(窗口管理、平台检测、图标适配)
  - Vite 构建链(双产物 dist/ + dist-electron/)
  - 共享层 shared/(类型、常量、工具函数)
  - IPC 通信框架 + 安全守卫

  【主题系统】
  - 蓝紫渐变主题(亮色/暗色双模式)
  - Ant Design ConfigProvider 适配(lightAlgorithm / darkAlgorithm)
  - Tailwind CSS 4 @theme 指令 + CSS 变量
  - 设计令牌三处同步(tokens.ts / globals.css / antd-theme.ts)

  【导航栏】
  - 自定义 H5 导航栏替代系统菜单
  - 个人版/企业版双布局
  - 未登录拦截 + 事件总线驱动登录弹窗

  【登录注册】
  - Modal 弹层(Portal)+ Tabs 切换
  - 登录/注册表单动态字段渲染
  - 记住密码 / 自动登录 / 用户协议

  【更新系统】
  - 自定义 API 版本检查(替代 electron-updater generic provider)
  - 手动下载 + SHA512 校验 + spawn NSIS 安装
  - 渲染进程更新状态机 Hook(useUpdater)
  - 检查更新按钮 + 下载进度展示

  【构建工具链】
  - build.mjs 构建总管(--win/--mac/--linux --personal/--enterprise --build/--clean/--sign/--upload/--publish)
  - scripts/ 自动化脚本(clean / generate-update-info / upload-oss / publish-release)
  - electron-builder NSIS 安装器(可选路径、多版本打包)
  - update-info.json 自动生成(fileSize/sha512/changelog/releaseDate)

  【代码质量】
  - ESLint + TypeScript strict + Prettier
  - husky + lint-staged(提交前自动检查)
  - commitlint(规范提交信息)
  - Playwright E2E + Vitest 单元测试框架
  - rollup-plugin-visualizer 打包体积分析

  【文档】
  - README.md(快速开始 + 目录结构 + 命令速查)
  - UpdateA.md(发布手册:API/签名/发版流程/数据库)
  - CHANGELOG.md(更新日志)
  - .env.example(构建环境变量模板)
2026-06-03 15:00:51 +08:00