wui-components-v2 1.1.75 → 1.1.77

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.
@@ -32,6 +32,7 @@ const props = defineProps<{
32
32
  const toast = useGlobalToast()
33
33
  const message = useGlobalMessage()
34
34
  const pageType = ref('')
35
+ console.log(props, 'props')
35
36
  onLoad((option: any) => {
36
37
  pageType.value = option.type || ''
37
38
  })
@@ -40,13 +41,14 @@ const router = useRouter()
40
41
  // rowActions按钮
41
42
  const anctions = computed(() => {
42
43
  const rowActions = props.rowActions || []
44
+ console.log([...rowActions.filter(isShowAction)], 1111111111111111)
43
45
  return [...rowActions.filter(isShowAction)]
44
46
  })
45
47
 
46
48
  // raction按钮
47
49
  const ractions = computed(() => {
48
- const ractions = props.ractions || []
49
- return [...ractions.filter(isShowAction)]
50
+ const list = props.ractions || []
51
+ return list.filter(isShowAction)
50
52
  })
51
53
 
52
54
  // actions按钮
@@ -90,8 +92,7 @@ async function action(subitem: rowActions) {
90
92
  props.zpaging.reload()
91
93
  toast.success({ msg: '操作成功!' })
92
94
  } catch (error: any) {
93
- toast.error(error)
94
- console.log(error)
95
+ console.log(error, 1111111)
95
96
  }
96
97
  }
97
98
  }
@@ -222,14 +222,35 @@ const schema = computed((): FormSchema => {
222
222
  validate(_model: Record<string, any>): FormSchemaIssue[] {
223
223
  const issues: FormSchemaIssue[] = []
224
224
  props.fieldGroup?.fields.forEach((item: Fields) => {
225
+ const value = _model[item.sourceId]
226
+ // 必填校验
225
227
  if (item.required) {
226
- const value = _model[item.sourceId]
227
228
  if (Array.isArray(value) && value.length < 1) {
228
229
  issues.push({ path: [item.sourceId], message: `请填写${item.title}` })
229
230
  } else if (!value) {
230
231
  issues.push({ path: [item.sourceId], message: `请填写${item.title}` })
231
232
  }
232
233
  }
234
+ // 自定义规则校验(item.rules: { message, pattern })
235
+ if (item.rules) {
236
+ const ruleList = Array.isArray(item.rules) ? item.rules : [item.rules]
237
+ const val = Array.isArray(value) ? value.join(',') : value
238
+ // 空值交给 required 处理,避免重复报错
239
+ if (val !== undefined && val !== null && val !== '') {
240
+ for (const rule of ruleList) {
241
+ if (rule.pattern) {
242
+ const pattern = typeof rule.pattern === 'string' ? new RegExp(rule.pattern) : rule.pattern
243
+ if (!pattern.test(String(val))) {
244
+ issues.push({
245
+ path: [item.sourceId],
246
+ message: rule.message || `${item.title}格式不正确`,
247
+ })
248
+ break
249
+ }
250
+ }
251
+ }
252
+ }
253
+ }
233
254
  })
234
255
  return issues
235
256
  },
@@ -118,7 +118,7 @@ function handleSubmit() {
118
118
  top: 5px;
119
119
  bottom: 5px;
120
120
  }
121
- ::deep(.icon-arrow) {
121
+ :deep(.icon-arrow) {
122
122
  display: inline-block;
123
123
  font-size: 20px;
124
124
  vertical-align: middle;
@@ -3,11 +3,13 @@ import { computed, defineOptions, onBeforeMount, onUnmounted, ref, toRaw } from
3
3
  import { onLoad } from '@dcloudio/uni-app'
4
4
  import { useRouter } from 'uni-mini-router'
5
5
  import FormControl from '../form-control/form-control.vue'
6
- import { addPageConfig, editPageConfig, editPageDataSave, enums, selectDatas } from '../../api/page'
7
- import type { Entities, Enums, Groups, dtmplConfig } from '../../type'
6
+ import { addPageConfig, editPageConfig, editPageDataSave, enums, selectDatas, actionDataSave } from '../../api/page'
7
+ import type { Entities, Enums, Groups, dtmplConfig, rowActions, Fields } from '../../type'
8
8
  import { useGlobalToast } from '../../composables/useGlobalToast'
9
+ import { useGlobalMessage } from '../../composables/useGlobalMessage'
9
10
  import foldCard from '../fold-card/fold-card.vue'
10
- import { generateHighResolutionID } from '../../utils/index'
11
+ import ActionPopup from '../action-popup/action-popup.vue'
12
+ import { generateHighResolutionID, comparator } from '../../utils/index'
11
13
  import TreeSelectControl from '../tree-select/index.vue'
12
14
  import batchUploadFile from '../batch-upload-file/batch-upload-file.vue'
13
15
 
@@ -28,11 +30,13 @@ const pageConfig = ref<dtmplConfig>({
28
30
  fieldMap: {},
29
31
  },
30
32
  buttons: [],
33
+ action: [],
31
34
  smartPaste: false,
32
35
  })
33
36
  const tree = ref({ value: '', sourceId: '' })
34
37
  const loading = ref(false)
35
38
  const globalToast = useGlobalToast()
39
+ const message = useGlobalMessage()
36
40
  const router = useRouter()
37
41
  const mainCode = ref('')
38
42
  const id = ref('')
@@ -42,7 +46,7 @@ const subLoading = ref(false)
42
46
  const Enumcolumn = ref<Enums | undefined>()
43
47
  const pageTitle = ref('')
44
48
  const pageType = ref('')
45
- const selectData = ref<{ [key: string]: { loading: boolean, data: string[] } }>({})
49
+ const selectData = ref<{ [key: string]: { loading: boolean; data: string[] } }>({})
46
50
  const rowData = ref<{ [key: string]: { [key: string]: any } }>({})
47
51
  const action = ref('')
48
52
  const hydrocarbonProgramToken = ref('')
@@ -54,7 +58,7 @@ const addEvent = ref('')
54
58
  const editEvent = ref('')
55
59
  const rowAddEvent = ref('')
56
60
  const sendRowAddEvent = ref('')
57
- const smartPaste=ref(false)
61
+ const smartPaste = ref(false)
58
62
  // 折叠面板
59
63
  const collapses = ref('')
60
64
  const groupsformat = computed(() => {
@@ -62,9 +66,26 @@ const groupsformat = computed(() => {
62
66
  return item.displayConfig.includes('displayed')
63
67
  })
64
68
  })
65
- const canSmartPaste=computed(()=>{
66
- return pageConfig.value?.smartPaste??false
69
+ const canSmartPaste = computed(() => {
70
+ return pageConfig.value?.smartPaste ?? false
67
71
  })
72
+ // 保存按钮旁的动态操作按钮(循环展示);兼容后端返回的 action / actions 字段名
73
+ const pageActions = computed(() => {
74
+ const cfg = pageConfig.value as dtmplConfig & { actions?: rowActions[] }
75
+ return cfg.action || cfg.actions || []
76
+ })
77
+
78
+ // 参考 card-botom-buttons 的 isShowAction:根据前置条件(preposes)判断动态按钮是否禁用
79
+ function isActionDisabled(item: rowActions): boolean {
80
+ const fieldMap = (pageConfig.value.entity && pageConfig.value.entity.fieldMap) || {}
81
+ if (item.preposes && item.preposes.length > 0) {
82
+ return !item.preposes.every((prepose: Fields) => {
83
+ return comparator(prepose.comparator || 'equal', fieldMap[prepose.sourceId], prepose.defaultValue)
84
+ })
85
+ }
86
+ return false
87
+ }
88
+ console.log(pageActions.value, 'pageActions.value')
68
89
  onLoad((option: any) => {
69
90
  sourceId.value = option.sourceId
70
91
  mainCode.value = option.mainCode || ''
@@ -108,6 +129,7 @@ async function getEditPageConfig() {
108
129
  fieldMap: {},
109
130
  },
110
131
  buttons: [],
132
+ action: [],
111
133
  }
112
134
  getEnums()
113
135
  uni.$off(sendRowAddEvent.value)
@@ -125,44 +147,50 @@ async function getEditPageConfig() {
125
147
  loading.value = true
126
148
  if (id.value) {
127
149
  res = await editPageConfig(sourceId.value, id.value)
128
- }
129
- else {
150
+ } else {
130
151
  res = await addPageConfig(sourceId.value)
152
+ console.log(res, 'res')
131
153
  }
132
154
  loading.value = false
133
155
  // 初始化折叠面板
134
- if (res.dtmplConfig) {
135
- uni.setNavigationBarTitle({
136
- title: `${res.dtmplConfig.title}`,
137
- })
138
- pageConfig.value = res.dtmplConfig
139
- const visibleGroups = pageConfig.value.groups.filter((item: Groups) => item.displayConfig.includes('displayed'))
140
- collapses.value = visibleGroups.length > 0 ? visibleGroups[0].id : ''
156
+ if (res.dtmplConfig) {
157
+ uni.setNavigationBarTitle({
158
+ title: `${res.dtmplConfig.title}`,
159
+ })
160
+ pageConfig.value = res.dtmplConfig
161
+ const visibleGroups = pageConfig.value.groups.filter((item: Groups) => item.displayConfig.includes('displayed'))
162
+ collapses.value = visibleGroups.length > 0 ? visibleGroups[0].id : ''
141
163
 
142
164
  pageConfig.value.groups.forEach((item: Groups) => {
143
165
  // 初始化勾选数据
144
166
  if (item.type === 'relation' && (item.buttons.includes('dtmplAdd') || item.buttons.includes('selectAdd'))) {
145
167
  selectData.value[item.id] = {
146
- data: (pageConfig.value.entity && pageConfig.value.entity.arrayMap[item.id]?.map((sebitem: any) => {
147
- return `${sebitem.code}`
148
- })) || [],
168
+ data:
169
+ (pageConfig.value.entity &&
170
+ pageConfig.value.entity.arrayMap[item.id]?.map((sebitem: any) => {
171
+ return `${sebitem.code}`
172
+ })) ||
173
+ [],
149
174
  loading: false,
150
175
  }
151
176
  }
152
177
  // 初始化行数据
153
178
  if (item.type === 'relation' && item.buttons.includes('rowAdd')) {
154
- rowData.value[item.id] = (pageConfig.value.entity && pageConfig.value.entity.arrayMap[item.id]?.map((sebitem: any) => {
155
- return {
156
- id: sebitem.code,
157
- ...sebitem.fieldMap,
158
- }
159
- })) || []
179
+ rowData.value[item.id] =
180
+ (pageConfig.value.entity &&
181
+ pageConfig.value.entity.arrayMap[item.id]?.map((sebitem: any) => {
182
+ return {
183
+ id: sebitem.code,
184
+ ...sebitem.fieldMap,
185
+ }
186
+ })) ||
187
+ []
160
188
  }
161
189
  })
162
190
  getEnums()
191
+ console.log(pageConfig.value, 'pageConfig.value')
163
192
  }
164
- }
165
- catch (error) {
193
+ } catch (error) {
166
194
  loading.value = false
167
195
  console.log('error:', error)
168
196
  }
@@ -178,12 +206,10 @@ async function getEnums() {
178
206
  }
179
207
  })
180
208
  })
181
- if (!params.length)
182
- return
209
+ if (!params.length) return
183
210
  const res = await enums(params.join('&'))
184
211
  Enumcolumn.value = res.enumMap || {}
185
- }
186
- catch (error) {
212
+ } catch (error) {
187
213
  console.log('error:', error)
188
214
  }
189
215
  }
@@ -195,130 +221,210 @@ async function rowAddSave(all: any) {
195
221
  uni.$emit(rowAddEvent.value, all)
196
222
  }
197
223
 
198
- // 保存
199
- async function save() {
224
+ // 保存数据并返回保存后的实体编码;行添加场景会在内部直接处理跳转
225
+ async function saveData(): Promise<{ entityCode: string; data: Record<string, any> }> {
200
226
  // 判断是否为树添加
201
227
  if (pageType.value === '树' && !tree.value.value) {
202
- return globalToast.warning('请选择分组')
228
+ globalToast.warning('请选择分组')
229
+ throw new Error('请选择分组')
203
230
  }
204
231
 
205
- try {
206
- const formArray: any[] = []
207
- formControlRef.value.forEach((element: any) => {
208
- formArray.push(element.submit())
209
- })
210
- const res = await Promise.all(formArray)
211
- const beasData = res.reduce((acc, cur) => {
212
- return { ...acc, ...cur }
213
- }, {})
214
- subLoading.value = true
215
-
216
- /**
217
- *
218
- * 421639572264099847.$$flag$$:true
219
- 421639572264099847[0].$$relation$$:拥有角色
220
- 421639572264099847[0].唯一编码:448591711817211909
221
- */
222
- let all: Record<string, any> = {}
223
- for (const key in selectData.value) {
224
- if (Object.prototype.hasOwnProperty.call(selectData.value, key)) {
225
- const element = selectData.value[key].data
226
- if (element) {
227
- all[`${key}.$$flag$$`] = true
228
- element.forEach((item, index) => {
229
- all[`${key}[${index}].$$relation$$`] = pageConfig.value.groups.find(item => item.id === key)?.relationNames[0]
230
- if (typeof item === 'string') {
231
- all[`${key}[${index}].唯一编码`] = item.split('@R@')[0]
232
- }
233
- })
234
- }
232
+ const formArray: any[] = []
233
+ formControlRef.value.forEach((element: any) => {
234
+ formArray.push(element.submit())
235
+ })
236
+ const res = await Promise.all(formArray)
237
+ const beasData = res.reduce((acc, cur) => {
238
+ return { ...acc, ...cur }
239
+ }, {})
240
+ subLoading.value = true
241
+
242
+ /**
243
+ *
244
+ * 421639572264099847.$$flag$$:true
245
+ 421639572264099847[0].$$relation$$:拥有角色
246
+ 421639572264099847[0].唯一编码:448591711817211909
247
+ */
248
+ let all: Record<string, any> = {}
249
+ for (const key in selectData.value) {
250
+ if (Object.prototype.hasOwnProperty.call(selectData.value, key)) {
251
+ const element = selectData.value[key].data
252
+ if (element) {
253
+ all[`${key}.$$flag$$`] = true
254
+ element.forEach((item, index) => {
255
+ all[`${key}[${index}].$$relation$$`] = pageConfig.value.groups.find(item => item.id === key)?.relationNames[0]
256
+ if (typeof item === 'string') {
257
+ all[`${key}[${index}].唯一编码`] = item.split('@R@')[0]
258
+ }
259
+ })
235
260
  }
236
261
  }
237
- console.log('rowData.value', rowData.value)
238
- for (const key in rowData.value) {
239
- if (Object.prototype.hasOwnProperty.call(rowData.value, key)) {
240
- const element1 = rowData.value[key]
241
- if (element1) {
242
- all[`${key}.$$flag$$`] = true
243
- element1.forEach((item: any, index: any) => {
244
- all[`${key}[${index}].$$relation$$`] = pageConfig.value.groups.find(item => item.id === key)?.relationNames[0]
245
- all[`${key}[${index}].唯一编码`] = item.id
246
-
247
- for (const key1 in item) {
248
- if (Object.prototype.hasOwnProperty.call(item, key1)) {
249
- console.log('item[key1]', item[key1])
250
- if (item[key1] && item[key1].response) {
251
- all[`${key}[${index}].${key1}`] = JSON.stringify({
252
- valid: item[key1].disabled ? 'old' : 'new',
253
- fileKey: JSON.parse(item[key1].response).fileKey,
254
- fileName: item[key1].name,
255
- })
256
- }
262
+ }
263
+ console.log('rowData.value', rowData.value)
264
+ for (const key in rowData.value) {
265
+ if (Object.prototype.hasOwnProperty.call(rowData.value, key)) {
266
+ const element1 = rowData.value[key]
267
+ if (element1) {
268
+ all[`${key}.$$flag$$`] = true
269
+ element1.forEach((item: any, index: any) => {
270
+ all[`${key}[${index}].$$relation$$`] = pageConfig.value.groups.find(item => item.id === key)?.relationNames[0]
271
+ all[`${key}[${index}].唯一编码`] = item.id
272
+
273
+ for (const key1 in item) {
274
+ if (Object.prototype.hasOwnProperty.call(item, key1)) {
275
+ console.log('item[key1]', item[key1])
276
+ if (item[key1] && item[key1].response) {
277
+ all[`${key}[${index}].${key1}`] = JSON.stringify({
278
+ valid: item[key1].disabled ? 'old' : 'new',
279
+ fileKey: JSON.parse(item[key1].response).fileKey,
280
+ fileName: item[key1].name,
281
+ })
282
+ }
257
283
 
258
- if (typeof item[key1] === 'string') {
259
- // all[`${key}[${index}].${key1}`] = item[key1].split('@R@')[0]
260
- all[`${key}[${index}].${key1}`] = item[key1]
261
- }
284
+ if (typeof item[key1] === 'string') {
285
+ // all[`${key}[${index}].${key1}`] = item[key1].split('@R@')[0]
286
+ all[`${key}[${index}].${key1}`] = item[key1]
262
287
  }
263
288
  }
264
- })
265
- }
289
+ }
290
+ })
266
291
  }
267
292
  }
268
- console.log('all', all, beasData)
269
- all = {
270
- ...all,
271
- ...beasData,
272
- }
293
+ }
294
+ console.log('all', all, beasData)
295
+ all = {
296
+ ...all,
297
+ ...beasData,
298
+ }
273
299
 
274
- // 判断是否为行添加
275
- if (rowAddEvent.value) {
276
- subLoading.value = false
277
- return rowAddSave({ ...all, id: pageConfig.value.entity.code })
278
- }
300
+ // 判断是否为行添加
301
+ if (rowAddEvent.value) {
302
+ subLoading.value = false
303
+ rowAddSave({ ...all, id: pageConfig.value.entity.code })
304
+ return { entityCode: pageConfig.value.entity.code, data: all }
305
+ }
279
306
 
280
- const newAll: Record<string, any> = {}
307
+ const newAll: Record<string, any> = {}
281
308
 
282
- for (const key1 in all) {
283
- if (Object.prototype.hasOwnProperty.call(all, key1)) {
284
- if (all[key1] && all[key1].response) {
285
- newAll[`${key1}`] = JSON.stringify({
286
- valid: all[key1].disabled ? 'old' : 'new',
287
- fileKey: JSON.parse(all[key1].response).fileKey,
288
- fileName: all[key1].name,
289
- })
290
- }
291
- else {
292
- newAll[key1] = all[key1]
293
- }
309
+ for (const key1 in all) {
310
+ if (Object.prototype.hasOwnProperty.call(all, key1)) {
311
+ if (all[key1] && all[key1].response) {
312
+ newAll[`${key1}`] = JSON.stringify({
313
+ valid: all[key1].disabled ? 'old' : 'new',
314
+ fileKey: JSON.parse(all[key1].response).fileKey,
315
+ fileName: all[key1].name,
316
+ })
317
+ } else {
318
+ newAll[key1] = all[key1]
294
319
  }
295
320
  }
321
+ }
322
+
323
+ const saveRes: any = await editPageDataSave(
324
+ tree.value.sourceId || sourceId.value,
325
+ id.value,
326
+ newAll,
327
+ tree.value.value || mainCode.value
328
+ )
329
+ return { entityCode: saveRes.entityCode, data: newAll }
330
+ }
331
+
332
+ // 保存
333
+ async function save() {
334
+ try {
335
+ const { entityCode, data } = await saveData()
336
+ // 行添加场景已在 saveData 内完成跳转
337
+ if (rowAddEvent.value) return
338
+ // 发送事件
339
+ if (addEvent.value) uni.$emit(addEvent.value, { entityCode, data })
340
+ if (editEvent.value) uni.$emit(editEvent.value, entityCode)
341
+
342
+ // ★ 通知 wui-select-popup 刷新列表数据
343
+ uni.$emit('selectPopup:refresh', sourceId.value)
344
+
345
+ subLoading.value = false
346
+ router.back()
347
+ } catch (error) {
348
+ subLoading.value = false
349
+ console.log('error:', error)
350
+ }
351
+ }
352
+
353
+ // 底部动态操作按钮(保存旁)相关数据
354
+ const actionItem = ref<Groups>()
355
+ const actionItemShow = ref(false)
356
+ const actionCode = ref('')
357
+ // ActionPopup 成功后的刷新处理(编辑页无 zpaging,直接返回上一页)
358
+ const actionZpaging = { reload: () => router.back() }
359
+
360
+ // 执行底部动态操作按钮:直接走 action 接口(不提交表单)
361
+ async function executeAction(subitem: rowActions) {
362
+ if (subLoading.value) return
363
+ // 行添加场景无已保存实体,无法执行 action
364
+ if (rowAddEvent.value) {
365
+ globalToast.warning('请先保存后再操作')
366
+ return
367
+ }
368
+ // action 需要已保存实体的编码(编辑场景为 id)
369
+ const code = id.value
370
+ if (!code) {
371
+ globalToast.warning('请先保存后再操作')
372
+ return
373
+ }
374
+ actionCode.value = code
375
+ runAction(subitem)
376
+ }
296
377
 
297
- editPageDataSave(tree.value.sourceId || sourceId.value, id.value, newAll, tree.value.value || mainCode.value).then((res: any) => {
298
- // 发送事件
299
- if (addEvent.value)
300
- uni.$emit(addEvent.value, { entityCode: res.entityCode, data: newAll })
301
- if (editEvent.value)
302
- uni.$emit(editEvent.value, res.entityCode)
303
-
304
- // ★ 通知 wui-select-popup 刷新列表数据
305
- uni.$emit('selectPopup:refresh', sourceId.value)
306
-
307
- subLoading.value = false
308
- router.back()
309
- }).catch((error: any) => {
310
- subLoading.value = false
311
- globalToast.error(error.message)
378
+ // 执行 action:带二次确认则先确认,再提交
379
+ function runAction(subitem: rowActions) {
380
+ if (subitem.beforeExeConfirm) {
381
+ message.confirm({
382
+ msg: subitem.beforeExeConfirm,
383
+ title: '提示',
384
+ success: () => doAction(subitem),
312
385
  })
386
+ return
313
387
  }
314
- catch (error) {
315
- console.log('error:', error)
388
+ doAction(subitem)
389
+ }
390
+
391
+ // 提交 action:含写入项则弹窗录入,否则直接调用 action 接口
392
+ async function doAction(subitem: rowActions) {
393
+ if (subitem.writes && subitem.writes.length) {
394
+ actionItem.value = {
395
+ id: subitem.id,
396
+ title: subitem.title,
397
+ type: '',
398
+ buttons: [],
399
+ fields: subitem.writes,
400
+ pointSourceId: '',
401
+ mstrucId: '',
402
+ relationNames: [],
403
+ readOnly: false,
404
+ displayConfig: [],
405
+ }
406
+ actionItemShow.value = true
407
+ return
408
+ }
409
+ try {
410
+ subLoading.value = true
411
+ await actionDataSave(subitem.id, actionCode.value, {})
412
+ subLoading.value = false
413
+ globalToast.success({ msg: '操作成功!' })
414
+ // 通知列表/弹窗刷新
415
+ uni.$emit('selectPopup:refresh', sourceId.value)
416
+ router.back()
417
+ } catch (error: any) {
418
+ subLoading.value = false
419
+ globalToast.error(error)
316
420
  }
317
421
  }
318
422
 
319
423
  // 跳转勾选页面
320
424
  function gotoSlect(group: Groups) {
321
- router.push(`/pages/select-list/index?sourceId=${group.id}&title=${pageTitle.value}&selectEvent=${SELECTEVENT}&sendSelectEvent=${SENDSELECTEVENT}&extControlType=${''}&cardModel=complex`)
425
+ router.push(
426
+ `/pages/select-list/index?sourceId=${group.id}&title=${pageTitle.value}&selectEvent=${SELECTEVENT}&sendSelectEvent=${SENDSELECTEVENT}&extControlType=${''}&cardModel=complex`
427
+ )
322
428
  // 发送数据给选择页面,延迟发送防止页面不刷新
323
429
  setTimeout(() => {
324
430
  console.log('selectData:', selectData.value)
@@ -344,14 +450,12 @@ async function getSelectData(data: any, relationID: string) {
344
450
  const res = await selectDatas(relationID, codes)
345
451
  if (pageConfig.value.entity) {
346
452
  pageConfig.value.entity.arrayMap[relationID] = res.entities
347
- }
348
- else {
453
+ } else {
349
454
  pageConfig.value.entity = { arrayMap: { [relationID]: res.entities }, code: '', fieldMap: {} }
350
455
  }
351
456
 
352
457
  selectData.value[relationID].loading = false
353
- }
354
- catch (error) {
458
+ } catch (error) {
355
459
  console.log('error:', error)
356
460
  }
357
461
  }
@@ -361,10 +465,7 @@ async function getAddData(data: any, relationID: string) {
361
465
  addEvent.value = ''
362
466
  try {
363
467
  let codes = ''
364
- selectData.value[relationID].data = [
365
- ...data,
366
- ...selectData.value[relationID].data,
367
- ]
468
+ selectData.value[relationID].data = [...data, ...selectData.value[relationID].data]
368
469
  selectData.value[relationID].data.forEach((item: any) => {
369
470
  codes += `codes=${item}&`
370
471
  })
@@ -373,18 +474,15 @@ async function getAddData(data: any, relationID: string) {
373
474
  if (pageConfig.value.entity) {
374
475
  if (pageConfig.value.entity.arrayMap) {
375
476
  pageConfig.value.entity.arrayMap[relationID] = res.entities
376
- }
377
- else {
477
+ } else {
378
478
  pageConfig.value.entity.arrayMap = { [relationID]: res.entities }
379
479
  }
380
- }
381
- else {
480
+ } else {
382
481
  pageConfig.value.entity = { arrayMap: { [relationID]: res.entities }, code: '', fieldMap: {} }
383
482
  }
384
483
 
385
484
  selectData.value[relationID].loading = false
386
- }
387
- catch (error) {
485
+ } catch (error) {
388
486
  console.log('error:', error)
389
487
  }
390
488
  }
@@ -401,8 +499,7 @@ async function getEditData(data: any, relationID: string) {
401
499
  const res = await selectDatas(relationID, codes)
402
500
  pageConfig.value.entity.arrayMap[relationID] = res.entities
403
501
  selectData.value[relationID].loading = false
404
- }
405
- catch (error) {
502
+ } catch (error) {
406
503
  console.log('error:', error)
407
504
  }
408
505
  }
@@ -420,7 +517,9 @@ function gotoAdd(group: Groups) {
420
517
  // 跳转编辑页面
421
518
  function edit(group: Groups, field: Entities) {
422
519
  const editEvent = generateHighResolutionID()
423
- router.push(`/pages/edit-page/index?sourceId=${group.id}&id=${field.code}&title=${group.title}&editEvent=${editEvent}`)
520
+ router.push(
521
+ `/pages/edit-page/index?sourceId=${group.id}&id=${field.code}&title=${group.title}&editEvent=${editEvent}`
522
+ )
424
523
  // 接收编辑页面发送过来的数据
425
524
  uni.$once(editEvent, (data: any) => {
426
525
  uni.$off(editEvent)
@@ -432,7 +531,9 @@ function edit(group: Groups, field: Entities) {
432
531
  function gotoRowAdd(group: Groups) {
433
532
  const rowAddEvent = generateHighResolutionID()
434
533
  const sendRowAddEvent = generateHighResolutionID()
435
- router.push(`/pages/edit-page/index?sourceId=${group.id}&id=&title=${group.title}&rowAddEvent=${rowAddEvent}&sendRowAddEvent=${sendRowAddEvent}`)
534
+ router.push(
535
+ `/pages/edit-page/index?sourceId=${group.id}&id=&title=${group.title}&rowAddEvent=${rowAddEvent}&sendRowAddEvent=${sendRowAddEvent}`
536
+ )
436
537
  // 发送数据给行添加页面
437
538
  setTimeout(() => {
438
539
  // groups: conf.groups,
@@ -459,12 +560,13 @@ function gotoRowAdd(group: Groups) {
459
560
  ...newData,
460
561
  id,
461
562
  })
462
- }
463
- else {
464
- rowData.value[group.id] = [{
465
- ...newData,
466
- id,
467
- }]
563
+ } else {
564
+ rowData.value[group.id] = [
565
+ {
566
+ ...newData,
567
+ id,
568
+ },
569
+ ]
468
570
  }
469
571
 
470
572
  console.log(pageConfig.value.entity)
@@ -477,34 +579,36 @@ function gotoRowAdd(group: Groups) {
477
579
  ...data,
478
580
  },
479
581
  })
480
- }
481
- else {
582
+ } else {
482
583
  if (pageConfig.value.entity && pageConfig.value.entity.arrayMap) {
483
584
  pageConfig.value.entity = {
484
585
  arrayMap: {
485
586
  ...pageConfig.value.entity.arrayMap,
486
- [group.id]: [{
487
- arrayMap: {},
488
- code: id,
489
- fieldMap: {
490
- ...data,
587
+ [group.id]: [
588
+ {
589
+ arrayMap: {},
590
+ code: id,
591
+ fieldMap: {
592
+ ...data,
593
+ },
491
594
  },
492
- }],
595
+ ],
493
596
  },
494
597
  code: id,
495
598
  fieldMap: {},
496
599
  }
497
- }
498
- else {
600
+ } else {
499
601
  pageConfig.value.entity = {
500
602
  arrayMap: {
501
- [group.id]: [{
502
- arrayMap: {},
503
- code: id,
504
- fieldMap: {
505
- ...data,
603
+ [group.id]: [
604
+ {
605
+ arrayMap: {},
606
+ code: id,
607
+ fieldMap: {
608
+ ...data,
609
+ },
506
610
  },
507
- }],
611
+ ],
508
612
  },
509
613
  code: id,
510
614
  fieldMap: {},
@@ -521,7 +625,9 @@ function gotoRowAdd(group: Groups) {
521
625
  function rowEdit(group: Groups, field: Entities) {
522
626
  const rowAddEvent = generateHighResolutionID()
523
627
  const sendRowAddEvent = generateHighResolutionID()
524
- router.push(`/pages/edit-page/index?sourceId=${group.id}&id=&title=${group.title}&rowAddEvent=${rowAddEvent}&sendRowAddEvent=${sendRowAddEvent}`)
628
+ router.push(
629
+ `/pages/edit-page/index?sourceId=${group.id}&id=&title=${group.title}&rowAddEvent=${rowAddEvent}&sendRowAddEvent=${sendRowAddEvent}`
630
+ )
525
631
  // 发送数据给行编辑页面
526
632
  setTimeout(() => {
527
633
  // groups: conf.groups,
@@ -581,14 +687,16 @@ function rowEdit(group: Groups, field: Entities) {
581
687
  */
582
688
  function canClick(group: Groups) {
583
689
  if (group.max) {
584
- if (pageConfig.value.entity && pageConfig.value.entity.arrayMap[group.id] && pageConfig.value.entity.arrayMap[group.id].length >= group.max) {
690
+ if (
691
+ pageConfig.value.entity &&
692
+ pageConfig.value.entity.arrayMap[group.id] &&
693
+ pageConfig.value.entity.arrayMap[group.id].length >= group.max
694
+ ) {
585
695
  return true
586
- }
587
- else {
696
+ } else {
588
697
  return false
589
698
  }
590
- }
591
- else {
699
+ } else {
592
700
  return false
593
701
  }
594
702
  }
@@ -599,17 +707,23 @@ function canClick(group: Groups) {
599
707
  function remove(group: Groups, field: Entities) {
600
708
  // 行编辑数据
601
709
  if (rowData.value[group.id]) {
602
- rowData.value[group.id] = rowData.value[group.id].filter((item: any) => item.id !== (field.code || field.fieldMap.id))
710
+ rowData.value[group.id] = rowData.value[group.id].filter(
711
+ (item: any) => item.id !== (field.code || field.fieldMap.id)
712
+ )
603
713
  }
604
714
 
605
715
  // 显示数据
606
716
  if (pageConfig.value.entity.arrayMap[group.id]) {
607
- pageConfig.value.entity.arrayMap[group.id] = pageConfig.value.entity.arrayMap[group.id].filter((item: any) => (item.code || item.fieldMap.id) !== (field.code || field.fieldMap.id))
717
+ pageConfig.value.entity.arrayMap[group.id] = pageConfig.value.entity.arrayMap[group.id].filter(
718
+ (item: any) => (item.code || item.fieldMap.id) !== (field.code || field.fieldMap.id)
719
+ )
608
720
  }
609
721
 
610
722
  // 行选择数据
611
723
  if (selectData.value[group.id]) {
612
- selectData.value[group.id].data = selectData.value[group.id].data.filter((item: any) => item.split('@R@')[0] !== field.code)
724
+ selectData.value[group.id].data = selectData.value[group.id].data.filter(
725
+ (item: any) => item.split('@R@')[0] !== field.code
726
+ )
613
727
  }
614
728
 
615
729
  console.log(rowData.value[group.id], field, '删除行数据')
@@ -619,28 +733,26 @@ function remove(group: Groups, field: Entities) {
619
733
  */
620
734
  function handleFileChange(e: any, group: Groups) {
621
735
  console.log(e, group)
622
- const newData: { [key: string]: any } = {
736
+ const newData: { [key: string]: any } = {}
623
737
 
624
- }
625
-
626
- group.fields.forEach((item) => {
738
+ group.fields.forEach(item => {
627
739
  newData[item.sourceId] = ''
628
740
  })
629
741
  const id = generateHighResolutionID()
630
- if (group.batchAddFileField)
631
- newData[group.batchAddFileField?.sourceId] = e.file
742
+ if (group.batchAddFileField) newData[group.batchAddFileField?.sourceId] = e.file
632
743
 
633
744
  if (rowData.value[group.id]) {
634
745
  rowData.value[group.id].push({
635
746
  ...newData,
636
747
  id,
637
748
  })
638
- }
639
- else {
640
- rowData.value[group.id] = [{
641
- ...newData,
642
- id,
643
- }]
749
+ } else {
750
+ rowData.value[group.id] = [
751
+ {
752
+ ...newData,
753
+ id,
754
+ },
755
+ ]
644
756
  }
645
757
 
646
758
  // 显示数据
@@ -652,34 +764,36 @@ function handleFileChange(e: any, group: Groups) {
652
764
  ...newData,
653
765
  },
654
766
  })
655
- }
656
- else {
767
+ } else {
657
768
  if (pageConfig.value.entity && pageConfig.value.entity.arrayMap) {
658
769
  pageConfig.value.entity = {
659
770
  arrayMap: {
660
771
  ...pageConfig.value.entity.arrayMap,
661
- [group.id]: [{
662
- arrayMap: {},
663
- code: id,
664
- fieldMap: {
665
- ...newData,
772
+ [group.id]: [
773
+ {
774
+ arrayMap: {},
775
+ code: id,
776
+ fieldMap: {
777
+ ...newData,
778
+ },
666
779
  },
667
- }],
780
+ ],
668
781
  },
669
782
  code: id,
670
783
  fieldMap: {},
671
784
  }
672
- }
673
- else {
785
+ } else {
674
786
  pageConfig.value.entity = {
675
787
  arrayMap: {
676
- [group.id]: [{
677
- arrayMap: {},
678
- code: id,
679
- fieldMap: {
680
- ...newData,
788
+ [group.id]: [
789
+ {
790
+ arrayMap: {},
791
+ code: id,
792
+ fieldMap: {
793
+ ...newData,
794
+ },
681
795
  },
682
- }],
796
+ ],
683
797
  },
684
798
  code: id,
685
799
  fieldMap: {},
@@ -687,6 +801,7 @@ function handleFileChange(e: any, group: Groups) {
687
801
  }
688
802
  }
689
803
  }
804
+ console.log(pageConfig, 'props111')
690
805
  </script>
691
806
 
692
807
  <template>
@@ -697,15 +812,20 @@ function handleFileChange(e: any, group: Groups) {
697
812
  <view v-else>
698
813
  <wd-cell v-if="pageType === '树'" title="分组" title-width="100px">
699
814
  <TreeSelectControl
700
- v-model="tree" select-mode="single" :source-id="sourceId" title="分组"
701
- ext-control-type="relselect " :readonly="false" :clearable="false"
815
+ v-model="tree"
816
+ select-mode="single"
817
+ :source-id="sourceId"
818
+ title="分组"
819
+ ext-control-type="relselect "
820
+ :readonly="false"
821
+ :clearable="false"
702
822
  />
703
823
  </wd-cell>
704
824
  <wd-collapse v-model="collapses" accordion>
705
- <wd-collapse-item v-for="group in groupsformat" :key="group.id" :name="group.id">
825
+ <wd-collapse-item v-for="group in groupsformat" :key="group.id" :name="group.id">
706
826
  <template #title>
707
827
  <view class="flex items-center justify-between">
708
- <view class="flex-1 flex items-center justify-between pr-2">
828
+ <view class="flex-1 flex items-center justify-between pr-2">
709
829
  <view>{{ group.title }}</view>
710
830
  <view v-if="group.type === 'relation'">
711
831
  <view v-if="selectData[group.id]?.loading" class="flex justify-center p-3">
@@ -715,22 +835,35 @@ function handleFileChange(e: any, group: Groups) {
715
835
  <view v-if="!group.readOnly" class="w-upload flex justify-center gap-2">
716
836
  <batchUploadFile
717
837
  v-if="group.batchAddFileField && group.batchAddFileField.extControlType === 'file'"
718
- @handle-file-change="(e) => { handleFileChange(e, group) }"
838
+ @handle-file-change="
839
+ e => {
840
+ handleFileChange(e, group)
841
+ }
842
+ "
719
843
  />
720
844
  <wd-button
721
- v-if="group.buttons.includes('selectAdd')" :disabled="canClick(group)" type="info"
722
- size="small" @click.stop="gotoSlect(group)"
845
+ v-if="group.buttons.includes('selectAdd')"
846
+ :disabled="canClick(group)"
847
+ type="info"
848
+ size="small"
849
+ @click.stop="gotoSlect(group)"
723
850
  >
724
851
  选择
725
852
  </wd-button>
726
853
  <wd-button
727
- v-if="group.buttons.includes('dtmplAdd')" :disabled="canClick(group)" type="primary"
728
- size="small" @click.stop="gotoAdd(group)"
854
+ v-if="group.buttons.includes('dtmplAdd')"
855
+ :disabled="canClick(group)"
856
+ type="primary"
857
+ size="small"
858
+ @click.stop="gotoAdd(group)"
729
859
  >
730
860
  新增
731
861
  </wd-button>
732
862
  <wd-button
733
- v-if="group.buttons.includes('rowAdd')" :disabled="canClick(group)" type="primary" size="small"
863
+ v-if="group.buttons.includes('rowAdd')"
864
+ :disabled="canClick(group)"
865
+ type="primary"
866
+ size="small"
734
867
  @click.stop="gotoRowAdd(group)"
735
868
  >
736
869
  新增
@@ -744,8 +877,11 @@ function handleFileChange(e: any, group: Groups) {
744
877
  </template>
745
878
 
746
879
  <FormControl
747
- v-if="group.type === 'fieldGroup'" ref="formControlRef" :field-group="group"
748
- :entity="pageConfig?.entity?.fieldMap" :enum-column="Enumcolumn"
880
+ v-if="group.type === 'fieldGroup'"
881
+ ref="formControlRef"
882
+ :field-group="group"
883
+ :entity="pageConfig?.entity?.fieldMap"
884
+ :enum-column="Enumcolumn"
749
885
  :company-filter="props.companyFilter"
750
886
  :company-field-source-id="props.companyFieldSourceId"
751
887
  :smart-paste="canSmartPaste"
@@ -757,8 +893,13 @@ function handleFileChange(e: any, group: Groups) {
757
893
  <view v-else>
758
894
  <view v-for="(field, index) in pageConfig?.entity?.arrayMap[group.id]" :key="field.code">
759
895
  <foldCard
760
- :index="index" :enum-column="{}" :groups="group" :source-id="sourceId" :columns="group.fields"
761
- model="complex" :data="field"
896
+ :index="index"
897
+ :enum-column="{}"
898
+ :groups="group"
899
+ :source-id="sourceId"
900
+ :columns="group.fields"
901
+ model="complex"
902
+ :data="field"
762
903
  >
763
904
  <template v-if="!group.readOnly" #buttons>
764
905
  <wd-button v-if="group.buttons.includes('dtmplEdit')" size="small" @click="edit(group, field)">
@@ -768,7 +909,9 @@ function handleFileChange(e: any, group: Groups) {
768
909
  编辑
769
910
  </wd-button>
770
911
  <wd-button
771
- v-if="group.buttons.includes('singleDelete')" type="danger" size="small"
912
+ v-if="group.buttons.includes('singleDelete')"
913
+ type="danger"
914
+ size="small"
772
915
  @click="remove(group, field)"
773
916
  >
774
917
  删除
@@ -781,11 +924,29 @@ function handleFileChange(e: any, group: Groups) {
781
924
  </wd-collapse-item>
782
925
  </wd-collapse>
783
926
  <view class="h-12" />
784
- <view class="fixed bottom-0 left-0 right-0 box-border w-100% flex p-2 bg-white dark:bg-[var(--wot-dark-background)]">
785
- <wd-button class="flex-1" :loading="subLoading" @click="save">
786
- 保存
927
+ <view
928
+ class="fixed bottom-0 left-0 right-0 box-border w-100% flex gap-2 p-2 bg-white dark:bg-[var(--wot-dark-background)]"
929
+ >
930
+ <wd-button
931
+ v-for="subitem in pageActions"
932
+ :key="subitem.id"
933
+ class="flex-1"
934
+ :loading="subLoading"
935
+ :disabled="isActionDisabled(subitem)"
936
+ plain
937
+ @click="executeAction(subitem)"
938
+ >
939
+ {{ subitem.title }}
787
940
  </wd-button>
941
+ <wd-button class="flex-1" :loading="subLoading" @click="save">保存</wd-button>
788
942
  </view>
943
+ <ActionPopup
944
+ v-model:show="actionItemShow"
945
+ :enum-column="Enumcolumn"
946
+ :zpaging="actionZpaging"
947
+ :field-group="actionItem"
948
+ :code="actionCode"
949
+ />
789
950
  </view>
790
951
  </view>
791
952
  </template>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wui-components-v2",
3
- "version": "1.1.75",
3
+ "version": "1.1.77",
4
4
  "description": "wui 组件库",
5
5
  "author": "wgxshh",
6
6
  "license": "MIT",
package/type.ts CHANGED
@@ -74,6 +74,12 @@ export interface PageData {
74
74
  entities: Entities[]
75
75
  }
76
76
 
77
+ // 字段自定义校验规则(如 { message, pattern })
78
+ export interface FieldRule {
79
+ message?: string | null
80
+ pattern?: string | RegExp
81
+ }
82
+
77
83
  // 表单字段配置
78
84
  export interface Fields extends Columns {
79
85
  disabled: boolean
@@ -85,6 +91,7 @@ export interface Fields extends Columns {
85
91
  max?: string
86
92
  min?: string
87
93
  comparator?: Comparator
94
+ rules?: FieldRule | FieldRule[]
88
95
  }
89
96
 
90
97
  // 编辑按钮配置
@@ -125,6 +132,8 @@ export interface dtmplConfig {
125
132
  groups: Groups[]
126
133
  entity: Entity
127
134
  buttons: string[]
135
+ /** 底部动态操作按钮(保存旁),循环展示 */
136
+ action?: rowActions[]
128
137
  }
129
138
  // 枚举项
130
139
  export interface EnumItem {