legacy-direct-projection.mjs 5.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. function text(value) { return String(value ?? '').trim(); }
  2. function number(value, fallback = 0) { const parsed = Number(value); return Number.isFinite(parsed) ? parsed : fallback; }
  3. function dateValue(value) {
  4. const raw = text(value);
  5. if (!/^\d{4}-\d{1,2}-\d{1,2}(?:[ T]\d{1,2}:\d{2}(?::\d{2}(?:\.\d+)?)?)?/.test(raw)) return null;
  6. const normalized = raw.replace(/^(\d{4})-(\d)(?=-)/, '$1-0$2').replace(/-(\d)(?=[ T])/, '-0$1').replace(' ', 'T');
  7. const date = new Date(normalized + (normalized.includes('T') ? '+08:00' : 'T00:00:00+08:00'));
  8. return Number.isNaN(date.getTime()) ? null : { __type: 'Date', iso: date.toISOString() };
  9. }
  10. function setIf(body, key, value) { if (value !== null && value !== undefined && value !== '') body[key] = value; }
  11. const legacyAddonFields = {
  12. 53: ['kcid','scid','xxcs','yhid','jrscb'],
  13. 54: ['pl','bxrq','dslx','dszt','fxpl','jffs','jssj','kcid','kssj','plxm','scsj','sdsd','szmd','szyh','yysj','yykcid'],
  14. 56: ['pl','con','djq','ygg','dqrq','dsid','fxrl','xxqs','szmdid','userId','learned'],
  15. 58: ['yxx','cksl','kcid','syjd','yhid'],
  16. 59: ['pf','jffs','jsmz','kcid','kclx','kcmc','kzsj','pjnr','pldp','xymz','yyds','plpjsj','szmdid'],
  17. 60: ['fxzt','kcid','plid','wcsj','yhid','kywrq','kywsj','xxjlid','orderId'],
  18. 61: ['df','askid','wrong','userId','answerid','dontKnow','prevScore','totalScore'],
  19. };
  20. const numericAddonFields = new Set(['scid','xxcs','yhid@53','djq','ygg','userId@56','learned','yxx','cksl','pf','kcid@60','plid','yhid@60','xxjlid','orderId']);
  21. function signatureValue(modelId, field, value) {
  22. return numericAddonFields.has(field) || numericAddonFields.has(`${field}@${modelId}`) ? number(value) : text(value);
  23. }
  24. function addonSignature(modelId, source) {
  25. return JSON.stringify(legacyAddonFields[modelId].map((field) => signatureValue(modelId, field, source[field])));
  26. }
  27. function commonBody(modelId, row, itemId) {
  28. const spec = specs[modelId];
  29. const generalId = number(row.GeneralID ?? row.generalId);
  30. const body = {
  31. company,
  32. sourceKey: `legacy:model:${modelId}:general:${generalId}`,
  33. generalId,
  34. itemId,
  35. modelId,
  36. nodeId: number(row.NodeID ?? row.nodeId, spec.nodeId),
  37. tableName: spec.tableName,
  38. title: text(row.Title ?? row.title),
  39. subtitle: text(row.Subtitle ?? row.subtitle),
  40. inputer: text(row.Inputer ?? row.inputer),
  41. topImg: text(row.TopImg ?? row.topImg),
  42. template: text(row.Template ?? row.template),
  43. hits: number(row.Hits ?? row.hits),
  44. status: 99,
  45. };
  46. const created = dateValue(row.CreateTime ?? row.createTime);
  47. if (created) { body.createTime = created; body.upDateTime = created; }
  48. return body;
  49. }
  50. function addonBody(modelId, row, itemId, generalId) {
  51. // Parse REST/SDK reserves the property name `id`. The physical legacy id is
  52. // assigned in one controlled SQL step after both objects exist.
  53. const body = { company, sourceKey: `legacy:model:${modelId}:general:${generalId}` };
  54. if (modelId === 53) Object.assign(body, {
  55. kcid: text(row.kcid), scid: number(row.scid), xxcs: number(row.xxcs), yhid: number(row.yhid), jrscb: text(row.jrscb),
  56. });
  57. if (modelId === 54) for (const field of ['pl','bxrq','dslx','dszt','fxpl','jffs','jssj','kcid','kssj','plxm','scsj','sdsd','szmd','szyh','yysj','yykcid']) body[field] = text(row[field]);
  58. if (modelId === 56) Object.assign(body, {
  59. pl: text(row.pl), con: text(row.con), djq: number(row.djq), ygg: number(row.ygg), dqrq: text(row.dqrq),
  60. dsid: text(row.dsid), fxrl: text(row.fxrl), xxqs: text(row.xxqs), szmdid: text(row.szmdid),
  61. userId: number(row.UserID ?? row.userId), learned: number(row.learned),
  62. });
  63. if (modelId === 58) Object.assign(body, {
  64. yxx: number(row.yxx), cksl: number(row.cksl), kcid: text(row.kcid), syjd: text(row.syjd), yhid: text(row.yhid),
  65. });
  66. if (modelId === 59) {
  67. for (const field of ['jffs','jsmz','kcid','kclx','kcmc','kzsj','pjnr','pldp','xymz','yyds','plpjsj','szmdid']) body[field] = text(row[field]);
  68. setIf(body, 'pf', row.pf === null || row.pf === '' ? null : number(row.pf));
  69. body.legacyGeneralId = generalId;
  70. body.studentName = text(row.Title ?? row.title);
  71. body.coachName = text(row.Inputer ?? row.inputer);
  72. body.courseName = text(row.kcmc ?? row.Subtitle ?? row.subtitle);
  73. body.storeId = number(row.szmdid);
  74. const lessonAt = dateValue(row.plpjsj) || dateValue(row.CreateTime ?? row.createTime);
  75. const sourceCreatedAt = dateValue(row.CreateTime ?? row.createTime);
  76. if (lessonAt) body.lessonAt = lessonAt;
  77. if (sourceCreatedAt) body.sourceCreatedAt = sourceCreatedAt;
  78. }
  79. if (modelId === 60) Object.assign(body, {
  80. fxzt: text(row.fxzt), kcid: number(row.kcid), plid: number(row.plid), wcsj: text(row.wcsj), yhid: number(row.yhid),
  81. kywrq: text(row.kywrq), kywsj: text(row.kywsj), xxjlid: number(row.xxjlid), orderId: number(row.orderId),
  82. });
  83. if (modelId === 61) Object.assign(body, {
  84. df: text(row.df), askid: text(row.askid), wrong: text(row.wrong), userId: text(row.UserID ?? row.userId),
  85. answerid: text(row.answerid), dontKnow: text(row.dontKnow), prevScore: text(row.prev_score ?? row.prevScore), totalScore: text(row.totalScore),
  86. });
  87. return body;
  88. }
  89. export function projectionFor(companyValue, specsValue) { company=companyValue; specs=specsValue; return {commonBody,addonBody,legacyAddonFields,signatureValue}; }
  90. let company, specs;
  91. export { commonBody, addonBody, legacyAddonFields, signatureValue };