Files
g3fo-recurring-investment/IMPACT_ANALYSIS.md
T
justin a374bf0178 Enhance recurring investment features and UI components:
- Implement restrictions on the start date selection in the creation form to prevent past dates.
- Add order status display in the recent execution records for better visibility.
- Introduce system code mapping for order statuses, frequency types, and end types, ensuring multi-language support.
- Implement pagination for the investment plans list to improve performance and user experience.
- Update internationalization files to include new labels for order status and other UI elements.
- Document changes in `IMPACT_ANALYSIS.md` and `TASK_SUMMARY.md` for clarity on the updates.
2026-10-14 14:19:14 +08:00

1238 lines
50 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Impact Analysis Report
## 1. 改动概览
- **背景与目标**:按 V5 demo `hkex-trade/recurring-investment.html` 落地「定期投资」页面(计划列表、创建表单、确认弹窗、终止计划),作为应用首页。
- **涉及模块**:路由首页、顶栏导航、i18n、全局主题色、定期投资视图/组件/Store。
- **改动类型**:功能新增 + 视觉令牌对齐。
## 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `src/router/index.ts` | `/` 由 `HomeView` 改为 `RecurringInvestmentView`;`meta.titleKey` 改为 `recurring.title`。 |
| `src/stores/recurringPlans.ts` | 新增 `addPlan` / `cancelPlan` / `runningCount`;内存示例数据,无接口。 |
| `src/views/RecurringInvestmentView.vue` | 新增列表、表单校验、确认弹窗、移动端卡片。 |
| `src/components/recurring/AssetChipPicker.vue` | 新增资产晶片多选与搜索下拉。 |
| `src/composables` / `useUrlPreferences` | 未改;语言主题仍仅走 URL query。 |
| `src/styles/main.scss` / `variables.scss` | 主色与语义色对齐 demo(`--color-primary` 等);新增 `--color-up/down/warn` 等令牌。 |
| `src/i18n/locales/*` | 新增 `recurring.*` 文案(繁/简/英)。 |
| `src/components/AppHeader.vue` | 已自 `App.vue` 移除引用并删除组件文件;壳层不再展示顶栏标题与导航。 |
| `src/App.vue` | 去掉 `<AppHeader />`,页面内容由 `RouterView` 直接渲染。 |
| `src/styles/element-plus-theme.scss` | 新增:对齐 `--el-*` 输入/选择框 hover、focus 与 `--color-*` 令牌(含 `html.dark` 下 primary RGB)。 |
与原逻辑差异:首页不再展示 ECharts 示例(`HomeView.vue` 仍保留,未挂路由)。表单提交仅写入 Pinia 内存,不调用后端。
## 3. 调用方与影响范围分析
- **路由 `/`**:所有默认入口进入定期投资页。
- **顶栏**:`common.home` 不再作为首页标签;关于页路由不变。
- **主题变量**:`--color-bg` / `--color-muted` / `--color-primary` 变化会影响顶栏与关于页观感(非接口行为)。
- **破坏性变更**:否(无对外 API;旧首页组件文件仍在仓库中)。
## 4. 风险与回滚
- **风险级别**:低。纯前端示例页,计划数据刷新即丢失。
- **主要风险**:移动端表格改为卡片,与 demo 桌面表有布局差异(符合本仓库响应式规范)。
- **回滚**:将 `/` 指回 `HomeView.vue`,并还原主题变量与顶栏文案。
- **回滚方式是否简单**:是。
## 5. 验证与测试
- `npm run build`(vue-tsc + Vite)通过。
- 浏览器冒烟:列表展示、资产搜索选择、校验、确认建立、终止计划、语言/主题 URL 切换、移动端卡片。
## 配置变更
无环境变量或配置中心变更。
---
## 补充:Token、开发代理与服务端多语言(2025-10-08)
### 1. 改动概览
- **背景与目标**:与 Order-H5 一致,支持 URL `token` 写入请求头;本地开发代理到 `192.168.3.233`;通过 `getAllList` 加载服务端多语言。
- **涉及模块**:`vite.config.ts`、`src/api/http.ts`、`src/stores/auth.ts`、`src/stores/serviceI18n.ts`、`src/api/base.ts`、`src/api/scheduleInvestment.ts`、`src/main.ts`、`src/App.vue`。
- **改动类型**:配置变更 + 基础设施。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `vite.config.ts` | `/base`、`/trade` 代理至 `VITE_API_PROXY_TARGET`(默认 `https://192.168.3.233`)。 |
| `.env.development` | `VITE_API_BASE_URL` 置空;新增 `VITE_API_PROXY_TARGET`。 |
| `src/api/http.ts` | 请求头 `token`、`Accept-Language`;统一 `code === '0'` 成功处理。 |
| `src/utils/token.ts` / `stores/auth.ts` | URL 优先解析 token 并持久化(localStorage)。 |
| `stores/serviceI18n.ts` | 拉取 `/base/systemI18n/getAllList` 并按 zh-CN/zh-TW/en-US 映射。 |
| `src/api/scheduleInvestment.ts` | 封装 `POST /trade/schedule-investment/exchanges`。 |
| `src/main.ts` / `App.vue` | 启动与 query 变化时加载服务端 i18n(有 token 时)。 |
语言/主题仍仅 URL 控制,未使用 localStorage。
### 3. 调用方与影响范围
- 所有经 `http` 的请求需有效 token(与后端约定一致)。
- `useServiceI18n().si18n(id)` 供后续对接接口返回的 `*I18nId` 字段。
- **破坏性变更**:否(定期投资页仍用本地 vue-i18n 文案)。
### 4. 风险与回滚
- **风险级别**:低;无 token 时多语言接口可能失败,前端仍可用本地 messages。
- **回滚**:还原 `vite.config.ts`、`.env.development` 与 `http.ts` 拦截器。
### 5. 验证与测试
- `npm run build` 通过。
### 配置变更(本节)
| 配置项 | 含义 | Dev 默认 |
|--------|------|----------|
| `VITE_API_PROXY_TARGET` | Vite 代理目标主机 | `https://192.168.3.233` |
| `VITE_API_BASE_URL` | Axios baseURL,空则同源 | 空 |
---
## 补充:URL accountId / clientId
- **模块**:`src/config/urlContext.ts`、`stores/auth.ts`、`api/http.ts`、`composables/useAccountContext.ts`、`App.vue`
- **行为**:从 query 解析 `clientId`、`accountId`;POST 体自动附带;仅 URL 来源,不持久化 localStorage
- **破坏性变更**:否
---
## 补充:创建表单交易所下拉(2025-10-08)
### 1. 改动概览
- **背景与目标**:在「创建定期投资」表单中,于「資產」字段上方增加交易所代码下拉,数据来自 `POST /api/admin/exchange/getSelectItemList`。
- **涉及模块**:`src/api/exchange.ts`、`src/views/RecurringInvestmentView.vue`、`src/components/recurring/AssetChipPicker.vue`、`vite.config.ts`、i18n。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `src/api/exchange.ts` | 新增 `getExchangeSelectItemList()`。 |
| `vite.config.ts` | 开发代理增加 `/api` → `VITE_API_PROXY_TARGET`。 |
| `RecurringInvestmentView.vue` | 挂载时拉取交易所列表;`isEnabled === false` 的项不展示;必填校验;切换交易所清空已选资产;未选交易所时禁用资产选择器。 |
| `AssetChipPicker.vue` | 支持 `disabled` 属性。 |
| `src/i18n/locales/*` | 新增 `recurring.exchange`。 |
### 3. 调用方与影响范围
- 创建表单提交仍写 Pinia 内存,`exchangeCode` 暂未写入 `RecurringPlanDraft`(待对接创建 API 时扩展)。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低;接口需登录 token,失败时下拉为空且表单校验拦截。
- **回滚**:移除交易所字段与 `exchange.ts`,还原 `vite.config.ts` 代理项。
### 5. 验证与测试
- `npm run build` 通过。
### 配置变更(本节)
| 配置项 | 含义 |
|--------|------|
| Vite `server.proxy['/api']` | 转发 admin 等 `/api/*` 接口至后端 |
---
## 补充:资产列表对接 getSimpleStockPage(2025-10-08)
### 1. 改动概览
- **背景与目标**:创建表单在选定交易所后,从 `POST /product/product/getSimpleStockPage` 拉取可投标的,请求体 `exchangeCodes` 为交易所下拉选中值;支持 `searchName`。
- **涉及模块**:`src/api/product.ts`、`vite.config.ts`(`/product` 代理)、`RecurringInvestmentView.vue`、`AssetChipPicker.vue`、`InvestAsset` 类型、i18n。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `src/api/product.ts` | 新增 `getSimpleStockPage`、`extractSimpleStockRecords`。 |
| `vite.config.ts` | 开发代理增加 `/product`。 |
| `RecurringInvestmentView.vue` | 交易所变更时请求标的列表;搜索框防抖 300ms 带 `searchName` 重查;映射 `productCode`/`localName`/`productKey` 等到 `InvestAsset`。 |
| `AssetChipPicker.vue` | `loading`、`search` 事件。 |
| `investAssets.ts` | 不再作为创建表单数据源(文件保留)。 |
### 3. 调用方与影响范围
- 资产选择依赖 token 与产品服务可用性;失败时列表为空。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低;`size: 100000` 单次体量较大,需关注后端与网络耗时。
- **回滚**:恢复 `INVEST_ASSETS` 与旧 `AssetChipPicker` 用法,移除 `/product` 代理。
### 5. 验证与测试
- `npm run build` 通过。
---
## 补充:交易所与资产并排布局(2025-10-08)
- **模块**:`RecurringInvestmentView.vue` 表单栅格与 `.field--exchange` / `.field--asset` 样式。
- **行为**:`md+` 同一行各 `12` 列平分;`xs` 仍为两行堆叠。交易所下拉在该行内 `max-width: none` 铺满列宽。
- **破坏性变更**:否。
---
## 补充:资产选择器单选与控件样式对齐(2025-10-08)
- **模块**:`AssetChipPicker.vue`。
- **行为**:资产仅能选一项(新选替换旧选);未选交易所时展示与 `el-select` 一致的「請選擇」占位文案与 `--color-muted` 色;控件高度与边框/背景对齐 Element Plus 默认输入框(32px、`--color-control-*`)。
- **调用方**:`RecurringInvestmentView.vue` 仍使用 `InvestAsset[]`,最多一项。
- **破坏性变更**:否(原多选 UI 改为单选,业务表单语义仍为单资产创建)。
---
## 补充:定期投资页标题/标签字号加大(2026-10-08)
### 1. 改动概览
- **背景与目标**:表头「資產」、表单标题「創建定期投資」、字段标签「交易所 *」、结束方式切换「期數」等文字偏小,提升可读性。
- **涉及模块**:`src/views/RecurringInvestmentView.vue` 样式。
- **改动类型**:视觉调整(无逻辑变更)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `.panel-head h2` / `.panel-head--notes h2` | `13px` → `16px`(含「創建定期投資」「我的計劃」等区块标题)。 |
| `.plan-table th` | `10px` → `13px`,字距略收(`0.12em` → `0.08em`)。 |
| `.field label` | `10.5px` → `13px`,字距略收(`0.1em` → `0.06em`)。 |
| `.end-toggle button` | `13px` → `15px`。 |
### 3. 调用方与影响范围
- 仅本页 scoped 样式;表格表头、表单标签、区块标题、结束方式按钮同步变大。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是(还原上述字号即可)。
### 5. 验证与测试
- 浏览器核对桌面列表表头、创建表单标题/标签/期数切换按钮字号。
---
## 补充:创建表单对齐 schedule-investment 入参(2026-10-08)
### 1. 改动概览
- **背景与目标**:创建定期投资表单字段与交易接口入参一致(投资类型、价格类型、定投周期/执行日、结束类型、交易时间偏移等);`clientId`/`accountId` 仍由 `http` 拦截器从 Pinia 合并。
- **涉及模块**:`RecurringInvestmentView.vue`、`src/types/scheduleInvestment.ts`、`src/utils/scheduleInvestmentPayload.ts`、`src/api/scheduleInvestment.ts`、`src/types/recurringInvestment.ts`、i18n。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| 表单 | 新增 `investmentType`、`orderPriceType`、`frequencyType`、`frequencyDay`、`ctOffsetMinutes`;按金额/数量切换输入;周期仅 DAILY/WEEKLY/MONTHLY。 |
| `buildScheduleInvestmentCreateBody` | 将表单映射为 `ScheduleInvestmentCreateBody`(含 `endType` NO_END/END_DATE/COUNT、`totalExecutionCount`、`productCode`)。 |
| `createScheduleInvestmentPlan` | `POST /trade/schedule-investment/plan/create`;确认建立时调用,成功后仍写入本地示例列表。 |
### 3. 调用方与影响范围
- 创建流程依赖 URL `token`、`clientId`、`accountId` 及后端 create 接口可用。
- **破坏性变更**:否(列表仍用本地 Pinia;表单原「间隔」细粒度选项改为与接口一致的三种周期)。
### 4. 风险与回滚
- **风险级别**:中(create 路径或字段名若与后端不一致需调整 API 封装)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;表单校验与确认弹窗预览。
---
## 补充:创建表单控件宽度统一(≥768px 为 70%)
### 1. 改动概览
- **背景与目标**:宽屏下 `el-select` 被 `max-width: 340px` 限制,而 `el-input`、资产选择框为 100% 列宽,视觉不一致;统一为平板及以上宽度占字段区域 70%,移动端仍为 100%。
- **涉及模块**:`RecurringInvestmentView.vue`(`.form-body` 样式)。
- **改动类型**:缺陷修复 / UI。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `.form-body` | 新增 CSS 变量 `--form-control-width`:`100%`(默认)、`respond-up(md)` 时为 `70%`。 |
| `.control-*` / `.end-toggle` / `.asset-wrap` | 移除 `max-width: 340px`,统一使用 `--form-control-width`。 |
### 3. 调用方与影响范围
- 仅定期投资创建表单面板内控件宽度;无脚本与 API 变更。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是(还原样式块即可)。
### 5. 验证与测试
- 宽屏(≥768px)下交易所、资产、金额/数量、下拉、日期、结束方式切换条宽度一致为 70%;窄屏仍为全宽。
---
## 补充:创建定投接口路径更正
### 1. 改动概览
- **背景与目标**:后端创建计划路径为 `POST /trade/schedule-investment/plan/create`,与前端原 `/trade/schedule-investment/create` 不一致导致 404。
- **涉及模块**:`src/api/scheduleInvestment.ts`。
- **改动类型**:缺陷修复。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `createScheduleInvestmentPlan` | URL 改为 `/trade/schedule-investment/plan/create`;入参 `ScheduleInvestmentCreateBody` 不变。 |
### 3. 调用方与影响范围
- 调用方:`RecurringInvestmentView.vue` 确认建立流程。
- **破坏性变更**:否(仅修正路径)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- 带 `token`、`clientId`、`accountId` 提交创建;确认网络请求路径与响应 `code === 0`。
---
## 补充:交易所下拉改用 schedule-investment/exchanges
### 1. 改动概览
- **背景与目标**:创建表单交易所选项改为 `POST /trade/schedule-investment/exchanges`,不再调用 `/base/exchange/getAllExchanges`。
- **涉及模块**:`scheduleInvestment.ts`、`scheduleInvestment.ts`(类型)、`RecurringInvestmentView.vue`;删除 `src/api/exchange.ts`。
- **改动类型**:缺陷修复 / 接口对齐。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `getScheduleInvestmentExchanges` | 返回类型 `ScheduleInvestmentExchangeItem[]`(`exchangeCode`、`nameI18nId`、`tradeDate`)。 |
| `loadExchangeOptions` | 调用上述接口;展示文案仍经 `si18n(nameI18nId)`。 |
| `exchange.ts` | 已删除。 |
### 3. 调用方与影响范围
- 仅定期投资页交易所下拉;资产搜索仍用 `getSimpleStockPage` + `exchangeCodes`。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低(若 `data` 非数组需再适配分页结构)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- 打开创建表单,交易所下拉有数据且标签为 i18n 名称;切换后资产列表正常加载。
---
## 补充:我的计划列表对接 plan/page
### 1. 改动概览
- **背景与目标**:「我的定期投資計劃」由 `POST /trade/schedule-investment/plan/page` 拉取,仅传分页 `current`/`size`,其余筛选项传空字符串;移除 Pinia 内存示例数据。
- **涉及模块**:`scheduleInvestment.ts`(API/类型)、`scheduleInvestmentPlanMapper.ts`、`recurringPlans.ts`、`RecurringInvestmentView.vue`、i18n。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `getScheduleInvestmentPlanPage` | `current`+`size` 及空筛选字段请求;映射 `records` → `RecurringPlan`。 |
| `loadPlans` | 挂载与创建成功后刷新列表;`runningCount` 按非终止状态统计。 |
| `recurringPlans` store | 去掉 `addPlan` 与种子数据,改为 `setPlans`。 |
### 3. 调用方与影响范围
- 列表展示金额/数量、周期+执行日、结束日期/期数/无结束;终止按钮仍为本地状态(待对接终止 API)。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低(分页暂取第一页 `size=50`;若 `current` 须从 0 起需再对齐)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- 进入页面请求 `plan/page`;创建成功后列表刷新;`ACTIVE` 计入进行中数量。
---
## 补充:创建入参字段 qtyPerExecution
- **改动**:`ScheduleInvestmentCreateBody` 与 `buildScheduleInvestmentCreateBody` 中按数量定投字段由 `quantityPerExecution` 改为 `qtyPerExecution`,与接口及列表 `records` 一致。
- **破坏性变更**:否(仅请求 JSON 字段名)。
- **风险**:低。
---
## 补充:限价单 limitPrice
- **改动**:`orderPriceType === 'LIMIT'` 时表单展示「限价」输入,校验 `> 0`,创建请求体附带 `limitPrice`;市价单不传该字段。
- **涉及**:`RecurringInvestmentView.vue`、`scheduleInvestmentPayload.ts`、`ScheduleInvestmentCreateBody`、i18n。
- **破坏性变更**:否。
- **风险**:低。
---
## 补充:创建计划 productEngName / productLocalName
- **改动**:`getSimpleStockPage` 映射保留 `engName`、`localName`;`buildScheduleInvestmentCreateBody` 写入 `productEngName`、`productLocalName`。
- **破坏性变更**:否。
- **风险**:低。
---
## 补充:计划列表「详情」弹窗(2026-10-09)
### 1. 改动概览
- **背景与目标**:我的计划列表「操作」列增加「详情」,调用 `POST /trade/schedule-investment/plan/detail`(`planNo`)弹窗展示计划要点与最近执行记录。
- **涉及模块**:`src/api/scheduleInvestment.ts`、`src/types/scheduleInvestment.ts`、`RecurringInvestmentView.vue`、i18n(zh-TW / zh-CN / en-US)。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `getScheduleInvestmentPlanDetail` | 新增详情接口封装。 |
| 类型 `ScheduleInvestmentPlanDetailData` 等 | 描述 `plan` + `recentExecutions` 响应结构。 |
| `openPlanDetail` / 详情 `el-dialog` | 加载详情、格式化周期/结束/投资方式等字段;执行记录表格或空态。 |
| 列表操作列 / 移动卡片 | 「详情」与「终止」并列。 |
### 3. 调用方与影响范围
- 依赖列表项 `planNo`(来自 `plan/page` 映射);无 `planNo` 时前端提示,不发起请求。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低(只读查询;失败由 http 拦截器提示)。
- **回滚方式是否简单**:是(移除按钮与 API 封装即可)。
### 5. 验证与测试
- `npm run build`;列表点击详情,核对弹窗字段与空执行记录文案。
### 补充(2026-10-09)
- 详情弹窗不再展示「渠道」;「交易所」通过 `getScheduleInvestmentExchanges` 缓存与创建表单相同逻辑(`si18n(nameI18nId)`)反显文案,无匹配时回退 `exchangeCode`。
- 产品行 `productLocalName` / `productEngName`:`en-US` 优先英文,简繁优先本地名(`investAssetDisplay.ts`);列表映射保留双语字段,切换 URL `lang` 后名称随语言更新。
- 计划「終止」:`el-dialog` 二次确认 + 选填 `terminateReason`,调用 `POST /trade/schedule-investment/plan/terminate`(`planNo`),成功后 `loadPlans` 刷新列表。
---
## 补充:创建表单「预览下次执行」(2026-10-09)
### 1. 改动概览
- **背景与目标**:创建计划表单底部增加「预览下次执行」,调用 `POST /trade/schedule-investment/plan/next-execution`,在弹窗展示节假日调整后的执行日与时点。
- **涉及模块**:`src/api/scheduleInvestment.ts`、`src/types/scheduleInvestment.ts`、`RecurringInvestmentView.vue`、i18n(zh-TW / zh-CN / en-US)。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `previewScheduleInvestmentNextExecution` | 新增 next-execution 接口封装。 |
| `ScheduleInvestmentNextExecutionRequest` / `Data` | 描述请求与响应字段。 |
| `validateNextExecutionPreview` / `openNextExecutionPreview` | 校验交易所、周期、执行日(周/月)、CT 偏移;`startDate` 选填传入。 |
| 创建表单 `form-actions` | 增加按钮与预览 `el-dialog`(`ri-preview` 样式)。 |
### 3. 调用方与影响范围
- 仅创建表单使用;不改动「继续」全流程校验(仍要求标的、金额等)。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低(只读预览;失败由 http 拦截器提示)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;填写交易所与周期后点击预览,核对弹窗字段与 `deferred` 文案。
---
## 补充:创建表单 CT 偏移选项接口(2026-10-10)
### 1. 改动概览
- **背景与目标**:「交易時間偏移」由 `POST /trade/schedule-investment/options/ct-time`(`exchangeCode`、`productCode`)拉取选项,下拉展示 `displayName`,取值 `offsetMinutes`。
- **涉及模块**:`src/api/scheduleInvestment.ts`、`src/types/scheduleInvestment.ts`、`RecurringInvestmentView.vue`、i18n(zh-TW / zh-CN / en-US)。
- **改动类型**:功能新增。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `getScheduleInvestmentCtTimeOptions` | 新增 ct-time 接口封装。 |
| `ScheduleInvestmentCtTimeOptionsRequest` / `Data` / `Option` | 描述请求与 `options` 列表结构。 |
| `loadCtOffsetOptions` / `watch` | 交易所与标的变更时请求;当前偏移不在列表时回退首项。 |
| 创建表单 CT 字段 | `el-input-number` 改为可筛选 `el-select`;未选标的时禁用。 |
| `isCtOffsetValid` | 有选项时校验是否在列表内;无选项时保留 0–240 兜底。 |
### 3. 调用方与影响范围
- 仅创建计划表单;创建/预览请求体仍传 `ctOffsetMinutes` 数值。
- **破坏性变更**:否(交互由手输改为下拉,选项由后端决定)。
### 4. 风险与回滚
- **风险级别**:低(依赖交易所+产品;失败时选项为空、字段禁用,提交校验不通过)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;选择交易所与资产后确认下拉加载与提交偏移值正确。
---
## 补充:计划列表金额/数量展示(2026-10-09)
### 1. 改动概览
- **背景与目标**:移动卡片按 `investmentType` 区分「金额」「数量」标签;桌面列表表头统一为「金额/数量」。
- **涉及模块**:`RecurringInvestmentView.vue`、`src/i18n/locales/*`(`recurring.colAmount`)。
- **改动类型**:缺陷修复 / 文案对齐。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `planInvestmentLabel` | 新增:`QUANTITY` → `recurring.quantity`,否则 `recurring.amount`;用于移动卡片 meta 的 `<dt>`。 |
| `recurring.colAmount`(三语) | 由单一「金额」改为「金额/数量」(与 `planDetail.colAmount` 一致),用于计划列表表头。 |
### 3. 调用方与影响范围
- 计划列表移动卡片与桌面表头文案;单元格数值仍由 `planInvestmentDisplay` 输出。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;列表含 AMOUNT / QUANTITY 计划时核对卡片标签与表头。
---
## 补充:计划列表资产列省略与 Tooltip(2026-10-09)
### 1. 改动概览
- **背景与目标**:桌面计划表「资产」列限制宽度,长名称单行省略,悬停 `el-tooltip` 展示全文。
- **涉及模块**:`RecurringInvestmentView.vue`(`planAssetCellText`、表样式 `plan-table__asset-*`)。
- **改动类型**:体验优化。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `planAssetCellText` | 拼接代码、名称与 `+N` 多标的后缀,供 tooltip 与展示一致。 |
| `plan-table` | `table-layout: fixed`;资产列宽约 220px;内层 `text-overflow: ellipsis`。 |
### 3. 调用方与影响范围
- 仅「我的计划」桌面表格首列;移动卡片不变。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;长产品名悬停可见完整 tooltip。
---
## 补充:移动计划卡片操作按钮样式(2026-10-09)
### 1. 改动概览
- **背景与目标**:移动卡片「详情 / 终止」与桌面表一致,纯文字链接、无边框。
- **涉及模块**:`RecurringInvestmentView.vue`(复用 `detail-link` / `cancel-link`)。
- **改动类型**:体验优化。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| 计划卡片 `plan-card__actions` | 按钮类名改为 `detail-link`、`cancel-link`;移除 `plan-card__detail` / `plan-card__cancel` 边框样式。 |
### 3. 调用方与影响范围
- 仅移动端计划卡片底部操作区。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- 移动断点下核对详情(主色)、终止(跌色)文字与悬停下划线。
---
## 补充:清理脚手架示例(2026-10-09)
### 1. 改动概览
- **背景与目标**:接口已全部对接,移除未使用的 ECharts 示例、关于页、静态资产列表与相关依赖/文案。
- **涉及模块**:路由、视图/组件删除、`i18n`、`main.scss`、`package.json`、文档。
- **改动类型**:重构 / 清理。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| 删除 `SampleChart.vue`、`HomeView.vue`、`AboutView.vue` | 不再保留未挂路由或纯技术栈展示的页面。 |
| 删除 `constants/investAssets.ts` | 创建表单资产已由 `getSimpleStockPage` 提供,静态列表无引用。 |
| `router/index.ts` | 移除 `/about`;首页路由名改为 `recurring-investment`。 |
| `package.json` | 移除 `echarts` 依赖。 |
| `main.scss` | 移除仅示例图表使用的 `--chart-height`、`--color-chart-*`。 |
| `i18n` | 移除 `home.*`、`common.home`/`common.about`;新增 `recurring.amountPlaceholder`。 |
| `RecurringInvestmentView.vue` | 金额输入 placeholder 改为 i18n。 |
### 3. 调用方与影响范围
- 无对外 API;用户若曾收藏 `/about` 将 404(本应用此前无入口链至该页)。
- **破坏性变更**:否(功能面仅删除未使用示例)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是(自 Git 恢复删除文件与依赖)。
### 5. 验证与测试
- `npm run build`。
- 冒烟:定期投资列表/创建/详情/终止、语言切换。
---
## 补充:URL `lang` 短码与 README(2026-10-10)
### 1. 改动概览
- **背景与目标**:文档与地址栏统一使用 `zh` / `tw` / `en` 作为 `lang` 查询参数;完善 README。
- **涉及模块**:`src/config/appLocale.ts`、`src/config/urlPreferences.ts`、`README.md`、`.cursor/rules/project-core.mdc`。
- **改动类型**:配置/文档 + 行为小幅调整。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `appLocale.ts` | 新增 `URL_LANG_CODES`、`resolveLocaleFromLangParam`、`localeToUrlLang`;短码映射到内部 `zh-CN` / `zh-TW` / `en-US`。 |
| `urlPreferences.ts` | 读入经 `resolveLocaleFromLangParam`;写出 `preferencesToQuery` 使用短码。 |
| `README.md` | 补充环境、目录、URL 参数表与示例(`lang=zh|tw|en`)。 |
仍接受旧 URL `lang=zh-TW` 等;切换或写入 query 时地址栏为 `tw` 等短码。
### 3. 调用方与影响范围
- **调用方**:`parsePreferencesFromSearch` / `parsePreferencesFromQuery` / `preferencesToQuery`(`main.ts`、`app` store、`useUrlPreferences`)。
- 内部 `AppLocale` 与 vue-i18n 键名不变;仅 URL 展示与解析规则扩展。
- **破坏性变更**:否(旧长格式仍可读;书签若依赖写出为长格式,首次 replace 后会变为短码)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是(还原 `appLocale` / `urlPreferences` 与文档)。
### 5. 验证与测试
- `npm run build`:通过。
- 建议手工:`?lang=zh`、`?lang=tw`、`?lang=en` 及 `?lang=zh-TW` 兼容读取。
---
## 补充:Vite 开发服局域网 / 隧道访问(2026-10-10)
### 1. 改动概览
- **背景与目标**:`npm run dev` / `preview` 可通过本机 IP 或穿透域名访问,不限于 localhost。
- **涉及模块**:`vite.config.ts`、`README.md`。
- **改动类型**:配置变更。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `vite.config.ts` | `server.host: true`、`server.allowedHosts: true`;`preview` 同步 `host` / `allowedHosts`。 |
### 3. 调用方与影响范围
- 仅本地/内网开发体验;生产构建产物不变。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低(开发机需自行注意防火墙与勿暴露敏感环境)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run dev`:终端出现 Network URL;同网段可打开页面。
---
## 补充:frequencyDay 与后端约定对齐(2026-10-10)
### 1. 改动概览
- **背景与目标**:后端 `WEEKLY` 支持 `1`–`7`(ISO 周一=1)、英文全名/三字码;`MONTHLY` 支持 `1`–`31`(可带前导零);`DAILY` 不传 `frequencyDay`。前端提交已用 `MON`…`SUN` 与 `1`…`31`,需兼容接口回显。
- **涉及模块**:`src/utils/frequencyDay.ts`(新增)、`scheduleInvestmentPlanMapper.ts`、`RecurringInvestmentView.vue`。
- **改动类型**:缺陷修复 / 行为对齐。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `frequencyDay.ts` | `normalizeWeeklyDayToCode`、`normalizeMonthlyDay`、`formatFrequencyDayLabel`。 |
| `scheduleInvestmentPlanMapper.ts` | 列表映射时将 `frequencyDay` 规范为表单/i18n 可用值。 |
| `RecurringInvestmentView.vue` | 计划列表、详情频率、确认预览统一走 `formatFrequencyDayLabel`。 |
### 3. 调用方与影响范围
- 创建/预览请求体:`DAILY` 不传 `frequencyDay`;`WEEKLY`/`MONTHLY` 经 `frequencyDayForApi` 仅提交数字字符串(周 `1`–`7`,月 `1`–`31`)。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`。
---
## 补充:VITE_BASE_URL 接入 Vite base(2026-10-10)
### 1. 改动概览
- **背景与目标**:`.env.development` 已配置 `VITE_BASE_URL=/recurring-investment`,需写入 Vite `base`,使静态资源与 Vue Router 子路径部署一致。
- **涉及模块**:`vite.config.ts`、`src/env.d.ts`、`.env.production`、`README.md`。
- **改动类型**:配置变更。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `vite.config.ts` | `loadEnv` 读取 `VITE_BASE_URL`,经 `resolveViteBase` 设置 `base`(子路径末尾补 `/`)。 |
| `.env.production` | 新增,与开发环境一致的 `VITE_BASE_URL` / `VITE_API_BASE_URL`。 |
| `src/router/index.ts` | 无改;已使用 `createWebHistory(import.meta.env.BASE_URL)`。 |
### 3. 调用方与影响范围
- 开发与生产入口 URL 为 `/recurring-investment/`(非根路径 `/`)。
- 网关/Nginx 需将应用挂载到同子路径或做等价转发。
- **破坏性变更**:是(若此前按根路径 `/` 访问或部署,需改为带子路径)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚**:删除或清空 `VITE_BASE_URL`,移除 `vite.config.ts` 的 `base` 绑定。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;本地 `npm run dev` 访问 `http://localhost:5173/recurring-investment/`。
---
## 补充:仅创建计划请求体携带 clientId / accountId(2026-10-10)
### 1. 改动概览
- **背景与目标**:除「新建定投计划」外,其余交易/产品/基础接口不应在请求体中附带 URL 解析的 `clientId`、`accountId`。
- **涉及模块**:`src/api/http.ts`。
- **改动类型**:缺陷修复。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `src/api/http.ts` | 移除请求拦截器对 POST `data` 的全局合并 `clientId`/`accountId`。 |
| `src/utils/scheduleInvestmentPayload.ts` / `RecurringInvestmentView.vue` | 无改;创建计划仍通过 `buildScheduleInvestmentCreateBody` 显式写入两字段。 |
### 3. 调用方与影响范围
- 经 `http` 的列表、详情、终止、CT 选项、下次执行预览、`getSimpleStockPage`、`getAllList` 等不再自动附带账户上下文。
- **破坏性变更**:否(与后端契约对齐;创建接口行为不变)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚**:恢复 `http.ts` 拦截器中的合并逻辑。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;创建计划请求体仍含 `clientId`/`accountId`;其它 POST 仅含业务字段。
---
## 补充:资产下拉分页与滚动加载(2026-10-10)
### 1. 改动概览
- **背景与目标**:创建表单资产搜索不再单次请求 `size: 100000`;改为每页 50 条,下拉滚动触底追加加载。
- **涉及模块**:`RecurringInvestmentView.vue`、`AssetChipPicker.vue`、i18n。
- **改动类型**:性能优化 / 体验改进。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `RecurringInvestmentView.vue` | `loadExchangeAssets` 支持 `current` 递增与 `append`;维护 `assetHasMore` / `assetPage` / `assetSearchKeyword`;`onAssetLoadMore` 处理触底。 |
| `AssetChipPicker.vue` | `.asset-drop` 滚动监听,触发 `loadMore`;展示 `hasMore` / `loadingMore` 底部提示。 |
| i18n | 新增 `recurring.assetScrollHint`。 |
### 3. 调用方与影响范围
- 仅定期投资创建表单资产晶片;搜索防抖仍传 `searchName` 并重置为第一页。
- **破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低;若后端 `current` 为 1 起始需与现用 0 起始对齐(与原实现一致)。
- **回滚**:恢复单次大 `size` 请求并移除 `loadMore` 链路。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;交易所切换、搜索、下拉滚动加载更多。
---
## 补充:下次执行预览移除执行时间行(2026-10-10)
### 1. 改动概览
- **背景与目标**:预览弹窗不再展示 `executionDateTime`(`recurring.previewExecutionDateTime`)。
- **涉及模块**:`RecurringInvestmentView.vue`。
- **改动类型**:界面调整。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| 下次执行预览 `<dl>` | 删除 `executionDateTime` 的 `<dt>`/`<dd>`;接口数据仍可能返回该字段,仅不展示。 |
### 3. 调用方与影响范围
- 仅预览弹窗展示;**破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低;**回滚方式是否简单**:是(恢复两行模板)。
### 5. 验证与测试
- 打开「下次执行」预览,确认无「执行时间」行,其余字段正常。
---
## 补充:下次执行预览接口字段与加载态(2026-10-12)
### 1. 改动概览
- **背景与目标**:`POST /trade/schedule-investment/plan/next-execution` 响应 `data` 调整为 `nextExecutionDate`、`nextExecutionTime`;预览弹窗同步展示;请求较慢时按钮与弹窗内展示 loading。
- **涉及模块**:`src/types/scheduleInvestment.ts`、`RecurringInvestmentView.vue`。
- **改动类型**:缺陷修复 / 界面调整。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `ScheduleInvestmentNextExecutionData` | 移除 `scheduledDate`、`executionDate`、`executionDateTime`、`deferred`、`ctOffsetMinutes`;改为 `nextExecutionDate`、`nextExecutionTime`。 |
| `openNextExecutionPreview` | 请求期间按钮 loading;数据返回后再打开弹窗。 |
| 预览弹窗模板 | 仅展示下次执行日、执行时间。 |
| 「预览下次执行」按钮 | `:loading="nextExecutionPreviewLoading"`。 |
### 3. 调用方与影响范围
- 仅创建表单预览流程;**破坏性变更**:是(依赖旧响应字段的前端逻辑已移除,与当前后端契约一致)。
### 4. 风险与回滚
- **风险级别**:低;**回滚方式是否简单**:是(恢复类型与模板)。
### 5. 验证与测试
- 填妥交易所与周期后点「预览下次执行」:按钮 loading、弹窗内 loading,成功后显示日期与时间;接口失败时弹窗关闭且已有错误提示。
---
## 补充:创建计划 productCode 入参(2026-10-12)
### 1. 改动概览
- **背景与目标**:创建定投计划(及 CT 时间选项)应提交接口字段 `productCode`(如 `1`),不得使用展示用 `productCodeUnique`(如 `1.HK`)。
- **涉及模块**:`InvestAsset`、`mapSimpleStockToAsset`、`buildScheduleInvestmentCreateBody`、`resolvePickedProductCode`、`scheduleInvestmentPlanMapper`。
- **改动类型**:缺陷修复。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `InvestAsset` | 新增 `productCode`(接口用),与 `productCodeUnique`(展示用)区分。 |
| `mapSimpleStockToAsset` | 从 `getSimpleStockPage` 写入 `productCode`;`code` 仍为 `productCodeUnique` 优先。 |
| `buildScheduleInvestmentCreateBody` | `productCode` 仅取自 `asset.productCode`。 |
| `resolvePickedProductCode` | CT 选项请求与创建计划一致,仅用 `asset.productCode`。 |
### 3. 调用方与影响范围
- 创建计划、`options/ct-time`;**破坏性变更**:否(修正错误入参)。
### 4. 风险与回滚
- **风险级别**:低;**回滚方式是否简单**:是。
### 5. 验证与测试
- 选择 SEHK `1.HK` 资产创建计划,请求体 `productCode` 为 `1`;CT 偏移选项请求同上。
---
## 补充:计划详情执行记录移除委托状态列(2026-10-12)
### 1. 改动概览
- **背景与目标**:计划详情「最近执行」表格不再展示委托状态。
- **涉及模块**:`RecurringInvestmentView.vue`、三语言 `planDetail.colOrderStatus`。
- **改动类型**:界面调整。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `detail-exec-table` | 删除 `colOrderStatus` 表头与 `row.orderStatus` 单元格。 |
### 3. 调用方与影响范围
- 仅详情弹窗执行记录表;**破坏性变更**:否(接口仍可能返回 `orderStatus`,前端不展示)。
### 4. 风险与回滚
- **风险级别**:低;**回滚方式是否简单**:是。
### 5. 验证与测试
- 打开计划详情,确认执行记录表为四列:计划执行日、实际交易日、金额/数量、执行状态。
---
## 补充:计划详情执行记录成交字段列(2026-10-13)
### 1. 改动概览
- **背景与目标**:详情「最近执行」表去掉「实际交易日」,展示关联委托成交的 `filledQty`、`filledAmount`、`avgFilledPrice`。
- **涉及模块**:`ScheduleInvestmentPlanExecutionRecord`、`RecurringInvestmentView.vue`、三语言 `planDetail` 列文案。
- **改动类型**:界面调整 + 类型扩展。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `ScheduleInvestmentPlanExecutionRecord` | 新增可选字段 `filledQty`、`filledAmount`、`avgFilledPrice`。 |
| `detail-exec-table` | 移除 `actualTradeDate` 列;新增三列及 `formatExecutionFilledQty/Amount/AvgFilledPrice` 格式化。 |
| i18n | 删除 `colActualDate`;新增 `colFilledQty`、`colFilledAmount`、`colAvgFilledPrice`。 |
### 3. 调用方与影响范围
- 仅计划详情弹窗执行记录表;数据来自 `recentExecutions`,无额外请求。**破坏性变更**:否(列展示调整,接口字段向后兼容)。
### 4. 风险与回滚
- **风险级别**:低;**回滚方式是否简单**:是。
### 5. 验证与测试
- 打开计划详情,确认列为:计划执行日、金额/数量、成交数量、成交金额、成交均价、执行状态;无成交数据时三列显示 `0` 或 `—`(字段缺失为 `—`,数值 `0` 正常格式化)。
---
## 补充:计划详情「最近执行」响应式布局(2026-10-13)
### 1. 改动概览
- **背景与目标**:执行记录列增多后,加宽详情弹窗、移动端卡片化、平板横滑提示与表头首列 sticky。
- **涉及模块**:`RecurringInvestmentView.vue`、三语言 `executionTableScrollHint`。
- **改动类型**:界面 / 响应式。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `detailDialogWidth` | 移动 `520px`、平板 `720px`、桌面 `920px`(均 `96vw` 上限)。 |
| `detail-exec-block` | `<768px` 每条执行为卡片;否则表格 + `.app-table-scroll`。 |
| `.detail-exec-table` | 紧凑 padding、表头可换行、计划执行日列 sticky。 |
### 3. 调用方与影响范围
- 仅计划详情弹窗;**破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低;**回滚方式是否简单**:是。
### 5. 验证与测试
- 移动宽:执行记录为卡片,无横向挤压。
- 平板 / 窄桌面:表格可横滑,见提示文案;首列固定。
- 宽桌面:弹窗加宽后六列表格可读。
---
## 补充:创建表单隐藏价格类型与 CT 偏移(2026-10-13)
### 1. 改动概览
- **背景与目标**:创建计划固定市价单,不再展示「订单价格类型」「交易时间偏移」;创建与「预览下次执行」请求显式传 `ctOffsetMinutes: null`(待后端支持缺省/0 后可再调整)。
- **涉及模块**:`RecurringInvestmentView.vue`、`scheduleInvestmentPayload.ts`、`scheduleInvestment.ts` 类型、三语 `recurring.*`。
- **改动类型**:功能调整(表单简化)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| 创建表单 UI | 移除价格类型、限价、CT 偏移控件;投资金额/数量下增加 `orderPriceTypeMarketHint`。 |
| `buildScheduleInvestmentCreateBody` | 固定 `ctOffsetMinutes: null`;`orderPriceType` 固定 `MARKET`。 |
| `buildNextExecutionPreviewBody` | 固定 `ctOffsetMinutes: null`。 |
| `ScheduleInvestmentCreateBody` | `ctOffsetMinutes: number \| null`,创建时传 `null`。 |
| 确认弹窗 | 移除 CT 偏移预览行;仍展示订单价格类型(市价)。 |
| `getScheduleInvestmentCtTimeOptions` | 创建表单不再调用(详情仍可读接口返回的偏移)。 |
### 3. 调用方与影响范围
- 仅创建/预览路径;计划详情、列表仍展示后端返回的 `ctOffsetMinutes`。
- **破坏性变更**:否(对外接口字段减少可选传参,行为与产品约定一致)。
### 4. 风险与回滚
- **风险级别**:低;依赖后端对缺省 `ctOffsetMinutes` 的处理与文档一致。
- **回滚方式是否简单**:是(恢复表单项与 payload 字段即可)。
### 5. 验证与测试
- `npm run build` 通过。
- 创建表单:无价格类型/偏移字段,金额下有两行 hint;预览下次执行仅需交易所与周期。
- 网络:create / next-execution 请求体 `ctOffsetMinutes` 为 `null`。
---
## 补充:结束类型 GTC 下拉项(2026-10-13)
- **背景**:将「无结束日期」勾选并入结束类型 `el-select`,文案为「GTC」。
- **改动类型**:功能优化(UI/表单)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `EndMode` | 新增 `'none'`。 |
| `RecurringInvestmentView` | `endModeOptions` 含 date / none / count;移除 `noEnd` 表单项与勾选框;`date` 模式必填结束日期。 |
| `resolveEndType` | `none`→`NO_END`、`date`→`END_DATE`、`count`→`COUNT`。 |
| `scheduleInvestmentPlanMapper` | API `NO_END`(兼容 `NONE`)映射 `endMode: 'none'`。 |
| i18n | `recurring.endByGtc`、`recurring.endGtcHint`。 |
### 3. 调用方与影响范围
- 创建计划、确认预览、列表/详情结束条件展示文案统一为 GTC 选项。
- **破坏性变更**:是(创建请求 `endType` 由 `NONE`/`DATE` 改为 `NO_END`/`END_DATE`;列表仍兼容旧枚举读取)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;表单三种结束类型切换与提交 payload `endType` 符合预期。
---
## 补充:开始日期禁选过去日 + 详情执行订单状态列(2026-10-14)
- **背景与目标**:创建计划开始日期不得早于今天;计划详情最近执行列表展示后端 `orderStatus`。
- **涉及模块**:`RecurringInvestmentView.vue`、三语言 `planDetail.colOrderStatus`。
- **改动类型**:缺陷修复 / 功能优化(UI)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `disableFormStartDate` / `isStartDateBeforeToday` | 按本地日历日禁用/校验开始日期。 |
| 创建表单 `el-date-picker`(startDate) | 绑定 `:disabled-date="disableFormStartDate"`。 |
| `validate()` | 开始日期为空或早于今天时 `fieldError.startDate`。 |
| 详情 `detail-exec-table` / 移动端卡片 | 末列增加 `colOrderStatus` 与 `row.orderStatus`。 |
### 3. 调用方与影响范围
- 仅创建表单与计划详情弹窗展示;**破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;开始日期面板不可点选昨日;详情执行表末列为订单状态。
---
## 补充:订单状态系统码展示(2026-10-14)
- **背景与目标**:计划详情「最近执行」的 `orderStatus` 为系统码 `codeValue`(如 `12`),需通过 `POST /admin/systemCode/getByCodeTypeBatch`(`param: ['OrderStatus']`)映射 `descriptionI18nId`,并结合已有 `systemI18n` 展示当前语言文案。
- **涉及模块**:`src/api/systemCode.ts`、`src/stores/systemCode.ts`、`src/composables/useSystemCode.ts`、`RecurringInvestmentView.vue`。
- **改动类型**:功能优化(UI)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `getSystemCodeByCodeTypeBatch` | 新增批量查询系统码 API 封装。 |
| `useSystemCodeStore.ensureCodeTypes` | 缓存 `OrderStatus` 等 codeType 的 value→i18nId 映射。 |
| `useSystemCode().codeLabel` | 解析 codeValue 为服务端多语言文案。 |
| `formatOrderStatus` / 详情执行表与移动端卡片 | 原样展示 `row.orderStatus` 改为 `formatOrderStatus`。 |
### 3. 调用方与影响范围
- 仅定期投资计划详情弹窗执行记录「订单状态」列;**破坏性变更**:否(无匹配码时仍回退显示原 codeValue)。
### 4. 风险与回滚
- **风险级别**:低(依赖 admin 系统码与 base i18n 接口可用性)。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;详情执行记录订单状态显示为 i18n 文案而非裸数字码。
---
## 补充:定投周期系统码下拉(2026-10-14)
- **背景与目标**:创建表单「定投周期」选项来自 `getByCodeTypeBatch` 的 `ScheduleInvestmentFrequencyType`(`DAILY` / `WEEKLY` / `MONTHLY`),展示 `descriptionI18nId` 对应服务端多语言;列表/详情/确认预览的周期文案与表单一致。
- **涉及模块**:`systemCode` store/composable、`scheduleInvestment.ts` 常量、`RecurringInvestmentView.vue`、`recurringInvestment.ts`(draft `frequencyType`)。
- **改动类型**:功能优化(UI)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `useSystemCodeStore` | 按 `sort` 保留系统码条目,提供 `getSortedCodeValues`。 |
| `codeSelectOptions` / `codeLabelWithFallback` | 下拉选项与带本地 i18n 回退的文案解析。 |
| `frequencyOptions` | 优先系统码列表,接口失败时回退 `FREQUENCY_TYPE_KEYS` + 静态 i18n。 |
| `frequencyTypeLabel` | 替换多处 `t('recurring.frequency.*')`。 |
| `onMounted` `ensureCodeTypes` | 增加 `ScheduleInvestmentFrequencyType`。 |
### 3. 调用方与影响范围
- 创建表单周期下拉、计划列表/详情/确认弹窗周期展示;**破坏性变更**:否(选项 value 仍为 `DAILY` 等 API 枚举)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;周期下拉为服务端文案;未加载系统码时仍显示静态 i18n。
---
## 补充:结束类型系统码下拉(2026-10-14)
- **背景与目标**:创建表单「结束类型」组合框左侧选项来自 `ScheduleInvestmentEndType`(`NO_END` / `END_DATE` / `COUNT`),展示服务端 i18n;表单内部仍用 `endMode`(`none` / `date` / `count`)与提交逻辑不变。
- **涉及模块**:`scheduleInvestment.ts` 常量、`scheduleInvestmentPlanMapper.ts`(`endMode` ↔ API 枚举)、`RecurringInvestmentView.vue`。
- **改动类型**:功能优化(UI)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `endModeToScheduleEndType` / `scheduleEndTypeToEndMode` | UI 与 API 结束类型互转。 |
| `endModeOptions` | 系统码驱动下拉,`codeValue` 映射为 `endMode`。 |
| `endTypeLabel` | 列表/详情/确认中 GTC 等结束类型文案与下拉一致。 |
| `ensureCodeTypes` | 增加 `ScheduleInvestmentEndType`。 |
### 3. 调用方与影响范围
- 创建表单结束类型选择与相关展示;**破坏性变更**:否。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;结束类型下拉显示服务端文案(如 GTC 对应 `NO_END`)。
---
## 补充:我的计划列表分页(2026-10-14)
- **背景与目标**:「我的定期投资计划」表格/卡片列表对接 `plan/page` 分页,避免一次拉取过多记录。
- **涉及模块**:`RecurringInvestmentView.vue`。
- **改动类型**:功能优化(UI)。
### 2. 方法级改动分析
| 位置 | 差异 |
|------|------|
| `loadPlans` | 使用 `current` / `size` 请求,写入 `planPageTotal`;支持 `loadPlans(1)` 重置页码。 |
| `el-pagination` | 默认每页 10 条,可选 10/20/50;移动端精简 layout。 |
| 空状态 | 以 `planPageTotal === 0` 判断无计划。 |
### 3. 调用方与影响范围
- 计划列表展示与创建/终止后刷新;**破坏性变更**:否(`runningCount` 仍为当前页内统计,与改前单页数据范围一致)。
### 4. 风险与回滚
- **风险级别**:低。
- **回滚方式是否简单**:是。
### 5. 验证与测试
- `npm run build`;翻页、改每页条数后列表与总数一致;新建计划后回到第 1 页。