Files

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) })