/** * 松江退养补贴 - DMS 模拟数据种子 * 网关: 121.43.55.7:2101 * * 用法: node scripts/seed-dms-mock-data.js * 可选: node scripts/seed-dms-mock-data.js --force (即使已有数据也追加) */ const http = require("http"); const qs = require("querystring"); const fs = require("fs"); const path = require("path"); const HOST = "121.43.55.7"; const PORT = 2101; const FORCE = process.argv.includes("--force"); const COL = { xzqh: { columnId: 1842, modelId: 1965, tag: "sjnmtybt_xzqh" }, jebz: { columnId: 1843, modelId: 1966, tag: "sjnmtybt_jebz" }, alart: { columnId: 1841, modelId: 1964, tag: "sjnmtybt_alart" }, lcb: { columnId: 1844, modelId: 1967, tag: "sjnmtybt_lcb" }, pcb: { columnId: 1845, modelId: 1968, tag: "sjnmtybt_pcb" }, pctj: { columnId: 1846, modelId: 1969, tag: "sjnmtybt_pctj" }, ryjbxx: { columnId: 1847, modelId: 1970, tag: "sjnmtybt_ryjbxx" }, ffmx: { columnId: 1849, modelId: 1974, tag: "sjnmtybt_ffmx" }, }; function req(urlPath, fields, token, method) { return new Promise((resolve, reject) => { const body = qs.stringify(fields || {}); const headers = { "Content-Type": "application/x-www-form-urlencoded", "Content-Length": Buffer.byteLength(body), }; if (token) { headers.Token = token; headers.token = token; } const r = http.request( { hostname: HOST, port: PORT, path: urlPath, method: method || "POST", headers }, (res) => { let data = ""; res.on("data", (c) => (data += c)); res.on("end", () => { try { resolve(JSON.parse(data)); } catch (e) { resolve({ raw: data, status: res.statusCode }); } }); } ); r.on("error", reject); r.write(body); r.end(); }); } async function login() { const res = await req("/proxy_oauth/user/login", { userName: "user_liu", password: "WE176852439@lmx", clientId: "1", }); if (res.code != 200) throw new Error("login fail: " + JSON.stringify(res)); return res.message; } async function addContent(token, col, contentObj) { const payload = Object.assign( { title: contentObj.title || contentObj.c_name || contentObj.c_batch_number || "模拟数据", content: contentObj.content || contentObj.c_remarks || "mock", }, contentObj ); const res = await req( "/proxy_dms/content/addContent", { columnId: String(col.columnId), modelId: String(col.modelId), content: JSON.stringify(payload), }, token ); return res; } async function selectList(token, col, pageSize) { const res = await req( "/proxy_dms/content/selectContentList", { columnId: String(col.columnId), modelId: String(col.modelId), states: "0", pageNum: "1", pageSize: String(pageSize || 5), }, token ); const list = (res.content && res.content.list) || (res.content && res.content.records) || (Array.isArray(res.content) ? res.content : []) || []; return { code: res.code, total: (res.content && (res.content.total || res.content.totalCount)) || list.length, list }; } function towns() { return [ { code: "T_YEXIE", name: "叶榭镇", plan: "17010002" }, { code: "T_SHESHAN", name: "佘山镇", plan: "17010003" }, { code: "T_CHEDUN", name: "车墩镇" }, { code: "T_SHIHUDANG", name: "石湖荡镇" }, { code: "T_MAOGANG", name: "泖港镇" }, { code: "T_XINBANG", name: "新浜镇" }, { code: "T_XIAOKUNSHAN", name: "小昆山镇" }, ]; } (async () => { const token = await login(); console.log("login ok"); const summary = { added: {}, skipped: {}, errors: [] }; // 若人员表已有模拟标记数据且非 force,则跳过整库种子(避免重复) const existRy = await selectList(token, COL.ryjbxx, 20); const hasMock = existRy.list && existRy.list.some((i) => String(i.c_remarks || i.content || "").includes("MOCK_SEED_260804")); if (hasMock && !FORCE) { console.log("检测到已有 MOCK_SEED_260804 数据,跳过写入。如需追加请加 --force"); const out = { skipped: true, tip: "use --force to append" }; fs.writeFileSync(path.join(__dirname, "seed-dms-mock-result.json"), JSON.stringify(out, null, 2)); return; } async function seedOne(key, col, rows) { const ids = []; for (const row of rows) { const res = await addContent(token, col, row); if (res.code == 200) { ids.push(res.content); console.log(" +", key, res.content, row.title || row.c_name || row.c_batch_number || ""); } else { console.log(" x", key, res.code, res.message || res.content); summary.errors.push({ key, row, res }); } } summary.added[key] = ids; return ids; } // ---------- 1. 行政区划 ---------- console.log("\n[1] 行政区划"); const districtTitle = "松江区"; await seedOne("xzqh_district", COL.xzqh, [ { title: districtTitle, c_name: districtTitle, c_parent_id: "0", c_level: "DISTRICT", c_code: "D_SJ", c_remarks: "MOCK_SEED_260804|level=DISTRICT|code=D_SJ", content: "MOCK_SEED_260804", }, ]); const townRows = towns().map((t) => ({ title: t.name, c_name: t.name, c_parent_id: "D_SJ", c_level: "TOWN", c_code: t.code, c_entrust_plan_code: t.plan || "", c_remarks: "MOCK_SEED_260804|level=TOWN|code=" + t.code, content: "MOCK_SEED_260804", })); await seedOne("xzqh_town", COL.xzqh, townRows); const villageRows = [ { town: "T_YEXIE", name: "叶榭村", code: "V_YX_001" }, { town: "T_YEXIE", name: "井凌桥村", code: "V_YX_002" }, { town: "T_SHESHAN", name: "陈坊村", code: "V_SS_001" }, { town: "T_CHEDUN", name: "车墩村", code: "V_CD_001" }, ].map((v) => ({ title: v.name, c_name: v.name, c_parent_id: v.town, c_level: "VILLAGE", c_code: v.code, c_remarks: "MOCK_SEED_260804|level=VILLAGE|code=" + v.code + "|town=" + v.town, content: "MOCK_SEED_260804", })); await seedOne("xzqh_village", COL.xzqh, villageRows); // ---------- 2. 金额标准(年度标准一行双金额)---------- console.log("\n[2] 金额标准"); const now = Date.now(); const stdRows = towns().map((t) => ({ title: t.name + "-年度标准", c_town_id: t.code, c_amount: 1280, c_funeral_amount: 6000, c_date_time: now, c_standard_type: "YEARLY_ADJUST", c_current_flag: "true", c_adjust_reason: "2025年度标准", c_remarks: "MOCK_SEED_260804|YEARLY_ADJUST|" + t.code, content: "MOCK_SEED_260804", })); await seedOne("jebz", COL.jebz, stdRows); // ---------- 3. 人员 ---------- console.log("\n[3] 人员"); const people = [ { title: "张三", c_name: "张三", c_id_number: "310117198001011234", c_phone_number: 13800138001, c_address: "上海市松江区叶榭镇叶榭村1组", c_bank_card_number: "6228480030001234567", c_social_insurance_code: "170100021001", c_household_type: "农业", c_district_id: "D_SJ", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_village_code: "310117112001", c_entrust_plan_code: "17010002", c_entrust_plan_name: "叶榭镇委托发放", c_payee_name: "张三", c_bank_name: "上海农商银行叶榭支行", c_bank_type: "农商", c_bank_branch_code: "322290003001", c_enjoy_start_month: "202501", c_monthly_standard: 1280, c_insurance_status: "正常参保", c_insurance_match_result: "SUCCESS", c_biz_status: "NORMAL", c_pay_this_month: "true", c_source: "村级录入", c_input_village_id: "V_YX_001", c_remarks: "MOCK_SEED_260804|P001|正常在库", content: "MOCK_SEED_260804", }, { title: "李四", c_name: "李四", c_id_number: "310117197505051234", c_phone_number: 13800138002, c_address: "上海市松江区叶榭镇井凌桥村2组", c_bank_card_number: "6228480030002234567", c_social_insurance_code: "170100021002", c_household_type: "农业", c_district_id: "D_SJ", c_town_id: "T_YEXIE", c_village_id: "V_YX_002", c_entrust_plan_code: "17010002", c_payee_name: "李四", c_bank_name: "中国农业银行松江支行", c_bank_type: "农行", c_enjoy_start_month: "202406", c_monthly_standard: 1280, c_insurance_status: "正常参保", c_insurance_match_result: "SUCCESS", c_biz_status: "NORMAL", c_pay_this_month: "true", c_source: "Excel导入", c_input_village_id: "V_YX_002", c_remarks: "MOCK_SEED_260804|P002|正常在库", content: "MOCK_SEED_260804", }, { title: "王五", c_name: "王五", c_id_number: "310117196808081234", c_phone_number: 13800138003, c_address: "上海市松江区佘山镇陈坊村", c_bank_card_number: "6228480030003234567", c_social_insurance_code: "170100031001", c_household_type: "农业", c_town_id: "T_SHESHAN", c_village_id: "V_SS_001", c_entrust_plan_code: "17010003", c_payee_name: "王五", c_bank_type: "农商", c_monthly_standard: 1280, c_insurance_match_result: "PENDING", c_biz_status: "PENDING_TOWN_APPROVE", c_pay_this_month: "true", c_source: "村级录入", c_remarks: "MOCK_SEED_260804|P003|待镇经发初审", content: "MOCK_SEED_260804", }, { title: "赵六", c_name: "赵六", c_id_number: "310117195912121234", c_phone_number: 13800138004, c_address: "上海市松江区叶榭镇叶榭村", c_bank_card_number: "6228480030004234567", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_payee_name: "赵六", c_bank_type: "农商", c_monthly_standard: 1280, c_biz_status: "FUNERAL", c_pay_this_month: "false", c_death_date: "2025-09-15", c_heir_name: "赵小明", c_heir_id_number: "310117199001011111", c_heir_bank_card: "6228480030005234567", c_heir_phone: "13900139001", c_funeral_diff_amount: 6000, c_source: "死亡名单", c_remarks: "MOCK_SEED_260804|P004|死亡丧葬", content: "MOCK_SEED_260804", }, { title: "钱七", c_name: "钱七", c_id_number: "310117197011111234", c_phone_number: 13800138005, c_address: "上海市松江区车墩镇车墩村", c_bank_card_number: "6228480030006234567", c_town_id: "T_CHEDUN", c_village_id: "V_CD_001", c_payee_name: "钱七", c_bank_type: "农行", c_monthly_standard: 1280, c_insurance_match_result: "FAIL", c_biz_status: "ABNORMAL", c_pay_this_month: "false", c_source: "村级录入", c_remarks: "MOCK_SEED_260804|P005|居保匹配失败待人工确认", content: "MOCK_SEED_260804", }, { title: "孙八", c_name: "孙八", c_id_number: "310117198303031234", c_phone_number: 13800138006, c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_payee_name: "孙八", c_bank_card_number: "6228480030007234567", c_bank_type: "农商", c_monthly_standard: 1280, c_biz_status: "PAUSED", c_pay_this_month: "false", c_source: "村级录入", c_remarks: "MOCK_SEED_260804|P006|暂停发放", content: "MOCK_SEED_260804", }, ]; await seedOne("ryjbxx", COL.ryjbxx, people); // ---------- 4. 批次 ---------- console.log("\n[4] 批次"); const batches = [ { title: "202604-叶榭-村级待初审", c_batch_number: "VB202604001", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_district_id: "D_SJ", c_batch_level: "VILLAGE", c_pay_month: "202604", c_current_stage: "STAGE2_TOWN_PRECHECK", c_status: "PENDING_TOWN_APPROVE", c_people_count: 2, c_standard_amount: 2560, c_normal_amount: 2560, c_death_amount: 0, c_additional_amount: 0, c_supplementary_payment_amount: 0, c_funeral_amount: 0, c_deduct_amount: 0, c_total_amount: 2560, c_export_status: "未出盘", c_return_status: "未回盘", c_pay_date: "2026-04-20", c_submitter: "叶榭村合作社-张会计", c_entrust_plan_code: "17010002", c_remarks: "MOCK_SEED_260804|待镇经发初审", content: "MOCK_SEED_260804", }, { title: "202603-叶榭-镇级已回盘", c_batch_number: "MB202603001", c_town_id: "T_YEXIE", c_village_id: "", c_district_id: "D_SJ", c_batch_level: "TOWN", c_pay_month: "202603", c_current_stage: "STAGE8_RETURN_CONFIRM", c_status: "RETURNED", c_people_count: 3, c_standard_amount: 3840, c_normal_amount: 3840, c_death_amount: 6000, c_additional_amount: 0, c_supplementary_payment_amount: 0, c_funeral_amount: 6000, c_deduct_amount: 0, c_total_amount: 9840, c_export_disk_no: "DP20260301", c_export_file_name: "LSJ20260320.N7C", c_export_status: "已导出", c_return_status: "部分异常", c_summary_no: "170000061804", c_pay_bank: "农商", c_pay_date: "2026-03-20", c_return_date: "2026-03-25", c_submitter: "社区事务中心-业务科", c_town_opinion: "同意发放", c_entrust_plan_code: "17010002", c_remarks: "MOCK_SEED_260804|已回盘含失败", content: "MOCK_SEED_260804", }, // 注:不再种子混村镇级批 MB202604002(两村明细挂同一无村居镇批,属脏数据;领导审走真实村批流程) ]; await seedOne("pcb", COL.pcb, batches); // ---------- 5. 发放明细 ---------- console.log("\n[5] 发放明细"); const details = [ { title: "张三-202603发放", c_batch_id: "MB202603001", c_batch_number: "MB202603001", c_user_id: "P001", c_name: "张三", c_id_number: "310117198001011234", c_pay_month: "202603", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_district_id: "D_SJ", c_standard_amount: 1280, c_one_time_amount: 0, c_supplementary_payment_amount: 0, c_death_amount: 0, c_deduct_amount: 0, c_additional_amount: 0, c_total_amount: 1280, c_pay_bank: "农商", c_bank_card_number: "6228480030001234567", c_standard_id: "STD_YEXIE_MONTHLY", c_exported: "true", c_remarks: "MOCK_SEED_260804|回盘成功", content: "MOCK_SEED_260804", }, { title: "李四-202603发放", c_batch_id: "MB202603001", c_batch_number: "MB202603001", c_user_id: "P002", c_name: "李四", c_id_number: "310117197505051234", c_pay_month: "202603", c_town_id: "T_YEXIE", c_village_id: "V_YX_002", c_standard_amount: 1280, c_total_amount: 1280, c_pay_bank: "农行", c_bank_card_number: "6228480030002234567", c_exported: "true", c_remarks: "MOCK_SEED_260804|回盘失败-冻结", content: "MOCK_SEED_260804", }, { title: "赵六-202603丧葬", c_batch_id: "MB202603001", c_batch_number: "MB202603001", c_user_id: "P004", c_name: "赵六", c_id_number: "310117195912121234", c_pay_month: "202603", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_standard_amount: 0, c_death_amount: 6000, c_total_amount: 6000, c_pay_bank: "农商", c_bank_card_number: "6228480030005234567", c_exported: "true", c_remarks: "MOCK_SEED_260804|丧葬补贴-继承人账户", content: "MOCK_SEED_260804", }, ]; await seedOne("ffmx", COL.ffmx, details); // ---------- 6. 流程跟踪 ---------- console.log("\n[6] 流程跟踪"); const logs = [ { title: "VB202604001-提交初审", c_process_number: "PN202604001", c_batch_id: "VB202604001", c_batch_no: "202604", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_stage: "STAGE1_PERSONNEL_INPUT", c_biz_type: "月度批次人员申请", c_approve_node: "村合作社", c_operator: "张会计", c_operator_role: "村合作社录入员", c_operator_org: "叶榭村合作社", c_action: "提交", c_opinion: "本月新增人员已录入", c_result: "成功", c_status: "已完成", c_operate_time: now - 86400000 * 2, c_remarks: "MOCK_SEED_260804", content: "MOCK_SEED_260804", }, { title: "MB202603001-回盘确认", c_process_number: "PN202603010", c_batch_id: "MB202603001", c_batch_no: "202603", c_town_id: "T_YEXIE", c_stage: "STAGE8_RETURN_CONFIRM", c_biz_type: "回盘信息更新", c_approve_node: "社区事务中心-业务部门", c_operator: "王专员", c_action: "回盘确认", c_opinion: "1人账户冻结失败,纳入下月处理", c_result: "部分异常", c_status: "已完成", c_operate_time: now - 86400000 * 10, c_remarks: "MOCK_SEED_260804", content: "MOCK_SEED_260804", }, ]; await seedOne("lcb", COL.lcb, logs); // ---------- 7. 告警 ---------- console.log("\n[7] 告警"); const alerts = [ { title: "AL-死亡停发-赵六", c_batch_no: "202603", c_batch_id: "MB202603001", c_personnel_id: "P004", c_personnel_name: "赵六", c_town_id: "T_YEXIE", c_village_id: "V_YX_001", c_level: "HIGH", c_type: "DEATH_STATUS", c_content: "死亡信息已录入,系统预警停止继续发放", c_handle_status: "CLOSED", c_handle_result: "已转丧葬补贴申请", c_initiator: "系统", c_recipient: "社区事务中心-业务部门", c_handler: "王专员", c_handle_time: now - 86400000 * 20, c_status: "已关闭", c_process_id: "PN202603010", c_remarks: "MOCK_SEED_260804|系统预警", content: "MOCK_SEED_260804", }, { title: "AL-回盘失败-李四", c_batch_no: "202603", c_batch_id: "MB202603001", c_personnel_id: "P002", c_personnel_name: "李四", c_town_id: "T_YEXIE", c_village_id: "V_YX_002", c_level: "HIGH", c_type: "RETURN_FAIL", c_content: "回盘失败:账户冻结", c_fail_reason_code: "003", c_handle_status: "PENDING", c_initiator: "系统", c_recipient: "社区事务中心-业务部门", c_status: "待处理", c_remarks: "MOCK_SEED_260804|失败码003", content: "MOCK_SEED_260804", }, { title: "AL-居保匹配失败-钱七", c_batch_no: "202604", c_personnel_id: "P005", c_personnel_name: "钱七", c_town_id: "T_CHEDUN", c_village_id: "V_CD_001", c_level: "MEDIUM", c_type: "INSURANCE_MATCH_FAIL", c_content: "居保状态匹配失败,待人工确认", c_handle_status: "PROCESSING", c_initiator: "系统", c_recipient: "社区事务中心-业务部门", c_status: "处理中", c_remarks: "MOCK_SEED_260804", content: "MOCK_SEED_260804", }, ]; await seedOne("alart", COL.alart, alerts); // ---------- 8. 批次统计 ---------- console.log("\n[8] 批次统计"); const stats = [ { title: "202603-叶榭-街镇汇总", c_batch_id: "MB202603001", c_batch_number: "MB202603001", c_summary_no: "170000061804", c_pay_month: "202603", c_town_id: "T_YEXIE", c_village_id: "", c_pay_bank: "合计", c_grain: "街镇", c_number_of_people: "3", c_should_pay_count: 3, c_should_pay_amount: 9840, c_actual_pay_count: 2, c_actual_pay_amount: 7280, c_fail_count: 1, c_fail_amount: 1280, c_standard_amount: 3840, c_death_amount: 6000, c_additional_amount: 0, c_supplementary_payment_amount: 0, c_return_date: "2026-03-25", c_handler: "王专员", c_reviewer: "李复核", c_remarks: "MOCK_SEED_260804|应发/实发/失败三套", content: "MOCK_SEED_260804", }, { title: "202603-叶榭-农商", c_batch_id: "MB202603001", c_batch_number: "MB202603001", c_pay_month: "202603", c_town_id: "T_YEXIE", c_pay_bank: "农商", c_grain: "银行", c_number_of_people: "2", c_should_pay_count: 2, c_should_pay_amount: 7280, c_actual_pay_count: 2, c_actual_pay_amount: 7280, c_fail_count: 0, c_fail_amount: 0, c_standard_amount: 1280, c_death_amount: 6000, c_remarks: "MOCK_SEED_260804", content: "MOCK_SEED_260804", }, { title: "202603-叶榭-农行", c_batch_id: "MB202603001", c_batch_number: "MB202603001", c_pay_month: "202603", c_town_id: "T_YEXIE", c_pay_bank: "农行", c_grain: "银行", c_number_of_people: "1", c_should_pay_count: 1, c_should_pay_amount: 1280, c_actual_pay_count: 0, c_actual_pay_amount: 0, c_fail_count: 1, c_fail_amount: 1280, c_standard_amount: 1280, c_remarks: "MOCK_SEED_260804|李四冻结失败", content: "MOCK_SEED_260804", }, ]; await seedOne("pctj", COL.pctj, stats); // 校验计数 console.log("\n[校验] 各表条数抽样"); const counts = {}; for (const [k, col] of Object.entries(COL)) { const r = await selectList(token, col, 100); const mockCount = (r.list || []).filter((i) => String(JSON.stringify(i)).includes("MOCK_SEED_260804") ).length; counts[k] = { apiTotal: r.total, pageMockHits: mockCount, code: r.code }; console.log(" ", k, counts[k]); } const result = { time: new Date().toISOString(), force: FORCE, summary, counts, tips: { filter: "所有模拟数据 c_remarks/content 含 MOCK_SEED_260804", townCodes: towns().map((t) => t.code), sampleBatchNos: ["VB202604001", "MB202603001"], samplePeople: ["P001张三", "P002李四", "P003王五", "P004赵六死亡", "P005钱七匹配失败", "P006孙八暂停"], queryExample: { url: "POST /proxy_dms/content/selectContentList", body: { columnId: 1847, modelId: 1970, states: 0, pageNum: 1, pageSize: 20 }, }, }, }; const outPath = path.join(__dirname, "seed-dms-mock-result.json"); fs.writeFileSync(outPath, JSON.stringify(result, null, 2), "utf8"); console.log("\nDONE ->", outPath); })().catch((e) => { console.error(e); process.exit(1); });