docs(fe-cmbiz): community/biz 前端入口 review版spec定稿(HJ-FE-CMBIZ-001·Ultracode)

给 Wave4 后端配前端(no-orphan闭合+B端可演示):community消息中心+biz客户询单看板(game-studio)+biz admin处理队列(game-admin),消费已入库契约零后端改动。10 agents(4 recon→起草→四镜头评审含design-lens→定稿,接受18/重定向1/记录2)。
- 评审逮:D5 biz demo试玩取包 owner-agnostic 契约缺口(卡AC-FE-4 B端现金线命脉,升跨前后端硬前置)/§0端点17→19矛盾(blocker)/清除invent契约引用(runtime实查仅1-102-001-001无owner-agnostic端点)/D1「我的中心」承载页(design-lens补,本波唯一动导航处)
- scope收敛=纯前端·消费已入库契约·零后端·不做M4资金流UI;三块可拆(最小必交=①消息中心+②biz客户侧,③admin受7权限点staging闸门约束未过则顺延)
- 待创始人拍:D1客户入口位置/D2等级奖励是否做/D3 admin队列是否本波接/D5⚠️demo取包路径

待创始人审review+UI走查→拍4口径→开execution。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
zizi 2026-06-11 14:20:08 +00:00
parent a2d10be66b
commit d7eee53fa5
2 changed files with 576 additions and 0 deletions

View File

@ -0,0 +1,451 @@
# community / biz 前端入口 · 评审版
> 编号 **HJ-FE-CMBIZ-001** 2026-06-11 类型Review结论先行供创始人拍板定稿后出 execution 版)
> 任务:为 **Wave4 已建后端**community 通知底座 + biz 轻量 lead form提交 `737e6d5`集成门全绿、staging 两链路实测)**补前端入口**,闭合 no-orphan 铁律AGENTS §6.7「残缺/孤儿设计」),并让 **B 端现金线可演示**(近期现金靠 B 端)。
> 上游依赖:后端契约/端点已定稿冻结于 `contracts/api-schemas/community.yaml` + `biz.yaml`,建模块评审版/执行版见 `2026-06-11-Wave4-community-biz-review.md`HJ-WAVE4-001/ `2026-06-11-Wave4-community-biz-execution.md`HJ-WAVE4-EXEC-001创始人已拍 D-A/D-B/D-C
> **本波边界:纯前端 UI消费已入库契约零后端改动。** 照搬 game-studio 五层范式 / game-admin wanxiang 范本,零创新。
> 状态:**待创始人拍板**§0.1 列 9 项 UX/产品口径待裁,其中 D1/D2/D3 是产品口径真决策、D5 是跨前后端契约缺口需 runtime owner 协调拍定、D9 是客户写动作微流程口径;其余 D4/D6/D7/D8 可由 execution 版单 agent 定)。本文是「须双 spec」铁律下的第一份评审版不含代码级细节以降认知负荷。
---
## 0. 结论(一句话)
**Wave4 后端 19 个对外可封装端点-操作community app 5 + biz app 7 + biz admin 7另 community RPC 4 + mock-trigger 1 为同进程/联调投递工具,非前端封装)目前 0 前端入口=违反 no-orphan。本波按「已验证范式克隆」把它们接成可达 UI——零创新、零后端改动、零新依赖唯一需要创始人拍的不是技术、而是 3 个产品口径:① biz 客户入口要不要在 studio 主导航露出B 端是不是 studio 注册用户)② community 是否本波就做「等级/奖励」展示(还是只做消息中心)③ admin biz 队列是否本波就接(受 7 个权限点 system_menu 登记这道前置闸门约束)。**
> **端点计数基准(全文统一)**:端点数一律以 **HTTP operation** 计——`/admin-api/biz/leads/{id}/quotes` 同一 path 含 POST(报价)+GET(报价历史) 计 **2** 个 operation。故 biz admin 端 = **7 operation / 6 URL path**§3.3 操作表按 path 呈现 6 行(「报价(+历史)」一行承载 POST+GET 两 operation§4.4 图把 quotes 拆 d4a/d4b 两节点显式呈现 7 operation——三处与「封 7」按 operation 计自洽。全文及 AC-FE-6 勾验一律用 **19**=5+7+7不再出现「17」。
**本波交付清单3 块 / 推荐范围)**
| 块 | 前端仓 | 页面 | 消费端点 | P0 必交 vs 增强 |
|---|---|---|---|---|
| ① community 消息中心 | game-studio | 消息列表(四类 tab + 已读)/ 未读角标 / 我的等级 / 我的奖励 | community.yaml app 端 5 个 | 消息中心三件(列表/已读/角标)**本波必交**;等级/奖励**推荐本波做但属增强**D-B 范围内,后端已就绪) |
| ② biz 客户询单看板 | game-studio | 提单表单 / 我的订单列表 / 询单详情(进度时间线+报价+demo 试玩)/ 反馈确认 | biz.yaml app 端 7 个 + runtime 双路由(复用) | **本波必交**B 端现金线可演示是本波核心目标之一) |
| ③ biz admin 处理队列 | game-admin | 处理队列 / 代客发起 / 指派 / 报价(+历史)/ 推进状态机 / 线下签署 | biz.yaml admin 端 7 个 | **受权限点登记前置闸门约束**;闸门未过=本波**降级为增强**(详见 §0.1-D3、§6 风险) |
**推荐 sequencing① community 先(更简单、纯展示、被全链路 M5 依赖、无前置闸门)→ ② biz 客户侧B 端价值高、复用 project 范式)→ ③ biz admin受权限点闸门约束闸门过了再接。** 三块互不耦合,可并行三 worktree但若要排优先级按此序。
> **交付范围分层(按前置闸门结果裁剪)****最小必交集 = ① 消息中心三件(列表/已读/角标)+ ② biz 客户侧全套****条件增强 = ③ admin 队列(前置=权限点 system_menu 闸门过§4.2 可执行 SQL 校验)+ ① 等级/奖励(前置=D2 拍板)**。闸门未过/D2 不做时,对应增强项顺延,最小必交集不受影响。
**全文证据边界**game-studio 五层范式 + 请求/守卫/Vant 用法、game-admin wanxiang 四页范本、两契约 19 端点、TabBar 现状(仅 3 入口无 badge 槽、零前端桩grep `biz/community/messages` 在 game-studio/src 零命中),均经 2026-06-11 实查仓库核实(见各节 file:line。「demo 试玩走 play vs preview 路由」「站内信 bizRef 跳转映射」「admin 详情端点缺口」三处为契约未定项,已在 §0.1 / §5 标为待裁。
---
## 0.1 ⭐ 待创始人拍板的关键决策(汇总,详表见 §8
> 以下 **3 项是真正需要创始人拍的产品/口径决策**D1/D2/D3另有 **D5 是跨前后端契约缺口、必须在开 execution 前与 runtime owner 协调定死可执行契约**(不是前端单 agent 能自决的路由选择,详见下表与 §6.2 风险)。其余 4 项D4/D6/D7/D8+ D9客户写动作微流程属信息架构/交互细节,可由 execution 版单 agent 直接定,已在 §8 标注「execution 自决」。**D1/D2/D3 按推荐拍 + D5 与 runtime owner 对齐后即可开 execution 版。**
| ⭐ | 关键决策 | 推荐 | 不这样做的代价 |
|---|---|---|---|
| **D1** | **biz 客户入口在 studio 的信息架构位置 + 「我的中心」承载页落点**(主导航露出 vs 「我的」二级;且现状 TabBar「我的」直指 `/project` 项目列表页、并无聚合入口容器biz 入口/消息入口/等级奖励卡/角标四者无处可挂) | **不占 TabBar 第 4 格承载页二选一execution 起步先钉死)**(a) **新建独立 `/me` 个人中心页**作为 biz 入口/消息入口/等级奖励卡/角标统一容器TabBar 第三入口由 `/project` 改指 `/me`、`/project` 降为其二级;或 (b) **在 `Project.vue` 顶部新增聚合入口区 banner**。无论哪种都须改动「我的」承载页Project.vue 或新增 /me§2 非目标「不改既有导航」放宽为「不动 feed/create 两区、不重构既有公共组件『我的』承载页允许新增聚合入口区」。B 端客户复用同一 user 登录体系(契约客户侧用同一 user Token`getLoginUserId` 归属),但非主流量人群,故挂二级不占主导航 | 若强上 TabBar 第 4 格3 入口变 4 入口C 端竖屏导航被低频 B 端业务挤占若不解决承载页D1/D2/D6 四个二级入口无聚合落点、散挂各处=信息架构断层,实现者在「四入口挂哪」处 block若纯邀请链需独立落地页/独立登录态,本波工作量翻倍且 B 端获客本波不必做 |
| **D2** | **community 本波范围:只做消息中心 vs 含「等级/奖励」展示** | **含等级/奖励展示**(合并进「消息中心」单页分区或「我的」页卡片)——后端 `/community/level` + `/community/rewards` 已就绪D-B 范围内P-INC-01 新人激励是「能赚钱」叙事的可视化抓手,不做=后端能力孤儿 | 只做消息中心:`/level` + `/rewards` 两端点成孤儿(违反 no-orphanP-INC-01 新人激励对用户不可见,「创作有成长有奖励」的产品故事缺一环 |
| **D3** | **admin biz 队列是否本波接(受 7 权限点 system_menu 登记闸门约束)** | **本波接,但前置=先确认 7 个 `biz:lead:*`/`biz:quote:*`/`biz:acceptance:sign` 权限点已 import 到 staging system_menu**`biz_menu.sql` 已备父菜单 7100 + 7 权限点 7101-7107共 8 行闸门未过则本波只交付客户侧①②admin③ 顺延。**闸门校验=可执行 SQL**(见 §4.2,对 staging 跑 `SELECT id,permission FROM system_menu WHERE id BETWEEN 7100 AND 7107` 期望 8 行,缺则先 import 再验) | 若权限点未登记就建 admin 页:超管可用、非超管角色 403@PreAuthorize 兜底);若不接 admin运营无法在 UI 报价/推进状态机B 端闭环只有客户侧半环,「可演示」打折(演示需运营推进 demo 才能让客户试玩验收) |
| **D5⚠** | **biz demo 客户试玩取包路径——跨前后端契约缺口(卡 AC-FE-4 这条 B 端现金线命脉,须开 execution 前与 runtime owner 钉死,不能留 execution 自决)** | **二选一钉死可执行契约**(a) 约定运营代建 demo **走正式发布流使 `game_runtime_package.status=1` 后用 `scene=play` 取包**(不动后端契约面,但改变 demo 交付语义=demo 须入正式发布态);或 (b) **runtime 新增 owner-agnostic 的取包判定能力**(属后端改动,超本波「零后端改动」边界,须升级为跨模块协调项)。**在路径未通前 AC-FE-4 标记为受阻、本波 demo 试玩可能降级为占位** | runtime.yaml 当前只有两个 scene`preview`(校验调用者为版本 owner运营代建 demo 的 owner≠客户客户走 preview 必被 owner 校验拦)、`play`(仅放行 status=1 已发布且明文「不在前端兜底」runtime.yaml:239。若不先定契约就开工实现者拿到 `BizLeadDetailRespVO.demoPreviewable=true` 却无任何前端可调的 owner-agnostic 取包端点 → demo 试玩闭环不可达B 端「可演示」目标落空 |
> 另D4 站内信 bizRef 跳转映射、D6 未读角标承载位、D7 时间线组件复用粒度、D8 金额/精度展示约定、D9 feedback/confirm 客户写动作先后约束——见 §8均可 execution 自决(已给推荐),不阻塞拍板。**注D5 已从 execution 自决升格为「开 execution 前须与 runtime owner 协调拍定」的硬前置(原评审低估为「路由选择/中风险」,实为契约面缺口)。**
---
## 1. 背景与目标
### 1.1 现状:后端齐、前端缺
```mermaid
graph LR
subgraph BE["Wave4 后端737e6d5 已建·集成门全绿·staging 两链路实测)"]
CM["community 通知底座<br/>app 5 端点 + RPC 4 + mock-trigger 1"]
BZ["biz 轻量 lead form<br/>app 7 端点 + admin 7 端点"]
end
subgraph FE["前端入口(本波)"]
S1["game-studio<br/>消息中心 + 客户询单看板"]
A1["game-admin<br/>biz 处理队列"]
end
CM -. "app 5 端点 0 入口" .-> S1
BZ -. "app 7 端点 0 入口" .-> S1
BZ -. "admin 7 端点 0 入口" .-> A1
style BE fill:#1a3a4a,color:#cfeefe
style FE fill:#3a2a1a,color:#fde0c0
```
- **现状确认(实查)**`grep biz/community/messages``game-studio/src` **零命中**、在 `game-admin/src` biz 相关**零命中**——两侧全是净新建前端,无任何桩。后端端点已可经 Swagger/curl 验,但**用户在 UI 上无任何入口可达**=典型 no-orphan 违反(有 API 无入口)。
### 1.2 目标
1. **闭合 no-orphanAGENTS §6.7**Wave4 每个对外业务端点都有前端入口可达RPC/mock-trigger 除外,非对外)。
2. **B 端现金线可演示**:客户提单 → 运营报价/推进 → demo 就绪 → 客户试玩/确认验收,一条 B 端闭环能在 staging 真人走查跑通(近期现金靠 B 端AGENTS §1
3. **community 通知触达可见**:生成完成/审核结果/收益变动三类站内信 + 新人激励成长,在 studio 可见。
### 1.3 非目标见 §2技术落点见 §4权衡见 §5验收见 §7。
---
## 2. 非目标(明确不做,防 scope 蔓延)
| 不做 | 理由 / 归属 |
|---|---|
| **改任何后端契约 / -api 包 / DDL** | 本波纯消费已冻结契约community.yaml/biz.yaml契约缺口如 admin 详情端点 D3 备注)走待裁,不私自补后端 |
| **M4 资金流 UI**:在线收款入口 / 在线电子签章 / reward 真实到账明细 / 分账 | biz 资金流T-BIZ-08 收款 / T-BIZ-03 签章)+ community reward 真实发放全留 M4契约 biz.yaml:17、community.yaml:20。本波报价区**禁出现「立即支付/下单」入口**,只「线下签署」兜底;奖励区文案**禁写「已发放/已到账」**status=0 显示「已触发·待发放」 |
| **超 P0 增强**community SOC/GRW 域(关系图谱/排行/成就/扇出/邮件,全 P1/P2biz P-BIZ-05~07/09~11/13/14 | 仅做本波 11 P0community 5 + biz 6对应前端后端只留接口桩的能力前端不做入口。**注P0 功能数biz 6≠ 端点数biz app 7——两者口径不同1 个 P0 可对应多端点**(如 P-BIZ-03 进度看板 = leads/my + leads/{id} + progress 三端点),勿误读为应相等 |
| **community RPC 4 端点 + mock-trigger 1 的前端封装** | RPC`/rpc-api/community/notify/*`)是上游 aigc/project/trade 同进程调用非对外mock-trigger 是 staging 投递工具admin 端,由后端/联调用前端不封community.yaml:4-7、153-251 |
| **biz 运营侧「公告 type=2」投递运营入口** | 后端四类 notify 只产 type1/3/4公告 type2 靠 mock-trigger 手动;本波前端四类 tab 全列但 type2 可能恒空,不做公告投递台 |
| **下沉/重构既有公共组件****不动 feed/create 两区导航** | 最小改动;新页一律复用 `components/`AppButton/EmptyState/LoadingBar 等)、新增路由不动既有 feed/create 两区。**例外D1**:「我的」承载页允许新增聚合入口区(新建 `/me` 或 Project.vue 顶部加 banner以承载 biz/消息/等级奖励/角标四个二级入口——这不是「重构导航」,是为四个二级入口补一个聚合落点(详见 §0.1-D1、§6.1 |
---
## 3. 页面与流程(三块)
### 3.0 三块全景
```mermaid
graph TB
subgraph studio["game-studio客户/创作者端·Vant·D4 深色·/app-api"]
M["① community 消息中心<br/>消息列表/角标/等级/奖励"]
B["② biz 客户询单看板<br/>提单/我的订单/详情(时间线+报价+demo)/反馈确认"]
end
subgraph admin["game-admin运营端·Element Plus·/admin-api"]
Q["③ biz admin 处理队列<br/>队列/代客发起/指派/报价/推进/签署"]
end
B <-. "同一询单·客户只读看 / 运营推进状态机" .-> Q
style studio fill:#1a2a2a,color:#cfeefe
style admin fill:#2a2a3a,color:#d8d0fe
```
> 客户侧②(看状态)与运营侧③(推状态机)是同一询单的两面:状态机唯一推进者=运营admin advance客户唯一写动作=确认验收3待验收→4已交付
---
### 3.1 ① community 消息中心【game-studio】
**页面清单**(照 `/project` 范式,全 `meta:{requiresAuth:true}` 登录态私有):
| 页面 | 路由(建议) | 消费端点 | P0 |
|---|---|---|---|
| 消息列表(四类 tab + 已读筛选) | `/messages` | GET `/app-api/community/messages` + POST `.../{id}/read` | 必交 |
| 未读角标(全局,非独立页) | 入口处挂 | GET `/app-api/community/messages/unread-count` | 必交 |
| 我的等级(成长进度) | 合并消息中心分区 或 `/me/level` | GET `/app-api/community/level` | 增强D2 |
| 我的奖励(触发记录) | 合并 或 `/me/rewards` | GET `/app-api/community/rewards` | 增强D2 |
**消息列表数据形状**CommunityMessageRespVOcommunity.yaml:262-273id / type(1系统2公告3审核4收益) / bizRef(跳转键) / title / content(审核拒绝含原因) / readStatus(0未读1已读) / readTime / createTime**游标分页**nextCursor int64 nullable对齐 feed cursor 模型,**非 project 的 total 模型**)。
> **type=2 公告 tab 恒空的处置(已知空态,须差异化)**:本波四类 notify 只产 type1/3/4公告 type2 靠 mock-trigger 手动,正常运营下 type2 恒空§2 非目标)。**推荐本波直接不渲染 type2 公告 tab**(待有公告投递台再加),避免给用户一个永远 EmptyState 的入口;若 execution 选择保留四 tab 全列,则 type2 须给**专属空态文案「暂无平台公告」**(区别于其他 tab 的「暂无消息」),不可与普通空态混用。
**用户流程(消息列表 → 已读 → 角标递减)**
```mermaid
sequenceDiagram
participant U as 用户
participant V as 消息中心页
participant API as /app-api/community
U->>V: 进入消息中心
V->>API: GET messages?type&readStatus&cursor&size
API-->>V: {list, nextCursor}
V->>API: GET messages/unread-count
API-->>V: {total, byType}
Note over V: 三态loading→空态(EmptyState)→列表;四类 tab 横滚筛选
U->>V: 点击某条未读消息
V->>API: POST messages/{id}/read登录态写
API-->>V: true
Note over V: 乐观置 readStatus=1 + 角标 total--
V->>V: 据 type+bizRef 决定跳转D4 映射,或本波先不跳)
```
**等级/奖励展示要点D2 采纳则做)**
- 等级CommunityLevelRespVO:274-282level 恒=1小白MVP 仅此档);核心=进度条「publishedCount / nextMilestoneTarget如 2/3距下一新人奖励」nextMilestone=null 显「已达成全部新人里程碑」。publishedCount 是「尽力计数」(勘误#3,可能少计),前端**不宣称「精确」**,按返回值如实展示。
- 奖励CommunityRewardRespVO:283-293奖励卡列表status=0 显「已触发·待发放」(**本波终态,禁写「已发放/已到账」**,真实发放留 M4rewardType 决定文案1流量包=N 曝光 / 2现金=¥X.XX金额分→元
---
### 3.2 ② biz 客户询单看板【game-studio】
**页面清单**(照 `/project` 列表+详情+子流程三联范式,全 `requiresAuth:true`
| 页面 | 路由(建议) | 消费端点 | P0 |
|---|---|---|---|
| 提单表单 | `/biz-orders/new` | POST `/app-api/biz/leads` + GET `/biz/templates`(选模板) | 必交(**提交后流向 + 字段引导见下** |
| 我的订单列表(五态 tab | `/biz-orders/my-orders` | GET `/app-api/biz/leads/my` | 必交(**列表态策略见下** |
| 询单详情(时间线+报价+demo | `/biz-orders/:id` | GET `/biz/leads/{id}` + `.../progress` | 必交 |
| 试玩反馈 + 确认验收(详情内动作) | 详情页内 | POST `/biz/acceptances/{leadId}/feedback` + `.../confirm` | 必交 |
| demo 试玩(详情内嵌/跳转) | 复用 runtime + `src/host/GamePlayer.vue`(照 `views/play/Play.vue:20` 挂载,非 components 复用) | GET `/app-api/runtime/package/{versionId}` + `/manifest` | 必交(**取包路径见 D5 跨前后端契约缺口** |
**biz 五态状态机**(单线性,仅相邻正向单跳,客户只读不能推进;推进=运营做):
```mermaid
stateDiagram-v2
[*] --> 待跟进0: 客户提单
待跟进0 --> 已报价1: 运营报价(admin)
已报价1 --> 制作中2: 运营推进(admin)
制作中2 --> 待验收3: 运营推进+demo就绪(admin)
待验收3 --> 已交付4: 客户确认验收(✅客户唯一写动作)
note right of 待验收3: demoPreviewable=true 才亮「试玩 demo」
note right of 待跟进0: 客户侧只读看状态/报价/进度
```
> 五态色(照 project `status.ts` 范式建 biz 版 status.tsD8/§50待跟进 muted、1已报价 cyan、2制作中 amber、3待验收 amber/cyan、4已交付 green。
> **列表→详情 demo 可用性一致性(实现纪律,防误判)**:列表项消费的 `BizLeadRespVO` **无 `demoPreviewable` 字段**(该字段仅在详情 `BizLeadDetailRespVO`)。故**列表态不预判 demo 是否可试玩**:对 `status=3 待验收` 单统一显「待验收·去试玩」引导(行动指引,让客户知道该点哪一单),进入详情后再由 `demoPreviewable` 决定试玩按钮亮/灰 +「暂不可预览」文案。**execution 勿令列表直接判 preview——列表无此字段。**
**用户流程(客户视角全旅程)**
```mermaid
sequenceDiagram
participant C as 客户
participant V as 客户看板(studio)
participant API as /app-api/biz
participant RT as /app-api/runtime
C->>V: 提单bizType*+title*+场景+联系方式+选模板)
V->>API: POST /biz/leads
API-->>V: leadId状态机开 status=0
Note over C,V: 运营侧(admin)报价→推进→制作→demo 就绪→推进待验收
C->>V: 进「我的订单」→ 点开询单详情
V->>API: GET /biz/leads/{id}(含 latestQuote/progressList/demoPreviewable
API-->>V: 详情status=3 待验收, demoPreviewable=true
Note over V: 时间线渲染 progressList报价区标注「报价仅供参考·本波不支持在线支付」
C->>V: 点「试玩 demo」
V->>RT: GET /runtime/package/{versionId}(判就绪)+ /manifestsha256 注入)
RT-->>V: 包就绪 → GamePlayer.vue 注入试玩
C->>V: 提交反馈 + 确认验收
V->>API: POST /acceptances/{leadId}/feedback → .../confirm
API-->>V: true状态机 3→4 已交付)
```
**提单提交后流向 + 字段引导B 端旅程唯一入口,须明确避免首体验断裂)**`BizLeadCreateReqVO``bizType/title` 必填其余sceneDesc/contactName/contactPhone/company/templateId全可选。
- **提交成功流向**:成功 Toast 后**跳 `/biz-orders/my-orders` 并高亮新单**status=0或直接进 `/biz-orders/:id` 详情看 status=0二选一 execution 定,但**必须有明确落地页**,不可提交后停在原表单。
- **模板选择**纯可选不做必选引导templateId 来自 GET `/biz/templates`
- **联系方式软提示**contactPhone 等契约可选,但**B 端运营跟进唯一靠它**B 端获客本波不做,联系方式是运营触达客户的唯一抓手),表单层做**软提示引导填写**(不强制必填,不破契约)。
**关键 UX 降级态AC-BIZ-2 R1 必验)**demo 取包负路径versionId 缺失/非法、无产物、编译失败 → runtime.yaml 现仅定义 `1-102-001-001`「无对应就绪运行包」一码)→ 看板降级显示「该 demo 暂不可预览」、按钮置灰,**不透传 500**。`BizLeadDetailRespVO.demoPreviewable=false`(后端 `validateDemoPreviewable` 判 demoVersionId 非空且 runtime 包就绪,**具体取包判定能力依赖 D5 钉定的契约**——runtime 当前无 owner-agnostic 判定端点,详见 §6.2/§0.1-D5时同样置灰。**正常路径:待验收态恒为 demo 就绪advance→3 硬守门保证);负路径仅覆盖「包就绪后被驱逐/失效」的少数情形**(消除「待验收必就绪」与「待验收要兜不就绪」的表观对立)。
---
### 3.3 ③ biz admin 处理队列【game-admin】
**页面清单**(照 `wanxiang/withdraw` + `review` 范本ContentWrap 搜索栏 + el-table + Pagination + Dialog`views/wanxiang/biz/`,与 dashboard/featured/withdraw/adSlot 并列)。**下表 6 行 = 6 URL path其中「报价+历史)」一行承载 POST+GET 两 operation故 admin 封 7 operation计数基准同 §0/§4.4**
| 操作 | 端点 | 权限点 | 交互 |
|---|---|---|---|
| 处理队列owner/status/bizType 筛选total 分页) | GET `/admin-api/biz/leads/page` | biz:lead:query | el-table + 操作列按 status 条件渲染 |
| 代客发起 | POST `/admin-api/biz/leads` | biz:lead:create | 搜索栏 ep:plus 开 Dialog8 字段) |
| 指派负责人 | PUT `/biz/leads/{id}/assign` | biz:lead:assign | 行内开小 DialogownerUserIdD备注裸 userId |
| 报价(+历史) | POST/GET `/biz/leads/{id}/quotes` | biz:quote:create/query | DialogamountFen 元↔分换算 D8 |
| 推进状态机 | POST `/biz/leads/{id}/advance` | biz:lead:advance | DialogtoStatus + note→3 显 demoVersionId 必填);**demoVersionId 来源见下「demo 产出桥接」** |
| 线下签署兜底 | PUT `/biz/acceptances/{id}/sign-offline` | biz:acceptance:sign | 行内二次确认 |
> **demo 产出桥接(运营旅程隐藏断点,须显式画进流程)**:契约里**没有「为某 lead 生成 demo」的端点**advance→3 弹窗的 `demoVersionId` 由运营**手工回填**,其来源是运营**先去 game-studio 创作流(或 admin 既有创作入口)为该需求另行生成一个 game/version → 拿到 versionId → 复制回 biz advance 弹窗**。本波推荐**纯人工复制 versionId**(不做「从 biz 队列一键跳创作流并带 leadId 回链」的桥接增强,属超本波最小边界,标待裁顺延)。**实现者须知:这是跨页/跨系统运营动作advance 弹窗只提供 demoVersionId 输入框 + 「去创作流生成 demo」文案提示不在 biz 内造 demo 生成入口。** 见 §3.0 运营流程节点。
**运营处理流程(状态机唯一推进者)**
```mermaid
graph LR
Q["队列<br/>默认 status=0 待跟进"] -->|指派| A["落 owner"]
A -->|报价 0→1| QU["已报价"]
QU -->|推进 1→2| MK["制作中"]
MK -.->|运营另去创作流生成 demo<br/>拿 versionId 复制回 advance 弹窗| BR["demo 产出桥接<br/>(跨页/跨系统·契约无生成端点·人工回填)"]
BR -->|推进 2→3<br/>demoVersionId 必填+包就绪| WV["待验收"]
WV -.->|客户确认 3→4| DONE["已交付"]
WV -->|线下签署兜底| SIGN["signed_offline=1"]
style WV fill:#3a3520,color:#fde0c0
style DONE fill:#1a3a2a,color:#c0fdd0
style BR fill:#3a2030,color:#fec0d8
```
**admin 侧硬约束**
- **推进→3 待验收硬守门**demoVersionId 必填且 runtime 包须就绪,后端 `validateDemoPreviewable` 守门,不就绪抛 BIZ_DEMO_NOT_READY1-110-003-***);前端 advance 弹窗让运营填 demoVersionId提交失败拦截器自动 Toast「该模板暂不可预览」。
- **非法流转(跳级/回退)写前拒** BIZ_LEAD_STATUS_ILLEGAL_TRANSITION前端推进 UI 按当前态只露下一合法态。
- **详情端点缺口D3 备注,最关键)**admin 侧 `AdminBizLeadController` **无单询单详情 GET**(只有 `/leads/page` + `/leads/{id}/quotes`app 侧 detail 端点带 customer_user_id 强归属校验(运营登录态≠客户,复用会抛 BIZ_LEAD_NOT_OWNER。**本波推荐 (b) 前端不做独立详情、列表行 + GET quotes 报价历史拼装**(避免后端改动,守住「零后端改动」边界);若要进度时间线/最新报价/demo 三块完整详情,需后端补 admin 版无校验 detail属后端改动超本波边界标待裁
---
## 4. 技术落点(照现有范式克隆,不另起炉灶)
### 4.1 game-studio①②五层范式克隆
| 层 | 落点 | 范本 | 要点 |
|---|---|---|---|
| API | `src/api/community.ts` + `src/api/biz.ts` | `api/project.ts:20-89` | 每函数贴 yaml path自带 `/app-api` 前缀),`request<T>`T=解包后 data`api/index.ts:5-11``export * as communityApi/bizApi`(命名空间防同名冲突) |
| 类型 | `src/api/types.ts` 新增段 | `types.ts:1-16` 铁律 | 逐字段镜像 yaml VO**禁造契约外字段**int64→number |
| Store | `src/store/community.ts` + `biz.ts` | `store/project.ts:17-88` | Pinia setup storeref 态 + load* action + loading 自管;`store/index.ts` 追加导出 |
| Mock | `src/mock/community.ts` + `biz.ts` | `mock/project.ts` | 导出 routes 数组handler 返业务 data / 抛 MockError`mock/index.ts:12-25` 注册 ALL_ROUTES具体 path 排 :param 前 |
| View | `src/views/messages/` + `src/views/biz-orders/` | `views/project/{Project,Detail}.vue` | `<script setup>` 头块注释写「职责/契约纪律/边缘失败」;状态机元数据抽 `status.ts`biz 五态 + community 四类 meta 表 + 筛选数组) |
**全局基建直接复用(勿重造)**
- **请求/鉴权/错误**`api/request.ts` 是唯一 axios 实例——响应拦截器已解包 CommonResult:125-144、请求拦截器无条件注入 `tenant-id:1`:96+ `Bearer token`:101-104、业务 code≠0 自动 Toast+reject、HTTP401/code401 走 handle401 跳 `/login?redirect=`。**页面侧惯例 = `await api.xxx().catch(()=>{})` 吞 reject 仅做收尾,不重复弹 Toast**Project.vue:35-41 范式)。
- **路由守卫**`router/index.ts:133-138` 守卫铁律——requiresAuth 路由 + 未真实登录跳 `/login?redirect=`;判据必须用 `userStore.isRealLogin()`(仅 localStorage 真 token**不能用 isLogin()** 因恒 trueuser.ts:98-112 警告。community/biz 全是登录态私有数据,路由全加 `requiresAuth:true`
- **「互动即弹登录」**Feed.vue:151-170写动作提单/反馈/确认/标记已读)入口最前置 `if(!userStore.isRealLogin())``showConfirmDialog({confirmButtonText:'去登录'})` → 跳登录带 redirect / 取消静默返回。
- **Vant 用法(关键)**:实测全 src **零 `<van-*>` 标签**UI 全用原生 HTML + scoped CSS + D4 token`styles/tokens.css`**禁硬编码色值**),只用 3 个命令式 APIshowToast / showConfirmDialog
- **地基组件**`components/index.ts:5-11`,共 7 个TabBar / GameCard / LoadingBar / EmptyState / InteractBar / AppButton / Placeholder。空态/加载/按钮一律复用。
- **试玩宿主 `GamePlayer.vue` 不在 `components/`,位于 `src/host/GamePlayer.vue`**(参照 `views/play/Play.vue:20` 的挂载方式 `import GamePlayer from '../../host/GamePlayer.vue'`**非 components 复用**。biz 详情内嵌试玩照此挂载;其 props 签名=`gameId / versionId / mode('play'|'preview') / 可选 manifest 直传 / 可选 fetchPackage 覆盖`withDefaults内部走 runtimeApi 取包 + sha256 注入)。
- **列表分页**community/biz 列表契约都是 **cursor 分页**nextCursor int64 nullable照 feedFeed.vue:111-123 触底 loadMore**非 project 的 pageNo/pageSize**。
### 4.2 game-adminwanxiang 范本克隆
| 层 | 落点 | 范本 | 要点 |
|---|---|---|---|
| 整页 | `views/wanxiang/biz/index.vue` | `wanxiang/withdraw/index.vue`(默认筛选队列+行操作+理由弹窗+金额格式化)/ `review/index.vue`(精简版) | ContentWrap 搜索栏 + el-table操作列 fixed right按 status `v-if` 条件渲染)+ Pagination**total 分页**+ Dialog`defineOptions({name:'WanxiangBizLead'})` 供 keep-alive |
| API | `api/wanxiang/biz.ts` | `api/wanxiang/trade.ts` 结构 | 顶部块注释列契约路径 + 端鉴权说明;`export enum` 状态机 + RespVO/ReqVO每函数 `if(isMock()) return mockPage/mockResult` 兜底 + `request.get/post`url 相对 `/biz/...`,自动补 `/admin-api` |
| 路由 | `router/modules/remaining.ts` `/wanxiang` 下加 child | `remaining.ts:244-301` | 静态路由name=WanxiangBizLead无需后端菜单下发 |
| 常量 | `biz/constants.ts` 或页内 statusText/statusTagType | `adSlot/constants.ts` / `review/index.vue:162-188` | tag 色用 `Record<number,TagType>` 显式标注;金额 amountFen「分」照 `withdraw:200 fen2yuan`/100 |
**admin 侧前置/约束**
- **权限点登记D3 硬前置,闸门校验=可执行 SQL**7 个 `biz:lead:query/create/assign/advance` + `biz:quote:create/query` + `biz:acceptance:sign` 须先在 yudao `system_menu` 登记 RBAC`game-cloud/game-module-biz/sql/biz_menu.sql` 已备**父菜单 7100 + 7 权限点 7101-7107共 8 行**;该 SQL 不进 Flyway、需手动 `mysql --default-character-set=utf8mb4 ... < biz_menu.sql` 执行),否则 @PreAuthorize 兜底 403。**闸门校验步骤(实现者可自动判定,勿口头确认)**:对 staging MySQL 跑
```sql
SELECT id, permission FROM system_menu WHERE id BETWEEN 7100 AND 7107; -- 期望 8 行7100 父菜单 + 7101-7107 权限点)
```
**不足 8 行**则先 `mysql --default-character-set=utf8mb4 -h<host> -u<user> -p<pwd> <db> < game-cloud/game-module-biz/sql/biz_menu.sql`(含中文须 utf8mb4 防乱码,幂等可重复)**再复验**;满 8 行才建 admin③否则③顺延、本波只交①②。
- **权限点门禁要不要挂前端execution 自决)**:现存全部 wanxiang 页**零 `v-hasPermi`**grep rc=1黄金模块 review 同样裸用),靠后端 @PreAuthorize 兜底。推荐**沿用现状不挂前端点**(若引入 v-hasPermi 需确认 system_menu seed 已到 staging否则超管外角色按钮全隐
- **指派选人源execution 自决)**assign 只收裸 ownerUserIdLong无运营成员下拉数据源。推荐**纯 el-input-number 填 userId**(接 yudao system 用户列表做选人器属增强,超本波最小边界)。
### 4.3 staging env + 构建
- **studio**`.env.staging`(已入库,根 .gitignore 显式豁免):`VITE_API_BASE=http://100.64.0.7:48080` + `VITE_STUDIO_TOKEN=test1``vite --mode staging` 联调真后端。
- **admin**`.env.local``VITE_APP_WANXIANG_MOCK=false` 接 staging改 base 指 100.64.0.7:48080`VITE_APP_WANXIANG_MOCK=true` 走前端 mock 独立验收。
- **构建铁律(记忆 frontend-spine-built**`vue-tsc --noEmit` 是假门禁;真门禁用 **`npm run build`**studio `vue-tsc -b && vite build`admin 走完整 vite build
### 4.4 消费端点清单(对齐契约,逐条可追溯)
```mermaid
graph LR
subgraph CMY["community.yaml app 端studio 封 5"]
c1["GET messages"]:::e
c2["POST messages/{id}/read"]:::e
c3["GET messages/unread-count"]:::e
c4["GET level"]:::e
c5["GET rewards"]:::e
end
subgraph BZA["biz.yaml app 端studio 封 7"]
b1["POST leads"]:::e
b2["GET leads/my"]:::e
b3["GET leads/{id}"]:::e
b4["GET leads/{id}/progress"]:::e
b5["GET templates"]:::e
b6["POST acceptances/{leadId}/feedback"]:::e
b7["POST acceptances/{leadId}/confirm"]:::e
end
subgraph BZD["biz.yaml admin 端admin 封 7 operation / 6 path"]
d1["GET leads/page"]:::e
d2["POST leads"]:::e
d3["PUT leads/{id}/assign"]:::e
d4a["POST leads/{id}/quotes报价"]:::e
d4b["GET leads/{id}/quotes报价历史"]:::e
d5["POST leads/{id}/advance"]:::e
d6["PUT acceptances/{id}/sign-offline"]:::e
end
RT["runtime 双路由(复用·不封)<br/>GET package/{versionId} + /manifest"]:::r
classDef e fill:#1a2a3a,color:#cfe6fe
classDef r fill:#2a1a2a,color:#fec0fe
```
> **计数基准(同 §0**:以 HTTP operation 计——admin 封 **7 operation**`leads/{id}/quotes` 同 path 含 POST+GET图中拆 d4a/d4b 显式呈现)对应 **6 URL path**。AC-FE-6 no-orphan 勾验以本图 19 条 operation5+7+7为准。
---
## 5. 关键权衡
### 5.1 sequencingcommunity 先 vs biz 先
| 维度 | community 先 | biz 先 |
|---|---|---|
| 复杂度 | 低纯展示、cursor 列表 + 角标,无状态机推进) | 中(跨 studio+admin 两仓、状态机、demo 取包负路径、权限点闸门) |
| 价值 | 全链路 M5 依赖(通知触达可见)、但非现金线 | **B 端现金线可演示**(本波核心目标) |
| 前置阻断 | 无 | admin③ 受 7 权限点 system_menu 登记闸门约束 |
| **推荐** | **① 先建(更简单、无闸门、做暖身验证范式)→ ② 客户侧 → ③ admin闸门过了再接** | — |
> 三块零耦合,可并行三 worktree模块边界=并行边界)。但若资源串行,按上序。
### 5.2 跨 studio + admin 两前端协调
- **同一询单两面**:客户②看状态/报价/进度只读运营③推状态机唯一推进者。demo 试玩链路客户②走 runtime复用 GamePlayer运营③只填 demoVersionId 触发推进。
- **数据源一致性**金额一律「分」amountFen两侧展示统一 /100 转元D8进度时间线唯一数据源=GET progress事务保证状态翻转与时间线节点原子写
- **「编排器旁路/批跑 API 全绿掩盖 UI 缺陷」铁律**(记忆 frontend-link-ui-walk-publish-fixUI 走查是唯一手段CDP 走查 chrome 一律在 mini-desktop 起6c6g exit144 作废)。
### 5.3 UX 状态范式(每页必覆盖)
| UX 点 | 处置 |
|---|---|
| 三态(每数据页) | ①加载中loading && 空 → LoadingBar indeterminate②空态!loading && 空 → EmptyState title/description/actionText③正常列表/详情;失败走拦截器 Toast |
| 提交防重 | submitting ref + AppButton :loading + :disabledCreate.vue:36/199 范式) |
| **demo 未就绪守门**(核心风险点 §3.2 | demoPreviewable=false / 取包负路径 → 「该 demo 暂不可预览」+ 按钮置灰,不透传 500 |
| **状态机时间线**biz 详情) | game_biz_progress 按 create_time 升序渲染竖向时间线(节点=toStatus+note+operatorUserId+createTime首条 fromStatus=null 为「提单」);**无现成时间线组件,需新建**D7**默认页内联**——本波只 biz 进度一个确定消费者,现状无任何 Timeline 组件、project 审核流用 StatusBadge 非时间线;待 community 审核流真要时间线再按 rule-of-three 抽公共件) |
| **未读角标** | total>0 入口红点byType 各 tab 角标;**TabBar 当前无 badge 槽**TabBar.vue:26-30 仅 path/match/label/icon承载位见 D6推荐挂「我的」二级入口处单独挂角标不改 TabBar。**刷新时机(防 stale 红点)**:每次进入承载入口页(「我的」/`/me``onMounted` 拉一次 `unread-count` + 消息中心内已读操作后乐观递减;**本波不做实时推送**(无推送通道,轮询/进入即拉为准),见 D6 |
| **feedback/confirm 先后**biz 待验收态两写动作) | 反馈为「确认验收」的**可选前置**:确认弹窗内含选填反馈框,一次提交=先 `feedback`(带 demoVersionId`confirm`**允许空反馈直接确认**(契约不强制先后)。两步 demoVersionId 同取自详情 `demoVersionId`feedback 提交前校验非空,见 D9 |
| **报价非订单提示** | 所有报价展示处标注「报价金额仅供参考,本波不支持在线支付/下单」 |
| 归属隔离 | 前端不做(后端 Mapper 强制 getLoginUserId() 谓词,可信边界);非本人数据后端拒,前端走拦截器 Toast |
---
## 6. Blast radius / 风险 / 兼容
### 6.1 影响面
```mermaid
graph TB
subgraph touch["本波触及(前端两仓·零后端)"]
T1["game-studio新增 api/store/views/router 各 2 模块"]
T1b["game-studio『我的』承载页改造(D1)<br/>新建 /me 个人中心页 或 Project.vue 顶部加聚合入口区<br/>(承载 biz/消息/等级奖励/角标四个二级入口)"]
T2["game-admin新增 views/wanxiang/biz + api/wanxiang/biz.ts + remaining.ts 加 child"]
end
subgraph untouch["本波不触及"]
U1["后端契约/-api/DDL零改动"]
U2["既有路由feed/create 两区 + wanxiang 既有四页"]
U3["既有公共组件(只复用不改)"]
end
style touch fill:#3a2a1a,color:#fde0c0
style untouch fill:#1a2a1a,color:#c0fdc8
```
- **构建/部署**studio :4173、admin :4174两独立前端独立构建独立 serve
- **「我的」承载页是真触及点D1原评审低估**:现状 TabBar 第三入口「我的」直指 `/project`Project.vue 纯项目列表页,无聚合入口区结构)。要承载 biz 入口/消息入口/等级奖励卡/角标四个二级入口,必须**新建 `/me` 个人中心页TabBar 改指 /me、/project 降二级)或在 Project.vue 顶部加聚合入口区 banner**——二选一 execution 起步钉死,并补「我的中心」页自身的空态/加载/角标刷新时机。这是本波**会动既有导航的唯一处**(已在 §2 非目标放宽为「不动 feed/create 两区」)。
- **与既有不冲突**:新增路由 path`/messages``/biz-orders/*``/me`与既有不撞admin 新增 wanxiang 子路由不动既有。**角标承载位D6**:推荐挂「我的」承载页二级入口处单独挂角标,**TabBar 不改**TabBar 现纯路由组件无数据请求,加 badge 需引数据源+刷新时机);刷新时机=进入承载页 onMounted 拉 unread-count + 已读乐观递减。
### 6.2 风险表
| 风险 | 级别 | 处置 |
|---|---|---|
| **admin 7 权限点未 import staging** → 建好即 403 | 高 | D3 硬前置:建 admin③ 前先 grep/查 staging system_menu 确认 7101-7107 已在;未在则③顺延、本波只交①② |
| **admin 无详情端点**§3.3 D3 备注) | 中 | 守「零后端改动」:本波 (b) 列表行 + quotes 拼装;完整详情需后端补,标待裁 |
| **demo 试玩取包路径=跨前后端契约缺口**D5已升格为开 execution 前硬前置,非「路由选择」) | **高** | runtime.yaml 现仅两个 scene`preview`(校验调用者为版本 owner运营代建 demo 的 owner≠客户客户走 preview 必被 owner 校验拦——**具体错误码待与 runtime owner 确认runtime.yaml 现只定义 `1-102-001-001`「无对应就绪运行包」,并无独立的 preview-not-owner 码**)、`play`(仅放行 status=1 已发布且明文「不在前端兜底」runtime.yaml:239。**契约面暂无任何 owner-agnostic 取包/判定端点**。处置=D5 二选一钉死:(a) demo 走正式发布流使 status=1 后用 play scene或 (b) runtime 补 owner-agnostic 判定能力(后端改动、超本波边界、升级跨模块协调项)。**路径未通前 AC-FE-4 标受阻、demo 试玩可能降级占位** |
| **站内信 bizRef 跳转映射契约未定**D4 | 低 | 推荐本波先做「点击标记已读不跳转」最小集跳转映射type3→项目详情/type4→收益页MVP 无收益明细页execution 自决或顺延 |
| **vue-tsc --noEmit 假门禁** | 中 | 真门禁 npm run build记忆铁律CI/收口必跑 full build |
| **admin 构建腐化**vite8 等) | 低 | 照记忆 admin-ui-walk-cdp-recipe钉 vite 5.1.4 清装、移杂散 pnpm-workspace.yaml |
### 6.3 兼容/回滚
- **回滚**:新增页/路由/api 文件,删除即回退;不动既有=回滚零风险(除 D6 若改 TabBar 需还原一处)。
- **兼容**:消费已冻结契约,后端不变;前端 mock 模式VITE 空串/WANXIANG_MOCK=true可独立验收不依赖 staging。
---
## 7. 验收标准CDP-on-mini 真人走查为准)
> 记忆 ui-walkthrough-cdpadmin-ui-walk-cdp-recipe / frontend-link-ui-walk-publish-fixUI 走查是唯一手段,**chrome 一律在 mini-desktop 起对 staging 跑**;批跑/API 全绿不能替代 UI 走查(编排器旁路掩盖缺陷铁律)。
| 验收项 | 标准 |
|---|---|
| **AC-FE-1 community 消息中心** | studio 真人走查:进消息中心 → 四类 tab 切换 → 点未读消息标记已读 → 角标递减三态loading/空/列表)均现 |
| **AC-FE-2 community 等级/奖励**D2 采纳) | 等级进度条显 publishedCount/target奖励卡 status=0 显「已触发·待发放」(禁「已发放」) |
| **AC-FE-3 biz 客户提单→看板** | 真人走查:提单(选模板)→ 我的订单见新单 status=0 → 详情见五态徽标 + 时间线 + 报价区(标注「不支持在线支付」) |
| **AC-FE-4 biz demo 试玩+验收** | 待验收态 demoPreviewable=true → 点试玩 demoGamePlayer 注入)→ 提交反馈 → 确认验收 → 状态机 3→4**负路径demoPreviewable=false 显「暂不可预览」+按钮置灰,不 500** |
| **AC-FE-5 biz admin 队列**D3 闸门过则验) | admin 真人走查:队列筛选 → 代客发起 → 指派 → 报价(0→1) → 推进(填 demoVersionId→3) → 客户侧能看到推进结果 |
| **AC-FE-6 no-orphan 闭合** | Wave4 全部对外业务端点community app 5 + biz app 7 + biz admin 7都有前端入口可达RPC/mock-trigger 除外逐端点对照清单§4.4)勾验 |
| **AC-FE-7 构建门** | studio + admin 各 `npm run build` 绿(真 vite build非 noEmit |
---
## 8. 待确认项(创始人拍 D1~D3 + D5 须 runtime owner 协调D4/D6/D7/D8/D9 execution 自决,已给推荐)
| # | 待确认 | 推荐 | 谁定 |
|---|---|---|---|
| **D1** | biz 客户入口在 studio 位置 + 「我的中心」承载页落点(现 TabBar「我的」直指 `/project` 项目列表、无聚合入口容器) | 不占 TabBar 第 4 格承载页二选一execution 起步钉死):(a) 新建 `/me` 个人中心页统一承载 biz/消息/等级奖励/角标TabBar 第三入口改指 `/me``/project` 降二级;或 (b) Project.vue 顶部加聚合入口区 banner。biz 客户用同一 user 登录体系挂「我的」二级 | **创始人**(承载页 a/b 形态可 execution 定,但「动『我的』承载页」这一既有导航放宽须创始人知会) |
| **D2** | community 本波是否做「等级/奖励」展示 | **做**(后端已就绪,否则 /level+/rewards 成孤儿) | **创始人** |
| **D3** | admin biz 队列是否本波接(受 7 权限点 system_menu 登记闸门) | **接,前置=先确认权限点已 import staging可执行 SQL 校验见 §4.2,期望 8 行 id 7100-7107**;未过则③顺延、本波交①② | **创始人** |
| **D5⚠** | **biz demo 客户试玩取包路径跨前后端契约缺口非「play vs preview 路由选择」)** | **开 execution 前与 runtime owner 二选一钉死**(a) demo 走正式发布流使 status=1 后用 `scene=play`(不动契约、改 demo 交付语义);或 (b) runtime 补 owner-agnostic 取包判定能力后端改动、升跨模块协调项。runtime 当前**无** owner-agnostic 端点、仅 `1-102-001-001` 一码。路径未通前 AC-FE-4 受阻、demo 试玩可能降级占位 | **runtime owner + 创始人**(涉是否动后端边界) |
| D4 | 站内信 bizRef 各 type 点击跳转映射 | 本波最小集「点击标记已读不跳转」跳转映射顺延type4 收益无明细页) | execution 自决 |
| D6 | 未读角标承载位 + 刷新时机(改 TabBar 加 badge vs 「我的」二级单独挂;何时重拉 unread-count | 「我的」二级入口单独挂角标,**TabBar 不改**;刷新策略=**进入承载入口页 onMounted 拉一次 unread-count + 消息中心内已读后乐观递减**,本波不做实时推送(无推送通道,轮询/进入即拉为准) | execution 自决 |
| D7 | 进度时间线组件复用粒度(可复用 Timeline.vue vs 页内联) | **本波只 biz 进度一个确定消费者,默认「页内联」**rule-of-three现状无任何 Timeline 组件、project 审核流用 StatusBadge 非时间线,单消费者不抽公共件;待 community 审核流真要时间线再抽) | execution 自决 |
| D8 | 金额/精度展示约定(分→元、是否带 ¥、报价单位元/万元) | 统一分→元(/100保留两位 + ¥admin 报价输入用「元」前端换分(避大额浮点) | execution 自决 |
| D9 | feedback 与 confirm 客户写动作先后/依赖(契约 feedback 强制 demoVersionId、confirm demoVersionId 可空,后端不强制 feedback 先于 confirm | **反馈为「确认验收」的可选前置**:确认弹窗内含选填反馈框,一次提交=先 `feedback`(带 demoVersionId`confirm`;允许空反馈直接确认。两步 demoVersionId **同取自 `GET /biz/leads/{id}` 详情的 `demoVersionId`**demoPreviewable=true 那个版本feedback 提交前校验该值非空 | execution 自决 |
---
## 附:与上游 spec 的关系(防混淆)
- **HJ-WAVE4-001 / EXEC-001**(建模块评审版/执行版)= **后端** community/biz 建设(已交付 737e6d5。本文 HJ-FE-CMBIZ-001 = 其**前端入口补全**,消费其冻结契约,零后端改动。
- 命名注意:本波 biz **admin 侧落 game-admin 仓**(运营端 Element Plusbiz **客户侧 + community 落 game-studio 仓**(产品端 Vant二者跨两前端仓但同消费一份 biz.yaml 契约的不同端(/app-api vs /admin-api

View File

@ -0,0 +1,125 @@
# community / biz 前端入口 · 评审纪要(四镜头 findings 逐条处置)
> 编号 **HJ-FE-CMBIZ-001-MIN** 2026-06-11 关联:`2026-06-11-community-biz前端入口-review.md`(定稿后)
> 范围feasibility(5) + scope-guardian(3) + coherence(6) + design-lens(7),共 **21 条** findings 逐条处置。
> 处置原则:接受的→直接改 review.md标具体落点拒绝/重定向的→说明理由。所有契约引用均经 2026-06-11 实查仓库核实runtime.yaml / biz.yaml / community.yaml / biz_menu.sql / TabBar.vue / Project.vue / components/index.ts
---
## 处置统计
| 处置 | 条数 | findings |
|---|---|---|
| **接受**(已改 review.md | **18** | feas#1/#2/#3/#4/#5scope#1coh#1/#2/#3/#4/#6design#1/#2/#3/#4/#5/#6/#7 |
| **重定向**(采纳但反转/降级推荐结论) | **2** | scope#2D7 抽组件→反转为默认页内联design#7 的「时间线复用」隐含项同源(并入 D7 重定向) |
| **记录/无改动**FYI 或文档已自洽) | **2** | scope#3FYI 范围确认coh#5(「客户三态」概念,文档自洽无对应物) |
> 注design#7 本体(提单提交后流向)为接受;其与 scope#2 共享「单消费者抽组件」信号的部分并入 D7 重定向。按 finding 主体归类:**接受 18 / 重定向 1scope#2/ 记录 2scope#3、coh#5**,合计 21。
---
## 一、feasibility可行性5 findings
### feas#1 [major·接受] biz demo 取包路径=契约缺口,非「路由选择/中风险」
- **核实**runtime.yaml:35-36/56 实查 = 仅 `scene=preview`(校验调用者为版本 ownerstatus∈{0,1}+ `scene=play`(仅 status=1错误码仅 `1-102-001-001`,且 :239 明文「不在前端兜底」。无 owner-agnostic 端点。运营代建 demo 的 owner≠客户客户 → preview 必被 owner 校验拦、play 又要 status=1。证据成立。
- **处置****D5 从「execution 自决/中风险」升格为「开 execution 前须与 runtime owner 协调拍定的硬前置」**。§0.1 新增 D5⚠ 决策行(二选一:(a) demo 走正式发布使 status=1 用 play / (b) runtime 补 owner-agnostic 能力=后端改动升跨模块协调项§6.2 风险级别由「中」改「高」§8 D5 谁定改「runtime owner + 创始人」§3.2/§3.3 取包路径引用全部指向 D5。**路径未通前 AC-FE-4 标受阻、demo 试玩可能降级占位**。
### feas#2 [major·接受] D3 admin 闸门缺可执行验证手段
- **核实**biz_menu.sql 实查不进 Flyway、需手动 mysql 执行id 实为 **7100~7107**7100 父菜单 + 7101-7107 七权限点,共 8 行review 原文仅写「7101-7107」漏父菜单。全文无可执行校验命令。证据成立。
- **处置**§4.2 补**可执行闸门校验 SQL**`SELECT id,permission FROM system_menu WHERE id BETWEEN 7100 AND 7107`(期望 8 行),不足则 `mysql --default-character-set=utf8mb4 ... < biz_menu.sql` 再复验§0.1-D3 / §8-D3 同步补「8 行 / id 7100-7107 / 可执行 SQL」。
### feas#3 [minor·接受] GamePlayer.vue 位置标注错误
- **核实**components/index.ts 实查 7 组件TabBar/GameCard/LoadingBar/EmptyState/InteractBar/AppButton/Placeholder**不含 GamePlayer**GamePlayer.vue 实在 `src/host/GamePlayer.vue`Play.vue:20 即 `import ... from '../../host/GamePlayer.vue'`。证据成立。
- **处置**§4.1 地基组件行更正——7 组件清单照实列GamePlayer 单列「不在 components/、在 src/host/」+ props 签名gameId/versionId/mode/可选 manifest/可选 fetchPackage+ 照 Play.vue:20 挂载§3.2 demo 试玩行复用路径改为 `src/host/GamePlayer.vue`
### feas#4 [minor·接受] 端点计数 17 vs 19 自相矛盾
- **核实**§0 同句「17 个」与「共 19」打架实查 community app=5 + biz app=7 + biz admin=7=19。与 coh#1 同源。
- **处置**:见 coh#1§0 改 19 + 计数基准声明)。
### feas#5 [minor·接受] feedback 强制 demoVersionId 与 confirm 字段贯穿未说明
- **核实**BizFeedbackReqVO required:[demoVersionId]:430confirm requestBody required:false:178。lead.demoVersionId 在 BizLeadDetailRespVO:377/387。证据成立。
- **处置**:新增 **D9**§8两步 demoVersionId 同取自 `GET /biz/leads/{id}` 详情的 demoVersionIdfeedback 提交前校验非空§5.3 补 feedback/confirm 先后行(确认弹窗内含选填反馈,一次提交先 feedback 后 confirm允许空反馈直接确认
---
## 二、scope-guardian范围守卫3 findings
### scope#1 [minor·接受] §0 端点总数自相矛盾
- 与 coh#1/feas#4 同源。**处置**:见 coh#1
### scope#2 [minor·重定向] D7 抽 Timeline.vue 基于推测性复用
- **核实**game-studio 实查无任何 Timeline 组件project 审核/发布流用 StatusBadge.vue非时间线本波时间线唯一确定消费者只有 biz 询单进度一处。「单消费者抽接口=抽象未挣到工钱」信号成立。
- **处置(重定向:反转原推荐)**:原 review 倾向「可复用 Timeline.vuecommunity 审核流可能复用)」;按 rule-of-three **反转为默认「页内联」**。§5.3 时间线行 + §8-D7 改为「默认页内联,待 community 审核流真要时间线再抽」。
### scope#3 [minor·记录无改动] 三块是否本波全交FYI/范围确认)
- **核实**:计划已正确处理可拆性(③受闸门约束未过即降级、①等级/奖励自标增强)。范围守卫认可,仅作记录。
- **处置(采纳建议补一句,非改 scope**§0 交付清单后补**「交付范围分层」一句**——最小必交集=①消息中心三件+②biz 客户侧;条件增强=③admin前置权限点闸门+①等级/奖励(前置 D2。便于实现 agent 按闸门结果裁剪。
---
## 三、coherence内部一致性6 findings
### coh#1 [blocker·接受] §0 一句话结论 17 vs 19 自相矛盾
- **核实**§0 line 13「17 个」被自身括号「共 19」否定全文其余§4.4/§7 AC-FE-6一律 19契约实测 5+7+7=19。body 权威「17」是错数。
- **处置blocker 必修)**§0 改「**19 个对外可封装端点-操作**」+ 删「共 19」歧义新增**端点计数基准声明**(以 HTTP operation 计quotes 同 path 含 POST+GET=2admin 7 operation/6 path全文统一 19。
### coh#2 [major·接受] biz admin「封 7」计数基准未声明§0头/§3.3表/§4.4图打架)
- **核实**§0.1/§4.2/§4.4 称 admin「7」但 §3.3 表 6 行、§4.4 图 6 节点d4=POST/GET quotes 1 节点 2 操作。「7」按 operation、「6」按 path文档未点明。与 coh#1 同根。
- **处置**§0/§4.4 加计数基准声明operation vs path**§4.4 图把 d4 拆 d4a/d4b 两节点显式呈现 7 operation**§3.3 表上方补「6 行=6 path报价行承载 POST+GET 两 operation=admin 封 7 operation」。
### coh#3 [major·接受] §6.2 引用 runtime.yaml 未定义的错误码/能力
- **核实**runtime.yaml 全文仅 `1-102-001-001`**无 `1-102-001-003`、无 `RUNTIME_PACKAGE_PREVIEW_NOT_OWNER`、无 getStatus、无 owner-agnostic 端点**。§6.2/§3.2/§3.3 均 invent 了不存在的契约面。证据成立execution agent 会照抄查不到的码)。
- **处置**§6.2 D5 行**删除 `1-102-001-003 / RUNTIME_PACKAGE_PREVIEW_NOT_OWNER`**,改「具体错误码待与 runtime owner 确认runtime.yaml 现仅定义 1-102-001-001」§3.2 line 204 删「getStatus owner-agnostic」改「validateDemoPreviewable + 依赖 D5 钉定契约、runtime 现无 owner-agnostic 端点」§8-D5 同步去 getStatus 措辞。
### coh#4 [minor·接受] 「待验收必就绪」与「待验收要兜不就绪」表观对立
- **核实**line 201「待验收态前后端必保证 demo 就绪」与 AC-FE-4「负路径 demoPreviewable=false 置灰」并存,未点破「门后包可能被驱逐/失效」。
- **处置**§3.2 关键 UX 降级态补一句**「正常路径待验收恒就绪advance→3 硬守门保证);负路径仅覆盖包就绪后被驱逐/失效的少数情形」**,消除对立。
### coh#5 [minor·记录无改动] 全文不存在「客户三态」概念
- **核实**:文档对 biz 客户建模为「只读看状态/报价/进度 + 唯一写=确认验收」,状态机=五态,文中「三态」均指 UI 渲染三态loading/空/列表)。文档**自身自洽**,无「客户三态」对应物。
- **处置(记录,不改)**:确认文档内部自洽,无遗漏的客户侧状态分类(客户视角=五态只读 + 单写动作,已在 §3.2 充分表达)。若上游另有「客户三态」聚合口径,属上游术语,本文无需引入。
### coh#6 [minor·接受] 「端点数」与「P0 数」相邻易混line 82 biz 6 vs biz app 7
- **核实**line 82「biz 6」=P0 功能数P-BIZ-01/02/03/04/08/12biz app 7=端点数。两轴不同但贴近且都冠「biz」。
- **处置**§2 line 82 补注**「P0 功能数biz 6≠端点数biz app 71 个 P0 可对应多端点(如 P-BIZ-03 进度看板=leads/my+leads/{id}+progress 三端点)」**。
---
## 四、design-lens设计缺失7 findings
### design#1 [major·接受] 信息架构断层:「我的」承载页不存在
- **核实**TabBar.vue:27-29 实查三入口写死 `/feed //create /project``/project`→Project.vue 自述「我的项目列表」、无入口区/卡片栏结构router meta.title='我的项目'。D1/D2/D6 四个二级入口无聚合落点。与 §2 非目标「不改既有导航」冲突。证据成立。
- **处置****D1 升格涵盖「我的中心承载页落点」**——§0.1-D1 / §8-D1 改为二选一((a) 新建 `/me` 个人中心页、TabBar 第三入口改指 /me、/project 降二级;或 (b) Project.vue 顶部加聚合入口区 banner§2 非目标放宽为「不动 feed/create 两区」+ 例外说明§6.1 影响面新增 T1b『我的』承载页改造节点 + 专条说明「会动既有导航的唯一处」+ 补承载页空态/加载/角标刷新时机。
### design#2 [major·接受] biz demo 产出桥接是隐藏断点versionId 从哪来)
- **核实**biz.yaml admin 7 端点**无任何「生成 demo」端点**advance→3 的 demoVersionId 由运营手填,来源是运营另去创作流生成 version 再复制回。流程图全黑盒。证据成立。
- **处置****§3.3 新增「demo 产出桥接」节点**(运营先去 game-studio 创作流生成 game/version → 拿 versionId → 复制回 advance 弹窗;本波纯人工复制、不做一键跳创作流带 leadId 回链=超边界顺延advance 弹窗只给 demoVersionId 输入框+「去创作流生成 demo」文案提示不在 biz 内造生成入口§3.3 运营流程 mermaid 加 BR「demo 产出桥接」节点。
### design#3 [major·接受] biz 列表项无 demoPreviewable列表→详情态缺失
- **核实**BizLeadRespVO列表 VO:368-379仅 status/demoVersionId**无 demoPreviewable**(仅在 BizLeadDetailRespVO :387。列表无法预判哪单可试玩。证据成立。
- **处置**§3.2 五态色后**补「列表→详情 demo 可用性一致性」纪律**——列表态不预判 preview对 status=3 统一显「待验收·去试玩」引导,进详情后由 demoPreviewable 决定亮/灰§3.2 my-orders 行标「列表态策略见下」。
### design#4 [minor·接受] feedback 与 confirm 先后/依赖未定义
- **核实**feedback required demoVersionId、confirm 可空,均作用于待验收 3 态,后端不强制先后。能否空反馈直接确认未说明。
- **处置**:并入 **D9**(同 feas#5)——反馈为确认的可选前置,确认弹窗内含选填反馈框,一次提交先 feedback 后 confirm允许空反馈直接确认§5.3 补 feedback/confirm 先后行。
### design#5 [minor·接受] community type2 公告 tab 恒空无处置
- **核实**community.yaml messages type enum[1,2,3,4],但四类 notify RPC 只产 type1/3/4无 type2 生产路径。§2 自承「type2 可能恒空」但未给空态/隐藏策略。
- **处置**§3.1 补 **type2 处置**——**推荐本波直接不渲染 type2 公告 tab**(待有公告投递台再加);若保留四 tab 则 type2 须给专属空态「暂无平台公告」(区别普通「暂无消息」)。
### design#6 [minor·接受] 未读角标刷新/递减时机仅覆盖单条已读
- **核实**§3.1 仅「点开单条已读 total--」;跨页返回/新信到达/批量已读的角标重拉时机未定义。community.yaml unread-count 需主动 GET 无推送。
- **处置****D6 补刷新时机**§8-D6 + §5.3 角标行 + §6.1)——进入承载入口页 onMounted 拉一次 unread-count + 消息中心内已读后乐观递减;本波不做实时推送(无推送通道,轮询/进入即拉为准)。
### design#7 [minor·接受] 提单表单提交后流向/字段引导未充分定义
- **核实**BizLeadCreateReqVO 仅 bizType/title 必填其余全可选templateId 来自 GET /biz/templates。§3.2 仅列端点,未说提交后跳哪/模板是否必选/联系方式如何触达。证据成立。
- **处置**§3.2 **补「提单提交后流向 + 字段引导」段**——成功 Toast 后跳 `/biz-orders/my-orders` 高亮新单 或 进 `/biz-orders/:id` 详情二选一但必有明确落地页模板纯可选不做必选引导联系方式契约可选但做软提示引导B 端运营跟进唯一抓手。§3.2 提单行标「提交后流向+字段引导见下」。
---
## 五、定稿后状态确认
- **blocker 全消**coh#117→19已修 + 计数基准声明,全文 grep 无「17 个对外/共 19」。
- **invent 契约引用全清**`1-102-001-003 / RUNTIME_PACKAGE_PREVIEW_NOT_OWNER / getStatus / owner-agnostic 端点` 全文 grep 仅存于「runtime 现无此端点」的否定性表述,无既定契约误引。
- **scope 收敛**:纯前端 UI·消费已入库契约·零后端改动·不做 M4 资金流 UI——非目标表保持报价禁「立即支付」、奖励禁「已发放」D1 仅放宽「我的承载页加聚合入口区」、未越界后端。
- **真前置浮出**D5demo 取包契约缺口)已从隐性 execution 自决升为显性跨模块协调硬前置,避免实现者在不可达路径上 block。