刘光辉
4 小时以前 06f314545ac3514d7ce28939920866ae8188d31c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Embedded in native JNPF form events. Native forms own persistence and history.
(function createErrataRevisionRuntime() {
  const table = 'kanwu_chuli_mingxi';
  const auditInterface = '1f7b38dee4cec69f0ad88afc2fcb84e3';
  const requestInterface = '012e85618f1f4a35a1c21bea394c8ad3';
  const sourceFields = ['kanwu_zixiang_id', 'kanwu_shenqing_id', 'wenjian_id', 'banben_id',
    'wenjian_bianhao', 'wenjian_mingcheng', 'banbenhao', 'kanwu_weizhi', 'kanwu_neirong',
    'xiugai_jianyi', 'kanwu_yuanyin', 'fujian', 'shifou_yichuli'];
  const text = value => String(value ?? '').trim();
  function fail(message) { throw new Error(message); }
  function parseRows(value) {
    let rows = value;
    if (typeof value === 'string') {
      try { rows = JSON.parse(value); } catch { fail('勘误数据格式错误,请重新加载'); }
    }
    if (!Array.isArray(rows)) fail('勘误数据未正确返回,请重新加载');
    const seen = new Set();
    return rows.map(row => {
      if (!row || !text(row.kanwu_zixiang_id) || !text(row.kanwu_shenqing_id) || !text(row.wenjian_id)) {
        fail('勘误来源不完整,请联系管理员');
      }
      if (seen.has(row.kanwu_zixiang_id)) fail('勘误来源重复,请联系管理员');
      seen.add(row.kanwu_zixiang_id);
      if (!Array.isArray(row.fujian)) fail('勘误附件格式错误,请联系管理员');
      return Object.fromEntries(sourceFields.map(key => [key, row[key] ?? '']));
    });
  }
  function canonical(value) {
    if (Array.isArray(value)) return value.map(canonical);
    if (value && typeof value === 'object') return Object.fromEntries(Object.keys(value).sort().map(key => [key, canonical(value[key])]));
    return value;
  }
  const sameSource = (a, b) => sourceFields.every(key => JSON.stringify(canonical(a[key] ?? '')) === JSON.stringify(canonical(b[key] ?? '')));
  function mergeRows(current, incoming) {
    const old = new Map((Array.isArray(current) ? current : []).map(row => [row.kanwu_zixiang_id, row]));
    return incoming.map(source => {
      const previous = old.get(source.kanwu_zixiang_id);
      // Changed source text requires a fresh decision; source ids are never child primary keys.
      if (previous && sameSource(previous, source)) return { ...previous, ...source };
      return { ...source, ...(previous?.id ? { id: previous.id } : {}),
        ...(previous?.f_id ? { f_id: previous.f_id } : {}),
        chuli_jielun: '', chuli_yuanyin: '', chuli_ren_id: '', chuli_shijian: null };
    });
  }
  async function fetchSource(args, interfaceId, idField, id) {
    const response = await args.onlineUtils.request('/api/system/DataInterface/' + interfaceId + '/Actions/InfoByIds', 'post', {
      ids: [id], interfaceId, paramList: [{ field: 'search_val', defaultValue: '' }],
      propsValue: idField, relationField: 'wenjian_bianhao',
    });
    if (!Array.isArray(response?.data)) fail('勘误查询失败,请重新加载后提交');
    const matches = response.data.filter(row => text(row[idField]) === id);
    if (matches.length !== 1) fail('修订来源已失效,无法核对勘误');
    return matches[0];
  }
  function reminder(rows) {
    return rows.length ? '是' : '否';
  }
  function auditSourceChange(args) {
    if (!args.data?.xiuding_shenqing_zixiang_id) { args.setFormData(table, []); return; }
    try { args.setFormData(table, mergeRows([], parseRows(args.data.kanwu_mingxi))); }
    catch (error) {
      args.setFormData(table, []);
      args.onlineUtils.toast(error.message, 'warning');
    }
  }
  function requestSourceChange(args) {
    try {
      const value = args.data?.wenjian_id ? reminder(parseRows(args.data.kanwu_mingxi)) : '';
      args.setFormData('xiuding_shenqing_zixiang.kanwu_tixing', value, args.rowIndex);
    } catch (error) {
      args.setFormData('xiuding_shenqing_zixiang.kanwu_tixing', '勘误读取失败,请重新选择文件', args.rowIndex);
      args.onlineUtils.toast(error.message, 'warning');
    }
  }
  async function beforeAuditSubmit(args) {
    const id = text(args.formData.xiuding_shenqing_zixiang_id);
    if (!id) fail('请选择修订申请明细');
    const source = await fetchSource(args, auditInterface, 'xiuding_shenqing_zixiang_id', id);
    if (text(args.formData.xiuding_shenqing_zixiang_id) !== id) fail('修订来源已切换,请重新提交');
    if (text(source.wenjian_id) !== text(args.formData.wenjian_id) ||
        text(source.yuan_wenjian_banben_id) !== text(args.formData.yuan_wenjian_banben_id)) fail('修订文件或来源版本不一致,请重新选择');
    const incoming = parseRows(source.kanwu_mingxi);
    const current = Array.isArray(args.formData[table]) ? args.formData[table] : [];
    const next = mergeRows(current, incoming);
    const changed = current.length !== incoming.length || current.some((row, i) => !incoming[i] || !sameSource(row, incoming[i]));
    args.setFormData(table, next);
    // Restore deleted rows and surface newly approved or changed notes before allowing submission.
    if (changed) fail('已刷新勘误列表,请逐条核对并填写处理方式、原因后重新提交');
    for (let i = 0; i < next.length; i++) {
      const row = next[i];
      if (!['yixiugai_queren', 'bucaina'].includes(row.chuli_jielun) || !text(row.chuli_yuanyin)) {
        fail('第 ' + (i + 1) + ' 条勘误请选择“已修改确认”或“不采纳”,并说明原因');
      }
      if (!text(row.chuli_ren_id) || !row.chuli_shijian) fail('第 ' + (i + 1) + ' 条勘误缺少处理留痕,请重新填写处理方式或原因');
    }
  }
  async function beforeRequestSubmit(args) {
    const rows = args.formData.xiuding_shenqing_zixiang || [];
    const selection = JSON.stringify(rows.map(row => [row.wenjian_id, row.yuan_wenjian_banben_id]));
    const values = await Promise.all(rows.map(async row => {
      const source = await fetchSource(args, requestInterface, 'wenjian_id', text(row.wenjian_id));
      if (text(source.yuan_wenjian_banben_id) !== text(row.yuan_wenjian_banben_id)) fail('文件当前版本已变化,请重新选择');
      return reminder(parseRows(source.kanwu_mingxi));
    }));
    if (JSON.stringify((args.formData.xiuding_shenqing_zixiang || []).map(row => [row.wenjian_id, row.yuan_wenjian_banben_id])) !== selection) {
      fail('修订文件清单已变化,请重新提交');
    }
    let changed = false;
    values.forEach((value, i) => {
      if (text(rows[i].kanwu_tixing) !== value) changed = true;
      args.setFormData('xiuding_shenqing_zixiang.kanwu_tixing', value, i);
    });
    if (changed) fail('已更新“是否需要勘误”,请核对后重新提交');
  }
  function decisionChange(args) {
    const row = args.formData[table]?.[args.rowIndex];
    if (!row) return;
    const userId = args.onlineUtils.getUserInfo()?.userId;
    args.setFormData(table + '.chuli_ren_id', userId || '', args.rowIndex);
    args.setFormData(table + '.chuli_shijian', userId ? Date.now() : null, args.rowIndex);
  }
  // Opening a saved record must display its historical snapshot without rewriting it.
  async function auditOnLoad(args) {
    if (args.formData.id || !text(args.formData.xiuding_shenqing_zixiang_id)) return;
    const id = text(args.formData.xiuding_shenqing_zixiang_id);
    try {
      const source = await fetchSource(args, auditInterface, 'xiuding_shenqing_zixiang_id', id);
      if (text(args.formData.xiuding_shenqing_zixiang_id) === id) {
        args.setFormData(table, mergeRows(args.formData[table], parseRows(source.kanwu_mingxi)));
      }
    } catch (error) { args.onlineUtils.toast(error.message || '勘误加载失败,请重新选择文件', 'warning'); }
  }
  return { parseRows, mergeRows, reminder, auditSourceChange, requestSourceChange,
    beforeAuditSubmit, beforeRequestSubmit, decisionChange, auditOnLoad };
})