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,769 @@
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
+ :data-test-id="`EL-FORM-t4nN1q-${index}`"
10
+ >
11
+ <el-row :gutter="10" data-test-id="EL-ROW-i6hi71">
12
+ <!-- 字段选择 -->
13
+ <el-col :span="6" data-test-id="EL-COL-YtO6It">
14
+ <el-form-item
15
+ :label="isItDefault ? t('dataFilter') : ''"
16
+ prop="CloumnName"
17
+ data-test-id="EL-FORM-ITEM-X2DfMG"
18
+ >
19
+ <el-select
20
+ v-model="item.CloumnName"
21
+ filterable
22
+ data-test-id="EL-SELECT-Tla5bC"
23
+ @change="handleChangeColumn($event, index)"
24
+ >
25
+ <el-option
26
+ v-for="(it, index) in fieldSetting"
27
+ :key="it.key"
28
+ :label="t(it.fieldName)"
29
+ :value="it.key"
30
+ :disabled="
31
+ filterConditions.some((item) => item.CloumnName === it.key) ||
32
+ otherFilterConditions.some((item) => item.CloumnName === it.key)
33
+ "
34
+ :data-test-id="`EL-OPTION-24JqP4-${index}`"
35
+ />
36
+ </el-select>
37
+ </el-form-item>
38
+ </el-col>
39
+
40
+ <!-- 操作符 -->
41
+ <el-col v-if="item.CloumnName" :span="4" data-test-id="EL-COL-o6tUCn">
42
+ <el-form-item prop="Operator" data-test-id="EL-FORM-ITEM-lwyEu4">
43
+ <el-select
44
+ v-model="item.Operator"
45
+ :placeholder="t('selectOperation')"
46
+ data-test-id="EL-SELECT-B8JVKa"
47
+ @change="handleChangeOperator($event, index)"
48
+ >
49
+ <el-option
50
+ v-for="(it, index) in operatorOptionsFunction(item.ColumnType)"
51
+ :key="it.value"
52
+ :label="t(it.label)"
53
+ :value="it.value"
54
+ :data-test-id="`EL-OPTION-698Ga6-${index}`"
55
+ />
56
+ </el-select>
57
+ </el-form-item>
58
+
59
+ <!-- StartOrEnd(仅类型4) -->
60
+ <el-form-item v-if="item.ColumnType === 4" prop="StartOrEnd" data-test-id="EL-FORM-ITEM-iI09Nl">
61
+ <el-select
62
+ v-model="item.StartOrEnd"
63
+ style="margin-top: 1rem"
64
+ :placeholder="t('startOrEndTime')"
65
+ data-test-id="EL-SELECT-hYLMt4"
66
+ >
67
+ <el-option
68
+ v-for="(it, index) in startOrEndOptions"
69
+ :key="it.value"
70
+ :label="t(it.label)"
71
+ :value="it.value"
72
+ :data-test-id="`EL-OPTION-qkQDv6-${index}`"
73
+ />
74
+ </el-select>
75
+ </el-form-item>
76
+ </el-col>
77
+
78
+ <!-- 值输入 -->
79
+ <el-col v-if="item.Operator && ![9, 10].includes(item.Operator)" :span="12" data-test-id="EL-COL-bWX9Cb">
80
+ <!-- 文本 / 附件 / 超链接 -->
81
+ <el-form-item
82
+ v-if="isTextLikeType(item.ColumnType) && isTextOperator(item.Operator)"
83
+ prop="TextValue"
84
+ data-test-id="EL-FORM-ITEM-MaRru1"
85
+ >
86
+ <el-input v-model="item.TextValue" :placeholder="t('inputText')" clearable data-test-id="EL-INPUT-RoUXuD" />
87
+ </el-form-item>
88
+
89
+ <!-- 数字范围 -->
90
+ <el-form-item
91
+ v-else-if="item.ColumnType === 2 && [13, 14].includes(item.Operator)"
92
+ prop="NumberRangeValue"
93
+ data-test-id="EL-FORM-ITEM-vLLx0f"
94
+ >
95
+ <el-input-number
96
+ v-model="item.NumberRangeValue[0]"
97
+ :max="item.NumberRangeValue[1] ?? Number.MAX_SAFE_INTEGER"
98
+ :controls="false"
99
+ :placeholder="t('minValue')"
100
+ disabled-scientific
101
+ clearable
102
+ data-test-id="EL-INPUT-NUMBER-nxVp98"
103
+ />
104
+ <span data-test-id="SPAN-aJGkhM"> - </span>
105
+ <el-input-number
106
+ v-model="item.NumberRangeValue[1]"
107
+ :min="item.NumberRangeValue[0] ?? Number.MIN_SAFE_INTEGER"
108
+ :controls="false"
109
+ :placeholder="t('maxValue')"
110
+ disabled-scientific
111
+ clearable
112
+ data-test-id="EL-INPUT-NUMBER-BhVdW7"
113
+ />
114
+ <el-button type="text" data-test-id="EL-BUTTON-1EWCV6" @click="handleNumberValidate(index)">
115
+ <i class="mdi mdi-close" data-test-id="I-a2oGJf" />
116
+ </el-button>
117
+ </el-form-item>
118
+
119
+ <!-- 单选/多选 -->
120
+ <el-form-item
121
+ v-else-if="isSelectType(item.ColumnType) && [15, 16].includes(item.Operator)"
122
+ prop="SelectRangeValue"
123
+ data-test-id="EL-FORM-ITEM-tjsXva"
124
+ >
125
+ <el-select
126
+ v-model="item.SelectRangeValue"
127
+ collapse-tags
128
+ collapse-tags-tooltip
129
+ multiple
130
+ filterable
131
+ :placeholder="t('selectOptions')"
132
+ clearable
133
+ data-test-id="EL-SELECT-3wxMW0"
134
+ >
135
+ <el-option
136
+ v-for="(opt, index) in fieldSelectOptionsFunction(item.CloumnName)"
137
+ :key="opt.value"
138
+ :label="t(opt.label)"
139
+ :value="opt.value"
140
+ :data-test-id="`EL-OPTION-5wrWi6-${index}`"
141
+ />
142
+ </el-select>
143
+ </el-form-item>
144
+ <el-form-item
145
+ v-else-if="isSelectType(item.ColumnType) && [5].includes(item.Operator)"
146
+ prop="SingleSelectValue"
147
+ data-test-id="EL-FORM-ITEM-tjsXvb"
148
+ >
149
+ <el-select
150
+ v-model="item.SingleSelectValue"
151
+ collapse-tags
152
+ collapse-tags-tooltip
153
+ filterable
154
+ :placeholder="t('selectOptions')"
155
+ clearable
156
+ data-test-id="EL-SELECT-3wxMWS"
157
+ >
158
+ <el-option
159
+ v-for="(opt, index) in fieldSelectOptionsFunction(item.CloumnName)"
160
+ :key="opt.value"
161
+ :label="t(opt.label)"
162
+ :value="opt.value"
163
+ :data-test-id="`EL-OPTION-5wrWi5-${index}`"
164
+ />
165
+ </el-select>
166
+ </el-form-item>
167
+
168
+ <!-- 日期单值 -->
169
+ <el-form-item
170
+ v-else-if="isDateType(item.ColumnType) && [1, 2, 3, 4, 5].includes(item.Operator)"
171
+ prop="DateTimeOperatorValue"
172
+ data-test-id="EL-FORM-ITEM-932Tco"
173
+ >
174
+ <el-row :gutter="10" data-test-id="EL-ROW-CWWfMC">
175
+ <el-col :span="6" data-test-id="EL-COL-3tGiBz8">
176
+ <el-select
177
+ v-model="item.DateTimeOperatorValue.TimeType"
178
+ :placeholder="t('timePrecision')"
179
+ clearable
180
+ data-test-id="EL-SELECT-nphb5z"
181
+ >
182
+ <el-option
183
+ v-for="(it, index) in timePrecisionOptions"
184
+ :key="it.value"
185
+ :label="t(it.label)"
186
+ :value="it.value"
187
+ :data-test-id="`EL-OPTION-7foEY9-${index}`"
188
+ />
189
+ </el-select>
190
+ </el-col>
191
+ <el-col :span="18" data-test-id="EL-COL-rxXI8U">
192
+ <el-date-picker
193
+ v-model="item.DateTimeOperatorValue.TimeValue"
194
+ :type="item.DateTimeOperatorValue.TimeType === 0 ? 'date' : 'datetime'"
195
+ :format="timePrecisionOptionsFunction(item.DateTimeOperatorValue.TimeType)"
196
+ value-format="x"
197
+ :placeholder="t('selectTime')"
198
+ clearable
199
+ data-test-id="EL-DATE-PICKER-BFwrVh"
200
+ />
201
+ </el-col>
202
+ </el-row>
203
+ </el-form-item>
204
+
205
+ <!-- 日期范围 -->
206
+ <el-form-item
207
+ v-else-if="isDateType(item.ColumnType) && item.Operator === 11"
208
+ prop="DateTimeRangeValue"
209
+ data-test-id="EL-FORM-ITEM-nM49hw"
210
+ >
211
+ <el-row :gutter="10" data-test-id="EL-ROW-zZIFj0">
212
+ <el-col :span="6" data-test-id="EL-COL-k6LrJP">
213
+ <el-select
214
+ v-model="item.DateTimeRangeValue.TimeType"
215
+ :placeholder="t('timePrecision')"
216
+ clearable
217
+ data-test-id="EL-SELECT-93yQnb"
218
+ >
219
+ <el-option
220
+ v-for="(it, index) in timePrecisionOptions"
221
+ :key="it.value"
222
+ :label="t(it.label)"
223
+ :value="it.value"
224
+ :data-test-id="`EL-OPTION-WuL5hF-${index}`"
225
+ />
226
+ </el-select>
227
+ </el-col>
228
+ <el-col :span="24" data-test-id="EL-COL-Zy3UKA">
229
+ <el-date-picker
230
+ :key="componentKey"
231
+ v-model="item.DateTimeRangeValue.TimeValue"
232
+ style="width: 90%; margin-top: 1rem"
233
+ :type="item.DateTimeRangeValue.TimeType === 0 ? 'daterange' : 'datetimerange'"
234
+ :format="timePrecisionOptionsFunction(item.DateTimeRangeValue.TimeType)"
235
+ value-format="x"
236
+ clearable
237
+ range-separator="-"
238
+ :start-placeholder="t('starttime')"
239
+ :end-placeholder="t('endtime')"
240
+ data-test-id="EL-DATE-PICKER-fPXNSn"
241
+ @clear="item.DateTimeRangeValue.TimeValue = []"
242
+ @change="(() => {
243
+ componentKey++
244
+ })"
245
+ />
246
+ </el-col>
247
+ </el-row>
248
+ </el-form-item>
249
+
250
+ <!-- 动态筛选 -->
251
+ <el-form-item
252
+ v-else-if="isDateType(item.ColumnType) && item.Operator === 12"
253
+ prop="DateTimeDynamicFilteringValue"
254
+ data-test-id="EL-FORM-ITEM-3pz54d"
255
+ >
256
+ <el-row :gutter="10" data-test-id="EL-ROW-wcwmDm">
257
+ <el-col :span="12" data-test-id="EL-COL-1WOBcB">
258
+ <el-select
259
+ v-model="item.DateTimeDynamicFilteringValue.DateType"
260
+ :placeholder="t('dynamicFiltering')"
261
+ clearable
262
+ data-test-id="EL-SELECT-93zW0f"
263
+ @change="handleDateTimeDynamicFilteringValueChange($event, index)"
264
+ >
265
+ <el-option
266
+ v-for="(it, index) in dynamicFilteringOptions"
267
+ :key="it.value"
268
+ :label="t(it.label)"
269
+ :value="it.value"
270
+ :data-test-id="`EL-OPTION-j2Gto6-${index}`"
271
+ />
272
+ </el-select>
273
+ </el-col>
274
+ <el-col :span="12" data-test-id="8">
275
+ <div style="width: 200px" data-test-id="DIV-oQYQZI" />
276
+ </el-col>
277
+ </el-row>
278
+ </el-form-item>
279
+
280
+ <!-- 自定义单区间 -->
281
+ <el-form-item
282
+ v-if="
283
+ item.DateTimeDynamicFilteringValue.DateType === 0 || item.DateTimeDynamicFilteringValue.DateType === 1
284
+ "
285
+ prop="DateTimeDynamicFilteringCustomize"
286
+ data-test-id="EL-FORM-ITEM-oKi0MK"
287
+ >
288
+ <el-col v-if="item.DateTimeDynamicFilteringValue.DateType === 0" :span="24" data-test-id="EL-COL-5XNCgU">
289
+ <el-row :gutter="10" data-test-id="EL-ROW-zHGl1c">
290
+ <el-col :span="8" data-test-id="EL-COL-tTDMtb">
291
+ <el-select
292
+ v-model="item.DateTimeDynamicFilteringCustomize[0].PastOrFuture"
293
+ :placeholder="t('pastOrFuture')"
294
+ clearable
295
+ data-test-id="EL-SELECT-xifi4x"
296
+ >
297
+ <el-option
298
+ v-for="(it, index) in pastOrFutureOptions"
299
+ :key="it.value"
300
+ :label="t(it.label)"
301
+ :value="it.value"
302
+ :data-test-id="`EL-OPTION-0ql2zr-${index}`"
303
+ />
304
+ </el-select>
305
+ </el-col>
306
+ <el-col :span="8" data-test-id="EL-COL-T5qcri">
307
+ <el-input-number
308
+ v-model="item.DateTimeDynamicFilteringCustomize[0].NumberValue"
309
+ :min="1"
310
+ :max="365"
311
+ :precision="0"
312
+ :controls="false"
313
+ style="width: 100%"
314
+ clearable
315
+ data-test-id="EL-INPUT-NUMBER-RYLnRt"
316
+ />
317
+ </el-col>
318
+ <el-col :span="8" data-test-id="EL-COL-JlxABO">
319
+ <el-select
320
+ v-model="item.DateTimeDynamicFilteringCustomize[0].DayType"
321
+ :placeholder="t('unit')"
322
+ clearable
323
+ data-test-id="EL-SELECT-8Lpazq"
324
+ >
325
+ <el-option
326
+ v-for="(it, index) in dayTypeOptions"
327
+ :key="it.value"
328
+ :label="t(it.label)"
329
+ :value="it.value"
330
+ :data-test-id="`EL-OPTION-ncuVRo-${index}`"
331
+ />
332
+ </el-select>
333
+ </el-col>
334
+ </el-row>
335
+ </el-col>
336
+
337
+ <!-- 自定义双区间 -->
338
+ <el-col
339
+ v-else-if="item.DateTimeDynamicFilteringValue.DateType === 1"
340
+ :span="24"
341
+ data-test-id="EL-COL-eM8opS"
342
+ >
343
+ <el-row :gutter="10" data-test-id="EL-ROW-lcZ8pe">
344
+ <el-col :span="8" data-test-id="EL-COL-7j3j0p">
345
+ <el-select
346
+ v-model="item.DateTimeDynamicFilteringCustomize[0].PastOrFuture"
347
+ :placeholder="t('pastOrFuture')"
348
+ clearable
349
+ data-test-id="EL-SELECT-FjHTpQ"
350
+ >
351
+ <el-option
352
+ v-for="(it, index) in pastOrFutureOptions"
353
+ :key="it.value"
354
+ :label="t(it.label)"
355
+ :value="it.value"
356
+ :data-test-id="`EL-OPTION-xpcYp5-${index}`"
357
+ />
358
+ </el-select>
359
+ </el-col>
360
+ <el-col :span="8" data-test-id="EL-COL-JnQ12D">
361
+ <el-input-number
362
+ v-model="item.DateTimeDynamicFilteringCustomize[0].NumberValue"
363
+ :min="1"
364
+ :max="365"
365
+ :precision="0"
366
+ :controls="false"
367
+ style="width: 100%"
368
+ clearable
369
+ data-test-id="EL-INPUT-NUMBER-3lwksG"
370
+ />
371
+ </el-col>
372
+ <el-col :span="8" data-test-id="EL-COL-ms7sgy">
373
+ <el-select
374
+ v-model="item.DateTimeDynamicFilteringCustomize[0].DayType"
375
+ :placeholder="t('unit')"
376
+ clearable
377
+ data-test-id="EL-SELECT-fgZOLb"
378
+ >
379
+ <el-option
380
+ v-for="(it, index) in dayTypeOptions"
381
+ :key="it.value"
382
+ :label="t(it.label)"
383
+ :value="it.value"
384
+ :data-test-id="`EL-OPTION-Q07Tx8-${index}`"
385
+ />
386
+ </el-select>
387
+ </el-col>
388
+ </el-row>
389
+ <el-row :gutter="10" style="margin-top: 1rem" data-test-id="EL-ROW-XkOYka">
390
+ <el-col :span="8" data-test-id="EL-COL-dLQQRb">
391
+ <el-select
392
+ v-model="item.DateTimeDynamicFilteringCustomize[1].PastOrFuture"
393
+ :placeholder="t('pastOrFuture')"
394
+ clearable
395
+ data-test-id="EL-SELECT-ZNyGMx"
396
+ >
397
+ <el-option
398
+ v-for="(it, index) in pastOrFutureOptions"
399
+ :key="it.value"
400
+ :label="t(it.label)"
401
+ :value="it.value"
402
+ :data-test-id="`EL-OPTION-nlnE2g-${index}`"
403
+ />
404
+ </el-select>
405
+ </el-col>
406
+ <el-col :span="8" data-test-id="EL-COL-3uTjYF">
407
+ <el-input-number
408
+ v-model="item.DateTimeDynamicFilteringCustomize[1].NumberValue"
409
+ :min="1"
410
+ :max="365"
411
+ :precision="0"
412
+ :controls="false"
413
+ style="width: 100%"
414
+ clearable
415
+ data-test-id="EL-INPUT-NUMBER-w1GgpV"
416
+ />
417
+ </el-col>
418
+ <el-col :span="8" data-test-id="EL-COL-wDLRGi">
419
+ <el-select
420
+ v-model="item.DateTimeDynamicFilteringCustomize[1].DayType"
421
+ :placeholder="t('unit')"
422
+ clearable
423
+ data-test-id="EL-SELECT-3d7Hyz"
424
+ >
425
+ <el-option
426
+ v-for="(it, index) in dayTypeOptions"
427
+ :key="it.value"
428
+ :label="t(it.label)"
429
+ :value="it.value"
430
+ :data-test-id="`EL-OPTION-wkFjZV-${index}`"
431
+ />
432
+ </el-select>
433
+ </el-col>
434
+ </el-row>
435
+ </el-col>
436
+ </el-form-item>
437
+ </el-col>
438
+ <el-col v-if="!isItDefault" :span="2" data-test-id="EL-COL-7VbmTB">
439
+ <!-- 删除按钮 -->
440
+ <el-button type="text" data-test-id="EL-BUTTON-f9487D" @click="removeFilter(index)">
441
+ <i class="mdi mdi-close" data-test-id="I-lr2pJ2" />
442
+ </el-button>
443
+ </el-col>
444
+ </el-row>
445
+ </el-form>
446
+ </div>
447
+ </template>
448
+ <script setup>
449
+ import { ref, nextTick } from 'vue';
450
+ import { useI18n } from 'vue-i18n';
451
+ import { ElMessageBox, ElMessage } from 'element-plus';
452
+
453
+ const { t } = useI18n();
454
+ const props = defineProps({
455
+ filterConditions: {
456
+ type: Array,
457
+ default: () => [],
458
+ }, // 筛选条件
459
+ fieldSetting: {
460
+ type: Array,
461
+ default: () => [],
462
+ }, // 筛选条件内容的字段配置
463
+ isItDefault: {
464
+ type: Boolean,
465
+ default: false,
466
+ }, // 是否默认筛选条件
467
+ otherFilterConditions: {
468
+ type: Array,
469
+ default: () => [],
470
+ }, // 其他筛选条件
471
+ selectOptions: {
472
+ type: Object,
473
+ default: function () {
474
+ return {};
475
+ },
476
+ }, // 外部传入的筛选选项数据
477
+ });
478
+ const componentKey = ref(1);
479
+ const { filterConditions, fieldSetting, isItDefault, otherFilterConditions } = props;
480
+ // 工具函数:判断字段类型
481
+ const isTextLikeType = (type) => [1, 5, 6].includes(type); // 文本、附件、超链接
482
+ const isSelectType = (type) => [7, 8].includes(type); // 单选、多选
483
+ const isDateType = (type) => [3, 4].includes(type); // 日期、日期范围
484
+ const isTextOperator = (op) => [5, 6, 7, 8].includes(op); // 等于、包含等
485
+
486
+ const filterForm = ref([]);
487
+ // 验证规则动态生成
488
+ const getRules = (item) => {
489
+ const rules = {};
490
+
491
+ if (![9, 10].includes(item?.Operator)) {
492
+ if (item.ColumnType === 2 && [13, 14].includes(item.Operator)) {
493
+ rules.NumberRangeValue = [
494
+ {
495
+ validator: (rule, value, callback) => {
496
+ if (value.length === 1 && value[0] !== null) {
497
+ return callback(new Error(t('inputValidRange')));
498
+ }
499
+ if (value.length === 2 && (value[0] === null) !== (value[1] === null)) {
500
+ return callback(new Error(t('inputValidRange')));
501
+ }
502
+ if (value.length === 2 && value[0] !== null && value[1] !== null && value[0] > value[1]) {
503
+ return callback(new Error(t('startValueCannotGreaterThanEndValue')));
504
+ }
505
+ callback();
506
+ },
507
+ trigger: 'change',
508
+ },
509
+ ];
510
+ }
511
+ }
512
+
513
+ return rules;
514
+ };
515
+ /**
516
+ * 数字范围验证
517
+ * @param index 筛选条件索引
518
+ */
519
+ const handleNumberValidate = (index) => {
520
+ filterConditions[index].NumberRangeValue = [];
521
+ filterForm.value[index].clearValidate('NumberRangeValue');
522
+ filterForm.value[index].validateField('NumberRangeValue');
523
+ };
524
+
525
+ /* 时间精度 */
526
+ const timePrecisionOptions = ref([
527
+ { value: 0, label: 'daily', timeFormat: 'YYYY-MM-DD' },
528
+ { value: 1, label: 'hour', timeFormat: 'YYYY-MM-DD HH' },
529
+ { value: 2, label: 'minute', timeFormat: 'YYYY-MM-DD HH:mm' },
530
+ { value: 3, label: 'second', timeFormat: 'YYYY-MM-DD HH:mm:ss' },
531
+ ]);
532
+ /**
533
+ * 时间精度选项
534
+ * @param timeType 时间精度
535
+ * @returns 时间格式
536
+ */
537
+ const timePrecisionOptionsFunction = (timeType) => {
538
+ return timePrecisionOptions.value.find((item) => item.value === timeType)?.timeFormat;
539
+ };
540
+ /* 动态筛选 */
541
+ const dynamicFilteringOptions = ref([
542
+ { value: 2, label: 'today' },
543
+ { value: 3, label: 'yesterday' },
544
+ { value: 4, label: 'thisWeek' },
545
+ { value: 5, label: 'lastWeek' },
546
+ { value: 6, label: 'thisMonth' },
547
+ { value: 7, label: 'lastMonth' },
548
+ { value: 8, label: 'lastThreeMonths' },
549
+ { value: 0, label: 'custom' },
550
+ { value: 1, label: 'customRange' },
551
+ ]);
552
+ /* 动态筛选自定义筛选 */
553
+ const pastOrFutureOptions = ref([
554
+ { value: 0, label: 'past' },
555
+ { value: 1, label: 'future' },
556
+ ]);
557
+ /* 动态筛选自定义筛选时间类型 */
558
+ const dayTypeOptions = ref([
559
+ { value: 1, label: 'daily' },
560
+ { value: 2, label: 'week' },
561
+ { value: 3, label: 'month' },
562
+ { value: 4, label: 'quarter' },
563
+ { value: 5, label: 'year' },
564
+ ]);
565
+ /* 筛选条件内容的字段类型为4时,判断逻辑选项 */
566
+ const startOrEndOptions = ref([
567
+ { value: 0, label: 'intervalStart' },
568
+ { value: 1, label: 'intervalEnd' },
569
+ ]);
570
+ /* 判断逻辑 */
571
+ const operatorOptions = ref([
572
+ { value: 1, label: 'greaterThan' },
573
+ { value: 2, label: 'greaterThanOrEqualTo' },
574
+ { value: 3, label: 'lessThan' },
575
+ { value: 4, label: 'lessThanOrEqualTo' },
576
+ { value: 5, label: 'equalTo' },
577
+ { value: 6, label: 'notEqualTo' },
578
+ { value: 7, label: 'contains' },
579
+ { value: 8, label: 'notContains' },
580
+ { value: 9, label: 'yesEmpty' },
581
+ { value: 10, label: 'notEmpty' },
582
+ { value: 11, label: 'selectRange' },
583
+ { value: 12, label: 'dynamicFiltering' },
584
+ { value: 13, label: 'inRange' },
585
+ { value: 14, label: 'notInRange' },
586
+ { value: 15, label: 'isOneOf' },
587
+ { value: 16, label: 'notAnyOf' },
588
+ ]);
589
+ /**
590
+ * 筛选条件内容的字段类型改变时,判断逻辑选项改变
591
+ * @param fieldTypeId 筛选条件内容的字段类型
592
+ * @returns 筛选条件内容的判断逻辑选项
593
+ */
594
+ const operatorOptionsFunction = (fieldTypeId) => {
595
+ const mapping = {
596
+ 1: [5, 6, 7, 8, 9, 10], // 文本
597
+ 2: [9, 10, 13, 14], // 数字
598
+ 3: [1, 2, 3, 4, 5, 9, 10, 11, 12], // 日期
599
+ 4: [1, 2, 3, 4, 5, 9, 10, 11, 12], // 日期范围
600
+ 5: [5, 6, 7, 8, 9, 10], // 附件
601
+ 6: [5, 6, 7, 8, 9, 10], // 超链接
602
+ 7: [5], // 单选
603
+ 8: [9, 10, 15, 16], // 多选
604
+ };
605
+ const allowed = mapping[fieldTypeId] || [];
606
+ return operatorOptions.value.filter((op) => allowed.includes(op.value));
607
+ };
608
+ /**
609
+ * 筛选条件内容的字段类型改变时,判断逻辑选项改变
610
+ * @param columnName 筛选条件内容的字段类型
611
+ * @returns 筛选条件内容的判断逻辑选项
612
+ */
613
+ const fieldSelectOptionsFunction = (columnName) => {
614
+ // 添加输入验证,确保columnName是有效的字符串
615
+ if (columnName === null || columnName === undefined) {
616
+ return [];
617
+ }
618
+ try {
619
+ // 优先使用外部提供的直接字段配置
620
+ if (props.selectOptions && typeof props.selectOptions === 'object') {
621
+ // 1.直接通过字段名配置
622
+ if (props.selectOptions[columnName]) {
623
+ return Array.isArray(props.selectOptions[columnName]) ? props.selectOptions[columnName] : [];
624
+ }
625
+ // 2.通过类型配置(例如xxxOptions)
626
+ const typeOptionsKey = Object.keys(props.selectOptions).find(
627
+ (key) => key.endsWith('Options') && columnName.includes(key.replace('Options', '')),
628
+ );
629
+ if (typeOptionsKey) {
630
+ return Array.isArray(props.selectOptions[typeOptionsKey]) ? props.selectOptions[typeOptionsKey] : [];
631
+ }
632
+ }
633
+ // 从字段配置中获取选项
634
+ const dataSource = Array.isArray(fieldSetting) ? fieldSetting : [];
635
+ const field = dataSource.find((f) => f && f.key === columnName);
636
+ if (field && (field.fieldTypeId === 7 || field.fieldTypeId === 8)) {
637
+ // 选择类型字段(单选/多选)
638
+ if (field.fieldSelectOptions) {
639
+ try {
640
+ const opts = JSON.parse(field.fieldSelectOptions);
641
+ return Array.isArray(opts)
642
+ ? opts.map((opt) => ({
643
+ label: field.isDoc ? opt : opt ? opt.key || opt.label || opt.value : '',
644
+ value: field.isDoc ? opt : opt ? opt.value : '',
645
+ }))
646
+ : [];
647
+ } catch (jsonError) {
648
+ ElMessage.error(t('apiError'));
649
+ }
650
+ }
651
+ }
652
+
653
+ return [];
654
+ } catch (e) {
655
+ return [];
656
+ }
657
+ };
658
+ /**
659
+ * 筛选条件内容的字段类型改变时,赋默认值
660
+ * @param type 筛选条件内容的字段类型
661
+ */
662
+ const fieldTypeFun = (type) => {
663
+ if ([1, 5, 6].includes(type)) {
664
+ return 5;
665
+ }
666
+ if (type === 2) {
667
+ return 13;
668
+ }
669
+ if ([3, 4].includes(type)) {
670
+ return 11;
671
+ }
672
+ if (type === 7) {
673
+ return 5;
674
+ }
675
+ if (type === 8) {
676
+ return 15;
677
+ }
678
+ return null;
679
+ };
680
+ /**
681
+ * 筛选条件内容的字段类型改变时,判断逻辑选项改变
682
+ * @param value 筛选条件内容的字段类型
683
+ * @param index 筛选条件的索引
684
+ */
685
+ const handleChangeColumn = (value, index) => {
686
+ const field = props.fieldSetting.find((f) => f.key === value);
687
+ const item = filterConditions[index];
688
+ Object.assign(item, {
689
+ CloumnName: value,
690
+ ColumnType: field?.fieldTypeId,
691
+ Operator: fieldTypeFun(field?.fieldTypeId),
692
+ StartOrEnd: null,
693
+ TextValue: null,
694
+ IsCustomSetting: field?.isDoc,
695
+ DocCustomId: field?.isDoc ? field.key : null,
696
+ NumberRangeValue: [],
697
+ SelectRangeValue: [],
698
+ SingleSelectValue: null,
699
+ DateTimeOperatorValue: { TimeType: null, TimeValue: null },
700
+ DateTimeRangeValue: { TimeType: [3, 4].includes(field?.fieldTypeId) ? 0 : null, TimeValue: [] },
701
+ DateTimeDynamicFilteringValue: { DateType: null },
702
+ DateTimeDynamicFilteringCustomize: [
703
+ { PastOrFuture: null, NumberValue: null, DayType: null },
704
+ { PastOrFuture: null, NumberValue: null, DayType: null },
705
+ ],
706
+ });
707
+ };
708
+ /**
709
+ *
710
+ * @param value 筛选条件内容的判断逻辑
711
+ * @param index 筛选条件的索引
712
+ */
713
+ const handleChangeOperator = (value, index) => {
714
+ const item = filterConditions[index];
715
+ // 清空无关字段
716
+ Object.assign(item, {
717
+ TextValue: null,
718
+ NumberRangeValue: [],
719
+ SelectRangeValue: [],
720
+ SingleSelectValue: null,
721
+ DateTimeOperatorValue: { TimeType: null, TimeValue: null },
722
+ DateTimeRangeValue: { TimeType: null, TimeValue: [] },
723
+ DateTimeDynamicFilteringValue: { DateType: null },
724
+ DateTimeDynamicFilteringCustomize: [
725
+ { PastOrFuture: null, NumberValue: null, DayType: null },
726
+ { PastOrFuture: null, NumberValue: null, DayType: null },
727
+ ],
728
+ });
729
+ };
730
+ /**
731
+ * 动态筛选自定义筛选时间类型改变时,判断逻辑选项改变
732
+ * @param value 动态筛选自定义筛选时间类型
733
+ * @param index 筛选条件的索引
734
+ */
735
+ const handleDateTimeDynamicFilteringValueChange = (value, index) => {
736
+ const item = filterConditions[index];
737
+ item.DateTimeDynamicFilteringCustomize = [
738
+ { PastOrFuture: null, NumberValue: null, DayType: null },
739
+ { PastOrFuture: null, NumberValue: null, DayType: null },
740
+ ];
741
+ };
742
+ /**
743
+ * 删除筛选条件
744
+ * @param index 筛选条件的索引
745
+ */
746
+ const removeFilter = (index) => {
747
+ ElMessageBox.confirm(t('confirmToDelete'), t('confirmDelete'), {
748
+ confirmButtonText: t('confirm'),
749
+ cancelButtonText: t('cancel'),
750
+ type: 'warning',
751
+ }).then(() => {
752
+ filterConditions.splice(index, 1);
753
+ // emit('update:filterConditions', filterConditions);
754
+ });
755
+ };
756
+ // 暴露提交方法
757
+ const validateAllForms = async () => {
758
+ await nextTick();
759
+ try {
760
+ await Promise.all(filterForm.value.map((form) => form?.validate?.() || Promise.resolve()));
761
+ return true;
762
+ } catch (error) {
763
+ ElMessage.error(t('checkForm'));
764
+ return false;
765
+ }
766
+ };
767
+ defineExpose({ validateAllForms });
768
+ </script>
769
+ <style scoped lang="scss"></style>