widget.qw 1.0.83 → 1.0.85

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 (108) hide show
  1. package/.env.development +10 -10
  2. package/.env.production +8 -8
  3. package/README.md +75 -75
  4. package/build/style.css +521 -471
  5. package/build/widget.qw.es.js +253 -84
  6. package/build/widget.qw.umd.js +252 -83
  7. package/index.html +17 -17
  8. package/package.json +47 -47
  9. package/src/App.vue +26 -26
  10. package/src/api/index.js +173 -165
  11. package/src/components/AuditBar.vue +396 -396
  12. package/src/components/BillCard.vue +164 -164
  13. package/src/components/CascaderPicker.vue +132 -132
  14. package/src/components/CascaderPop.vue +375 -371
  15. package/src/components/CheckGroup.vue +113 -113
  16. package/src/components/DatetimeDropdown.vue +62 -0
  17. package/src/components/{DatetimePicker/index.vue → DatetimePicker.vue} +124 -124
  18. package/src/components/DayDropdown.vue +56 -56
  19. package/src/components/FilePicker.vue +169 -169
  20. package/src/components/HeadBar.vue +130 -0
  21. package/src/components/Input.vue +80 -80
  22. package/src/components/MonthDropdown.vue +51 -51
  23. package/src/components/MultiPicker.vue +123 -123
  24. package/src/components/ObjsEditor.vue +334 -334
  25. package/src/components/SecretNotify.js +5 -5
  26. package/src/components/Sheet.vue +92 -92
  27. package/src/components/SingleApiPicker.vue +108 -108
  28. package/src/components/SinglePicker.vue +102 -102
  29. package/src/components/SingleUserSelector.vue +425 -425
  30. package/src/components/Switch.vue +64 -64
  31. package/src/components/TreePicker.vue +113 -113
  32. package/src/components/UserPicker.vue +106 -106
  33. package/src/components/UserProfile.vue +129 -129
  34. package/src/components/UsersPicker.vue +118 -118
  35. package/src/components/YearDropdown.vue +59 -59
  36. package/src/components/data_selector.vue +303 -303
  37. package/src/components/image_picker.vue +123 -123
  38. package/src/components/images_picker.vue +195 -195
  39. package/src/components/index.js +172 -162
  40. package/src/components/mult_list_selector.vue +155 -155
  41. package/src/components/subdepartment_selector.vue +481 -481
  42. package/src/components/user_selector.vue +639 -639
  43. package/src/components/widget/DataPop.vue +95 -95
  44. package/src/components/{DatetimePicker → widget}/DatetimePop.vue +342 -342
  45. package/src/components/widget/TreePop.vue +88 -88
  46. package/src/components/widget/UserPop.vue +347 -347
  47. package/src/main.js +117 -117
  48. package/src/router/index.ts +183 -173
  49. package/src/util/array_util.js +32 -32
  50. package/src/util/auth_util.js +72 -72
  51. package/src/util/bool_util.js +5 -5
  52. package/src/util/bus.js +1 -1
  53. package/src/util/cache_util.js +18 -18
  54. package/src/util/errer_code.js +6 -6
  55. package/src/util/eval_util.js +19 -19
  56. package/src/util/icon_util.js +36 -36
  57. package/src/util/image_util.js +27 -27
  58. package/src/util/index.js +57 -57
  59. package/src/util/num_util.js +70 -70
  60. package/src/util/obj_util.js +28 -28
  61. package/src/util/request.js +73 -73
  62. package/src/util/request_json.js +71 -71
  63. package/src/util/request_json_mute.js +65 -65
  64. package/src/util/request_upload.js +79 -79
  65. package/src/util/route_util.js +31 -31
  66. package/src/util/str_util.js +143 -143
  67. package/src/util/time_util.js +406 -406
  68. package/src/util/toast_util.js +24 -24
  69. package/src/util/tree_util.js +153 -153
  70. package/src/util/uuid_util.js +9 -9
  71. package/src/util/validate.js +182 -182
  72. package/src/util/vue_filter.js +223 -223
  73. package/src/views/auditbar/index.vue +78 -78
  74. package/src/views/billcard/index.vue +48 -48
  75. package/src/views/cascaderpicker/index.vue +0 -0
  76. package/src/views/cascaderpicker/userpicker.vue +183 -0
  77. package/src/views/cascaderpop/index.vue +90 -90
  78. package/src/views/checkgroup/index.vue +35 -35
  79. package/src/views/dataSelector/index.vue +48 -48
  80. package/src/views/datetimedropdown/index.vue +34 -0
  81. package/src/views/datetimepicker/index.vue +34 -34
  82. package/src/views/daydropdown/index.vue +31 -31
  83. package/src/views/filepicker/index.vue +32 -32
  84. package/src/views/headbar/index.vue +28 -0
  85. package/src/views/home/index.vue +0 -0
  86. package/src/views/imagepicker/index.vue +31 -31
  87. package/src/views/imagespicker/index.vue +37 -37
  88. package/src/views/input/index.vue +35 -35
  89. package/src/views/monthdropdown/index.vue +31 -31
  90. package/src/views/multListSelector/index.vue +61 -61
  91. package/src/views/multipicker/index.vue +36 -36
  92. package/src/views/objseditor/index.vue +277 -277
  93. package/src/views/productSelector/index.vue +35 -35
  94. package/src/views/projectpicker/index.vue +41 -41
  95. package/src/views/secretnotify/index.vue +27 -27
  96. package/src/views/sheet/index.vue +45 -45
  97. package/src/views/singlepicker/index.vue +35 -35
  98. package/src/views/subdepartmentSelector/index.vue +40 -40
  99. package/src/views/switch/index.vue +34 -34
  100. package/src/views/treepicker/index.vue +41 -41
  101. package/src/views/userSelector/index.vue +54 -54
  102. package/src/views/userSelectorNew/index.vue +45 -45
  103. package/src/views/userpicker/index.vue +43 -43
  104. package/src/views/userprofile/index.vue +30 -30
  105. package/src/views/userspicker/index.vue +43 -43
  106. package/src/views/yeardropdown/index.vue +32 -32
  107. package/src/vm/index.js +1 -1
  108. package/vite.config.ts +122 -122
@@ -1,335 +1,335 @@
1
- <template>
2
- <van-field :label="props.label" v-if="!isGone" :disabled="isDisabled" :required="isRequired"
3
- :placeholder="props.placeholder">
4
- <template #input>
5
- <div class="widget-box">
6
- <div class="option" v-for="(item, index) in modelValue" :key="index">
7
- <div v-if="index != data.selectIndex" style=" display: flex;align-items: center;">
8
- <van-icon name="arrow-left" @click.stop="onForward(index)" />
9
- <div style="padding: 5px 5px;">
10
- <div v-for="(k, j) in visiableKeys" :key="j" style="padding:2px 2px;font-size: 12px;">
11
- <div v-if="props.schema[k].type != 'Images'">
12
- {{ `${key2name(k)}:${key2value(k, item)}` }}
13
- </div>
14
- <div v-else>
15
- <ImagesPicker v-model="item[k]" readonly />
16
- </div>
17
- </div>
18
- </div>
19
-
20
- <div style="display: flex;flex-direction:column;cursor: pointer;">
21
- <van-icon name="edit"
22
- v-if="props.schema.auth != 'readonly' && props.auth != 'readonly' && props.auth != 'disabled'"
23
- @click.stop="onEdit(index)" />
24
-
25
- <van-icon name="arrow" @click.stop="onBack(index)" style="margin:8px 0" />
26
-
27
- <van-icon name="cross"
28
- v-if="props.schema.auth != 'readonly' && props.auth != 'readonly' && props.auth != 'disabled'"
29
- @click.stop="onDelete(index)" />
30
- </div>
31
- </div>
32
-
33
- <van-form v-if="data.isShowInput && index == data.selectIndex" :model="data.inputValue">
34
- <van-field v-for="(key, i) in keys" :key="i" :label="props.schema[key].label"
35
- v-show="props.schema[key].auth != 'gone'" :required="props.schema[key].auth === 'required'"
36
- :disabled="props.schema[key].auth === 'readonly'">
37
-
38
- <template #input>
39
- <van-field
40
- v-if="props.schema[key].type == 'String' && !props.schema[key]?.schema?.options"
41
- :disabled="props.schema[key].auth === 'readonly'" v-model="data.inputValue[key]"
42
- :placeholder="`请输入${key2name(key)}`" type="text" />
43
-
44
- <van-field
45
- v-if="props.schema[key].type == 'Number' && !props.schema[key]?.schema?.options"
46
- :disabled="props.schema[key].auth === 'readonly'"
47
- v-model.number="data.inputValue[key]" :placeholder="`请输入${key2name(key)}`"
48
- type="number" />
49
-
50
- <van-switch v-if="props.schema[key].type == 'Boolean'"
51
- :disabled="props.schema[key].auth === 'readonly'" v-model="data.inputValue[key]" />
52
-
53
- <DatetimePicker v-if="props.schema[key].type == 'Datetime'"
54
- :auth="props.schema[key].auth" v-model="data.inputValue[key]" placeholder="选择时间" />
55
-
56
- <ImagesPicker v-if="props.schema[key].type == 'Images'" :auth="props.schema[key].auth"
57
- v-model="data.inputValue[key]" />
58
-
59
- <DateSelector v-if="props.schema[key]?.schema?.options" v-model="data.inputValue[key]"
60
- :auth="props.schema[key].auth" :options="props.schema[key]?.schema?.options"
61
- :placeholder="`请输入${key2name(key)}`" :columnsFieldNames="{
62
- text: (props.schema[key]?.schema?.options || []).length > 0 ? Object.keys(props.schema[key].schema.options[0])[0] : '',
63
- value: (props.schema[key]?.schema?.options || []).length > 0 ? Object.keys(props.schema[key].schema.options[0])[1] : ''
64
- }" @select="onChangeOption(key)" />
65
-
66
- <ObjsEditor v-if="props.schema[key].type == 'Array' && props.schema[key].auth != 'gone'"
67
- :auth="props.schema[key].auth" v-model="data.inputValue[key]"
68
- :schema="props.schema[key].schema" />
69
- </template>
70
- </van-field>
71
-
72
- <div style="margin: 16px; display: flex;align-items: center;justify-content: center;">
73
- <van-button v-if="data.isShowInput" @click="onInputConfirm" size="mini">保存</van-button>
74
- <van-button v-if="data.isShowInput" @click="onInputCancel" size="mini">取消</van-button>
75
- </div>
76
- </van-form>
77
- </div>
78
-
79
- <van-icon name="plus" v-if="!data.isShowInput && props.auth != 'readonly' && props.auth != 'disabled'"
80
- @click="onNewOption" />
81
- </div>
82
- </template>
83
- </van-field>
84
- </template>
85
-
86
- <script setup>
87
- import { nextTick, ref, onMounted, defineProps, defineEmits, reactive, computed, watch } from 'vue'
88
- import { useVModel } from '@vueuse/core'
89
- import util from '@/util'
90
- import DatetimePicker from './DatetimePicker/index.vue'
91
- import DateSelector from './data_selector.vue'
92
- import ImagesPicker from './images_picker.vue'
93
-
94
- const props = defineProps({
95
- modelValue: {
96
- type: Array,
97
- default: []
98
- },
99
- label: {
100
- type: String,
101
- default: ''
102
- },
103
- placeholder: {
104
- type: String,
105
- default: ''
106
- },
107
- readonly: {
108
- type: Boolean,
109
- default: true
110
- },
111
- required: {
112
- type: Boolean,
113
- default: false
114
- },
115
- auth: {
116
- type: String,
117
- default: 'option'
118
- },
119
- schema: {
120
- type: Object,
121
- default: {
122
- type: "String",
123
- label: '名称',
124
- default: '',
125
- //权限取值范围: required 必填 option 选填 readonly 只读 gone 隐藏
126
- auth: 'option'
127
- }
128
- }
129
- })
130
-
131
- const emit = defineEmits(['update:modelValue'])
132
- const modelValue = useVModel(props, 'modelValue', emit)
133
- const { isRequired, isReadonly, isGone, isDisabled } = util.props2auth(props)
134
-
135
- const data = reactive({
136
- inputValue: {},
137
- isShowInput: false,
138
- selectIndex: -1,
139
- oldModelValue: []
140
- })
141
- const keys = Object.keys(props.schema)
142
- const visiableKeys = keys.filter(k => props.schema[k].auth != 'gone')
143
-
144
- watch(() => JSON.stringify(modelValue.value), (n, o) => {
145
- if (!modelValue.value)
146
- modelValue.value = []
147
-
148
- data.oldModelValue = JSON.parse(JSON.stringify(modelValue.value))
149
- }, {
150
- immediate: true
151
- }, {
152
- deep: true
153
- })
154
-
155
- onMounted(() => {
156
- })
157
-
158
- const makeDefaultValue = () => {
159
- let res = {}
160
-
161
- keys.forEach(key => {
162
- // 复制默认值,防止对象类型的默认值被修改
163
- if (props.schema[key].default === 'uuid')
164
- res[key] = util.uuid8()
165
- else
166
- res[key] = JSON.parse(JSON.stringify(props.schema[key].default))
167
- })
168
-
169
- return res
170
- }
171
-
172
- const onForward = (index) => {
173
- util.arySwapPrev(modelValue.value, index)
174
- }
175
-
176
- const onBack = (index) => {
177
- util.arySwapNext(modelValue.value, index)
178
- }
179
-
180
- const onDelete = (index) => {
181
- modelValue.value.splice(index, 1)
182
- }
183
-
184
- const key2name = (key) => {
185
- return props.schema[key].label
186
- }
187
-
188
- const key2value = (key, item) => {
189
- console.log('key2value', key, item[key], item)
190
-
191
- let v = item[key]
192
- if (props.schema[key].type === 'Images') {
193
- return (v || []).join(',')
194
- }
195
- else if (Array.isArray(v)) {
196
- let formatValues = v.map(e => {
197
- let kvs = Object.keys(e).map(k => {
198
- console.log(props.schema[key])
199
- console.log(key)
200
- console.log(v)
201
- console.log(k)
202
-
203
- let label = props.schema[key].schema[k].label
204
- let formatValue = e[k]
205
-
206
- //下拉框选项,用选项的第二个属性value找选中的选项
207
- //再取选项的第一个属性name作为标题
208
- if (props.schema[key].schema[k]?.schema?.options) {
209
- let one = props.schema[key].schema[k]?.schema?.options.find(item => item[Object.keys(item)[1]] === formatValue)
210
- if (one)
211
- formatValue = one[Object.keys(one)[0]]
212
- else
213
- formatValue = ''
214
- }
215
-
216
- return `${label}:${formatValue}`
217
- })
218
- return kvs.join(',')
219
- })
220
-
221
- return formatValues.join(' > ')
222
- }
223
- //下拉框选项,用选项的第二个属性value找选中的选项
224
- //再取选项的第一个属性name作为标题
225
- else if (props.schema[key]?.schema?.options) {
226
- let one = props.schema[key]?.schema?.options.find(item => item[Object.keys(item)[1]] === v)
227
- return one ? one[Object.keys(one)[0]] : ''
228
- }
229
- else {
230
- if (props.schema[key].type === 'Boolean')
231
- v = v ? '是' : '否'
232
-
233
- return v
234
- }
235
- }
236
-
237
- const onEdit = (index) => {
238
- data.selectIndex = index
239
- data.inputValue = JSON.parse(JSON.stringify(modelValue.value[data.selectIndex]))
240
- data.isShowInput = true
241
- }
242
-
243
- const onNewOption = () => {
244
- let oldModelValue = JSON.parse(JSON.stringify(modelValue.value))
245
- modelValue.value = [...(modelValue.value || []), makeDefaultValue()]
246
- nextTick(() => {
247
- data.oldModelValue = oldModelValue
248
- onEdit(modelValue.value.length - 1)
249
- })
250
- }
251
-
252
- const onInputConfirm = () => {
253
- let idx = modelValue.value.indexOf(item => JSON.stringify(item) === JSON.stringify(data.inputValue))
254
- if (idx > -1 && idx != data.selectIndex) {
255
- util.warnToast('重复添加')
256
- return
257
- }
258
-
259
- if (!data.inputValue) {
260
- data.isShowInput = false
261
- data.inputValue = makeDefaultValue()
262
- data.selectIndex = -1
263
- modelValue.value = data.oldModelValue
264
- return
265
- }
266
-
267
- modelValue.value[data.selectIndex] = data.inputValue
268
-
269
- data.isShowInput = false
270
- data.inputValue = makeDefaultValue()
271
- data.selectIndex = -1
272
- }
273
-
274
- const onInputCancel = () => {
275
- data.isShowInput = false
276
- data.inputValue = makeDefaultValue()
277
- data.selectIndex = -1
278
- modelValue.value = data.oldModelValue
279
- }
280
-
281
- const onChangeOption = (key) => {
282
- console.log('onChangeOption', key, data.inputValue[key], props.schema[key]?.schema?.options)
283
- let val = data.inputValue[key]
284
- let options = props.schema[key].schema.options
285
-
286
- //用选中对象给输入项的同名属性值赋值
287
- let option = options.find(item => item[Object.keys(item)[1]] === val)
288
- Object.keys(option).forEach(k => {
289
- if (props.schema[k])
290
- data.inputValue[k] = option[k]
291
- })
292
- }
293
- </script>
294
-
295
- <style lang="scss" scoped>
296
- .widget {
297
- background: #fff;
298
- box-sizing: border-box;
299
- height: 100%;
300
- text-align: left;
301
- font-size: 12px;
302
- }
303
-
304
- .option {
305
- margin: 0 8px 8px 0;
306
- padding: 5px 10px;
307
- border-radius: 6px;
308
- border: 2px solid #e1e1e1;
309
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
310
- color: #666;
311
- display: inline-block;
312
- position: relative;
313
- }
314
-
315
- :deep(.van-field__label) {
316
- margin: auto;
317
-
318
- }
319
-
320
- :deep(.van-cell) {
321
- font-size: 12px;
322
- padding: 5px 5px;
323
-
324
- }
325
-
326
- :deep(.van-icon) {
327
- font-size: 12px;
328
- }
329
-
330
- :deep(.van-popup) {
331
- .van-cell {
332
- padding: 5px 25px;
333
- }
334
- }
1
+ <template>
2
+ <van-field :label="props.label" v-if="!isGone" :disabled="isDisabled" :required="isRequired"
3
+ :placeholder="props.placeholder">
4
+ <template #input>
5
+ <div class="widget-box">
6
+ <div class="option" v-for="(item, index) in modelValue" :key="index">
7
+ <div v-if="index != data.selectIndex" style=" display: flex;align-items: center;">
8
+ <van-icon name="arrow-left" @click.stop="onForward(index)" />
9
+ <div style="padding: 5px 5px;">
10
+ <div v-for="(k, j) in visiableKeys" :key="j" style="padding:2px 2px;font-size: 12px;">
11
+ <div v-if="props.schema[k].type != 'Images'">
12
+ {{ `${key2name(k)}:${key2value(k, item)}` }}
13
+ </div>
14
+ <div v-else>
15
+ <ImagesPicker v-model="item[k]" readonly />
16
+ </div>
17
+ </div>
18
+ </div>
19
+
20
+ <div style="display: flex;flex-direction:column;cursor: pointer;">
21
+ <van-icon name="edit"
22
+ v-if="props.schema.auth != 'readonly' && props.auth != 'readonly' && props.auth != 'disabled'"
23
+ @click.stop="onEdit(index)" />
24
+
25
+ <van-icon name="arrow" @click.stop="onBack(index)" style="margin:8px 0" />
26
+
27
+ <van-icon name="cross"
28
+ v-if="props.schema.auth != 'readonly' && props.auth != 'readonly' && props.auth != 'disabled'"
29
+ @click.stop="onDelete(index)" />
30
+ </div>
31
+ </div>
32
+
33
+ <van-form v-if="data.isShowInput && index == data.selectIndex" :model="data.inputValue">
34
+ <van-field v-for="(key, i) in keys" :key="i" :label="props.schema[key].label"
35
+ v-show="props.schema[key].auth != 'gone'" :required="props.schema[key].auth === 'required'"
36
+ :disabled="props.schema[key].auth === 'readonly'">
37
+
38
+ <template #input>
39
+ <van-field
40
+ v-if="props.schema[key].type == 'String' && !props.schema[key]?.schema?.options"
41
+ :disabled="props.schema[key].auth === 'readonly'" v-model="data.inputValue[key]"
42
+ :placeholder="`请输入${key2name(key)}`" type="text" />
43
+
44
+ <van-field
45
+ v-if="props.schema[key].type == 'Number' && !props.schema[key]?.schema?.options"
46
+ :disabled="props.schema[key].auth === 'readonly'"
47
+ v-model.number="data.inputValue[key]" :placeholder="`请输入${key2name(key)}`"
48
+ type="number" />
49
+
50
+ <van-switch v-if="props.schema[key].type == 'Boolean'"
51
+ :disabled="props.schema[key].auth === 'readonly'" v-model="data.inputValue[key]" />
52
+
53
+ <DatetimePicker v-if="props.schema[key].type == 'Datetime'"
54
+ :auth="props.schema[key].auth" v-model="data.inputValue[key]" placeholder="选择时间" />
55
+
56
+ <ImagesPicker v-if="props.schema[key].type == 'Images'" :auth="props.schema[key].auth"
57
+ v-model="data.inputValue[key]" />
58
+
59
+ <DateSelector v-if="props.schema[key]?.schema?.options" v-model="data.inputValue[key]"
60
+ :auth="props.schema[key].auth" :options="props.schema[key]?.schema?.options"
61
+ :placeholder="`请输入${key2name(key)}`" :columnsFieldNames="{
62
+ text: (props.schema[key]?.schema?.options || []).length > 0 ? Object.keys(props.schema[key].schema.options[0])[0] : '',
63
+ value: (props.schema[key]?.schema?.options || []).length > 0 ? Object.keys(props.schema[key].schema.options[0])[1] : ''
64
+ }" @select="onChangeOption(key)" />
65
+
66
+ <ObjsEditor v-if="props.schema[key].type == 'Array' && props.schema[key].auth != 'gone'"
67
+ :auth="props.schema[key].auth" v-model="data.inputValue[key]"
68
+ :schema="props.schema[key].schema" />
69
+ </template>
70
+ </van-field>
71
+
72
+ <div style="margin: 16px; display: flex;align-items: center;justify-content: center;">
73
+ <van-button v-if="data.isShowInput" @click="onInputConfirm" size="mini">保存</van-button>
74
+ <van-button v-if="data.isShowInput" @click="onInputCancel" size="mini">取消</van-button>
75
+ </div>
76
+ </van-form>
77
+ </div>
78
+
79
+ <van-icon name="plus" v-if="!data.isShowInput && props.auth != 'readonly' && props.auth != 'disabled'"
80
+ @click="onNewOption" />
81
+ </div>
82
+ </template>
83
+ </van-field>
84
+ </template>
85
+
86
+ <script setup>
87
+ import { nextTick, ref, onMounted, defineProps, defineEmits, reactive, computed, watch } from 'vue'
88
+ import { useVModel } from '@vueuse/core'
89
+ import util from '@/util'
90
+ import DatetimePicker from './DatetimePicker.vue'
91
+ import DateSelector from './data_selector.vue'
92
+ import ImagesPicker from './images_picker.vue'
93
+
94
+ const props = defineProps({
95
+ modelValue: {
96
+ type: Array,
97
+ default: []
98
+ },
99
+ label: {
100
+ type: String,
101
+ default: ''
102
+ },
103
+ placeholder: {
104
+ type: String,
105
+ default: ''
106
+ },
107
+ readonly: {
108
+ type: Boolean,
109
+ default: true
110
+ },
111
+ required: {
112
+ type: Boolean,
113
+ default: false
114
+ },
115
+ auth: {
116
+ type: String,
117
+ default: 'option'
118
+ },
119
+ schema: {
120
+ type: Object,
121
+ default: {
122
+ type: "String",
123
+ label: '名称',
124
+ default: '',
125
+ //权限取值范围: required 必填 option 选填 readonly 只读 gone 隐藏
126
+ auth: 'option'
127
+ }
128
+ }
129
+ })
130
+
131
+ const emit = defineEmits(['update:modelValue'])
132
+ const modelValue = useVModel(props, 'modelValue', emit)
133
+ const { isRequired, isReadonly, isGone, isDisabled } = util.props2auth(props)
134
+
135
+ const data = reactive({
136
+ inputValue: {},
137
+ isShowInput: false,
138
+ selectIndex: -1,
139
+ oldModelValue: []
140
+ })
141
+ const keys = Object.keys(props.schema)
142
+ const visiableKeys = keys.filter(k => props.schema[k].auth != 'gone')
143
+
144
+ watch(() => JSON.stringify(modelValue.value), (n, o) => {
145
+ if (!modelValue.value)
146
+ modelValue.value = []
147
+
148
+ data.oldModelValue = JSON.parse(JSON.stringify(modelValue.value))
149
+ }, {
150
+ immediate: true
151
+ }, {
152
+ deep: true
153
+ })
154
+
155
+ onMounted(() => {
156
+ })
157
+
158
+ const makeDefaultValue = () => {
159
+ let res = {}
160
+
161
+ keys.forEach(key => {
162
+ // 复制默认值,防止对象类型的默认值被修改
163
+ if (props.schema[key].default === 'uuid')
164
+ res[key] = util.uuid8()
165
+ else
166
+ res[key] = JSON.parse(JSON.stringify(props.schema[key].default))
167
+ })
168
+
169
+ return res
170
+ }
171
+
172
+ const onForward = (index) => {
173
+ util.arySwapPrev(modelValue.value, index)
174
+ }
175
+
176
+ const onBack = (index) => {
177
+ util.arySwapNext(modelValue.value, index)
178
+ }
179
+
180
+ const onDelete = (index) => {
181
+ modelValue.value.splice(index, 1)
182
+ }
183
+
184
+ const key2name = (key) => {
185
+ return props.schema[key].label
186
+ }
187
+
188
+ const key2value = (key, item) => {
189
+ console.log('key2value', key, item[key], item)
190
+
191
+ let v = item[key]
192
+ if (props.schema[key].type === 'Images') {
193
+ return (v || []).join(',')
194
+ }
195
+ else if (Array.isArray(v)) {
196
+ let formatValues = v.map(e => {
197
+ let kvs = Object.keys(e).map(k => {
198
+ console.log(props.schema[key])
199
+ console.log(key)
200
+ console.log(v)
201
+ console.log(k)
202
+
203
+ let label = props.schema[key].schema[k].label
204
+ let formatValue = e[k]
205
+
206
+ //下拉框选项,用选项的第二个属性value找选中的选项
207
+ //再取选项的第一个属性name作为标题
208
+ if (props.schema[key].schema[k]?.schema?.options) {
209
+ let one = props.schema[key].schema[k]?.schema?.options.find(item => item[Object.keys(item)[1]] === formatValue)
210
+ if (one)
211
+ formatValue = one[Object.keys(one)[0]]
212
+ else
213
+ formatValue = ''
214
+ }
215
+
216
+ return `${label}:${formatValue}`
217
+ })
218
+ return kvs.join(',')
219
+ })
220
+
221
+ return formatValues.join(' > ')
222
+ }
223
+ //下拉框选项,用选项的第二个属性value找选中的选项
224
+ //再取选项的第一个属性name作为标题
225
+ else if (props.schema[key]?.schema?.options) {
226
+ let one = props.schema[key]?.schema?.options.find(item => item[Object.keys(item)[1]] === v)
227
+ return one ? one[Object.keys(one)[0]] : ''
228
+ }
229
+ else {
230
+ if (props.schema[key].type === 'Boolean')
231
+ v = v ? '是' : '否'
232
+
233
+ return v
234
+ }
235
+ }
236
+
237
+ const onEdit = (index) => {
238
+ data.selectIndex = index
239
+ data.inputValue = JSON.parse(JSON.stringify(modelValue.value[data.selectIndex]))
240
+ data.isShowInput = true
241
+ }
242
+
243
+ const onNewOption = () => {
244
+ let oldModelValue = JSON.parse(JSON.stringify(modelValue.value))
245
+ modelValue.value = [...(modelValue.value || []), makeDefaultValue()]
246
+ nextTick(() => {
247
+ data.oldModelValue = oldModelValue
248
+ onEdit(modelValue.value.length - 1)
249
+ })
250
+ }
251
+
252
+ const onInputConfirm = () => {
253
+ let idx = modelValue.value.indexOf(item => JSON.stringify(item) === JSON.stringify(data.inputValue))
254
+ if (idx > -1 && idx != data.selectIndex) {
255
+ util.warnToast('重复添加')
256
+ return
257
+ }
258
+
259
+ if (!data.inputValue) {
260
+ data.isShowInput = false
261
+ data.inputValue = makeDefaultValue()
262
+ data.selectIndex = -1
263
+ modelValue.value = data.oldModelValue
264
+ return
265
+ }
266
+
267
+ modelValue.value[data.selectIndex] = data.inputValue
268
+
269
+ data.isShowInput = false
270
+ data.inputValue = makeDefaultValue()
271
+ data.selectIndex = -1
272
+ }
273
+
274
+ const onInputCancel = () => {
275
+ data.isShowInput = false
276
+ data.inputValue = makeDefaultValue()
277
+ data.selectIndex = -1
278
+ modelValue.value = data.oldModelValue
279
+ }
280
+
281
+ const onChangeOption = (key) => {
282
+ console.log('onChangeOption', key, data.inputValue[key], props.schema[key]?.schema?.options)
283
+ let val = data.inputValue[key]
284
+ let options = props.schema[key].schema.options
285
+
286
+ //用选中对象给输入项的同名属性值赋值
287
+ let option = options.find(item => item[Object.keys(item)[1]] === val)
288
+ Object.keys(option).forEach(k => {
289
+ if (props.schema[k])
290
+ data.inputValue[k] = option[k]
291
+ })
292
+ }
293
+ </script>
294
+
295
+ <style lang="scss" scoped>
296
+ .widget {
297
+ background: #fff;
298
+ box-sizing: border-box;
299
+ height: 100%;
300
+ text-align: left;
301
+ font-size: 12px;
302
+ }
303
+
304
+ .option {
305
+ margin: 0 8px 8px 0;
306
+ padding: 5px 10px;
307
+ border-radius: 6px;
308
+ border: 2px solid #e1e1e1;
309
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
310
+ color: #666;
311
+ display: inline-block;
312
+ position: relative;
313
+ }
314
+
315
+ :deep(.van-field__label) {
316
+ margin: auto;
317
+
318
+ }
319
+
320
+ :deep(.van-cell) {
321
+ font-size: 12px;
322
+ padding: 5px 5px;
323
+
324
+ }
325
+
326
+ :deep(.van-icon) {
327
+ font-size: 12px;
328
+ }
329
+
330
+ :deep(.van-popup) {
331
+ .van-cell {
332
+ padding: 5px 25px;
333
+ }
334
+ }
335
335
  </style>