wui-components-v2 1.1.69 → 1.1.70

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 (45) hide show
  1. package/api/core/index.ts +74 -74
  2. package/api/menu.ts +45 -45
  3. package/api/page.ts +114 -114
  4. package/api/sys.ts +12 -12
  5. package/components/add-address-page/add-address-page.vue +77 -77
  6. package/components/custom-date-picker/custom-date-picker.vue +106 -106
  7. package/components/custom-select-picker/custom-select-picker.vue +95 -95
  8. package/components/demo-block/demo-block.vue +63 -63
  9. package/components/detail-popup/detail-popup.vue +99 -99
  10. package/components/evaluation-page/evaluation-page.vue +196 -196
  11. package/components/fold-card/fold-card.vue +171 -171
  12. package/components/form-control/form-control.vue +661 -661
  13. package/components/global-message/global-message.vue +68 -68
  14. package/components/label-value/label-value.vue +144 -144
  15. package/components/list-top-buttons/list-top-buttons.vue +19 -19
  16. package/components/login-form/login-form.vue +126 -126
  17. package/components/mulselect-picker/mulselect-picker.vue +86 -86
  18. package/components/product-card/product-card.vue +201 -201
  19. package/components/search/search.vue +128 -128
  20. package/components/user-choose/user-choose.vue +1 -1
  21. package/components/wui-enume-select-control/wui-enume-select-control.vue +92 -92
  22. package/components/wui-list/wui-list.vue +235 -235
  23. package/components/wui-menus/wui-menus.vue +247 -247
  24. package/components/wui-menus1/components/navbar.vue +43 -43
  25. package/components/wui-menus1/wui-menus.vue +564 -564
  26. package/components/wui-notify-info/wui-notify-info.vue +280 -280
  27. package/components/wui-search-history-babbar/wui-search-history-babbar.vue +204 -204
  28. package/components/wui-select-list/wui-select-list.vue +310 -310
  29. package/components/wui-select-popup/wui-select-popup.vue +612 -612
  30. package/components/wui-system-settings/wui-system-settings.vue +144 -144
  31. package/components/wui-tabbar/wui-tabbar.vue +106 -106
  32. package/components/wui-tree-page/components/tree-item.vue +238 -238
  33. package/components/wui-user/wui-user.vue +202 -202
  34. package/composables/useCompanyFieldFilter.ts +91 -91
  35. package/composables/useEnumes.ts +2 -2
  36. package/composables/useMenus.ts +193 -193
  37. package/index.ts +83 -83
  38. package/package.json +1 -1
  39. package/static/iconfont/iconfont.css +63 -63
  40. package/store/language.ts +151 -151
  41. package/styles/dark-mode.css +523 -523
  42. package/styles/dark-mode.min.css +1 -1
  43. package/type.ts +2 -2
  44. package/utils/control-tree.ts +2 -2
  45. package/utils/control-type-supportor.ts +148 -148
@@ -1,661 +1,661 @@
1
- <script lang="ts" setup>
2
- import { computed, onBeforeMount, ref, toRaw, watch } from 'vue'
3
- import type { FormSchema, FormSchemaIssue } from '@wot-ui/ui/components/wd-form/types'
4
- import dayjs from 'dayjs/esm/index'
5
- import type { Enums, Fields, Groups } from '../../type'
6
- import WuiSelectPopup from '../wui-select-popup/wui-select-popup.vue'
7
- import ControlTypeSupportor from '../../utils/control-type-supportor'
8
- import { useCompanyFieldFilter } from '../../composables/useCompanyFieldFilter'
9
- import customSelectPicker from '../custom-select-picker/custom-select-picker.vue'
10
- import CustomDatePicker from '../custom-date-picker/custom-date-picker.vue'
11
- import addAddressPage from '../add-address-page/add-address-page.vue'
12
- import userChoose from '../user-choose/user-choose.vue'
13
- import { generateHighResolutionID } from '../../utils/index'
14
- import scanInput from '../scan-input/scan-input.vue'
15
- // import { enums } from '../../api/page'
16
- defineOptions({
17
- name: 'FormControl',
18
- })
19
- const props = defineProps<{
20
- fieldGroup?: Groups
21
- entity?: { [key: string]: string }
22
- enumColumn?: Enums
23
- companyFilter?: boolean
24
- companyFieldSourceId?: string
25
- smartPaste?: boolean
26
- }>()
27
- const fileTypes = [
28
- {
29
- label: '照片',
30
- value: 'image',
31
- },
32
- {
33
- label: '视频',
34
- value: 'video',
35
- },
36
- // {
37
- // label: '文件',
38
- // value: 'file',
39
- // },
40
- ]
41
- const fileType = ref<any>('image')
42
- const action = ref<string>('')
43
- const hydrocarbonProgramToken = ref<string>('')
44
- const token = ref<string>('')
45
- const form = ref<any>(null)
46
- const model = ref<any>({})
47
- const addEvent = generateHighResolutionID() // 全局事件名称
48
- const { filteredFields: fields } = useCompanyFieldFilter(
49
- () => props.fieldGroup,
50
- model,
51
- props.companyFilter, // 是否自适应显示快递公司填充框
52
- props.companyFieldSourceId // 快递公司对应字段
53
- )
54
- const giveDefaultValue = (value: any) => {
55
- const { extInfo = {} } = uni.getStorageSync('userInfo') || {}
56
- const rawDefaultValue = extInfo.fieldMap || {}
57
- const defaultValue: Record<string, any> = {}
58
- for (const key in rawDefaultValue) {
59
- if (Object.prototype.hasOwnProperty.call(rawDefaultValue, key)) {
60
- const val = rawDefaultValue[key]
61
- defaultValue[key] = typeof val === 'string' && val.includes('@R@') ? val.split('@R@')[0] : val
62
- }
63
- }
64
- return defaultValue[value] || {}
65
- }
66
- giveDefaultValue({})
67
- // 初始化表单数据
68
- function initFormData() {
69
- const models: { [key: string]: any } = {}
70
- props.fieldGroup?.fields.forEach((item: Fields) => {
71
- // 树、多选
72
- if (
73
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'tree-entity-select' ||
74
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'multiselect'
75
- ) {
76
- return (models[item.sourceId] =
77
- (props.entity && props.entity[item.sourceId]?.split(',')) || item.transDefaultValue || [])
78
- }
79
-
80
- if (ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselect') {
81
- return (models[item.sourceId] =
82
- (props.entity && props.entity[item.sourceId]?.split('@,@')) ||
83
- (item.transDefaultValue && item.transDefaultValue?.split('@,@')) ||
84
- [])
85
- }
86
-
87
- // 文件
88
- if (
89
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'file' ||
90
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relfile'
91
- ) {
92
- if (props.entity && typeof props.entity[item.sourceId] === 'object') {
93
- return (models[item.sourceId] = [props.entity[item.sourceId]])
94
- }
95
- return (models[item.sourceId] =
96
- (props.entity &&
97
- props.entity[item.sourceId] && [
98
- {
99
- disabled: JSON.parse(props.entity[item.sourceId]).valid,
100
- url: `${action.value}/v3/files${JSON.parse(props.entity[item.sourceId])?.base.path}?@token=${token.value}&@programToken=${hydrocarbonProgramToken.value}`,
101
- name: `${JSON.parse(props.entity[item.sourceId])?.base.fileName}`,
102
- response: JSON.stringify({
103
- fileKey: `$blob:${JSON.parse(props.entity[item.sourceId])?.base.bytesInfoVO.code}`,
104
- }),
105
- },
106
- ]) ||
107
- item.transDefaultValue ||
108
- [])
109
- }
110
-
111
- // 时间
112
- if (
113
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'datetime' ||
114
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'date'
115
- ) {
116
- return (models[item.sourceId] =
117
- (props.entity && dayjs(props.entity[item.sourceId]).valueOf()) ||
118
- (item.transDefaultValue && dayjs(item.transDefaultValue).valueOf()) ||
119
- null)
120
- }
121
-
122
- // 评分
123
- if (ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'progress') {
124
- const val = props.entity?.[item.sourceId]
125
- return (models[item.sourceId] = val !== undefined && val !== null && val !== '' ? Number(val) : 0)
126
- }
127
-
128
- return (models[item.sourceId] = (props.entity && props.entity[item.sourceId]) || item.transDefaultValue || '')
129
- })
130
-
131
- // 遍历 models,处理 $$user. 前缀
132
- const processedModels: Record<string, any> = {}
133
- for (const key in models) {
134
- if (Object.prototype.hasOwnProperty.call(models, key)) {
135
- const val = models[key]
136
- if (typeof val === 'string' && val.includes('$$user.')) {
137
- processedModels[key] = giveDefaultValue(val.split('$$user.')[1])
138
- } else {
139
- processedModels[key] = val
140
- }
141
- }
142
- }
143
-
144
- model.value = {
145
- ...processedModels,
146
- }
147
- }
148
-
149
- //-s
150
- const shouldMonitor = computed(() => {
151
- const newList = fields.value
152
- .filter((item: any) => item.relValueField || item.relValueField3)
153
- .map((innerItem: any) => ({
154
- id: innerItem.sourceId,
155
- title: innerItem.title,
156
- relValueField: innerItem.relValueField.id,
157
- relValueField3: innerItem.relValueField3.id,
158
- }))
159
- console.log('shouldMonitor:', newList)
160
- return newList
161
- })
162
- //-e
163
-
164
- // 存储变化后的数据,{ [fieldKey]: newValue, ... }
165
- const changedData = ref<Record<string, any>>({})
166
- const initialModel = ref<Record<string, any>>({})
167
-
168
- // 监听 shouldMonitor 中 relValueField / relValueField3 对应的 model 字段
169
- watch(
170
- () => {
171
- const snapshot: Record<string, any> = {}
172
- shouldMonitor.value?.forEach((item: any) => {
173
- if (item.relValueField) snapshot.relValueField = model.value[item.relValueField]
174
- if (item.relValueField3) snapshot.relValueField3 = model.value[item.relValueField3]
175
- })
176
- return snapshot
177
- },
178
- newVal => {
179
- // 只存储与初始值不同的字段(表单变化的值)
180
- const changed: Record<string, any> = {}
181
- shouldMonitor.value?.forEach((item: any) => {
182
- if (item.relValueField && newVal.relValueField !== initialModel.value[item.relValueField]) {
183
- changed.relValueField = newVal.relValueField
184
- }
185
- if (item.relValueField3 && newVal.relValueField3 !== initialModel.value[item.relValueField3]) {
186
- changed.relValueField3 = newVal.relValueField3
187
- }
188
- })
189
- changedData.value = changed
190
-
191
- // 当所有被监听的字段都有值时,存入缓存供 select-list 页面读取
192
- const values = Object.values(newVal)
193
- const allExist = values.length > 0 && values.every(v => v !== null && v !== undefined && v !== '')
194
- if (allExist) {
195
- uni.setStorageSync('paramsData', {
196
- changedData: changedData.value,
197
- rawData: shouldMonitor.value,
198
- })
199
- console.log('changedData:', changedData.value)
200
- }
201
- }
202
- )
203
-
204
- onBeforeMount(() => {
205
- action.value = uni.getStorageSync('BASE_URL')
206
- hydrocarbonProgramToken.value = uni.getStorageSync('HYDROCARBON_PROGRAM_TOKEN')
207
- token.value = uni.getStorageSync('TOKEN')
208
- initFormData()
209
- initialModel.value = JSON.parse(JSON.stringify(model.value))
210
- })
211
- function formatSelectColumns(columns: any) {
212
- return columns.map((item: any) => {
213
- return {
214
- ...item,
215
- label: item.title,
216
- }
217
- })
218
- }
219
-
220
- const schema = computed((): FormSchema => {
221
- return {
222
- validate(_model: Record<string, any>): FormSchemaIssue[] {
223
- const issues: FormSchemaIssue[] = []
224
- props.fieldGroup?.fields.forEach((item: Fields) => {
225
- if (item.required) {
226
- const value = _model[item.sourceId]
227
- if (Array.isArray(value) && value.length < 1) {
228
- issues.push({ path: [item.sourceId], message: `请填写${item.title}` })
229
- } else if (!value) {
230
- issues.push({ path: [item.sourceId], message: `请填写${item.title}` })
231
- }
232
- }
233
- })
234
- return issues
235
- },
236
- isRequired(path: string) {
237
- return props.fieldGroup?.fields.some(f => f.sourceId === path && f.required) ?? false
238
- },
239
- }
240
- })
241
-
242
- // 监听文件上传成功
243
- function handleFileChange(e: any, item: Fields) {
244
- model.value[item.sourceId] = e.fileList
245
- }
246
-
247
- function submit() {
248
- return new Promise((resolve, reject) => {
249
- form.value
250
- .validate()
251
- .then(({ valid }: any) => {
252
- if (valid) {
253
- const data: { [key: string]: any } = {}
254
- for (const key in model.value) {
255
- if (Object.prototype.hasOwnProperty.call(model.value, key)) {
256
- fields.value?.forEach((item: Fields) => {
257
- if (item.sourceId === key) {
258
- if (ControlTypeSupportor.getControlType(item) === 'file') {
259
- data[key] = toRaw(model.value[key][0])
260
- } else if (
261
- ControlTypeSupportor.getControlType(item) === 'relselect' ||
262
- ControlTypeSupportor.getControlType(item) === 'tree-entity-select'
263
- ) {
264
- if (Array.isArray(model.value[key])) {
265
- data[key] = model.value[key].join('@,@')
266
- } else {
267
- data[key] = model.value[key]
268
- }
269
- } else {
270
- data[key] = model.value[key]
271
- }
272
- }
273
- })
274
- }
275
- }
276
- resolve(data)
277
- } else {
278
- reject(valid)
279
- }
280
- })
281
- .catch((error: any) => {
282
- console.log(error, 'error')
283
- reject(error)
284
- })
285
- })
286
- }
287
-
288
- // 暴露方法/变量给父组件
289
- defineExpose({
290
- submit,
291
- })
292
- </script>
293
-
294
- <template>
295
- <view>
296
- <wd-form ref="form" :model="model" :schema="schema" error-type="toast" :label-width="120" class="custom-from-style">
297
- <addAddressPage v-if="props?.smartPaste" v-model="model" :group="props.fieldGroup" />
298
- <view v-for="item in fields" :key="item.sourceId">
299
- <view v-show="!item.title?.includes('y') && !item.hidden">
300
- <wd-form-item
301
- v-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'text'"
302
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
303
- :prop="item.sourceId"
304
- :title="item.title"
305
- >
306
- <wd-input
307
- v-model="model[item.sourceId]"
308
- :readonly="item.disabled || item.rowEditType === 'readonly'"
309
- :clearable="!item.disabled"
310
- :placeholder="`请输入${item.title}`"
311
- :class="{ 'disabled-input': item.disabled || item.rowEditType === 'readonly' }"
312
- />
313
- </wd-form-item>
314
- <wd-form-item
315
- v-else-if="
316
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'decimal'
317
- "
318
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
319
- :prop="item.sourceId"
320
- :title="item.title"
321
- >
322
- <wd-input
323
- v-model="model[item.sourceId]"
324
- type="number"
325
- :readonly="item.disabled || item.rowEditType === 'readonly'"
326
- :clearable="!item.disabled"
327
- :placeholder="`请输入${item.title}`"
328
- />
329
- </wd-form-item>
330
- <wd-form-item
331
- v-else-if="
332
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'password'
333
- "
334
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
335
- :prop="item.sourceId"
336
- :title="item.title"
337
- >
338
- <wd-input
339
- v-model="model[item.sourceId]"
340
- show-password
341
- :readonly="item.disabled || item.rowEditType === 'readonly'"
342
- :clearable="!item.disabled"
343
- :placeholder="`请输入${item.title}`"
344
- />
345
- </wd-form-item>
346
- <wd-form-item
347
- v-else-if="
348
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'textarea'
349
- "
350
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
351
- :prop="item.sourceId"
352
- :title="item.title"
353
- >
354
- <wd-textarea
355
- v-model="model[item.sourceId]"
356
- :readonly="item.disabled || item.rowEditType === 'readonly'"
357
- :clearable="!item.disabled"
358
- :placeholder="`请输入${item.title}`"
359
- auto-height
360
- />
361
- </wd-form-item>
362
- <wd-form-item
363
- v-else-if="
364
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'select'
365
- "
366
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
367
- :prop="item.sourceId"
368
- :title="item.title"
369
- :style="{ display: item.title?.includes('y') ? 'none' : null }"
370
- >
371
- <customSelectPicker
372
- v-model="model[item.sourceId]"
373
- :placeholder="`请选择${item.title}`"
374
- :columns="enumColumn && formatSelectColumns(enumColumn[item.mstrucId])"
375
- type="radio"
376
- />
377
- </wd-form-item>
378
- <wd-form-item
379
- v-else-if="
380
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
381
- 'relselect-extdis'
382
- "
383
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
384
- :prop="item.sourceId"
385
- :title="item.title"
386
- :style="{ display: item.title?.includes('y') ? 'none' : null }"
387
- >
388
- <userChoose
389
- v-model="model[item.sourceId]"
390
- :placeholder="`请选择${item.title}`"
391
- :source-id="item.sourceId"
392
- :title="item.title"
393
- :add-event="addEvent"
394
- :ext-control-type="item.extControlType"
395
- />
396
- </wd-form-item>
397
- <wd-form-item
398
- v-else-if="
399
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'multiselect'
400
- "
401
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
402
- :prop="item.sourceId"
403
- :title="item.title"
404
- >
405
- <customSelectPicker
406
- v-model="model[item.sourceId]"
407
- :placeholder="`请选择${item.title}`"
408
- :columns="enumColumn && formatSelectColumns(enumColumn[item.mstrucId])"
409
- type="checkbox"
410
- />
411
- </wd-form-item>
412
- <wd-form-item
413
- v-else-if="
414
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'date'
415
- "
416
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
417
- :prop="item.sourceId"
418
- :title="item.title"
419
- >
420
- <customDatePicker
421
- v-model="model[item.sourceId]"
422
- type="date"
423
- :clearable="!item.disabled"
424
- :placeholder="`请选择${item.title}`"
425
- />
426
- </wd-form-item>
427
- <wd-form-item
428
- v-else-if="
429
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'datetime'
430
- "
431
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
432
- :prop="item.sourceId"
433
- :title="item.title"
434
- >
435
- <customDatePicker
436
- v-model="model[item.sourceId]"
437
- type="datetime"
438
- :clearable="!item.disabled"
439
- :placeholder="`请选择${item.title}`"
440
- />
441
- </wd-form-item>
442
- <wd-form-item
443
- v-else-if="
444
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'time'
445
- "
446
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
447
- :prop="item.sourceId"
448
- :title="item.title"
449
- >
450
- <customDatePicker
451
- v-model="model[item.sourceId]"
452
- type="time"
453
- use-second
454
- :clearable="!item.disabled"
455
- :placeholder="`请选择${item.title}`"
456
- />
457
- </wd-form-item>
458
- <wd-form-item
459
- v-else-if="
460
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'date-YY'
461
- "
462
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
463
- :prop="item.sourceId"
464
- :title="item.title"
465
- >
466
- <customDatePicker
467
- v-model="model[item.sourceId]"
468
- type="year"
469
- use-second
470
- :clearable="!item.disabled"
471
- :placeholder="`请选择${item.title}`"
472
- />
473
- </wd-form-item>
474
- <wd-form-item
475
- v-else-if="
476
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'file' ||
477
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relfile'
478
- "
479
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
480
- :prop="item.sourceId"
481
- :title="item.title"
482
- >
483
- <wd-radio-group v-if="!item.disabled" v-model="fileType" inline shape="dot" custom-class="custom-radio">
484
- <wd-radio v-for="(titem, index) in fileTypes" :key="index" :value="titem.value">
485
- {{ titem.label }}
486
- </wd-radio>
487
- </wd-radio-group>
488
- <wd-upload
489
- :accept="fileType"
490
- :disabled="item.disabled || item.rowEditType === 'readonly'"
491
- :limit="1"
492
- :header="{
493
- 'hydrocarbon-program-token': hydrocarbonProgramToken,
494
- 'hydrocarbon-token': token,
495
- }"
496
- :file-list="model[item.sourceId]"
497
- :action="`${action}/v3/upload`"
498
- @success="
499
- e => {
500
- handleFileChange(e, item)
501
- }
502
- "
503
- />
504
- </wd-form-item>
505
- <wd-form-item
506
- v-else-if="
507
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselect'
508
- "
509
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
510
- :prop="item.sourceId"
511
- :title="item.title"
512
- :style="{ display: item.title?.includes('y') ? 'none' : null }"
513
- >
514
- <WuiSelectPopup
515
- v-model="model[item.sourceId]"
516
- :source-id="item.sourceId"
517
- :title="item.title"
518
- :ext-control-type="Number(item.max) === 1 ? 'relselect' : 'ss'"
519
- :readonly="item.disabled || item.rowEditType === 'readonly'"
520
- :clearable="!item.disabled"
521
- :default-select-first="!!item.defaultSelectFirst"
522
- />
523
- </wd-form-item>
524
- <wd-form-item
525
- v-else-if="
526
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
527
- 'relselectvalue'
528
- "
529
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
530
- :prop="item.sourceId"
531
- :title="item.title"
532
- >
533
- <WuiSelectPopup
534
- v-model="model[item.sourceId]"
535
- :source-id="item.sourceId"
536
- :title="item.title"
537
- :ext-control-type="item.extControlType"
538
- :readonly="item.disabled || item.rowEditType === 'readonly'"
539
- :clearable="!item.disabled"
540
- :default-select-first="!!item.defaultSelectFirst"
541
- />
542
- </wd-form-item>
543
- <wd-form-item
544
- v-else-if="
545
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
546
- 'tree-entity-select' ||
547
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
548
- 'table-entity-select'
549
- "
550
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
551
- :prop="item.sourceId"
552
- :title="item.title"
553
- >
554
- <WuiSelectPopup
555
- v-model="model[item.sourceId]"
556
- :source-id="item.sourceId"
557
- :title="item.title"
558
- :ext-control-type="Number(item.max) === 1 ? 'relselect' : 'ss'"
559
- :readonly="item.disabled || item.rowEditType === 'readonly'"
560
- :clearable="!item.disabled"
561
- :default-select-first="!!item.defaultSelectFirst"
562
- fold-card-model="complex"
563
- />
564
- </wd-form-item>
565
- <!-- done -->
566
- <wd-form-item
567
- v-else-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'int'"
568
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
569
- :prop="item.sourceId"
570
- :title="item.title"
571
- >
572
- <view style="text-align: left">
573
- <wd-input-number
574
- v-model="model[item.sourceId]"
575
- :disabled="item.disabled || item.rowEditType === 'readonly'"
576
- :min="Number(item.min || 0)"
577
- :max="Number(item.max || Infinity)"
578
- />
579
- </view>
580
- </wd-form-item>
581
- <wd-form-item
582
- v-else-if="
583
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'QRCode'
584
- "
585
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
586
- :prop="item.sourceId"
587
- :title="item.title"
588
- >
589
- <scanInput v-model="model[item.sourceId]" :disabled="item.disabled || item.rowEditType === 'readonly'" />
590
- </wd-form-item>
591
- <wd-form-item
592
- v-else-if="
593
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'progress'
594
- "
595
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
596
- :prop="item.sourceId"
597
- :title="item.title"
598
- >
599
- <wd-rate
600
- allow-half
601
- v-model="model[item.sourceId]"
602
- :disabled="item.disabled || item.rowEditType === 'readonly'"
603
- />
604
- </wd-form-item>
605
- <!-- done -->
606
- <wd-form-item
607
- v-else-if="
608
- ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'yes-no-switch'
609
- "
610
- :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
611
- :prop="item.sourceId"
612
- :title="item.title"
613
- >
614
- <view style="text-align: left">
615
- <wd-switch
616
- v-model="model[item.sourceId]"
617
- size="16"
618
- :disabled="item.disabled || item.rowEditType === 'readonly'"
619
- active-value="是"
620
- inactive-value="否"
621
- />
622
- </view>
623
- </wd-form-item>
624
- </view>
625
- </view>
626
- </wd-form>
627
- </view>
628
- </template>
629
-
630
- <style scoped>
631
- .custom-from-style {
632
- :deep(.custom-radio) {
633
- display: flex;
634
- padding: 4px;
635
- }
636
-
637
- :deep(.wd-form-item .wd-cell__wrapper) {
638
- gap: 12px;
639
- }
640
- :deep(.wd-form-item) {
641
- border-top: 0.6px solid #e8e8e8;
642
- padding: 12px 6px;
643
- margin: auto 6px;
644
- width: calc(100% - 12px);
645
- }
646
- :deep(.no-border-top) {
647
- border-top: none;
648
- }
649
- }
650
- :deep(.disabled-input) {
651
- background-color: #e8e8e8 !important;
652
- }
653
-
654
- /* 暗黑模式适配 */
655
- :global(.wot-theme-dark) .custom-from-style :deep(.wd-form-item) {
656
- border-top-color: #3d3d3d;
657
- }
658
- :global(.wot-theme-dark) ::deep(.disabled-input) {
659
- background-color: #2f2f2f !important;
660
- }
661
- </style>
1
+ <script lang="ts" setup>
2
+ import { computed, onBeforeMount, ref, toRaw, watch } from 'vue'
3
+ import type { FormSchema, FormSchemaIssue } from '@wot-ui/ui/components/wd-form/types'
4
+ import dayjs from 'dayjs/esm/index'
5
+ import type { Enums, Fields, Groups } from '../../type'
6
+ import WuiSelectPopup from '../wui-select-popup/wui-select-popup.vue'
7
+ import ControlTypeSupportor from '../../utils/control-type-supportor'
8
+ import { useCompanyFieldFilter } from '../../composables/useCompanyFieldFilter'
9
+ import customSelectPicker from '../custom-select-picker/custom-select-picker.vue'
10
+ import CustomDatePicker from '../custom-date-picker/custom-date-picker.vue'
11
+ import addAddressPage from '../add-address-page/add-address-page.vue'
12
+ import userChoose from '../user-choose/user-choose.vue'
13
+ import { generateHighResolutionID } from '../../utils/index'
14
+ import scanInput from '../scan-input/scan-input.vue'
15
+ // import { enums } from '../../api/page'
16
+ defineOptions({
17
+ name: 'FormControl',
18
+ })
19
+ const props = defineProps<{
20
+ fieldGroup?: Groups
21
+ entity?: { [key: string]: string }
22
+ enumColumn?: Enums
23
+ companyFilter?: boolean
24
+ companyFieldSourceId?: string
25
+ smartPaste?: boolean
26
+ }>()
27
+ const fileTypes = [
28
+ {
29
+ label: '照片',
30
+ value: 'image',
31
+ },
32
+ {
33
+ label: '视频',
34
+ value: 'video',
35
+ },
36
+ // {
37
+ // label: '文件',
38
+ // value: 'file',
39
+ // },
40
+ ]
41
+ const fileType = ref<any>('image')
42
+ const action = ref<string>('')
43
+ const hydrocarbonProgramToken = ref<string>('')
44
+ const token = ref<string>('')
45
+ const form = ref<any>(null)
46
+ const model = ref<any>({})
47
+ const addEvent = generateHighResolutionID() // 全局事件名称
48
+ const { filteredFields: fields } = useCompanyFieldFilter(
49
+ () => props.fieldGroup,
50
+ model,
51
+ props.companyFilter, // 是否自适应显示快递公司填充框
52
+ props.companyFieldSourceId // 快递公司对应字段
53
+ )
54
+ const giveDefaultValue = (value: any) => {
55
+ const { extInfo = {} } = uni.getStorageSync('userInfo') || {}
56
+ const rawDefaultValue = extInfo.fieldMap || {}
57
+ const defaultValue: Record<string, any> = {}
58
+ for (const key in rawDefaultValue) {
59
+ if (Object.prototype.hasOwnProperty.call(rawDefaultValue, key)) {
60
+ const val = rawDefaultValue[key]
61
+ defaultValue[key] = typeof val === 'string' && val.includes('@R@') ? val.split('@R@')[0] : val
62
+ }
63
+ }
64
+ return defaultValue[value] || {}
65
+ }
66
+ giveDefaultValue({})
67
+ // 初始化表单数据
68
+ function initFormData() {
69
+ const models: { [key: string]: any } = {}
70
+ props.fieldGroup?.fields.forEach((item: Fields) => {
71
+ // 树、多选
72
+ if (
73
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'tree-entity-select' ||
74
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'multiselect'
75
+ ) {
76
+ return (models[item.sourceId] =
77
+ (props.entity && props.entity[item.sourceId]?.split(',')) || item.transDefaultValue || [])
78
+ }
79
+
80
+ if (ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselect') {
81
+ return (models[item.sourceId] =
82
+ (props.entity && props.entity[item.sourceId]?.split('@,@')) ||
83
+ (item.transDefaultValue && item.transDefaultValue?.split('@,@')) ||
84
+ [])
85
+ }
86
+
87
+ // 文件
88
+ if (
89
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'file' ||
90
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relfile'
91
+ ) {
92
+ if (props.entity && typeof props.entity[item.sourceId] === 'object') {
93
+ return (models[item.sourceId] = [props.entity[item.sourceId]])
94
+ }
95
+ return (models[item.sourceId] =
96
+ (props.entity &&
97
+ props.entity[item.sourceId] && [
98
+ {
99
+ disabled: JSON.parse(props.entity[item.sourceId]).valid,
100
+ url: `${action.value}/v3/files${JSON.parse(props.entity[item.sourceId])?.base.path}?@token=${token.value}&@programToken=${hydrocarbonProgramToken.value}`,
101
+ name: `${JSON.parse(props.entity[item.sourceId])?.base.fileName}`,
102
+ response: JSON.stringify({
103
+ fileKey: `$blob:${JSON.parse(props.entity[item.sourceId])?.base.bytesInfoVO.code}`,
104
+ }),
105
+ },
106
+ ]) ||
107
+ item.transDefaultValue ||
108
+ [])
109
+ }
110
+
111
+ // 时间
112
+ if (
113
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'datetime' ||
114
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'date'
115
+ ) {
116
+ return (models[item.sourceId] =
117
+ (props.entity && dayjs(props.entity[item.sourceId]).valueOf()) ||
118
+ (item.transDefaultValue && dayjs(item.transDefaultValue).valueOf()) ||
119
+ null)
120
+ }
121
+
122
+ // 评分
123
+ if (ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'progress') {
124
+ const val = props.entity?.[item.sourceId]
125
+ return (models[item.sourceId] = val !== undefined && val !== null && val !== '' ? Number(val) : 0)
126
+ }
127
+
128
+ return (models[item.sourceId] = (props.entity && props.entity[item.sourceId]) || item.transDefaultValue || '')
129
+ })
130
+
131
+ // 遍历 models,处理 $$user. 前缀
132
+ const processedModels: Record<string, any> = {}
133
+ for (const key in models) {
134
+ if (Object.prototype.hasOwnProperty.call(models, key)) {
135
+ const val = models[key]
136
+ if (typeof val === 'string' && val.includes('$$user.')) {
137
+ processedModels[key] = giveDefaultValue(val.split('$$user.')[1])
138
+ } else {
139
+ processedModels[key] = val
140
+ }
141
+ }
142
+ }
143
+
144
+ model.value = {
145
+ ...processedModels,
146
+ }
147
+ }
148
+
149
+ //-s
150
+ const shouldMonitor = computed(() => {
151
+ const newList = fields.value
152
+ .filter((item: any) => item.relValueField || item.relValueField3)
153
+ .map((innerItem: any) => ({
154
+ id: innerItem.sourceId,
155
+ title: innerItem.title,
156
+ relValueField: innerItem.relValueField.id,
157
+ relValueField3: innerItem.relValueField3.id,
158
+ }))
159
+ console.log('shouldMonitor:', newList)
160
+ return newList
161
+ })
162
+ //-e
163
+
164
+ // 存储变化后的数据,{ [fieldKey]: newValue, ... }
165
+ const changedData = ref<Record<string, any>>({})
166
+ const initialModel = ref<Record<string, any>>({})
167
+
168
+ // 监听 shouldMonitor 中 relValueField / relValueField3 对应的 model 字段
169
+ watch(
170
+ () => {
171
+ const snapshot: Record<string, any> = {}
172
+ shouldMonitor.value?.forEach((item: any) => {
173
+ if (item.relValueField) snapshot.relValueField = model.value[item.relValueField]
174
+ if (item.relValueField3) snapshot.relValueField3 = model.value[item.relValueField3]
175
+ })
176
+ return snapshot
177
+ },
178
+ newVal => {
179
+ // 只存储与初始值不同的字段(表单变化的值)
180
+ const changed: Record<string, any> = {}
181
+ shouldMonitor.value?.forEach((item: any) => {
182
+ if (item.relValueField && newVal.relValueField !== initialModel.value[item.relValueField]) {
183
+ changed.relValueField = newVal.relValueField
184
+ }
185
+ if (item.relValueField3 && newVal.relValueField3 !== initialModel.value[item.relValueField3]) {
186
+ changed.relValueField3 = newVal.relValueField3
187
+ }
188
+ })
189
+ changedData.value = changed
190
+
191
+ // 当所有被监听的字段都有值时,存入缓存供 select-list 页面读取
192
+ const values = Object.values(newVal)
193
+ const allExist = values.length > 0 && values.every(v => v !== null && v !== undefined && v !== '')
194
+ if (allExist) {
195
+ uni.setStorageSync('paramsData', {
196
+ changedData: changedData.value,
197
+ rawData: shouldMonitor.value,
198
+ })
199
+ console.log('changedData:', changedData.value)
200
+ }
201
+ }
202
+ )
203
+
204
+ onBeforeMount(() => {
205
+ action.value = uni.getStorageSync('BASE_URL')
206
+ hydrocarbonProgramToken.value = uni.getStorageSync('HYDROCARBON_PROGRAM_TOKEN')
207
+ token.value = uni.getStorageSync('TOKEN')
208
+ initFormData()
209
+ initialModel.value = JSON.parse(JSON.stringify(model.value))
210
+ })
211
+ function formatSelectColumns(columns: any) {
212
+ return columns.map((item: any) => {
213
+ return {
214
+ ...item,
215
+ label: item.title,
216
+ }
217
+ })
218
+ }
219
+
220
+ const schema = computed((): FormSchema => {
221
+ return {
222
+ validate(_model: Record<string, any>): FormSchemaIssue[] {
223
+ const issues: FormSchemaIssue[] = []
224
+ props.fieldGroup?.fields.forEach((item: Fields) => {
225
+ if (item.required) {
226
+ const value = _model[item.sourceId]
227
+ if (Array.isArray(value) && value.length < 1) {
228
+ issues.push({ path: [item.sourceId], message: `请填写${item.title}` })
229
+ } else if (!value) {
230
+ issues.push({ path: [item.sourceId], message: `请填写${item.title}` })
231
+ }
232
+ }
233
+ })
234
+ return issues
235
+ },
236
+ isRequired(path: string) {
237
+ return props.fieldGroup?.fields.some(f => f.sourceId === path && f.required) ?? false
238
+ },
239
+ }
240
+ })
241
+
242
+ // 监听文件上传成功
243
+ function handleFileChange(e: any, item: Fields) {
244
+ model.value[item.sourceId] = e.fileList
245
+ }
246
+
247
+ function submit() {
248
+ return new Promise((resolve, reject) => {
249
+ form.value
250
+ .validate()
251
+ .then(({ valid }: any) => {
252
+ if (valid) {
253
+ const data: { [key: string]: any } = {}
254
+ for (const key in model.value) {
255
+ if (Object.prototype.hasOwnProperty.call(model.value, key)) {
256
+ fields.value?.forEach((item: Fields) => {
257
+ if (item.sourceId === key) {
258
+ if (ControlTypeSupportor.getControlType(item) === 'file') {
259
+ data[key] = toRaw(model.value[key][0])
260
+ } else if (
261
+ ControlTypeSupportor.getControlType(item) === 'relselect' ||
262
+ ControlTypeSupportor.getControlType(item) === 'tree-entity-select'
263
+ ) {
264
+ if (Array.isArray(model.value[key])) {
265
+ data[key] = model.value[key].join('@,@')
266
+ } else {
267
+ data[key] = model.value[key]
268
+ }
269
+ } else {
270
+ data[key] = model.value[key]
271
+ }
272
+ }
273
+ })
274
+ }
275
+ }
276
+ resolve(data)
277
+ } else {
278
+ reject(valid)
279
+ }
280
+ })
281
+ .catch((error: any) => {
282
+ console.log(error, 'error')
283
+ reject(error)
284
+ })
285
+ })
286
+ }
287
+
288
+ // 暴露方法/变量给父组件
289
+ defineExpose({
290
+ submit,
291
+ })
292
+ </script>
293
+
294
+ <template>
295
+ <view>
296
+ <wd-form ref="form" :model="model" :schema="schema" error-type="toast" :label-width="120" class="custom-from-style">
297
+ <addAddressPage v-if="props?.smartPaste" v-model="model" :group="props.fieldGroup" />
298
+ <view v-for="item in fields" :key="item.sourceId">
299
+ <view v-show="!item.title?.includes('y') && !item.hidden">
300
+ <wd-form-item
301
+ v-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'text'"
302
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
303
+ :prop="item.sourceId"
304
+ :title="item.title"
305
+ >
306
+ <wd-input
307
+ v-model="model[item.sourceId]"
308
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
309
+ :clearable="!item.disabled"
310
+ :placeholder="`请输入${item.title}`"
311
+ :class="{ 'disabled-input': item.disabled || item.rowEditType === 'readonly' }"
312
+ />
313
+ </wd-form-item>
314
+ <wd-form-item
315
+ v-else-if="
316
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'decimal'
317
+ "
318
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
319
+ :prop="item.sourceId"
320
+ :title="item.title"
321
+ >
322
+ <wd-input
323
+ v-model="model[item.sourceId]"
324
+ type="number"
325
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
326
+ :clearable="!item.disabled"
327
+ :placeholder="`请输入${item.title}`"
328
+ />
329
+ </wd-form-item>
330
+ <wd-form-item
331
+ v-else-if="
332
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'password'
333
+ "
334
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
335
+ :prop="item.sourceId"
336
+ :title="item.title"
337
+ >
338
+ <wd-input
339
+ v-model="model[item.sourceId]"
340
+ show-password
341
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
342
+ :clearable="!item.disabled"
343
+ :placeholder="`请输入${item.title}`"
344
+ />
345
+ </wd-form-item>
346
+ <wd-form-item
347
+ v-else-if="
348
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'textarea'
349
+ "
350
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
351
+ :prop="item.sourceId"
352
+ :title="item.title"
353
+ >
354
+ <wd-textarea
355
+ v-model="model[item.sourceId]"
356
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
357
+ :clearable="!item.disabled"
358
+ :placeholder="`请输入${item.title}`"
359
+ auto-height
360
+ />
361
+ </wd-form-item>
362
+ <wd-form-item
363
+ v-else-if="
364
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'select'
365
+ "
366
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
367
+ :prop="item.sourceId"
368
+ :title="item.title"
369
+ :style="{ display: item.title?.includes('y') ? 'none' : null }"
370
+ >
371
+ <customSelectPicker
372
+ v-model="model[item.sourceId]"
373
+ :placeholder="`请选择${item.title}`"
374
+ :columns="enumColumn && formatSelectColumns(enumColumn[item.mstrucId])"
375
+ type="radio"
376
+ />
377
+ </wd-form-item>
378
+ <wd-form-item
379
+ v-else-if="
380
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
381
+ 'relselect-extdis'
382
+ "
383
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
384
+ :prop="item.sourceId"
385
+ :title="item.title"
386
+ :style="{ display: item.title?.includes('y') ? 'none' : null }"
387
+ >
388
+ <userChoose
389
+ v-model="model[item.sourceId]"
390
+ :placeholder="`请选择${item.title}`"
391
+ :source-id="item.sourceId"
392
+ :title="item.title"
393
+ :add-event="addEvent"
394
+ :ext-control-type="item.extControlType"
395
+ />
396
+ </wd-form-item>
397
+ <wd-form-item
398
+ v-else-if="
399
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'multiselect'
400
+ "
401
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
402
+ :prop="item.sourceId"
403
+ :title="item.title"
404
+ >
405
+ <customSelectPicker
406
+ v-model="model[item.sourceId]"
407
+ :placeholder="`请选择${item.title}`"
408
+ :columns="enumColumn && formatSelectColumns(enumColumn[item.mstrucId])"
409
+ type="checkbox"
410
+ />
411
+ </wd-form-item>
412
+ <wd-form-item
413
+ v-else-if="
414
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'date'
415
+ "
416
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
417
+ :prop="item.sourceId"
418
+ :title="item.title"
419
+ >
420
+ <customDatePicker
421
+ v-model="model[item.sourceId]"
422
+ type="date"
423
+ :clearable="!item.disabled"
424
+ :placeholder="`请选择${item.title}`"
425
+ />
426
+ </wd-form-item>
427
+ <wd-form-item
428
+ v-else-if="
429
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'datetime'
430
+ "
431
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
432
+ :prop="item.sourceId"
433
+ :title="item.title"
434
+ >
435
+ <customDatePicker
436
+ v-model="model[item.sourceId]"
437
+ type="datetime"
438
+ :clearable="!item.disabled"
439
+ :placeholder="`请选择${item.title}`"
440
+ />
441
+ </wd-form-item>
442
+ <wd-form-item
443
+ v-else-if="
444
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'time'
445
+ "
446
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
447
+ :prop="item.sourceId"
448
+ :title="item.title"
449
+ >
450
+ <customDatePicker
451
+ v-model="model[item.sourceId]"
452
+ type="time"
453
+ use-second
454
+ :clearable="!item.disabled"
455
+ :placeholder="`请选择${item.title}`"
456
+ />
457
+ </wd-form-item>
458
+ <wd-form-item
459
+ v-else-if="
460
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'date-YY'
461
+ "
462
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
463
+ :prop="item.sourceId"
464
+ :title="item.title"
465
+ >
466
+ <customDatePicker
467
+ v-model="model[item.sourceId]"
468
+ type="year"
469
+ use-second
470
+ :clearable="!item.disabled"
471
+ :placeholder="`请选择${item.title}`"
472
+ />
473
+ </wd-form-item>
474
+ <wd-form-item
475
+ v-else-if="
476
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'file' ||
477
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relfile'
478
+ "
479
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
480
+ :prop="item.sourceId"
481
+ :title="item.title"
482
+ >
483
+ <wd-radio-group v-if="!item.disabled" v-model="fileType" inline shape="dot" custom-class="custom-radio">
484
+ <wd-radio v-for="(titem, index) in fileTypes" :key="index" :value="titem.value">
485
+ {{ titem.label }}
486
+ </wd-radio>
487
+ </wd-radio-group>
488
+ <wd-upload
489
+ :accept="fileType"
490
+ :disabled="item.disabled || item.rowEditType === 'readonly'"
491
+ :limit="1"
492
+ :header="{
493
+ 'hydrocarbon-program-token': hydrocarbonProgramToken,
494
+ 'hydrocarbon-token': token,
495
+ }"
496
+ :file-list="model[item.sourceId]"
497
+ :action="`${action}/v3/upload`"
498
+ @success="
499
+ e => {
500
+ handleFileChange(e, item)
501
+ }
502
+ "
503
+ />
504
+ </wd-form-item>
505
+ <wd-form-item
506
+ v-else-if="
507
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'relselect'
508
+ "
509
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
510
+ :prop="item.sourceId"
511
+ :title="item.title"
512
+ :style="{ display: item.title?.includes('y') ? 'none' : null }"
513
+ >
514
+ <WuiSelectPopup
515
+ v-model="model[item.sourceId]"
516
+ :source-id="item.sourceId"
517
+ :title="item.title"
518
+ :ext-control-type="Number(item.max) === 1 ? 'relselect' : 'ss'"
519
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
520
+ :clearable="!item.disabled"
521
+ :default-select-first="!!item.defaultSelectFirst"
522
+ />
523
+ </wd-form-item>
524
+ <wd-form-item
525
+ v-else-if="
526
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
527
+ 'relselectvalue'
528
+ "
529
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
530
+ :prop="item.sourceId"
531
+ :title="item.title"
532
+ >
533
+ <WuiSelectPopup
534
+ v-model="model[item.sourceId]"
535
+ :source-id="item.sourceId"
536
+ :title="item.title"
537
+ :ext-control-type="item.extControlType"
538
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
539
+ :clearable="!item.disabled"
540
+ :default-select-first="!!item.defaultSelectFirst"
541
+ />
542
+ </wd-form-item>
543
+ <wd-form-item
544
+ v-else-if="
545
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
546
+ 'tree-entity-select' ||
547
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) ===
548
+ 'table-entity-select'
549
+ "
550
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
551
+ :prop="item.sourceId"
552
+ :title="item.title"
553
+ >
554
+ <WuiSelectPopup
555
+ v-model="model[item.sourceId]"
556
+ :source-id="item.sourceId"
557
+ :title="item.title"
558
+ :ext-control-type="Number(item.max) === 1 ? 'relselect' : 'ss'"
559
+ :readonly="item.disabled || item.rowEditType === 'readonly'"
560
+ :clearable="!item.disabled"
561
+ :default-select-first="!!item.defaultSelectFirst"
562
+ fold-card-model="complex"
563
+ />
564
+ </wd-form-item>
565
+ <!-- done -->
566
+ <wd-form-item
567
+ v-else-if="ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'int'"
568
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
569
+ :prop="item.sourceId"
570
+ :title="item.title"
571
+ >
572
+ <view style="text-align: left">
573
+ <wd-input-number
574
+ v-model="model[item.sourceId]"
575
+ :disabled="item.disabled || item.rowEditType === 'readonly'"
576
+ :min="Number(item.min || 0)"
577
+ :max="Number(item.max || Infinity)"
578
+ />
579
+ </view>
580
+ </wd-form-item>
581
+ <wd-form-item
582
+ v-else-if="
583
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'QRCode'
584
+ "
585
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
586
+ :prop="item.sourceId"
587
+ :title="item.title"
588
+ >
589
+ <scanInput v-model="model[item.sourceId]" :disabled="item.disabled || item.rowEditType === 'readonly'" />
590
+ </wd-form-item>
591
+ <wd-form-item
592
+ v-else-if="
593
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'progress'
594
+ "
595
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
596
+ :prop="item.sourceId"
597
+ :title="item.title"
598
+ >
599
+ <wd-rate
600
+ allow-half
601
+ v-model="model[item.sourceId]"
602
+ :disabled="item.disabled || item.rowEditType === 'readonly'"
603
+ />
604
+ </wd-form-item>
605
+ <!-- done -->
606
+ <wd-form-item
607
+ v-else-if="
608
+ ControlTypeSupportor.getControlType(item, props.entity && props.entity[item.sourceId]) === 'yes-no-switch'
609
+ "
610
+ :class="{ 'no-border-top': fields.indexOf(item) === 0 }"
611
+ :prop="item.sourceId"
612
+ :title="item.title"
613
+ >
614
+ <view style="text-align: left">
615
+ <wd-switch
616
+ v-model="model[item.sourceId]"
617
+ size="16"
618
+ :disabled="item.disabled || item.rowEditType === 'readonly'"
619
+ active-value="是"
620
+ inactive-value="否"
621
+ />
622
+ </view>
623
+ </wd-form-item>
624
+ </view>
625
+ </view>
626
+ </wd-form>
627
+ </view>
628
+ </template>
629
+
630
+ <style scoped>
631
+ .custom-from-style {
632
+ :deep(.custom-radio) {
633
+ display: flex;
634
+ padding: 4px;
635
+ }
636
+
637
+ :deep(.wd-form-item .wd-cell__wrapper) {
638
+ gap: 12px;
639
+ }
640
+ :deep(.wd-form-item) {
641
+ border-top: 0.6px solid #e8e8e8;
642
+ padding: 12px 6px;
643
+ margin: auto 6px;
644
+ width: calc(100% - 12px);
645
+ }
646
+ :deep(.no-border-top) {
647
+ border-top: none;
648
+ }
649
+ }
650
+ :deep(.disabled-input) {
651
+ background-color: #e8e8e8 !important;
652
+ }
653
+
654
+ /* 暗黑模式适配 */
655
+ :global(.wot-theme-dark) .custom-from-style :deep(.wd-form-item) {
656
+ border-top-color: #3d3d3d;
657
+ }
658
+ :global(.wot-theme-dark) ::deep(.disabled-input) {
659
+ background-color: #2f2f2f !important;
660
+ }
661
+ </style>