refactor: 设置器加载统一,代码优化 #269 (#383)

* feat: 小功能建设(4)

* refactor: 设置器加载统一,代码优化 #269

---------

Co-authored-by: jiangchunfu <jiangchunfu@kaike.la>
This commit is contained in:
Jiangchunfu 2024-08-07 14:53:14 +08:00 committed by sudoooooo
parent 12206fd3ee
commit 4e993f4d55
4 changed files with 53 additions and 187 deletions

View File

@ -37,8 +37,8 @@
</el-form> </el-form>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { watch, ref, shallowRef } from 'vue' import { watch, ref, shallowRef, type Component } from 'vue'
import { get as _get, pick as _pick, isFunction as _isFunction } from 'lodash-es' import { get as _get, pick as _pick, isFunction as _isFunction, values as _values } from 'lodash-es'
import FormItem from '@/materials/setters/widgets/FormItem.vue' import FormItem from '@/materials/setters/widgets/FormItem.vue'
import setterLoader from '@/materials/setters/setterLoader' import setterLoader from '@/materials/setters/setterLoader'
@ -48,6 +48,7 @@ import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
interface Props { interface Props {
formConfigList: Array<any> formConfigList: Array<any>
moduleConfig: any moduleConfig: any
customComponents?: Record<string, Component>
} }
interface Emit { interface Emit {
@ -70,7 +71,7 @@ const formatValue = ({ item, moduleConfig }: any) => {
result = _get(moduleConfig, key, item.value) result = _get(moduleConfig, key, item.value)
} }
if (keys) { if (keys) {
result = _pick(moduleConfig, keys) result = _values(_pick(moduleConfig, keys))
} }
return result return result
@ -79,7 +80,7 @@ const formatValue = ({ item, moduleConfig }: any) => {
const formFieldData = ref<Array<any>>([]) const formFieldData = ref<Array<any>>([])
const init = ref<boolean>(true) const init = ref<boolean>(true)
const components = shallowRef<any>({}) const components = shallowRef<any>(props.customComponents || {})
const handleFormChange = (data: any, formConfig: any) => { const handleFormChange = (data: any, formConfig: any) => {
if (_isFunction(formConfig?.valueSetter)) { if (_isFunction(formConfig?.valueSetter)) {
@ -132,7 +133,9 @@ const normalizationValues = (configList: Array<any> = []) => {
const registerComponents = async (formFieldData: any) => { const registerComponents = async (formFieldData: any) => {
let innerSetters: Array<any> = [] let innerSetters: Array<any> = []
const setters = formFieldData.map((item: any) => { const setters = formFieldData
.filter((item: any) => !item.custom)
.map((item: any) => {
if (item.type === 'Customed') { if (item.type === 'Customed') {
innerSetters.push(...(item.content || []).map((content: any) => content.type)) innerSetters.push(...(item.content || []).map((content: any) => content.type))
} }

View File

@ -3,34 +3,23 @@
<div class="setter-title"> <div class="setter-title">
{{ currentEditText }} {{ currentEditText }}
</div> </div>
<el-form class="question-config-form" label-position="top" @submit.prevent> <SetterField
<template v-for="(item, index) in formFields" :key="index"> class="question-config-form"
<FormItem label-position="top"
v-if="item.type && !item.hidden && Boolean(registerTypes[item.type])" :form-config-list="formFields"
:form-config="item"
:style="item.style"
>
<Component
v-if="Boolean(registerTypes[item.type])"
:is="components[item.type]"
:module-config="moduleConfig" :module-config="moduleConfig"
:form-config="item"
@form-change="handleFormChange" @form-change="handleFormChange"
/> />
</FormItem>
</template>
</el-form>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, shallowRef, toRef } from 'vue' import { computed, toRef } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useEditStore } from '@/management/stores/edit' import { useEditStore } from '@/management/stores/edit'
import { get as _get } from 'lodash-es' import { get as _get } from 'lodash-es'
import FormItem from '@/materials/setters/widgets/FormItem.vue'
import setterLoader from '@/materials/setters/setterLoader'
import statusConfig from '@/management/pages/edit/setterConfig/statusConfig' import statusConfig from '@/management/pages/edit/setterConfig/statusConfig'
import SetterField from '@/management/pages/edit/components/SetterField.vue'
const textMap = { const textMap = {
Success: '提交成功页面配置', Success: '提交成功页面配置',
@ -41,8 +30,6 @@ const editStore = useEditStore()
const { currentEditStatus } = storeToRefs(editStore) const { currentEditStatus } = storeToRefs(editStore)
const { schema, changeSchema } = editStore const { schema, changeSchema } = editStore
const components = shallowRef<any>({})
const registerTypes = ref<any>({})
const moduleConfig = toRef(schema, 'submitConf') const moduleConfig = toRef(schema, 'submitConf')
const currentEditText = computed(() => (textMap as any)[currentEditStatus.value]) const currentEditText = computed(() => (textMap as any)[currentEditStatus.value])
const formFields = computed(() => { const formFields = computed(() => {
@ -53,8 +40,6 @@ const formFields = computed(() => {
return { ...item, value } return { ...item, value }
}) })
registerComponents(list)
return list return list
}) })
@ -64,39 +49,6 @@ const handleFormChange = ({ key, value }: any) => {
value value
}) })
} }
const registerComponents = async (formFieldData: any) => {
const setters = formFieldData.map((item: any) => item.type)
const settersSet = new Set(setters)
const settersArr = Array.from(settersSet)
const allSetters = settersArr.map((item) => {
return {
type: item,
path: item
}
})
try {
const comps = await setterLoader.loadComponents(allSetters)
for (const comp of comps) {
if (!comp) {
continue
}
const { type, component, err } = comp
if (!err) {
const componentName = component.name
components.value[type] = component
registerTypes.value[type] = componentName
}
}
} catch (err) {
console.error(err)
}
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.question-edit-form { .question-edit-form {

View File

@ -2,146 +2,57 @@
<div class="question-config"> <div class="question-config">
<div class="question-config-wrapper"> <div class="question-config-wrapper">
<div class="question-config-main"> <div class="question-config-main">
<div v-for="form of setterList" :key="form.key" class="config-item"> <div v-for="form of formConfigList" :key="form.key" class="config-item">
<div class="config-title"> <div class="config-title">
<span> <span>
{{ form.title }} {{ form.title }}
</span> </span>
</div> </div>
<el-form <SetterField
:key="form.key"
class="question-config-form" class="question-config-form"
label-position="left" label-position="left"
label-width="200px" label-width="200px"
@submit.prevent :form-config-list="form.formList"
> :module-config="baseConf"
<template v-for="(item, index) in form.formList"> :custom-components="{
<FormItem WhiteList,
v-if="item.type && !item.hidden && Boolean(registerTypes[item.type])" TeamMemberList
:key="index" }"
:form-config="item"
:style="item.style"
>
<Component
v-if="Boolean(registerTypes[item.type])"
:is="components[item.type]"
:module-config="form.dataConfig"
:form-config="item"
@form-change="handleFormChange" @form-change="handleFormChange"
/> ></SetterField>
</FormItem>
</template>
</el-form>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ref, onMounted, shallowRef } from 'vue' import { ref, toRef } from 'vue'
import {
cloneDeep as _cloneDeep,
isArray as _isArray,
get as _get,
isFunction as _isFunction
} from 'lodash-es'
import { useEditStore } from '@/management/stores/edit' import { useEditStore } from '@/management/stores/edit'
import baseConfig from '@/management/pages/edit/setterConfig/baseConfig' import baseConfig from '@/management/pages/edit/setterConfig/baseConfig'
import baseFormConfig from '@/management/pages/edit/setterConfig/baseFormConfig' import baseFormConfig from '@/management/pages/edit/setterConfig/baseFormConfig'
import FormItem from '@/materials/setters/widgets/FormItem.vue' import SetterField from '@/management/pages/edit/components/SetterField.vue'
import setterLoader from '@/materials/setters/setterLoader'
import WhiteList from './components/WhiteList.vue' import WhiteList from './components/WhiteList.vue'
import TeamMemberList from './components/TeamMemberList.vue' import TeamMemberList from './components/TeamMemberList.vue'
const editStore = useEditStore() const editStore = useEditStore()
const { schema, changeSchema } = editStore const { schema, changeSchema } = editStore
const baseConf = toRef(schema, 'baseConf')
const formConfigList = ref<Array<any>>([]) const baseConfigWithFormList = baseConfig.map((item) => ({
const components = shallowRef<any>({
['WhiteList']: WhiteList,
['TeamMemberList']: TeamMemberList
})
//
const registerTypes = ref<any>({
WhiteList: 'WhiteList',
TeamMemberList: 'TeamMemberList'
})
const schemaBaseConf = computed(() => schema?.baseConf || {})
const setterList = computed(() => {
const list = _cloneDeep(formConfigList.value)
return list.map((form) => {
const dataConfig: any = {}
for (const formItem of form.formList) {
const formKey = formItem.key ? formItem.key : formItem.keys
let formValue
if (_isArray(formKey)) {
formValue = []
for (const key of formKey) {
const val = _get(schema, key, formItem.value)
formValue.push(val)
dataConfig[key] = val
}
} else {
formValue = _get(schema, formKey, formItem.value)
dataConfig[formKey] = formValue
}
formItem.value = formValue
}
//
form.formList = form.formList.filter((item: any) => {
if (_isFunction(item.relyFunc)) {
return item.relyFunc(schemaBaseConf.value)
}
return true
})
form.dataConfig = dataConfig
return form
})
})
const handleFormChange = (data: any) => {
changeSchema({
key: data.key,
value: data.value
})
}
onMounted(async () => {
formConfigList.value = baseConfig.map((item) => ({
...item, ...item,
formList: item.formList.map((key) => (baseFormConfig as any)[key]).filter((config) => !!config) formList: item.formList.map((key) => (baseFormConfig as any)[key]).filter((config) => !!config)
})) }))
const formConfigList = ref<Array<any>>(baseConfigWithFormList)
const formList = formConfigList.value.map((item) => item.formList).flat() const handleFormChange = ({ key, value }: any) => {
const typeList = formList changeSchema({
.filter((item) => !item.custom) key: `baseConf.${key}`,
.map((item) => ({ value: value
type: item.type, })
path: item.path || item.type }
}))
const comps = await setterLoader.loadComponents(typeList)
for (const comp of comps) {
if (!comp) {
continue
}
const { type, component, err } = comp
if (!err) {
const componentName = component.name
components.value[type] = component
registerTypes.value[type] = componentName
}
}
})
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,13 +1,13 @@
// 问卷设置,定义了字段和对应的设置器 // 问卷设置,定义了字段和对应的设置器
export default { export default {
base_effectTime: { base_effectTime: {
keys: ['baseConf.begTime', 'baseConf.endTime'], keys: ['begTime', 'endTime'],
label: '答题有效期', label: '答题有效期',
type: 'QuestionTime', type: 'QuestionTime',
placeholder: 'yyyy-MM-dd hh:mm:ss' placeholder: 'yyyy-MM-dd hh:mm:ss'
}, },
limit_tLimit: { limit_tLimit: {
key: 'baseConf.tLimit', key: 'tLimit',
label: '问卷回收总数', label: '问卷回收总数',
type: 'InputNumber', type: 'InputNumber',
tip: '0为无限制此功能用于限制该问卷总提交的数据量。当数据量达到限额时该问卷将不能继续提交', tip: '0为无限制此功能用于限制该问卷总提交的数据量。当数据量达到限额时该问卷将不能继续提交',
@ -16,19 +16,19 @@ export default {
min: 0 min: 0
}, },
limit_answerTime: { limit_answerTime: {
keys: ['baseConf.answerBegTime', 'baseConf.answerEndTime'], keys: ['answerBegTime', 'answerEndTime'],
label: '答题时段', label: '答题时段',
tip: '问卷仅在指定时间段内可填写', tip: '问卷仅在指定时间段内可填写',
type: 'QuestionTimeHour', type: 'QuestionTimeHour',
placement: 'top' placement: 'top'
}, },
interview_pwd_switch: { interview_pwd_switch: {
key: 'baseConf.passwordSwitch', key: 'passwordSwitch',
label: '访问密码', label: '访问密码',
type: 'CustomedSwitch' type: 'CustomedSwitch'
}, },
interview_pwd: { interview_pwd: {
key: 'baseConf.password', key: 'password',
type: 'InputSetter', type: 'InputSetter',
placeholder: '请输入6位字符串类型访问密码 ', placeholder: '请输入6位字符串类型访问密码 ',
maxLength: 6, maxLength: 6,
@ -37,7 +37,7 @@ export default {
} }
}, },
answer_type: { answer_type: {
key: 'baseConf.whitelistType', key: 'whitelistType',
label: '答题名单', label: '答题名单',
type: 'RadioGroup', type: 'RadioGroup',
options: [ options: [
@ -56,7 +56,7 @@ export default {
] ]
}, },
white_placeholder: { white_placeholder: {
key: 'baseConf.whitelistTip', key: 'whitelistTip',
label: '名单登录提示语', label: '名单登录提示语',
placeholder: '请输入名单提示语', placeholder: '请输入名单提示语',
type: 'InputSetter', type: 'InputSetter',
@ -66,7 +66,7 @@ export default {
} }
}, },
white_list: { white_list: {
keys: ['baseConf.whitelist', 'baseConf.memberType'], keys: ['whitelist', 'memberType'],
label: '白名单列表', label: '白名单列表',
type: 'WhiteList', type: 'WhiteList',
custom: true, // 自定义导入高级组件 custom: true, // 自定义导入高级组件
@ -75,7 +75,7 @@ export default {
} }
}, },
team_list: { team_list: {
key: 'baseConf.whitelist', key: 'whitelist',
label: '团队空间成员选择', label: '团队空间成员选择',
type: 'TeamMemberList', type: 'TeamMemberList',
custom: true, // 自定义导入高级组件 custom: true, // 自定义导入高级组件