af-mobile-client-vue3 1.2.22 → 1.2.23

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.
@@ -3,9 +3,9 @@ import type { FormInstance } from 'vant'
3
3
  import XFormItem from '@af-mobile-client-vue3/components/data/XFormItem/index.vue'
4
4
  import XOlMap from '@af-mobile-client-vue3/components/data/XOlMap/index.vue'
5
5
  import { formatDate } from '@af-mobile-client-vue3/hooks/useCommon'
6
- import { addOrModifyEntity, runLogic } from '@af-mobile-client-vue3/services/api/common'
7
- import { post } from '@af-mobile-client-vue3/services/restTools'
6
+ import { addOrModifyEntity, getConfigByName, runLogic } from '@af-mobile-client-vue3/services/api/common'
8
7
  import { useUserStore } from '@af-mobile-client-vue3/stores'
8
+
9
9
  import {
10
10
  showFailToast,
11
11
  showSuccessToast,
@@ -20,6 +20,10 @@ interface FormItem {
20
20
  isOnlyAddOrEdit?: boolean
21
21
  type?: string
22
22
  model?: string
23
+ name?: string
24
+ rule?: {
25
+ type: string
26
+ }
23
27
  }
24
28
 
25
29
  interface SilenceAddFormItem extends FormItem {
@@ -34,6 +38,13 @@ interface GroupFormItems {
34
38
  groupName?: string
35
39
  tableName?: string
36
40
  }
41
+
42
+ interface InitParams {
43
+ formItems?: GroupFormItems
44
+ formData?: object
45
+ getDataParams?: object
46
+ }
47
+
37
48
  const props = withDefaults(defineProps<{
38
49
  configName?: string
39
50
  groupFormItems?: GroupFormItems
@@ -43,6 +54,7 @@ const props = withDefaults(defineProps<{
43
54
  mode?: string
44
55
  submitButton?: boolean
45
56
  isHandleFormKey?: boolean
57
+ paramLogicNameParam?: any
46
58
  }>(), {
47
59
  configName: undefined,
48
60
  groupFormItems: null,
@@ -52,24 +64,28 @@ const props = withDefaults(defineProps<{
52
64
  mode: '查询',
53
65
  submitButton: true,
54
66
  isHandleFormKey: true,
67
+ paramLogicNameParam: undefined,
55
68
  })
69
+
56
70
  const emits = defineEmits(['onSubmit', 'xFormItemEmitFunc'])
57
71
  const userStore = useUserStore()
72
+
73
+ // 核心状态
58
74
  const xFormRef = ref<FormInstance>()
59
- const myFormItems = ref<FormItem[]>([])
60
- const rules = reactive({})
75
+ const loaded = ref(false)
61
76
  const form = ref({})
62
- const formGroupName = ref<string | null>(null)
77
+ const rules = reactive({})
78
+ const myGetDataParams = ref({})
79
+
80
+ // 配置相关状态
81
+ const formConfig = ref<GroupFormItems | null>(null)
82
+ const formGroupName = ref<string>('default')
63
83
  const myServiceName = ref('')
64
- const loaded = ref(false)
65
- let myGetDataParams = reactive({})
66
84
  const tableName = ref('')
67
85
 
68
- const internalFormConfig = ref<GroupFormItems | null>(null)
69
- const internalSubmitButton = ref<boolean | undefined>(undefined)
70
-
86
+ // 计算属性
71
87
  const realJsonData = computed(() => {
72
- const sourceFormItems = internalFormConfig.value?.formJson || props.groupFormItems?.formJson
88
+ const sourceFormItems = formConfig.value?.formJson
73
89
  if (!sourceFormItems)
74
90
  return []
75
91
 
@@ -80,24 +96,25 @@ const realJsonData = computed(() => {
80
96
 
81
97
  // 过滤出用于静默新增场景的表单项
82
98
  const silenceAddJsonData = computed(() => {
83
- return myFormItems.value.filter((item) => {
99
+ return realJsonData.value.filter((item) => {
84
100
  return item.addOrEdit === 'silenceAdd'
85
101
  }) as SilenceAddFormItem[]
86
102
  })
87
103
 
88
104
  const resolvedSubmitButton = computed(() => {
89
- if (props.configName && internalSubmitButton.value !== undefined) {
90
- return internalSubmitButton.value
105
+ if (props.configName && formConfig.value?.showSubmitBtn !== undefined) {
106
+ return formConfig.value.showSubmitBtn
91
107
  }
92
108
  return props.submitButton
93
109
  })
94
110
 
111
+ // 地图预览相关
95
112
  const previewMapRef = ref(null)
96
- // 假设你只预览第一个 addressSearch 类型的经纬度
97
113
  const previewLonLatKey = computed(() => {
98
114
  const item = realJsonData.value.find(i => i.type === 'addressSearch')
99
115
  return item ? `${item.model}_lon_lat` : null
100
116
  })
117
+
101
118
  const previewMapPoint = computed(() => {
102
119
  const val = form.value[previewLonLatKey.value]
103
120
  if (val && typeof val === 'string' && val.includes(',')) {
@@ -123,128 +140,225 @@ watch(previewMapPoint, async (val) => {
123
140
  }
124
141
  }, { immediate: true })
125
142
 
126
- onBeforeMount(() => {
127
- if (!props.configName && props.groupFormItems) {
128
- if (props.groupFormItems && props.groupFormItems.tableName) {
129
- tableName.value = props.groupFormItems.tableName.split(' ')[0] || ''
130
- }
131
- init({ formItems: props.groupFormItems, serviceName: props.serviceName, formData: props.formData, formName: props.formName })
132
- }
133
- })
134
-
135
- watch(() => props.configName, (newConfigName) => {
136
- if (newConfigName) {
137
- loadFormConfig(newConfigName)
138
- }
139
- else if (props.groupFormItems) {
140
- init({ formItems: props.groupFormItems, serviceName: props.serviceName, formData: props.formData, formName: props.formName })
141
- }
142
- }, { immediate: true })
143
-
144
- async function loadFormConfig(name: string) {
143
+ // 统一的初始化函数 - 仅在组件挂载时调用
144
+ async function initializeForm() {
145
145
  loaded.value = false
146
+
146
147
  try {
147
- const result = await post(`/api/${props.serviceName || import.meta.env.VITE_APP_SYSTEM_NAME}/logic/openapi/getLiuliConfiguration`, { configName: name })
148
- if (result) {
149
- internalFormConfig.value = result
150
- internalSubmitButton.value = result.showSubmitBtn
151
- myServiceName.value = props.serviceName || ''
152
- formGroupName.value = result.groupName || 'default'
153
- myFormItems.value = result.formJson as FormItem[]
154
-
155
- form.value = props.formData || {}
156
- Object.keys(rules).forEach(key => delete rules[key])
157
- for (const item of realJsonData.value) {
158
- setFormProps(form, item)
159
- }
148
+ if (props.configName) {
149
+ await loadFormConfig()
150
+ }
151
+ else if (props.groupFormItems) {
152
+ await initWithGroupFormItems()
160
153
  }
161
154
  else {
162
- console.warn(`Config '${name}' 不存在.`)
163
- internalFormConfig.value = null
164
- internalSubmitButton.value = undefined
165
- myFormItems.value = []
166
- form.value = {}
167
- Object.keys(rules).forEach(key => delete rules[key])
155
+ console.warn('未提供配置名称或表单配置,等待 init 函数调用')
156
+ resetForm()
168
157
  }
169
158
  }
170
159
  catch (error) {
171
- console.error(`无法加载配置 '${name}':`, error)
172
- internalFormConfig.value = null
173
- internalSubmitButton.value = undefined
174
- myFormItems.value = []
175
- form.value = {}
176
- Object.keys(rules).forEach(key => delete rules[key])
160
+ console.error('表单初始化失败:', error)
161
+ resetForm()
177
162
  }
178
163
  finally {
179
164
  loaded.value = true
180
165
  }
181
166
  }
182
167
 
183
- function init(params) {
168
+ // 加载配置的方式初始化
169
+ async function loadFormConfig(): Promise<void> {
170
+ return new Promise((resolve, reject) => {
171
+ getConfigByName(props.configName!, (result) => {
172
+ if (result) {
173
+ // 如果有 paramLogicName,自动请求并赋值
174
+ if (result.paramLogicName && !props.formData) {
175
+ let logicParam = props.paramLogicNameParam
176
+ if (typeof logicParam === 'string') {
177
+ try {
178
+ logicParam = JSON.parse(logicParam)
179
+ }
180
+ catch {
181
+ logicParam = { value: logicParam }
182
+ }
183
+ }
184
+ logicParam = {
185
+ ...logicParam,
186
+ currUserName: userStore.getUserInfo().name,
187
+ currUserId: userStore.getUserInfo().id,
188
+ orgId: userStore.getUserInfo().orgid,
189
+ }
190
+ runLogic(result.paramLogicName, logicParam || {}, props.serviceName).then((data: any) => {
191
+ if (data) {
192
+ form.value = data
193
+ }
194
+ })
195
+ }
196
+ setupFormConfig(result)
197
+ resolve()
198
+ }
199
+ else {
200
+ console.warn(`配置 '${props.configName}' 不存在`)
201
+ reject(new Error(`配置 '${props.configName}' 不存在`))
202
+ }
203
+ }, props.serviceName)
204
+ })
205
+ }
206
+
207
+ // 直接使用 groupFormItems 初始化
208
+ async function initWithGroupFormItems() {
209
+ if (!props.groupFormItems) {
210
+ throw new Error('groupFormItems 不能为空')
211
+ }
212
+
213
+ setupFormConfig(props.groupFormItems)
214
+
215
+ // 设置表名
216
+ if (props.groupFormItems.tableName) {
217
+ tableName.value = props.groupFormItems.tableName.split(' ')[0] || ''
218
+ }
219
+ }
220
+
221
+ // 设置表单配置
222
+ function setupFormConfig(config: GroupFormItems) {
223
+ console.log('>>>> config: ', JSON.stringify(config))
224
+ formConfig.value = config
225
+ myServiceName.value = props.serviceName || ''
226
+ formGroupName.value = config.groupName || 'default'
227
+ console.log('>>>> props.formData: ', props.formData)
228
+ form.value = props.formData || {}
229
+
230
+ // 清理并重新设置验证规则
231
+ setupValidationRules()
232
+ }
233
+
234
+ // 设置验证规则
235
+ function setupValidationRules() {
236
+ // 清理现有规则
237
+ Object.keys(rules).forEach(key => delete rules[key])
238
+
239
+ // 为每个表单项设置规则
240
+ for (const item of realJsonData.value) {
241
+ if (item.rule) {
242
+ setFormRule(item)
243
+ }
244
+ }
245
+ }
246
+
247
+ // 设置单个表单项的验证规则
248
+ function setFormRule(item: FormItem) {
249
+ if (!item.model || !item.rule)
250
+ return
251
+
252
+ rules[item.model] = []
253
+ let defaultValue: any
254
+ let message: string
255
+
256
+ switch (item.rule.type) {
257
+ case 'number':
258
+ message = '数字'
259
+ defaultValue = 0
260
+ break
261
+ case 'integer':
262
+ message = '整数'
263
+ defaultValue = 0
264
+ break
265
+ case 'float':
266
+ message = '小数'
267
+ defaultValue = 0.0
268
+ break
269
+ case 'string':
270
+ message = '字符串'
271
+ defaultValue = ''
272
+ break
273
+ default:
274
+ return
275
+ }
276
+
277
+ rules[item.model].push({
278
+ type: item.rule.type,
279
+ message: `${item.name || item.model}必须为${message}`,
280
+ transform: (value: any) => {
281
+ if (value && value.length !== 0) {
282
+ return Number(value)
283
+ }
284
+ else {
285
+ return defaultValue
286
+ }
287
+ },
288
+ trigger: 'blur',
289
+ })
290
+ }
291
+
292
+ // 重置表单状态
293
+ function resetForm() {
294
+ formConfig.value = null
295
+ formGroupName.value = 'default'
296
+ myServiceName.value = ''
297
+ tableName.value = ''
298
+ form.value = {}
299
+ Object.keys(rules).forEach(key => delete rules[key])
300
+ myGetDataParams.value = {}
301
+ }
302
+
303
+ // 监听 formData 变化
304
+ watch(() => props.formData, (newVal) => {
305
+ if (newVal) {
306
+ form.value = newVal
307
+ }
308
+ })
309
+
310
+ // 组件挂载时初始化
311
+ onBeforeMount(() => {
312
+ initializeForm()
313
+ })
314
+
315
+ // 支持函数调用方式初始化
316
+ function init(params: InitParams) {
184
317
  const {
185
318
  formItems,
186
- serviceName,
187
319
  formData = {},
188
- formName = 'default',
320
+ getDataParams = {},
189
321
  } = params
190
- loaded.value = false
191
- myFormItems.value = JSON.parse(JSON.stringify(formItems.formJson)) as FormItem[]
192
- myServiceName.value = serviceName
193
- formGroupName.value = formName
194
- for (let i = 0; i < realJsonData.value.length; i++) {
195
- const item = realJsonData.value[i]
196
- setFormProps(form, item)
197
- }
198
- if (formData)
199
- form.value = formData
200
322
 
201
- myGetDataParams = params.getDataParams || {}
202
- loaded.value = true
203
- }
323
+ // 重置状态
324
+ loaded.value = false
204
325
 
205
- function setFormProps(form, item) {
206
- if (item.rule) {
207
- rules[item.model] = []
208
- let defaultValue
209
- let message
210
- switch (item.rule.type) {
211
- case 'number':
212
- message = '数字'
213
- defaultValue = 0
214
- break
215
- case 'integer':
216
- message = '整数'
217
- defaultValue = 0
218
- break
219
- case 'float':
220
- message = '小数'
221
- defaultValue = 0.0
222
- break
223
- case 'string':
224
- message = '字符串'
225
- defaultValue = ''
226
- break
326
+ try {
327
+ if (props.configName) {
328
+ // 通过 props 中的配置名称初始化
329
+ loadFormConfig()
227
330
  }
228
- rules[item.model].push({
229
- type: item.rule.type,
230
- message: `${item.name}必须为${message}`,
231
- transform: (value) => {
232
- if (value && value.length !== 0)
233
- return Number(value)
234
- else
235
- return defaultValue
236
- },
237
- trigger: 'blur',
238
- })
331
+ else if (formItems) {
332
+ // 直接使用传入的配置初始化
333
+ setupFormConfig(formItems)
334
+ form.value = formData || props.formData || {}
335
+ myGetDataParams.value = getDataParams
336
+
337
+ // 设置表名
338
+ if (formItems.tableName) {
339
+ tableName.value = formItems.tableName.split(' ')[0] || ''
340
+ }
341
+ }
342
+ else {
343
+ console.warn('init 函数调用时既没有 props.configName 也没有 formItems')
344
+ resetForm()
345
+ }
346
+ }
347
+ catch (error) {
348
+ console.error('init 函数初始化失败:', error)
349
+ resetForm()
350
+ }
351
+ finally {
352
+ loaded.value = true
239
353
  }
240
354
  }
241
355
 
242
- function setForm(obj) {
356
+ function setForm(obj: object) {
243
357
  Object.assign(form.value, obj)
244
358
  }
245
359
 
246
360
  // 获取表单字段实际值
247
- function getRealKey(key, mustHandleKey = false) {
361
+ function getRealKey(key: string, mustHandleKey = false) {
248
362
  if (key === 'selected_id')
249
363
  return key
250
364
  if (props.isHandleFormKey || mustHandleKey) {
@@ -275,8 +389,8 @@ async function asyncSubmit() {
275
389
  })
276
390
  }
277
391
 
278
- function handleFormKeys(form, mustHandleKey = false) {
279
- const realForm = {}
392
+ function handleFormKeys(form: any, mustHandleKey = false) {
393
+ const realForm: any = {}
280
394
  for (const key of Object.keys(form)) {
281
395
  const value = form[key]
282
396
  const extraFormKeyTagIndex = key.indexOf('@')
@@ -302,7 +416,7 @@ function handleFormKeys(form, mustHandleKey = false) {
302
416
  return realForm
303
417
  }
304
418
 
305
- async function appendSilenceAddFields(form) {
419
+ async function appendSilenceAddFields(form: any) {
306
420
  if (props.mode === '新增') {
307
421
  for (const item of silenceAddJsonData.value) {
308
422
  switch (item.silencePurpose) {
@@ -330,7 +444,7 @@ async function appendSilenceAddFields(form) {
330
444
  }
331
445
  }
332
446
  for (const item of silenceAddJsonData.value.filter(item => item.silencePurpose === 'customize')) {
333
- const result: any = await runLogic(item.silenceSource, form, props.serviceName)
447
+ const result: any = await runLogic(item.silenceSource!, form, props.serviceName)
334
448
  if (result) {
335
449
  const keys = Object.keys(result)
336
450
  if (keys.length === 1 && keys[0] === 'value') {
@@ -349,7 +463,7 @@ async function appendSilenceAddFields(form) {
349
463
 
350
464
  function prepareForm() {
351
465
  const formObj = { ...form.value }
352
- const cleanedForm = {}
466
+ const cleanedForm: any = {}
353
467
 
354
468
  for (const key of Object.keys(formObj)) {
355
469
  const value = formObj[key]
@@ -381,7 +495,7 @@ function prepareForm() {
381
495
  }
382
496
 
383
497
  // 递归清理对象内部
384
- const cleanedObject = {}
498
+ const cleanedObject: any = {}
385
499
  let hasValidValue = false
386
500
 
387
501
  for (const objKey of objectKeys) {
@@ -443,19 +557,16 @@ async function onSubmit() {
443
557
  async function validate() {
444
558
  await xFormRef.value?.validate()
445
559
  }
446
- function emitFunc(func, data, value) {
560
+ function emitFunc(func: any, data: any, value: any) {
447
561
  emits(func, data, value)
448
562
  emits('xFormItemEmitFunc', func, data, value)
449
563
  }
450
564
 
451
- watch(() => props.formData, (_val) => {
452
- form.value = _val
453
- })
454
565
  defineExpose({ init, form, formGroupName, validate, asyncSubmit, setForm, getFormData })
455
566
  </script>
456
567
 
457
568
  <template>
458
- <VanForm ref="xFormRef" class="x-form-container" @submit="onSubmit">
569
+ <VanForm v-if="loaded" ref="xFormRef" class="x-form-container" @submit="onSubmit">
459
570
  <div class="form-fields-scrollable">
460
571
  <VanCellGroup inset>
461
572
  <XFormItem
@@ -123,11 +123,11 @@ defineExpose({ init })
123
123
  </template>
124
124
 
125
125
  <style scoped lang="less">
126
- #x-form-group{
127
- background-color: rgb(247,248,250);
126
+ #x-form-group {
127
+ background-color: rgb(247, 248, 250);
128
128
  padding-bottom: 10px;
129
- .x-form-group-item{
130
- margin:20px 0;
129
+ .x-form-group-item {
130
+ margin: 20px 0;
131
131
  }
132
132
  }
133
133
  </style>
@@ -141,7 +141,7 @@ const currInst = getCurrentInstance()
141
141
  // 配置中心->表单项变更触发函数
142
142
  const dataChangeFunc = debounce(async () => {
143
143
  if (attr.dataChangeFunc) {
144
- await executeStrFunctionByContext(currInst, attr.dataChangeFunc, [form, val => modelData.value = val, attr, null, mode])
144
+ await executeStrFunctionByContext(currInst, attr.dataChangeFunc, [form, (formData: any) => emits('setForm', formData), attr, null, mode])
145
145
  }
146
146
  }, 500)
147
147
 
@@ -160,44 +160,6 @@ const showFormItemFunc = debounce(async () => {
160
160
  }
161
161
  }, 500)
162
162
 
163
- // 监听 props.modelValue 的变化
164
- // watch(() => props.modelValue, (newVal) => {
165
- // console.log('props.modelValue===', props.modelValue)
166
- // })
167
-
168
- /* function getDeafultValue(){
169
- console.log('attr===', attr)
170
- if (attr.type === 'radio' || attr.type === 'rate' || attr.type === 'slider' || attr.type === 'area' || attr.type === 'citySelect' || attr.type === 'calendar' || attr.type === 'textarea' || attr.type === 'intervalPicker' || attr.type === 'input' || attr.type === 'select') {
171
- if (attr.formDefault)
172
- localValue.value = attr.formDefault
173
- if (attr.queryFormDefault)
174
- localValue.value = attr.queryFormDefault
175
- }
176
-
177
- if (attr.type === 'checkbox' || attr.type === 'uploader' || attr.type === 'file' || attr.type === 'image' || attr.type === 'datePicker' || attr.type === 'timePicker') {
178
- if (attr.formDefault) {
179
- if (attr.type === 'checkbox' || attr.type === 'image' || attr.type === 'file')
180
- formSelectDefaultValue.value = attr.formDefault
181
- else
182
- formSelectDefaultValue.value.push(attr.formDefault)
183
- }
184
- if (attr.queryFormDefault) {
185
- // console.log(querySelectDefaultValue.value)
186
- querySelectDefaultValue.value.push(...attr.queryFormDefault)
187
- // querySelectDefaultValue.value = attr.queryFormDefault
188
- }
189
- }
190
-
191
- if (attr.type === 'rangePicker') {
192
- if (attr.formDefault)
193
- formSelectDefaultValue.value = attr.formDefault
194
- if (attr.queryFormDefault) {
195
- const dateArray = getRangeByType(attr.queryFormDefault, true)
196
- pickerValue.value = `${dateArray[0]} ~ ${dateArray[1]}`
197
- querySelectDefaultValue.value = pickerValue.value
198
- }
199
- }
200
- } */
201
163
  /**
202
164
  * 检测是否传入了有效的值
203
165
  * @returns any
@@ -337,7 +299,6 @@ function getDateRange({
337
299
  }
338
300
  }
339
301
 
340
- // 删除 localValue 相关
341
302
  // 监听 props.form 的变化
342
303
  watch(
343
304
  () => props.form,
@@ -346,6 +307,21 @@ watch(
346
307
  if (props.attr.keyName && (props.attr.keyName.toString().includes('async ') || props.attr.keyName.toString().includes('function'))) {
347
308
  debouncedUpdateOptions()
348
309
  }
310
+ if (props.attr.showFormItemFunc) {
311
+ showFormItemFunc()
312
+ }
313
+ },
314
+ { deep: true },
315
+ )
316
+
317
+ // 监听 modelData 的变化,调用 dataChangeFunc
318
+ watch(
319
+ () => modelData.value,
320
+ (newVal, oldVal) => {
321
+ // 避免初始化时的调用
322
+ if (oldVal !== undefined && newVal !== oldVal) {
323
+ dataChangeFunc()
324
+ }
349
325
  },
350
326
  { deep: true },
351
327
  )
@@ -596,12 +572,9 @@ async function updateResOptions(type) {
596
572
  const startIndex = attr.keyName.indexOf('[') + 1
597
573
  const endIndex = attr.keyName.indexOf(']', startIndex)
598
574
  const formModel = attr.keyName.substring(startIndex, endIndex).replace('.', '_')
599
- // console.log(form)
600
575
  const formModelData = form[formModel]
601
576
  if (formModel?.length && formModelData?.length) {
602
577
  await searchToListOption(searchData, (res) => {
603
- // console.log(res)
604
- // console.log(form)
605
578
  getDataCallback(res.filter((h) => {
606
579
  return formModelData['0'] === h.f_organization_id || formModelData['0'] === h.f_department_id || formModelData['0'] === h.parentid
607
580
  // if (formModel.indexOf('org') > -1) {