cloud-web-corejs 1.0.54-dev.804 → 1.0.54-dev.806

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -72,16 +72,17 @@ modules = {
72
72
  treeDefaultZds: [],
73
73
  productOption: {},
74
74
  showSzTaMbDialog: false,
75
- showItemSzTaMbDialog: false,
76
75
  showMenuKindDialog: false,
77
76
  productCategoryCodes: [],
78
- zdEnIndex: "",
79
77
 
80
78
  referenceEntity: null,
81
79
  referenceKey: null,
82
80
  referenceShowFields: null,
83
81
  refServiceName: null,
84
- currentIndex: 0,
82
+ // 存行引用而不是行索引:两个弹框都是 modal=false(没有遮罩),
83
+ // 开着的时候还能点后面的「新增」,而 addTaMbItems 是 splice(0,0) 插到最前面,
84
+ // 存索引会当场整体错位,配置写到隔壁行上
85
+ currentRow: null,
85
86
  showReferenceZdDialog: false,
86
87
 
87
88
  showEntityDialog: false,
@@ -101,40 +102,18 @@ modules = {
101
102
  showTmDialog: false,
102
103
 
103
104
  showToTaBmZdDialog: false,
105
+ // 和 currentRow 分开存:两个弹框可以同时打开,共用一个会互相覆盖
106
+ toTaBmZdRow: null,
104
107
  toTaBmZdEntity: null,
105
108
  toTaBmZdField: null,
106
109
  showEntityDialog3: false,
107
110
  showEntityFieldDialog3: false,
108
111
 
109
- inputValue: null, // 当前值
110
- preValue: null, // 上一次的值(变更前的值)
112
+ preValue: null, // 字段名输入框获得焦点时的原值(changeZdEn 用来迁移子行)
111
113
 
112
114
  sid: null,
113
115
  showOtherAuthDialog:false,
114
116
 
115
- zdTypeMap: {
116
- Boolean: "布尔",
117
- Integer: "整数",
118
- Long: "长整数",
119
- Decimal: "精度小数",
120
- Money: "金额",
121
- Text: "文本",
122
- TextArea: "长文本",
123
- DateTime: "日期时间",
124
- Reference: "关联表(文本)",
125
- ReferenceLong: "关联表(长整型)",
126
- },
127
-
128
- treeFlagMap:{
129
- name: "名称",
130
- wbs: "WBS码",
131
- parent: "上级ID",
132
- treePath: "树ID路径",
133
- treePathName: "树名称路径",
134
- hasChild: "是否有下级",
135
- grade: "层级",
136
- },
137
-
138
117
  readonly: false,
139
118
  isCompare: false,
140
119
  };
@@ -143,6 +122,40 @@ modules = {
143
122
  ...mapGetters([
144
123
  "userFlag",
145
124
  ]),
125
+ // 这两张映射表只用于 fieldCompare 显示"旧值",文案必须和模板里
126
+ // el-option 的 label 走同一套 $t1,否则英文环境下下拉是英文、对比值是中文
127
+ zdTypeMap() {
128
+ return {
129
+ Boolean: this.$t1("布尔"),
130
+ Integer: this.$t1("整数"),
131
+ Long: this.$t1("长整数"),
132
+ Decimal: this.$t1("精度小数"),
133
+ Money: this.$t1("金额"),
134
+ Text: this.$t1("文本"),
135
+ TextArea: this.$t1("长文本"),
136
+ DateTime: this.$t1("日期时间"),
137
+ Reference: this.$t1("关联表(文本)"),
138
+ ReferenceLong: this.$t1("关联表(长整型)"),
139
+ };
140
+ },
141
+ // 单选弹框存的是字段名字符串,zdDialog 的 rows 要的是行对象(按 fieldKey=taZdMc 匹配)
142
+ referenceKeyRows() {
143
+ return this.referenceKey ? [{taZdMc: this.referenceKey}] : [];
144
+ },
145
+ toTaBmZdFieldRows() {
146
+ return this.toTaBmZdField ? [{taZdMc: this.toTaBmZdField}] : [];
147
+ },
148
+ treeFlagMap() {
149
+ return {
150
+ name: this.$t1("名称"),
151
+ wbs: this.$t1("WBS码"),
152
+ parent: this.$t1("上级ID"),
153
+ treePath: this.$t1("树ID路径"),
154
+ treePathName: this.$t1("树名称路径"),
155
+ hasChild: this.$t1("是否有下级"),
156
+ grade: this.$t1("层级"),
157
+ };
158
+ },
146
159
  },
147
160
  created() {
148
161
  if(this.hData){
@@ -174,6 +187,12 @@ modules = {
174
187
  getData(callback) {
175
188
  if(this.extractedObj){
176
189
  this.dataId = this.extractedObj.id;
190
+ // callback 分支(getNewData → createModifyTable)不能在这里被吞掉,
191
+ // 否则从该入口进来点「创建/更新数据表」会静默无反应
192
+ if (callback) {
193
+ callback({objx: this.$baseLodash.cloneDeep(this.extractedObj)});
194
+ return;
195
+ }
177
196
  this.initData(this.extractedObj)
178
197
  //获取操作日志数据
179
198
  this.$refs["oplogTable"].initData({
@@ -222,10 +241,10 @@ modules = {
222
241
  });
223
242
  } else if (this.hData){
224
243
  this.dataId = this.hData.id
225
- /* this.isEdit = true;
226
- this.szTaMb = this.$baseLodash.cloneDeep(this.hData);
227
- this.getMenuKindAuth(this.szTaMb.menuKindCode);
228
- this.getCreatedTableColumns(); */
244
+ if (callback) {
245
+ callback({objx: this.$baseLodash.cloneDeep(this.hData)});
246
+ return;
247
+ }
229
248
  this.initData(this.$baseLodash.cloneDeep(this.hData));
230
249
  if (this.compareHData && this.$attrs.isCompare) {
231
250
  this.oldSzTaMb = this.$baseLodash.cloneDeep(this.compareHData);
@@ -240,34 +259,6 @@ modules = {
240
259
  this.getMenuKindAuth(this.szTaMb.menuKindCode);
241
260
  }
242
261
  },
243
- updateStatus(status) {
244
- let text;
245
- if (status === 3) {
246
- text = this.$t1("您确定要作废吗?");
247
- }
248
- this.$baseConfirm(text).then(() => {
249
- this.$http({
250
- aes: true,
251
- url: USER_PREFIX + `/szTaMb/updateStatus`,
252
- method: `post`,
253
- data: {
254
- id: this.dataId,
255
- status: status,
256
- },
257
- isLoading: true,
258
- success: (res) => {
259
- this.$message({
260
- message: res.content,
261
- type: "success",
262
- duration: 500,
263
- onClose: (t) => {
264
- this.$baseReload();
265
- },
266
- });
267
- },
268
- });
269
- });
270
- },
271
262
  saveData() {
272
263
  this.$refs.editForm.$baseValidate((valid) => {
273
264
  if (valid) {
@@ -277,11 +268,68 @@ modules = {
277
268
  this.$baseAlert(this.$t1("明细不能为空!"));
278
269
  return false;
279
270
  }
271
+ if (!this.validateItems(szTaZdMbDTOs)) {
272
+ return false;
273
+ }
280
274
  this.szTaMb.szTaZdMbDTOs = szTaZdMbDTOs;
281
275
  this.openPreformDialog();
282
276
  }
283
277
  });
284
278
  },
279
+ /**
280
+ * 明细必填校验。
281
+ *
282
+ * 表格开了虚拟滚动(initVxeTable 默认 scrollY.gt = 20),超过 20 行以后屏幕外的行
283
+ * 根本不会渲染,单元格里那些 el-form-item 也就没挂上去 —— el-form 的 validate
284
+ * 只能覆盖当前视口。字段数超过 20 的数据表模板是常态,所以必填必须自己按 fullData 走一遍。
285
+ */
286
+ validateItems(szTaZdMbDTOs) {
287
+ let requiredFields = [
288
+ {field: "zdEn", label: this.$t1("实体字段名称")},
289
+ {field: "zdCh", label: this.$t1("字段描述")},
290
+ ];
291
+ // Object.create(null) 而不是 {}:字段名可能叫 constructor / toString 之类,
292
+ // 普通对象会命中原型链上的同名属性,误判成重复
293
+ let seenZdEn = Object.create(null);
294
+ for (let i = 0; i < szTaZdMbDTOs.length; i++) {
295
+ let row = szTaZdMbDTOs[i];
296
+ for (let j = 0; j < requiredFields.length; j++) {
297
+ let {field, label} = requiredFields[j];
298
+ let value = row[field];
299
+ if (value === null || value === undefined || String(value).trim() === "") {
300
+ this.$baseAlert(
301
+ this.$t1("第{index}行的[{label}]不能为空!", {
302
+ index: i + 1,
303
+ label,
304
+ })
305
+ );
306
+ this.scrollToItemRow(row);
307
+ return false;
308
+ }
309
+ }
310
+ // 实体字段名重复的话建表时才会炸,这里提前拦住
311
+ let zdEn = String(row.zdEn).trim();
312
+ if (seenZdEn[zdEn] !== undefined) {
313
+ this.$baseAlert(
314
+ this.$t1("第{index}行的实体字段名称[{zdEn}]与第{index2}行重复!", {
315
+ index: i + 1,
316
+ zdEn,
317
+ index2: seenZdEn[zdEn] + 1,
318
+ })
319
+ );
320
+ this.scrollToItemRow(row);
321
+ return false;
322
+ }
323
+ seenZdEn[zdEn] = i;
324
+ }
325
+ return true;
326
+ },
327
+ scrollToItemRow(row) {
328
+ let $table = this.$refs["table-szTaZdMb"];
329
+ if ($table && $table.scrollToRow) {
330
+ $table.scrollToRow(row);
331
+ }
332
+ },
285
333
  saveDataHandle(preformData) {
286
334
  let formData = {
287
335
  ...this.szTaMb,
@@ -357,10 +405,10 @@ modules = {
357
405
  let taZdMc = row.taZdMc;
358
406
  let createdTableColumnArray = this.createdTableColumnArray;
359
407
  let oldResult = createdTableColumnArray.includes(row?.hData?.taZdMc)
360
- ? "是"
408
+ ? this.$t1("是")
361
409
  : "_";
362
410
  let result = taZdMc && createdTableColumnArray.includes(taZdMc)
363
- ? "是"
411
+ ? this.$t1("是")
364
412
  : "_";
365
413
  return [
366
414
  <el-form-item>
@@ -551,11 +599,6 @@ modules = {
551
599
  },
552
600
  },
553
601
  ],
554
- config:{
555
- // rowConfig:{
556
- // height: 60,
557
- // }
558
- }
559
602
  };
560
603
  this.$vxeTableUtil.initVxeTable(tableOption).then((opts) => {
561
604
  this.productOption = opts;
@@ -611,9 +654,14 @@ modules = {
611
654
  },
612
655
  deleteItem(row, rowIndex) {
613
656
  if (row.referenceZd) {
657
+ // clearReferenceZd 是 filter 出新数组赋值回去,传进来的 rowIndex 会失效,
658
+ // 所以下面必须重新按行引用定位
614
659
  this.clearReferenceZd(row);
615
660
  }
616
- this.szTaMb.szTaZdMbDTOs.splice(rowIndex, 1);
661
+ let index = this.szTaMb.szTaZdMbDTOs.indexOf(row);
662
+ if (index >= 0) {
663
+ this.szTaMb.szTaZdMbDTOs.splice(index, 1);
664
+ }
617
665
  },
618
666
  confirmInsertSzTaMb(rows) {
619
667
  if (rows.length > 0) {
@@ -623,21 +671,27 @@ modules = {
623
671
  this.$set(this.szTaMb, "sszstBm", row.taBm);
624
672
  }
625
673
  },
626
- confirmInsertItemSzTaMb(rows) {
627
- if (rows.length > 0) {
628
- let row = rows[0];
629
- let szTaZdMbDTO = this.szTaMb.szTaZdMbDTOs[this.zdEnIndex];
630
- this.$set(szTaZdMbDTO, "zdEn", row.taBm + "." + szTaZdMbDTO.zdEn);
631
- this.$set(szTaZdMbDTO, "dybm", row.taEn);
632
- }
633
- },
634
674
  confirmInsertMenuKind(rows) {
635
675
  if (rows.length > 0) {
636
676
  let row = rows[0];
637
677
  this.$set(this.szTaMb, "menuKindCode", row.menuKindCode);
638
678
  this.$set(this.szTaMb, "menuKindName", row.name);
679
+ // 权限是按表单分类取的,换了分类必须重取:
680
+ // 否则新建单据(进来时 menuKindCode 为空、menuKindAuth 停在 editAuth:0)
681
+ // 手工选完分类后「保存」按钮依然不渲染,流程直接走不下去
682
+ this.getMenuKindAuth(row.menuKindCode);
639
683
  }
640
684
  },
685
+ clearSszst() {
686
+ // sszst 不在 szTaMb 的初始声明里(confirmInsertSzTaMb 也是 $set 写进去的),走 $set
687
+ this.$set(this.szTaMb, "sszst", null);
688
+ this.$set(this.szTaMb, "sszstBm", null);
689
+ },
690
+ clearMenuKind() {
691
+ this.szTaMb.menuKindCode = "";
692
+ // 反向同理:分类清空后旧分类的权限不能继续留着
693
+ this.menuKindAuth = { editAuth: 0 };
694
+ },
641
695
  getNewData(callback) {
642
696
  this.getData((res0) => {
643
697
  let szTaMb = res0.objx;
@@ -658,12 +712,14 @@ modules = {
658
712
  });
659
713
  },
660
714
  createModifyTable() {
715
+ let url = this.getServiceUrl("/dbTable/createUpdateTable");
716
+ if (!url) return;
661
717
  let text = this.$t1("您确定要创建/更新数据表吗?");
662
718
  this.$baseConfirm(text).then(() => {
663
719
  this.getNewData((data) => {
664
720
  this.$http({
665
721
  aes: true,
666
- url: "/" + this.szTaMb.serviceName + `/dbTable/createUpdateTable`,
722
+ url: url,
667
723
  method: `post`,
668
724
  data: data,
669
725
  isLoading: true,
@@ -681,6 +737,18 @@ modules = {
681
737
  });
682
738
  });
683
739
  },
740
+ /**
741
+ * 拼「服务名 + 接口路径」。serviceName 为空时不要拼出 /null/... 打到后端,
742
+ * 直接提示并返回 null,由调用方中止。
743
+ */
744
+ getServiceUrl(path) {
745
+ let serviceName = this.szTaMb.serviceName;
746
+ if (!serviceName) {
747
+ this.$baseAlert(this.$t1("服务名不能为空,请先选择表单分类"));
748
+ return null;
749
+ }
750
+ return "/" + serviceName + path;
751
+ },
684
752
  isReferenceZdType(zdType) {
685
753
  return zdType === "Reference" || zdType === "ReferenceLong";
686
754
  },
@@ -691,37 +759,55 @@ modules = {
691
759
  let referenceKey = null;
692
760
  let referenceShowFields = [];
693
761
 
762
+ let referenceShowRows = [];
763
+
694
764
  if (referenceZd) {
695
765
  let index = referenceZd.indexOf(".");
696
766
  referenceEntity = referenceZd.substring(0, index);
697
767
  referenceKey = referenceZd.substr(index + 1);
698
- referenceShowFields = this.szTaMb.szTaZdMbDTOs
768
+ // 回填已有的关联显示字段行时必须带上 zdEn / zdCh:
769
+ // confirmReferenceZdDialog 新建行要用它们拼 "ref_" + zdEn,
770
+ // 只回填 taZdMc 会生成 zdEn 为 "ref_undefined"、zdCh 为空的脏行
771
+ referenceShowRows = this.szTaMb.szTaZdMbDTOs
699
772
  .filter((item) => {
700
- let flag = false;
701
- if (item.relationZd === referenceZd || item.relationZd === referenceZd2) {
702
- flag = true
703
- }
704
- return flag;
773
+ return item.relationZd === referenceZd || item.relationZd === referenceZd2;
705
774
  })
706
775
  .map((item) => {
707
- return item.referenceZd.substr(index + 1);
776
+ let taZdMc = item.referenceZd ? item.referenceZd.substr(index + 1) : null;
777
+ return {
778
+ taZdMc,
779
+ zdEn: item.zdEn ? item.zdEn.replace(/^ref_/, "") : taZdMc,
780
+ zdCh: item.zdCh,
781
+ };
708
782
  });
783
+ referenceShowFields = referenceShowRows.map((item) => item.taZdMc);
709
784
  }
710
785
 
711
786
  this.referenceEntity = referenceEntity;
712
787
  this.referenceKey = referenceKey;
713
788
  this.referenceShowFields = referenceShowFields;
714
789
  this.refServiceName = row.refServiceName ?? null;
790
+ this.referenceShowRows = referenceShowRows;
715
791
 
716
- this.referenceShowRows = referenceShowFields.map((item) => {
717
- return {
718
- taZdMc: item,
719
- };
720
- });
721
-
722
- this.currentIndex = rowIndex;
792
+ this.currentRow = row;
723
793
  this.showReferenceZdDialog = true;
724
794
  },
795
+ /**
796
+ * item 是不是 parentRow 在 parentRefZd 这个关联配置下带出来的显示字段行。
797
+ *
798
+ * relationZd 历史上出现过三种写法(无后缀 / 后缀是主字段 zdEn / 后缀是子行自己的 zdEn),
799
+ * 这里全部认,避免漏匹配导致子行变成孤儿。
800
+ */
801
+ isReferenceChildRow(item, parentRow, parentRefZd) {
802
+ if (!parentRefZd || !item.relationZd) {
803
+ return false;
804
+ }
805
+ return (
806
+ item.relationZd === parentRefZd
807
+ || item.relationZd === parentRefZd + "." + parentRow.zdEn
808
+ || item.relationZd === parentRefZd + "." + item.zdEn
809
+ );
810
+ },
725
811
  changeZdType(row) {
726
812
  let map = {
727
813
  "Integer": "11",
@@ -736,23 +822,6 @@ modules = {
736
822
  this.clearReferenceZd(row);
737
823
  }
738
824
  },
739
- getReferenceChildRows(row) {
740
- let referenceZd = row.referenceZd;
741
- if (!referenceZd && !row.zdEn) {
742
- return [];
743
- }
744
- let referenceZd2 = referenceZd ? referenceZd + "." + row.zdEn : null;
745
- let relationZdSuffix = row.zdEn ? "." + row.zdEn : null;
746
- return this.szTaMb.szTaZdMbDTOs.filter((item) => {
747
- if (referenceZd && (referenceZd === item.relationZd || referenceZd2 === item.relationZd)) {
748
- return true;
749
- }
750
- if (relationZdSuffix && item.relationZd && item.relationZd.endsWith(relationZdSuffix)) {
751
- return true;
752
- }
753
- return false;
754
- });
755
- },
756
825
  confirmClearReferenceZd(row) {
757
826
  if (!row.referenceZd) {
758
827
  return;
@@ -761,11 +830,9 @@ modules = {
761
830
  this.$baseAlert(this.$t1("该字段已在数据库中创建,不能清空关联配置"));
762
831
  return;
763
832
  }
764
- let childRows = this.getReferenceChildRows(row);
765
- if (childRows.some((item) => this.hasFieldCreated(item))) {
766
- this.$baseAlert(this.$t1("关联显示字段已在数据库中创建,不能清空关联配置"));
767
- return;
768
- }
833
+ // 这里原来还有一道「关联显示字段已在数据库中创建」的检查,是死代码:
834
+ // 显示字段行不建库、taZdMc 恒为空,hasFieldCreated 永远返回 false。
835
+ // 连同它唯一的调用方 getReferenceChildRows 一并删掉。
769
836
  let text = this.$t1("清空关联配置将同时删除关联显示字段,您确定要继续吗?");
770
837
  this.$baseConfirm(text).then(() => {
771
838
  this.clearReferenceZd(row);
@@ -788,7 +855,11 @@ modules = {
788
855
  row.refServiceName = null;
789
856
  },
790
857
  confirmReferenceZdDialog() {
791
- let row = this.szTaMb.szTaZdMbDTOs[this.currentIndex];
858
+ let row = this.currentRow;
859
+ if (!row) {
860
+ this.showReferenceZdDialog = false;
861
+ return;
862
+ }
792
863
  let oldReferenceZd = row.referenceZd;
793
864
  let oldReferenceZd2 = row.referenceZd + "." + row.zdEn;
794
865
 
@@ -799,6 +870,18 @@ modules = {
799
870
 
800
871
  let referenceShowFields = this.referenceShowFields;
801
872
 
873
+ // 关联表 / 关联字段任一为空都拼不出合法的 referenceZd,硬走下去
874
+ // 新建行的 relationZd 会拼成 "null.xxx",父子彻底断开、之后再也认不回来。
875
+ // 两个都为空是"清空关联配置",属于合法操作,放行走下面的删除分支。
876
+ if (referenceEntity && !referenceKey) {
877
+ this.$baseAlert(this.$t1("关联字段不能为空"));
878
+ return;
879
+ }
880
+ if (!referenceZd && referenceShowFields.length) {
881
+ this.$baseAlert(this.$t1("关联表不能为空"));
882
+ return;
883
+ }
884
+
802
885
  let keys = referenceShowFields.map((item) => {
803
886
  return referenceEntity + "." + item;
804
887
  });
@@ -819,6 +902,10 @@ modules = {
819
902
  delIndex.push(index);
820
903
  } else {
821
904
  item.refServiceName = refServiceName;
905
+ // 关联表没变、只换了关联字段时,保留下来的子行必须把 relationZd 迁到新的
906
+ // referenceZd 上。否则它们既变成认不回来的孤儿行,
907
+ // 又会因为下面 oldKeys 匹配不到而被当成"新字段"重复插入一遍。
908
+ item.relationZd = referenceZd ? referenceZd + "." + row.zdEn : null;
822
909
  }
823
910
  }
824
911
  });
@@ -831,7 +918,7 @@ modules = {
831
918
  }
832
919
 
833
920
  let oldKeys = this.szTaMb.szTaZdMbDTOs
834
- .filter((item) => (referenceZd === item.relationZd || (referenceZd + "." + item.zdEn) === item.relationZd))
921
+ .filter((item) => this.isReferenceChildRow(item, row, referenceZd))
835
922
  .map((item) => item.referenceZd);
836
923
  let addReferenceShowFields = referenceShowFields.filter((item, index) => {
837
924
  return !oldKeys.includes(referenceEntity + "." + item);
@@ -839,23 +926,32 @@ modules = {
839
926
 
840
927
  let addIndex = -1;
841
928
  let lastIndex = this.szTaMb.szTaZdMbDTOs.findLastIndex((item) => {
842
- return referenceZd === item.relationZd || (referenceZd + "." + item.zdEn) === item.relationZd;
929
+ return this.isReferenceChildRow(item, row, referenceZd);
843
930
  });
844
- addIndex = lastIndex >= 0 ? lastIndex + 1 : this.currentIndex + 1;
931
+ addIndex = lastIndex >= 0
932
+ ? lastIndex + 1
933
+ : this.szTaMb.szTaZdMbDTOs.indexOf(row) + 1;
845
934
 
846
935
  let referenceShowRows = this.referenceShowRows;
847
936
 
848
937
  let addReferenceShowRows = referenceShowRows.filter((item, index) => {
849
938
  return addReferenceShowFields.includes(item.taZdMc);
850
939
  });
940
+ // 已占用的字段名,用来给新建行避让重名;本轮生成的也要边生成边记进去
941
+ let usedZdEns = this.szTaMb.szTaZdMbDTOs
942
+ .map((item) => item.zdEn)
943
+ .filter((item) => !!item);
851
944
  addReferenceShowRows.forEach((item, index) => {
852
945
  let rIndex = addIndex + index;
853
946
  let orders = (row.orders || 0) + index + 1;
854
947
 
948
+ let zdEn = this.buildReferenceZdEn(item.zdEn || item.taZdMc, row, usedZdEns);
949
+ usedZdEns.push(zdEn);
950
+
855
951
  let newItem = this.createRow();
856
952
  Object.assign(newItem, {
857
- zdEn: "ref_" + item.zdEn,
858
- zdCh: item.zdCh,
953
+ zdEn,
954
+ zdCh: item.zdCh || null,
859
955
  required: false,
860
956
  referenceZd: referenceEntity + "." + item.taZdMc,
861
957
  zdType: "Text",
@@ -873,6 +969,35 @@ modules = {
873
969
  this.handleReferenceOrders(row);
874
970
  this.showReferenceZdDialog = false;
875
971
  },
972
+ /**
973
+ * 生成关联显示字段行的实体字段名。
974
+ *
975
+ * 基础名是 ref_<源字段>。两个字段绑同一张表的同一个字段时会撞
976
+ * (典型:创建人 / 修改人都关联 sc_user.id 并显示 name,都想叫 ref_name),
977
+ * 撞了才退化成 ref_<父字段>_<源字段>;还撞就往后加序号。
978
+ * 先到先得,已存在的行不改名,所以存量数据不受影响。
979
+ *
980
+ * @param {String} srcName 源字段名
981
+ * @param {Object} parentRow 发起关联的主字段行
982
+ * @param {Array} usedZdEns 已占用的字段名(含本轮刚生成的)
983
+ */
984
+ buildReferenceZdEn(srcName, parentRow, usedZdEns) {
985
+ let base = "ref_" + srcName;
986
+ if (!usedZdEns.includes(base)) {
987
+ return base;
988
+ }
989
+ let withParent = parentRow.zdEn
990
+ ? "ref_" + parentRow.zdEn + "_" + srcName
991
+ : base;
992
+ if (withParent !== base && !usedZdEns.includes(withParent)) {
993
+ return withParent;
994
+ }
995
+ let index = 2;
996
+ while (usedZdEns.includes(withParent + "_" + index)) {
997
+ index++;
998
+ }
999
+ return withParent + "_" + index;
1000
+ },
876
1001
  createRow(){
877
1002
  let row = {
878
1003
  "orders": null,
@@ -912,11 +1037,9 @@ modules = {
912
1037
  let orders = row.orders || 0;
913
1038
  if (referenceZd) {
914
1039
  this.szTaMb.szTaZdMbDTOs
915
- .filter((item) => referenceZd === item.relationZd || (referenceZd + "." + item.zdEn === item.relationZd))
1040
+ .filter((item) => this.isReferenceChildRow(item, row, referenceZd))
916
1041
  .forEach((item, index) => {
917
- if (referenceZd === item.relationZd || (referenceZd + "." + item.zdEn === item.relationZd)) {
918
- item.orders = orders + index + 1;
919
- }
1042
+ item.orders = orders + index + 1;
920
1043
  });
921
1044
  }
922
1045
  },
@@ -926,14 +1049,23 @@ modules = {
926
1049
  if (this.referenceEntity !== row.taBm) {
927
1050
  this.referenceKey = null;
928
1051
  this.referenceShowFields = [];
1052
+ // 换了关联表,上一张表的显示字段行必须一起丢掉,
1053
+ // 否则 confirmReferenceZdDialog 会拿旧表的 taZdMc 去拼新表的 referenceZd
1054
+ this.referenceShowRows = [];
929
1055
  }
930
1056
  this.referenceEntity = row.taBm;
931
1057
  this.refServiceName = row.serviceName;
932
1058
  }
933
1059
  },
1060
+ clearReferenceEntity() {
1061
+ this.referenceKey = null;
1062
+ this.refServiceName = null;
1063
+ this.referenceShowFields = [];
1064
+ this.referenceShowRows = [];
1065
+ },
934
1066
  openEntityFieldDialog1() {
935
1067
  if (!this.referenceEntity) {
936
- this.$baseAlert("关联表不能为空");
1068
+ this.$baseAlert(this.$t1("关联表不能为空"));
937
1069
  return;
938
1070
  }
939
1071
  this.showEntityFieldDialog1 = true;
@@ -946,21 +1078,22 @@ modules = {
946
1078
  },
947
1079
  openEntityFieldDialog2() {
948
1080
  if (!this.referenceEntity) {
949
- this.$baseAlert("关联表不能为空");
1081
+ this.$baseAlert(this.$t1("关联表不能为空"));
950
1082
  return;
951
1083
  }
952
1084
  this.showEntityFieldDialog2 = true;
953
1085
  },
954
1086
  confirmEntityFieldDialog2(rows) {
955
- if (rows.length) {
956
- this.referenceShowRows = rows;
957
- this.referenceShowFields = rows.map((row) => {
958
- return row.taZdMc;
959
- });
960
- }
1087
+ // 不能用 rows.length 兜底:回填可用之后,把勾选全部取消掉
1088
+ // 就是"清空显示字段"的正常操作,必须让它生效
1089
+ this.referenceShowRows = rows || [];
1090
+ this.referenceShowFields = this.referenceShowRows.map((row) => {
1091
+ return row.taZdMc;
1092
+ });
961
1093
  },
962
1094
  getCreatedTableColumns() {
963
- if (!this.szTaMb.taBm) return;
1095
+ // 这里是首屏静默取数,serviceName 缺失时直接跳过,不弹提示打扰用户
1096
+ if (!this.szTaMb.taBm || !this.szTaMb.serviceName) return;
964
1097
  this.$http({
965
1098
  aes: true,
966
1099
  url: "/" + this.szTaMb.serviceName + "/dbTable/getTableColumns",
@@ -1044,9 +1177,6 @@ modules = {
1044
1177
  let min = 100;
1045
1178
  let szTaZdMbDTOs = this.szTaMb.szTaZdMbDTOs;
1046
1179
  let value = 0;
1047
- let allOrders = szTaZdMbDTOs
1048
- .filter((item) => item.orders !== null && item.orders !== undefined)
1049
- .map((item) => item.orders);
1050
1180
  szTaZdMbDTOs.forEach((item) => {
1051
1181
  let orders = item.orders;
1052
1182
  if (orders !== null && orders !== undefined && orders < 9000) {
@@ -1091,10 +1221,12 @@ modules = {
1091
1221
  this.$baseAlert(this.$t1("数据表不能为空"));
1092
1222
  return;
1093
1223
  }
1224
+ let url = this.getServiceUrl("/dbTable/getSzTaZdMbs");
1225
+ if (!url) return;
1094
1226
  this.showDtDialog = false;
1095
1227
  this.$http({
1096
1228
  // aes: true,
1097
- url: "/" + this.szTaMb.serviceName + `/dbTable/getSzTaZdMbs`,
1229
+ url: url,
1098
1230
  method: `post`,
1099
1231
  data: {
1100
1232
  stringOne: dbTable,
@@ -1198,10 +1330,15 @@ modules = {
1198
1330
  }
1199
1331
  this.toTaBmZdEntity = toTaBmZdEntity;
1200
1332
  this.toTaBmZdField = toTaBmZdField;
1201
- this.currentIndex = rowIndex;
1333
+ this.toTaBmZdRow = row;
1202
1334
  this.showToTaBmZdDialog = true;
1203
1335
  },
1204
1336
  confirmToTaBmZdDialog() {
1337
+ let row = this.toTaBmZdRow;
1338
+ if (!row) {
1339
+ this.showToTaBmZdDialog = false;
1340
+ return;
1341
+ }
1205
1342
  let toTaBmZdEntity = this.toTaBmZdEntity;
1206
1343
  let toTaBmZdField = this.toTaBmZdField;
1207
1344
  if (!toTaBmZdEntity) {
@@ -1212,8 +1349,7 @@ modules = {
1212
1349
  this.$baseAlert(this.$t1("对应表字段不能为空"));
1213
1350
  return;
1214
1351
  }
1215
- this.szTaMb.szTaZdMbDTOs[this.currentIndex].toTaBmZd =
1216
- toTaBmZdEntity + "." + toTaBmZdField;
1352
+ row.toTaBmZd = toTaBmZdEntity + "." + toTaBmZdField;
1217
1353
  this.showToTaBmZdDialog = false;
1218
1354
  },
1219
1355
  openEntityDialog3() {
@@ -1241,20 +1377,31 @@ modules = {
1241
1377
  this.toTaBmZdField = row.taZdMc;
1242
1378
  }
1243
1379
  },
1244
- inputZdEn(row) {
1245
-
1246
- this.preValue = row.zdEn; // 更新旧值
1247
- this.fkey = true
1380
+ /**
1381
+ * 进入字段名输入框时记下原值。
1382
+ *
1383
+ * 原来是靠 keydown 开闸(fkey),但鼠标右键粘贴、拖拽填入、部分输入法提交路径
1384
+ * 都不产生 keydown,那些场景下 changeZdEn 整个被跳过,子行的 relationZd
1385
+ * 会停在旧字段名上变成孤儿行。改成 focus 播种,任何修改途径都覆盖得到。
1386
+ */
1387
+ cacheZdEn(row) {
1388
+ this.preValue = row.zdEn;
1248
1389
  },
1390
+ /**
1391
+ * 改字段名时,把该行关联带出来的显示字段行的 relationZd 一起迁过去。
1392
+ */
1249
1393
  changeZdEn(val, row) {
1250
- if(!this.fkey)return
1251
1394
  let oldVal = this.preValue;
1252
- let newVal = val
1395
+ let newVal = val;
1396
+ this.preValue = newVal;
1397
+ if (oldVal === undefined || oldVal === null || oldVal === newVal) {
1398
+ return;
1399
+ }
1253
1400
  if (this.isReferenceZdType(row.zdType)) {
1254
1401
  let referenceZd = row.referenceZd;
1255
1402
  if (referenceZd) {
1256
- let referenceZd2 = row.referenceZd + "." + oldVal
1257
- let relationZd = row.referenceZd + "." + newVal
1403
+ let referenceZd2 = referenceZd + "." + oldVal;
1404
+ let relationZd = referenceZd + "." + newVal;
1258
1405
  this.szTaMb.szTaZdMbDTOs.forEach((item, index) => {
1259
1406
  if (referenceZd === item.relationZd || referenceZd2 === item.relationZd) {
1260
1407
  item.relationZd = relationZd;
@@ -1262,7 +1409,6 @@ modules = {
1262
1409
  });
1263
1410
  }
1264
1411
  }
1265
- this.fkey = false
1266
1412
  },
1267
1413
 
1268
1414
  getOtherMenuKindAuth() {
@@ -1287,7 +1433,7 @@ modules = {
1287
1433
  this.$baseReload()
1288
1434
  },
1289
1435
  excelExport(){
1290
- this.$excelExport({title: '数据表字段明细导出', targetRef: 'table-szTaZdMb', prefix: USER_PREFIX, type: 'selected'})
1436
+ this.$excelExport({title: this.$t1('数据表字段明细导出'), targetRef: 'table-szTaZdMb', prefix: USER_PREFIX, type: 'selected'})
1291
1437
  },
1292
1438
  getHValue(row, column) {
1293
1439
  if (row.hData && row.hData.id) {