资金流水
记录模拟交易引起的扣款、回款与交易后余额变化。
From 421fed8569071d74fc20eb1c678282ced3c7189c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=BF=E4=BA=91=E7=A7=8B=E6=9C=88?= <15273589815@163.com> Date: Sun, 13 Sep 2026 23:56:27 +0800 Subject: [PATCH] =?UTF-8?q?feat(advisor):=20=E8=A1=A5=E5=85=A8=E6=8A=95?= =?UTF-8?q?=E9=A1=BE=E6=B5=81=E7=A8=8B=E5=85=A5=E5=8F=A3=EF=BC=88=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E7=9B=AE=E6=A0=87=20=E2=86=92=20=E6=9F=A5=E7=9C=8B?= =?UTF-8?q?=E6=96=B9=E6=A1=88=E4=B9=A6=EF=BC=89=EF=BC=8C=E5=B9=B6=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E9=A1=B5=E9=9D=A2=E7=BC=BA=E7=BC=93=E5=AD=98=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 1. 投顾流程此前是断的 投顾工作台只有 4 个「生成草案」操作 + 1 个只读列表,而**确认目标**与**查看方案书** 这两个端点虽然存在却**没有入口** —— 于是目标永远停在 `pending_confirmation`、 方案书永远停在 `pending`。 实测客户 9001 正是如此:`confirmed_at: null`、方案书 `review_status=pending`。 而「录入客户目标」成功后的提示是"已提交,等待确认与审核",**没有下一步可点**。 改动: - 新增操作卡「目标确认与方案书」:输入客户 ID → 查询目标 → 显示目标状态、 方案书状态、收益区间 / 回撤 / 期限 / 基准 / 确认时间 → **确认目标** / **查看方案书**。 - **录入目标后自动跳到目标状态页**,把确认按钮摆在眼前,而不是停在"已提交"。 - `ADVISOR_CONFIRM_GOAL` / `ADVISOR_GOAL_BOOK` 补登记进 `api-client.js` (`ADVISOR_CUSTOMER_GOAL` 早已注册却从未被使用)。 - 404「当前投资目标不存在」按**正常情况**处理(给下一步提示),不当故障报警。 ⚠️ **审核与发布不在此范围**:`review_book` / `publish_book` 都要求 `admin=True` (见 `investment_goal_service`),那是管理员的动作,投顾侧到"确认 + 看方案书"为止。 方案书仍会停在 `pending`,除非管理员侧也补上入口。 ## 2. 9 个页面的 script 标签缺缓存版本参数 投顾工作台的 script 是 `dashboard.js`(**没有 `?v=`**),另有 8 个页面同样如此 (客户的持仓/下单/流水/盈亏/测评/成交明细、管理员工作台、运营工作台)。 浏览器会一直用缓存的旧 JS —— **改了代码也看不到效果**,这是"功能很奇怪"的一部分。 已统一补上 `?v=20260913`,投顾页的 js/css 提到 `-2`。 ## 3. 过程中我损坏过 8 个文件,已恢复 第一次批量补版本参数时我用了 PowerShell `Get-Content -Raw` + `Set-Content`: **PS 5.1 默认按 ANSI/GBK 读**,把 UTF-8 中文读成乱码再写回 (`角色与权限` → `瑙掕壊鏉冮檺`)并写入 BOM。`tests/unit/api/test_portal_frontend.py` 的断言当场抓到了它(找不到「角色与权限」)。 已 `git checkout` 恢复全部 8 个文件,改用 Python 重做(显式 UTF-8、不写 BOM、 保持原换行),现在每个文件的改动都是 **1 增 1 删**。 验证:`tests/unit/api/test_portal_frontend.py` 35 passed;unit+contract **1395 passed**; ruff 通过;mypy 251 文件 0 错;确认目标实测 200 (`pending_confirmation` → `confirmed`,写入 `confirmed_at`), 重复确认被状态机以 409 拒绝。 --- app/static/portal/common/api-client.js | 2 + .../portal/customer/cash-ledger/index.html | 2 +- .../portal/customer/holdings/index.html | 2 +- app/static/portal/customer/orders/index.html | 2 +- .../portal/customer/profit-loss/index.html | 2 +- .../customer/risk-questionnaire/index.html | 2 +- .../portal/customer/transactions/index.html | 2 +- .../employee-advisor/dashboard/dashboard.js | 124 +++++++++++++++++- .../employee-advisor/dashboard/index.html | 4 +- .../employee-console/workspace/index.html | 2 +- .../employee-operations/dashboard/index.html | 2 +- 11 files changed, 135 insertions(+), 11 deletions(-) diff --git a/app/static/portal/common/api-client.js b/app/static/portal/common/api-client.js index 6bf92ad..2a9f33f 100644 --- a/app/static/portal/common/api-client.js +++ b/app/static/portal/common/api-client.js @@ -60,6 +60,8 @@ const ENDPOINTS = Object.freeze({ ADVISOR_RECOMMEND: { method: 'POST', path: '/api/v1/advisor/recommendations', idempotent: true }, ADVISOR_CREATE_GOAL: { method: 'POST', path: '/api/v1/advisor/investment-goals', idempotent: true }, ADVISOR_CUSTOMER_GOAL: { method: 'GET', path: '/api/v1/advisor/customers/{customerId}/investment-goals/current' }, + ADVISOR_CONFIRM_GOAL: { method: 'POST', path: '/api/v1/advisor/investment-goals/{goalNo}/confirmations', idempotent: true }, + ADVISOR_GOAL_BOOK: { method: 'GET', path: '/api/v1/advisor/investment-goals/{goalNo}/goal-book' }, OFFSITE_MAILS: { method: 'GET', path: '/api/v1/offsite-fund/mails' }, OFFSITE_MAILBOX: { method: 'GET', path: '/api/v1/offsite-fund/mailbox-status' }, }); diff --git a/app/static/portal/customer/cash-ledger/index.html b/app/static/portal/customer/cash-ledger/index.html index 33dc45f..bd4bdec 100644 --- a/app/static/portal/customer/cash-ledger/index.html +++ b/app/static/portal/customer/cash-ledger/index.html @@ -1 +1 @@ -
记录模拟交易引起的扣款、回款与交易后余额变化。
记录模拟交易引起的扣款、回款与交易后余额变化。
持仓份额、市值和盈亏均由 T006 后端接口返回。
持仓份额、市值和盈亏均由 T006 后端接口返回。
按提交时间倒序展示模拟委托,首版市价委托会立即全额成交。
按提交时间倒序展示模拟委托,首版市价委托会立即全额成交。
仅展示后端已计算的累计盈亏、今日盈亏和持仓盈亏,不推导缺失的已实现收益。
仅展示后端已计算的累计盈亏、今日盈亏和持仓盈亏,不推导缺失的已实现收益。