174 lines
8.0 KiB
JavaScript
174 lines
8.0 KiB
JavaScript
const BASE = 'http://localhost:8080/api/v1'
|
|
|
|
async function api(path, options = {}) {
|
|
const res = await fetch(`${BASE}${path}`, options)
|
|
const text = await res.text()
|
|
let json = null
|
|
try { json = JSON.parse(text) } catch { /* empty body */ }
|
|
if (!res.ok) {
|
|
throw new Error(`${options.method || 'GET'} ${path} -> ${res.status} ${text}`)
|
|
}
|
|
return json
|
|
}
|
|
|
|
function auth(token) {
|
|
return { 'content-type': 'application/json', authorization: `Bearer ${token}` }
|
|
}
|
|
|
|
async function main() {
|
|
const login = await api('/auth/login', {
|
|
method: 'POST',
|
|
headers: { 'content-type': 'application/json' },
|
|
body: JSON.stringify({ username: 'admin', password: 'Admin@2026' }),
|
|
})
|
|
const token = login.data.accessToken
|
|
console.log('登录成功\n')
|
|
|
|
const daysFromNow = (n) => {
|
|
const d = new Date(Date.now() + n * 86400000)
|
|
const pad = (x) => String(x).padStart(2, '0')
|
|
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}T${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
|
|
}
|
|
|
|
const issues = [
|
|
{
|
|
title: '【演示】登录页面白屏无法进入系统',
|
|
description: '输入正确账号密码点击登录后,页面白屏无任何响应,控制台报 React 渲染错误。',
|
|
status: 'draft', priority: 'high', phase: '测试阶段', subProject: '前端开发',
|
|
category: '界面问题', impactLevel: '严重', impactScope: '影响全部用户',
|
|
assigneeId: 2, reviewerId: 1, departmentId: 2, deadline: daysFromNow(7),
|
|
},
|
|
{
|
|
title: '【演示】CSV 导出中文乱码',
|
|
description: '导出指摘列表 CSV 后,用 Excel 打开中文标题显示为乱码,需在文件头加 BOM。',
|
|
status: 'pending', priority: 'medium', phase: '编码阶段', subProject: '后端开发',
|
|
category: '功能缺陷', impactLevel: '一般', impactScope: '仅本页面',
|
|
assigneeId: 3, reviewerId: 1, departmentId: 3, deadline: daysFromNow(5),
|
|
},
|
|
{
|
|
title: '【演示】Dashboard 统计图表不渲染',
|
|
description: '工作台首页图表区域空白,ECharts 容器高度为 0,需确认图表初始化时机。',
|
|
status: 'in_progress', priority: 'high', phase: '测试阶段', subProject: '前端开发',
|
|
category: '界面问题', impactLevel: '较大', impactScope: '影响部分模块',
|
|
assigneeId: 2, reviewerId: 1, departmentId: 2, deadline: daysFromNow(3),
|
|
attachments: [{ name: 'screenshot-dashboard-blank.png', content: 'PNG 占位:Dashboard 图表白屏截图(演示数据)' }],
|
|
},
|
|
{
|
|
title: '【演示】Agent 审批卡点击无响应',
|
|
description: 'Agent 执行后弹出审批卡,点击批准/驳回按钮无反应,接口 500。',
|
|
status: 'in_progress', priority: 'urgent', phase: '编码阶段', subProject: '后端开发',
|
|
category: '功能缺陷', impactLevel: '严重', impactScope: '影响全部用户',
|
|
assigneeId: 3, reviewerId: 1, departmentId: 4, deadline: daysFromNow(2),
|
|
agent: { goal: '查找登录白屏相似案例并生成对应方案', action: 'approve-pending' },
|
|
},
|
|
{
|
|
title: '【演示】通知铃铛未读数量不更新',
|
|
description: '收到状态流转通知后,右上角铃铛未读数仍为 0,需刷新才显示。',
|
|
status: 'pending_confirm', priority: 'medium', phase: '上线阶段', subProject: '通知模块',
|
|
category: '功能缺陷', impactLevel: '一般', impactScope: '仅本页面',
|
|
assigneeId: 3, reviewerId: 1, departmentId: 2, deadline: daysFromNow(6),
|
|
},
|
|
{
|
|
title: '【演示】附件下载返回 404',
|
|
description: '点击附件下载按钮,接口返回 404,MinIO 对象与数据库记录不一致。',
|
|
status: 'closed', priority: 'low', phase: '测试阶段', subProject: '后端开发',
|
|
category: '功能缺陷', impactLevel: '一般', impactScope: '仅本页面',
|
|
assigneeId: 2, reviewerId: 1, departmentId: 2, deadline: daysFromNow(-3),
|
|
attachments: [{ name: 'error-log.txt', content: '2026-08-01 10:23:45 ERROR download attachment 404' }],
|
|
},
|
|
{
|
|
title: '【演示】逾期未处理的紧急指摘',
|
|
description: '该指摘已超过整改截止日期仍未处理,需催办担当者。',
|
|
status: 'pending', priority: 'urgent', phase: '上线阶段', subProject: '数据库',
|
|
category: '数据问题', impactLevel: '严重', impactScope: '影响全部用户',
|
|
assigneeId: 3, reviewerId: 1, departmentId: 3, deadline: daysFromNow(-1),
|
|
},
|
|
{
|
|
title: '【演示】Agent 方案被驳回回退人工',
|
|
description: 'Agent 生成方案后经审批被驳回,回退人工模式由担当者手动处理。',
|
|
status: 'in_progress', priority: 'high', phase: '编码阶段', subProject: '前端开发',
|
|
category: '需求变更', impactLevel: '较大', impactScope: '影响部分模块',
|
|
assigneeId: 2, reviewerId: 1, departmentId: 4, deadline: daysFromNow(4),
|
|
agent: { goal: '自动生成附件下载修复方案', action: 'reject' },
|
|
},
|
|
{
|
|
title: '【演示】CSV 导出大数据量性能',
|
|
description: '导出 1 万条指摘时接口耗时超过 30 秒,前端超时。',
|
|
status: 'closed', priority: 'medium', phase: '编码阶段', subProject: '后端开发',
|
|
category: '性能问题', impactLevel: '较大', impactScope: '影响部分模块',
|
|
assigneeId: 3, reviewerId: 1, departmentId: 3, deadline: daysFromNow(-2),
|
|
},
|
|
{
|
|
title: '【演示】多状态流转完整链路验证',
|
|
description: '该指摘完整走完 草稿→待对应→对应中→待确认→已关闭 全链路,用于演示状态机与流转日志。',
|
|
status: 'closed', priority: 'medium', phase: '需求阶段', subProject: '业务验证',
|
|
category: '需求变更', impactLevel: '一般', impactScope: '仅本页面',
|
|
assigneeId: 2, reviewerId: 1, departmentId: 3, deadline: daysFromNow(-5),
|
|
},
|
|
]
|
|
|
|
const FLOW = {
|
|
draft: [],
|
|
pending: ['pending'],
|
|
in_progress: ['pending', 'in_progress'],
|
|
pending_confirm: ['pending', 'in_progress', 'pending_confirm'],
|
|
closed: ['pending', 'in_progress', 'pending_confirm', 'closed'],
|
|
}
|
|
|
|
const created = []
|
|
for (const [i, it] of issues.entries()) {
|
|
const num = String(i + 1).padStart(2, '0')
|
|
const { status, attachments, agent, ...payload } = it
|
|
const res = await api('/issues', {
|
|
method: 'POST',
|
|
headers: auth(token),
|
|
body: JSON.stringify(payload),
|
|
})
|
|
const issue = res.data
|
|
console.log(`[${num}] 创建 ${issue.issueNo} - ${issue.title}`)
|
|
|
|
for (const s of FLOW[status] || []) {
|
|
await api(`/issues/${issue.id}/status`, {
|
|
method: 'PATCH',
|
|
headers: auth(token),
|
|
body: JSON.stringify({ status: s, remark: '演示流转' }),
|
|
})
|
|
console.log(` 流转 -> ${s}`)
|
|
}
|
|
|
|
if (attachments && attachments.length) {
|
|
for (const a of attachments) {
|
|
const fd = new FormData()
|
|
fd.append('file', new Blob([a.content], { type: 'text/plain' }), a.name)
|
|
await api(`/issues/${issue.id}/attachments`, { method: 'POST', headers: { authorization: `Bearer ${token}` }, body: fd })
|
|
console.log(` 上传附件 ${a.name}`)
|
|
}
|
|
}
|
|
|
|
if (agent) {
|
|
const exec = await api('/agent/execute', {
|
|
method: 'POST',
|
|
headers: auth(token),
|
|
body: JSON.stringify({ issueId: issue.id, goal: agent.goal }),
|
|
})
|
|
const planId = exec.data.planId
|
|
console.log(` Agent 执行 -> plan#${planId}`)
|
|
if (agent.action === 'approve-pending') {
|
|
console.log(` Agent 审批保持 pending(演示审批中)`)
|
|
} else if (agent.action === 'reject') {
|
|
await api(`/agent/approval/${planId}/reject`, {
|
|
method: 'POST',
|
|
headers: auth(token),
|
|
body: JSON.stringify({ comment: '方案不适用,请人工处理' }),
|
|
})
|
|
console.log(` Agent 已驳回 plan#${planId}`)
|
|
}
|
|
}
|
|
created.push(issue)
|
|
}
|
|
|
|
console.log(`\n完成:共创建 ${created.length} 条演示数据`)
|
|
}
|
|
|
|
main().catch((e) => { console.error('失败:', e.message); process.exit(1) })
|