migrate-household-address-20260909.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /**
  2. * 人员模型 1970:新增户籍地址 c_household_address;
  3. * 将 c_address 别名统一为「联系地址」(原「家庭地址/联系地址」拆分)。
  4. *
  5. * 只改 fieldList,勿走 updatefieldList(生产 DMS 对 rename 会 500)。
  6. * 用法:node migrate-household-address-20260909.js
  7. */
  8. const http = require("http");
  9. const qs = require("querystring");
  10. const fs = require("fs");
  11. const path = require("path");
  12. const HOST = "121.43.55.7";
  13. const PORT = 2101;
  14. const PERSONNEL_MODEL = 1970;
  15. function post(urlPath, fields, token) {
  16. return new Promise((resolve, reject) => {
  17. const body = qs.stringify(fields || {});
  18. const headers = {
  19. "Content-Type": "application/x-www-form-urlencoded",
  20. "Content-Length": Buffer.byteLength(body),
  21. };
  22. if (token) {
  23. headers.Token = token;
  24. headers.token = token;
  25. }
  26. const req = http.request(
  27. { hostname: HOST, port: PORT, path: urlPath, method: "POST", headers },
  28. (res) => {
  29. let data = "";
  30. res.on("data", (c) => (data += c));
  31. res.on("end", () => {
  32. try {
  33. resolve(JSON.parse(data));
  34. } catch (e) {
  35. resolve({ raw: data, status: res.statusCode });
  36. }
  37. });
  38. }
  39. );
  40. req.on("error", reject);
  41. req.write(body);
  42. req.end();
  43. });
  44. }
  45. function text(shortName, alias, must, seq) {
  46. return {
  47. alias,
  48. customType: "",
  49. describe: "格式为富文本",
  50. frontType: "content",
  51. id: 2,
  52. must: !!must,
  53. name: "c_" + shortName,
  54. searchType: "2",
  55. sequence: seq || 1,
  56. showParam: "name,alias,desc,type,front_type,must,default_value",
  57. type: "text",
  58. };
  59. }
  60. function normalizeFieldList(raw) {
  61. let fl = raw;
  62. if (typeof fl === "string") fl = JSON.parse(fl);
  63. const out = {};
  64. Object.keys(fl || {}).forEach((k) => {
  65. let v = fl[k];
  66. if (typeof v === "string") v = JSON.parse(v);
  67. out[k] = v;
  68. });
  69. return out;
  70. }
  71. async function getModel(token, modelId) {
  72. const res = await post("/proxy_dms/model/getModelById", { modelId: String(modelId) }, token);
  73. if (res.code != 200) throw new Error("getModel " + modelId + " fail: " + JSON.stringify(res));
  74. return res.content;
  75. }
  76. async function applyUpdates(token, modelId, addMap, renameAliasMap) {
  77. const model = await getModel(token, modelId);
  78. const fieldList = normalizeFieldList(model.fieldList);
  79. if (Object.keys(fieldList).length < 2) {
  80. throw new Error("model " + modelId + " fieldList 异常,拒绝覆盖");
  81. }
  82. const addfieldList = {};
  83. Object.keys(addMap || {}).forEach((shortName) => {
  84. const full = "c_" + shortName;
  85. if (fieldList[full]) return;
  86. const p = addMap[shortName];
  87. p.name = full;
  88. fieldList[full] = p;
  89. addfieldList[shortName] = {
  90. alias: p.alias,
  91. type: p.type,
  92. frontType: p.frontType,
  93. must: p.must,
  94. name: shortName,
  95. describe: p.describe,
  96. searchType: p.searchType,
  97. sortType: p.sortType,
  98. sequence: p.sequence,
  99. showParam: p.showParam,
  100. customType: p.customType || "",
  101. id: p.id,
  102. };
  103. });
  104. const aliasFixed = [];
  105. Object.keys(renameAliasMap || {}).forEach((full) => {
  106. if (!fieldList[full]) return;
  107. const nextAlias = renameAliasMap[full];
  108. if (fieldList[full].alias === nextAlias) return;
  109. fieldList[full] = Object.assign({}, fieldList[full], { alias: nextAlias });
  110. aliasFixed.push(full);
  111. });
  112. if (Object.keys(addfieldList).length === 0 && aliasFixed.length === 0) {
  113. return {
  114. modelId,
  115. modelName: model.modelName,
  116. code: 200,
  117. message: "无需变更",
  118. added: [],
  119. updated: [],
  120. };
  121. }
  122. const res = await post(
  123. "/proxy_dms/model/updateFieldList",
  124. {
  125. modelId: String(modelId),
  126. fieldList: JSON.stringify(fieldList),
  127. addfieldList: JSON.stringify(addfieldList),
  128. delfieldList: JSON.stringify({}),
  129. updatefieldList: JSON.stringify({}),
  130. },
  131. token
  132. );
  133. const verify = await getModel(token, modelId);
  134. const vfl = normalizeFieldList(verify.fieldList);
  135. return {
  136. modelId,
  137. modelName: model.modelName,
  138. code: res.code,
  139. message: res.message || res.content,
  140. added: Object.keys(addfieldList),
  141. updated: aliasFixed,
  142. addressAlias: vfl.c_address ? vfl.c_address.alias : null,
  143. householdAddress: vfl.c_household_address || null,
  144. };
  145. }
  146. async function main() {
  147. const login = await post("/proxy_oauth/user/login", {
  148. userName: "user_liu",
  149. password: "WE176852439@lmx",
  150. clientId: "1",
  151. });
  152. const token = login.message;
  153. if (!token) throw new Error("login failed: " + JSON.stringify(login));
  154. const result = await applyUpdates(
  155. token,
  156. PERSONNEL_MODEL,
  157. {
  158. household_address: text("household_address", "户籍地址", false, 41),
  159. },
  160. {
  161. c_address: "联系地址",
  162. }
  163. );
  164. const outPath = path.join(
  165. __dirname,
  166. "../../docs/_migrate_household_address_20260909.json"
  167. );
  168. fs.writeFileSync(outPath, JSON.stringify(result, null, 2), "utf8");
  169. console.log(JSON.stringify(result, null, 2));
  170. }
  171. main().catch((e) => {
  172. console.error(e);
  173. process.exit(1);
  174. });