Files
zentao-flow/workspace/specs/ai-sop-20260723-1024/05_delivery/dev_log.md
T

98 KiB
Raw Blame History

开发交付记录(dev_log)

一期:zt_story_expand 加列 ai_participation_rate(2026-07-23,依据 prd_final v1.24 FR-004 / dev_plan v4.0 §2)

改动文件

文件 动作 说明
codes/zentao/sql/20260724_alter_zt_story_expand_add_ai_rate.sql 新增 DDL(说明头+回滚+可重入 INFORMATION_SCHEMA 判断)
codes/zentao/src/main/java/com/sa/zentao/entity/ZtStoryExpand.java 修改 加 private String aiParticipationRate;(紧随 aiEfficiencyCoefficient)
codes/zentao/src/test/java/com/sa/zentao/service/ZtStoryExpandServiceTest.java 新增 回归测试 2 场景

单元测试记录

# 场景 结果
1 新增路径:实体带 aiParticipationRate 透传到 insert ✅ 通过
2 更新路径:selectById 命中后透传到 updateById ✅ 通过

执行:mvn test -Dtest=ZtStoryExpandServiceTest → Tests run: 2, Failures: 0, Errors: 0 / BUILD SUCCESS(JDK 21,tmp/jdk-21.0.2)

排障记录(后续跑测试必看)

  1. surefire fork 失败(Boot Manifest-JAR / 'other' has different root,Windows+JDK21):需加 -Dsurefire.useManifestOnlyJar=false。建议团队在 pom.xml 固化该配置(未擅改团队构建文件)
  2. MyBatis-Plus 单测:需 @BeforeAll 手工 TableInfoHelper.initTableInfo(...) 初始化实体缓存
  3. MP 3.5.5 saveOrUpdate 行为:先 selectById 判断存在性再决定 insert/updateById——mock 需覆盖 selectById

未做(按约定)

  • git 操作(分支/提交由用户处理);生产 DDL 执行(待 D2 窗口+备份);W 值与 PRD 附件上传(待 storyId)

二期开发(2026-07-23,dev_plan v4.0 §3,任务见 tasks.md)

后端(agent-3 实施,DT1-DT4+DT10)

  • DT1:sql/ 新增 3 个 DDL(zt_file.url、zt_meeting.url、zt_story 8 列,含说明头+回滚+可重入)
  • DT2:FileTypes +6 类;实体 ZtFile/ZtMeeting/ZtStory 补字段;POST /common/uploadBind(上传+绑定+按类型刷新主表 url/status,非法回滚不落盘)
  • DT3:POST /zt-task/aiBatchAdd(事务/整批拒绝/防重 skipped/status=wait/创建人 ai/estimate 映射/返回 taskIds)
  • DT4:userReview 补写 activateddate(:567);sql/20260724_insert_ai_user.sql(可重入,MD5 默认密,注释建议改密)
  • DT10 单测:Tests run: 19, Failures: 0, Errors: 0(UploadBindRefreshOwnerUrlTest 13 例 + AiBatchAddServiceTest 4 例 + 既有回归 2 例);编译 BUILD SUCCESS
  • 遗留:鉴权未实施(必决项待用户定);uploadBind 回滚可能留孤儿文件(低危);insert_ai_user.sql 生产执行前先测试库跑

前端(agent-4 实施,DT5-DT8)

  • DT5:新增 components/MdPreview(markdown-it 渲染,禁注入;依赖需 npm i markdown-it);uploads 组件向后兼容扩展(可切 /common/uploadBind,34 处现有调用零影响);api/base.js 补 uploadBind
  • DT6:用户需求详情加「需求讨论会议」tab(懒加载+storyIds 过滤,TODO 待后端 FIND_IN_SET);顺手修复了模板引用不存在的方法 handleClick
  • DT7:会议 add/editDialog 渲染 uploads(objectType=meeting);详情附件区块(操作人/时间/.md 在线查看/下载)
  • DT8:研发需求详情 7 区块(需求 ID+复制 / AI 指标 12 字段 / 用例+模版查看下载 / 提交测试报告(未 pass 禁用)/ 其他文档 / 代码审查报告(轮次+状态)/ 工作日志)
  • 验证:SFC 解析+模板编译+babel 全过;eslint 零新增 error
  • 待联调:markdown-it 未装;uploadBind 响应结构假设;会议 pageList 前端兜底过滤;AI 指标当月匹配

框架侧(DT9)

  • .claude/skills/tgassist/scripts/upload_md.py:通用上传脚本(file+objectType+objectId+reviewResult,BASE_URL 可配)

DDL 测试库执行(2026-07-23,192.168.1.161/zentao_dev)

执行 5 个脚本(4 DDL + ai 账户)并逐列验证通过:

项 验证
zt_story_expand.ai_participation_rate ✅
zt_file.url / zt_meeting.url ✅
zt_story 8 列(7 url + code_review_status) ✅ 8/8
zt_user ai 账户 ✅

教训记录:首次用 pymysql 自写分隔器执行时,脚本内"注释里的分号"导致每个文件首个语句被静默跳过(守卫变量 @c 为 NULL → IF 走 SELECT 1 空操作)。已直接补执行缺失语句并复核。生产执行请用标准 mysql 客户端(脚本本身含说明头+可重入守卫,客户端执行无此问题)。192.168.3.200 库按用户指示未做任何连接/写入。


端到端冒烟(2026-07-28,8086 端口连 161 测试库)

项 结果 证据
uploadBind(aiCodeReview+reviewResult=pass) ✅ code=0;zt_file.url 生成;zt_story.code_review_url 写入、code_review_status=pass(story 6566)
aiBatchAdd(devel+test 两任务) ✅ code=0,created=2,taskIds=[5263,5264];zt_task:status=wait、openedby=ai、estimate=1.0/0.5
aiBatchAdd 幂等(重复提交) ✅ created=0,两任务全部 skipped

排障记录:aiBatchAdd 首次冒烟报"失败",日志(F:/logs/zentao/zentao.log)显示实为 HttpMessageNotReadableException: Invalid UTF-8——是 curl -d 中文未按 UTF-8 编码所致,非接口问题。改用 --data-binary @file.json(UTF-8 文件)后通过。排查过程曾误排:zt_task left 保留字(实体已有 @TableField("left") 反引号处理)、161/200 库表结构差异(161 zt_task 列为 camelCase,与实体一致)。

8086 冒烟实例已关闭(8085 为用户自有实例,未触碰)。冒烟数据(story 6566 的审查附件 id=220、任务 5263/5264)保留在 161 测试库,可随手清理。


前端联调(2026-07-28,playwright+系统Chrome headless 真机验证)

最终:全套 10/11 + 聚焦 4/4 通过(唯一未过项为旧脚本的过时按钮文案定位,已由聚焦脚本验证功能正常)。验证环境:后端 8086(连 161)+ 前端 dev server 8088(代理 8086)。

联调发现并已修复的 BUG

# BUG 修复
1 审查状态显示"未审"、提交按钮卡死 后端:ZtStoryDTO 补 8 个新字段(BeanUtils 才带得出去)
2 AI 指标区块"暂无数据"(queryByMonth 的 projectId 过滤不匹配) 后端:新增 GET /zt-story-expand/queryByStoryId;前端改调该接口(api/count.js 补路径)
3 前端读 code_review_status(snake)而后端出 codeReviewStatus(camel) 前端 product.vue 5 处统一 camelCase
4 .md 判断只认标题后缀(冒烟文件标题无 .md 后缀) isMd 改认 extension 字段
5 uploadBind 的 url 用 baseUrl 绝对地址 → 跨域加载失败 url 改存相对路径 /zentao/img/...(经前端源/代理可达,生产同源同样成立)
6 markdown-it v14 纯 ESM 与 webpack4 不兼容(8 编译错误) 降级 markdown-it@12.3.2(package.json 已改)

页面级验证点(截图 tmp/pw_*.png)

登录跳转 ✅;研发详情 6 区块(需求ID/AI指标实数 8.5+0.6+人员/审查报告通过绿标/提交测试报告按钮可用/工作日志/测试用例)✅;MD 在线渲染出完整 markdown(标题/列表/加粗)✅;用户需求「需求讨论会议」tab ✅;会议详情附件区块 ✅;冒烟任务在「关联任务」可见(郭其兵/张富斌)✅

给用户/运维的注意事项

  • 用户 8085 实例跑的是修复前旧代码(重启即得修复)
  • file.baseUrl 拓扑:uploadBind 现存相对路径,跨域问题已消;/common/upload 老接口仍用绝对 baseUrl(历史行为未动)
  • 161 冒烟残留:zt_file 220(deleted)/221、zt_task 5263/5264、story 6566 的 expand 改写、url 字段改动
  • 运行中:后端 8086(含全部修复)、dev server 8088(供点击验收)

真实点击测试(2026-07-28,playwright 真实 UI 交互,全部通过)

研发详情页(8/8):登录 ✅;点「复制」出提示 ✅;UI 上传工作日志 → zt_file(222)+zt_story.work_log_url 刷新(相对路径)✅;UI 提交测试报告 → zt_file(223)+test_report_submit_url 刷新 ✅;卡点反例(未审需求 6565 显示"不可提交")✅

会议链路(4/4+渲染):UI 新建会议(产品/类型/时间/地点/参会人/主题/3 个必填富文本)→ zt_meeting 落库 ✅;编辑弹窗上传 MD → zt_file(228) 落库 ✅;zt_meeting.url 刷新 ✅;会议详情附件区块显示 + MD 在线渲染出内容 ✅

本轮修复:老式两段式上传(/common/upload+updateFile)不刷新 zt_meeting.url → ZtMeetingServiceImpl 加 refreshMeetingUrl(add/modify 均挂,与 uploadBind 的 refreshOwnerUrl 双通道一致)。

测试脚本资产(可复用回归):tmp/pw_ui_test.py(页面区块)、pw_ui_test2.py(AI指标+MD渲染)、pw_real_click.py(上传+卡点)、pw_real_click2.py(会议链路);运行器 tmp/pw-venv。


三期:绩效消费(2026-07-28 用户授权"全跑",批1+批2+前端完成)

口径默认锁定(decision_log 2026-07-28):总分=0100×权重;Bug率按‰;severity 12 重大/3~4 普通;申诉=系统入口+人工复核;产品助理验收链补写字段。

批1:数据与计算基座(agent-5)

  • DDL×3:zt_perf_config(uk_role_item)、zt_doc_check(uk_story_month_doc,含申诉状态流字段)、init 62 行规则(9 岗位,权重合计均=1.00)——已执行 161:61 行生效(1 行 INSERT IGNORE 去重)
  • calculators 18 个(策略模式+linear/threshold/manual 规则):双完成率(PRD/团队)、版本计划、双 Bug 率、Bug 密度、检出率、双及时率、准时率、饱和度、代码质量(MD 头部正则解析 round/flat 双模式)、运维 4 项、双文档齐备
  • 完成率接入:GET /count/workloadRate;月末核查 job(每月 28 日 02:00)+ POST /count/generateDocCheck/docCheckAppeal/docCheckAppealResolve
  • FR-014 全套:五路判定+zt_doc_check 快照+扣分合并 scopeJson+申诉回滚
  • 测试:44 例(PerfTestSupport 手工 TableInfo 初始化)

批2:报表引擎+接口(agent-6)

  • PerfScoreEngine:linear(封顶/segments)/threshold 分档/manual 透传/bonus 条件/refund 连续 N 月返还
  • ZtPerfController(/zt-perf):report(落库读/实时算)、generateMonthScore(保留人工分重算)、manualScore、appeal(scopeJson.appeals)、appealReview(overturned 回滚满分防重复)、config CRUD(admin 限定)
  • scopeJson 统一结构(PerfMonthScope POJO)
  • 测试:引擎 7+服务 3

前端(agent-7)

  • src/views/perf/ 4 页面:report.vue(9 岗位 tab+总分卡+申诉/复核)、docCheck.vue(五列 ✓/✗+月度确认锁定)、manualScoreDialog.vue、config.vue(规则行内编辑+JSON 校验)
  • src/api/perf.js + router/modules/perf.js 注册;eslint 0 error、模板编译全过

全量验证

  • mvn test:Tests run: 73, Failures: 0, Errors: 0 / BUILD SUCCESS(批1 44+批2 10+一二期 19)
  • 并行碰撞已对齐(zt_perf_config 实体/服务以批1 版本为准;批2 最小修复批1 文件 2 处编译错误)

遗留/待办

  • 岗位细分(前后端 userType 同为 KFZ,resolveRole 默认 backendDev,TODO);FR-014 扣分归属(现取 story.assignedTo,待 IT 经理确认);docCheckConfirm 接口占位 TODO(前端已留);申诉 account 为空场景口径;菜单权限码需在 base_role 配置(perf-report/doccheck/config 等)后页面可见
  • 待联调:启动 8086 加载三期代码 → perf 页面真实验证 + 对拍(最近月份 vs 线下 Excel)

三期联调(2026-07-28,161 环境,全部通过)

接口:完成率(当月无迭代 rate=0+remark 口径)✅;/zt-perf/report(backendDev 实算 total=10+auto/manual 徽标)✅;FR-014 generateDocCheck(6566 置指数 25 后:五路判定 3✓2✗ 扣 4 分,判定源正确)✅;docCheckMatrix(docs map+deduct+status 契约一致)✅;docCheckConfirm ✅。

页面(真实浏览器验证):/perf/report(9 岗位 tab+总分卡+auto/manual 徽标+申诉/编辑列)✅;/perf/docCheck(6566 行 3✓2✗ 扣4 状态 pending)✅;/perf/config(规则 61 行表格+编辑)✅。

联调修复(7 处):①新增 docCheckMatrix/docCheckConfirm 接口(前端契约缺数据源);②岗位 tab 中文→编码映射(report/config 页 roleList 改 label+value 双轨);③总分卡岗位显示加 roleLabel 中文映射;④report 空账号(全部人员)→ 兜底当前登录人(service);⑤controller account 参数 required=false;⑥菜单注册(base_menu 父级+3页+7按钮,授 3 角色,admin 全量自动可见);⑦dev server 重启识别新 views/perf 目录。

注意(对拍时关注):空数据月份 auto 项 raw=0→score=0 的语义(如 bugDensity 扣满)需真实数据验证规则合理性;完成率分母"当月无迭代"口径待真实迭代数据验证;FR-014 扣分归集依赖 story.assignedTo(6566 无负责人故 deductByAccount 为空,符合预期但生产需关注)。

可视化验收后调整(用户反馈):研发详情「需求 ID」区块+复制按钮移除(页面顶部已有 ID+标题,冗余;方法 copyStoryId 一并删)。dev_plan §3.5 已同步。


会议纪要 MD 预览修复链(2026-07-29,161 环境,实测通过)

问题:用户需求详情会议纪要 tab 点 MD 在线查看失败/下载 0KB;fileList 一度返回空。

根因与修复:

  1. CommonsController.downLoad 硬编码 linuxFilePath → 改 OS 感知路径(Windows 下 0KB 的根因)。
  2. legacy /common/upload 不写 url 字段 → 现在写入相对路径 /zentao/img/...(与 uploadBind 一致)。
  3. zt_file 历史数据:234/235/236 手工补 objecttype='meeting'(老 upload 不传 objectType,靠保存时 updateFile 绑定);230/232/233 曾被 updateFile 清理逻辑标 deleted='1'(当时 objecttype 未绑定,editDialog fileList 查不到 → 视为已移除)。
  4. MdPreview 组件由纯文本 pre 改为 mavon-editor 预览模式(只读/代码高亮/表格/引用,PM 与 F:\zd 均已装 mavon-editor@2.10.4)。

防误删核查:meeting editDialog 打开时 fileList(objectType='meeting') 装入 form.files(editDialog.vue:345-353),保存时 getParam 拼 id 串 → updateFile 的 notIn 清理不会误删已绑定附件。闭环安全。

实测(8089 前端 + 8085 后端,真实浏览器):用户需求 324 详情 → 会议纪要 tab(会议卡 84:时间/操作人/需求会议 tag/MD 按钮齐全,tab 不再粘连)→ 点 MD → rich_demo.md 富文本渲染通过(表格/SQL 代码块高亮/引用/嵌套列表)。接口层:fileList 返回 3 条 deleted='0' 附件;GET /zentao/img/....md 200/598B(8085/8086 均通)。截图 tmp/pw_324_meeting_tab.png、tmp/pw_324_md_preview.png。


指标公式验证 + 5‰ 豁免阈值修复(2026-07-29,P0 关闭)

验证范围:SRC-002 新版考核 xlsx 全部 9 岗位 sheet × zt_perf_config 61 行规则 × calculators 代码,逐条对照(此前只做过单测与接口级验证,未做全量公式核对)。

一致项(56/61 行):9 岗位权重合计均=1.0;linear/threshold/manual 参数与 xlsx 全部吻合,含易错点——后端代码质量 round 模式(初审严重3/错误超6扣3/复审严重5/错误1)vs 前端 flat(每问题扣3);前端饱和度 0.3 vs 后端 0.2;王宇航表无 PRD 项且稳定性 0.2;UI 三档 threshold(100/40/0);tester 线上Bug 普通扣5、重大扣100=该项0分;opsMajorTask 百分制换算=及时率×20 与 xlsx 一致(deductPerStep=1 在百分制下等价,非错误)。

P0 差异(4 行):xlsx/PRD §7.3 规定线上Bug率与产品缺陷率「≤5‰ 得满分」,实现缺豁免阈值——有 1 个普通 Bug 就扣 3 分。影响 id 4(projectManager/onlineBugRate)、11(projectManagerWyh/onlineBugRate)、19(productManager/productDefectRate)、24(productAssistant/productDefectRate)。

修复:AbstractWeightedBugCalculator 增加 exemptPerMille 分支——分子=当月上线需求(releaseddate 当月)的 prod Bug 数,分母=当月上线需求 estimate 和,率≤5‰ 满分豁免、超才按个扣分;tester(id45,xlsx 无豁免口径)及无该参数的规则走原逻辑不受影响。4 行 rule_json 已加 "exemptPerMille":5(161 库 + sql/20260728_init_zt_perf_config.sql 同步)。

单测:BugIndicatorCalculatorsTest 新增 3 用例(1‰ 豁免满分 / 10‰ 超阈值扣 6 分 / 无上线需求边界满分),perf 包 54 个测试全绿。

遗留(已在 PRD 标注待确认,非本次新增):加分项 4 条默认停用(id34/41/48/52,待 IT 经理确认口径);acceptOnTime 走 manual(zt_story_user 验收时间链断裂);AC-013-2 与线下真实考核 Excel 对拍未做(需用户提供线下 Excel/真实月份)。


CHG-027 框架验收指标新字段+接口(2026-07-29,161 环境,实测通过)

背景:用户拍板——老验收标准(zt_storyspec.verify)不动,AI 框架验收指标走新字段+接口。

改动:

  1. DDL:zt_story_expand 加 acceptance_criteria MEDIUMTEXT(Given/When/Then MD),161 已执行 + sql/20260729_alter_zt_story_expand_acceptance.sql 迁移文件。
  2. 实体 ZtStoryExpand.acceptanceCriteria + mapper XML resultMap 补映射;service 零改动(updateById 空值不覆盖,新字段随 saveOrUpdate 自然透传)。
  3. 上传通道=现有 /zt-story-expand/saveOrUpdate(框架指标同通道),不新增端点(避免与 saveOrUpdate 重复设计)。

验证:单测+1(insert 透传 acceptanceCriteria,3/3 绿);真实接口(8086)——324 上传 Given/When/Then 中文 MD → code:0,queryByStoryId 回读字段完整;6566(finished)→ 正确拒绝"该需求已完成,不可再修改";zt_storyspec.verify 确认不受影响。

注意:用户 8085 需重启加载本次改动(本字段 + 5‰ 豁免修复 + MdPreview/mavon 相关)。


QA 测试文档生成(2026-07-29)

06_test_docs/ 建成:test_cases.md(36 条用例:33 AC + CHG-027 补充 + TC-002-4 附件防误删回归,14 FR + CHG-027 全覆盖,含环境/账号/前置数据/覆盖矩阵/执行记录表/阻塞依赖)、defects.md、regression.md(模板待执行填充)。已知阻塞:TC-013-2 依赖线下 Excel;上传类用例前置=8085 重启加载 CHG-026/027。


研发详情上传按钮位置修正(2026-07-29)

用户反馈:4 个文档区块(提交测试报告/其他测试文档/代码审查报告/工作日志)上传按钮浮在文件列表上方 → storyinfo/components/product.vue 调整为文件列表在前、上传按钮在最后(测试用例/模版为只读区无上传钮,不动)。已同步 F:\zd,8089 热更新实测截图 tmp/pw_6566_review_sec.png 确认。另:测试用例文档(zt_file 238)已 uploadBind 挂 6566,test_case_url 刷新,下载 200/12566B(curl 中文 title GBK 乱码已 DB 修正——框架 python 上传无此问题)。


AI 指标区块撤掉三个人员字段(2026-07-29,用户拍板)

productPerson/developPerson/testPerson 三字段无自动数据源(打分弹窗手填,6566 为 SQL 调试数据)→ 研发详情 AI 指标区块撤下这三项展示(storyinfo/components/product.vue,9 项保留)。不动:zt_story_expand 三列、打分弹窗、需求报表列(属工时统计功能);右侧基本信息的产品经理/测试人员为 zt_story 自有字段,保留。已同步 F:\zd,8089 实测截图 tmp/pw_6566_ai_block.png。


测试报告模版生成+传禅道(2026-07-29)

06_test_docs/test_report_template.md(7 节:概述/环境/执行汇总/36 条明细空表/缺陷统计/回归/结论签字)→ uploadBind(objectType=testReport) 挂 6566(zt_file 239,test_report_download_url 刷新,下载 200/2348B)。6566 测试类文档现状:用例✓ 模版✓ 提交件✗(待执行)其他✗。


200→161 全库复制 + zentao_dev_2026 增量 DDL(2026-07-29)

复制:200 zentao_dev(只读,94 表 2.6GB)→ 161 zentao_dev_2026。zt_action/zt_actionrecent 按计划只建空表;其余 92 表行数对拍全部一致;中文抽查正常。过程排障:161 元数据锁(残留事务→DROP TABLE 排队→新连接挂起),KILL 阻塞线程后恢复;max_allowed_packet=64MB 导致大字段表断连 → 脚本按 12MB 分包+断点续跑+重试(tmp/db_copy_200_to_161.py)。

增量 DDL(用户指定只加字段不含数据):zt_file.url、zt_meeting.url、zt_story 7 url 列+code_review_status、zt_story_expand ai_participation_rate+acceptance_criteria 共 12 列 + zt_perf_config/zt_doc_check 两空表,幂等脚本 tmp/apply_ddl_2026.py,验证通过。未加(属数据):zt_perf_config 61 行规则种子、ai 用户、绩效菜单 base_menu——跑绩效功能前需补。


CHG-028 饱和度达标工时口径修正(2026-07-29)

用户发现:郭尚雨 6 月老月报 91% vs 新绩效 104%——排查为分子差异(老=分配工时 estimate、新=实绩 consumed),属口径并存(老报表不动)。另发现实现误用老系统分母(工作日×8−请假)×0.75,与 xlsx/PRD §7.3「团队总工作天数×5」不符 → 用户拍板改为 (当月工作天数 − 请假小时÷8)×5(半天=0.5 天),分子维持 zt_effort.consumed。WorkSaturationCalculator 已改;单测 15/15 绿(新增请假半天用例);规则配置无需改(百分比规则不变)。PRD v1.26、decision_log 已录。注意:8085 重启后生效;分母变小(5h/天 vs 6h/天)→ 饱和度百分比整体上升,历史月份重算分数会变高,属预期。


CHG-029 老模块饱和度统一(2026-07-29,8086 实测一致)

用户拍板"再老的改"。排查发现 91/104 均为老模块(IZtCountService)两方法口径分叉:月报分子排除 closed/cancel 任务、地盘不排除。统一为新口径:分子=实绩工时(zt_task.consumed,全状态任务)、分母=(工作天数−请假小时÷8)×5。改动 IZtCountService 5 处(setUserWorkTime、buildKFZScore 分子+workTime 全集、地盘方法分母+分子、项目组汇总分子、buildXMZLScore 显示)。8086(2026 库)实测郭尚雨 2026-06:月报列表 saturation=1.25、地盘绩效 saturation=1.25,完全一致(131h÷105h)。注意:①老模块分子用 zt_task.consumed(131h),新绩效模块用 zt_effort(86.5h)——两表数据不一致导致老页面 125% vs 新绩效 82.4% 得分 64,属数据源差异,后续要么对齐数据源要么老页面淘汰;②8085 需用户 IDE 重编译重启生效;③前端 axios 带 Authorization 头,curl 直调需 -H "Authorization: token"("token" 头过滤器不读)。


CHG-030 aiBatchAdd 工时预算校验(2026-07-29,8086 实测通过)

用户拍板"拆的任务工时不能比研发需求总工时高"。aiBatchAdd 新增预算校验:已有任务 estimate 合计 + 本批新增(dup 跳过项不计)> zt_story_expand.evaluation_time → 整批拒绝(报文明细:已有Xh+新增Yh>预算Zh);无评估工时不设防。单测+4(预算内放行/超额拒绝/已有任务计入/无预算放行,8/8 绿)。8086 实测:22h 已有下 12h 新增被拒(消息正确含"新增0h"重复项剔除)、22+2>10 被拒、调 30h 后 24≤30 放行(created=1+skipped 重复项)。测试数据已清理。注意:2026 库(200 镜像)zt_story_expand.evaluation_time 全列为空 → 预算校验在该库当前不触发(无预算数据),生产/老库有评估工时后才生效;8085 需 IDE 重编译重启。


CHG-032 撤销禅道侧工时校验(2026-07-29)

用户明确"禅道不能做校验" → CHG-030 全部回滚:ZtTaskServiceImpl.aiBatchAdd 恢复原状(预算校验+storyExpandService 注入移除),AiBatchAddServiceTest 4 个预算用例移除(回 4/4 绿)。工时匹配纪律只在框架侧:拆任务时 Σ任务工时=需求评估工时(PRD FR-006 规则5、tgassist PJM 纪律,均已去掉"禅道兜底"表述)。8085 重编译后 aiBatchAdd 回到无校验状态。


CHG-029 全量验证闭环(2026-07-29,8086 实测)

补改最后一处漏网:workDetailsCount(开发者工作统计)saturation 分子 storyTotalTime(estimate)→workTime(consumed)。四处实测(郭尚雨 2026-06,2026 库):月报(全产品集)=1.25、月报(119 中道救援)=1.09、地盘绩效=1.25、开发者工作统计(119)=1.09——公式全统一(consumed÷(21×5=105h)),109 vs 125 纯产品集筛选范围差异(119 线下 114h vs 全部 131h),与用户页面所见完全吻合。buildXMZLScore 达标工时显示同步新口径。


CHG-034 达标工时团队口径(2026-07-29)

用户指出 CHG-028 实现不符 xlsx 字面("完全不是一个东西")→ 改严格团队口径。新模块 WorkSaturationCalculator 与老模块 4 处(setUserWorkTime/地盘方法/XMZL 显示/项目组汇总经 dto 传递)统一 teamExamineTime。单测 15/15 绿(新增团队平摊用例:(w×2−0.5)×5÷2)。8086 实测:2026 库 KFZ=13 人、6 月无请假 → 团队口径=(21×13−0)×5÷13=105h,地盘绩效 examineTime=105.0/saturation=1.25 一致(无请假时与个人口径同值)。未能实测请假平摊:os_system.it_approval 是 join 视图不可写,且 2026 全年无请假记录;单测已覆盖。遗留口径疑点:getApprovalTime 同日分支直接累加 apply_days(单位疑为小时,与老代码用法一致按小时/8 折算;OA 无数据可校,若实际为天需改折算);张富斌(测试)user_type=KFZ 被计入团队人数——xlsx 要求"后端+前端",若其为测试应改 user_type 或另行排除,待用户确认。


前端老口径描述改新 Excel(2026-07-29)

用户指出月报点击查看仍显示老描述。改 3 文件:performance.vue(KFZ 考核表:月度达标工时公式→团队总工作天数×5÷开发人数/请假全团队摊、数据映射 有效工时allocationTime→实际产出工时workTime;代码质量 5%→10%且规则改 xlsx 初审/复审两段;文档质量 15%→10%;不规范行为描述改 xlsx 六维度)、reportForms.vue(工作饱和度 tooltip+注释块→实绩÷月度达标工时)、monthReport.vue(列头"可用工时(6*工作天数)"→"月度达标工时",数据列 haveTime 本就是团队口径 105h)。已同步 F:\zd,8089 热更新编译通过。注意:地盘绩效页得分计算(saturationScore 等)仍是老规则,与页面上新 Excel 描述并存——完整新算分在 /perf/report,老页淘汰前存在此割裂,已在 PRD 7.5 标注 ❌/🔶 项。


CHG-035 三期绩效页面下线(2026-07-29,用户拍板)

用户:"不需要这些页面,月报的绩效按钮就是人工评分"。2026 库删除绩效菜单 13 行+授权 37 行;恢复备份 sql/20260729_insert_perf_menu.sql(列名完整,50 INSERT)。页面代码/zt_perf_config 61 规则/zt_doc_check 保留未删。人工评分=月报「绩效」按钮(老 editDialog 流程)。8085 重新登录后菜单消失。FR-012/013/014 功能本体保留,仅入口下线。


CHG-036 老弹窗得分改新 Excel(2026-07-29,8086 实测通过)

方案经用户确认后实施:utils/PerfScoreRules 纯函数(及时完成25:95段扣1/94段扣2 分段累计;Bug密度30:>15%每增1%扣3分无截断;饱和度20:<100%每减1%扣2分)+ IZtCountService.buildKFZScore 接入(punctuality/bugDensity/saturation 三分项替换,codeQuality 5→10、documentQuality 15→10、workAttitude 5 满分默认)。弹窗路径核实:月报 查看/绩效按钮 → performance.vue → myWorkScore → buildKFZScore(KFZ),总分由前端 sum(六得分项+两加分项)自动合成。PerfScoreRulesTest 3/3 绿(分段/截断/科学计数 BigDecimal 归一)。8086 实测郭尚雨 2026-06:saturation 1.25→20、及时率 1.0→25、bugDensity 4%→30、三项人工满分,总分=100,与新 Excel 逐项吻合。月报列表 DTO 不带得分字段(只展示比率列)不受影响。buildCsScore(标注"老的")无调用方,顺带对齐不影响任何页面。8085 需 IDE 重编译重启。


CHG-037 老绩效弹窗全岗位改新 Excel(2026-07-30,8086 实测通过)

背景:CHG-036 只改了 KFZ 弹窗得分;本次把月报「绩效」弹窗其余岗位全部切到新 Excel(SRC-002)口径,岗位得分改由新绩效引擎(zt_perf_config 规则)按 score×weight 加权产出。

后端:

  • PerformanceDTO 新增 7 字段:workloadPrdScore/workloadTeamScore/opsMajorTaskScore/opsMonitorScore/opsInspectScore/opsBackupScore/otherOpsScore。
  • IZtCountService 新增 perfItemScore(scope, itemKey, default):按岗位 itemKey 从 perfReportService.report 取加权得分;指标无数据/人工项(score=null)给满分默认。
  • buildXMJLScore(项目经理)重写:PRD完成率20/团队完成率30/版本计划10/线上Bug10/文档齐备10/问题管理5/稳定性10/技能5;王宇航按 account 走 projectManagerWyh 变体(无 PRD 项、团队40、稳定性20);旧 programCount/任务管理/Bug管理/会议管理 附加计算废弃。
  • buildCPJLScore(产品经理):PRD完成率40/团队完成率20/项目准时率10/产品缺陷率15/问题响应10/主动性5;展示字段(计划/准时上线数、严重/普通 Bug 数)保留原取数。
  • buildXMZLScore(产品助理):PRD完成率50/及时验收20(人工默认满分,zt_story_user 验收链断裂维持人工)/产品缺陷率15/问题响应10/主动性5。
  • buildYwScore(运维,新增方法+UserType.YW 调度分支):大项任务20/监控15/巡检10/备份10 走引擎(opsEngineer 4 项 calculator),其他运维15/稳定性20/不规范行为10 人工满分默认。
  • buildCScore(测试)及时完成改 PerfScoreRules.testerPlanScore(=100%得20,每减1%扣2分);buildUiScore 改 uiPunctualityScore(=100%得50/90%+得40/<90%得0)。

前端(performance.vue,已同步 F:\zd\web_zentao):XMGLY/CPJL/XMZL 三区块按 xlsx 全量重写(行/权重/评分标准/得分说明逐字对齐 SRC-002);新增 YW 区块(含创新贡献加分项);新增王宇航变体块(account 判断先于 userType switch);juedgeRole 加 YW;各区块总计 amountTo 同步新得分字段。

验证:

  • 单测:PerfScoreRulesTest +2(testerPlan/uiPunctuality 分段边界,5/5 绿);perf 包+Ops/Bug 计算回归 33 绿。
  • 8086(2026 库)myWorkScore 六账号实测:王宇航 workloadTeamScore=35.6、孙世超 26.7、魏冬霞 workloadTeamScore=15.6/productBugRate=15、李语嫣 releaseScore=20/productBugRate=15、岑海峰 opsMonitor=12.75/opsInspect=7.5/opsBackup=9.7/otherOps=15、刘圣清 designScore=40/workAttitude=10——各岗位得分字段均按新口径产出。
  • 8089 弹窗截图四岗位通过:王宇航(tmp/pw_chg037_wangyuhang.png,总分 85.6)、蒋恒·项目经理(tmp/pw_chg037_jiangheng.png,总分 66.7)、李语嫣·产品助理(tmp/pw_chg037_liyuyan.png,总分 50)、刘圣清·UI(tmp/pw_chg037_liushengqing.png,总分 50)。

注意/遗留:

  1. 8085 需用户 IDE 重编译重启生效;本次验证用 8086(已含本改动)+ 8088(8089 dev server 默认端口 8088,临时以 VUE_APP_BACK_REST_URL=8086 启动,未改 .env.local)。
  2. CPJL(魏冬霞)/YW(岑海峰)在 2026 库 2026 全年无任务,月报列表不出行,弹窗未截图;两岗位得分字段已经 8086 API 实测,前端结构经语法+字段绑定核对。
  3. 版本计划完成率多人为 0:2026 库版本发布数据稀疏,引擎按实数算出 0(非默认值缺失),生产数据下另行观察。
  4. 人工评审项(其他运维/稳定性/不规范行为/问题管理/技能等)满分默认,IT 经理弹窗手改后提交,老流程不变。

CHG-038 KFZ 前后端工程师分流(2026-07-30,8086 实测通过)

背景:用户拍板——新 Excel 前端/后端工程师是两张表(前端:饱和度30%、无文档质量项、代码质量 flat 每问题扣3;其余逐项相同),系统 user_type 只有 KFZ 无法区分 → 加「开发方向」标识,用户拍板维护入口=用户新增/编辑表单下拉。

DDL:zt_user 加 dev_direction varchar(16)(frontend=前端/backend=后端,NULL 按后端口径,仅 KFZ 有效),161 zentao_dev+zentao_dev_2026 已执行 + sql/20260730_alter_zt_user_dev_direction.sql 迁移文件。

后端:

  • ZtUser/ZtUserDTO 加 devDirection;addUser 非 KFZ 置空、modifyUser 同步 setter(非 KFZ 置空);pageList/登录返回自然带出。
  • PerfScoreRules.saturationScore 参数化满分(rate, full),新增 FULL_SATURATION_FRONT=30;原 20 满分重载委托保持 CHG-036 行为。
  • buildKFZScore 分流:frontend → 饱和度满分 30、文档质量项不设(DTO 初始 0,前端表无此项)、devDirection 透出;backend/NULL → 原口径不变。PerformanceDTO 加 devDirection。

前端:

  • 用户新增/编辑弹窗(user/dialog/addDialog.vue、editDialog.vue):用户属性=开发者时出现「开发方向」下拉(前端/后端,必填校验仅 KFZ 生效);编辑经 leftCopy 自动带出已存值。
  • performance.vue:KFZ case 按 isFrontDev()(优先 myWorkScore DTO.devDirection,其次行数据/登录用户)分流两个区块——前端块:饱和度30%、无文档质量行、代码质量 flat 描述、amountTo 剔除 documentQualityScore;后端块维持原样;getMyWorkScore 拿到 DTO 后重建表格保证方向准确。已同步 F:\zd\web_zentao。

验证:

  • 单测 PerfScoreRulesTest +1(前端饱和度 30/20/0 边界+默认 20 兼容,6/6 绿)。
  • 8086(2026 库)实测:郭尚雨临时标 frontend → myWorkScore 返回 devDirection=frontend、saturation 1.25→saturationScore=30(后端口径应为 20)、documentQualityScore=0(不计);弹窗截图 tmp/pw_chg038_guoshangyu_front.png——饱和度 30% 得 30、无文档质量行、代码质量 flat 描述、总分 100。金亮(NULL)对照截图 tmp/pw_chg038_jinliang_backend.png——后端块不变(文档质量行在、初审/复审描述)。用户编辑弹窗截图 tmp/pw_chg038_user_form.png——开发者属性下出现「开发方向」下拉且正确带出「前端」。测试后郭尚雨 dev_direction 已复位 NULL。
  • myWorkScore 注意:zt_month_score 有已存快照的月份返回快照不重算(既有行为),分流只对未保存月份生效。

待办:现有 KFZ 人员 dev_direction 全 NULL(=后端口径),等用户提供前后端名单后一次性 SQL 初始化。


CHG-037 补测:CS 测试工程师(2026-07-30,8086 实测通过)

首轮验证漏掉 CS 分支,补测:API——孙庆方 2026-06 及时率 96%→punctualityScore=12(testerPlanScore 20−4×2,CHG-037 新口径生效)、文洋洋 80%→0、检出率 29%/53%→bugFindScore=30、无线上 Bug→bugScore=20、测试文档 25/不规范行为 5 人工满分默认;弹窗截图 tmp/pw_chg037_cs_sunqingfang.png(五项得分 12/30/20/25/5、总计 92 与 API 一致)。admin(GSGC)API 确认走 buildXMJLScore 项目经理口径。注意:CS 分支 myWorkScore 响应约 8~10s(getBugFindScore 重查询,既有行为非本次引入),弹窗需等待数据返回;首轮截图空数据即等待不足所致,非缺陷。至此 9 张岗位表全部实测覆盖。


CHG-038 前后端名单初始化(2026-07-30,用户拍板)

用户提供名单:前端=周林芳、张富斌、孟冉,其余 KFZ 一律后端。两库已刷:zentao_dev 前端 3/后端 13、zentao_dev_2026 前端 3/后端 10(含原 NULL 全部补齐 backend,无 NULL 遗留)。张富斌 CHG-034 遗留疑点一并关闭——确认为前端开发(维持 KFZ,不改 CS)。8086 实测周林芳(6 月 139%)弹窗=前端块:饱和度 30% 得 30、无文档质量行,截图 tmp/pw_chg038_zhoulinfang.png。


月报出行机制澄清 + 运维入口解决(2026-07-30,用户拍板"找个迭代加一下")

机制定论(修正 CHG-037 遗留#2 的表述):月报列表=产品集→项目→执行(zt_executionproject)→过滤「begin 或 end 落在当月」的执行→取执行团队成员(zt_team)。三点推论:①产品经理挂在执行团队里就会出行,跟有无任务无关——魏冬霞 6 月不出行只是因为她在 139 飞侠车服而非当时查看的 119,切到 139 即在列(弹窗实测 45.6 分:团队15.6/缺陷15/响应10/主动5/准时0——计划45上线32);②长期迭代(如 146 代驾主流程 2025-02~2027-03)begin/end 永不落当月 → 成员任何月份都不出行(既有逻辑,未动);③生产 161 当前(2026-07)无任何 begin/end 落 7 月的执行,月报 7 月暂空属数据现状。

运维入口:岑海峰两库原本 0 任务 0 团队。按用户拍板:zentao_dev_2026 加入 车服-20260730(307,7/6-7/30 窗口内)→ 7 月 139 列表出行,YW 弹窗实测总分 74.8(监控12.3/巡检7.5/备份10/其他15/稳定20/行为10),截图 tmp/pw_yw_cenhaifeng.png;zentao_dev(生产)同步加 146(占位,窗口外不出行,待 8 月新迭代建立后把运维加进当月迭代即可)。至此 9 张岗位表弹窗全部实测通过(CPJL=魏冬霞 tmp/pw_cpjl_weidongxia.png、YW=岑海峰)。


CHG-039 workloadRatePrd 人员匹配修复(2026-07-30,8086 实测通过)

发现:用户质疑"魏冬霞 6 月工作量指数为 0 对吗"→ 排查:WorkloadRatePrdCalculator 按 product_person LIKE account 过滤,但该列实际存中文姓名("魏冬霞",多人逗号分隔如"蒋恒,李淑敏")→ 恒不匹配,分子恒 0 → 项目经理/产品经理/产品助理的 PRD 完成率得分恒 0(假"未达标")。

修复:scopeStoryIds 改按昵称匹配(userService.getByAccount→nickname),account 兜底(未来写英文账号也兼容)。单测 +1(昵称路径+验证 getByAccount 调用;account 兜底由原用例覆盖),WorkloadRateCalculatorsTest 5/5 绿。

8086(2026 库)实测:魏冬霞 workloadPrdScore 0→40(6 月指数 314.03÷105=299% 满分);孙世超 0→20(满分);李语嫣仍 0——她两库 expand 都是 0 行(无任何需求把 product_person 写成她),属数据缺失非匹配问题,若业务上 PRD 归她需补 product_person 数据。

注意:8085 需再次重编译重启加载本修复;生产 zentao_dev 的 zt_story_expand 仅 6 行(含"产品""张三"等脏数据),PRD 完成率指标要等评估流程把 product_person 写起来才真正可用。


0 分专项排查 + CHG-040 opsMajorTask 匹配修复(2026-07-31)

背景:用户要求"所有得分为 0 的认真检查"。对 9 个代表账号(2026 库,2026-06)逐项下钻,分类定论:

得分项 账号 判定
UI 任务及时 punctualityScore=0 刘圣清 真 0(6 月无任务,规则内)
版本计划 versionPlanFinishedRate=0 孙世超/王宇航 口径问题:6 月发布需求 123 个但 estimate 全 0/NULL → 分母 0 → percent() 按 0% 扣分;非"没按时发布"。待用户拍板(补 estimate / 分母 0 按个数算 / 给满分豁免 / 维持)
项目准时率 productProjectOnTimeRateScore=0 魏冬霞 真 0(计划 45 准时 32=71%,<90% 每减 1% 扣 2 → 扣完)
PRD 完成率 workloadPrdScore=0 李语嫣 数据缺失(无需求 product_person 写她名,两库均 0 行)
大项任务 opsMajorTaskScore=0 岑海峰 bug:zt_yw_task.belong_to_user 存中文姓名按 account 匹配恒空(CHG-039 同类)

CHG-040 修复:OpsMajorTaskCalculator 按昵称匹配(注入 IZtUserService,and 嵌套 OR+final 变量),account 兜底;单测+1(OpsCalculatorsTest 9/9 绿)。8086 实测:6 月=0(真 0,1 任务未完成)、7 月=13.2(3 任务 2 及时→66 分×0.2,与手算一致)。zt_yw_fwqsearch/patrol/backups 三表经核实存 account,监控/巡检/备份三项不受影响。

8085 需再次重编译重启(本修复+CHG-039)。


CHG-041 绩效弹窗「绩效数据」列补过程值(2026-07-31,8086 实测通过)

背景:用户要求"所有人的绩效数据那一列给值(分子分母等)"——CHG-037 各岗位弹窗的绩效数据列大量留空,得分看不到依据。

链路:计算器(ThreadLocal rawDetail,compute 入口清除防串)→ PerfIndicatorCalculator.consumeRawDetail(接口默认 null)→ ZtPerfReportServiceImpl.computeScope 收集并挂到 PerfMonthScope.Item.rawDetail(随 scopeJson 落库快照也带)→ IZtCountService.fillRawDetail 拷入 PerformanceDTO.perfRawDetail(buildXMJL/CPJL/XMZL/YW 四方法)→ 弹窗模板:data 绑定值以 #itemKey 开头时渲染 dataObj.perfRawDetail[itemKey](无数据显示 —,rawDetailOf 方法)。

各指标明细格式:工作量指数 "Σ指数 X / 达标 Yh = Z%";版本计划 "按时 Xh / 总发布 Yh = Z%(发布 n 个)";线上Bug/缺陷率 "Bug n 个(重大 x/普通 y)/ Σ工时 Yh = Z‰(豁免线 5‰)"(非豁免口径="按个扣分");项目准时率 "准时 x / 规划 y = Z%";运维大项 "及时 x / 到期 y = Z%";运维周频次 "实做 x / 应做 y(缺 z 次)";文档齐备 "缺失 n 份 × 扣 x 分 / 缺失 0 份 / 当月无核查记录"。

弹窗绑定:XMGLY/wyh/CPJL/XMZL/YW 五区块 19 行挂上明细(线上Bug 行原绑定的 普通/重大BUG数量(后端不赋值恒 0 误导)一并替换为明细;CPJL 准时率/缺陷率保留原展示字段追加明细)。CS/KFZ/UI 区块本就有 DTO 实值,不动。

验证:单测 63 全绿(rawDetail 调用不影响既有断言);8086 实测——孙世超 workloadRatePrd "Σ指数 242.8 / 达标 105h = 231.24%"→20、workloadRateTeam "Σ指数 1076.53 / 达标 1365h = 78.87%"→26.7、versionPlanRate "按时 0h / 总发布 0h = 0%(发布 123 个)"→0(估算口径问题直接可见);蒋恒弹窗截图 tmp/pw_chg041_jiangheng.png 五行明细全渲染。

注意:8085 需重编译重启(含 CHG-039/040/041 三批);老快照月份(zt_month_score 已存)明细为空显示 —,属正常。


CHG-042 项目经理 PRD 完成率改团队口径(2026-07-31,用户拍板)

背景:用户指出"孙世超是项目管理员,他的(PRD 完成率)不是他一个人的,是项目所有人"——xlsx 项目经理表 PRD 完成率与团队完成率同公式(分母"团队可用工作天数×5"、"除测试人员外其他岗位都作为工作量产出方纳入统计"),个人口径理解有误。

改动:WorkloadRatePrdCalculator 按岗位分流——projectManager/projectManagerWyh:范围=全部需求(不按 product_person 过滤)、分母=工作天数×5×产出人数(devProducerCount,KFZ 全员);产品经理/产品助理维持个人口径(product_person 昵称匹配+个人工时)不变。

验证:单测+1(团队口径不过滤+分母乘人数+不查 expand,6/6 绿);8086 实测 6 月——孙世超/蒋恒 workloadPrdScore 20→15.6(Σ指数 1076.53/达标 1365h=78.87%,每减 1% 扣 1 → 78×0.2),魏冬霞(产品经理)40 不变(个人口径 299.08%),李语嫣 0 不变(个人口径无数据)。

注意:8085 需重编译重启(含 CHG-039~042 四批)。


CHG-043 项目经理两项完成率改项目口径(2026-07-31,用户拍板"按照迭代来")

背景:CHG-042 把项目经理 PRD 完成率改成全部门口径(分母=全部 13 KFZ)后,用户拍板应按"他下面的开发"算——即他当月窗口内参与的迭代(执行)成员。

口径:项目经理(含王宇航变体)的 workloadRatePrd 与 workloadRateTeam 两项统一为项目口径——

  • 分子 = 他当月窗口内(迭代 begin 或 end 落当月,与月报列表过滤同一约定,长期迭代不算)参与的执行 → 关联产品的需求 workload_index 和;
  • 分母 = 工作天数×5×这些执行的 KFZ 成员去重数(测试不计;他本人 XMGLY 非 KFZ 天然不含);
  • 无在窗执行 → 分子 0/分母 0 → 该项 0 分。产品经理/助理维持个人口径、产品/其他岗位的"团队完成率"维持部门口径不变。

实现:AbstractWorkloadRateCalculator 新增 projectExecs/projectScopeStoryIds/projectProducerCount 三方法(team→execution→project→product→story 链),producerCount 钩子加 month 参数;Prd/Team 两计算器按 isProjectManager 分流。单测重写 1 例(项目口径全链路 mock+不查 expand 断言),6/6 绿。

8086 实测 6 月:孙世超 Σ556.83/525h(5 人)=106.06% → PRD 20/团队 30 双满分;蒋恒 Σ519.7/945h(9 人)=54.99% → PRD 10.8/团队 23.1;王宇航 Σ0/630h=0% → 按规则 50 分×0.4=20(项目当月无产出记录,非满分豁免);魏冬霞(产品经理)不变。

注意:8085 需重编译重启(CHG-039~043 五批);蒋恒/孙世超人数差异源于各自在窗执行不同成员集;代码窗口约定(begin/end 落当月)不含跨月长期迭代,与月报列表一致。


CHG-044 达标工时全链路上弹窗(2026-07-31,8086 实测通过)

背景:用户要求"分子分母都要列出来"——KFZ 弹窗工作量饱和度行原来只有 实绩/人均达标工时/饱和度,看不到团队口径的中间量。

改动:PerformanceDTO +3 字段(teamWorkDays 团队总工作天数·人天、teamLeaveDays 团队请假折算天数、teamTargetTime 团队达标总工时);IZtCountService 新增 fillTeamExamine(setUserWorkTime 调用,KFZ/CS/UI/XMJL 链路全覆盖),teamExamineTime 与请假折算抽取 teamLeaveDays 共用;performance.vue 两个 KFZ 块饱和度行绑定补齐五行。

展示效果(郭尚雨 6 月):实际产出工时 131 / 团队总工作天数 273 / 团队达标总工时 1365 / 月度达标工时 105 / 工作饱和度 125% → 得分 20。截图 tmp/pw_chg044_guoshangyu.png。8086 API 同值验证;单测无回归(Misc/PerfScoreRules 21 绿)。8085 需重编译重启。


CHG-045 版本计划完成率改工作量指数加权(2026-07-31,用户拍板"workload_index 用这个")

背景:版本计划完成率原按 zt_story.estimate 加权,123 个 6 月发布需求 estimate 全 0 → 分母 0 → 孙世超/王宇航该项恒 0(假"未达标");用户拍板改用 zt_story_expand.workload_index。

改动:VersionPlanRateCalculator 加权源 estimate → expand.workload_index(String 列,parseIndex 非数字/空按 0;无 expand 行自然不进分子分母);明细改"按时 X / 总发布 Y(指数加权,发布 n 个)= Z%"。单测改写+新增各 1(指数加权正常值、无指数分母 0 边界),Misc 16/16 绿。

8086 实测 6 月:孙世超 versionPlanFinishedRate 0→5.4(按时 477.1/总 658.21=72.48% → 100−23×2=54 → ×0.1)。覆盖说明:123 个发布需求仅 34 个有 expand 指数,无指数需求按 0 权重不进分子分母(占比失真风险随评估流程覆盖率提升自然消解)。8085 需重编译重启。


CHG-046 《AI项目文档更新记录》独立承载全链路(2026-07-31,用户拍板"加字段+功能完善+前端展示")

背景:五类文档中仅《AI项目文档更新记录》无独立承载(原设计寄身 aiWorkLog 的 doc_update 类,从未产出,全库零命中)。

改动:

  1. DDL:zt_story 加 ai_doc_update_url varchar(512),161 两库已执行 + sql/20260731_alter_zt_story_doc_update.sql。
  2. FileTypes 增 aiDocUpdate("aiDocUpdate","AI项目文档更新记录");uploadBind(refreshOwnerUrl) 增该类型→刷新 zt_story.ai_doc_update_url;ZtStory 实体加字段(MP 自动映射,无需 XML)。
  3. FR-014 核查判定改通道:DOC_DOC_UPDATE 由"zt_file(aiWorkLog) doc_update 类"改为 zt_file(aiDocUpdate),detail 同步;DocCheckServiceTest 断言更新(4/4 绿)。
  4. 前端 storyinfo/components/product.vue 研发需求详情新增《AI项目文档更新记录》区块(工作日志与交付物之间):文件列表+上传按钮(aiDocUpdate),aiDocUpdateFiles+fileFieldMap+fetchObjectFiles 三处接线。已同步 F:\zd。

8086 全链路实测:multipart 上传测试 MD 到 6566 → code:0(zt_file 8799)→ zt_story.ai_doc_update_url 刷新 → fileList 返回该文件(注意:fileList 无 @RequestBody,必须 form 表单传参,JSON 体不绑定)→ 6566 详情页新区块渲染文件+上传按钮(截图 tmp/pw_chg046_6566.png)。curl 上传中文 title GBK 乱码已 DB 修正(已知 curl 老问题,框架/浏览器上传无此问题)。8085 需重编译重启。

说明:①快照/实时判定之争本轮不动(用户问的是承载);②框架侧生产 doc_update 内容仍待 DT9 挂钩点补齐(现以手动上传为主);③zt_doc_check 六月快照范围不含 6566(其月工作量不在 6 月),核查翻牌效果待真实大型需求上传后自然呈现。


CHG-047 文档齐备改实时字段判定+项目口径(2026-07-31,用户拍板"需求的 url 字段直接判断")

背景:①快照归属错位——项目经理"文档齐备"按 assignedTo 归集,孙世超项目 4 个大型需求五类全缺(20 份),扣分却挂在 luoyong/sunying(其考核表无此项),孙世超反显满分;②用户拍板不要快照表/月末 job,直接读需求 url 字段实时判。

改动:DocReadyScoreCalculator 重写(继承 AbstractWorkloadRateCalculator 复用 CHG-043 项目口径取数)——

  • 判定:大型需求(当月有指数记录且指数>20)的 zt_story 五个 url 字段(testCaseUrl/testReportSubmitUrl/aiDocUpdateUrl/codeReviewUrl/workLogUrl)非空即在,缺失 n 份 × 扣 2 分扣完截止;
  • 归属:projectManager/projectManagerWyh ∩ 他当月窗口内执行关联产品的大型需求;其他岗位=全量大型需求;
  • 明细:"大型需求 m 个,缺失 n 份(8930缺[用例,报告,更新记录,审查,日志] …)";
  • 不再读 zt_doc_check 快照(表与手动触发接口保留,矩阵页已下线);TestDocReadyCalculator(CS 测试文档项)不动。

验证:单测改写 2 例+新增 1 例(项目口径缺 2→96/无指数记录→100/无在窗执行→100),Misc 17/17 绿。8086 实测 6 月:孙世超 满分 10 → 6(4 个大型需求×5 类全缺=20 份×2=扣 40,明细逐需求列出缺失类型);王宇航 10(项目范围当月无大型需求)。8085 需重编译重启。

后续提醒:zt_doc_check 快照表与 generateDocCheck 接口已成摆设(仅矩阵页用,已下线),可择机清理;异议流程随快照一并闲置。


CHG-048 PRD 完成率项目口径扩到产品经理/助理(2026-07-31,用户拍板"跟项目管理员一样的方案")

背景:魏冬霞 PRD 完成率原按个人口径(product_person 名下 314.03/105h=299.08%),用户指出 xlsx 该公式与项目管理员同文字("团队可用工作天数×5"、"除测试外都纳入统计"),应同方案。核实:她与孙世超同属车服团队(在窗执行同为 286/297/300/301 → 产品 150)。

改动:WorkloadRatePrdCalculator 项目口径分支由 projectManager/projectManagerWyh 扩到 productManager/productAssistant(isProjectScopedRole 四角色统一:范围=当月窗口内执行关联产品的需求、分母=执行内 KFZ 成员数×天数×5);product_person 个人口径保留为其余角色兜底(实际已无使用者)。团队完成率(workloadRateTeam)维持 CHG-043 不变(项目经理=项目口径,其余=部门口径)。

验证:单测默认角色改 backendDev(个人兜底路径保持覆盖)+新增 CPJL 项目口径用例,WorkloadRate 7/7、Misc 17/17 绿。8086 实测 6 月:魏冬霞 314.03/105(299.08%) → 556.83/525h=106.06% → 40 满分(与孙世超同数据源,数值收敛合理);李语嫣 0 不变(她项目产品 145 当月无指数记录,属数据缺失);孙世超不变。

注意:①李语嫣的 0 根因=产品 145 无工作量数据(非口径);②四角色的 PRD 完成率与团队完成率现在数据源差异=项目 vs 部门,xlsx 两行得以区分;③8085 需重编译重启。


CHG-049 版本计划完成率改项目口径(2026-07-31,用户拍板"孙世超是飞侠的为啥不区分")

背景:versionPlanRate 原全表统计(145/150/161 三产品混算 72.48%),且指数覆盖严重不均(150 占 30/34 权重、145 道路救援 72 个发布仅 1 个有指数)——孙世超是飞侠车服项目经理,应按其项目产品区分。

改动:VersionPlanRateCalculator 继承 AbstractWorkloadRateCalculator 复用 CHG-043 项目口径:projectManager/projectManagerWyh 只统计他当月窗口内执行关联产品的发布需求(其余角色=全表兜底,当前无使用者);指数加权逻辑(CHG-045)不变。单测版本正常用例补项目 mock(Misc 17/17 绿)。

8086 实测 6 月:

  • 孙世超 5.4→9.4:按时 477.1/总发布 516.61(发布 38 个·产品 150)=92.35%,每减 1% 扣 2 → 94×0.1
  • 王宇航 0:按时 0/总发布 33(发布 72 个·产品 145 道路救援)=0%——他项目是道路救援,72 个发布仅 1 个有指数(权重 33 且未按时),覆盖率不足致其版本率失真(单需求决定 100%) 注意:145 产品线指数覆盖率 1/72,王宇航的版本率在该产品评估流程跑起来前不可用于考核;8085 需重编译重启。

CHG-050 Bug 率 5‰ 豁免复活:分母改任务工时+项目口径(2026-07-31,用户拍板"需求工时是任务sum")

背景:线上Bug率/产品缺陷率的 5‰ 豁免分母原取 zt_story.estimate(全库未填)→ 率恒 0‰ 恒豁免,用户在车服加 6 月线上 Bug(zt_bug 2566,普通,挂 8277)验证发现扣分不触发。

改动(AbstractWeightedBugCalculator 继承 AbstractWorkloadRateCalculator 复用项目口径):

  1. 分母 zt_story.estimate → 当月上线需求的 devel 任务 estimate 合计(用户拍板"需求工时是任务sum");
  2. 四角色(项目经理/王宇航/产品经理/产品助理)上线需求范围 ∩ 当月窗口内执行关联产品(同 CHG-043 项目口径);
  3. 无上线需求 → 满分并注明(项目范围)。

验证:单测 exempt 两例改任务工时 mock+项目 mock(Bug 12、Workload 7、Misc 17 全绿;排障一例:mock 执行时间跨月末边界致项目范围为空)。8086 实测 6 月(测试 Bug 2566 在库):孙世超 9.7(1 普通/165.5h=6.04‰>5‰ → 扣 3 → 97×0.1,明细"Bug 1 个(重大 0/普通 1)/ Σ工时 165.5h = 6.04‰");王宇航 10(项目 0 Bug/275.5h 豁免);魏冬霞产品缺陷率 14.55(同 Bug,97×0.15)。

注意:①测试 Bug id=2566 标题含"【测试】…可删",影响孙世超/魏冬霞 6 月该项得分,不要时直接删行即可;②150 单产品 165.5h 的分母较小,1 个普通 Bug 即破 5‰ 线——项目口径下该指标对小团队偏敏感,属口径本身特性;③8085 需重编译重启。


CHG-051 引擎扣分统一为加权尺度(2026-07-31,用户拍板"10分满分 10-2")

背景:用户质疑"缺 20 份为啥还是 6 分"——引擎原按 100 分制扣分再 ×权重(扣分量只有 xlsx 字面 1/10 效果),与 KFZ(CHG-036 起即加权尺度)两套尺度并存。

改动:AbstractPerfIndicatorCalculator 新增 scaleDeduct——配置权重注入 rule(__w),扣分按 1/权重 放大到 100 分制再扣(最终 ×权重=xlsx 字面加权扣分);接入 applyLinear(全部 rate 类)、perBugScore(Bug 类)、OpsCount(运维周频次)、DocReady(文档齐备)四处扣分点;threshold 分档与 PerfScoreRules(KFZ/CS/UI)本就加权尺度不变。结果对齐 xlsx:10 分项缺 1 份=扣 2(10−2=8),缺 20 份=扣完=0。

单测:新增加权用例 3(docReady 缺 2→60、Bug 超线 2 普通→40、监控缺 2→60),全量 93 绿(旧用例配置无 weight 不走缩放,行为不变)。

预期效果(孙世超 6 月,手算):文档齐备 6→0(20 份×2/0.1=400 扣完);线上Bug 9.7→7(3/0.1=30→70×0.1);团队完成率 26.7→19.0(11/0.3=36.7→63.3×0.3);版本计划 9.4→4(6/0.1=60→40×0.1);PRD 完成率 20(满分项不受影响)。

实测状态:8086 重启时 161 数据库 Too many connections(共享开发库连接耗尽,HikariCP checkFailFast;pymysql 同样 1040),待连接释放后补实测。8085 需重编译重启。


CHG-053 绩效弹窗跟随月报选中产品集(2026-07-31,用户拍板"按照当前选择产品")

背景:用户拍板公式"按理说都是根据某个产品来算的"——弹窗不再只按本人项目,而跟随月报下拉选中的产品集。

链路:monthReport.vue 把 dataForm.project(下拉选中的 program id)→ editDialog :program → performance.vue program prop → myWorkScore 请求加 project 参数;后端 IZtCountService.myWorkScore:project 非空时 pids=该 program 的产品集(替代本人授权产品),并在调度分支外裹 AbstractPerfIndicatorCalculator.setCurrentProgram/clearCurrentProgram(try/finally);AbstractWorkloadRateCalculator 的 projectScopeStoryIds/projectProducerCount 优先走选中产品集(新增 currentProgramProductIds/execsOfProducts,选中时不再要求本人是该迭代成员),null 时回退 CHG-043 本人路径。影响范围:任务/需求取数(pids)+ 引擎全部项目口径指标(工作量/版本/Bug率/齐备)。

验证:单测 93 全绿无回归。8086 API 实测(孙世超 6 月):program=139 → prd 20/team 30(556.83/525h=106.06%)、vp 4(92.35%)、bug 7(6.04‰)、doc 0;program=119 → prd/team 0(Σ0/630h)、vp 0(72 发布仅 33 权重按时 0)、bug 10 豁免、doc 10(无大型需求)——同一人两套分随切换。8089 UI 实测:下拉 139 弹窗含 556.83/525h/92.35%(截图 tmp/pw_chg053_139_jun.png);119 无本项目数据。已同步 F:\zd。

注意:①快照月(zt_month_score 已存)仍返回旧存值;②8085 需重编译重启+前端发版;③附带修正 playwright 脚本月份控制(直填月份输入框替代「上月」按钮)。

CHG-053 补充(同日):用户实测发现魏冬霞在 139 下团队完成率仍显 1365h——WorkloadRateTeamCalculator 的项目口径分支只开了项目经理 → 同步改 isProjectScopedRole 四角色(CHG-052 的正确归位,随"按当前选择产品"生效)。复测:魏冬霞 program=139 → 团队完成率 1365h/78.87%/0 → 525h/106.06%/满分 20;program=119 → 0(Σ0/630h)。WorkloadRate 7/7 绿。


CHG-054 CS 测试需求范围修正:assignedTo ∪ expand.test_person(2026-07-31,用户拍板"先修复")

背景:孙颖缺陷检出率恒 0 排查——当前测试需求范围仅 zt_story.assignedTo(她 6 月 3 个),而 zt_story_expand.test_person 指定她测的 6 月有 24 个(其中 21 个 assignedTo 是开发);全量 134 个指定需求中 assignedTo 是她的仅 12 个,assignedTo 口径严重漏算。

改动:IZtCountService 新增 testStoriesOf(注入 IZtStoryExpandService,test_person 中文姓名 like 匹配,assignedTo 池∪expand 指定,均按产品+releaseddate 当月过滤);三处 buildCScore 调用点(newPerformanceCount/programCount/myWorkScore 的 CS 分支)统一替换原 assignedTo 二次过滤。

8086 实测(孙颖):6 月 检出率 0.0%(24 个需求已纳入计算、devSlightBug=0,真无检出,此前是"取不到数不算");5 月 检出率 48%(12 个普通 Bug)→ bugFindScore 满分 30(修复前恒 0)。其余 CS 账号同享修正。8085 需重编译重启。


CHG-055 检出率得分不为空(2026-07-31,用户拍板"得分不能为空 要么为0")

getBugFindScore 三条空值路径统一显式赋 0:无测试需求、无开发工时、检出率 i≤0,均 set bugFindRate=0 + bugFindScore=0(原不赋值弹窗显示空)。8086 实测孙颖 6 月 bugFindScore=0(不再是 null)。


CHG-057 需求详情页撤审查状态显示(2026-08-06,用户拍板"代码审查报告不需要通过或者不通过在需求详情页面")

改动:storyinfo/components/product.vue——「代码审查报告」区块标题旁状态徽标(通过绿/未通过红/未审)移除;codeReviewStatusText computed 一并删除(全文件无其他引用)。保留不动:①提交测试报告卡点(codeReviewStatus !== 'pass' 时提示"代码审查未通过,不可提交"+隐藏上传按钮,FR-008 SOP 卡点);②后端 code_review_status 字段与 uploadBind 解析写入(代码质量考核取数依赖)。

验证:vue-template-compiler 模板编译 errors=none;script 块 @babel/core 解析 ok。两副本已同步(codes/web_zentao + F:\zd\web_zentao)。⚠️ 页面级验证待补:8085/8086 后端当前未运行(8088/8089 dev server 在线,热更新已生效),8085 启动后刷新需求详情页确认。

补记(留痕补齐,证据指引):

  • CHG-056(08-04,Bug 分级 severity 1=重大、2/3/4=普通):IZtCountService.java:1339 注释处 + AbstractWeightedBugCalculator/DefectFindRateCalculator 两处同步修改;decision_log 已录。
  • CHG-058(08-05,AI 代码审查/工作日志/文档更新记录三区块前端上传入口移除,上传只走 AI 框架通道):product.vue 三处 CHG-058 注释;同会话另完成 mermaid 流程图渲染(public/mermaid.min.js 静态引入 + MdPreview window.mermaid 渲染,8088 实测 9130 流程图通过)。

CHG-059 aiBatchAdd 补历史留痕(2026-08-06,用户报"AI 拆的任务历史记录没有")

根因:aiBatchAdd 只 insert zt_task,不写 zt_action——且全库从未有过 task 级 action(手工建任务也不写),需求详情的「历史记录」区块(actionList 按 objecttype+objectid 查)只见 story 级动态,故 AI 拆任务完全无痕迹。

改动:ZtTaskServiceImpl.aiBatchAdd 每个新建任务写一条需求级动态(与 uploadBind 上传留痕同模式:ActionType.XQ + ActionStatus.BJ,actor=ai,product=需求产品,extra=指派账号由前端映射昵称),comment="AI拆分任务:{名称}(开发/测试,工时Xh)";skipped 防重项不写。actionService 为类内既有注入,无新依赖。

单测:AiBatchAddServiceTest +1(留痕用例:新建写动态/comment 含任务名与工时/extra=指派账号/skipped 不写),setUp 补 actionService mock。Tests run: 5, Failures: 0, Errors: 0。

8086 实测:临时 2 任务上传 → zt_action+zt_actionrecent 各写 2 条(comment/extra 正确)→ 临时任务与 action 行已清理;18563/18564(修复前创建)按原创建时间补录动态 2 条(comment 标注"补录")。

注意:8085 为用户实例,跑的是修复前代码——需 IDE 重编译重启后 aiBatchAdd 才有留痕;历史里 18563/18564 的补录记录已可直接看到。


CHG-060 aiBatchAdd 补任务级留痕(2026-08-06,用户指出"任务侧历史也要有,手工拆任务本来有")

更正 CHG-059 的误判:此前"全库零 task 级 action"系 2026 库复制时 zt_action 按计划清空所致——手工建任务本就写 RW+XJ(ZtTaskServiceImpl:681,actor=登录人)。

改动:aiBatchAdd 在 CHG-059 需求级动态之外,每个新建任务再写一条任务级动态(ActionType.RW + ActionStatus.XJ,objectId=taskId,actor=ai,comment 空,与手工建任务同一形状),任务详情页历史可见。

单测:留痕用例补 RW+XJ 断言(mock insert 不回填 id,objectId 为 null 校验形状),5/5 全绿。

8086 实测:临时任务 18567 → story 级(edited+comment)与 task 级(opened,product=150)双写成功,actionrecent 同步;临时数据已清理。18563/18564 按原创建时间补录 task 级动态 2 条。

注意:8085 需 IDE 重编译重启后生效(含 CHG-059/060 两批)。


CHG-061 AI 通道接口鉴权 + ai 永久 token(2026-08-06,用户拍板"创建人都要 token 的")

背景:AI 上传三接口(saveOrUpdate/aiBatchAdd/uploadBind)此前无鉴权直连(R-003/DT4 二期必决项)。JwtUtil.sign 本无过期设计,token 天然永久。

改动:

  1. 鉴权门禁——saveOrUpdateExpand、aiBatchAdd:限 ai 账户 token(非 ai 登录用户也拒);uploadBind:需任意有效登录态(前端上传组件在用,不能限 ai)。
  2. 创建人改取 token 身份——aiBatchAdd 的 openedby 与两级 zt_action actor、refreshOwnerUrl 的上传动态 actor(无登录态兜底 ai 兼容直调)、zt_file.addedby 沿用既有 token 取值。
  3. ai 永久 token 已生成:HMAC256(account=ai),存 .claude/ai_token.txt(已用 8085 验证:真 token 放行 / 伪造 token"请登录")。
  4. 框架脚本:submit_assessment.py、upload_md.py 自动带 Authorization(读 ZENTAO_AI_TOKEN → .claude/ai_token.txt);两脚本默认地址改正线→本地 8085(用户拍板"别用正线的 url"),打正线需显式设 ZENTAO_BASE_URL。

单测:AiBatchAdd +1(非ai整批拒绝且零写入)、ZtStoryExpand +2(非ai/无token拒绝、ai放行)、UploadBind 测试补 actionService mock(修复 08-05 留痕上线时未补 mock 的既有断点)。三类 6+5+13=24 全绿。

8086 实测 3×3 矩阵:无 token 三接口全拒;admin token 仅 uploadBind 放行(zt_file.addedby=admin);ai token 全通(任务 openedby=ai、action actor=ai/admin 各归各)。测试数据已清理(zt_file 8815/8816 软删、任务 18569 软删、action 行删除、9130 test_other_url 恢复 08-05 值;上传目录留 2 个探针 MD 孤儿文件,低危)。

注意:①8085 需 IDE 重编译重启后门禁生效(重启前旧代码照旧放行,脚本带 token 向下兼容);②生产 itsm 仍为无鉴权旧代码,发版前该口子都在;③ai 账户密码仍是默认 MD5(123456),建议改密——改密不影响已签 token(checkToken 只验签不查库)。


9130 任务换新流程重建(2026-08-06,用户指出原任务建于修改前)

18563/18564(无 token 时代创建+手工补录留痕)软删、补录行清除 → 8085 新代码下以 ai token 重传 aiBatchAdd:18570(devel/6h/罗勇)+ 18571(test/3h/未指派),openedby=ai,需求级+任务级动态由系统自动双写(119044-119047),9130 链路数据全部为真实流程产出,无手工补录。


CHG-062 批拆留痕合并为一条(2026-08-06,用户拍板"一次上传多个任务应该就一条记录")

改动:aiBatchAdd 需求级留痕由"每任务一条"改为"每批次一条"——循环内只写任务级(RW+opened)并收集文案,循环结束写一条需求级动态:AI拆分任务 N 个:①名称(开发,工时6.0h,指派:罗勇);②名称(测试,工时3.0h,未指派);有重复跳过项追加";重复跳过 M 个";指派经 userService.getByAccount 转中文名(查不到兜底账号);extra 不再携带指派(文案内嵌)。

单测:留痕用例改写为聚合断言(个数/序号/指派/跳过数),AiBatchAdd 6/6 绿。

8086 实测:2 任务批拆 → 需求级 1 条+任务级 2 条;未指派文案"未指派"(无冗余前缀)。9130 既有 2 条单任务记录已合并重写成一条(原创建时间保留)。截图 tmp/pw_9130_history.png。

注意:8085 需 IDE 重编译重启生效。


CHG-063 文档区块归集「需求文档」tab(2026-08-06,用户拍板"放在需求的一生后面加一个 tab 需求文档")

改动:storyinfo/components/product.vue——测试用例/测试报告模版、提交测试报告、其他测试文档、代码审查报告、工作日志、AI项目文档更新记录 共 6 个文档区块由左栏(span16)整体迁移至右栏 el-tabs 新增第三个 pane「需求文档」(位于 需求的一生 之后);左栏保留 需求描述/验收标准/附件/AI指标/交付物/历史记录。数据与方法零改动(fetchBlockFile/uploadForm/卡点逻辑原样)。

验证:vue-template-compiler errors=none(移动时丢失 需求的一生 pane 闭合标签一处,已修);六区块 tab 内齐全、左栏无残留(程序化断言);8088+8085 实测 9130 页面:tabs=[基本信息/需求的一生/需求文档],六区块渲染正常、上传按钮/卡点状态正确。截图 tmp/pw_9130_doctab.png。已同步 F:\zd。

已知:tab 头在 span8 窄栏下标签偏挤(el-tabs 默认样式,功能性影响无);提交测试报告上传按钮因 9130 code_review_status=pass 正常可用。


CHG-064 产品助理弹窗前后端对齐(2026-08-06,用户报"产品助理的前端页面显示有问题")

根因:08-05 用户拍板"绩效的除了产品和项目经理其他撤回到 git 提交版本",08-05 会话完成了后端 IZtCountService 还原(buildXMZLScore 等回老版),但前端 performance.vue 的 XMZL 区块未同步还原——新版区块绑定的 workloadPrdScore/productBugRate/productProblemResponse/productResponsibilityScore 老后端不产出 → 弹窗得分全空。全角色对齐核查:CS/UI=老+老✓;CPJL/XMGLY/KFZ/YW=新+新✓(按拍板保留);XMZL 是唯一前后端错配。

改动:performance.vue 的 case 'XMZL' 块还原为 git HEAD 版(及时验收20/项目文档50/会议管理30,绑定 releaseCount/releaseOnTimeCount/releaseOnTimeRate/documentQualityProblem/projectDocumentScore/meetWeek/meetStory/meetScore 老字段)。已同步 F:\zd。

验证:编译 errors=none;字段交叉核对(HEAD 绑定 10 字段 ↔ 老后端 getReleaseScore/getMeetScore 全部有产出,documentQualityProblem DTO 默认 0);8088+8085 实测李语嫣(145 道路救援 2026-06)弹窗:及时验收 0/项目文档 50/会议管理 30/总计 80 渲染正常。截图 tmp/pw_xmzl_liyuyan.png。纯前端改动,8085 无需重启(dev server 热更新)。


CHG-065 产品助理+UI 弹窗改新 Excel 口径(2026-08-06,用户拍板"不对 按照新的excel来"、"还有ui人员的也更新掉")

背景:撤销 CHG-064/08-05 对 XMZL 的老版还原,产品助理与 UI 均按新 Excel(SRC-002)执行。

改动:

  1. buildXMZLScore 重建为新口径:scope=perfReportService.report(month, "productAssistant", account) + fillRawDetail;workloadPrdScore=perfItemScore(workloadRatePrd,50)、releaseScore=20(人工默认满分)、productBugRate=perfItemScore(productDefectRate,15)、productProblemResponse=10、productResponsibilityScore=5(后两项人工满分默认);移除老版 getReleaseScore/getMeetScore/documentQualityScore=50/projectDocumentScore=50 与 0.75 达标工时。
  2. buildUiScore 及时率得分:老内联公式(90 边界漏判:90%→0)改走 PerfScoreRules.uiPunctualityScore(=100%→50/≥90%→40/<90%→0,CHG-037 规则类幸存);designScore=40/workAttitude=10 本已符合新 Excel 不动。
  3. 前端 performance.vue:XMZL 区块恢复新 Excel 版(撤销 CHG-064 老版还原);UI 区块无需改(git 版行/权重/字段本就与新 Excel 一致)。已同步 F:\zd。

验证:前端编译 errors=none;后端 PerfScoreRulesTest 6/6 绿。8086 API 实测(2026-06):李语嫣 workloadPrdScore=0(真0,145 无指数记录)/releaseScore=20/productBugRate=15/productProblemResponse=10/productResponsibilityScore=5,perfRawDetail 两键齐——与 CHG-037 时期实测值一致;刘圣清 punctualityScore=0(真0,无任务)/designScore=40/workAttitude=10。8088 弹窗结构核验:两角色新行齐全、无旧版残留(截图 tmp/pw_chg065_xmzl.png、pw_chg065_ui.png)。

注意:8085 当前跑的是老后端,弹窗数值要 IDE 重编译重启后才按新口径显示(现在页面显示的是老后端值:PRD完成率空/及时验收0/问题响应15 等 DTO 默认值)。


CHG-066 XMZL 弹窗列错位修复(2026-08-06,用户报"分项跑到绩效数据那一列")

根因:performance.vue 模板 <td v-if="item.category"> 仅在行配置含 category 时渲染类目格——XMZL 区块「项目绩效」rowspan=2 只覆盖前两行,产品缺陷率/问题响应和解决两行无类目格 → 单元格少一个整行左移,得分值落进「绩效数据」列。全角色扫描:仅 XMZL 有此配置缺陷(KFZ/CS/UI/YW/XMGLY/CPJL 覆盖均正常)。

改动:XMZL 区块首行 rowspan 2→4(项目绩效覆盖 完成率/验收/缺陷率/响应 四行,与新 Excel 结构一致)。已同步 F:\zd。

验证:编译 errors=none;8088 实拍李语嫣弹窗:项目绩效跨四行分组正确、各列对齐、得分 0/20/15/10/5 落「得分」列、总计 50、首行明细"Σ指数 0 / 达标 630h = 0%"正常(截图 tmp/pw_chg065_xmzl.png)。同期 8085 已带 CHG-065 新后端(弹窗数值与 8086 API 实测一致)。


CHG-067 Bug 需求关联字段 story→toStory(2026-08-06,用户拍板"story 字段应该没用 启用的是toStory")

数据证据:全库 prod Bug 76 个 story>0 的 0 个、toStory>0 的 23 个;dev Bug 2433 个 story>0 的 0 个、toStory>0 的 2251 个——story 列全库未用,需求关联实际全走 toStory。

改动(4 处死字段修复):

  1. AbstractWeightedBugCalculator.computeWithExempt:5‰豁免分子取数 .in(getStory) → .in(getTostory)(线上Bug率/产品缺陷率核心修复,此前结构性漏算恒满分);
  2. IZtCountService:1350(buildCPJLScore 展示严重/普通 Bug 数)同改;
  3. ZtBugServiceImpl:527:入参本就是 toStory 的 ID,查询列同步改(按需求查 Bug 列表此前恒空);
  4. ZtStoryServiceImpl:1982:关闭需求联动关闭未关闭 Bug(此前永远找不到 Bug)。 已用 toStory 的(检出率 getBugFindScore/DefectFindRateCalculator/ZtStoryServiceImpl:2363)不动。

验证:perf 计算器套件 13+7+10 全绿。8086 新代码实测:王宇航 2026-02 onlineBugRate 100→40(2 普通 Bug/336.2h=5.95‰ 超豁免线,扣 6→加权尺度 40,与手算一致);无回归——李语嫣 6月=15(真0)、孙世超 6月=7(同 CHG-051)。排障:首轮实测误打 CHG-065 残留 8086 实例(占端口新实例未起),杀旧重启后复测通过。王宇航 2 月快照已恢复原值(备份 tmp/wyh_202602_snapshot_backup.json),历史月份是否统一重算待用户拍板。

注意:8085 需 IDE 重编译重启生效; prod Bug story=0 的录入习惯意味着仍有 17 个历史 prod Bug 两字段都空(任何口径都够不着,含 6 月的 2411)——要么补关联,要么接受豁免。


CHG-068 需求文档 tab 视觉重设计 + tab 头间距(2026-08-06,用户拍板"tab 靠太近"、"需求文档页面太丑你优化他")

tab 头间距根因:App.vue 全局 .el-tabs__item{width:4rem!important} 定宽,5 字标题(需求的一生)溢出 63px 盒子与下一个 tab 粘连;另有来历不明的 rem padding 覆盖。修复:.filterInfo 作用域 width:auto!important 解除定宽 + 兄弟选择器 margin-left:16px(绕开 padding 覆盖链)。

需求文档 tab 重设计(数据绑定零改动,测试断言全部保留):六类文档由"白卡片堆叠+hr"改为分节卡片——节标题(蓝色竖条+16px 标题+份数徽章)、文件行(文档图标+文件名悬停变色+灰色小字 操作人·时间+查看/下载)、子分组(测试用例/模版)、卡点提示改 el-alert 风格黄条、审查轮次改蓝色徽章、空态文案统一"暂无附件(由 AI 框架上传)"。

验证:编译 errors=none(生成器脚本四重大括号事故 14 处已修);13 项关键绑定程序化断言无缺;8088 实拍:tab 头间距正常、六分节渲染正确、计数徽章正确(2/1/2/1/2/2 份)。截图 tmp/pw_9130_doctab.png。已同步 F:\zd。

CHG-068 补充(同日):

  • meta 行字段大小写修复:fileList 接口返回 addedby/addeddate(全小写),新旧模板都绑的 item.addedBy/addedDate(驼峰)恒空——老设计空 span 不可见,新设计 meta 行暴露为吊着的孤「·」。改绑正确字段名 + 空值整行不渲染(7 处)。实拍:文件名+「ai · 2026-08-05 17:14」完整对齐。
  • tab 间距收敛:margin-left 16px→6px(用户反馈"间隔又太远"),文本对文本约 31px。

CHG-069 saveScopeJson 登录态 NPE 修复 + 打包(2026-08-06)

根因:ZtPerfReportServiceImpl.saveScopeJson:356 无防御读 RiskUserThreadLocal.get().getName()——该写法一直靠 ThreadLocal 静态初始化块预置 admin 的隐性 quirk 撑着;CHG-061 给 AiBatchAddServiceTest 加的 tearDown clean() 把这个默认值清掉,同线程后续跑的 ZtPerfReportServiceTest 即 NPE(测试顺序依赖暴露)。

修复:①saveScopeJson 空值兜底 "system"(生产侧同样防未来调度线程无登录态 NPE);②ZtPerfReportServiceTest 补 BeforeEach 登录态/AfterEach 清理(测试自给自足)。

验证:ZtPerfReportServiceTest 3/3、AiBatchAddServiceTest 6/6、ZtStoryExpandServiceTest 5/5 全绿。

打包:mvn package -DskipTests → codes/zentao/target/zentao.jar(154MB,2026-08-06 15:54,含 CHG-039~069 全部改动)。


mermaid 发布包缺失修复(2026-08-06,用户报"打包发布到测试环境流程图没有正常显示")

根因:mermaid 三件套(public/mermaid.min.js、index.html <%= BASE_URL %>mermaid.min.js 引用、MdPreview mermaid 渲染逻辑)08-05 会话只加在 codes 副本,F:\zd 副本一直没有——用户从 zd 打发布包,包里无 mermaid。

处理:三件套同步 zd;清 webpack 缓存重打 F:\zd\web_zentao\dist(mermaid.min.js ✓ / index.html head 引用(先于 app bundle,window.mermaid 可用)✓ / MdPreview 代码入 chunk-37091a66、chunk-56c8e14c ✓ 全量搜索证实)。注意点:publicPath='/',mermaid 以 /mermaid.min.js 绝对路径引用,前端须部署在域名根路径。


CHG-070 productPageList 性能修复(2026-08-06,用户报"接口要5秒")

定位(161 实测):产品列表页统计拉的 3 张全量表——zt_story() 3447行/923ms、**zt_bug() 未关闭 954行/7340ms(steps MEDIUMTEXT 共 44MB,均值 46KB/行)**、zt_story_user(*) 2273行/498ms。zt_bug 全字段拉取是唯一主因。

改动:ZtProductServiceImpl.productPageList 三处查询修剪 select 列(story: id/product/status/stage;bug: id/product/status;story_user: id/product/status),统计逻辑零改动。

验证:修剪后 SQL 预演 50/27/93ms;8086 端到端实测 0.49/0.19/0.23s(原约 5s,~20 倍提升),结果集正确(total=10)。已重打 target/zentao.jar(17:02),发布 8015 即可生效。


CHG-071 exportScope 快照三格式兼容(2026-08-06,用户问"exportScope 要按新修改调整吗"+NPE 报错)

根因:zt_month_score.scope_json 三种格式并存——①老 DTO 平铺(弹窗提交时代)②引擎 PerfMonthScope(generateMonthScore)③docCheck 专项(FR-014 扣分合并);exportScope 一律按老 DTO 解析 → 后两种全 null → generatorDevlopExcel 取 delayTask.toString() NPE(luoyong 2026-06=docCheck 格式实锤)。

改动:exportScope 解析改走新助手 resolveScoreDto——引擎格式=新算 DTO 为底+人工项(source=manual)按 score×weight 覆盖;老 DTO 格式=直接反序列化+统计字段缺失从新算回填(backfillStats 13 字段);其他格式=新算 DTO。

验证:8086 导出 2026-06(原 NPE 场景)HTTP 200/13.6s/有效 xlsx——罗勇开发考核表完整渲染(任务 9/超期 2/及时率 88%→8 分、Bug 密度 0→30 分),统计字段齐。已重打 target/zentao.jar(17:28)。

同族遗留:myWorkScore 弹窗对引擎/docCheck 格式快照同样按老 DTO 解析会空值——弹窗出现历史月份空分时同一招修(resolveScoreDto 可直接复用),待用户指示。


CHG-072 myWorkScore 快照分流 + CHG-073 userList 脱敏(2026-08-06,用户拍板"1 2 都做")

CHG-072(exportScope 同族):myWorkScore 拆为薄壳+myWorkScoreCompute——老 DTO 平铺快照维持快路径;引擎/docCheck 格式快照不再按老格式解析(全空),改走新算+人工项以快照覆盖(overlayManualScores 复用)。实测:luoyong 6月(docCheck 快照)修复前全空→修复后 punctualityScore=8/delayTask=2/totalTask=9 等新算值;sunying 5月(老快照)快路径快照值原样。

CHG-073:userList 响应剔除 password 列(MD5 哈希不下发),其余 51 字段全保留兼容。排障:实体 @TableField("\password`")` 列名带反引号,首版按 getColumn() 匹配失效,改按 getProperty() 匹配后实测 password 不再泄露。

打包:target/zentao.jar(2026-08-06 17:54,含 CHG-070~073)。


CHG-074 月报列表达标工时与弹窗对齐(2026-08-07,用户指出"月度达标应该跟详情的一致")

根因:08-05 还原波及 pageMonthReport——月度达标工时退回老个人口径((21×8)×0.75=126),且饱和度分子用 storyTotalTime(estimate);而弹窗 myWorkScore 走团队口径(21×5=105)+实绩 consumed。两处不一致。

改动:pageMonthReport 的 haveTime 改 teamExamineTime(accountIds,...)(在窗 KFZ 人均,无 KFZ 退回个人口径兜底);饱和度分子 storyTotalTime→workTime(实绩)。

验证:8086 实测月报 139/2026-06——全员达标=105.0(与弹窗一致);陈浩 126/105=120%、罗勇 25/105=24%、孙颖 84/105=80%。jar 已重打(17:5x 见时间戳)。


CHG-075 exportScope 静默空响应修复(2026-08-07,用户报"没有文件导出")

根因(双重):①方法尾部 catch(Exception){log.error} 静默吞异常——"未查询到数据"(当月无在窗执行/任务)等异常被吞成空 200,前端拿到 0B 响应即无文件也无提示;②无快照人员 continue 跳过——当月(如 8 月)没人有快照时一个文件都不产。

改动:①BusinessException 重新抛出交全局异常处理器回 JSON(前端弹"未查询到数据"等真实原因),其他异常包装"导出失败";②无快照人员用新算 DTO 导出(自动分+人工满分默认),有快照走 CHG-071 三格式解析。

验证:8086 实测——2026-08+139 返回 JSON 错误(前端可提示)0.4s;2026-06+139 文件 23.5KB→44.4KB(无快照人员补齐,含陈浩表)。jar 已重打。


CHG-076 aiBatchAdd 中文姓名指派映射(2026-08-07,用户拍板"指派中文要查数据库")

改动:aiBatchAdd 建任务前解析 assignedTo——非既有账号时按 zt_user.nickname 查库映射为账号(AI 框架传中文名场景);账号原样、查不到原样保留。需求级留痕文案的指派展示用映射后账号取昵称。

验证:单测+1(中文名映射用例,7/7 绿);8086 实测 assignedTo="罗勇" → 落库 assignedto=luoyong(验证数据已清理)。jar 已重打。


CHG-056 绩效导出换新版式 + 并行改动合并修复(2026-08-10,用户拍板"改")

导出换新版式:9 份新模版(9 岗位 sheet 全量,含王宇航变体/前后端分离/新增运维)由 tmp/make_perf_templates.py 从 SRC-002 xlsx 生成(占位符 {name}/{date}/{得分键}/{total}/detail_*);IZtCountService 7 个 generator 重写(新键名+devDirection 分流前后端模版+perfRawDetail 明细入「绩效数据」列)、新增 generatorYwExcel + exportScope YW 分支、helper(scoreStr/scoreTotal/perfDetail 等)。

排障两个坑:①openpyxl 生成的 xlsx 是 inlineStr 单元格,POI setCellValue 会残留旧 <is> 内联串导致读回旧值(占位符零替换)→ writeXlsx 先 setCellType(BLANK) 再写值修复;②并行改动撞车:另一会话在 IZtCountService 上做了"选中产品集 KFZ 成员"口径(buildKFZScore 加 accountIds 参数+fillTeamExamine(accountIds)),但底版偏旧,把 CHG-036/038(PerfScoreRules 算分、前后端分流)与 CHG-054/055(testStoriesOf/检出率赋 0)覆盖丢失 → 已全部合并还原(保留 accountIds 团队口径新逻辑,恢复 PerfScoreRules 算分+devDirection+testStoriesOf+显式 0 分),补回 PerfScoreRules import;pom.xml 的 surefire skipTests 硬编码块(为绕 AOT 报错加的)已移除(lombok 1.18.34 已治本)。

验证:单测 92 全绿(surefire 恢复可跑);8086 实测——郭尚雨 devDir=backend/docQ=10/饱和 20、孟冉 devDir=frontend/无文档质量项、孙颖检出率显式 0;导出全量 28 sheet 无残留占位符,孙世超 sheet 得分+明细全对(20/30/4/10/0/5/10/5,总 84),孟冉前端模版无文档质量行,郭尚雨后端 sheet 总分 100。

注意:①王宇航 sheet 走变体模版(无 PRD 行);②岑海峰 6 月不在窗口执行内不出 sheet(7 月起正常);③导出列路径(exportScope)不读 zt_month_score 快照、实时算;④8085 需重编译重启+前端发版。


CHG-057 CS 测试文档齐备改实时字段判定(2026-08-10,用户拍板口径)

口径(用户定):范围=zt_story_expand.test_person 指定 ∪ assignedTo 且本月发布的需求(复用 CHG-054 testStoriesOf);判定=test_case_url(用例)+ test_report_submit_url(提交件,AI 模版 testReportDownload 不计)非空;每缺一份扣 3 分(25 分项直接扣完截止);本月无需求→满分 25。

改动:buildCScore 弃写死 25,实时遍历 testedStory 两个 url 字段计数,documentQualityProblem=缺失数透出展示。

8086 实测:孙颖 6 月 缺失 46(23 需求×2)→ 0;孙庆方 缺失 34 → 0(2026 库这些需求确实没人传测试文档,非误判);孙颖 2025-12(无测试需求月)→ 满分 25 ✓。8085 需重编译重启。

注:引擎的 TestDocReadyCalculator(快照版,归属按 account 匹配中文名列本就失效)自此彻底废弃,仅 CS 弹窗路径生效;原 CS 弹窗「测试文档」行 data 绑定 documentQualityProblem(问题个数)直接显示缺失份数。


CHG-058 需求文档拆独立区块 + 前端改动恢复(2026-08-11,用户拍板"可以加类型/入口处改/顺带前端")

改动:FileTypes 增 storyPrd("storyPrd","需求文档");uploadBind 刷新 prd_url(storyPrd 与 story 同字段);upload_md.py VALID_TYPES+用法注释(需求文档一律 storyPrd,story 保留给手动附件,互不影响他人接入);storyinfo/product.vue「需求文档」归位到右侧「需求文档」tab 顶部 section(复用 dc0b5a5 doc-sec 版式),无上传按钮、纯 AI 框架上传,空态文案"暂无附件(由 AI 框架上传)"。6566 实测:上传→prd_url 刷新→fileList 返回→tab 渲染;9130 需求文档已传(zt_file 8824,内容由 zt_storyspec 真实 spec 生成,curl GBK 乱码 title 已 SQL 修正),截图 tmp/pw_9130_prd_tab。已同步 F:\zd\web_zentao。

并行会话撞车处置:郭其兵 08-11 13:10 提交 dc0b5a5「新版绩效」(main_2026 分支),收编了我 13:10 前的前端工作(CHG-036~053/046/会议等)+他自己的三期绩效页面(views/perf/*);工作区被切到该提交后,我 14 点的 CHG-058 前端编辑(未提交)丢失 → 从 F:\zd\web_zentao(14:16 同步版)拷回 product.vue,diff 验证恰好是 CHG-058 那 49 行、无其他损失。codes/web_zentao 当前状态=dc0b5a5 + product.vue(M, CHG-058),建议尽快提交避免再次被冲。

环境备忘:用户的 8085 IDE 后端与我的 8086 当前都连 zentao_dev_2026(IDE run config 带 2026 覆盖);8088 前端由用户在 codes/web_zentao 启动。生产 itsm 未动。


CHG-077 uploadBind 入口 story→storyPrd 归一化 + 8 需求错传数据修复(2026-08-17,用户拍板"改"+"一起")

起因:200 库 9209 用户报"上传的 md 落到了附件"。排查实证:AI 通道把 PRD/验收标准用 objectType=story 调 uploadBind(zt_action 留痕"上传需求"),而「需求文档」区块只认 storyPrd(product.vue fileFieldMap);且 refreshOwnerUrl 中 story 与 storyPrd 同写 prd_url,last-write-wins 致 prd_url 被后传的验收标准覆盖。误用源头:对外接口文档 §5.2 只列 story 未列 storyPrd(CHG-058 只改了 upload_md.py 客户端,管不住外部调用方)。

改动:UploadDTO 增 normalizeObjectTypeForBind()(story 归一 storyPrd);CommonsController.uploadBind 校验后调用,一处生效(refreshOwnerUrl 与 zt_file 落库同读 DTO)。原生两段式上传不受影响(UI 手动附件不走 uploadBind,前端全项目无 story 传参)。

单测:新增 UploadBindNormalizeTest 4 条(story→storyPrd / storyPrd 不变 / 其他类型不变 / null 安全);回归 UploadBindRefreshOwnerUrlTest 13 条。17/17 绿。

200 库数据修复(已提交回读验证):18 条 ai 误传 story 文件改 storyPrd(9143×4/9179×3/9180×1/9208×2/9209×2/9213×2/9226×2/9238×2);8 需求 prd_url 从"验收标准"校正回 PRD/需求说明/需求文档(9143→9395、9179→9343、9180→9335、9208→9435、9209→9428、9213→9416、9226→9404、9238→9397 的 url)。

待办:代码改动在本地 codes/zentao,需郭其兵提交+部署后归一化才在线生效;对外接口文档 §5.2 仍只列 story——归一化上线后文档与行为一致,可不急改。


CHG-078 用户需求导出/分页加「迭代版本」列(2026-08-17,用户拍板)

需求:/zt-story-user/export 与 pageList 加迭代版本列,参照分页列表 execList 字段,只要迭代名称、多迭代拼接。

现状:列表页已有该列(userstory/product.vue 用 execList 渲染);缺口在导出(execList 标 @ExcelIgnore)。

改动:ZtStoryUserDTO 增 execNames(@ExcelProperty "迭代版本" index=5,后续列 index 顺移+1);ZtStoryUserServiceImpl 增静态 buildExecNames(名称去重排序逗号拼接,空→null),pageList 与 storyListByProductId 两处填充点接入。前端零改动。

单测:BuildExecNamesTest 4/4 绿(多迭代拼接/单迭代/空/空白名过滤)。

待办:代码在本地 codes/zentao,需郭其兵提交+部署生效。


CHG-079 modifyTask 后端权限校验:创建人/项目管理员/admin(2026-08-28,已撤销——用户拍板"后端不用改")

背景:代码勘察发现 /zt-task/modifyTask 后端无任何归属/角色校验(前端仅按钮显隐控制:openedby 本人 或 XMGLY/GSGC),任何登录用户可直调接口改任意任务——而 estimate/left/consumed 是绩效算分输入,存在越权篡改风险。

改动:ZtTaskServiceImpl.modifyTask(selectById 判空后)加门禁:当前用户为 admin、任务 openedby 本人、或 userType==XMGLY(项目管理员)三者其一放行,否则抛"仅任务创建人或项目管理员可修改任务"。原有的状态卡点(cancel/closed/done 拒改)与 KFZ 评审流转不受影响。

口径说明:①GSGC(公司高层)未纳入后端白名单——用户本次只点名项目管理员,前端 GSGC 按钮(doing/wait 可编辑)与后端将不一致,如需放开再说;②ai 创建的任务 openedby=ai,此后仅项目管理员/admin 可改;③startTask 原有的指派人校验、aiBatchAdd/saveOrUpdate 的 ai 门禁均不受影响。

验证:JDK17 mvn compile BUILD SUCCESS。未写单测(modifyTask 为重 DB 依赖方法,现测试体系无对应基建)。

待办:8085 需重编译重启生效;代码需郭其兵提交部署(同 CHG-077/078 一并)。

撤销记录(同日):用户确认后端不用改(modifyTask 加门禁会挡住前端已放开的 GSGC 编辑 doing/wait 等既有路径,回归风险>收益),代码已还原,编译状态回到改动前。


CHG-080 任务编辑放开 XMJL 项目经理(前端,2026-08-28,用户拍板"项目经理也可以修改、只用改前端")

背景:任务编辑按钮的角色白名单此前只有 XMGLY(项目管理员)/GSGC(公司高层),XMJL(项目经理,如孙世超)在全前端都改不了别人创建的任务。用户确认后端不动(CHG-079 已撤销),仅放前端。

改动(三处,编辑按钮 userType 白名单加 XMJL):

  1. implement/task/components/product.vue:312(研发任务列表)
  2. territory/task/components/product.vue:321(地盘任务列表)
  3. implement/taskinfo/components/product.vue:608(任务详情页)——顺带修笔误:waiting(不存在的状态)→ wait,否则详情页 XMJL/XMGLY 对 wait 状态任务仍无编辑入口(与列表页口径不一致)

未动:implement/look/tab/content.vue 编辑菜单项本就无角色门槛(仅 task-edit 权限键);testtask 页无角色限制。前提:XMJL 角色的菜单权限需含 task-edit 键(BaseRoleAuthority 数据配置),无键则按钮仍不显示。

同步:三文件已同步 F:\zd\web_zentao(diff 核对仅本次改动)。

待办:8088 前端热更新/重启生效;代码需随 CHG-077/078 一并提交。


CHG-082 aiBatchAdd 放行 affair 事务任务(后端,2026-09-16,用户拍板"就事务 开始开发")

背景:AI 拆批接口 /zt-task/aiBatchAdd 的类型白名单原为 devel/test(后 CHG-081 放行 design,未入本档)。事务型任务(affair)此前传参会整批拒绝 任务类型仅支持devel/test/design:affair。

改动(两处 + 测试):

  1. ZtTaskServiceImpl.java:1382-1390:白名单加 TaskType.affair,报错文案同步为 devel/test/design/affair
  2. ZtTaskAiBatchDTO.java:26:type 注释补 affair
  3. AiBatchAddServiceTest:新增 aiBatchAdd_affair_createsTask(仿 design 用例,断言留痕显示「事务」);aiBatchAdd_illegalType_rejectsAll DisplayName 同步

已核对不受影响(affair 与 design 同路径,天然隔离):

  • 需求计划时间回写:batchAddTask:1314-1324 只对 devel/test 回写,affair 跳过
  • 绩效专项公式:取数按类型显式过滤(如 IZtCountService.java:1256 只查 type="devel"),affair 不进
  • 需求级留痕:ZtTaskServiceImpl.java:1471 按 TaskType 枚举动态取中文名,affair 自动显示「事务」
  • 看板挂载:ZtKanbanlaneServiceImpl.addTask 按任务状态分列,与类型无关

已知行为(与 design 一致,用户已知情):

  • 需求状态联动 taskFinishChangeStatus else 分支(ZtStoryServiceImpl.java:1623-1645):需求下无活跃 devel/test 任务时,affair 任务会把需求看板列置 backlog/ready
  • 指派 affair 任务会触发微信指派通知(taskSendZpMessage,与类型无关)

验证:mvn test -Dtest=AiBatchAddServiceTest → 10/10 通过(JDK 17)。


CHG-083 三个统计接口性能优化(后端,2026-09-16,用户要求"不要影响老的代码/其他业务,先留存正线数据再比对")

背景:/zt-project/projectTeamTimeWork、/count/storyBarChart、/count/bugBarChart 正线耗时 7~19s。

根因:

  1. 两个柱状图在 6 个月循环内每月调用全量绩效 newPerformanceCount(全岗位算分、逐人 bug/审批/文档查询),而图表只用 KFZ 成员的 allocationTime/examineTime 两个字段;
  2. storyBarChart 逐月 userMapByIds(null) 全用户表扫描 ×6、allProductList() ×6、逐用户 filter 任务全表;
  3. projectTeamTimeWork 任务查询无日期条件捞全量历史、全用户表扫描、天数×人数×任务数三层 O(n³) 扫描。

改动(老共享方法 newPerformanceCount/fillTeamExamine/getApprovalTime 等一行未动,其他业务路径不受影响):

  1. IZtCountService 新增私有 kfzMonthTimesLite():复刻图表实际消费口径(成员集合同 newPerformanceCount 798-840 行;allocationTime 同 buildKFZScore 的 Σestimate 剔除 closed/cancel;examineTime 团队人均口径公式同 fillTeamExamine),跳过无关算分;任务按指派人预分组
  2. 新增批量请假查询 ZtTaskMapper.itApprovalsByNames(XML 条件与 itApprovalByUserName 完全一致,name 改 IN;老 SQL 未动)+ IZtTaskService/ZtTaskServiceImpl 透传——原逐人逐月跨库查 os_system.it_approval(date() 函数不走索引,约 人数×6 次),现每月 1 次
  3. storyBarChart:allProductList 提出循环按需取一次;多部门成员实绩工时按指派人预分组(floatBatchAdd 两位精度口径保持一致)
  4. bugBarChart:仅需 allocationTime,needExamine=false 跳过达标工时/请假计算
  5. ZtProjectServiceImpl.projectTeamTimeWork:任务 SQL 加 estStarted 当月范围(按天循环本就只匹配当月任务,口径不变);用户表只查团队成员∪任务相关人(原全表);任务按 yyyy-MM-dd#账号 预分组替代三层扫描

验证(证据:F:\zentao\1\PM\perf-snapshots\20260916\):

  • 留存正线基线(8013,老代码)→ 本地起新代码直连正线库(application-local.yml 用户已指向 192.168.3.200/zentao_dev)→ 同一时刻背靠背比对:
    • storyBarChart:16.6s → 3.9s,data IDENTICAL
    • bugBarChart:14.1s → 1.1s,data IDENTICAL
    • projectTeamTimeWork:6.9s → 0.12s,data IDENTICAL
    • 对照组 monthScopeByProgram(未改动路径):IDENTICAL,耗时不变(4.1s vs 4.9s)
  • 单测 103/103 通过(JDK 17)
  • 中途插曲:增量编译导致 v2 实例 baseMapper 绑定异常(NPE),clean compile 后消失;8085 dev 库与正线库数据不同,8085 基线仅用于过程验证

注意:本地验证期间本地实例曾直连正线库运行约 15 分钟(只读接口验证),已关停。