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,542 @@
1
+ <template>
2
+ <div class="view-box flex-center" data-test-id="DIV-f6cLWs">
3
+ <el-tabs
4
+ v-model="editableTabsValue"
5
+ type="card"
6
+ :closable="false"
7
+ :stretch="false"
8
+ data-test-id="EL-TABS-hQi8BJ"
9
+ @tab-click="handleTabClick"
10
+ >
11
+ <!-- 遍历所有可编辑标签(保留标签,仅控制过滤条件显示) -->
12
+ <el-tab-pane
13
+ v-for="(item, index) in editableTabs"
14
+ :key="item.id"
15
+ :label="item.viewName"
16
+ :name="item.viewName"
17
+ :data-test-id="`EL-TAB-PANE-yEF1MT-${index}`"
18
+ >
19
+ <template #label>
20
+ <div class="tab-label-container">
21
+ <el-popover
22
+ :title="item.id < 0 && (item.viewName === '全部' || item.viewName === 'all') ? t('all') : item.viewName"
23
+ placement="bottom"
24
+ width="auto"
25
+ data-test-id="EL-POPOVER-KqCZyA"
26
+ >
27
+ <template #reference>
28
+ <div class="fixed-width flex-center" data-test-id="DIV-Vgcixm">
29
+ <v-icon
30
+ :style="{ color: iconColors[Number(item.meta)] }"
31
+ class="mdi mdi-book-open-blank-variant"
32
+ data-test-id="V-ICON-F6vGIl"
33
+ />
34
+ <span
35
+ class="tab-title"
36
+ :style="viewId === item.id ? 'font-weight: 700' : ''"
37
+ data-test-id="SPAN-4OpUJc"
38
+ >
39
+ {{
40
+ item.id < 0 && (item.viewName === '全部' || item.viewName === 'all') ? t('all') : item.viewName
41
+ }}
42
+ </span>
43
+ </div>
44
+ </template>
45
+ <!-- 仅当parsedFilter有效时显示过滤条件 -->
46
+ <div v-if="isParsedFilterValid(item.parsedFilter)" class="span-box" data-test-id="DIV-BiX4o2">
47
+ <div style="margin-bottom: 5px" data-test-id="DIV-v0zgNe">{{ t('dataFilter') }}</div>
48
+ <span
49
+ v-for="(subArray, subIndex) in item.parsedFilter"
50
+ :key="subIndex"
51
+ :data-test-id="`SPAN-Y5w6Ny-${subIndex}`"
52
+ >
53
+ <template v-if="subArray.length > 0">
54
+ <span
55
+ v-for="(field, fieldIndex) in subArray"
56
+ :key="fieldIndex"
57
+ :data-test-id="`SPAN-RA8qb9-${fieldIndex}`"
58
+ >
59
+ {{ t(field) || field }}
60
+ <span v-if="fieldIndex < subArray.length - 1" data-test-id="SPAN-Zj5s2a">&nbsp;</span>
61
+ </span>
62
+ <br v-if="subIndex < item.parsedFilter.length - 1" data-test-id="BR-g8bZ8D" />
63
+ </template>
64
+ </span>
65
+ </div>
66
+ <!-- parsedFilter无效时显示提示(可选) -->
67
+ <div v-else class="empty-filter-tip" data-test-id="DIV-5qrLAo" />
68
+ </el-popover>
69
+ <!-- 标签操作下拉菜单(始终显示) -->
70
+ <el-dropdown
71
+ v-if="viewType"
72
+ placement="bottom-start"
73
+ trigger="click"
74
+ data-test-id="EL-DROPDOWN-S8ReG5"
75
+ @command="(command) => handleViewOption(item, command)"
76
+ @click.stop
77
+ >
78
+ <span class="mdi mdi-dots-vertical" data-test-id="SPAN-JZNwUC" />
79
+ <template #dropdown>
80
+ <el-dropdown-menu data-test-id="EL-DROPDOWN-MENU-lXcUWS">
81
+ <el-dropdown-item command="edit" data-test-id="EL-DROPDOWN-ITEM-a8rxXb">
82
+ <span class="mdi mdi-pencil" style="margin-right: 0.5rem" data-test-id="SPAN-c8iMHY" />
83
+ {{ t('edit') }}
84
+ </el-dropdown-item>
85
+ <el-dropdown-item command="copy" data-test-id="EL-DROPDOWN-ITEM-cTJWPm">
86
+ <span class="mdi mdi-content-copy" style="margin-right: 0.5rem" data-test-id="SPAN-ixzjfp" />
87
+ {{ t('copy') }}
88
+ </el-dropdown-item>
89
+ <el-dropdown-item command="delete" data-test-id="EL-DROPDOWN-ITEM-le8tGS">
90
+ <span class="mdi mdi-trash-can" style="margin-right: 0.5rem" data-test-id="SPAN-Ihig61" />
91
+ {{ t('delete') }}
92
+ </el-dropdown-item>
93
+ </el-dropdown-menu>
94
+ </template>
95
+ </el-dropdown>
96
+ </div>
97
+ </template>
98
+ </el-tab-pane>
99
+ </el-tabs>
100
+ <!-- 更多视图(保留标签,仅控制过滤条件显示) -->
101
+ <div v-if="moreTabs.length" class="view-more" data-test-id="DIV-VIE0ym">
102
+ <el-dropdown trigger="click" placement="bottom-end" data-test-id="EL-DROPDOWN-Y6vrvm">
103
+ <span data-test-id="SPAN-N2VdKy">
104
+ <el-button type="text" data-test-id="EL-BUTTON-8gv545">
105
+ <div class="flex-center" data-test-id="DIV-mCNYU8">
106
+ <div v-if="!isShowClickTab" class="more-txt" data-test-id="DIV-z5UnfR">{{ t('moreView') }}</div>
107
+ <div v-else class="more-txt" data-test-id="DIV-54VVVY">
108
+ {{ clickViewName === 'all' ? t('all') : clickViewName }}
109
+ </div>
110
+ <div data-test-id="DIV-YkEYuZ"><span class="mdi mdi-chevron-down" data-test-id="SPAN-OA1DMi" /></div>
111
+ </div>
112
+ </el-button>
113
+ </span>
114
+ <template #dropdown>
115
+ <el-dropdown-menu data-test-id="EL-DROPDOWN-MENU-EaVFiu">
116
+ <el-dropdown-item
117
+ v-for="(item, index) in moreTabs"
118
+ :key="item.id"
119
+ :data-test-id="`EL-DROPDOWN-ITEM-p4mHqG-${index}`"
120
+ @click="handleTabOperation2(item)"
121
+ >
122
+ <el-popover
123
+ :title="item.id < 0 && (item.viewName === '全部' || item.viewName === 'all') ? t('all') : item.viewName"
124
+ placement="left"
125
+ width="aoto"
126
+ data-test-id="EL-POPOVER-bIn3x3"
127
+ >
128
+ <template #reference>
129
+ <div class="fixed-width flex-center" data-test-id="DIV-iCwDyl">
130
+ <v-icon
131
+ :style="{ color: iconColors[item.meta] }"
132
+ class="mdi mdi-book-open-blank-variant"
133
+ style="margin-right: 0.5rem"
134
+ data-test-id="V-ICON-V8uyqx"
135
+ />
136
+ <span class="tab-title" data-test-id="SPAN-kvDuvy">
137
+ {{
138
+ item.id < 0 && (item.viewName === '全部' || item.viewName === 'all') ? t('all') : item.viewName
139
+ }}
140
+ </span>
141
+ </div>
142
+ </template>
143
+ <!-- 仅当parsedFilter有效时显示过滤条件 -->
144
+ <div v-if="isParsedFilterValid(item.parsedFilter)" class="span-box" data-test-id="DIV-PgJjLg">
145
+ <div style="margin-bottom: 5px" data-test-id="DIV-qlWueE">{{ t('dataFilter') }}</div>
146
+ <span
147
+ v-for="(subArray, subIndex) in item.parsedFilter"
148
+ :key="subIndex"
149
+ :data-test-id="`SPAN-gwUPHe-${subIndex}`"
150
+ >
151
+ <template v-if="subArray.length > 0">
152
+ <span
153
+ v-for="(field, fieldIndex) in subArray"
154
+ :key="fieldIndex"
155
+ :data-test-id="`SPAN-Yoke3N-${fieldIndex}`"
156
+ >
157
+ {{ t(field) || field }}
158
+ <span v-if="fieldIndex < subArray.length - 1" data-test-id="SPAN-b69aKz">&nbsp;</span>
159
+ </span>
160
+ <br v-if="subIndex < item.parsedFilter.length - 1" data-test-id="BR-6bC7S9" />
161
+ </template>
162
+ </span>
163
+ </div>
164
+ <!-- parsedFilter无效时显示提示(可选) -->
165
+ <div v-else class="empty-filter-tip" data-test-id="DIV-5FYT0D" />
166
+ </el-popover>
167
+ <!-- 更多视图操作下拉菜单(始终显示) -->
168
+ <el-dropdown
169
+ v-if="viewType"
170
+ placement="bottom-start"
171
+ trigger="hover"
172
+ data-test-id="EL-DROPDOWN-VwI5JN"
173
+ @command="(command) => handleViewOption(item, command)"
174
+ >
175
+ <span class="mdi mdi-dots-vertical" data-test-id="SPAN-88aNbL" />
176
+ <template #dropdown>
177
+ <el-dropdown-menu data-test-id="EL-DROPDOWN-MENU-uB6AzT">
178
+ <el-dropdown-item command="edit" data-test-id="EL-DROPDOWN-ITEM-pPx9rh">
179
+ <span class="mdi mdi-pencil" style="margin-right: 0.5rem" data-test-id="SPAN-gONTrg" />
180
+ {{ t('edit') }}
181
+ </el-dropdown-item>
182
+ <el-dropdown-item command="copy" data-test-id="EL-DROPDOWN-ITEM-GzG8Jm">
183
+ <span class="mdi mdi-content-copy" style="margin-right: 0.5rem" data-test-id="SPAN-N1W2YJ" />
184
+ {{ t('copy') }}
185
+ </el-dropdown-item>
186
+ <el-dropdown-item command="delete" data-test-id="EL-DROPDOWN-ITEM-n2UcqQ">
187
+ <span class="mdi mdi-trash-can" style="margin-right: 0.5rem" data-test-id="SPAN-PL9dTd" />
188
+ {{ t('delete') }}
189
+ </el-dropdown-item>
190
+ </el-dropdown-menu>
191
+ </template>
192
+ </el-dropdown>
193
+ </el-dropdown-item>
194
+ </el-dropdown-menu>
195
+ </template>
196
+ </el-dropdown>
197
+ </div>
198
+ <!-- 操作按钮区(始终显示) -->
199
+ <div v-if="viewType" class="flex-center" data-test-id="DIV-1GGakX">
200
+ <el-tooltip :content="t('createView')" placement="top" :enterable="false" data-test-id="EL-TOOLTIP-tBu398">
201
+ <div class="plus-icon" data-test-id="DIV-2LlLoK" @click="emit('openViewDrawer')">
202
+ <el-button type="text" data-test-id="EL-BUTTON-v7caGb">
203
+ <span class="mdi mdi-plus" data-test-id="SPAN-vVJa7G" />
204
+ </el-button>
205
+ </div>
206
+ </el-tooltip>
207
+ <div class="plus-icon flex-center" data-test-id="DIV-7acJL9">
208
+ <el-tooltip
209
+ :content="t('viewOperationRecordTxt')"
210
+ placement="top"
211
+ :enterable="false"
212
+ data-test-id="EL-TOOLTIP-QQUw4G"
213
+ >
214
+ <el-button type="text" data-test-id="EL-BUTTON-D3QSbJ" @click="emit('openLogDrawer')">
215
+ <span class="mdi mdi-text-box-check-outline" style="margin-right: 0.5rem" data-test-id="SPAN-4M2L0o" />
216
+ {{ t('viewOperationRecordTxt') }}
217
+ </el-button>
218
+ </el-tooltip>
219
+ </div>
220
+ </div>
221
+
222
+ <!-- 视图编辑/复制抽屉(始终可用) -->
223
+ <!-- <ViewAddDrawer
224
+ v-if="isAddDrawerVisible"
225
+ v-model="isAddDrawerVisible"
226
+ :init-data="drawerInitData"
227
+ data-test-id="VIEWADDDRAWER-dsvnJb"
228
+ @view-saved="handleViewSaved"
229
+ @update:modelValue="isAddDrawerVisible = $event"
230
+ /> -->
231
+ </div>
232
+ </template>
233
+
234
+ <script setup>
235
+ import { ref, watch, nextTick } from 'vue';
236
+ import { useI18n } from 'vue-i18n';
237
+ // import ViewAddDrawer from './viewAddDrawer.vue';
238
+ import apiFunction from '@/scriptFiles/checkApiErrorMechanism';
239
+ import { ElMessageBox, ElMessage } from 'element-plus';
240
+ import { processFilterData } from './viewManageTool.js';
241
+
242
+ const { t } = useI18n();
243
+
244
+ // 接收父组件参数
245
+ const props = defineProps({
246
+ pageData: {
247
+ type: Object,
248
+ default: () => ({}),
249
+ },
250
+ viewType: {
251
+ type: Boolean,
252
+ default: false,
253
+ },
254
+ viewIdFromList: {
255
+ type: Number,
256
+ default: null,
257
+ },
258
+ tabs: {
259
+ type: Array,
260
+ required: true,
261
+ default: () => [],
262
+ },
263
+ selectOptions: {
264
+ type: Object,
265
+ default: () => ({}),
266
+ },
267
+ });
268
+
269
+ // 暴露事件给父组件
270
+ const emit = defineEmits(['openViewDrawer', 'openLogDrawer', 'tabUpdate', 'tabClick']);
271
+
272
+ // 响应式数据
273
+ const viewId = ref(''); // 视图id
274
+ const isShowClickTab = ref(false);
275
+ const clickViewName = ref('');
276
+ const iconColors = ref(['#125088', '#FF0000', '#F0D155', '#99C0E4', '#FF7A21', '#323338', '#34AA1A']);
277
+ const editableTabs = ref([]); // 保留所有可编辑标签
278
+ const moreTabs = ref([]); // 保留所有更多标签
279
+ const editableTabsValue = ref('');
280
+ const drawerInitData = ref(null);
281
+ const isEditing = ref(false); // 区分操作类型
282
+
283
+ // 校验parsedFilter是否有效(核心工具函数)
284
+ const isParsedFilterValid = (parsedFilter) => {
285
+ return (
286
+ Array.isArray(parsedFilter) &&
287
+ parsedFilter.length > 0 &&
288
+ parsedFilter.some((subArr) => Array.isArray(subArr) && subArr.length > 0)
289
+ );
290
+ };
291
+
292
+ // 标签点击事件
293
+ function handleTabClick(tab) {
294
+ isShowClickTab.value = false;
295
+ clickViewName.value = '';
296
+ // 获取当前激活的标签名
297
+ let tabName = tab.paneName;
298
+ // 如果 paneName 是 ComputedRefImpl,获取它的值
299
+ if (tabName && typeof tabName.value !== 'undefined') {
300
+ tabName = tabName.value;
301
+ }
302
+ // 使用 tabName 查找标签项
303
+ const clickedTab = editableTabs.value.find((item) => item.viewName === tabName);
304
+
305
+ if (clickedTab) {
306
+ editableTabsValue.value = clickedTab.viewName;
307
+ viewId.value = clickedTab.id;
308
+ nextTick(() => {
309
+ emit('tabClick', viewId.value, 1);
310
+ });
311
+ } else {
312
+ ElMessage.error(t('tabNotFound'));
313
+ }
314
+ }
315
+
316
+ // 更多视图点击事件
317
+ function handleTabOperation2(tabItem) {
318
+ isShowClickTab.value = true;
319
+ clickViewName.value =
320
+ tabItem.id < 0 && (tabItem.viewName === '全部' || tabItem.viewName === 'all') ? 'all' : tabItem.viewName;
321
+ viewId.value = tabItem.id;
322
+ editableTabsValue.value = ''; //清空激活项
323
+ nextTick(() => {
324
+ emit('tabClick', viewId.value, 1);
325
+ });
326
+ }
327
+
328
+ // 删除视图接口调用
329
+ async function doDeleteOperation(id) {
330
+ await apiFunction
331
+ .deleteView(id)
332
+ .then((res) => {
333
+ if (res.data?.code === 0) {
334
+ // 如果删除的是当前显示的更多视图,重置状态
335
+ if (isShowClickTab.value && viewId.value === id) {
336
+ isShowClickTab.value = false;
337
+ clickViewName.value = '';
338
+ }
339
+ emit('tabUpdate');
340
+ } else {
341
+ ElMessage.error(t(res.data.message));
342
+ }
343
+ })
344
+ .catch(() => {
345
+ ElMessage.error(t('apiError'));
346
+ });
347
+ }
348
+
349
+ // 标签操作(编辑/复制/删除)
350
+ function handleViewOption(tabItem, command) {
351
+ switch (command) {
352
+ case 'edit':
353
+ isEditing.value = true;
354
+ drawerInitData.value = {
355
+ mode: 'edit',
356
+ data: { ...tabItem },
357
+ permissionCode: props.pageData.permissionCode,
358
+ docCode: props.pageData.docCode,
359
+ };
360
+ nextTick(() => {
361
+ // 编辑相关操作
362
+ // emit('tabClick', tabItem.id, 'edit');
363
+ emit('tabClick', tabItem.id, 0, props.selectOptions);
364
+ });
365
+ break;
366
+
367
+ case 'copy':
368
+ drawerInitData.value = {
369
+ mode: 'copy',
370
+ data: {
371
+ ...tabItem,
372
+ name: `${t('copy')}${tabItem.name}`,
373
+ },
374
+ permissionCode: props.pageData.permissionCode,
375
+ docCode: props.pageData.docCode,
376
+ };
377
+ nextTick(() => {
378
+ // 复制相关操作
379
+ // emit('tabClick', tabItem.id, 'copy');
380
+ emit('tabClick', tabItem.id, 2, props.selectOptions);
381
+ });
382
+ break;
383
+
384
+ case 'delete':
385
+ ElMessageBox.confirm(t('viewDeleteTip'), t('delReminder'), {
386
+ type: 'warning',
387
+ confirmButtonText: t('confirm'),
388
+ cancelButtonText: t('cancel'),
389
+ })
390
+ .then(async () => {
391
+ await doDeleteOperation(tabItem.id);
392
+ })
393
+ .catch(() => {
394
+ return;
395
+ });
396
+ break;
397
+ }
398
+ }
399
+
400
+ function getEditableTabsValue() {
401
+ const foundInArray1 = editableTabs.value.find((item) => item.id === viewId.value);
402
+ if (foundInArray1) {
403
+ editableTabsValue.value = foundInArray1.viewName;
404
+ isShowClickTab.value = false;
405
+ clickViewName.value = '';
406
+ } else {
407
+ // 如果在第一个数组没找到,在第二个数组中查找
408
+ const foundInArray2 = moreTabs.value.find((item) => item.id === viewId.value);
409
+ if (foundInArray2) {
410
+ isShowClickTab.value = true;
411
+ clickViewName.value =
412
+ foundInArray2.id < 0 && (foundInArray2.viewName === '全部' || foundInArray2.viewName === 'all')
413
+ ? 'all'
414
+ : foundInArray2.viewName;
415
+ }
416
+ }
417
+ }
418
+
419
+ // 监听父组件tabs变化,仅解析不过滤标签
420
+ watch(
421
+ () => props.tabs,
422
+ (newTabs) => {
423
+ const safeTabs = Array.isArray(newTabs) ? newTabs : [];
424
+ // 1. 拆分标签(保留所有标签,不过滤)
425
+ if (safeTabs.length > 6) {
426
+ editableTabs.value = processFilterData(safeTabs.slice(0, 6)); // 仅解析,不过滤
427
+ moreTabs.value = processFilterData(safeTabs.slice(6)); // 仅解析,不过滤
428
+ } else {
429
+ editableTabs.value = processFilterData(safeTabs); // 仅解析,不过滤
430
+ moreTabs.value = [];
431
+ }
432
+ if (props.viewIdFromList) {
433
+ isEditing.value = true;
434
+ viewId.value = props.viewIdFromList;
435
+ }
436
+ // 2. 根据操作类型设置激活标签
437
+ if (isEditing.value) {
438
+ // 编辑操作:保持当前tab不变
439
+ isEditing.value = false; // 重置标志位
440
+ nextTick(() => {
441
+ getEditableTabsValue();
442
+ emit('tabClick', viewId.value, 'refresh');
443
+ });
444
+ } else {
445
+ // 检查当前选中的视图是否还存在
446
+ const currentViewExists = safeTabs.some((item) => item.id === viewId.value);
447
+ if (currentViewExists) {
448
+ // 如果当前选中的视图还存在,保持选中状态
449
+ nextTick(() => {
450
+ getEditableTabsValue();
451
+ });
452
+ } else {
453
+ // 其他操作:重置到第一个tab
454
+ isShowClickTab.value = false;
455
+ clickViewName.value = '';
456
+ editableTabsValue.value = safeTabs.length > 0 ? safeTabs[0].viewName : '';
457
+ viewId.value = safeTabs.length > 0 ? safeTabs[0]?.id : 0;
458
+ nextTick(() => {
459
+ emit('tabClick', viewId.value);
460
+ });
461
+ }
462
+ }
463
+ },
464
+ { deep: true, immediate: true },
465
+ );
466
+
467
+ // 视图保存后通知父组件刷新
468
+ // function handleViewSaved() {
469
+ // // eslint-disable-next-line vue/custom-event-name-casing
470
+ // emit('tab-update');
471
+ // }
472
+ </script>
473
+
474
+ <style scoped>
475
+ .flex-center {
476
+ display: flex;
477
+ align-items: center;
478
+ }
479
+
480
+ .view-box {
481
+ overflow-x: auto;
482
+ }
483
+
484
+ .view-box :deep(.el-tabs) {
485
+ max-width: 80%;
486
+ overflow: hidden;
487
+ }
488
+
489
+ .view-more {
490
+ margin-left: 20px;
491
+ margin-top: -15px;
492
+ }
493
+
494
+ .more-txt {
495
+ max-width: 80px;
496
+ overflow: hidden;
497
+ white-space: nowrap;
498
+ text-overflow: ellipsis;
499
+ }
500
+
501
+ .plus-icon {
502
+ margin-left: 20px;
503
+ margin-top: -15px;
504
+ }
505
+
506
+ .fixed-width {
507
+ width: 100px;
508
+ box-sizing: border-box;
509
+ }
510
+
511
+ .tab-title {
512
+ display: block;
513
+ overflow: hidden;
514
+ white-space: nowrap;
515
+ text-overflow: ellipsis;
516
+ margin-left: 5px;
517
+ width: 75px;
518
+ text-align: center;
519
+ }
520
+
521
+ /* 新增:标签容器样式 */
522
+ .tab-label-container {
523
+ display: flex;
524
+ align-items: center;
525
+ position: relative;
526
+ }
527
+
528
+ /* 空过滤条件提示样式 */
529
+ .empty-filter-tip {
530
+ color: #999;
531
+ font-size: 12px;
532
+ padding: 4px 0;
533
+ }
534
+
535
+ .span-box span:first-child {
536
+ color: #909399;
537
+ margin-right: 5px;
538
+ }
539
+
540
+ :deep(.el-dropdown-menu__item) {
541
+ }
542
+ </style>
@@ -0,0 +1,115 @@
1
+ <template>
2
+ <el-dialog
3
+ v-model="showDialog"
4
+ :before-close="dialogOptions.beforeClose"
5
+ :width="`${dialogOptions.width}%`"
6
+ :close-on-click-modal="closeOnClickModal"
7
+ :btn_array="dialogOptions.btns"
8
+ :scope="dialogOptions.scope"
9
+ :append-to-body="true"
10
+ :modal-append-to-body="true"
11
+ center
12
+ align-center
13
+ class="globalDialog"
14
+ style="border-radius: 6px"
15
+ data-test-id="EL-DIALOG-cQVOLz"
16
+ @optionClick="optionClick"
17
+ >
18
+ <template #header>
19
+ {{ $t(dialogOptions.title) }}
20
+ </template>
21
+ <div :style="{ height: defHeight + 'rem' }" data-test-id="DIV-9zutsg">
22
+ <div class="bodydivcontent" data-test-id="DIV-KWYRpI">
23
+ <slot />
24
+ </div>
25
+ </div>
26
+ <template v-if="!dialogOptions.isReadonly" #footer>
27
+ <div v-if="!dialogOptions.customFooter" class="dialog-footer" data-test-id="DIV-YsulBT">
28
+ <el-button
29
+ v-show="!dialogOptions.detail && !loading"
30
+ type="primary"
31
+ data-test-id="EL-BUTTON-atr1gR"
32
+ @click="dialogEvent('submit')"
33
+ >{{ $t('confirm') }}
34
+ </el-button>
35
+ <el-button
36
+ v-show="!dialogOptions.detail && loading"
37
+ type="primary"
38
+ :loading="loading"
39
+ data-test-id="EL-BUTTON-Kjdhyk"
40
+ @click="dialogEvent('submit')"
41
+ >{{ $t('confirm') }}
42
+ </el-button>
43
+ <!-- <el-button style="color: #595959" @click="dialogEvent('close')">{{ $t('cancel') }}</el-button> -->
44
+ </div>
45
+ <span v-else class="dialog-footer" data-test-id="SPAN-bKKXSO">
46
+ <slot name="footer" />
47
+ </span>
48
+ </template>
49
+ </el-dialog>
50
+ </template>
51
+
52
+ <script setup>
53
+ import { ref, watch } from 'vue';
54
+ // eslint-disable-next-line vue/valid-define-emits
55
+ const emit = defineEmits();
56
+ const props = defineProps({
57
+ dialogOptions: {
58
+ type: Object,
59
+ required: true,
60
+ width: {
61
+ type: String,
62
+ default: '30%',
63
+ },
64
+ title: {
65
+ type: String,
66
+ default: '标题',
67
+ },
68
+ appendBody: {
69
+ type: Boolean,
70
+ default: false,
71
+ },
72
+ dialogStatus: {
73
+ type: Boolean,
74
+ required: true,
75
+ default: false,
76
+ },
77
+ isReadonly: {
78
+ type: Boolean,
79
+ default: false,
80
+ },
81
+ },
82
+ });
83
+ const loading = ref(false);
84
+ const closeOnClickModal = ref(false);
85
+ const defHeight = ref(props.dialogOptions.height);
86
+
87
+ function optionClick(name, obj, btns, scope) {
88
+ emit(name, obj, btns, scope);
89
+ }
90
+ function dialogEvent(type) {
91
+ loading.value = true;
92
+ emit(type);
93
+ setTimeout(function () {
94
+ loading.value = false;
95
+ }, 2000);
96
+ }
97
+ const showDialog = ref(false);
98
+ watch(
99
+ () => props.dialogOptions.dialogStatus,
100
+ (val) => {
101
+ showDialog.value = val;
102
+ },
103
+ );
104
+ </script>
105
+
106
+ <style scoped lang="scss">
107
+ .bodydivcontent {
108
+ height: 100%;
109
+ }
110
+ .dialog-footer {
111
+ margin: 0 auto;
112
+ text-align: center;
113
+ height: 40px;
114
+ }
115
+ </style>