# A5 项目管理 demo 缺陷清单(票 16 · 黑盒 e2e 审计) - 分级:P0 主流程阻断/数据错误 · P1 功能错误/口径违背 · P2 体验/展示/功能弱化 · P3 建议。 - 复现环境:demo `index.html?api=http://localhost:8080`,uid 99021002(销售总监)/ 99021003(普通销售),种子客户 99021001 + 方案卡 99021008。 - 证据缩写:`probe*.json` = audit 目录下探针结果;截图 = `screenshots/`。 > **16R 修复状态(2026-09-11)**:D-01 已修(看板 badge/冲突入口仅进行中)、D-02 已修(68010 负责人∨管理员∨销售总监,报备专员细分角色随权限系统接线收紧——拍板记 README Decisions)、D-03 部分修(赢单快照四字段随标记落列;输单复盘字段为 spec §8 后续字段 spin-out 不采集)。P2/P3 维持记档待用户验收翻案。复测结论见票 17。 ## P0 无。主流程(建档→冲突解除双写→逐级推进→3→5 连跳→多步回退→赢单闭环/输单结项→关闭记因→三终态锁)全部走通,未发现数据错误。 ## P1 ### D-01 看板「冲突待处理」计数与 stage0 卡冲突入口不排除已关闭项目(死入口 + 计数虚高) - 页面:看板(A5-1-1 看板视图) - 复现:① uid=99021002 登录;② 新建项目后直接「关闭…」(stage0/status=2);③ 回看板。 - 期望:已关闭项目不属「冲突待处理」,卡片不应再提供冲突解除入口(详情动作区对终态已正确隐藏)。 - 实际:badge 与 stage0 列计数把已关闭项目照数计入(截图中 badge=5,其中 4 个已关闭);已关闭卡仍渲染「冲突解除」按钮;点击后服务端 68003 拒绝,属死入口。 - 证据:`GET /project/board` stage0 卡 `projectStatus=2, conflictActionAvailable=true`(4 例);对已关闭项目 `POST /project/filing/review` → `{"code":68003,"message":"项目已关闭/已结项(终态锁),不可冲突解除…"}`;screenshots/14-board-director.png。 - 注:spec §4 字面写 badge「=stage0 项目数」,但终态口径(§3 三终态锁)优先,且死入口无争议。待复核点仅「计数是否含驳回停留项目」。 ### D-02 状态机动作服务端无角色权限校验(除回退外全线裸奔) - 页面:详情动作区(原型 A5-1-1-1 冲突处理 / A5-1-1-2 方案设计确认 / A5-1-1-5 赢单输单) - 复现:uid=99021003(普通销售,非负责人非报备专员)登录 → 打开他人项目 → 直接调用/点击: ① stage0 项目「冲突解除」提交通过 → 成功,项目 0→1(screenshots/27、28;ui-result4 U41/U41b); ② `POST /project/stage/advance` → 成功推进; ③ `POST /project/close` → 成功关闭他人项目; ④ `POST /project/bid-result/mark` → 成功标记他人项目赢单。 - 期望(原型权限表):冲突处理仅报备专员+管理员;「确认通过」(推进)仅限项目负责人/销售管理员;标记赢单/输单仅限项目负责人及销售管理员。 - 实际:仅阶段回退有服务端权限(68005),其余动作任意登录用户可对任意项目执行。 - 证据:probe2 A2/A4/A8(code=0)、ui-result3/ui-result4。 - 备注:demo 单机演示下危害有限,但这是服务端口径违背而非前端简化(README 只声明回退权限在服务端强制)。 ### D-03 标记赢单/输单不采集快照,开标页签数据永远为空且无写入通道 - 页面:详情「开标」页签 + stage5 动作(原型 A5-1-1-5 赢单/输单) - 复现:stage5 项目点「标记赢单」→ 仅一个 confirm(无表单);成功后打开「开标」页签。 - 期望(原型弹窗必填):赢单=中标时间/中标金额/中标单位/中标方式/合同扫描件;输单=输单原因/竞品品牌/竞品中标单位/我方报价/竞品报价/失败分析。spec §2.3 亦将「开标 bid_result + 赢/输快照字段」列为本期范围(主表扩展列已建:bidAwardAmount/bidAwardMethod/bidOpenTime/bidOpenPlace/bidTime 等)。 - 实际:标记只写 bid_result;快照列永无写入端点;开标页签赢单/输单后所有字段仍为「-」(screenshots/12-bidopen-win.png、18);bid-open DTO 快照字段全 null。 - 证据:probe1 detail keys 含快照字段但值恒 null;ui-result U17。 ## P2 ### D-04 回退弹窗缺「回退原因类型 + 详细说明」(原型两字段均必填、原因类型按目标阶段字典联动) - 复现:stage≥2 进行中项目 → 「回退…」。 - 实际:弹窗仅「回退到」一个下拉;动态留痕无回退原因。原型 A5-1-2-2 回退弹窗:*回退至阶段 + *详细说明 + 与目标阶段联动的原因类型字典(转回商机/冲突处理/方案设计/商务报价/招投标准备各有专属选项)。 - 证据:screenshots/09-rollback-dialog.png;ui_audit U14。 ### D-05 「回退…」按钮对普通销售可见(原型:仅管理员和销售总监可见可操作) - 复现:uid=99021003 打开他人进行中 stage≥2 项目 → 动作区可见「回退…」,点击弹窗正常打开,提交才被 68005 拒。 - 期望:按钮按原型应不可见(README 自认「可见但服务端拒绝」,与原型「可见可操作仅限」不符)。 - 证据:screenshots/25、26;ui-result U39、ui-result4 U40。 ### D-06 demo 前端请求竞态:旧响应晚到覆盖新结果(scope/筛选快速切换、登录后首屏) - 复现:A 账号(列表 17 条)登录后立即点「我的项目」→ 短窗口内列表显示 manage 数据;快速连点 manage/mine 后终态可能与所选 scope 不一致。 - 实际:`loadBoard/loadList` 无请求去重/AbortController/序号守卫,先发后至即覆盖。API 层 scope 过滤本身正确(sales mine total=0)。 - 证据:ui_audit 首跑 U37 FAIL(mine 显示总监的「A5UI-输单」行);ui_audit2 R1/R2。 ### D-07 终态(已关闭/已结项)项目仍可新增跟进/附件 - 复现:对已结项项目 `POST /project/follow/add` → code=0。 - 期望:原型已关闭/结项页「所有页签只读,任何人不可编辑」。 - 证据:probe2 B8。 ### D-08 列表列与原型列定义差异大(缺 8 列、3 列为新增、2 列改名) - 缺:NO./地区/销售经理/客户信息(名称-联系人-脱敏手机)/来源商机/品牌/中标时间/操作(查看)。 - 新增:状态/报备/赢输(原型列表无,信息有价值);改名:当前节点→阶段、当前负责人→负责人。 - 证据:screenshots/16、17;ui-result U26/U27。 ### D-09 详情头部缺原型页首区字段 - 缺:项目编号、甲方单位、客户联系人、来源商机名称(DTO 有 sourceOppId 但不展示)、项目类型;无阶段 stepper(原型横向阶段导航高亮当前节点)。 - 证据:ui-result U07;screenshots/04、07。 ### D-10 顶部统计卡缺失(原型+spec §4「顶部统计卡 7 阶段计数 + 冲突待处理入口」) - 实际:看板/列表顶部仅「冲突待处理」一张卡,无全部项目与各阶段计数卡(点击筛选联动亦无)。 - 证据:ui-result U24;screenshots/14。 ### D-11 看板卡字段不全 - 缺原型卡的:最近跟进时间、中标时间、超期状态;负责人无部门前缀(原型「广东10部 陈亚」)。 - 证据:ui-result U23;screenshots/14。 ### D-12 写跟进弹窗字段缺失、跟进列表缺列 - 弹窗缺:跟进方式字典必填(demo 自由文本选填)、客户名称/联系人/电话、跟进结果标签、计划下次跟进时间、附件上传。 - 列表缺:跟进人、跟进人部门列。 - 证据:ui-result U34[follow]、U35;screenshots/19。 ### D-13 客户页签字段缺失、枚举未译名 - 缺:客户联系人/联系电话/客户等级(原型关联客户页签);customerType 直接显示 `ENTERPRISE`。 - 证据:ui-result U36;screenshots/19 前后页。 ### D-14 分屏视图(左列右详)未实现 - 原型 A5-1-1/A5-1-2-1 均有分屏视图(左侧卡片列表+右侧详情联动,页内高频操作);demo 仅 看板/列表/详情 三 tab,点行跳转式详情。 - 证据:demo index.html nav.tabs。 ### D-15 关闭信息展示原始枚举 - 头部「关闭」行显示 `MANUAL 2026-09-11 …`,未译为「主动关闭」等中文名(closeType 枚举无名称映射字段)。 - 证据:ui-result U19。 ### D-16 暂停/恢复、终止项目、编辑项目、移交负责人 均未实现 - 原型右上角操作与对应弹窗(暂停原因/预计恢复时间/终止三选项/编辑表单/移交新负责人+原因)全缺;spec 端点清单亦未定义(📝),其中「移交负责人」在 spec §5 有移交 Port 间接依据 → 待复核是否本期范围。 - 证据:demo 动作区全量按钮清单(U08/U11/U12)。 ## P3 ### D-17 建档表单形态与原型向导差异 - 无 3 步向导(填写信息→冲突检测→创建;检测为 spin-out)、客户/方案卡为裸 id 手输(原型目录级联选择,spec 提及 CustomerCatalogPort 目录选)、无销售经理/项目类型字段、品牌/金额/地区必填性放宽(spec §5.1 只定客户+卡必填,不判缺陷,仅记录)。 ### D-18 同一方案卡可被多项目重复绑定(待复核) - 复现:同客户同卡连续建两个项目均成功(code=0)。卡为引用语义(DB:卡 owner_type=1 归商机,项目仅存 scheme_card_id,无抢占/数据损坏)。「一项目一客户一卡」是否要求卡与项目互斥,spec 未明 → 待产品确认。 ### D-19 A5-1-4 项目统计页整体缺失 - demo 无统计入口;spec 端点清单亦未定义统计端点(按 spec 裁剪),建议后补。 ### D-20 board/list 数值类型不一致 - `conflictPendingCount`、列 `count`、卡片/行 id 均为字符串,前端以宽松比较兼容;建议统一数值/保持一致。 ### D-21 回退失败后弹窗保持打开 - 68005 被拒后 `dlgRollback` 不自动关闭(open=true),仅 toast 反馈,阻塞页面点击需手动取消。 - 证据:ui-result4 U40b。 ### D-22 跟进时间默认值取浏览器 UTC 时间 - README 已声明的演示性简化(toISOString),演示时可手改。非缺陷,记录备查。 ### D-23 错误信息泄露实现细节 - `followTime=垃圾时间` → 40001 message 返回 Spring 类型转换链(含 `@io.swagger.v3.oas.annotations.media.Schema` 等内部类名),建议转为业务文案。 ### D-24 推进/标记等写动作无二次确认 - 原型各阶段推进均有确认弹窗;demo 仅标记赢输有 confirm,推进直接执行(误触即推进,可回退兜底)。 ### D-25 分页无页码/跳至;列表无排序 - 原型页码+跳至+列排序;demo 仅上一页/下一页。 ### D-26 操作日志未拆分旧值/新值/敏感信息查看 - 原型操作日志含操作对象/字段、旧值、新值、查看明细;demo 动态为事件级投影(spec 口径 crm-log 投影,记录为增强方向)。 --- **待复核汇总**:D-01(badge 是否含驳回停留项目)、D-16(移交负责人是否本期范围)、D-18(卡互斥语义)。