syntec3-0-ui-components-test 1.0.0

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.
Files changed (99) hide show
  1. package/README.md +5 -0
  2. package/dist/S3_0UC_main.csv +4 -0
  3. package/dist/S3_0UC_sub.csv +2 -0
  4. package/dist/globalVariableS3_0UC.json +1 -0
  5. package/dist/style.css +1 -0
  6. package/dist/syntec3-0-ui-components.es.js +19518 -0
  7. package/dist/syntec3-0-ui-components.es.js.map +1 -0
  8. package/dist/syntec3-0-ui-components.umd.js +23 -0
  9. package/dist/syntec3-0-ui-components.umd.js.map +1 -0
  10. package/dist/vite.svg +1 -0
  11. package/dist/web.config +17 -0
  12. package/package.json +137 -0
  13. package/src/App.vue +31 -0
  14. package/src/assets/fonts/genYoGothicTW-normal.js +7 -0
  15. package/src/assets/image/defaultImage.png +0 -0
  16. package/src/assets/vue.svg +1 -0
  17. package/src/components/Layout/modules/fullPageGlobal.vue +113 -0
  18. package/src/components/Layout/modules/viewFile/config.js +65 -0
  19. package/src/components/Layout/modules/viewFile/createView.vue +1000 -0
  20. package/src/components/Layout/modules/viewFile/filterCriteria.vue +816 -0
  21. package/src/components/Layout/modules/viewFile/viewList.vue +291 -0
  22. package/src/components/Layout/modules/viewFile/viewManageTool.js +271 -0
  23. package/src/components/Layout/modules/viewFile/viewRecord.vue +472 -0
  24. package/src/components/Layout/modules/viewFile/viewTabs.vue +542 -0
  25. package/src/components/Layout/tools/GlobalDialog.vue +115 -0
  26. package/src/components/Pagination.vue +139 -0
  27. package/src/components/columnConfigNext.vue +273 -0
  28. package/src/components/customFilter/customFilter.vue +492 -0
  29. package/src/components/customFilter/filterCriteria.vue +769 -0
  30. package/src/components/customTable/components/headerOperation/index.vue +136 -0
  31. package/src/components/customTable/components/headerTabs/index.vue +171 -0
  32. package/src/components/customTable/components/tableContent/index.vue +440 -0
  33. package/src/components/customTable/index.vue +305 -0
  34. package/src/components/dialog.vue +85 -0
  35. package/src/components/pageContent.vue +48 -0
  36. package/src/components/popover.vue +402 -0
  37. package/src/configFiles/apiFile/baseApiList.json +11 -0
  38. package/src/configFiles/apiFile/coreApiList.json +24 -0
  39. package/src/configFiles/apiFile/mesApiList.json +4 -0
  40. package/src/configFiles/apiFile/mmsApiList.json +3 -0
  41. package/src/configFiles/errorCode.json +291 -0
  42. package/src/configFiles/version.js +2 -0
  43. package/src/i18n/lang/en-us.json +2060 -0
  44. package/src/i18n/lang/errorCodeTranslate.mjs +847 -0
  45. package/src/i18n/lang/zh-cn.json +2062 -0
  46. package/src/i18n/lang/zh-tw.json +2059 -0
  47. package/src/index.js +115 -0
  48. package/src/main.js +51 -0
  49. package/src/plugins/excel.js +88 -0
  50. package/src/router/index.js +41 -0
  51. package/src/scriptFiles/apiConfig/baseApis.js +10 -0
  52. package/src/scriptFiles/apiConfig/mesApis.js +10 -0
  53. package/src/scriptFiles/apiConfig/mmsApis.js +10 -0
  54. package/src/scriptFiles/apiConfig/privateCloudCoreApis.js +13 -0
  55. package/src/scriptFiles/apiConfig/serviceRoute.js +23 -0
  56. package/src/scriptFiles/apis/baseApiFunction.js +63 -0
  57. package/src/scriptFiles/apis/mesApiFunction.js +15 -0
  58. package/src/scriptFiles/apis/mmsApiFunction.js +9 -0
  59. package/src/scriptFiles/apis/privateCloudCoreApiFunction.js +101 -0
  60. package/src/scriptFiles/backendApiFunction.js +11 -0
  61. package/src/scriptFiles/checkApiErrorMechanism.js +137 -0
  62. package/src/scriptFiles/common/objectDataProcessing.js +65 -0
  63. package/src/scss/base/commom.scss +1068 -0
  64. package/src/scss/base/dialog.scss +45 -0
  65. package/src/scss/base/index.scss +3 -0
  66. package/src/scss/base/table.scss +28 -0
  67. package/src/store/index.js +25 -0
  68. package/src/store/module/langStore.js +116 -0
  69. package/src/style.css +52 -0
  70. package/src/utils/excel.js +86 -0
  71. package/src/utils/formula.js +69 -0
  72. package/src/utils/https.js +13 -0
  73. package/src/utils/i18n.js +42 -0
  74. package/src/utils/shiftSelect.js +164 -0
  75. package/src/utils/summation.js +77 -0
  76. package/src/utils/tableWidth.js +29 -0
  77. package/src/utils/toolFun.js +93 -0
  78. package/src/views/productionWorkOrder/components/columnConfig.vue +242 -0
  79. package/src/views/productionWorkOrder/components/docCustomFieldForm.vue +739 -0
  80. package/src/views/productionWorkOrder/components/filePreview.vue +148 -0
  81. package/src/views/productionWorkOrder/components/querySearch.vue +363 -0
  82. package/src/views/productionWorkOrder/configFiles/excelImportErrorCode.json +94 -0
  83. package/src/views/productionWorkOrder/configFiles/pdfDefaultConfig.js +933 -0
  84. package/src/views/productionWorkOrder/configFiles/planMakingScript.js +600 -0
  85. package/src/views/productionWorkOrder/configFiles/productionRelatedScript.js +368 -0
  86. package/src/views/productionWorkOrder/configFiles/rulse.js +23 -0
  87. package/src/views/productionWorkOrder/configFiles/status.js +50 -0
  88. package/src/views/productionWorkOrder/index.vue +2174 -0
  89. package/src/views/productionWorkOrder/productionFlowLabel/component/addCirculationLabel.vue +394 -0
  90. package/src/views/productionWorkOrder/productionFlowLabel/component/circulationLabelTable.vue +124 -0
  91. package/src/views/productionWorkOrder/productionFlowLabel/component/materialPartFilePreview.vue +167 -0
  92. package/src/views/productionWorkOrder/productionFlowLabel/component/workOrderInformation.vue +28 -0
  93. package/src/views/productionWorkOrder/productionFlowLabel/index.vue +604 -0
  94. package/src/views/production_work_order/components/priorityTooltip.vue +53 -0
  95. package/src/views/production_work_order/index.vue +1307 -0
  96. package/src/views/review_record/components/materialInfo.vue +50 -0
  97. package/src/views/review_record/components/rootCause.vue +42 -0
  98. package/src/views/review_record/components/workDetail.vue +115 -0
  99. package/src/views/review_record/index.vue +884 -0
@@ -0,0 +1,816 @@
1
+ <template>
2
+ <div>
3
+ <el-form
4
+ v-for="(item, index) in filterConditions"
5
+ ref="filterForm"
6
+ :key="index"
7
+ :model="item"
8
+ :rules="getRules(item)"
9
+ style="margin-bottom: 1rem"
10
+ :data-test-id="`EL-FORM-t4nN1q-${index}`"
11
+ class="filter-item"
12
+ >
13
+ <el-row :gutter="10" data-test-id="EL-ROW-i6hi71">
14
+ <!-- 字段选择 -->
15
+ <el-col :span="5" data-test-id="EL-COL-YtO6It">
16
+ <el-form-item prop="CloumnName" data-test-id="EL-FORM-ITEM-X2DfMG">
17
+ <el-select
18
+ v-model="item.CloumnName"
19
+ data-test-id="EL-SELECT-Tla5bC"
20
+ :disabled="item.CloumnName === defaultCreateTimeString"
21
+ filterable
22
+ @change="handleChangeColumn($event, index)"
23
+ >
24
+ <el-option
25
+ v-for="(it, index) in fieldSelectDataSource"
26
+ :key="it.key"
27
+ :label="it.key === 'salesOrderNumber' ? t(it.key) : t(it.fieldName)"
28
+ :value="it.key"
29
+ :disabled="filterConditions.some((item) => item.CloumnName === it.key)"
30
+ :data-test-id="`EL-OPTION-24JqP4-${index}`"
31
+ />
32
+ </el-select>
33
+ </el-form-item>
34
+ </el-col>
35
+
36
+ <!-- 操作符 -->
37
+ <el-col v-if="item.CloumnName" :span="5" data-test-id="EL-COL-o6tUCn">
38
+ <el-form-item prop="Operator" data-test-id="EL-FORM-ITEM-lwyEu4">
39
+ <el-select
40
+ v-model="item.Operator"
41
+ :placeholder="t('selectOperation')"
42
+ data-test-id="EL-SELECT-B8JVKa"
43
+ @change="handleChangeOperator($event, index)"
44
+ >
45
+ <el-option
46
+ v-for="(it, index) in operatorOptionsFunction(item.ColumnType)"
47
+ :key="it.value"
48
+ :label="t(it.label)"
49
+ :value="it.value"
50
+ :data-test-id="`EL-OPTION-698Ga6-${index}`"
51
+ />
52
+ </el-select>
53
+ </el-form-item>
54
+
55
+ <!-- StartOrEnd(仅类型4) -->
56
+ <el-form-item v-if="item.ColumnType === 4" prop="StartOrEnd" data-test-id="EL-FORM-ITEM-iI09Nl">
57
+ <el-select
58
+ v-model="item.StartOrEnd"
59
+ style="margin-top: 1rem"
60
+ :placeholder="t('startOrEndTime')"
61
+ data-test-id="EL-SELECT-hYLMt4"
62
+ >
63
+ <el-option
64
+ v-for="(it, index) in optionFile.startOrEndOptions"
65
+ :key="it.value"
66
+ :label="t(it.label)"
67
+ :value="it.value"
68
+ :data-test-id="`EL-OPTION-qkQDv6-${index}`"
69
+ />
70
+ </el-select>
71
+ </el-form-item>
72
+ </el-col>
73
+
74
+ <!-- 值输入 -->
75
+ <el-col v-if="item.Operator && ![9, 10].includes(item.Operator)" :span="12" data-test-id="EL-COL-bWX9Cb">
76
+ <!-- 文本 / 附件 / 超链接 -->
77
+ <el-form-item
78
+ v-if="isTextLikeType(item.ColumnType) && isTextOperator(item.Operator)"
79
+ prop="TextValue"
80
+ data-test-id="EL-FORM-ITEM-MaRru1"
81
+ >
82
+ <el-input v-model="item.TextValue" :placeholder="t('inputText')" clearable data-test-id="EL-INPUT-RoUXuD" />
83
+ </el-form-item>
84
+
85
+ <!-- 数字范围 -->
86
+ <el-form-item
87
+ v-else-if="(item.ColumnType === 2 || item.ColumnType === 9) && [13, 14].includes(item.Operator)"
88
+ prop="NumberRangeValue"
89
+ data-test-id="EL-FORM-ITEM-vLLx0f"
90
+ >
91
+ <el-input
92
+ v-model="item.NumberRangeValue[0]"
93
+ style="width: 150px"
94
+ type="number"
95
+ :controls="false"
96
+ :placeholder="t('minValue')"
97
+ clearable
98
+ data-test-id="EL-INPUT-NUMBER-nxVp98"
99
+ />
100
+ <span data-test-id="SPAN-aJGkhM"> - </span>
101
+ <el-input
102
+ v-model="item.NumberRangeValue[1]"
103
+ style="width: 150px"
104
+ type="number"
105
+ :controls="false"
106
+ :placeholder="t('maxValue')"
107
+ clearable
108
+ data-test-id="EL-INPUT-NUMBER-BhVdW7"
109
+ />
110
+ </el-form-item>
111
+
112
+ <!-- 单选/多选 -->
113
+ <el-form-item
114
+ v-else-if="isSelectType(item.ColumnType) && [5, 15, 16].includes(item.Operator)"
115
+ prop="SelectRangeValue"
116
+ data-test-id="EL-FORM-ITEM-tjsXva"
117
+ >
118
+ <el-select
119
+ v-model="item.SelectRangeValue"
120
+ collapse-tags
121
+ collapse-tags-tooltip
122
+ :multiple="item.ColumnType === 8"
123
+ :placeholder="t('selectOptions')"
124
+ clearable
125
+ data-test-id="EL-SELECT-3wxMWS"
126
+ >
127
+ <el-option
128
+ v-for="(opt, index) in fieldSelectOptionsFunction(item.CloumnName)"
129
+ :key="opt.value"
130
+ :label="t(opt.label)"
131
+ :value="opt.value"
132
+ :data-test-id="`EL-OPTION-5wrWi5-${index}`"
133
+ />
134
+ </el-select>
135
+ </el-form-item>
136
+
137
+ <!-- 日期单值 -->
138
+ <el-form-item
139
+ v-else-if="isDateType(item.ColumnType) && [1, 2, 3, 4, 5].includes(item.Operator)"
140
+ prop="DateTimeOperatorValue"
141
+ data-test-id="EL-FORM-ITEM-932Tco"
142
+ >
143
+ <el-row :gutter="10" data-test-id="EL-ROW-CWWfMC">
144
+ <el-col :span="6" data-test-id="EL-COL-3tGiBz">
145
+ <el-select
146
+ v-model="item.DateTimeOperatorValue.TimeType"
147
+ :placeholder="t('timePrecision')"
148
+ clearable
149
+ data-test-id="EL-SELECT-nphb5z"
150
+ >
151
+ <el-option
152
+ v-for="(it, index) in optionFile.timePrecisionOptions"
153
+ :key="it.value"
154
+ :label="t(it.label)"
155
+ :value="it.value"
156
+ :data-test-id="`EL-OPTION-7foEY9-${index}`"
157
+ />
158
+ </el-select>
159
+ </el-col>
160
+ <el-col :span="18" data-test-id="EL-COL-rxXI8U">
161
+ <el-date-picker
162
+ v-model="item.DateTimeOperatorValue.TimeValue"
163
+ :type="item.DateTimeOperatorValue.TimeType === 0 ? 'date' : 'datetime'"
164
+ :format="timePrecisionOptionsFunction(item.DateTimeOperatorValue.TimeType)"
165
+ value-format="x"
166
+ :placeholder="t('selectTime')"
167
+ clearable
168
+ data-test-id="EL-DATE-PICKER-BFwrVh"
169
+ />
170
+ </el-col>
171
+ </el-row>
172
+ </el-form-item>
173
+
174
+ <!-- 日期范围 -->
175
+ <el-form-item
176
+ v-else-if="isDateType(item.ColumnType) && item.Operator === 11"
177
+ prop="DateTimeRangeValue"
178
+ data-test-id="EL-FORM-ITEM-nM49hw"
179
+ >
180
+ <el-row :gutter="10" data-test-id="EL-ROW-zZIFj0">
181
+ <el-col :span="12" data-test-id="EL-COL-k6LrJP">
182
+ <el-select
183
+ v-model="item.DateTimeRangeValue.TimeType"
184
+ :placeholder="t('timePrecision')"
185
+ clearable
186
+ data-test-id="EL-SELECT-93yQnb"
187
+ >
188
+ <el-option
189
+ v-for="(it, index) in optionFile.timePrecisionOptions"
190
+ :key="it.value"
191
+ :label="t(it.label)"
192
+ :value="it.value"
193
+ :data-test-id="`EL-OPTION-WuL5hF-${index}`"
194
+ />
195
+ </el-select>
196
+ </el-col>
197
+ <el-col :span="24" data-test-id="EL-COL-Zy3UKA">
198
+ <el-date-picker
199
+ v-model="item.DateTimeRangeValue.TimeValue"
200
+ style="width: 90%; margin-top: 1rem"
201
+ :type="item.DateTimeRangeValue.TimeType === 0 ? 'daterange' : 'datetimerange'"
202
+ :format="timePrecisionOptionsFunction(item.DateTimeRangeValue.TimeType)"
203
+ clearable
204
+ range-separator="-"
205
+ :start-placeholder="t('startTime')"
206
+ :end-placeholder="t('endTime')"
207
+ data-test-id="EL-DATE-PICKER-fPXNSn"
208
+ />
209
+ </el-col>
210
+ </el-row>
211
+ </el-form-item>
212
+
213
+ <!-- 动态筛选 -->
214
+ <el-form-item
215
+ v-else-if="isDateType(item.ColumnType) && item.Operator === 12"
216
+ prop="DateTimeDynamicFilteringValue"
217
+ data-test-id="EL-FORM-ITEM-3pz54d"
218
+ >
219
+ <el-select
220
+ v-model="item.DateTimeDynamicFilteringValue.DateType"
221
+ :placeholder="t('dynamicFiltering')"
222
+ clearable
223
+ data-test-id="EL-SELECT-93zW0f"
224
+ @change="handleDateTimeDynamicFilteringValueChange($event, index)"
225
+ >
226
+ <el-option
227
+ v-for="(it, index) in optionFile.dynamicFilteringOptions"
228
+ :key="it.value"
229
+ :label="t(it.label)"
230
+ :value="it.value"
231
+ :data-test-id="`EL-OPTION-j2Gto6-${index}`"
232
+ />
233
+ </el-select>
234
+ </el-form-item>
235
+
236
+ <!-- 自定义单区间 -->
237
+ <el-form-item
238
+ v-if="
239
+ item.DateTimeDynamicFilteringValue.DateType === 0 || item.DateTimeDynamicFilteringValue.DateType === 1
240
+ "
241
+ prop="DateTimeDynamicFilteringCustomize"
242
+ data-test-id="EL-FORM-ITEM-oKi0MK"
243
+ >
244
+ <el-col
245
+ v-if="item.DateTimeDynamicFilteringValue.DateType === 0"
246
+ :span="24"
247
+ style="margin-top: 1rem"
248
+ data-test-id="EL-COL-5XNCgU"
249
+ >
250
+ <el-row :gutter="10" data-test-id="EL-ROW-zHGl1c">
251
+ <el-col :span="8" data-test-id="EL-COL-tTDMtb">
252
+ <el-select
253
+ v-model="item.DateTimeDynamicFilteringCustomize[0].PastOrFuture"
254
+ :placeholder="t('pastOrFuture')"
255
+ clearable
256
+ data-test-id="EL-SELECT-xifi4x"
257
+ >
258
+ <el-option
259
+ v-for="(it, ind) in optionFile.pastOrFutureOptions.filter((opt) => opt.value !== 2)"
260
+ :key="it.value"
261
+ :label="t(it.label)"
262
+ :value="it.value"
263
+ :data-test-id="`EL-OPTION-0ql2zr-${ind}`"
264
+ />
265
+ </el-select>
266
+ </el-col>
267
+ <el-col :span="8" data-test-id="EL-COL-T5qcri">
268
+ <el-input-number
269
+ v-model="item.DateTimeDynamicFilteringCustomize[0].NumberValue"
270
+ :min="1"
271
+ :max="365"
272
+ :precision="0"
273
+ :controls="false"
274
+ style="width: 100%"
275
+ clearable
276
+ data-test-id="EL-INPUT-NUMBER-RYLnRt"
277
+ />
278
+ </el-col>
279
+ <el-col :span="8" data-test-id="EL-COL-JlxABO">
280
+ <el-select
281
+ v-model="item.DateTimeDynamicFilteringCustomize[0].DayType"
282
+ :placeholder="t('unity')"
283
+ clearable
284
+ data-test-id="EL-SELECT-8Lpazq"
285
+ >
286
+ <el-option
287
+ v-for="(it, ind) in optionFile.dayTypeOptions"
288
+ :key="it.value"
289
+ :label="t(it.label)"
290
+ :value="it.value"
291
+ :data-test-id="`EL-OPTION-ncuVRo-${ind}`"
292
+ />
293
+ </el-select>
294
+ </el-col>
295
+ </el-row>
296
+ </el-col>
297
+
298
+ <!-- 自定义双区间 -->
299
+ <el-col
300
+ v-else-if="item.DateTimeDynamicFilteringValue.DateType === 1"
301
+ :span="24"
302
+ style="margin-top: 1rem"
303
+ data-test-id="EL-COL-eM8opS"
304
+ >
305
+ <el-row :gutter="10" data-test-id="EL-ROW-lcZ8pe">
306
+ <el-col :span="8" data-test-id="EL-COL-7j3j0p">
307
+ <el-select
308
+ v-model="item.DateTimeDynamicFilteringCustomize[0].PastOrFuture"
309
+ :placeholder="t('pastOrFuture')"
310
+ clearable
311
+ data-test-id="EL-SELECT-FjHTpQ"
312
+ @change="
313
+ (vel) => {
314
+ if (vel === 2) {
315
+ item.DateTimeDynamicFilteringCustomize[0].NumberValue = 1;
316
+ }
317
+ }
318
+ "
319
+ >
320
+ <el-option
321
+ v-for="(it, ind) in optionFile.pastOrFutureOptions"
322
+ :key="it.value"
323
+ :label="t(it.label)"
324
+ :value="it.value"
325
+ :data-test-id="`EL-OPTION-xpcYp5-${ind}`"
326
+ />
327
+ </el-select>
328
+ </el-col>
329
+ <el-col :span="8" data-test-id="EL-COL-JnQ12D">
330
+ <el-input-number
331
+ v-model="item.DateTimeDynamicFilteringCustomize[0].NumberValue"
332
+ :min="1"
333
+ :max="365"
334
+ :disabled="item.DateTimeDynamicFilteringCustomize[0].PastOrFuture === 2"
335
+ :precision="0"
336
+ :controls="false"
337
+ style="width: 100%"
338
+ clearable
339
+ data-test-id="EL-INPUT-NUMBER-3lwksG"
340
+ />
341
+ </el-col>
342
+ <el-col :span="8" data-test-id="EL-COL-ms7sgy">
343
+ <el-select
344
+ v-model="item.DateTimeDynamicFilteringCustomize[0].DayType"
345
+ :placeholder="t('unity')"
346
+ clearable
347
+ data-test-id="EL-SELECT-fgZOLb"
348
+ >
349
+ <el-option
350
+ v-for="(it, ind) in optionFile.dayTypeOptions"
351
+ :key="it.value"
352
+ :label="t(it.label)"
353
+ :value="it.value"
354
+ :data-test-id="`EL-OPTION-Q07Tx8-${ind}`"
355
+ />
356
+ </el-select>
357
+ </el-col>
358
+ </el-row>
359
+ <el-row :gutter="10" style="margin-top: 1rem" data-test-id="EL-ROW-XkOYka">
360
+ <el-col :span="8" data-test-id="EL-COL-dLQQRb">
361
+ <el-select
362
+ v-model="item.DateTimeDynamicFilteringCustomize[1].PastOrFuture"
363
+ :placeholder="t('pastOrFuture')"
364
+ clearable
365
+ data-test-id="EL-SELECT-ZNyGMx"
366
+ @change="
367
+ (vel) => {
368
+ if (vel === 2) {
369
+ item.DateTimeDynamicFilteringCustomize[1].NumberValue = 1;
370
+ }
371
+ }
372
+ "
373
+ >
374
+ <el-option
375
+ v-for="(it, ind) in optionFile.pastOrFutureOptions"
376
+ :key="it.value"
377
+ :label="t(it.label)"
378
+ :value="it.value"
379
+ :data-test-id="`EL-OPTION-nlnE2g-${ind}`"
380
+ />
381
+ </el-select>
382
+ </el-col>
383
+ <el-col :span="8" data-test-id="EL-COL-3uTjYF">
384
+ <el-input-number
385
+ v-model="item.DateTimeDynamicFilteringCustomize[1].NumberValue"
386
+ :min="1"
387
+ :max="365"
388
+ :disabled="item.DateTimeDynamicFilteringCustomize[1].PastOrFuture === 2"
389
+ :precision="0"
390
+ :controls="false"
391
+ style="width: 100%"
392
+ clearable
393
+ data-test-id="EL-INPUT-NUMBER-w1GgpV"
394
+ />
395
+ </el-col>
396
+ <el-col :span="8" data-test-id="EL-COL-wDLRGi">
397
+ <el-select
398
+ v-model="item.DateTimeDynamicFilteringCustomize[1].DayType"
399
+ :placeholder="t('unity')"
400
+ clearable
401
+ data-test-id="EL-SELECT-3d7Hyz"
402
+ >
403
+ <el-option
404
+ v-for="(it, ind) in optionFile.dayTypeOptions"
405
+ :key="it.value"
406
+ :label="t(it.label)"
407
+ :value="it.value"
408
+ :data-test-id="`EL-OPTION-wkFjZV-${ind}`"
409
+ />
410
+ </el-select>
411
+ </el-col>
412
+ </el-row>
413
+ </el-col>
414
+ </el-form-item>
415
+ </el-col>
416
+ <el-col v-if="item.CloumnName !== defaultCreateTimeString" :span="2" data-test-id="EL-COL-7VbmTB">
417
+ <!-- 删除按钮 -->
418
+ <el-button class="ml-2" type="text" data-test-id="EL-BUTTON-f9487D" @click="removeFilter(index)">
419
+ <i class="mdi mdi-close"></i>
420
+ </el-button>
421
+ </el-col>
422
+ </el-row>
423
+ </el-form>
424
+ </div>
425
+ </template>
426
+ <script setup>
427
+ import { ref, nextTick, computed } from 'vue';
428
+ import { useI18n } from 'vue-i18n';
429
+ import { ElMessageBox, ElMessage } from 'element-plus';
430
+ // import apiFunction from '@/scriptFiles/checkApiErrorMechanism.js';
431
+ import optionFile from './config.js';
432
+ const { t } = useI18n();
433
+ const props = defineProps({
434
+ filterConditions: {
435
+ type: Array,
436
+ default: () => [],
437
+ }, // 筛选条件
438
+ fieldSetting: {
439
+ type: Array,
440
+ default: () => [],
441
+ }, // 筛选条件内容的字段配置
442
+ // tz新增:外部提供的下拉数据源
443
+ selectOptions: {
444
+ type: Object,
445
+ default: () => ({}),
446
+ },
447
+ defaultCreateTimeString: {
448
+ type: String,
449
+ default: 'createTime',
450
+ }, // 默认创建时间字符串
451
+ });
452
+ const filterConditions = computed(() => props.filterConditions);
453
+ const filterForm = ref([]);
454
+ // 工具函数:判断字段类型
455
+ const isTextLikeType = (type) => [1, 5, 6].includes(type); // 文本、附件、超链接
456
+ const isSelectType = (type) => [7, 8].includes(type); // 单选、多选
457
+ const isDateType = (type) => [3, 4].includes(type); // 日期、日期范围
458
+ const isTextOperator = (op) => [5, 6, 7, 8].includes(op); // 等于、包含等
459
+
460
+ // 字段选择下拉框数据源处理 - 新增
461
+ const fieldSelectDataSource = computed(() => {
462
+ // 优先使用外部提供的字段列表数据源
463
+ if (props.selectOptions.fieldList) {
464
+ return props.selectOptions.fieldList;
465
+ }
466
+ // 否则使用默认的fieldSetting
467
+ return props.fieldSetting;
468
+ });
469
+
470
+ // 验证规则动态生成
471
+ const getRules = (item) => {
472
+ const rules = {
473
+ CloumnName: [{ required: true, message: t('selectField'), trigger: 'change' }],
474
+ Operator: [{ required: true, message: t('selectOperator'), trigger: 'change' }],
475
+ };
476
+
477
+ if (![9, 10].includes(item.Operator)) {
478
+ if (isTextLikeType(item.ColumnType) && isTextOperator(item.Operator)) {
479
+ rules.TextValue = [
480
+ { required: true, message: t('inputText'), trigger: 'blur' },
481
+ {
482
+ validator: (rule, value, callback) => {
483
+ if (value !== value.trim()) {
484
+ return callback(new Error(t('haveSpace')));
485
+ }
486
+ callback();
487
+ },
488
+ trigger: 'blur',
489
+ },
490
+ ];
491
+ }
492
+
493
+ if ((item.ColumnType === 2 || item.ColumnType === 9) && [13, 14].includes(item.Operator)) {
494
+ rules.NumberRangeValue = [
495
+ { required: true, message: t('inputRangeValue'), trigger: 'change' },
496
+ {
497
+ validator: (rule, value, callback) => {
498
+ const NumberReg = /^(([1-9]{1}[0-9]{0,9})|([0]{1}))((\.{1}[0-9]{1,6}$)|$)/;
499
+ if (!value || !Array.isArray(value) || value.some((v) => v == null) || value.length !== 2) {
500
+ return callback(new Error(t('inputValidRange')));
501
+ }
502
+ if ((!NumberReg.test(value[0]) && value[0]) || (!NumberReg.test(value[1]) && value[1])) {
503
+ return callback(new Error(t('numIntegerExceedTen') + ',' + t('numDecimalExceedSix')));
504
+ }
505
+ if (+value[0] > +value[1]) {
506
+ return callback(new Error(t('startValueCannotGreaterThanEndValue')));
507
+ }
508
+ callback();
509
+ },
510
+ trigger: 'change',
511
+ },
512
+ ];
513
+ }
514
+
515
+ if (isSelectType(item.ColumnType) && [15, 16].includes(item.Operator)) {
516
+ rules.SelectRangeValue = [{ required: true, message: t('selectOptions'), trigger: 'change' }];
517
+ }
518
+
519
+ if (isDateType(item.ColumnType) && [1, 2, 3, 4, 5].includes(item.Operator)) {
520
+ rules.DateTimeOperatorValue = [
521
+ { required: true, message: t('selectTime'), trigger: 'change' },
522
+ {
523
+ validator: (rule, value, callback) => {
524
+ if (value?.TimeType === null || !value?.TimeValue) {
525
+ return callback(new Error(t('selectTimeAndPrecision')));
526
+ }
527
+ callback();
528
+ },
529
+ trigger: 'change',
530
+ },
531
+ ];
532
+ }
533
+
534
+ if (item.ColumnType === 4) {
535
+ rules.StartOrEnd = [{ required: true, message: t('selectStartOrEnd'), trigger: 'change' }];
536
+ }
537
+
538
+ if (isDateType(item.ColumnType) && item.Operator === 11) {
539
+ rules.DateTimeRangeValue = [
540
+ { required: true, message: t('selectTimeRange'), trigger: 'change' },
541
+ {
542
+ validator: (rule, value, callback) => {
543
+ if (value?.TimeType === null || !value?.TimeValue || value.TimeValue.length !== 2) {
544
+ return callback(new Error(t('selectCompleteTimeRange')));
545
+ }
546
+ callback();
547
+ },
548
+ trigger: 'change',
549
+ },
550
+ ];
551
+ }
552
+
553
+ if (isDateType(item.ColumnType) && item.Operator === 12) {
554
+ rules.DateTimeDynamicFilteringValue = [
555
+ { required: true, message: t('selectDynamicFilteringType'), trigger: 'change' },
556
+ {
557
+ validator: (rule, value, callback) => {
558
+ if (value?.DateType === null) {
559
+ return callback(new Error(t('selectDynamicFilteringType')));
560
+ }
561
+ callback();
562
+ },
563
+ trigger: 'change',
564
+ },
565
+ ];
566
+ rules.DateTimeDynamicFilteringCustomize = [
567
+ {
568
+ validator: (rule, value, callback) => {
569
+ if (value[0]?.PastOrFuture === null || value[0]?.NumberValue === null || value[0]?.DayType === null) {
570
+ return callback(new Error(t('pleaseInput')));
571
+ }
572
+ callback();
573
+ },
574
+ trigger: 'change',
575
+ },
576
+ ];
577
+ if (
578
+ item?.DateTimeDynamicFilteringValue?.DateType !== null &&
579
+ item?.DateTimeDynamicFilteringValue?.DateType === 0
580
+ ) {
581
+ rules.DateTimeDynamicFilteringCustomize = [
582
+ {
583
+ validator: (rule, value, callback) => {
584
+ if (value[0]?.PastOrFuture === null || value[0]?.NumberValue === null || value[0]?.DayType === null) {
585
+ return callback(new Error(t('pleaseInput')));
586
+ }
587
+ callback();
588
+ },
589
+ trigger: 'change',
590
+ },
591
+ ];
592
+ }
593
+ if (
594
+ item?.DateTimeDynamicFilteringValue?.DateType !== null &&
595
+ item?.DateTimeDynamicFilteringValue?.DateType === 1
596
+ ) {
597
+ rules.DateTimeDynamicFilteringCustomize = [
598
+ {
599
+ validator: (rule, value, callback) => {
600
+ if (
601
+ value[0]?.PastOrFuture === null ||
602
+ value[0]?.NumberValue === null ||
603
+ value[0]?.DayType === null ||
604
+ value[1]?.PastOrFuture === null ||
605
+ value[1]?.NumberValue === null ||
606
+ value[1]?.DayType === null
607
+ ) {
608
+ return callback(new Error(t('pleaseInput')));
609
+ }
610
+ callback();
611
+ },
612
+ trigger: 'change',
613
+ },
614
+ ];
615
+ }
616
+ }
617
+ }
618
+
619
+ return rules;
620
+ };
621
+
622
+ /**
623
+ * 时间精度选项
624
+ * @param timeType 时间精度
625
+ * @returns 时间格式
626
+ */
627
+ const timePrecisionOptionsFunction = (timeType) => {
628
+ return optionFile.timePrecisionOptions.find((item) => item.value === timeType)?.timeFormat;
629
+ };
630
+ /**
631
+ * 筛选条件内容的字段类型改变时,判断逻辑选项改变
632
+ * @param fieldTypeId 筛选条件内容的字段类型
633
+ * @returns 筛选条件内容的判断逻辑选项
634
+ */
635
+ const operatorOptionsFunction = (fieldTypeId) => {
636
+ const mapping = {
637
+ 1: [5, 6, 7, 8, 9, 10], // 文本
638
+ 2: [9, 10, 13, 14], // 数字
639
+ 3: [1, 2, 3, 4, 5, 9, 10, 11, 12], // 日期
640
+ 4: [1, 2, 3, 4, 5, 9, 10, 11, 12], // 日期范围
641
+ 5: [5, 6, 7, 8, 9, 10], // 附件
642
+ 6: [5, 6, 7, 8, 9, 10], // 超链接
643
+ 7: [5], // 单选
644
+ 8: [9, 10, 15, 16], // 多选
645
+ 9: [9, 10, 13, 14], // 公式 按数字类型处理
646
+ };
647
+ const allowed = mapping[fieldTypeId] || [];
648
+ // 优先使用外部提供的操作符选项
649
+ if (props.selectOptions.operatorOptions) {
650
+ return props.selectOptions.operatorOptions.filter((op) => allowed.includes(op.value));
651
+ }
652
+ return optionFile.operatorOptions.filter((op) => allowed.includes(op.value));
653
+ };
654
+
655
+ /**
656
+ * 筛选条件内容的字段类型改变时,判断逻辑选项改变
657
+ * @param columnName 筛选条件内容的字段类型
658
+ * @returns 筛选条件内容的判断逻辑选项
659
+ */
660
+ const fieldSelectOptionsFunction = (columnName) => {
661
+ // 添加输入验证,确保columnName是有效的字符串
662
+ if (columnName === null || columnName === undefined) {
663
+ return [];
664
+ }
665
+ try {
666
+ // 优先使用外部提供的直接字段配置
667
+ if (props.selectOptions && typeof props.selectOptions === 'object') {
668
+ // 1.直接通过字段名配置
669
+ if (props.selectOptions[columnName]) {
670
+ return Array.isArray(props.selectOptions[columnName]) ? props.selectOptions[columnName] : [];
671
+ }
672
+ // 2.通过类型配置(例如xxxOptions)
673
+ const typeOptionsKey = Object.keys(props.selectOptions).find(
674
+ (key) => key.endsWith('Options') && columnName.includes(key.replace('Options', '')),
675
+ );
676
+ if (typeOptionsKey) {
677
+ return Array.isArray(props.selectOptions[typeOptionsKey]) ? props.selectOptions[typeOptionsKey] : [];
678
+ }
679
+ }
680
+ // 从字段配置中获取选项
681
+ const dataSource = Array.isArray(fieldSelectDataSource.value) ? fieldSelectDataSource.value : [];
682
+ const field = dataSource.find((f) => f && f.key === columnName);
683
+ if (field && (field.fieldTypeId === 7 || field.fieldTypeId === 8)) {
684
+ // 选择类型字段(单选/多选)
685
+ if (field.fieldSelectOptions) {
686
+ try {
687
+ const opts = JSON.parse(field.fieldSelectOptions);
688
+ return Array.isArray(opts)
689
+ ? opts.map((opt) => ({
690
+ label: field.isDoc ? opt : opt ? opt.key || opt.label || opt.value : '',
691
+ value: field.isDoc ? opt : opt ? opt.value : '',
692
+ }))
693
+ : [];
694
+ } catch (jsonError) {
695
+ return [];
696
+ }
697
+ }
698
+ }
699
+
700
+ return [];
701
+ } catch (e) {
702
+ ElMessage.error(t('apiError'));
703
+ }
704
+ };
705
+ /**
706
+ * 筛选条件内容的字段类型改变时,判断逻辑选项改变
707
+ * @param value 筛选条件内容的字段类型
708
+ * @param index 筛选条件的索引
709
+ */
710
+ const fieldTypeFun = (type) => {
711
+ if ([1, 5, 6].includes(type)) {
712
+ return 5;
713
+ }
714
+ if (type === 2) {
715
+ return 13;
716
+ }
717
+ if ([3, 4].includes(type)) {
718
+ return 11;
719
+ }
720
+ if (type === 7) {
721
+ return 5;
722
+ }
723
+ if (type === 8) {
724
+ return 15;
725
+ }
726
+ return null;
727
+ };
728
+ const handleChangeColumn = (value, index) => {
729
+ const field = fieldSelectDataSource.value.find((f) => f.key === value);
730
+ // const field = props.fieldSetting.find((f) => f.key === value);
731
+ const item = filterConditions.value[index];
732
+ Object.assign(item, {
733
+ CloumnName: value,
734
+ ColumnType: field?.fieldTypeId,
735
+ Operator: fieldTypeFun(field?.fieldTypeId),
736
+ StartOrEnd: null,
737
+ TextValue: null,
738
+ IsCustomSetting: field?.isDoc,
739
+ DocCustomId: field?.isDoc ? field.key : null,
740
+ NumberRangeValue: [],
741
+ SelectRangeValue: [],
742
+ DateTimeOperatorValue: { TimeType: null, TimeValue: null },
743
+ DateTimeRangeValue: { TimeType: [3, 4].includes(field?.fieldTypeId) ? 0 : null, TimeValue: [] },
744
+ DateTimeDynamicFilteringValue: { DateType: null },
745
+ DateTimeDynamicFilteringCustomize: [
746
+ { PastOrFuture: null, NumberValue: null, DayType: null },
747
+ { PastOrFuture: null, NumberValue: null, DayType: null },
748
+ ],
749
+ });
750
+ };
751
+ /**
752
+ *
753
+ * @param value 筛选条件内容的判断逻辑
754
+ * @param index 筛选条件的索引
755
+ */
756
+ const handleChangeOperator = (value, index) => {
757
+ const item = filterConditions.value[index];
758
+ // 清空无关字段
759
+ Object.assign(item, {
760
+ TextValue: null,
761
+ NumberRangeValue: [],
762
+ SelectRangeValue: [],
763
+ DateTimeOperatorValue: { TimeType: null, TimeValue: null },
764
+ DateTimeRangeValue: { TimeType: null, TimeValue: [] },
765
+ DateTimeDynamicFilteringValue: { DateType: null },
766
+ DateTimeDynamicFilteringCustomize: [
767
+ { PastOrFuture: null, NumberValue: null, DayType: null },
768
+ { PastOrFuture: null, NumberValue: null, DayType: null },
769
+ ],
770
+ });
771
+ };
772
+ /**
773
+ * 动态筛选自定义筛选时间类型改变时,判断逻辑选项改变
774
+ * @param value 动态筛选自定义筛选时间类型
775
+ * @param index 筛选条件的索引
776
+ */
777
+ const handleDateTimeDynamicFilteringValueChange = (value, index) => {
778
+ const item = filterConditions.value[index];
779
+ item.DateTimeDynamicFilteringCustomize = [
780
+ { PastOrFuture: null, NumberValue: null, DayType: null },
781
+ { PastOrFuture: null, NumberValue: null, DayType: null },
782
+ ];
783
+ };
784
+ /**
785
+ * 删除筛选条件
786
+ * @param index 筛选条件的索引
787
+ */
788
+ const removeFilter = (index) => {
789
+ ElMessageBox.confirm(t('confirmToDelete'), t('confirmDelete'), {
790
+ confirmButtonText: t('confirm'),
791
+ cancelButtonText: t('cancel'),
792
+ type: 'warning',
793
+ }).then(() => {
794
+ filterConditions.value.splice(index, 1);
795
+ // emit('update:filterConditions', filterConditions);
796
+ });
797
+ };
798
+ // 暴露提交方法
799
+ const validateAllForms = async () => {
800
+ await nextTick();
801
+ try {
802
+ await Promise.all(filterForm.value.map((form) => form?.validate?.() || Promise.resolve()));
803
+ return true;
804
+ } catch (error) {
805
+ ElMessage.error(t('checkForm'));
806
+ return false;
807
+ }
808
+ };
809
+ defineExpose({ validateAllForms });
810
+ </script>
811
+ <style scoped lang="scss">
812
+ .filter-item {
813
+ background-color: #f9fafb;
814
+ border-radius: 6px;
815
+ }
816
+ </style>