/** * 资质申请管理 — 三模块完整流程联调(模拟前端 persist 链路) * * 运行: node docs/test-reports/测试用例/test-qual-filing-full-e2e.mjs */ import path from "node:path"; import { fileURLToPath } from "node:url"; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const ROOT = path.resolve(__dirname, "../../.."); const API_BASE = process.env.API_BASE || "http://127.0.0.1:8095/safety-eval"; const ORG_INFO_ID = process.env.ORG_INFO_ID || "1"; const DEFAULT_URL = "https://s1.aigei.com/prevfiles/6f2754563be2491bad7c957904cd7d2a.jpg?e=2051020800&token=P7S2Xpzfz11vAkASLTkfHN7Fw-oOZBecqeJaxypL:CR60zg7VKDp-jUWyYls_rdvyQMM="; const issues = []; let passed = 0; let failed = 0; const ctx = {}; function log(step, msg) { console.log(`[${step}] ${msg}`); } function pass(name, detail = "") { passed += 1; console.log(` ✓ ${name}${detail ? ` — ${detail}` : ""}`); } function fail(name, detail = "") { failed += 1; console.log(` ✗ ${name}${detail ? ` — ${detail}` : ""}`); } function recordIssue(module, severity, title, detail) { issues.push({ module, severity, title, detail }); } async function api(method, apiPath, body) { const res = await fetch(`${API_BASE}${apiPath}`, { method, headers: { "Content-Type": "application/json", orgInfoId: ORG_INFO_ID }, body: body !== undefined ? JSON.stringify(body) : undefined, }); const text = await res.text(); try { return { httpStatus: res.status, ...JSON.parse(text) }; } catch { return { httpStatus: res.status, success: false, raw: text }; } } async function uploadAllMaterials(filingId) { const detail = await api("GET", `/qual-filing/detail?id=${filingId}`); for (const m of detail.data?.materials || []) { if (!m.attachmentUrl) { await api("POST", "/qual-filing-material/upload", { id: m.id, attachmentUrl: DEFAULT_URL }); } } } const FORMAL_BASIC = { filingTerritoryName: "渝北区", filingTerritoryCode: "渝北区", filingUnitName: "重庆渝安安全评价技术有限公司", filingUnitTypeCode: "本地单位", filingUnitTypeName: "本地单位", businessScope: "石油加工业,化学原料、化学品及医药制造业", registerAddress: "重庆市渝北区黄山大道中段88号", officeAddress: "重庆市渝北区黄山大道中段88号安全评价大厦12层", creditCode: "91500000MA5U8K9X2L", qualCertNo: "AQPJ-渝-2024-0018", legalPersonPhone: "王建国 / 023-67891234", contactPhone: "陈晓明 / 13912345678", infoDisclosureUrl: "https://www.yuan-an-safety.com/disclosure", fixedAssetAmount: 1580, workplaceArea: 1860, archiveRoomArea: 120, fulltimeEvaluatorCount: 32, registeredEngineerCount: 12, unitIntro: "本公司成立于2018年,主要从事安全评价、安全技术服务,具备独立法人资格。", attachmentUrl: DEFAULT_URL, }; async function persistLikeFrontend(filingId, mode = "application") { const saveRes = await api("POST", "/qual-filing/save-draft", { id: filingId, ...FORMAL_BASIC }); if (!saveRes.success) { throw new Error(saveRes.message || "save-draft failed"); } await api("POST", `/qual-filing-material/init-template?filingId=${filingId}`); await uploadAllMaterials(filingId); const commitmentContent = "本人是王建国是重庆渝安安全评价技术有限公司法定代表人,现代表我单位承诺如下:本单位提交的资质备案申请材料真实、准确、完整。"; await api("POST", "/qual-filing-commitment/save-or-update", { filingId, signDate: "2026-06-30", legalRepSignatureUrl: DEFAULT_URL, commitmentContent, }); const personnelPage = await api("GET", "/org-personnel/page?current=1&size=20"); const personnelIds = (personnelPage.data || []).map((p) => p.id).filter(Boolean); if (personnelIds.length) { await api("POST", "/qual-filing-personnel/batch-add-from-org", { filingId, sourcePersonnelIds: personnelIds, }); } const equipPage = await api("GET", "/org-equipment/page?current=1&size=20"); const equipIds = (equipPage.data || []).map((e) => e.id).filter(Boolean); if (equipIds.length) { await api("POST", "/qual-filing-equipment/batch-add-from-org", { filingId, sourceEquipmentIds: equipIds, }); } return api("GET", `/qual-filing/detail?id=${filingId}`); } // ── 模块1:资质备案申请 ── async function testModule1Application() { console.log("\n=== 模块1:资质备案申请 ==="); const existingPage = await api("GET", "/qual-filing/page?current=1&size=5&applyTypeCode=1&filingStatusCode=5"); let filingId = existingPage.data?.[0]?.id; if (filingId) { pass("复用已有暂存记录", `id=${filingId}`); } else { const draft = await api("POST", "/qual-filing/draft?applyTypeCode=1"); filingId = draft.data?.id; if (draft.success && filingId) { pass("新建申请草稿", `id=${filingId}`); } else { fail("新建申请草稿", draft.message); return; } } ctx.applicationId = filingId; const detailRes = await persistLikeFrontend(filingId); const detail = detailRes.data || {}; pass("暂存-基本信息", detail.filingUnitName); pass("暂存-材料10项已上传", (detail.materials || []).every((m) => m.uploadStatusCode === 2)); pass("暂存-承诺书", !!detail.commitment?.commitmentContent); pass("暂存-人员", `count=${(detail.personnelList || []).length}`); pass("暂存-装备", `count=${(detail.equipmentList || []).length}`); const listRes = await api("GET", "/qual-filing/page?current=1&size=20&applyTypeCode=1"); const inList = (listRes.data || []).some((r) => String(r.id) === String(filingId)); if (inList && detail.filingStatusCode === 5) { pass("列表-暂存记录可见", detail.filingStatusName); } else { fail("列表-暂存记录可见", `status=${detail.filingStatusCode}`); } const reload = await api("GET", `/qual-filing/detail?id=${filingId}`); if (reload.data?.businessScope?.includes("化学")) { pass("回显-修改后业务范围"); } else { fail("回显-修改后业务范围"); } const verifyMod = await import(path.join(ROOT, "src/pages/Container/QualApplication/filingVerify.js")); const verifyResult = verifyMod.verifyFilingPrerequisites({ ...FORMAL_BASIC, materials: reload.data?.materials || [], personnelList: reload.data?.personnelList || [], equipmentList: reload.data?.equipmentList || [], }); if (!verifyResult.passed) { const failedItems = verifyResult.items.filter((i) => !i.passed).map((i) => i.label); recordIssue( "资质备案申请", "阻塞", "前端提交核验:人员数量/结构未通过", `当前机构人员 ${(reload.data?.personnelList || []).length} 人,核验失败项:${failedItems.join("、")}。用户要求测试阶段暂不判断此项,但前端「提交申请」确认按钮仍被禁用。`, ); pass("前端核验-预期失败(人员不足)", failedItems.join(",")); } else { pass("前端核验-全部通过"); } const submit = await api("POST", `/qual-filing/submit?id=${filingId}`); if (submit.success && submit.data?.filingStatusCode === 2) { pass("后端提交-进入审核中", submit.data.filingStatusName); } else { fail("后端提交", submit.message); recordIssue("资质备案申请", "阻塞", "后端提交失败", submit.message || JSON.stringify(submit)); return; } const approve = await api("POST", `/qual-filing/approve?id=${filingId}`); if (approve.success && approve.data?.filingStatusCode === 1) { pass("审核通过-已备案", approve.data.filingStatusName); ctx.approvedApplicationId = filingId; } else { fail("审核通过", approve.message || approve.data?.filingStatusName); } } // ── 模块2:已备案资质管理 ── async function testModule2FiledManage() { console.log("\n=== 模块2:已备案资质管理 ==="); const filedPage = await api("GET", "/qual-filing/filed/page?current=1&size=20"); const filedList = filedPage.data || []; if (filedList.length > 0) { pass("已备案列表有数据", `count=${filedList.length}`); ctx.originFiledId = filedList[0].id; } else { fail("已备案列表有数据", "审核通过后应出现 applyType=3 记录"); recordIssue("已备案资质管理", "阻塞", "审核通过后已备案列表为空", "需确认 approve 是否创建 filed 记录"); return; } const origin = filedList[0]; if (origin.applyTypeCode === 3) { pass("已备案记录类型", origin.applyTypeName); } else { fail("已备案记录类型", `applyTypeCode=${origin.applyTypeCode}`); } const filedDraft = await api("POST", "/qual-filing/filed/draft"); const filedDraftId = filedDraft.data?.id; if (!filedDraft.success || !filedDraftId) { fail("资质备案填报-创建草稿", filedDraft.message); return; } pass("资质备案填报-创建草稿", `id=${filedDraftId}`); ctx.filedDraftId = filedDraftId; const saveRes = await persistLikeFrontend(filedDraftId); const detail = saveRes.data || {}; if (detail.filingStatusCode === 5 && detail.applyTypeCode === 3) { pass("填报暂存", `${detail.filingStatusName} applyType=${detail.applyTypeCode}`); } else { fail("填报暂存", `status=${detail.filingStatusCode} type=${detail.applyTypeCode}`); } const filedPageDefault = await api("GET", "/qual-filing/filed/page?current=1&size=20"); const draftInDefaultList = (filedPageDefault.data || []).some((r) => String(r.id) === String(filedDraftId)); if (!draftInDefaultList) { pass("已备案列表-默认不含填报暂存"); } else { fail("已备案列表-默认不含填报暂存"); recordIssue("已备案资质管理", "一般", "填报暂存不应出现在默认已备案列表", `draftId=${filedDraftId}`); } const filedPageDraftFilter = await api("GET", "/qual-filing/filed/page?current=1&size=20&filingStatusCode=5"); const draftInFilteredList = (filedPageDraftFilter.data || []).some((r) => String(r.id) === String(filedDraftId)); if (draftInFilteredList) { pass("已备案列表-显式筛选暂存可见"); } else { fail("已备案列表-显式筛选暂存可见", `draftId=${filedDraftId}`); } } // ── 模块3:备案变更管理 ── async function testModule3FilingChange() { console.log("\n=== 模块3:备案变更管理 ==="); const originId = ctx.originFiledId; if (!originId) { fail("发起变更", "无已备案 origin 记录"); return; } const changePage = await api("GET", "/qual-filing/change/page?current=1&size=20"); const changeList = changePage.data || []; if (changeList.length > 0) { pass("变更列表有数据", `count=${changeList.length}`); } else { fail("变更列表有数据", "应有已备案记录"); } const origin = changeList.find((r) => String(r.id) === String(originId)) || changeList[0]; if (!origin) { fail("变更源记录", "未找到"); return; } if (origin.filingStatusCode === 4) { recordIssue("备案变更管理", "阻塞", "已备案记录处于变更审核中", "无法再次发起变更"); fail("可发起变更", "状态=变更审核中"); return; } pass("可发起变更", origin.filingStatusName); const start = await api("POST", `/qual-filing-change/start?originFilingId=${originId}`); const draftId = start.data?.draftFilingId || start.data; if (!start.success || !draftId) { fail("发起变更", start.message); return; } pass("发起变更", `draftId=${draftId}`); ctx.changeDraftId = draftId; const changeBasic = { ...FORMAL_BASIC, businessScope: "石油加工业,化学原料、化学品及医药制造业;金属、非金属矿及其他矿采选业", unitIntro: "变更后:新增矿山采选业安全评价业务范围。", }; await api("POST", "/qual-filing/save-draft", { id: draftId, ...changeBasic }); await uploadAllMaterials(draftId); await api("POST", "/qual-filing-commitment/save-or-update", { filingId: draftId, signDate: "2026-06-30", legalRepSignatureUrl: DEFAULT_URL, commitmentContent: "变更备案承诺书", }); const changeDetail = await api("GET", `/qual-filing/detail?id=${draftId}`); if (changeDetail.data?.businessScope?.includes("矿采选业")) { pass("变更草稿-业务范围已修改"); } else { fail("变更草稿-业务范围已修改", changeDetail.data?.businessScope); } const changeSubmit = await api("POST", "/qual-filing-change/submit", { draftFilingId: draftId }); if (changeSubmit.success) { pass("提交变更", "success"); } else { fail("提交变更", changeSubmit.message); recordIssue("备案变更管理", "阻塞", "变更提交失败", changeSubmit.message); return; } const history = await api("GET", `/qual-filing-change/history?originFilingId=${originId}`); const changeCount = history.data?.changeCount ?? 0; if (history.success && changeCount > 0) { pass("变更历史", `changeCount=${changeCount}`); } else { fail("变更历史", `count=${changeCount}`); } const changeAfter = await api("GET", "/qual-filing/change/page?current=1&size=20"); const updated = (changeAfter.data || []).find((r) => String(r.id) === String(originId)); if (updated?.changeCount > 0) { pass("变更列表-变更次数更新", `${updated.filingStatusName} count=${updated.changeCount}`); } else { fail("变更列表-变更次数更新"); recordIssue("备案变更管理", "一般", "变更列表变更次数未更新", `originId=${originId}`); } } async function checkDataQuality() { console.log("\n=== 数据质量检查 ==="); const personnelPage = await api("GET", "/org-personnel/page?current=1&size=10"); const missingName = (personnelPage.data || []).filter((p) => !p.personName && !p.staffName); if (missingName.length) { recordIssue( "通用", "一般", "机构人员主数据姓名为空", `${missingName.length} 条人员记录 personName/staffName 为空,表单人员列表可能显示空白。`, ); pass("人员主数据-姓名缺失(已知)", `count=${missingName.length}`); } } async function main() { console.log("资质申请管理 — 三模块完整流程联调"); console.log(`API=${API_BASE} orgInfoId=${ORG_INFO_ID}\n`); await checkDataQuality(); await testModule1Application(); await testModule2FiledManage(); await testModule3FilingChange(); console.log(`\n=== 结果: ${passed} 通过, ${failed} 失败 ===`); console.log(`=== 问题记录: ${issues.length} 条 ===\n`); for (const [i, issue] of issues.entries()) { console.log(`${i + 1}. [${issue.module}] [${issue.severity}] ${issue.title}`); console.log(` ${issue.detail}\n`); } return { passed, failed, issues, ctx }; } const result = await main(); if (result.failed > 0) { process.exitCode = 1; } export default result;