@bytenew/bn-bus-ui 1.1.461 → 1.1.463

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 (167) hide show
  1. package/install.js +134 -0
  2. package/package.json +20 -4
  3. package/packages/BnAddress/index.vue +141 -0
  4. package/packages/BnAddressParse/index.vue +75 -0
  5. package/packages/BnAdvancedFilter/BnFilterView.vue +145 -0
  6. package/packages/BnAdvancedFilter/index.vue +345 -0
  7. package/packages/BnAdvancedFilter/util.js +171 -0
  8. package/packages/BnCascader/BnCascader.vue +543 -0
  9. package/packages/BnCascader/BnCascaderPanel.vue +1331 -0
  10. package/packages/BnCascader/cascaderDisplay.js +102 -0
  11. package/packages/BnCheck/BnCheck.vue +253 -0
  12. package/packages/BnColumnConfig/columnConfigDialog.vue +134 -0
  13. package/packages/BnColumnConfig/component/childrenFormSetting/assocTable.vue +143 -0
  14. package/packages/BnColumnConfig/component/childrenFormSetting/assocTableSearch.vue +314 -0
  15. package/packages/BnColumnConfig/component/childrenFormSetting/index.vue +243 -0
  16. package/packages/BnColumnConfig/component/defaultSet/defaultSet.vue +114 -0
  17. package/packages/BnColumnConfig/component/defaultSet/stringDefault.vue +210 -0
  18. package/packages/BnColumnConfig/component/funcExprDialog/funcExprDialog.vue +126 -0
  19. package/packages/BnColumnConfig/component/packageFilter/index.vue +141 -0
  20. package/packages/BnColumnConfig/component/paraExplainSet/index.vue +156 -0
  21. package/packages/BnColumnConfig/component/setOption/setOption.vue +321 -0
  22. package/packages/BnColumnConfig/component/setRelationOption/ConditionList.vue +277 -0
  23. package/packages/BnColumnConfig/component/setRelationOption/LevelHeader.vue +144 -0
  24. package/packages/BnColumnConfig/component/setRelationOption/setRelationOption.vue +642 -0
  25. package/packages/BnColumnConfig/data.js +129 -0
  26. package/packages/BnColumnConfig/index.scss +23 -0
  27. package/packages/BnColumnConfig/index.vue +309 -0
  28. package/packages/BnCondVal/BnCondVal.vue +112 -0
  29. package/packages/BnCondVal/itemVal/dateRegVal.vue +39 -0
  30. package/packages/BnCondVal/itemVal/dateVal.vue +39 -0
  31. package/packages/BnCondVal/itemVal/numRegVal.vue +67 -0
  32. package/packages/BnCondVal/itemVal/numVal.vue +44 -0
  33. package/packages/BnCondVal/itemVal/relationVal.vue +73 -0
  34. package/packages/BnCondVal/itemVal/selectColumnVal.vue +58 -0
  35. package/packages/BnCondVal/itemVal/selectVal.vue +59 -0
  36. package/packages/BnCondVal/itemVal/stringVal.vue +156 -0
  37. package/packages/BnCondition/index.vue +551 -0
  38. package/packages/BnCondition/util.js +232 -0
  39. package/packages/BnDatePicker/BnDatePicker.vue +194 -0
  40. package/packages/BnDrop/BnDrop.vue +917 -0
  41. package/packages/BnEmptyTip/BnEmptyTip.vue +107 -0
  42. package/packages/BnExportOrder/BnExportOrder.vue +241 -0
  43. package/packages/BnExportOrder/validatorCode.vue +94 -0
  44. package/packages/BnFileView/BnFileView.vue +271 -0
  45. package/packages/BnFileView/FileDetail.vue +125 -0
  46. package/packages/BnFileView/videoPreview.vue +70 -0
  47. package/packages/BnFilterOption/BnFilterOption.vue +160 -0
  48. package/packages/BnFunExpr/BnFunExpr.vue +608 -0
  49. package/packages/BnImportOrder/BnImportOrder.vue +323 -0
  50. package/packages/BnImportTemplate/BnImportTemplate.vue +866 -0
  51. package/packages/BnImportTemplate/assets/merge_tip_img.png +0 -0
  52. package/packages/BnImportTemplate/assets/sheet_tip.png +0 -0
  53. package/packages/BnImportTemplate/assets/xls.png +0 -0
  54. package/packages/BnImportTemplate/components/ImportTemplateTrigger.vue +198 -0
  55. package/packages/BnImportTemplate/components/TemplateEditDialog.vue +340 -0
  56. package/packages/BnImportTemplate/components/TemplateFieldsConfig.vue +401 -0
  57. package/packages/BnImportTemplate/components/TemplateListDialog.vue +297 -0
  58. package/packages/BnInpNum/BnInpNum.vue +165 -0
  59. package/packages/BnMenus/BnMenus.vue +502 -0
  60. package/packages/BnMenus/MenuItem.vue +321 -0
  61. package/packages/BnOrderCard/BnOrderCard.vue +389 -0
  62. package/packages/BnOrderCard/orderRemark.vue +178 -0
  63. package/packages/BnOrderCard/util.js +94 -0
  64. package/packages/BnOrderDetail/BnOrderDetail.vue +338 -0
  65. package/packages/BnOrderDetail/filterLogByUser.vue +108 -0
  66. package/packages/BnOrderDetail/orderLogs.vue +53 -0
  67. package/packages/BnOrderDetail/showSubForm/index.vue +41 -0
  68. package/packages/BnOrderDetail/showSubForm/showChildTable.vue +61 -0
  69. package/packages/BnOrderDetail/showSubForm/showTimeLine.vue +131 -0
  70. package/packages/BnOrderDetail/showSubForm/tableCellCopy.vue +84 -0
  71. package/packages/BnOrderShare/index.vue +378 -0
  72. package/packages/BnOrderShare/shareUrlInp.vue +54 -0
  73. package/packages/BnRadio/BnRadio.vue +181 -0
  74. package/packages/BnRelation/BnRelation.vue +120 -0
  75. package/packages/BnSelect/BnSelect.vue +485 -0
  76. package/packages/BnSmartForm/BnBatchForm.vue +334 -0
  77. package/packages/BnSmartForm/BnBatchFormDialog.vue +423 -0
  78. package/packages/BnSmartForm/BnSmartElf/elfLog/index.vue +57 -0
  79. package/packages/BnSmartForm/BnSmartElf/index.vue +95 -0
  80. package/packages/BnSmartForm/BnSmartFormPsychic.js +629 -0
  81. package/packages/BnSmartForm/BnSmartFormUtil.js +524 -0
  82. package/packages/BnSmartForm/addressForm/index.vue +73 -0
  83. package/packages/BnSmartForm/checkboxForm/index.vue +99 -0
  84. package/packages/BnSmartForm/childrenForm/childFormFile.vue +237 -0
  85. package/packages/BnSmartForm/childrenForm/childrenFormBody.vue +260 -0
  86. package/packages/BnSmartForm/childrenForm/index.vue +110 -0
  87. package/packages/BnSmartForm/childrenForm/searchInventory.vue +115 -0
  88. package/packages/BnSmartForm/chooseAssocTable/chooseAssocTable.vue +451 -0
  89. package/packages/BnSmartForm/chooseAssocTable/chooseChildGood.vue +229 -0
  90. package/packages/BnSmartForm/chooseAssocTable/tableCellCopy.vue +84 -0
  91. package/packages/BnSmartForm/chooseChildOrder/chooseChildOrder.vue +158 -0
  92. package/packages/BnSmartForm/chooseIPaasData/chooseIPaasData.vue +307 -0
  93. package/packages/BnSmartForm/chooseIPaasData/tableCellCopy.vue +84 -0
  94. package/packages/BnSmartForm/choosePackage/choosePackage.vue +361 -0
  95. package/packages/BnSmartForm/dateDualForm/index.vue +37 -0
  96. package/packages/BnSmartForm/dateForm/index.vue +38 -0
  97. package/packages/BnSmartForm/fileForm/fileFormData.js +50 -0
  98. package/packages/BnSmartForm/fileForm/index.vue +240 -0
  99. package/packages/BnSmartForm/formItemFooter/formItemFooter.vue +38 -0
  100. package/packages/BnSmartForm/formItemTop/formItemTop.vue +42 -0
  101. package/packages/BnSmartForm/index.vue +1201 -0
  102. package/packages/BnSmartForm/numberForm/index.vue +63 -0
  103. package/packages/BnSmartForm/radioForm/index.vue +72 -0
  104. package/packages/BnSmartForm/receiveForm/index.vue +112 -0
  105. package/packages/BnSmartForm/relationForm/index.vue +82 -0
  106. package/packages/BnSmartForm/scoreForm/index.vue +39 -0
  107. package/packages/BnSmartForm/selectForm/index.vue +55 -0
  108. package/packages/BnSmartForm/showValForm/index.vue +42 -0
  109. package/packages/BnSmartForm/showValForm/showValFormTable.vue +104 -0
  110. package/packages/BnSmartForm/smartFormsCommon.scss +43 -0
  111. package/packages/BnSmartForm/stringForm/index.vue +170 -0
  112. package/packages/BnVirtPopover/index.vue +319 -0
  113. package/packages/BnWebLog/BnWebLog.vue +140 -0
  114. package/packages/BnWorkSettingDrop/advancedOptions.js +112 -0
  115. package/packages/BnWorkSettingDrop/benBenAIUtil.js +89 -0
  116. package/packages/BnWorkSettingDrop/index.vue +292 -0
  117. package/packages/font/iconfont.css +243 -0
  118. package/packages/font/iconfont.ttf +0 -0
  119. package/packages/font/iconfont.woff +0 -0
  120. package/packages/font/iconfont.woff2 +0 -0
  121. package/utils/addressParse-old.js +645 -0
  122. package/utils/addressParse.js +735 -0
  123. package/utils/config.js +68 -0
  124. package/utils/index.js +1171 -0
  125. package/dist/assocTableSearch-C14i_zJO.js +0 -349
  126. package/dist/assocTableSearch.css +0 -1
  127. package/dist/bn-bus-ui.es.js +0 -65
  128. package/dist/bn-bus-ui.umd.js +0 -49
  129. package/dist/chooseIPaasData-Cl_5qkFA.js +0 -391
  130. package/dist/chooseIPaasData.css +0 -1
  131. package/dist/defaultSet-I4xpf8a4.js +0 -297
  132. package/dist/defaultSet.css +0 -1
  133. package/dist/fileFormData-D_Q1vylE.js +0 -53
  134. package/dist/formItemFooter-CTA7rDtV.js +0 -108
  135. package/dist/formItemFooter.css +0 -1
  136. package/dist/funcExprDialog-Cm5BiRM3.js +0 -139
  137. package/dist/funcExprDialog.css +0 -1
  138. package/dist/index-B6b4uj8v.js +0 -51
  139. package/dist/index-BWdkDTbz.js +0 -109
  140. package/dist/index-BdZ1zOap.js +0 -89
  141. package/dist/index-BdzNjjMC.js +0 -64
  142. package/dist/index-BfpZqab2.js +0 -66
  143. package/dist/index-BmkiB4hr.js +0 -66
  144. package/dist/index-Br1sqCoo.js +0 -58
  145. package/dist/index-C9qrl-yc.js +0 -183
  146. package/dist/index-CXFJXCn5.js +0 -746
  147. package/dist/index-DF114jZq.js +0 -135
  148. package/dist/index-DFPfZ_Il.js +0 -178
  149. package/dist/index-DSEtu7TN.js +0 -44
  150. package/dist/index-Did0UUWV.js +0 -221
  151. package/dist/index-DrPj-tmI.js +0 -45
  152. package/dist/index-DzDf9s2W.js +0 -89
  153. package/dist/index-LnjudNEI.js +0 -118
  154. package/dist/index-ObCfCmDT.js +0 -45
  155. package/dist/index.css +0 -1
  156. package/dist/index2.css +0 -1
  157. package/dist/index3.css +0 -1
  158. package/dist/index4.css +0 -1
  159. package/dist/index5.css +0 -1
  160. package/dist/index6.css +0 -1
  161. package/dist/index7.css +0 -1
  162. package/dist/install-C-scqkds.js +0 -23103
  163. package/dist/install.css +0 -1
  164. package/dist/setOption-CSnWzOny.js +0 -329
  165. package/dist/setOption.css +0 -1
  166. package/dist/setRelationOption-CJcHdfaa.js +0 -5217
  167. package/dist/setRelationOption.css +0 -1
@@ -0,0 +1,642 @@
1
+ <template>
2
+ <el-dialog v-model="show" title="联动组件选项配置" top="5vh"
3
+ :width="dialogWidth" :close-on-click-modal="false" :destroy-on-close="true" :fullscreen="fullscreen"
4
+ append-to-body>
5
+ <!-- 主内容区域 -->
6
+ <div class="setRelationOpt" v-if="moduleDefinition?.header">
7
+ <!-- 空状态提示与批量添加 -->
8
+ <div class="setRelationOpt-header" v-if="!showBatch">
9
+ <el-button type="text" @click="addLevel(0)" v-if="!hasLevels">添加选项</el-button>
10
+ <el-button type="text" @click="showBatch=true">批量添加</el-button>
11
+ </div>
12
+ <div v-else class="w-flex-between">
13
+ <!-- 输入框 -->
14
+ <div style="width: calc(100% - 330px)">
15
+ <el-input type="textarea" :rows="5" resize="none" v-model="batchAddContent"
16
+ placeholder="示例:&#10;质量问题+上衣&#10;服务问题+处理速度&#10;质量问题+上衣+褪色&#10;服务问题+态度+恶劣"/>
17
+ </div>
18
+ <!-- 使用说明 -->
19
+ <div class="setRelationOpt-tip">
20
+ <div class="w-margin-bottom4"><span class="w-font-weight w-font16 w-color-blue">1. </span>每行代表一条选项,每一级通过+分隔
21
+ </div>
22
+ <div class="w-margin-bottom4"><span class="w-font-weight w-font16 w-color-blue">2. </span>选项名称中请不要使用"+
23
+ - , "诸如此类特殊符号
24
+ </div>
25
+ <div class="w-margin-bottom4"><span class="w-font-weight w-font16 w-color-blue">3. </span>对于重复的名字我们将帮您去重合并
26
+ </div>
27
+ <div class="w-margin-bottom4"><span class="w-font-weight w-font16 w-color-blue">4. </span>
28
+ <span class="w-color-orange">请注意</span>,批量操作每次最多添加2000行,超出自动忽略
29
+ </div>
30
+ <div >
31
+ <el-button type="text" @click="showBatch = false">收起</el-button>
32
+ <el-button type="text" :loading="loading" :disabled="loading" @click="handleBatchAdd">确定</el-button>
33
+ </div>
34
+ </div>
35
+
36
+ </div>
37
+ <!-- 联动级别列表 -->
38
+ <div class="setRelationOpt-levels">
39
+ <div v-for="(header, index) in moduleDefinition.header" :key="header.id" class="setRelationOpt-levels-column">
40
+ <!-- 级别头部 -->
41
+ <level-header :title="header.title" :level="header.level" :can-add-next="canAddNextLevel(header)"
42
+ :can-delete="isLastLevel(header)"
43
+ @update:title="header.title = $event" @add-level="addLevel(header.level)"
44
+ @delete-level="deleteLevel(index)"/>
45
+ <!-- 选项列表 -->
46
+ <condition-list
47
+ :options="getOptions(index)"
48
+ :selected-option="selectedConditions[index]"
49
+ :level="index"
50
+ :is-first-level="index === 0"
51
+ :has-parent-selected="index === 0 || !!selectedConditions[index - 1]"
52
+ @update:options="updateOptions(index, $event)"
53
+ @select="item => selectCondition(item, index)"
54
+ @add="insertIndex => addCondition(index, insertIndex)"
55
+ @delete="itemIndex => deleteCondition(index, itemIndex)"
56
+ />
57
+ </div>
58
+ </div>
59
+ <div class="w-empty" v-if="!moduleDefinition.header || moduleDefinition.header.length == 0">还未设置选项</div>
60
+ </div>
61
+ <!-- 底部按钮 -->
62
+ <template #footer>
63
+ <div class="w-flex-right">
64
+ <el-button @click="show = false">取消</el-button>
65
+ <!-- <el-button @click="fullscreen = !fullscreen">全屏</el-button>-->
66
+ <el-button type="primary" @click="handleConfirm">确认</el-button>
67
+ </div>
68
+ </template>
69
+ </el-dialog>
70
+ </template>
71
+
72
+ <script>
73
+ import {cloneDeep} from "lodash";
74
+ import ConditionList from './ConditionList.vue';
75
+ import LevelHeader from './LevelHeader.vue';
76
+
77
+ /**
78
+ * 联动选项配置组件
79
+ * 用于配置多级联动选项(最多5级)
80
+ */
81
+ export default {
82
+ name: "SetRelationOption",
83
+
84
+ components: {
85
+ ConditionList,
86
+ LevelHeader
87
+ },
88
+
89
+ props: {
90
+ // API请求函数
91
+ postFunc: {
92
+ type: Function,
93
+ required: true
94
+ },
95
+
96
+ // 额外的请求参数
97
+ extendPost: {
98
+ type: Object,
99
+ required: true
100
+ }
101
+ },
102
+
103
+ data() {
104
+ return {
105
+ show: false,
106
+ showBatch: false,
107
+ fullscreen: false,
108
+ columnInfo: {},
109
+ maxLevel: 5, // 最多5级联动
110
+ loading: false, // 加载状态
111
+ selectedConditions: [], // 各级选中的条件
112
+ batchAddContent: '', // 批量添加内容
113
+ batchIds: [], // 批量添加的ID列表
114
+ batchIdIndex: 0 // 批量添加ID的索引
115
+ };
116
+ },
117
+
118
+ computed: {
119
+ // 模块定义
120
+ moduleDefinition() {
121
+ return this.columnInfo.moduleDefinition || {};
122
+ },
123
+
124
+ // 是否有级别
125
+ hasLevels() {
126
+ return this.moduleDefinition.header?.length > 0;
127
+ },
128
+
129
+ // 选项列表
130
+ optionList() {
131
+ return this.moduleDefinition.optionList || [];
132
+ },
133
+
134
+ /**
135
+ * 计算对话框宽度
136
+ * 根据级别数量动态调整:基础宽度 + (级别数 × (列宽 + 间距))
137
+ */
138
+ dialogWidth() {
139
+ const levelCount = this.moduleDefinition.header?.length || 0;
140
+
141
+ // 没有级别时使用最小宽度
142
+ if (levelCount <= 3) {
143
+ return '860px';
144
+ }
145
+
146
+ // 每个级别列宽240px + 间距12px = 252px
147
+ // 基础边距左右各20px = 40px
148
+ const baseWidth = 40;
149
+ const columnWidth = 240;
150
+ const gapWidth = 12;
151
+ const perLevelWidth = columnWidth + gapWidth;
152
+
153
+ // 计算总宽度:基础宽度 + (级别数 × 每级宽度) - 最后一个间距
154
+ const calculatedWidth = baseWidth + (levelCount * perLevelWidth) - gapWidth;
155
+
156
+ // 设置最小宽度600px,最大宽度1400px(支持最多5级)
157
+ const minWidth = 600;
158
+ const maxWidth = 1400;
159
+ const finalWidth = Math.min(Math.max(calculatedWidth, minWidth), maxWidth);
160
+
161
+ return `${finalWidth}px`;
162
+ }
163
+ },
164
+
165
+ methods: {
166
+ /**
167
+ * 打开对话框
168
+ */
169
+ open(column) {
170
+ this.columnInfo = cloneDeep(column);
171
+ this.show = true;
172
+ this.fullscreen = false;
173
+ this.selectedConditions = [];
174
+
175
+ // 默认选中第一级的第一个选项
176
+ if (this.optionList.length > 0) {
177
+ this.selectCondition(this.optionList[0], 0);
178
+ }
179
+ },
180
+
181
+ /**
182
+ * 判断是否可以添加下一级
183
+ */
184
+ canAddNextLevel(header) {
185
+ return header.level < this.maxLevel &&
186
+ header.level === this.moduleDefinition.header.length;
187
+ },
188
+
189
+ /**
190
+ * 判断是否为最后一级
191
+ */
192
+ isLastLevel(header) {
193
+ return header.level === this.moduleDefinition.header.length;
194
+ },
195
+
196
+ /**
197
+ * 获取指定级别的选项列表
198
+ */
199
+ getOptions(levelIndex) {
200
+ if (levelIndex === 0) {
201
+ return this.optionList;
202
+ }
203
+ return this.selectedConditions[levelIndex - 1]?.children || [];
204
+ },
205
+
206
+ /**
207
+ * 更新选项列表
208
+ */
209
+ updateOptions(levelIndex, newOptions) {
210
+ if (levelIndex === 0) {
211
+ this.moduleDefinition.optionList = newOptions;
212
+ } else if (this.selectedConditions[levelIndex - 1]) {
213
+ this.selectedConditions[levelIndex - 1].children = newOptions;
214
+ }
215
+ },
216
+
217
+ /**
218
+ * 选中条件
219
+ */
220
+ selectCondition(item, levelIndex) {
221
+ // 设置当前级别的选中项
222
+ this.selectedConditions.splice(levelIndex, this.maxLevel, item);
223
+
224
+ // 自动选中子级的第一个
225
+ this.autoSelectChildren(item, levelIndex);
226
+ },
227
+
228
+ /**
229
+ * 自动选中子级的第一个选项
230
+ */
231
+ autoSelectChildren(item, levelIndex) {
232
+ if (item?.children?.length > 0) {
233
+ this.selectedConditions.splice(levelIndex + 1, 1, item.children[0]);
234
+ this.autoSelectChildren(item.children[0], levelIndex + 1);
235
+ }
236
+ },
237
+
238
+ /**
239
+ * 添加级别
240
+ */
241
+ async addLevel(currentLevel) {
242
+ if (this.loading) return;
243
+
244
+ this.loading = true;
245
+ try {
246
+ const ids = await this.fetchIds(1);
247
+ if (!ids?.length) return;
248
+
249
+ this.moduleDefinition.header.push({
250
+ id: ids[0],
251
+ code: ids[0]+'',
252
+ title: `${currentLevel + 1}级选项`,
253
+ level: currentLevel + 1,
254
+ parentId: -1,
255
+ parentCode: '-1',
256
+ sequence: 0,
257
+ color: "#666666",
258
+ columnStatus: "1"
259
+ });
260
+ } finally {
261
+ this.loading = false;
262
+ }
263
+ },
264
+
265
+ /**
266
+ * 删除级别
267
+ */
268
+ async deleteLevel(levelIndex) {
269
+ const idsToDelete = this.collectLevelIds(levelIndex);
270
+
271
+ // 如果是新组件或没有数据,直接删除
272
+ if (!this.columnInfo.id) {
273
+ this.removeLevelData(levelIndex);
274
+ return;
275
+ }
276
+
277
+ // 检查是否可以删除
278
+ try {
279
+ const canDelete = await this.checkCanDelete(idsToDelete);
280
+ if (canDelete) {
281
+ this.removeLevelData(levelIndex);
282
+ } else {
283
+ this.$message.warning("有选项已关联工单数据,无法删除");
284
+ }
285
+ } catch (error) {
286
+ console.error('删除级别失败:', error);
287
+ }
288
+ },
289
+
290
+ /**
291
+ * 移除级别数据
292
+ */
293
+ removeLevelData(levelIndex) {
294
+ this.moduleDefinition.header.splice(levelIndex, 1);
295
+
296
+ if (levelIndex === 0) {
297
+ this.moduleDefinition.optionList = [];
298
+ } else {
299
+ this.removeChildrenAtLevel(this.optionList, 1, levelIndex);
300
+ }
301
+
302
+ this.selectedConditions = [];
303
+ },
304
+
305
+ /**
306
+ * 收集指定级别的所有选项ID
307
+ */
308
+ collectLevelIds(levelIndex) {
309
+ const ids = [];
310
+
311
+ if (levelIndex === 0) {
312
+ this.optionList.forEach(opt => ids.push(opt.id));
313
+ } else {
314
+ const collect = (options, level) => {
315
+ options.forEach(opt => {
316
+ if (level === levelIndex && opt.children) {
317
+ opt.children.forEach(child => ids.push(child.id));
318
+ } else if (opt.children) {
319
+ collect(opt.children, level + 1);
320
+ }
321
+ });
322
+ };
323
+ collect(this.optionList, 1);
324
+ }
325
+
326
+ return ids;
327
+ },
328
+
329
+ /**
330
+ * 递归移除指定级别的子选项
331
+ */
332
+ removeChildrenAtLevel(options, currentLevel, targetLevel) {
333
+ options.forEach(opt => {
334
+ if (currentLevel === targetLevel) {
335
+ opt.children = [];
336
+ } else if (opt.children) {
337
+ this.removeChildrenAtLevel(opt.children, currentLevel + 1, targetLevel);
338
+ }
339
+ });
340
+ },
341
+
342
+ /**
343
+ * 添加条件
344
+ */
345
+ async addCondition(levelIndex, insertIndex) {
346
+ if (this.loading) return;
347
+
348
+ this.loading = true;
349
+ try {
350
+ const ids = await this.fetchIds(1);
351
+ if (!ids?.length) return;
352
+
353
+ const isFirstLevel = levelIndex === 0;
354
+ const targetArray = isFirstLevel
355
+ ? this.optionList
356
+ : this.selectedConditions[levelIndex - 1]?.children;
357
+
358
+ if (!targetArray) return;
359
+
360
+ const newOption = {
361
+ id: ids[0],
362
+ code: ids[0]+'',
363
+ title: `选项${targetArray.length + 1}`,
364
+ level: levelIndex + 1,
365
+ parentId: isFirstLevel ? 0 : this.selectedConditions[levelIndex - 1].id,
366
+ parentCode: (isFirstLevel ? 0 : this.selectedConditions[levelIndex - 1].id)+'',
367
+ sequence: insertIndex + 1,
368
+ color: "#666666",
369
+ columnStatus: "1",
370
+ children: []
371
+ };
372
+
373
+ targetArray.splice(insertIndex + 1, 0, newOption);
374
+ } finally {
375
+ this.loading = false;
376
+ }
377
+ },
378
+
379
+ /**
380
+ * 删除条件
381
+ */
382
+ async deleteCondition(levelIndex, itemIndex) {
383
+ const targetArray = this.getOptions(levelIndex);
384
+ const option = targetArray[itemIndex];
385
+
386
+ // 如果是新组件,直接删除
387
+ if (!this.columnInfo.id) {
388
+ targetArray.splice(itemIndex, 1);
389
+ return;
390
+ }
391
+ console.log(option)
392
+
393
+ // 检查是否可以删除
394
+ try {
395
+ const canDelete = await this.checkCanDelete([option.id]);
396
+ if (canDelete) {
397
+ targetArray.splice(itemIndex, 1);
398
+ } else {
399
+ this.$message.warning("该选项已关联工单数据,无法删除");
400
+ }
401
+ } catch (error) {
402
+ console.error('删除条件失败:', error);
403
+ }
404
+ },
405
+
406
+ /**
407
+ * 批量添加
408
+ */
409
+ async handleBatchAdd() {
410
+ if (this.loading || !this.batchAddContent) return;
411
+ this.loading = true;
412
+ try {
413
+ // 解析输入内容
414
+ const parsedData = this.parseBatchContent(this.batchAddContent);
415
+ if (!parsedData.conditions.length) {
416
+ this.$message.warning('没有有效的选项数据');
417
+ return;
418
+ }
419
+
420
+ // 获取所需的ID
421
+ const ids = await this.fetchIds(parsedData.totalCount);
422
+ if (!ids) return;
423
+
424
+ this.batchIds = ids;
425
+ this.batchIdIndex = 0;
426
+
427
+ // 添加需要的级别
428
+ this.addLevelsIfNeeded(parsedData.maxLevel);
429
+
430
+ // 插入选项数据
431
+ parsedData.conditions.forEach(conditionArray => {
432
+ this.insertBatchCondition(conditionArray, this.optionList);
433
+ });
434
+
435
+ // this.batchAddContent = '';
436
+ this.$message.success('批量添加成功');
437
+ } finally {
438
+ this.loading = false;
439
+ }
440
+ },
441
+
442
+ /**
443
+ * 解析批量添加的内容
444
+ */
445
+ parseBatchContent(content) {
446
+ const lines = content.split("\n").map(line => line.trim()).filter(line => line).slice(0, 2000);
447
+
448
+ const conditions = [];
449
+ let maxLevel = 0;
450
+ let totalCount = 0;
451
+
452
+ lines.forEach(line => {
453
+ const items = line.split("+")
454
+ .map(item => item.trim())
455
+ .filter(item => item)
456
+ .slice(0, this.maxLevel);
457
+
458
+ if (items.length > 0) {
459
+ conditions.push(items);
460
+ maxLevel = Math.max(maxLevel, items.length);
461
+ totalCount += items.length;
462
+ }
463
+ });
464
+
465
+ // 计算需要添加的级别数
466
+ const currentLevelCount = this.moduleDefinition.header.length;
467
+ const newLevelCount = Math.max(0, maxLevel - currentLevelCount);
468
+
469
+ return {
470
+ conditions,
471
+ maxLevel,
472
+ totalCount: totalCount + newLevelCount
473
+ };
474
+ },
475
+
476
+ /**
477
+ * 添加需要的级别
478
+ */
479
+ addLevelsIfNeeded(targetLevel) {
480
+ const currentLevel = this.moduleDefinition.header.length;
481
+
482
+ for (let i = currentLevel; i < targetLevel; i++) {
483
+ this.moduleDefinition.header.push({
484
+ id: this.batchIds[this.batchIdIndex++],
485
+ title: `选项${i + 1}级标题`,
486
+ level: i + 1,
487
+ parentId: -1,
488
+ sequence: 0,
489
+ color: "#666666",
490
+ columnStatus: "1"
491
+ });
492
+ }
493
+ },
494
+
495
+ /**
496
+ * 递归插入批量条件
497
+ */
498
+ insertBatchCondition(titles, optionList, level = 0, parentId = 0) {
499
+ if (titles.length === 0) return optionList;
500
+
501
+ const title = titles[0];
502
+ const existingIndex = optionList.findIndex(opt => opt.title === title);
503
+
504
+ if (existingIndex > -1) {
505
+ // 已存在,继续处理子级
506
+ this.insertBatchCondition(
507
+ titles.slice(1),
508
+ optionList[existingIndex].children,
509
+ level + 1,
510
+ optionList[existingIndex].id
511
+ );
512
+ } else {
513
+ // 不存在,创建新选项
514
+ const newOption = this.createBatchOption(titles, level, parentId, optionList.length);
515
+ if (newOption) {
516
+ optionList.push(newOption);
517
+ }
518
+ }
519
+
520
+ return optionList;
521
+ },
522
+
523
+ /**
524
+ * 创建批量选项(含子级)
525
+ */
526
+ createBatchOption(titles, level, parentId, sequence) {
527
+ if (titles.length === 0 || this.batchIdIndex >= this.batchIds.length) {
528
+ return null;
529
+ }
530
+
531
+ const id = this.batchIds[this.batchIdIndex++];
532
+ const option = {
533
+ id,
534
+ code: id + '',
535
+ parentId,
536
+ parentCode:parentId+'',
537
+ title: titles[0],
538
+ level: level + 1,
539
+ color: "#666666",
540
+ columnStatus: "1",
541
+ sequence,
542
+ children: []
543
+ };
544
+
545
+ // 递归创建子级
546
+ if (titles.length > 1) {
547
+ const child = this.createBatchOption(titles.slice(1), level + 1, option.id, 0);
548
+ if (child) {
549
+ option.children.push(child);
550
+ }
551
+ }
552
+
553
+ return option;
554
+ },
555
+
556
+ /**
557
+ * 获取新ID
558
+ */
559
+ async fetchIds(count) {
560
+ try {
561
+ const res = await this.postFunc(
562
+ `/v2/projects/customId/${count}/${this.extendPost.appId}`,
563
+ null,
564
+ 'get'
565
+ );
566
+
567
+ if (res.code === 0 && res.data) {
568
+ return res.data;
569
+ }
570
+
571
+ this.$message.error('获取ID失败');
572
+ return null;
573
+ } catch (error) {
574
+ console.error('获取ID失败:', error);
575
+ this.$message.error('获取ID失败');
576
+ return null;
577
+ }
578
+ },
579
+
580
+ /**
581
+ * 检查是否可以删除
582
+ */
583
+ async checkCanDelete(optionIds) {
584
+ try {
585
+ const res = await this.postFunc('/v2/project/column/canDelRelationOption', {
586
+ projectId: this.extendPost.tableId,
587
+ columnId: this.columnInfo.id,
588
+ optionId: optionIds.join(','),
589
+ });
590
+ return res.code === 0 && res.data;
591
+ } catch (error) {
592
+ console.error('检查删除权限失败:', error);
593
+ return false;
594
+ }
595
+ },
596
+ /**
597
+ * 确认保存
598
+ */
599
+ handleConfirm() {
600
+ this.$emit('confirm', this.columnInfo);
601
+ this.show = false;
602
+ }
603
+ }
604
+ };
605
+ </script>
606
+
607
+ <style scoped lang="scss">
608
+ .setRelationOpt {
609
+ min-height: 280px;
610
+ // 头部区域
611
+ &-header {
612
+ display: flex;
613
+ align-items: center;
614
+ }
615
+
616
+ &-tip {
617
+ width: 330px;
618
+ color: #888;
619
+ font-size: 12px;
620
+ padding-left: 8px;
621
+ }
622
+
623
+ // 级别列表容器
624
+ &-levels {
625
+ display: flex;
626
+ gap: 12px;
627
+ padding-bottom: 10px;
628
+
629
+ // 级别列
630
+ &-column {
631
+ flex-shrink: 0;
632
+ width: 240px;
633
+ height: 360px;
634
+ border: 1px solid #ddd;
635
+ border-radius: 4px;
636
+ overflow: hidden;
637
+ display: flex;
638
+ flex-direction: column;
639
+ }
640
+ }
641
+ }
642
+ </style>