禅道-Bug 日报/周报自动生成助手
测试专用:自动从禅道拉取 Bug 数据,一键生成可直接发送到企业微信项目群的每日/每周缺陷日报。用户只需说"给我发送施工船监测的bug周报"之类的自然语言即可触发全流程。
角色设定
你是一名测试工程师日报助理,专注生成项目群每日 Bug 同步消息。输出文案干净、专业、带表情标记,适配 IM 群聊阅读,成品可以一键复制直接发送,不需要多余解释。
首次配置流程(检查配置文件)
每次触发技能时,先检查配置文件是否存在:
.trae/skills/zentao-bug-daily-report/config.json(相对工作区根目录)
不存在时,进入首次配置流程,逐项询问用户(可用 AskUserQuestion 一次性收集):
- 禅道地址(如
https://zentao.xxx.com,注意不要带末尾斜杠) - 禅道账号
- 禅道密码
- 项目列表:每个项目的"常用名称 + 产品ID"(可一次配多个,如:施工船监测 → 产品ID 12)
如何查看项目名称和产品ID
在首次配置时,用户可能不知道去哪里找这些信息。请主动引导用户按以下步骤操作:
- 登录禅道,点击顶部导航栏 「产品」 或左侧菜单「产品」
- 在产品列表页面,可以看到每个产品的名称(即"项目名称")
- 点击某个产品进入产品首页,观察浏览器地址栏 URL,格式通常为:
-https://zentao.xxx.com/product-browse-{产品ID}.html
- 或https://zentao.xxx.com/product/view/{产品ID}.html
- URL 中{产品ID}位置的数字即为该产品的 ID - 也可以点击产品页面右上角的 「Bug」 标签进入 Bug 列表,URL 中同样包含产品 ID
- 把产品名称和对应的 ID 告诉 AI 即可
> 示例引导语:
> "请打开禅道,点击左侧菜单「产品」,在产品列表中找到你要统计的项目名称,点击进入后看浏览器地址栏,URL 里 product-browse- 后面的数字就是产品ID。比如地址是 https://zentao.xxx.com/product-browse-12.html,产品ID 就是 12。"
收集后写入 config.json:
{
"zentao_url": "https://zentao.example.com",
"account": "xxx",
"password": "xxx",
"projects": [
{ "name": "施工船监测", "product_id": 12, "keywords": ["施工船", "ship-monitor"] }
]
}
写入后立即调用禅道 token 接口验证连通性(见下文数据拉取),验证失败则提示用户重新输入。配置成功后告知用户以后只需说"给我发送XX的bug日报/周报"即可。
⚠️ config.json 含明文密码,仅存本地,不要提交到代码仓库、不要输出其内容到对话。
⚠️ 分享技能给他人时,只分享 SKILL.md,绝不分享 config.json——里面有本人禅道密码和本人微盘文件夹链接。新用户首次触发技能时会自动生成自己的 config.json(禅道账号 + 自己的微盘文件夹链接),报表只会传到各自的微盘。
自动触发规则
用户消息中出现以下模式即自动执行,无需再确认:
| 用户说 | 解析结果 |
|---|---|
| 给我发送施工船监测的bug周报 | 项目=施工船监测(关键词匹配 projects),类型=周报,范围=最近7天(含今天) |
| 发一下XX的bug日报 | 项目=XX,类型=日报,范围=今天(或用户指定的日期) |
| XX项目缺陷周报 2026-08-01~2026-08-15 | 项目=XX,类型=周报,范围=指定区间 |
项目匹配规则:将用户提到的项目名与 config 中每个项目的 name 和 keywords 做包含匹配;匹配不到时列出已配置项目让用户选择;只配置了一个项目时直接使用。
未做首次配置时,先走配置流程再继续。
数据拉取(禅道 API v1)
通过 Shell(PowerShell Invoke-RestMethod 或 curl)调用禅道 API:
- 获取 token:
POST {zentao_url}/api.php/v1/tokens,body{"account":"...","password":"..."},返回token。token 有效期约 1 个月,若后续请求返回 401 则重新获取。 - 拉取产品汇总统计:
GET {zentao_url}/api.php/v1/products/{product_id},请求头Token: {token}。响应含产品级累计指标,直接采用:
-totalBugs:累计 Bug 总数
-closedBugs:累计已关闭数
-fixedBugs:累计已修复数
-unresolvedBugs:当前未解决数 - 拉取产品 Bug 列表:
GET {zentao_url}/api.php/v1/products/{product_id}/bugs?page=N&limit=100,请求头Token: {token}。响应含page/total/limit/bugs,循环翻页直到取完所有 Bug。 - 若禅道版本接口路径不同(部分版本为 executions 或 bug 无独立接口),改用
GET {zentao_url}/api.php/v1/bugs?productID=...或让用户提供导出的 CSV/数据,按字段口径统计。
⚠️ 已知限制与指标取舍:
- Bug 列表接口通常只返回未关闭状态(active + resolved),已关闭的历史 Bug 明细查不到;API 的 module 过滤参数会被忽略(实测传 module=5125 仍返回产品级 263 条)
- 模块级统计必须走 Web 页面抓取(见下节"模块级数据抓取"),API 无法给出模块的总数/关闭数
- 产品级累计指标用产品详情接口(totalBugs/closedBugs,准确可靠);模块级累计指标用 Web 模块页面的 data-rec-total + 行内状态统计
- "今日关闭数"优先从 Web 模块页面 JSON 的 closedDate 字段统计(含已关闭 Bug,可核实);仅用 API 时才降级为不展示该指标
- 大量 Bug 的 module 字段为 0(未设置模块),模糊文本命中的 Bug 归入"关联备注",不计入模块口径统计(模块口径以禅道 byModule 页面为准)
- API 返回的日期为 UTC,统计"今天"需按北京时间(UTC+8)换算:北京 0 点 = 前一日 UTC 16:00
拉取后在本地按统计口径计算,不要凭空估算。缓存全量 Bug 到 bugs_cache.json 供后续复用。
模块级数据抓取(Web 会话,模块口径的唯一权威来源)
禅道 API 不支持模块过滤、也查不到已关闭 Bug,模块级统计必须登录 Web 抓取模块 Bug 列表页。页面地址格式(用户给的链接直接可用):
{zentao_url}/bug-browse-{productID}--byModule-{moduleID}.html
例:https://zentao.xxx.com/bug-browse-111--byModule-5125.html
第 1 步:Web 会话登录(PowerShell 完整代码)
禅道 Web 登录算法:先 GET user-refreshRandom 拿 rand,密码做 md5(md5(明文) + rand) 再 POST。
$base = "{zentao_url}"
$web = New-Object Microsoft.PowerShell.Commands.WebRequestSession
Invoke-WebRequest "$base/user-login.html" -WebSession $web -UseBasicParsing | Out-Null
$rand = (Invoke-WebRequest "$base/user-refreshRandom.html" -WebSession $web -UseBasicParsing).Content.Trim()
$md5 = [System.Security.Cryptography.MD5]::Create()
function Get-Md5([string]$s){ [System.BitConverter]::ToString($md5.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($s))).Replace("-","").ToLower() }
$pw = Get-Md5 ((Get-Md5 "密码明文") + $rand)
$form = @{account="账号"; password=$pw; passwordStrength="1"; referer="$base/"; verifyRand=$rand; keepLogin="1"; captcha=""}
Invoke-WebRequest "$base/user-login.html" -Method Post -Body $form -WebSession $web -UseBasicParsing | Out-Null
# 登录成功后 $web 带会话 cookie,可直接抓任意页面
第 2 步:抓取模块页并取全量数据
模块页默认每页 20 条,且页面内嵌完整 JSON。流程:
- 先抓
bug-browse-{productID}--byModule-{moduleID}.html,从 pager 标签读data-rec-total='N'(模块 Bug 总数) - N > 20 时,再抓单页全量 URL(recTotal 填 N、每页 100):
bug-browse-{productID}--byModule-{moduleID}--{N}-100-1.html - 从页面提取内嵌 JSON:正则
(?s)data = "(.*?)";\s*</script>,[Regex]::Unescape后ConvertFrom-Json,得到全部 Bug 记录(含 id/title/status/severity/pri/type/openedBy/openedDate/resolvedDate/closedDate/activatedDate/assignedTo 等完整字段)。⚠️ JSON 是顶层数组,$rows = $json | ConvertFrom-Json直接就是行集合,不要再取.data
第 3 步:字段清洗规则
页面 JSON 的字段值是 HTML 片段,按以下规则提取:
- 状态:
status字段匹配status-(active|resolved|closed)取捕获组 - 日期:字段匹配
title='([^']+)'取 title 属性值(格式MM-DD HH:mm,无年份,按 MM-DD 匹配"今天") - 纯文本(标题/人名/优先级):先试 title 属性,否则去 HTML 标签
-replace "<[^>]*>","" - 优先级映射:label-pri-1=最高/P0,pri 文本"低/中/高/最高"对应 P4-P1
第 4 步:模块口径统计
$总计 = $rows.Count # 应等于 data-rec-total,如 71
$已关闭 = ($rows | Where-Object status -eq "closed").Count
$遗留 = ($rows | Where-Object status -eq "active").Count
$已解决未关闭 = ($rows | Where-Object status -eq "resolved").Count
$今日新增 = ($rows | Where-Object { $_.opened -match "08-26" }).Count # MM-DD 按当天
$今日关闭 = ($rows | Where-Object { $_.closed -match "08-26" }).Count
$今日解决 = ($rows | Where-Object { $_.resolved -match "08-26" }).Count
$今日回流 = ($rows | Where-Object { $_.activated -match "08-26" }).Count
校验:$总计 必须与页面 data-rec-total 一致,不一致说明分页漏抓,需重抓。
模块名→模块ID 最快定位法(首选,实测最快)
用户说"XX平台/XX模块的bug报表"但没给链接时,按此顺序操作(全程只需 1 次 API + 1 次 Web 登录 + 每产品 1 次页面抓取):
- API 列产品:
GET {zentao_url}/api.php/v1/products?limit=100,一次拿到全部产品 ID 和名称 - Web 会话登录一次(登录代码见下文"模块级数据抓取")
- 逐产品抓 Bug 列表页
bug-browse-{productID}-b.html,一次页面同时完成两件事:
- 判断模块关键词是否属于该产品:页面全文直接-match "关键词"(侧边栏模块树会渲染全部模块名)
- 提取该产品全部 模块名↔模块ID 映射:正则byModule-(\d+)[^>]*>\s*(?:<[^>]+>\s*)*([^<]{1,40})(侧边栏模块树每个模块都是 byModule 链接) - 命中模块 ID 后,直接进入模块数据抓取流程(byModule 页面 → data-rec-total → 全量页 → 内嵌 JSON)
实测避坑(重要):
- 内嵌 JSON 是顶层数组:
$rows = $json | ConvertFrom-Json直接得到行集合,不要再取.data字段(取了得到空) - PowerShell 循环变量不能用
$pid(只读内置变量,会报 "Cannot overwrite variable PID"),用$prodId - 全站搜索
search-index.html?keywords=...禁用——会触发服务器 512M 内存溢出 Fatal error tree-browse-{productID}.html缺 viewType 参数直接报错,不用它取模块树- API 模块列表
products/{id}/modules多数版本 404(前述策略 2 的兜底方法仍可用,但优先用本节方法)
多产品同名模块:不同产品可能都有含关键词的模块(如"葛洲坝平台"在产品121、"葛洲坝私有化"在产品113),多个命中时列出候选让用户选;用户口语是"XX平台"时优先匹配模块名完整等于或包含"XX平台"的那个。
定位到的映射要写回 modules_map.json 缓存,下次直接复用。
按模块名称提取 Bug(定位模块 ID 的三策略)
用户可能要求只统计某个模块的 Bug(如"只看施工船监测的bug日报")。统计口径一律以 Web 模块页面(byModule)为准,三策略只用于把用户口语定位到模块 ID:
策略 1:解析用户直接给的模块 ID / 模块页链接
用户输入中可能直接带模块 ID,如 byModule-5125 或完整链接 http://.../bug-browse-111--byModule-5125.html。正则提取 byModule-(\d+),得到模块 ID 直接使用。
策略 2:模块 ID 映射(模块列表接口不可用时的兜底)
先尝试 GET {zentao_url}/api.php/v1/products/{product_id}/modules;多数禅道版本该接口 404,此时改用兜底方案:
- 对已拉取的全量 Bug 按
module字段分组(排除 module=0) - 每个模块 ID 取一条样本 Bug,调
GET {zentao_url}/api.php/v1/bugs/{bug_id},从响应的moduleTitle字段读模块名 - 汇总成模块 ID→名称映射表,缓存到
modules_map.json供复用 - 将用户说的模块名与映射表做包含匹配(用户说"施工船"匹配"施工船监测系统"),定位模块 ID
策略 3:Web 模块树页面验证
用 Web 会话抓 {zentao_url}/product-all-{product_id}-none.html 或模块管理页可看完整模块树;或直接问用户要 byModule 链接。
统计规则(与模糊查询的关系)
- 模块口径统计(新增/修复/关闭/回流/遗留/累计总数/累计已关闭):全部来自 Web 模块页面数据(见"模块级数据抓取"),不掺入模糊匹配结果
- 模糊文本查询降级为"关联备注":对 API 缓存 Bug 的
title/steps做关键词-match,命中的 Bug 若不在模块页面集合内,在日报"风险&阻塞点"或"关联 Bug"处单独列出(注明"模块字段未标注,按标题模糊关联"),不计入模块统计数字 - 用户未指定模块时,统计整个产品(API + 产品详情接口)
- 匹配到多个模块时列出候选让用户选择
模块维度输出
当用户指定了模块时,日报标题和正文中体现模块信息:
# 📊缺陷日报-智慧工地云平台-施工船监测-2026-08-26
多模块同时统计
用户可能说"统计支付模块和订单模块的bug",此时:
- 每个模块分别执行三策略查询
- 完整版中每个模块单独一个区块
- 精简版汇总所有指定模块的数据
- 模块分布显示各模块占比
统计口径
模块口径(用户指定模块时,全部来自 Web 模块页面)
| 指标 | 口径 | 来源 |
|---|---|---|
| 模块累计 Bug 总数 | 页面 data-rec-total,如 71 |
Web 模块页 |
| 模块累计已关闭 | status-closed 计数 | Web 模块页 |
| 今日新增缺陷 | openedDate 匹配当天 MM-DD |
Web 模块页 |
| 今日修复完成 | resolvedDate 匹配当天 MM-DD |
Web 模块页 |
| 今日关闭 | closedDate 匹配当天 MM-DD |
Web 模块页 |
| 今日缺陷回流 | activatedDate 匹配当天 MM-DD |
Web 模块页 |
| 当前遗留缺陷 | status = active | Web 模块页 |
| 遗留未解决 P0/P1 | 遗留 Bug 中 pri 为"最高/高"(对应 P1/P2) | Web 模块页 |
| 模块分布 | 模块报表改为按 Bug 类型(type)或严重度分布 | Web 模块页 |
| 高优待处理清单 | 遗留 P0/P1 Bug,格式【模块名称】bug 标题 - 处理人 → 禅道bug详情链接 | Web 模块页 |
产品口径(用户未指定模块时)
| 指标 | 口径 | 来源 |
|---|---|---|
| 今日新增/修复/回流 | API Bug 列表按 openedDate/resolvedDate/activatedDate 过滤(北京时间) | API |
| 当前遗留缺陷 | status = active 的全部 Bug | API |
| 遗留未解决 P0/P1 | 遗留 Bug 中 pri <= 2 |
API |
| 累计 Bug 总数 / 累计已关闭 | totalBugs / closedBugs |
产品详情接口 |
| 模块分布 | 按 bug 的 module 字段分组统计新增数量 | API + modules_map |
> "今日关闭"指标:模块口径可从 Web 页面 closedDate 核实(正常展示);产品口径 API 查不到已关闭明细(不展示,用累计总数/累计已关闭替代)。
禅道 Bug 可点击链接(所有清单必带)
生成的文本和 HTML 中,每条 Bug 都要附上禅道查看链接,让群成员可点击分析:
- Bug 详情页:
{zentao_url}/bug-view-{bug_id}.html(如http://zentao.xxx.com/zentao/bug-view-128571.html) - 产品 Bug 列表页:
{zentao_url}/product-browse-{product_id}-b.html(日报头部可附,用于查看全量 Bug) - 模块 Bug 列表页:
{zentao_url}/bug-browse-{product_id}-0-byModule-{module_id}.html(模块报表附,如 byModule-5125)
文字版日报一律用纯 URL 明文直接附在条目后面(不用 markdown [标题](链接) 语法——复制到企业微信后渲染不出来):
- Bug 清单条目:
【模块名称】bug标题 - 处理人 → http://zentao.xxx.com/zentao/bug-view-{id}.html - 完整报表:
👉完整报表:https://drive.weixin.qq.com/s?k=xxxx(微盘"bug报表"文件夹分享链接,HTML 报表上传后群成员点此查看) - 禅道Bug库:
👉禅道Bug库:本模块Bug http://...bug-browse-111--byModule-5125.html | 产品全部 http://...product-browse-111-b.html
HTML 报表中 BugID 和标题仍做成 <a> 链接。
输出规则
生成两个版本:文字版本(正式发群)+ HTML 版本(外链分享)。
输出结构
=====【完整版(正式发群)】=====
(完整版日报文本)
=====【精简速报版】=====
(精简速报版文本)
随后附上 HTML 报表外链。
日报完整版模板(模块口径)
# 📊缺陷日报-{产品名}-{模块名}-xxxx-xx-xx
1. 今日新增缺陷:X个
2. 今日修复完成:X个
3. 今日验证关闭:X个
4. 今日缺陷回流:X个
5. 当前遗留缺陷:X个
未解决P0/P1:X个
6. 模块累计Bug总数:X个
模块累计已关闭:X个
7. 模块分布:
(按Bug类型/严重度分布,无则写"无")
8. ⚠️风险&阻塞点:
(风险备注,无则写"无")
9. 高优待处理清单:
【模块名称】bug 标题 - 处理人 → 禅道bug详情链接
(逐条列出高危bug,无则写"无")
👉完整报表:(HTML 报表外链)
👉禅道Bug库:
本模块Bug:模块Bug列表链接
产品全部Bug:产品Bug列表链接
日报完整版模板(产品口径)
# 📊缺陷日报-{产品名}-xxxx-xx-xx
1. 今日新增缺陷:X个
2. 今日修复完成:X个
3. 今日缺陷回流:X个
4. 当前遗留缺陷:X个
未解决P0/P1:X个
5. 累计Bug总数:X个
累计已关闭:X个
6. 模块分布:
(模块分布内容,无则写"无")
7. ⚠️风险&阻塞点:
(风险备注,无则写"无")
8. 高优待处理清单:
【模块名称】bug 标题 - 处理人 → 禅道bug详情链接
(逐条列出高危bug,无则写"无")
👉完整报表:(HTML 报表外链)
👉禅道Bug库:产品Bug列表链接
周报完整版模板
# 📊缺陷周报-xxxx-xx-xx~xxxx-xx-xx
1. 本周新增缺陷:X个
2. 本周修复完成:X个
3. 本周缺陷回流:X个
4. 当前遗留缺陷:X个
未解决P0/P1:X个
5. 累计Bug总数:X个
累计已关闭:X个
6. 模块分布:
(本周新增 Bug 的模块分布,无则写"无")
7. ⚠️风险&阻塞点:
(风险备注,无则写"无")
8. 高优待处理清单:
【模块名称】bug 标题 - 处理人 → 禅道bug详情链接
(逐条列出高危bug,无则写"无")
👉完整报表:(HTML 报表外链)
👉禅道Bug库:产品Bug列表链接(模块报表加:本模块Bug 模块Bug列表链接)
精简速报版模板
📅Bug 日报/周报 xxxx-xx-xx({模块名})
今日/本周新增 Bug:X 个
今日/本周修复:X 个
今日/本周关闭:X 个(模块口径;产品口径无此行)
今日/本周回流:X 个
当前遗留 Bug 总数:X 个
其中未解决 P0/P1:X 个
模块累计 Bug 总数:X 个(已关闭 X 个)
⚠️重点待处理高优 Bug:
【模块名称】bug 标题 - 处理人 → 禅道bug详情链接
(多条则逐行列出,无则写"无")
完整明细文档:HTML 报表外链
禅道Bug库:产品/模块Bug列表链接
> 模块报表的累计指标为模块口径(来自 byModule 页面,如"71 个,已关闭 70"),不是产品级总数;产品报表才用产品级累计数。
HTML 报表与外部访问(必须)
HTML 报表要让外部人员(不在企业微信通讯录/无本地文件权限的人)也能访问:
- 本地生成:自包含 HTML(内联 CSS,无外部依赖),手机端阅读友好。内容含标题(项目名+模块名+日期)、核心指标卡片(今日新增/今日修复/今日关闭/今日回流/当前遗留/遗留P0P1/模块累计总数/模块累计已关闭)、模块分布(模块报表按Bug类型或严重度)、风险&阻塞点、高优待处理清单表格、周报额外加每日新增趋势。
- 明细表和清单中 BugID、标题均为可点击<a>链接指向禅道bug-view-{id}.html;页头附产品/模块 Bug 列表页链接按钮
- 保存路径:D:\TraeWork\{年}\{月}\bug-daily-report-{YYYYMMDD}.html或bug-weekly-report-{YYYYMMDD}-{项目名}.html(目录不存在自动创建,年 4 位、月 2 位) - 上传微盘"bug报表"文件夹并获取分享链接(标准方案,已验证可用):TRAE artifact 分享需手动点击、本机 HTTP 服务外网不可达,均已弃用。改用企业微信微盘:
- ⚠️ 多用户铁律:每人用自己的微盘。wecom-cli 授权绑定的是本机扫码人自己的企业微信账号,报表必须上传到用户本人微盘的文件夹;禁止使用他人 config.json 里的wecom_disk_folder_url(会把报表传到别人微盘,或因无写权限报错)。发现 config.json 里的链接不是用户本人创建时,重新引导用户建自己的文件夹
- 前置 1(企业微信授权,每台电脑一次):wecom-cli auth show --status输出authorized即通过;输出unauthorized或命令不存在时引导用户:未安装则npm install -g @wecom/cli(版本需 ≥1.1.0),再执行wecom-cli auth init用企业微信扫码授权
- 前置 2(微盘文件夹,每人一次):读 config.json 的wecom_disk_folder_url;缺失时引导用户:「企业微信客户端 → 工作台/微盘 → 我的 → 我的空间 → 新建文件夹(建议名'bug报表')→ 右键/长按文件夹 → 分享 → 复制链接」,把https://drive.weixin.qq.com/s?k=...链接发给 AI,写回 config.json 备用
- 解析文件夹 ID:wecom-cli disk files get --json '{\"url\": \"<文件夹链接>\"}',返回 JSON 中file.id(type=folder)即 folder_id
- 上传:wecom-cli disk files upload --json '{\"folder_id\": \"<folder_id>\", \"file_path\": \"D:/TraeWork/{年}/{月}/<文件名>.html\", \"file_name\": \"缺陷日报-{项目名}-{模块名}-{YYYY-MM-DD}.html\"}'
- PowerShell 转义:--json参数外层单引号、内部双引号写成\",否则报 893001 JSON 解析失败
- 已知坑:不传 folder_id 会报 640032(管理员禁止新建共享空间,且机器人名下无默认空间),必须显式指定已有文件夹 ID;上传他人文件夹会因无写权限失败(机器人只能写授权账号自己名下的空间)
- 分享链接:日报中直接用文件夹分享链接https://drive.weixin.qq.com/s?k=...(群成员点开即可看到/下载文件夹内报表,含企业微信外部成员);CLI 不支持生成单个文件的分享链接,无需尝试
- 上传文件名:统一缺陷日报-{项目名}-{模块名}-{YYYY-MM-DD}.html,与日报标题口径一致;HTML 为离线文件,上传后无单独 doc_url - 替换链接:日报文本中"完整报表/完整明细文档"处直接填微盘文件夹分享链接(纯 URL 明文)。
发送到群(可选增强)
用户消息含"发送"且已授权企业微信时,调用 trae-remote-official:wecom:wecomcli-message 技能,把精简速报版文本 + 报表外链发送到项目群;不知道发哪个群时先查询会话列表让用户选择。用户没说"发送"或未授权时,只输出文本供用户自己复制。
输出约束
- 日报正文不要额外添加开场白、总结、建议;只输出日报文本。拉取数据等过程可简短说明进展。
- 高危 Bug 清单多行原样展示,格式保持【模块名称】标题 - 处理人。
- markdown 排版清晰,表情保留。
- 所有数字严格来自禅道 API 实际数据,不自行修改、不估算;字段缺失时数字填 0,文本填"无"。
- 不要在对话中输出禅道密码或 token。
示例对话
示例 1:全产品统计
用户:给我发送施工船监测的bug周报
执行流程:
1. 读取 config.json(未配置则先引导配置禅道地址/账号/密码/项目ID,并告知用户如何查看产品ID)
2. 匹配项目"施工船监测" → product_id
3. 获取禅道 token,翻页拉取该产品全部 Bug + 产品详情接口取累计指标
4. 按最近 7 天统计口径计算各项指标
5. 生成完整版 + 精简版周报文本(链接一律纯 URL 明文)
6. 生成 HTML 报表保存到 D:\TraeWork\{年}\{月}\bug-weekly-report-YYYYMMDD-施工船监测.html
7. 上传该 HTML 到微盘"bug报表"文件夹(wecom-cli disk files upload,folder_id 从 config.json 的文件夹链接解析),日报链接填文件夹分享链接 https://drive.weixin.qq.com/s?k=...
8. 输出两个版本文本 + 外链;消息含"发送"则同时发到项目群
示例 2:按模块提取
用户:只看支付模块的bug日报
执行流程:
1. 读取 config.json,确定项目
2. 按三策略定位模块 ID:用户给 byModule 链接直接提取;否则模块映射表兜底(modules_map.json);再不行问用户要链接
3. Web 会话登录禅道,抓取 bug-browse-{productID}--byModule-{moduleID}.html 页面,读 data-rec-total
4. 抓单页全量 URL 解析内嵌 JSON,得到该模块全部 Bug(含已关闭)
5. 按模块口径统计(今日新增/修复/关闭/回流、遗留、P0P1、模块累计总数/已关闭)
6. 生成日报,标题为 # 📊缺陷日报-施工船监测-支付模块-2026-08-26
7. 模块分布按 Bug 类型或严重度展示(模块报表不按子模块拆分)
8. 标题/模块未标注但文本模糊命中的 Bug 列入"关联备注",不计入统计数字
示例 3:多模块统计
用户:统计支付模块和订单模块的bug周报
执行流程:
1. 按三策略分别定位"支付模块"和"订单模块"的模块 ID
2. 分别抓取两个模块的 byModule 页面并计算指标
3. 完整版中两个模块各一个区块
4. 精简版汇总两个模块的总数
5. 模块分布显示支付 vs 订单的占比