feat: schema分离 (#311)

This commit is contained in:
dayou 2024-06-28 17:08:55 +08:00 committed by GitHub
parent 79e06ff40c
commit d6dc68429a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
29 changed files with 734 additions and 307 deletions

View File

@ -11,13 +11,16 @@
"field": "data458",
"title": "标题1",
"placeholder": "",
"randomSort": false,
"checked": false,
"minNum": "",
"maxNum": "",
"star": 5,
"placeholderDesc": "",
"urlKey": "",
"numberRange": {
"max": {
"placeholder": "1000",
"value": 1000
},
"min": {
"placeholder": "0",
"value": 0
}
},
"textRange": {
"min": {
"placeholder": "0",
@ -35,14 +38,8 @@
"showType": true,
"showSpliter": true,
"type": "radio",
"placeholderDesc": "",
"field": "data515",
"title": "标题2",
"placeholder": "",
"randomSort": false,
"checked": false,
"minNum": "",
"maxNum": "",
"options": [
{
"text": "选项1",
@ -62,23 +59,7 @@
"placeholderDesc": "",
"hash": "115020"
}
],
"importKey": "single",
"importData": "",
"cOption": "",
"cOptions": [],
"star": 5,
"exclude": false,
"textRange": {
"min": {
"placeholder": "0",
"value": 0
},
"max": {
"placeholder": "500",
"value": 500
}
}
]
}
]
}

View File

@ -6,30 +6,21 @@
"showIndex": true,
"showType": true,
"showSpliter": true,
"placeholderDesc": "",
"placeholder": "",
"isRequired": true,
"randomSort": false,
"innerRandom": false,
"hideSubTitleIndex": false,
"checked": false,
"minNum": "",
"maxNum": "",
"relyType": "and",
"extraOptions": [],
"importKey": "single",
"importData": "",
"addressType": 3,
"isAuto": false,
"urlKey": "",
"hasRely": true,
"relyList": [],
"optionOrigin": "",
"answerTip": "",
"type": "text",
"valid": "",
"title": "标题1",
"answer": "",
"numberRange": {
"max": {
"placeholder": "1000",
"value": 1000
},
"min": {
"placeholder": "0",
"value": 0
}
},
"textRange": {
"min": {
"placeholder": "0",
@ -46,45 +37,12 @@
"showIndex": true,
"showType": true,
"showSpliter": true,
"placeholderDesc": "",
"placeholder": "",
"isRequired": true,
"randomSort": false,
"innerRandom": false,
"hideSubTitleIndex": false,
"checked": false,
"minNum": "",
"maxNum": "",
"relyType": "and",
"extraOptions": [],
"importKey": "single",
"importData": "",
"cOption": "",
"cOptions": [],
"star": 5,
"urlKey": "",
"defaultProps": {
"children": "children",
"label": "name",
"id": "id"
},
"hasRely": true,
"relyList": [],
"optionOrigin": "",
"answerTip": "",
"min": "",
"max": "",
"type": "radio-star",
"title": "标题2",
"answer": "",
"textRange": {
"min": {
"placeholder": "0",
"value": 0
},
"max": {
"placeholder": "500",
"value": 500
}
}
"title": "标题2"
}
]
}

View File

@ -11,13 +11,16 @@
"field": "data458",
"title": "姓名",
"placeholder": "",
"randomSort": false,
"checked": false,
"minNum": "",
"maxNum": "",
"star": 5,
"exclude": false,
"placeholderDesc": "",
"numberRange": {
"max": {
"placeholder": "1000",
"value": 1000
},
"min": {
"placeholder": "0",
"value": 0
}
},
"textRange": {
"min": {
"placeholder": "0",
@ -40,10 +43,6 @@
"title": "选择您感兴趣的课程进行报名",
"placeholder": "",
"valid": "",
"randomSort": false,
"checked": false,
"minNum": "",
"maxNum": "",
"options": [
{
"text": "课程1",
@ -81,27 +80,7 @@
"othersKey": "",
"placeholderDesc": ""
}
],
"star": 5,
"exclude": false,
"urlKey": "",
"defaultProps": {
"children": "children",
"label": "name",
"id": "id"
},
"startDate": "",
"endDate": "",
"textRange": {
"min": {
"placeholder": "0",
"value": 0
},
"max": {
"placeholder": "500",
"value": 500
}
}
]
}
]
}

View File

@ -11,15 +11,16 @@
"field": "data631",
"title": "标题1",
"placeholder": "",
"sLimit": 1,
"randomSort": false,
"checked": false,
"minNum": "",
"maxNum": "",
"star": 5,
"exclude": false,
"placeholderDesc": "",
"urlKey": "",
"numberRange": {
"max": {
"placeholder": "1000",
"value": 1000
},
"min": {
"placeholder": "0",
"value": 0
}
},
"textRange": {
"min": {
"placeholder": "0",
@ -38,12 +39,8 @@
"showSpliter": true,
"type": "vote",
"innerType": "radio",
"placeholderDesc": "",
"field": "data606",
"title": "标题2",
"placeholder": "",
"randomSort": false,
"checked": false,
"minNum": "",
"maxNum": "",
"options": [
@ -65,18 +62,7 @@
"placeholderDesc": "",
"hash": "115020"
}
],
"star": 5,
"textRange": {
"min": {
"placeholder": "0",
"value": 0
},
"max": {
"placeholder": "500",
"value": 500
}
}
]
}
]
}

View File

@ -33,7 +33,7 @@ export function getListHeadByDataList(dataList) {
let othersCode;
const radioType = ['radio-star', 'radio-nps'];
if (radioType.includes(question.type)) {
const rangeConfigKeys = Object.keys(question.rangeConfig);
const rangeConfigKeys = question.rangeConfig ? Object.keys(question.rangeConfig) : [];
if (rangeConfigKeys.length > 0) {
othersCode = [{ code: `${question.field}_custom`, option: '填写理由' }];
}

View File

@ -59,8 +59,8 @@ const emit = defineEmits<Emit>()
//
const formatValue = ({ item, moduleConfig }: any) => {
if (_isFunction(item.valueAdapter)) {
const value = item.valueAdapter({ moduleConfig })
if (_isFunction(item.valueGetter)) {
const value = item.valueGetter({ moduleConfig })
return value
} else {
@ -82,8 +82,8 @@ const init = ref<boolean>(true)
const components = shallowRef<any>({})
const handleFormChange = (data: any, formConfig: any) => {
if (_isFunction(formConfig?.setterAdapter)) {
const resultData = formConfig.setterAdapter(data)
if (_isFunction(formConfig?.valueSetter)) {
const resultData = formConfig.valueSetter(data)
if (Array.isArray(resultData)) {
resultData.forEach((item) => {

View File

@ -15,7 +15,7 @@
</div>
</template>
<script lang="ts" setup>
import { computed, withDefaults } from 'vue'
import { computed } from 'vue'
import { useStore } from 'vuex'
import { type IMember, type ListItem } from '@/management/utils/types/workSpace'
import OperationSelect from './OperationSelect.vue'

View File

@ -22,7 +22,7 @@
</template>
<script lang="ts" setup>
import { ref, withDefaults } from 'vue'
import { ref } from 'vue'
import { useStore } from 'vuex'
import MemberList from './MemberList.vue'
import { getUserList } from '@/management/api/space'

View File

@ -1,6 +1,7 @@
import { defaultQuestionConfig } from '../config/questionConfig'
import { cloneDeep as _cloneDeep, map as _map } from 'lodash-es'
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
import { map as _map } from 'lodash-es'
import questionLoader from '@/materials/questions/questionLoader'
const generateQuestionField = () => {
const num = Math.floor(Math.random() * 1000)
return `data${num}`
@ -23,15 +24,6 @@ const generateHash = (hashList) => {
return hash
}
function getOptions(type) {
const options = [].concat({ ..._cloneDeep(defaultQuestionConfig) }.options)
if (type === QUESTION_TYPE.BINARY_CHOICE) {
options[0].text = '对'
options[1].text = '错'
}
return options
}
export const getNewField = (fields) => {
let field = generateQuestionField()
let isFieldExists = fields.includes(field)
@ -44,16 +36,30 @@ export const getNewField = (fields) => {
}
export const getQuestionByType = (type, fields) => {
const newQuestion = _cloneDeep(defaultQuestionConfig)
newQuestion.type = type
newQuestion.field = getNewField(fields)
newQuestion.options = getOptions(type)
const hashList = []
for (const option of newQuestion.options) {
const hash = generateHash(hashList)
hashList.push(hash)
option.hash = hash
const questionMeta = questionLoader.getMeta(type)
const { attrs } = questionMeta
let newQuestion = defaultQuestionConfig
if( attrs ) {
let questionSchema = {}
attrs.forEach(element => {
questionSchema[element.name] = element.defaultValue
});
newQuestion = questionSchema
} else {
newQuestion = defaultQuestionConfig
newQuestion.type = type
}
newQuestion.field = getNewField(fields) // 动态生成题目id
if('options ' in newQuestion) { // 动态更新选项的hash-id
const hashList = []
for (const option of newQuestion.options) {
const hash = generateHash(hashList)
hashList.push(hash)
option.hash = hash
}
}
return newQuestion
}

View File

@ -24,7 +24,7 @@ export default {
tip: '题目下方分割线,仅在移动端展示。'
}
],
valueAdapter({ moduleConfig }) {
valueGetter({ moduleConfig }) {
return _pick(
moduleConfig,
this.options.map((item) => item.key)

View File

@ -4,6 +4,75 @@ const meta = {
title: '判断题',
type: 'binary-choice',
componentName: 'BinaryChoiceModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'binary-choice'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'options',
propType: Array,
description: '这是用于描述选项',
defaultValue: [
{
"text": "对",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115019"
},
{
"text": "错",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115020"
}
]
},
],
formConfig: [basicConfig],
editConfigure: {
optionEdit: {

View File

@ -4,13 +4,93 @@ const meta = {
title: '多选',
type: 'checkbox',
componentName: 'CheckBoxModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'checkbox'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'options',
propType: Array,
description: '这是用于描述选项',
defaultValue: [
{
"text": "选项1",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115019"
},
{
"text": "选项2",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115020"
}
]
},
{
name: 'minNum',
propType: Number,
description: '最少选择数',
defaultValue: 0
},
{
name: 'maxNum',
propType: Number,
description: '最多选择数',
defaultValue: 0
}
],
formConfig: [
basicConfig,
{
name: 'optionConfig',
title: '选项配置',
type: 'Customed',
key: 'optionConfig',
content: [
{
label: '至少选择数',

View File

@ -52,7 +52,8 @@ export default {
},
props: {
optionList: {
type: Array
type: Array,
default: () => []
},
isShowOperation: {
type: Boolean,

View File

@ -4,6 +4,93 @@ export const meta = {
title: '单行输入框',
type: 'text',
componentName: 'InputModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'text'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'placeholder',
propType: String,
description: '这是用于描述引导提示文案',
defaultValue: ''
},
{
name: 'valid',
propType: String,
description: '这是用于描述内容限制格式',
defaultValue: ''
},
{
name: 'numberRange',
propType: Object,
description: '这是用于数字限制',
defaultValue: {
max: {
placeholder: '1000',
value: 1000
},
min: {
placeholder: '0',
value: 0
}
}
},
{
name: 'textRange',
propType: Object,
description: '这是用于字数限制',
defaultValue: {
max: {
placeholder: '500',
value: 500
},
min: {
placeholder: '0',
value: 0
}
}
}
],
formConfig: [
basicConfig,
{
@ -42,28 +129,14 @@ export const meta = {
name: 'numberRange',
title: '数字限制',
type: 'RangeSetter',
options: [],
key: 'numberRange',
value: [],
cleanKeys: {
numberRange: {
min: {
placeholder: '0',
value: 0
},
max: {
placeholder: '1000',
value: 1000
}
}
},
relyFunc: (data) => data.valid && data.valid === 'n'
},
{
name: 'textRange',
title: '字数限制',
type: 'RangeSetter',
options: [],
key: 'textRange',
value: []
},

View File

@ -121,7 +121,8 @@ export default defineComponent({
max,
readonly,
rangeConfig,
onMoreDataChange
onMoreDataChange,
selectMoreView
} = this
return (
@ -139,21 +140,20 @@ export default defineComponent({
iconClass="number"
onChange={confirmNps}
class={!readonly ? 'radio-nps-hover' : ''}
>
{isShowInput && (
<selectMoreView
showTitle={false}
key={`${field}_${rating}`}
moduleConfig={{
type: 'selectMoreModule',
field: `${field}_${rating}`,
placeholder: rangeConfig[rating]?.text,
value: rangeConfig[rating]?.othersValue || ''
}}
onChange={(e) => onMoreDataChange(e)}
></selectMoreView>
)}
</BaseRate>
/>
{isShowInput && (
<selectMoreView
showTitle={false}
key={`${field}_${rating}`}
moduleConfig={{
type: 'selectMoreModule',
field: `${field}_${rating}`,
placeholder: rangeConfig[rating]?.text,
value: rangeConfig[rating]?.othersValue || ''
}}
onChange={(e) => onMoreDataChange(e)}
></selectMoreView>
)}
</div>
)
}

View File

@ -2,9 +2,84 @@ import { ElMessage } from 'element-plus'
import basicConfig from '@materials/questions/common/config/basicConfig'
const meta = {
title: '评分',
title: 'nps评分',
type: 'radio-nps',
componentName: 'NpsModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'radio-nps'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'min',
propType: Number,
description: '这是用于描述NPS量表最小值',
defaultValue: 1
},
{
name: 'max',
propType: Number,
description: '这是用于描述NPS量表最大值',
defaultValue: 10
},
{
name: 'minMsg',
propType: String,
description: '这是用于描述最小值文案',
defaultValue: '极不满意'
},
{
name: 'maxMsg',
propType: String,
description: '这是用于描述最大值文案',
defaultValue: '十分满意'
},
{
name: 'rangeConfig',
propType: Object,
description: '这是用于描述评分高级设置',
defaultValue: {}
}
],
formConfig: [
basicConfig,
{
@ -17,11 +92,12 @@ const meta = {
value: v,
label: v
})),
valueSetter: (val, moduleConfig) => {
validate: (val, moduleConfig) => {
if (moduleConfig['max'] && val >= moduleConfig['max']) {
ElMessage.info('最小值不可大于最大值')
return true
return false
}
return true
}
},
{
@ -34,11 +110,12 @@ const meta = {
value: v,
label: v
})),
valueSetter: (val, moduleConfig) => {
validate: (val, moduleConfig) => {
if (moduleConfig['min'] && val <= moduleConfig['min']) {
ElMessage.info('最大值不可小于最小值')
return true
return false
}
return true
}
},
{

View File

@ -18,10 +18,8 @@
}
}
}
@media (max-width: 930px) {
:deep(.question-block) {
padding: 0;
}
.question-block {
padding: 0!important;
}
.radio-nps-hover {
.rate-item {

View File

@ -4,7 +4,13 @@ const meta = {
title: '单选',
type: 'radio',
componentName: 'RadioModule',
props: [
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
@ -15,28 +21,60 @@ const meta = {
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: '标题一'
defaultValue: 'radio'
},
{
name: 'extraOptions',
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'options',
propType: Array,
description: '这是用于固定选项配置',
defaultValue: []
}
description: '这是用于描述选项',
defaultValue: [
{
"text": "选项1",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115019"
},
{
"text": "选项2",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115020"
}
]
},
],
formConfig: [
basicConfig,
{
name: 'optionsExtra',
label: '固定选项配置',
labelStyle: {
'font-weight': 'bold'
},
type: 'Options',
options: [],
keys: 'extraOptions',
hidden: true
}
],
editConfigure: {
optionEdit: {

View File

@ -4,6 +4,74 @@ const meta = {
title: '评分',
type: 'radio-star',
componentName: 'StarModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'radio-star'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'starMin',
propType: Number,
description: '这是用于描述评分最小值',
defaultValue: 1
},
{
name: 'starMax',
propType: Number,
description: '这是用于描述评分最大值',
defaultValue: 5
},
{
name: 'starStyle',
propType: String,
description: '',
defaultValue: 'star',
},
{
name: 'rangeConfig',
propType: Object,
description: '这是用于描述评分高级设置',
defaultValue: {}
},
],
formConfig: [
basicConfig,
{

View File

@ -4,6 +4,92 @@ const meta = {
title: '多行输入框',
type: 'textarea',
componentName: 'TextareaModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'textarea'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'placeholder',
propType: String,
description: '这是用于描述引导提示文案',
defaultValue: ''
},
{
name: 'valid',
propType: String,
description: '这是用于描述内容限制格式',
defaultValue: ''
},
{
name: 'numberRange',
propType: Object,
description: '这是用于数字限制',
defaultValue: {
max: {
placeholder: '1000',
value: 1000
},
min: {
placeholder: '0',
value: 0
}
}
},
{
name: 'textRange',
propType: Object,
description: '这是用于字数限制',
defaultValue: {
max: {
placeholder: '500',
value: 500
},
min: {
placeholder: '0',
value: 0
}
}
}
],
formConfig: [
basicConfig,
{
@ -42,28 +128,14 @@ const meta = {
name: 'numberRange',
title: '数字限制',
type: 'RangeSetter',
options: [],
key: 'numberRange',
value: [],
cleanKeys: {
numberRange: {
min: {
placeholder: '0',
value: 0
},
max: {
placeholder: '1000',
value: 1000
}
}
},
relyFunc: (data) => data.valid && data.valid === 'n'
},
{
name: 'textRange',
title: '字数限制',
type: 'RangeSetter',
options: [],
key: 'textRange',
value: []
},

View File

@ -4,6 +4,87 @@ const meta = {
title: '投票',
type: 'vote',
componentName: 'VoteModule',
attrs: [
{
name: 'field',
propType: 'String',
description: '这是用于描述题目id',
defaultValue: ''
},
{
name: 'title',
propType: 'String',
description: '这是用于描述题目标题',
defaultValue: '标题一'
},
{
name: 'type',
propType: 'String',
description: '这是用于描述题目类型',
defaultValue: 'vote'
},
{
name: 'isRequired',
propType: Boolean,
description: '是否必填',
defaultValue: true
},
{
name: 'showIndex',
propType: Boolean,
description: '显示序号',
defaultValue: true
},
{
name: 'showType',
propType: Boolean,
description: '显示类型',
defaultValue: true
},
{
name: 'showSpliter',
propType: Boolean,
description: '显示分割线',
defaultValue: true
},
{
name: 'options',
propType: Array,
description: '这是用于描述选项',
defaultValue: [
{
"text": "选项1",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115019"
},
{
"text": "选项2",
"imageUrl": "",
"others": false,
"mustOthers": false,
"othersKey": "",
"placeholderDesc": "",
"hash": "115020"
}
]
},
{
name: 'minNum',
propType: Number,
description: '最少选择数',
defaultValue: 1
},
{
name: 'maxNum',
propType: Number,
description: '最多选择数',
defaultValue: 1
}
],
formConfig: [
basicConfig,
{
@ -18,7 +99,7 @@ const meta = {
key: 'innerType',
value: false,
// 输入转换
valueAdapter({ moduleConfig }) {
valueGetter({ moduleConfig }) {
if (moduleConfig.innerType === 'checkbox') {
return true
} else {
@ -26,7 +107,7 @@ const meta = {
}
},
// 输出转换
setterAdapter({ value }) {
valueSetter({ value }) {
return {
key: 'innerType',
value: value ? 'checkbox' : 'radio'

View File

@ -11,7 +11,6 @@
import { ref, computed } from 'vue'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss'
import { QUESTION_TYPE } from '@/common/typeEnum'
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
interface Props {
@ -25,18 +24,11 @@ interface Emit {
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const setterTypes = [QUESTION_TYPE.CHECKBOX, QUESTION_TYPE.VOTE]
const modelValue = ref(props.formConfig.value || 0)
const modelValue = ref(Number(props.formConfig.value) || 0)
const minModelValue = computed(() => {
const { min } = props.formConfig
const { type } = props.moduleConfig
if (min !== undefined) {
if (typeof min === 'string') {
return setterTypes.includes(type)
? Number(props.moduleConfig[min])
: Number(Number(props.moduleConfig[min]) + 1)
} else if (typeof props.formConfig.min === 'function') {
if (min) {
if (typeof min === 'function') {
return min(props.moduleConfig)
} else {
return Number(min)
@ -46,18 +38,14 @@ const minModelValue = computed(() => {
})
const maxModelValue = computed(() => {
const { type } = props.moduleConfig
const { max, min } = props.formConfig
if (max) {
if (typeof max === 'string') {
return setterTypes.includes(type)
? Number(props.moduleConfig[max])
: props.moduleConfig[max] - 1
} else if (typeof max === 'function') {
if (typeof max === 'function') {
return max(props.moduleConfig)
} else {
return Number(max)
}
return Number(max)
} else if (min !== undefined && Array.isArray(props.moduleConfig?.options)) {
return props.moduleConfig.options.length
} else {

View File

@ -33,25 +33,15 @@ const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const minModelValue = computed(() => {
const key = props.formConfig.key
const minValue = props.formConfig?.value?.min?.value
if (key === 'textRange') {
return parseInt(minValue)
}
return minValue || 1
return parseInt(minValue)
})
const maxModelValue = computed(() => {
const key = props.formConfig.key
const maxValue = props.formConfig?.value?.max?.value
if (key === 'textRange') {
return parseInt(maxValue)
}
return maxValue || 1
return maxValue ? parseInt(maxValue) : 1
})
const handleRangeChange = (eventType: 'max' | 'min', value: number) => {

View File

@ -61,10 +61,10 @@ const modelValue = ref(
)
const handleSelectChange = (value: string) => {
const { key, valueSetter } = props.formConfig
const { key, validate } = props.formConfig
if (valueSetter && typeof valueSetter == 'function') {
let verification: boolean = valueSetter(value, props.moduleConfig)
if (validate && typeof validate == 'function') {
let verification: boolean = validate(value, props.moduleConfig)
if (!verification) {
return
@ -72,7 +72,6 @@ const handleSelectChange = (value: string) => {
modelValue.value = props.moduleConfig[key]
}
emit(FORM_CHANGE_EVENT_KEY, { key, value })
}

View File

@ -18,7 +18,7 @@ export default function ({ dataConf }) {
// }
// 题型是多选或者子题型是多选innerType是用于投票
if (/checkbox/.test(type) || innerType === QUESTION_TYPE.CHECKBOX) {
if (type === QUESTION_TYPE.CHECKBOX || innerType === QUESTION_TYPE.CHECKBOX) {
value = value ? [value] : []
}
formValues[key] = value

View File

@ -2,26 +2,7 @@
* 处理单题的配置
*/
import { get as _get, map as _map } from 'lodash-es'
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
// 处理选择题的options
function handleOptions(item) {
const { type } = item
const options = item.options || []
const arr = _map(options, (optionItem) => {
const cleanOption = {}
// 投票逻辑处理
if (type.indexOf(QUESTION_TYPE.VOTE) > -1) {
cleanOption.voteCount = 0
}
return { value: optionItem['hash'], ...optionItem, ...cleanOption }
})
return { options: arr }
}
import { get as _get } from 'lodash-es'
export default function (questionConfig) {
let dataList = _get(questionConfig, 'dataConf.dataList')
@ -31,8 +12,7 @@ export default function (questionConfig) {
[item.field]: {
indexNumber: '',
voteTotal: 0,
...item,
...handleOptions(item)
...item
}
})
return pre

View File

@ -195,17 +195,19 @@ export function generateValidArr(
// 生成选择类或者评分类的题目的更多输入框
const generateOthersKeyMap = (question) => {
const { type, field, options, rangeConfig } = question
const { type, field } = question
let othersKeyMap = undefined
if (RATES.includes(type)) {
const { rangeConfig } = question
othersKeyMap = {}
for (const key in rangeConfig) {
if (rangeConfig[key].isShowInput) {
othersKeyMap[`${field}_${key}`] = key
}
}
} else if (type.includes(QUESTION_TYPE.RADIO) || type.includes(QUESTION_TYPE.CHECKBOX)) {
} else if (type?.includes(QUESTION_TYPE.RADIO) || type?.includes(QUESTION_TYPE.CHECKBOX)) {
const { options } = question
othersKeyMap = {}
options
.filter((op) => op.others)

View File

@ -38,7 +38,7 @@ const formValues = computed(() => {
})
const questionConfig = computed(() => {
let moduleConfig = props.moduleConfig
const { type, field, options, ...rest } = cloneDeep(moduleConfig)
const { type, field, options = [], ...rest } = cloneDeep(moduleConfig)
// console.log(field,'formValuechange')
let alloptions = options
if (type === QUESTION_TYPE.VOTE) {
@ -57,9 +57,8 @@ const questionConfig = computed(() => {
moduleConfig.othersValue = unref(othersValue)
}
if (
RATES.includes(type) &&
rest.rangeConfig &&
Object.keys(rest.rangeConfig).filter((index) => rest.rangeConfig[index].isShowInput).length > 0
RATES.includes(type) && rest?.rangeConfig &&
Object.keys(rest?.rangeConfig).filter((index) => rest?.rangeConfig[index].isShowInput).length > 0
) {
let { rangeConfig, othersValue } = useShowInput(field)
moduleConfig.rangeConfig = unref(rangeConfig)

View File

@ -56,6 +56,8 @@ export default {
return
}
}
router.push({ name: 'renderPage' })
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
const { questionData, questionSeq, rules, formValues } = adapter.generateData({