Files
ele-HeiXiu/CHANGELOG.md
YoungestSongMo 8b697e775d feat: 去除构建时版控变量 + 窗口标题动态版控 + 退出登录保留缓存 (0.0.24)
版控体系重构(13 文件):
- 移除 build.mjs --personal/--enterprise 参数和 EDITION 环境变量
- 统一安装包文件名:船长-HeiXiu-{os}-{版本号}-Setup.{ext}
- 简化 package.json 构建脚本,移除 :enterprise 变体
- scripts/*.mjs 不再接受 edition 参数
- 移除 shared/constants/app.ts 的 parseEdition()

窗口标题动态版控:
- 新格式:船长-HeiXiu-{os}-{版本号}(登录前)/ ·{版控} 后缀(登录后)
- 链路:AppProvider(account_type) → useEffect → appRuntime IPC → main process
- 移除 updater.ts 更新检查 API 的 edition 查询参数

本地存储生命周期修正:
- 退出登录不再自动清空缓存(user_id 隔离,重新登录命中缓存)
- clearUserStorage 添加 isOpen() 竞态守卫
- 移除 closeDatabase() 避免退出→重新登录后数据库不可用
- 手动「清理缓存」按钮保留

文档:
- CHANGELOG.md 新增 0.0.24 条目
- TODO.md 新增已完成项
2026-06-22 13:36:42 +08:00

20 KiB
Raw Blame History

更新日志

每次发版前修改此文件,npm run build:win 打包后会自动读取生成 update-info.json。


0.0.242026-06-22

去除构建时版本变量 + 窗口标题动态版控 + 退出登录保留缓存

版控体系重构

  • 去除构建时 EDITION 环境变量--personal/--enterprise 参数从 build.mjs 移除,vite.config.ts 不再注入 process.env.EDITION.env.* 清理相应行
  • 统一的安装包文件名船长-HeiXiu-{os}-{版本号}-Setup.{ext}(移除 ${env.EDITION}
  • package.json 简化:移除 3 条 :enterprise 构建脚本
  • scripts/*.mjs 统一upload-oss/generate-update-info/publish-release 不再接受 edition 参数

窗口标题动态版控

  • 新格式船长-HeiXiu-{os}-{版本号}(未登录)/ 船长-HeiXiu-{os}-{版本号}·{版控}(登录后)
  • 运行时链路AppProvider 根据 user.account_type 派生 editionuseEffectwindow.appRuntime.setWindowEdition() → IPC set-window-title → 主进程 buildWindowTitlemainWindow.setTitle
  • Edtion 类型守卫src/vite-env.d.ts + electron/electron-env.d.ts 双端类型声明
  • 更新检查 API 移除 edition 查询参数

本地存储生命周期修正

  • 退出登录不再自动清缓存AppProvider.logout() 移除 clearUserStorage() 调用。数据已按 user_id 隔离,同一用户重新登录缓存直接命中
  • clearUserStorage 竞态修复:添加 isOpen() 前置守卫,防止数据库未初始化时执行 SQL移除尾部 closeDatabase(),确保退出→重新登录周期内数据库持续可用
  • 手动清理保留DataManageSetting 的「清理缓存」按钮仍可主动触发

0.0.232026-06-22

三栏等比缩放修复 + 代码重组

三栏布局修复

  • 约束逻辑修正:双遍最小值约束改为 clamp + 超限兜底,修复窗口缩小至 1036px 以下时中列被挤出视口
  • 双触发器ResizeObserver + window.resize 事件双重驱动,防止 React 批量更新吞掉重绘
  • 三栏等比缩放:旧算法只保 left:right 比例,中列被动吸收剩余;新算法通过 prevWidthRef 反推中列上次宽度,三栏按各自占比同步缩放——窗口从半屏拉到全屏保持 ≈1:1:1

代码重组(第二轮)

  • src/utils/11 文件精简为 7 文件 —— env.ts(platform+device)、bus.ts(event-bus+ipc+logger)、display.ts(display+logo+type)、media-upload.ts
  • controls/14 文件精简为 6 文件 —— simple-widgets.tsx(6合1)、upload-widgets.tsx(ImageInput+VideoInput 去重)、list-upload-widgets.tsx(ImageListInput+AudioListInput)
  • FormField 提升:从 auth/components/ 提升到 src/components/ui/FieldConfig 类型同步移到 ui/types.ts
  • data-sync 归位:从 settings/sections/ 移到 infrastructure/storage/
  • electron/main/ 分组3 个 IPC handlerlog-ipc/safe-storage-ipc/storage-ipc收拢到 ipc/ 子目录
  • shell/ → frame/src/components/shell/ 重命名为 frame/,更直观表达"应用框架"
  • storage/ 分层15 文件平铺 → core/4+ stores/5+ services/4+ 入口

文档

  • 37 个文件夹全部生成 README.md不进 Git
  • PROJECT.md 目录树同步更新

0.0.222026-06-18

三栏布局比例缩放 + SeedanceContent 视频参考上传 + 本地存储基建

三栏布局:比例自适应缩放

  • ResizeObserver 改为等比例分配策略(替代固定默认值恢复):窗口 Snap/最大化/手动缩放时左-中-右三栏按当前比例同步缩放
  • 修复拖拽期间窗口缩放竞态:handleMouseUp 即时清除 draggingRef + needsRecalcRef 延迟补算,解决拖拽中最大化后放开鼠标布局卡死
  • 使用 containerRef.current 动态读取 DOM替代闭包捕获 mount 时 el),避免 Provider 重渲染后读到旧 DOM

Seedance2Content 内容编排

  • SeedanceContent 从占位文本重构为完整内容编排控件:文本描述 + 参考图片/视频/音频三条上传通道
  • 根据 param_schema[].spec.image_files / video_files / audio_files 动态渲染对应上传区域,不依赖 widget 名称的隐式约定
  • 内部值类型 { text, imageUrls[], videoUrls[], audioUrls[] } → 表单 JSON 字符串 → 提交时序列化为 API ContentItem[]text / image_url / video_url / audio_url 判别联合)
  • useModelUI 新增 widgetName 字段 + spec 媒体文件计数传参(imageFiles/videoFiles/audioFiles/uploadProvider
  • ModelInputForm.doSubmit 新增 seedance2Content 分支序列化逻辑

图片上传兼容视频文件

  • ImageInput / ImageListInputbuildAccept 根据 file_filter 自动区分 image/ vs video/ 前缀(原硬编码 image/ 导致视频文件不可选)
  • createMediaBeforeUpload 根据 filters 动态放行 video/* MIME
  • 公共模块 media-upload-utils.tsVIDEO_EXTENSIONS + buildAccept() + createMediaBeforeUpload() 三组件共享

本地存储基建sql.js + safeStorage

  • 数据库sql.jsWASM SQLite渲染进程内存数据库DDL 7 张表task_records / order_records / param_history / media_cache / sync_cursor / app_settings / _schema_version
  • 加密safeStorageOS DPAPI/Keychain加密持久化base64 编解码管线
  • IPC 文件操作8 个双向 IPC 通道FILE_WRITE/READ/DELETE/MAKE_DIR/SHOW_ITEM_IN_FOLDER/GET_DATA_DIR/FILE_SIZE/FILE_EXISTSresolveSafe() 路径穿越防护
  • 数据目录<userData>/heixiu-data/(沙箱内),含 heixiu.db(加密镜像)+ media-cache/<userId>/<date>/
  • 用户隔离JWT user_id 区分数据,getTodayKey() 日期分桶
  • 同步策略:本地优先 + 手动触发("加载历史数据"按钮),游标分页(sync_cursor 表),每批 100 条
  • 设置集成DataManageSetting 卡片(缓存统计 + 加载历史数据 + 保存到磁盘 + 清理缓存)

媒体输出预览优化

  • <img>/<video> 直接加载远程 URL无 CORS 限制),移除阻塞式 axios 下载
  • 类型检测URL 扩展名正则 + output_type 补充CDN 无扩展名链接)
  • <Image fallback> 加载失败占位图

其他

  • 修复 errorMessageRef 在渲染期间写入react-hooks/refs 警告)
  • CSP 添加 wasm-unsafe-eval 支持 WebAssembly + https: CDN 媒体源

0.0.212026-06-15

文件结构重组components/ pages/ 按职责分层

components/ → 三层拆分

  • providers/状态管理AppProvider / ThemeProvider / SettingsProvider
  • shell/应用外壳Layout / PageDispatcher / navbar/
  • ui/通用原子FloatingPanel / LegalTextModal

pages/ → 重命名消除歧义

  • headers/panels/NavBar 面板页,非 HTTP headers
  • login/auth/(含登录/注册/忘记密码/修改密码)
  • settings/blocks/sections/
  • home/components/useUI/home/controls/

home/ → 四层子结构

  • panels/ — 布局壳LeftPanel / CenterPanel / RightPanel
  • features/ — 功能面板Banner / ModelInput / ModelSelector / Output / TaskHistory
  • controls/ — 表单控件库12 个控件 + Widget 注册表)
  • hooks/ — 纯 HookuseModelUI

其他

  • HomeContext 从 HomeContent.tsx 拆分独立文件(解决 react-refresh ESLint 警告)
  • uploadValidation 内联到 ImageInputcontrols/ 不再混工具函数)
  • 删除空占位 Test3.tsx

支付系统 & 订单明细

  • RechargePage antd 6.x 适配InputNumber.addonAfterSpace.CompactSpace directionorientation,消除弃用警告
  • OrdersPage 订单明细页面/orders,方案 B — 独立订单管理页):
    • 状态筛选 Segmented全部/待支付/已支付/已过期/支付失败)+ 分页 Table
    • "继续支付"操作:打开支付 URL + startPolling 单订单轮询
    • pollingRef: Map<orderId, timer> 管理多订单并发轮询,幂等启动(重复点击防重)
    • 局部 state 更新 + 终态全量刷新(fetchOrders
    • AbortController 防竞态:切换筛选/分页时取消旧请求
    • columns 使用 useMemo 稳定引用
    • 错误态 Result + 重试按钮
  • PageDispatcher:注册 /orders 路由width: 820, height: 640新增 CLOSE_PAGE / PAGE_LOCK 事件监听
  • payments.ts:支付 API 模块类型体系(CreateOrderResponseBodyOrderListResponseBody / OrderInfoResponseBody 名义类型),PaymentAPI.getOrdersListInfo 支持 AbortSignal

0.0.202026-06-12

任务状态轮询 + Token 刷新容错增强 + 提交防抖 + 文件上传 Hook

任务状态轮询

  • 新增 useTaskPolling hook批量轮询非终态任务状态递归 setTimeout + next_poll_ms 自适应间隔
  • TaskHistory 集成批量轮询,OutputPreview 改为监听终态转换Context 桥接)触发 refetch(),消除重复请求
  • POLLING_STATUSES 统一管理非终态状态,所有轮询逻辑引用此常量
  • batchTaskStatus 使用 GET + 逗号拼接 task_ids=a,b,c,修复 axios 默认 bracket 序列化

Token 刷新容错增强

  • 主动刷新JWT exp 解码驱动定时器,在 75% 过期点通过 setTimeout 提前续期
  • 失败分级refreshHandler 永久失败refresh_token 过期)→ throw → 清 token 弹登录;临时失败(网络超时)→ return null → 仅拒绝当前请求不登出
  • 新增 RefreshTokenExpiredError 类区分失败类型
  • AppProvider 登录/自动登录/退出 启停主动刷新定时器

提交按钮防抖

  • 两级防护2s 节流防抖("你点击的太快了"+ 二次确认弹窗("您已提交,确认要再次提交吗?"
  • doSubmit 抽取为 useCallbackhandleSubmit 负责门控
  • 修复 useAsyncMutation.execute 返回值判空(原 try/catch 为死代码)

文件上传 Hook

  • 新增 useFileUpload hook封装 request.upload() 为 antd Upload 兼容 customRequest,复用全局拦截器
  • ImageInput / ImageListInput / AudioListInput 集成 customRequest
  • uploadValidation.beforeUpload 返回值修正:falsetrue(校验通过后放行至 customRequest

其他

  • AnnouncementDrawer 接入公告 API + EnumResolver
  • billing / announcement / banner 服务模块完善
  • 文档ARCHITECTURE.md 新增轮询/Token刷新/上传/防抖章节

0.0.192026-06-11

数据获取架构重构 + Mac 指纹采集 + Token 刷新容错 + 账单页面

数据获取架构重构

  • useAsyncData 集成 AbortControllercleanup 时真正中断 HTTP 请求,不再仅丢弃响应(解决 StrictMode 双重请求)
  • fetcher 签名变更:() => Promise<T>(signal: AbortSignal) => Promise<T>
  • API 模块统一 signal?: AbortSignal 可选参数,透传 axios configbanner/auth/models/task/vip
  • use-api.ts 成为数据 Hook 集中管理中心:
    • 新增 useAccountInfoPromise.all 并行获取用户信息 + VIP 等级
    • 新增 useBillingBalance — 账户余额
    • 新增 useBillingLedger — 账单明细(支持分页参数)
  • AccountInfo.tsx 重构:~40 行手写状态管理(useRef+useEffect+cancelled+retryTick)→ 1 行 useAccountInfo()
  • 共享工具 src/utils/display.tscentToYuan / formatDate,消除 AccountInfo/BillingInfo 重复定义
  • 移除 modelFirstFetchDone 模块级变量StrictMode 不安全)

Mac 硬件指纹采集

  • electron/preload/device.ts Mac 完整实现:
    • UUIDioreg -d2 -c IOPlatformExpertDeviceIOPlatformUUID
    • CPUsysctl -n hw.model → 机型标识
    • HDD三级回退 system_profiler SPNVMeDataTypeSPSerialATADataTypeSPHardwareDataType
  • isMacOS() / runMacCommand() / getMacHddValue() 辅助函数
  • getComponentId() / fingerprintSha256() Mac 早退分支,与 Windows 共享 SHA256 管线

账单页面

  • BillingInfo.tsx — 余额卡片BalanceCard+ 账单表格LedgerTable+ 分页
  • BillingAPIgetBalance / getLedgersignal 参数透传
  • PageDispatcher 注册 /billing 页面FloatingPanel 960×680
  • 修复 billing.ts signal 参数位置 bugget(url, {signal})get(url, undefined, {signal})
  • BillingInfo 标题精简:移除冗余页面 Title 和 Card title仅保留 FloatingPanel 标题栏

Bug 修复

  • Token 刷新容错auth-token.ts):网络错误/超时时保留 refresh_token仅 RefreshErrortoken 过期)时清除。 解决网络短暂中断后被迫手动重新登录的问题
  • AppProvider 自动登录email/admin_permissions 等 nullable 字段默认值修复(?? '' / ?? []
  • antd Table alignalign: 'left'align: 'left' as const,修复 TS2322 类型错误
  • 分页器位置:显式添加 position: ['bottomRight']

文档

  • CLAUDE.md 精简为 AI 行为规则,项目技术内容移入 ARCHITECTURE.md
  • ARCHITECTURE.md 新增数据获取架构、页面调度详情、Token 刷新错误分类、设备指纹

0.0.182026-06-10

前后端联调 — 任务创建 + 账户信息 + 预估花费

任务创建联调

  • CreatTaskRequestBody.device_id 改为后端必填参数API 层 Omit 封装,自动注入 getDeviceId()UUID v4 持久化,与登录/注册统一)
  • useSubmitTask 泛型同步改为 Omit<CreatTaskRequestBody, 'device_id'>,调用方无感
  • submitTask 移除 body.device_id || getDeviceId() 兜底逻辑,始终以本地生成的设备 ID 为准

预估花费计算(与 QT/Python 后端对齐)

  • src/utils/pricing.ts — 从 Python 后端 calculate_cost 完整移植六种定价模式:
    • 服务端:SIMPLE · MULTI_DIMENSION · BILLING_ADAPTERper_k_chars / rate + 条件附加费)
    • 客户端:fixed · per_k_chars · rate_matrix · matrix
  • ModelInputForm.tsx — 三层兜底预估消费展示:完整动态计价 → 配置文件兜底提取 → 模式标签
  • 修复 6 个定价 Bug
    • SIMPLE 浮点冗余 (x/100)*100 在 IEEE 754 下不恒等 → Math.round(分子)/100
    • rate_matrix / matrix 内联维度匹配缺少 .trim().toLowerCase() + null 跳过 → 统一 matchDimensions()
    • lookupMappingValue / matchDimensions 缺 null 守卫 → Cannot use 'in' operator 崩溃
    • rate_matrix 错误应用 unit_scalePython spec 无此行为)→ 移除乘法
    • matrix 模式 dimensions 空值提前返 nullMULTI_DIMENSION 不一致)→ 对齐处理
    • 矩阵维度提取 row.raw — API 实际在行顶层存储维度(如 resolutionraw 子对象不存在 → matrixRowData() 兼容两种格式
  • pricing_config 类型修正:Record<string, unknown>Record<string, unknown> | null(对齐 OpenAPI anyOf
  • 修复 React Hooks 顺序违例 — estimatedCostDisplay useMemo 移至提前返回之前

账户信息联调

  • AccountInfo.tsx "当前套餐"从 VIP 等级列表匹配详细数据:
    • vip_level_idVipLevelsItem.id 映射查找
    • 新增套餐说明、套餐周期字段,席位上限优先取 VIP 等级值
    • 到期时间提取 isExpired 变量复用
  • VipAPI.getVipLevels()AuthAPI.getUserInfo() 并行加载

模型列表缓存

  • 加密持久化缓存safe-storage启动时 Promise.all 初始化,缓存优先渲染消除 loading 闪烁
  • useModelList Stale-while-revalidate即时展示缓存 → 后台拉新 → 覆盖缓存

其他

  • VIP API 模块(src/services/modules/vip-api.ts)— 激活码/等级列表/订单/模拟支付
  • ESLint/TS 类型修复(未使用符号清理、分号补充)
  • CLAUDE.md 更新系统兼容性说明

0.0.172026-06-09

修复接口重复调用 — 请求量减半

  • AppProvider 自动登录 useEffect 增加 aborted 清理标志,修复 StrictMode 双重挂载导致 refreshToken/getUserInfo 各调两次
  • useModelList 提升到 LeftPanel 单例调用,修复 ModelSelector 和 TaskHistory 各自独立请求全量模型列表
  • 开发模式 DevTools 中"已停止"的请求即为 StrictMode 第一轮挂载被丢弃的请求
  • 模型输入栏三层架构useUI 组件体系10 种 widget → antd 映射)+ useModelUI Hookparam_schema → UIFieldConfig[]
  • constraints_config.requires 动态联动enable_switch 开关控制依赖字段启用/禁用
  • 修复模型默认值不加载antd 外部 form 实例忽略 initialValues+ DependentFormItem prop 透传断裂
  • PageDispatcher 统一页面调度Modal/Drawer/FloatingPanel 三容器,全局互斥,动态视口尺寸
  • 账户信息页AuthAPI.getUserInfo() 驱动,积分/套餐/统计三卡片布局
  • 代码去重runFieldChecks 校验运行器 + createImageBeforeUpload 上传校验工厂
  • 主题切换性能优化 — View Transitions API + 0.15s 统一过渡 + 设置页增强0.0.15 延续)
  • 目录调整wechat-work/ → headers/

0.0.162026-06-09

模型输入栏重构 + 统一页面调度 + 依赖联动

  • 模型输入栏三层架构useUI 组件体系10 种 widget → antd 映射)+ useModelUI Hookparam_schema → UIFieldConfig[]
  • constraints_config.requires 动态联动enable_switch 开关控制依赖字段启用/禁用
  • 修复模型默认值不加载antd 外部 form 实例忽略 initialValues+ DependentFormItem prop 透传断裂
  • PageDispatcher 统一页面调度Modal/Drawer/FloatingPanel 三容器,全局互斥,动态视口尺寸
  • 账户信息页AuthAPI.getUserInfo() 驱动,积分/套餐/统计三卡片布局
  • 代码去重runFieldChecks 校验运行器 + createImageBeforeUpload 上传校验工厂
  • 主题切换性能优化 — View Transitions API + 0.15s 统一过渡 + 设置页增强0.0.15 延续)
  • 目录调整wechat-work/ → headers/

0.0.152026-06-09

主题切换性能优化 — 桌面端流畅度提升

  • View Transitions API 驱动主题切换GPU 合成器单次 cross-fade 替代 80+ 个独立 CSS 过渡,消除 Electron 卡顿
  • 主题更新时序统一:applyHtmlTheme 从 updater → useLayoutEffectCSS 变量与 React 提交同帧
  • 过渡参数对齐:全部 0.2s ease0.15s linear,桌面应用更利落
  • CSS 过渡精准覆盖antd 容器组件Layout/Card/Modal/Table/Input/Menu 等 ~80 个类)替代 html * 全局选择器
  • 设置页 Esc 键关闭 + macOS 关闭按钮适配 + 关闭后焦点防跳转

0.0.14 -- 🚀更新公告

模型选择器焕新

  • 模型列表改为标签页分组展示新增「全部模型」Tab
  • 列表项新增悬停高亮效果,维护中模型自动置灰并提示
  • 修复选择模型后参数表单重复 key 报错
  • 类型体系重构,支持后端分类 slug 自动映射

0.0.132026-06-07

  • 修复主题切换后首页状态重置问题:设置页去路由化,改为事件总线驱动的 Modal 叠加
  • 首页三栏分隔条视觉对齐:移除右侧多余 margin左右完全对称
  • 轮播图新增关闭按钮session 级别隐藏,每次启动重新展示
  • 确立 QT 多窗口模型 → Web 架构映射原则:叠加层走 Modal/Drawer + 事件总线,不走路由
  • 修复首页三栏布局溢出:拖拽分隔条增加最大宽度约束 + 视口缩小时自动收窄面板,防止右侧面板被挤出视口

0.0.122026-06-04

  • 重构更新检查流程无更新不再抛异常PreCheck → 直接 IPC 通知
  • 新增用户决定下载流程:检查到新版本后展示更新内容,用户确认后再下载
  • 设置页新增"查看详情"弹窗Markdown 格式化展示更新日志
  • 新增"下载更新"按钮,与"安装更新"分离为两个独立操作
  • 修复测试服务器版本排序(字符串序 → 语义版本序0.0.10 正确排在 0.0.9 之后)
  • electron-updater Provider 增加 TTL 缓存,避免重复 API 请求
  • 修复 Windows cmd set 命令空格导致的 Invalid URL 问题
  • 修复 electron-updater 'error' 事件拦截,无更新不再爆红

格式说明

每个版本以 ## x.y.z日期 开头,内容为无序列表。打包脚本会提取最新版本的日志填入 update-info.json。