imeik-bizui 2.2.0 → 2.2.1

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.
@@ -238,3 +238,20 @@ export function getExpertsPageQuery(data) {
238
238
  data
239
239
  })
240
240
  }
241
+
242
+ /**
243
+ * 获取费用承担部门
244
+ * @param {*} data
245
+ * @returns
246
+ */
247
+ export function queryBudgetDepartManage(data) {
248
+ return request({
249
+ url: '/application-center-admin/data/exchange/queryBudgetDepartManage',
250
+ method: 'post',
251
+ params: {
252
+ tagModel: 'APPLY',
253
+ tagCode: 'al-fxssqxmbh'
254
+ },
255
+ data
256
+ })
257
+ }
@@ -0,0 +1,373 @@
1
+ <template>
2
+ <div :class="isView ? 'inline' : 'w-full'">
3
+ <div v-if="isView">
4
+ <ImDiffText v-if="attrs.showDiff" :show-diff="attrs.showDiff" :old-value="myValueName" :no-absolute="true" :new-value="newMyValueName" />
5
+ <span v-else :title="myValueName">{{ myValueName || '-' }}</span>
6
+ </div>
7
+ <el-cascader
8
+ v-else
9
+ :key="keyValue"
10
+ v-model="myValue"
11
+ class="department-cascader"
12
+ v-bind="$attrs"
13
+ :collapse-tags="!attrs.showAllTag"
14
+ :props="cascaderProps"
15
+ :options="options"
16
+ :show-all-levels="!!attrs.showAllLevels"
17
+ :disabled="!!attrs.disabled"
18
+ :size="attrs.size || ''"
19
+ clearable
20
+ filterable
21
+ @change="onChange"
22
+ v-on="listeners"
23
+ />
24
+ </div>
25
+ </template>
26
+
27
+ <script>
28
+ // 引入获取部门数据的接口
29
+ import { queryBudgetDepartManage } from '../../api/applycenter.js'
30
+ export default {
31
+ name: 'FieldCostBearDepartmentSelect',
32
+ props: {
33
+ value: {
34
+ type: String,
35
+ default: ''
36
+ },
37
+ // 用于接收外部传递扩展配置,如显示方式、默认值、选择器特性
38
+ attrs: {
39
+ type: Object,
40
+ default() {
41
+ return {}
42
+ }
43
+ },
44
+ // 代理事件监听,如input、change等
45
+ listeners: {
46
+ type: Object,
47
+ default() {
48
+ return {}
49
+ }
50
+ }
51
+ },
52
+ data() {
53
+ return {
54
+ keyValue: 0,
55
+ myValue: undefined,
56
+ options: [],
57
+ defaultDepartment: undefined
58
+ }
59
+ },
60
+ computed: {
61
+ /**
62
+ * 是否多选
63
+ */
64
+ isMultiple() {
65
+ return !!this.attrs.multiple
66
+ },
67
+
68
+ /**
69
+ * 级联选择器props
70
+ */
71
+ cascaderProps() {
72
+ return {
73
+ label: 'dicName',
74
+ value: 'dicValue',
75
+ children: 'subRegin',
76
+ expandTrigger: 'click',
77
+ checkStrictly: !!this.attrs.checkStrictly,
78
+ emitPath: false,
79
+ multiple: this.isMultiple
80
+ }
81
+ },
82
+
83
+ /**
84
+ * 是否只展示文字
85
+ */
86
+ isView() {
87
+ return this.attrs.isView
88
+ },
89
+
90
+ /**
91
+ * 差异值
92
+ */
93
+ diffValue() {
94
+ return this.attrs.diffValue
95
+ },
96
+
97
+ /**
98
+ * 显示值
99
+ */
100
+ myValueName() {
101
+ return this.getDisplayValue(this.myValue, 'dicName')
102
+ },
103
+
104
+ /**
105
+ * 差异值显示值
106
+ */
107
+ newMyValueName() {
108
+ return this.getDisplayValue(this.diffValue, 'dicName')
109
+ },
110
+
111
+ /**
112
+ * 显示值orgCode
113
+ */
114
+ myValueOrgCode() {
115
+ return this.getDisplayValue(this.myValue, 'orgCode')
116
+ }
117
+ },
118
+ watch: {
119
+ // 监听options变化,刷新组件(保持选项和渲染同步)
120
+ options: {
121
+ handler() {
122
+ this.keyValue++
123
+ }
124
+ },
125
+ // 监听value(外部v-model变化),同步myValue
126
+ value: {
127
+ immediate: true,
128
+ handler() {
129
+ this.setMyValue()
130
+ }
131
+ },
132
+ 'attrs.branchJson': {
133
+ handler(newVal, oldVal) {
134
+ if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
135
+ this.getOptions()
136
+ }
137
+ }
138
+ },
139
+ 'attrs.values': {
140
+ handler(newVal, oldVal) {
141
+ if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
142
+ this.getOptions()
143
+ }
144
+ }
145
+ },
146
+ 'attrs.dataRangeType': {
147
+ handler() {
148
+ this.getOptions()
149
+ }
150
+ },
151
+ // 监听默认选中模式
152
+ 'attrs.default': {
153
+ immediate: true,
154
+ handler(newVal, oldVal) {
155
+ // 如果默认选中“我的部门”,且无初始值,则设为默认部门
156
+ if (newVal) {
157
+ if (newVal !== oldVal && newVal === '2' && !this.value) {
158
+ this.myValue = this.defaultDepartment
159
+ } else {
160
+ !this.isView && (this.myValue = undefined)
161
+ }
162
+ this.getOptions(() => {
163
+ this.onChange()
164
+ })
165
+ }
166
+ }
167
+ },
168
+ // 监听特定默认值触发
169
+ 'attrs.defaultValue': {
170
+ immediate: true,
171
+ handler(newVal, oldVal) {
172
+ // 若启用“指定部门”并且当前没值,则设为该默认
173
+ if (newVal && newVal !== oldVal && this.attrs.default === '3' && !this.value) {
174
+ this.myValue = newVal
175
+ this.getOptions(() => {
176
+ this.onChange()
177
+ })
178
+ }
179
+ }
180
+ }
181
+ },
182
+ created() {
183
+ if (!this.options?.length) {
184
+ this.getOptions()
185
+ }
186
+ },
187
+ methods: {
188
+ /**
189
+ * 查找目标value在树节点中的完整路径name
190
+ */
191
+ findParent(data, target, result) {
192
+ for (const item of data) {
193
+ if (item.dicValue === target) {
194
+ result.unshift(item.dicName)
195
+ return true
196
+ }
197
+ if (item.subRegin?.length) {
198
+ const isFind = this.findParent(item.subRegin, target, result)
199
+ if (isFind) {
200
+ result.unshift(item.dicName)
201
+ return true
202
+ }
203
+ }
204
+ }
205
+ return false
206
+ },
207
+
208
+ /**
209
+ * 获取单选时的完整部门路径
210
+ */
211
+ getAllLabel(value) {
212
+ const result = []
213
+ this.findParent(this.options, value, result)
214
+ result.shift() // 移除第一个根节点
215
+ return result[result.length - 1] || ''
216
+ },
217
+
218
+ /**
219
+ * 递归查找树节点中某个value对应的属性值
220
+ * @param arr 树形数组
221
+ * @param val 查找的dicValue
222
+ * @param field 要获取的属性名 ('dicName' 或 'orgCode')
223
+ */
224
+ findNodeValue(arr, val, field) {
225
+ for (const item of arr) {
226
+ if (item.dicValue === val) {
227
+ return item[field]
228
+ }
229
+ if (item.subRegin?.length) {
230
+ const result = this.findNodeValue(item.subRegin, val, field)
231
+ if (result !== undefined) {
232
+ return result
233
+ }
234
+ }
235
+ }
236
+ },
237
+
238
+ /**
239
+ * 获取显示值(支持多选/单选,支持不同字段)
240
+ */
241
+ getDisplayValue(value, field) {
242
+ if (!value) return ''
243
+
244
+ if (this.isMultiple) {
245
+ if (!Array.isArray(value) || !value.length) return ''
246
+ return value
247
+ .map((item) => {
248
+ if (field === 'dicName') {
249
+ return this.findNodeValue(this.options, item, 'dicName') || ''
250
+ }
251
+ return this.findNodeValue(this.options, item, 'dicValue') || ''
252
+ })
253
+ .filter(Boolean)
254
+ .join(',')
255
+ } else {
256
+ if (field === 'dicName') {
257
+ return this.getAllLabel(value)
258
+ }
259
+ return this.findNodeValue(this.options, value, 'dicValue') || ''
260
+ }
261
+ },
262
+
263
+ setMyValue() {
264
+ if (!this.value) {
265
+ this.myValue = undefined
266
+ return
267
+ }
268
+ try {
269
+ // 如果是字符串且包含逗号,转换为数组
270
+ if (typeof this.value === 'string' && this.isMultiple) {
271
+ this.myValue = this.value.split(',').filter(Boolean)
272
+ } else {
273
+ this.myValue = this.isMultiple ? (Array.isArray(this.value) ? [...this.value] : [this.value]) : this.value
274
+ }
275
+ } catch (error) {
276
+ this.myValue = undefined
277
+ }
278
+ },
279
+
280
+ getOptions(callback) {
281
+ queryBudgetDepartManage({})
282
+ .then((res) => {
283
+ if (res.code === 200) {
284
+ const resData = res.data || {}
285
+ console.log('resData', resData)
286
+ this.options = this.formatData(resData.tagBudgetDeptLists) || []
287
+ this.defaultDepartment = resData.userBudgetDepartment || undefined
288
+ callback && callback()
289
+ } else {
290
+ this.$message.error(res.message)
291
+ }
292
+ })
293
+ .catch((error) => {
294
+ this.$message.error(error.message || '获取部门数据失败')
295
+ })
296
+ },
297
+
298
+ formatData(data) {
299
+ for (let i = 0; i < data.length; i++) {
300
+ const item = data[i]
301
+ if (item.subRegin && item.subRegin.length === 0) {
302
+ delete item.subRegin
303
+ }
304
+ if (item.subRegin && item.subRegin.length > 0) {
305
+ item.subRegin = this.formatData(item.subRegin)
306
+ }
307
+ }
308
+ return data
309
+ },
310
+
311
+ /**
312
+ * 派发事件
313
+ */
314
+ emitEvents(value) {
315
+ const eventData = {
316
+ detailName: this.myValueName,
317
+ detailOrgCode: this.myValueOrgCode
318
+ }
319
+ console.log('emitEvents', value, eventData)
320
+ this.$emit('input', value, eventData)
321
+ this.$emit('change', value, eventData)
322
+ },
323
+
324
+ /**
325
+ * 部门选择发生变化后调用
326
+ */
327
+ onChange() {
328
+ // 清空筛选输入
329
+ if (this.$refs.select) {
330
+ this.$refs.select.inputValue = ''
331
+ if (this.isMultiple && !this.myValue?.length) {
332
+ this.$refs.select.selectedLabel = ''
333
+ }
334
+ }
335
+
336
+ // 没有部门名时,重置v-model
337
+ if (!this.myValueName) {
338
+ this.myValue = undefined
339
+ }
340
+
341
+ // 处理输出值
342
+ const outputValue = this.myValue ? (this.isMultiple ? this.myValue.join(',') : this.myValue) : ''
343
+
344
+ // 如果数据还没加载,异步加载后再派发事件
345
+ if (!this.options?.length) {
346
+ this.getOptions(() => {
347
+ this.emitEvents(outputValue)
348
+ })
349
+ } else {
350
+ this.emitEvents(outputValue)
351
+ }
352
+ }
353
+ }
354
+ }
355
+ </script>
356
+ <style lang="scss" scoped>
357
+ .department-cascader {
358
+ width: 100%;
359
+
360
+ ::v-deep {
361
+ .el-cascader__tags {
362
+ align-items: center;
363
+ }
364
+ .el-cascader__search-input {
365
+ display: inline-block;
366
+ width: 10px;
367
+ flex: unset;
368
+ min-width: 10px;
369
+ margin-left: 15px;
370
+ }
371
+ }
372
+ }
373
+ </style>