| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163 |
- /**
- * 业务闭环断言:写后可读、审批改状态、区划完整、看板/回盘真数据
- */
- const http = require("http");
- const asserts = [];
- function req(method, path, body) {
- return new Promise((resolve) => {
- const data = body == null ? null : JSON.stringify(body);
- const headers = { Accept: "application/json" };
- if (data) {
- headers["Content-Type"] = "application/json";
- headers["Content-Length"] = Buffer.byteLength(data);
- }
- const r = http.request(
- { hostname: "localhost", port: 8088, path: "/sjnmtybt" + path, method, headers },
- (res) => {
- let raw = "";
- res.on("data", (c) => (raw += c));
- res.on("end", () => {
- try {
- resolve(JSON.parse(raw));
- } catch (e) {
- resolve({ code: res.statusCode, parseError: true, raw });
- }
- });
- }
- );
- r.on("error", (e) => resolve({ code: 0, error: e.message }));
- if (data) r.write(data);
- r.end();
- });
- }
- function check(name, cond, detail) {
- asserts.push({ name, pass: !!cond, detail: detail || "" });
- console.log((cond ? "PASS" : "FAIL") + " | " + name + (detail ? " | " + detail : ""));
- }
- (async () => {
- // 1 区划完整性
- const towns = await req("GET", "/api/regions?level=TOWN&parentId=D_SJ");
- check("7个镇", towns.code === 200 && towns.data.length === 7, "n=" + (towns.data || []).length);
- const ss = await req("GET", "/api/regions?level=VILLAGE&parentId=T_SHESHAN");
- check("佘山有村", ss.code === 200 && ss.data.length >= 1, "n=" + (ss.data || []).length + " " + (ss.data || []).map((x) => x.name).join(","));
- const cd = await req("GET", "/api/regions?level=VILLAGE&parentId=T_CHEDUN");
- check("车墩有村", cd.code === 200 && cd.data.length >= 1, "n=" + (cd.data || []).length);
- // 2 人员新增落库
- const idNo = "310117199908081" + String(Date.now()).slice(-4);
- const saved = await req("POST", "/api/personnel", {
- name: "闭环测试员",
- idNumber: idNo,
- townId: "T_YEXIE",
- villageId: "V_YX_001",
- bankCardNumber: "6228480030001111222",
- monthlyStandard: 1280,
- enjoyStartMonth: "202606",
- source: "村级录入",
- });
- check("人员保存成功", saved.code === 200 && saved.data && saved.data.id, saved.data && saved.data.id);
- const pid = saved.data && saved.data.id;
- const found = await req("POST", "/api/personnel/page", { pageNum: 1, pageSize: 50, idNumber: idNo });
- check("人员按身份证可查", found.code === 200 && found.data.total >= 1, "total=" + (found.data && found.data.total));
- // 3 创建批次并审批改状态
- const batch = await req("POST", "/api/batches", {
- batchNo: "202606",
- batchLevel: "VILLAGE",
- payMonth: "202606",
- townId: "T_YEXIE",
- villageId: "V_YX_001",
- payDate: "2026-06-20",
- personnelIds: [pid || "P001"],
- });
- check("批次创建", batch.code === 200 && batch.data && batch.data.id, batch.data && batch.data.id);
- const bid = batch.data && batch.data.id;
- const before = await req("GET", "/api/batches/" + bid);
- check("新建批次待初审", before.data && before.data.status === "PENDING_TOWN_APPROVE", before.data && before.data.status);
- const pass = await req("POST", "/api/batches/town-approve", {
- bizId: bid,
- action: "PASS",
- opinion: "闭环测试通过",
- });
- check("初审接口成功", pass.code === 200, pass.message);
- const after = await req("GET", "/api/batches/" + bid);
- check(
- "初审后阶段进入居保匹配",
- after.data && after.data.currentStage === "STAGE3_INSURANCE_MATCH",
- after.data && after.data.currentStage + "/" + after.data.status
- );
- const match = await req("POST", "/api/insurance-match/trigger", { batchId: bid });
- check("居保匹配返回人员项", match.code === 200 && match.data && (match.data.items || []).length >= 1, "items=" + ((match.data && match.data.items) || []).length);
- // 4 回盘明细来自真实发放
- const ret = await req("POST", "/api/return-disk/details/page", { pageNum: 1, pageSize: 20, batchId: "MB202603001" });
- check("回盘明细条数>=3", ret.code === 200 && ret.data.total >= 3, "total=" + (ret.data && ret.data.total));
- const failItem = (ret.data.list || []).find((x) => x.success === false);
- check("含失败回盘明细", !!failItem, failItem && failItem.name + "/" + failItem.failReasonCode);
- // 5 看板真实统计
- const dash = await req("GET", "/api/dashboard/summary?payMonth=202603&townId=T_YEXIE");
- check("看板非假数据100人", dash.code === 200 && dash.data.totalPeople !== 100, "people=" + (dash.data && dash.data.totalPeople));
- check("看板有统计明细", dash.data && (dash.data.townStats || []).length >= 1, "stats=" + ((dash.data && dash.data.townStats) || []).length);
- // 6 特殊业务落库可查
- const sp = await req("POST", "/api/special-biz", {
- personnelId: "P004",
- batchNo: "202603",
- bizType: "FUNERAL",
- amount: 6000,
- reason: "闭环丧葬测试",
- heirName: "赵小明",
- });
- check("特殊业务创建", sp.code === 200 && sp.data && sp.data.id, sp.data && sp.data.id);
- const spPage = await req("GET", "/api/special-biz/page?bizType=FUNERAL&pageNum=1&pageSize=50");
- check("特殊业务可分页查出", spPage.code === 200 && spPage.data.total >= 1, "total=" + (spPage.data && spPage.data.total));
- if (sp.data && sp.data.id) {
- const ap = await req("POST", "/api/special-biz/leader-approve", {
- bizId: sp.data.id,
- action: "PASS",
- opinion: "同意丧葬",
- });
- check("特殊业务审批", ap.code === 200 && ap.data.approveStatus === "已通过", ap.data && ap.data.approveStatus);
- }
- // 7 调标落库
- const std = await req("POST", "/api/amount-standards", {
- townId: "T_YEXIE",
- standardType: "MONTHLY",
- amount: 1380,
- effectiveTime: Date.now(),
- adjustReason: "闭环调标",
- });
- check("调标保存", std.code === 200, std.message);
- const cur = await req("GET", "/api/amount-standards/current?townId=T_YEXIE&standardType=MONTHLY");
- check("当前月补变为1380", cur.code === 200 && Number(cur.data.amount) === 1380, "amount=" + (cur.data && cur.data.amount));
- // 8 历史批次真数据(回盘+归档)
- const hist = await req("POST", "/api/dashboard/history-batches", {
- pageNum: 1,
- pageSize: 20,
- townId: "T_YEXIE",
- });
- check(
- "历史批次含真实回盘/归档",
- hist.code === 200 &&
- (hist.data.list || []).length >= 1 &&
- !(hist.data.list || []).some((x) => x.id === "VB202510001"),
- "ids=" + (hist.data.list || []).map((x) => x.id + ":" + x.status).join(",")
- );
- const fail = asserts.filter((a) => !a.pass);
- console.log("\nSUMMARY pass=" + (asserts.length - fail.length) + "/" + asserts.length);
- if (fail.length) {
- fail.forEach((f) => console.log(" - " + f.name + " :: " + f.detail));
- process.exit(2);
- }
- })().catch((e) => {
- console.error(e);
- process.exit(1);
- });
|