| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318 |
- /**
- * 业务流程缺字段补齐(2026-08-06)
- * - 发放明细 1974:实发/回盘结果
- * - 区划 1965:level/code/entrust_plan_code
- * - 流程 1967:待补发台账结构化字段
- *
- * 用法:node migrate-missing-biz-fields.js
- */
- 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;
- function post(urlPath, fields, token) {
- 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 req = http.request(
- { hostname: HOST, port: PORT, path: urlPath, 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 });
- }
- });
- }
- );
- req.on("error", reject);
- req.write(body);
- req.end();
- });
- }
- function text(shortName, alias, must, seq) {
- return {
- alias,
- customType: "",
- describe: "格式为富文本",
- frontType: "content",
- id: 2,
- must: !!must,
- name: "c_" + shortName,
- searchType: "2",
- sequence: seq || 1,
- showParam: "name,alias,desc,type,front_type,must,default_value",
- type: "text",
- };
- }
- function num(shortName, alias, must, seq) {
- return {
- alias,
- customType: "",
- describe: "number",
- frontType: "float_num",
- id: 6,
- must: !!must,
- name: "c_" + shortName,
- searchType: "1,3",
- sequence: seq || 5,
- showParam: "name,alias,desc,type,front_type,must,default_value",
- sortType: "1,2",
- type: "double",
- };
- }
- function ts(shortName, alias, must, seq) {
- return {
- alias,
- customType: "",
- describe: "时间戳",
- frontType: "date_time",
- id: 3,
- must: !!must,
- name: "c_" + shortName,
- searchType: "3",
- sequence: seq || 2,
- showParam: "name,alias,describe,type,front_type,must,date_type,date_picker",
- sortType: "1,2",
- type: "timestamp",
- };
- }
- function normalizeFieldList(raw) {
- let fl = raw;
- if (typeof fl === "string") fl = JSON.parse(fl);
- const out = {};
- Object.keys(fl || {}).forEach((k) => {
- let v = fl[k];
- if (typeof v === "string") v = JSON.parse(v);
- out[k] = v;
- });
- return out;
- }
- async function getModel(token, modelId) {
- const res = await post("/proxy_dms/model/getModelById", { modelId: String(modelId) }, token);
- if (res.code != 200) throw new Error("getModel " + modelId + " fail: " + JSON.stringify(res));
- return res.content;
- }
- async function updateFieldList(token, modelId, addMap) {
- const model = await getModel(token, modelId);
- const fieldList = normalizeFieldList(model.fieldList);
- if (Object.keys(fieldList).length < 2) {
- throw new Error("model " + modelId + " fieldList 异常,拒绝覆盖");
- }
- const addfieldList = {};
- Object.keys(addMap || {}).forEach((shortName) => {
- const full = "c_" + shortName;
- if (fieldList[full]) return;
- const p = addMap[shortName];
- p.name = full;
- fieldList[full] = p;
- addfieldList[shortName] = {
- alias: p.alias,
- type: p.type,
- frontType: p.frontType,
- must: p.must,
- name: shortName,
- describe: p.describe,
- searchType: p.searchType,
- sortType: p.sortType,
- sequence: p.sequence,
- showParam: p.showParam,
- customType: p.customType || "",
- id: p.id,
- };
- });
- if (Object.keys(addfieldList).length === 0) {
- return {
- modelId,
- modelName: model.modelName,
- code: 200,
- message: "无需新增",
- added: [],
- fields: Object.keys(fieldList).sort(),
- };
- }
- const res = await post(
- "/proxy_dms/model/updateFieldList",
- {
- modelId: String(modelId),
- fieldList: JSON.stringify(fieldList),
- addfieldList: JSON.stringify(addfieldList),
- delfieldList: JSON.stringify({}),
- updatefieldList: JSON.stringify({}),
- },
- token
- );
- const verify = await getModel(token, modelId);
- return {
- modelId,
- modelName: model.modelName,
- code: res.code,
- message: res.message || res.content,
- added: Object.keys(addfieldList),
- fields: Object.keys(normalizeFieldList(verify.fieldList)).sort(),
- };
- }
- function remarkTag(remarks, key) {
- if (!remarks || !key) return null;
- const re = new RegExp("(?:^|[|;])" + key + "=([^|;]+)");
- const m = String(remarks).match(re);
- return m ? m[1] : null;
- }
- async function backfillRegions(token) {
- const list = await post(
- "/proxy_dms/content/selectContentList",
- { columnId: "1842", modelId: "1965", page: "0", pageSize: "200", states: "0" },
- token
- );
- const rows = (list.content && list.content.data) || [];
- let updated = 0;
- for (const row of rows) {
- const remarks = row.c_remarks || "";
- const code = row.c_code || remarkTag(remarks, "code");
- const level = row.c_level || remarkTag(remarks, "level");
- const plan = row.c_entrust_plan_code || remarkTag(remarks, "plan") || remarkTag(remarks, "entrust");
- if (!code && !level && !plan) continue;
- if (row.c_code && row.c_level && (!plan || row.c_entrust_plan_code)) continue;
- const content = {
- id: row.id,
- c_code: code || row.c_code || "",
- c_level: level || row.c_level || "",
- };
- if (plan) content.c_entrust_plan_code = plan;
- const res = await post(
- "/proxy_dms/content/updateContent",
- { columnId: "1842", modelId: "1965", content: JSON.stringify(content) },
- token
- );
- if (res.code == 200) updated++;
- }
- return { total: rows.length, updated };
- }
- async function backfillPaymentReturns(token) {
- const list = await post(
- "/proxy_dms/content/selectContentList",
- { columnId: "1849", modelId: "1974", page: "0", pageSize: "200", states: "0" },
- token
- );
- const rows = (list.content && list.content.data) || [];
- let updated = 0;
- for (const row of rows) {
- if (row.c_return_success != null && row.c_return_success !== "") continue;
- const remarks = String(row.c_remarks || "");
- const fail = /回盘失败|RETURN_FAIL/.test(remarks);
- const ok = /回盘成功/.test(remarks);
- if (!fail && !ok) continue;
- const total = row.c_total_amount != null ? Number(row.c_total_amount) : 0;
- const content = {
- id: row.id,
- c_return_success: fail ? "false" : "true",
- c_actual_amount: fail ? 0 : total,
- c_return_result: fail ? "失败" : "成功",
- };
- const m = remarks.match(/回盘失败\|([^|]*)/);
- if (fail && m && m[1] && /^CODE_/.test(m[1])) {
- content.c_fail_reason_code = m[1];
- }
- const res = await post(
- "/proxy_dms/content/updateContent",
- { columnId: "1849", modelId: "1974", content: JSON.stringify(content) },
- token
- );
- if (res.code == 200) updated++;
- }
- return { total: rows.length, updated };
- }
- (async () => {
- const login = await post("/proxy_oauth/user/login", {
- userName: "user_liu",
- password: "WE176852439@lmx",
- clientId: "1",
- });
- if (login.code != 200) throw new Error("login fail " + JSON.stringify(login));
- const token = login.message;
- console.log("login ok");
- const results = [];
- results.push(
- await updateFieldList(token, 1974, {
- actual_amount: num("actual_amount", "实发金额", false, 30),
- return_success: text("return_success", "回盘是否成功", false, 31),
- return_result: text("return_result", "回盘结果", false, 32),
- fail_reason_code: text("fail_reason_code", "回盘失败原因码", false, 33),
- })
- );
- console.log("ffmx", results[results.length - 1]);
- results.push(
- await updateFieldList(token, 1965, {
- level: text("level", "区划层级", false, 10),
- code: text("code", "区划业务码", false, 11),
- entrust_plan_code: text("entrust_plan_code", "委托方案代码", false, 12),
- })
- );
- console.log("xzqh", results[results.length - 1]);
- results.push(
- await updateFieldList(token, 1967, {
- personnel_name: text("personnel_name", "人员姓名", false, 40),
- id_number: text("id_number", "身份证号", false, 41),
- source_payment_id: text("source_payment_id", "来源发放明细ID", false, 42),
- source_pay_month: text("source_pay_month", "来源发放年月", false, 43),
- fail_reason_code: text("fail_reason_code", "失败原因码", false, 44),
- alert_id: text("alert_id", "关联告警ID", false, 45),
- reissue_batch_id: text("reissue_batch_id", "补发批次ID", false, 46),
- reissue_payment_id: text("reissue_payment_id", "补发明细ID", false, 47),
- reissue_time: ts("reissue_time", "补发时间", false, 48),
- })
- );
- console.log("lcb", results[results.length - 1]);
- const regionBackfill = await backfillRegions(token);
- console.log("region backfill", regionBackfill);
- const payBackfill = await backfillPaymentReturns(token);
- console.log("payment return backfill", payBackfill);
- const out = { results, regionBackfill, payBackfill };
- const outPath = path.join(__dirname, "migrate-missing-biz-fields-result.json");
- fs.writeFileSync(outPath, JSON.stringify(out, null, 2), "utf8");
- console.log("DONE ->", outPath);
- const bad = results.filter((r) => r.code != 200);
- if (bad.length) process.exit(1);
- for (const r of results) {
- for (const a of r.added || []) {
- if (!r.fields.includes("c_" + a)) {
- console.error("missing after add", r.modelId, a);
- process.exit(1);
- }
- }
- }
- })().catch((e) => {
- console.error(e);
- process.exit(1);
- });
|