Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 抽离题型枚举 #272

Merged
merged 3 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -97,5 +97,9 @@
"moduleNameMapper": {
"^src/(.*)$": "<rootDir>/$1"
}
},
"engines": {
"node": ">=18.0.0",
"npm": ">=8.6.0"
}
}
50 changes: 50 additions & 0 deletions web/src/common/typeEnum.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 题型枚举
export enum QUESTION_TYPE {
TEXT = 'text',
TEXTAREA = 'textarea',
RADIO = 'radio',
CHECKBOX = 'checkbox',
BINARY_CHOICE = 'binary-choice',
RADIO_STAR = 'radio-star',
RADIO_NPS = 'radio-nps',
VOTE = 'vote',
}

// 题目类型标签映射对象
export const typeTagLabels: Record<QUESTION_TYPE, string> = {
[QUESTION_TYPE.TEXT]: '单行输入框',
[QUESTION_TYPE.TEXTAREA]: '多行输入框',
[QUESTION_TYPE.RADIO]: '单选',
[QUESTION_TYPE.CHECKBOX]: '多选',
[QUESTION_TYPE.BINARY_CHOICE]: '判断',
[QUESTION_TYPE.RADIO_STAR]: '评分',
[QUESTION_TYPE.RADIO_NPS]: 'NPS评分',
[QUESTION_TYPE.VOTE]: '投票'
}

// 输入类题型
export const INPUT = [
QUESTION_TYPE.TEXT,
QUESTION_TYPE.TEXTAREA
]

// 选择类题型分类
export const NORMAL_CHOICES = [
QUESTION_TYPE.RADIO,
QUESTION_TYPE.CHECKBOX
]

// 选择类题型分类
export const CHOICES = [
QUESTION_TYPE.RADIO,
QUESTION_TYPE.CHECKBOX,
QUESTION_TYPE.BINARY_CHOICE,
QUESTION_TYPE.VOTE
]

// 评分题题型分类
export const RATES = [
QUESTION_TYPE.RADIO_STAR,
QUESTION_TYPE.RADIO_NPS
]

Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
<script setup lang="ts">
import { computed, inject, ref, type ComputedRef } from 'vue'
import { ConditionNode, RuleNode } from '@/common/logicEngine/RuleBuild'
import { qAbleList } from '@/management/utils/constant.js'
import { CHOICES } from '@/common/typeEnum'
import { cleanRichText } from '@/common/xss'
const renderData = inject<ComputedRef<Array<any>>>('renderData') || ref([])
const props = defineProps({
Expand Down Expand Up @@ -94,7 +94,7 @@ const fieldList = computed(() => {
const currentIndex = renderData.value.findIndex((item) => item.field === props.ruleNode.target)
return renderData.value
.slice(0, currentIndex)
.filter((question: any) => qAbleList.includes(question.type))
.filter((question: any) => CHOICES.includes(question.type))
.map((item: any) => {
return {
label: `${item.showIndex ? item.indexNumber + '.' : ''} ${cleanRichText(item.title)}`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import { getQuestionByType } from '@/management/utils/index'
import { useStore } from 'vuex'
import { get as _get, isNumber as _isNumber } from 'lodash-es'
import { computed, ref } from 'vue'

import { QUESTION_TYPE } from '@/common/typeEnum.ts'
const store = useStore()

const activeNames = ref([0, 1])
Expand All @@ -70,8 +70,8 @@ const getNewQuestion = ({ type }) => {
const fields = questionDataList.value.map((item) => item.field)
const newQuestion = getQuestionByType(type, fields)
newQuestion.title = newQuestion.title = `标题${newQuestionIndex.value + 1}`
if (type === 'vote') {
newQuestion.innerType = 'radio'
if (type === QUESTION_TYPE.VOTE) {
newQuestion.innerType = QUESTION_TYPE.RADIO
}
return newQuestion
}
Expand Down
2 changes: 1 addition & 1 deletion web/src/management/pages/list/components/BaseList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ moment.locale('zh-cn')
import EmptyIndex from '@/management/components/EmptyIndex.vue'
import { CODE_MAP } from '@/management/api/base'
import { QOP_MAP } from '@/management/utils/constant'
import { QOP_MAP } from '@/management/utils/constant.ts'
import { deleteSurvey } from '@/management/api/survey'
import ModifyDialog from './ModifyDialog.vue'
import TagModule from './TagModule.vue'
Expand Down
1 change: 0 additions & 1 deletion web/src/management/pages/list/components/SpaceModify.vue
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ import { useStore } from 'vuex'
import { pick as _pick } from 'lodash-es'
import { ElMessage } from 'element-plus'
import 'element-plus/theme-chalk/src/message.scss'
import { QOP_MAP } from '@/management/utils/constant'
import MemberSelect from './MemberSelect.vue'
import { type IMember, type IWorkspace, UserRole } from '@/management/utils/types/workSpace'
Expand Down
2 changes: 1 addition & 1 deletion web/src/management/pages/publish/PublishPage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const mainChannel = computed(() => {
let fullUrl = ''
if (metaData.value) {
fullUrl = `${location.origin}/render/${metaData.value.surveyPath}`
fullUrl = `${location.origin}/render/${metaData.value.surveyPath}?t=${Date.now()}`
}
return { fullUrl }
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
// 问卷操作枚举
export const QOP_MAP = {
ADD: 'add',
COPY: 'copy',
EDIT: 'edit'
export enum QOP_MAP {
ADD = 'add',
COPY = 'copy',
EDIT = 'edit'
}

export const qAbleList = ['radio', 'checkbox', 'binary-choice', 'vote']
export const operatorOptions = [
{
label: '选择了',
Expand Down
3 changes: 2 additions & 1 deletion web/src/management/utils/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defaultQuestionConfig } from '../config/questionConfig'
import { cloneDeep as _cloneDeep, map as _map } from 'lodash-es'
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
const generateQuestionField = () => {
const num = Math.floor(Math.random() * 1000)
return `data${num}`
Expand All @@ -24,7 +25,7 @@ const generateHash = (hashList) => {

function getOptions(type) {
const options = [].concat({ ..._cloneDeep(defaultQuestionConfig) }.options)
if (type === 'binary-choice') {
if (type === QUESTION_TYPE.BINARY_CHOICE) {
options[0].text = '对'
options[1].text = '错'
}
Expand Down
15 changes: 0 additions & 15 deletions web/src/materials/questions/common/config/tagList.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import { ref, computed, inject } from 'vue'
import OptionConfig from '../AdvancedConfig/OptionConfig.vue'
import RateConfig from '../AdvancedConfig/RateConfig.vue'
import ExtraIcon from '../ExtraIcon/index.vue'
import { QUESTION_TYPE } from '@/common/typeEnum'
defineProps({
optionList: {
Expand Down Expand Up @@ -101,7 +102,7 @@ const onVisibleChange = (val) => {
}
const isNps = computed(() => {
return moduleConfig.value.type === 'radio-nps'
return moduleConfig.value.type === QUESTION_TYPE.RADIO_NPS
})
const min = computed(() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { defineComponent, watch, ref, computed } from 'vue'
import { filterXSS } from '@/common/xss'
import tagList from '@materials/questions/common/config/tagList'
import { typeTagLabels } from '@/common/typeEnum.ts'

import './style.scss'

Expand Down Expand Up @@ -58,7 +58,7 @@ export default defineComponent({
let ret = ''
types.forEach((t) => {
if (ret) return
const tv = tagList && tagList[t]
const tv = typeTagLabels && typeTagLabels[t]
if (tv && typeof tv === 'string') {
ret = tv.trim()
}
Expand Down
4 changes: 2 additions & 2 deletions web/src/materials/questions/widgets/VoteModule/index.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { computed, defineComponent } from 'vue'
import { includes } from 'lodash-es'

import { QUESTION_TYPE } from '@/common/typeEnum'
import AnswerProcess from './AnswerProcess/index.vue'
import BaseChoice from '../BaseChoice'

Expand Down Expand Up @@ -56,7 +56,7 @@ export default defineComponent({
}
const myOptions = computed(() => {
const { options } = props
if (props.innerType === 'checkbox') {
if (props.innerType === QUESTION_TYPE.CHECKBOX) {
return options.map((item) => {
return {
...item,
Expand Down
4 changes: 2 additions & 2 deletions web/src/materials/setters/widgets/InputNumber.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
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 {
Expand All @@ -25,7 +25,7 @@ interface Emit {
const emit = defineEmits<Emit>()
const props = defineProps<Props>()
const setterTypes = ['checkbox', 'vote']
const setterTypes = [QUESTION_TYPE.CHECKBOX, QUESTION_TYPE.VOTE]
const modelValue = ref(props.formConfig.value || 0)
const minModelValue = computed(() => {
const { min } = props.formConfig
Expand Down
3 changes: 2 additions & 1 deletion web/src/render/adapter/formValue.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// 定义提交的数据结构:{ field1: '', field2: [], field1_hash1: '', }
import { QUESTION_TYPE } from '@/common/typeEnum.ts'
export default function ({ dataConf }) {
const dataList = dataConf.dataList
const formValues = {}
Expand All @@ -17,7 +18,7 @@ export default function ({ dataConf }) {
// }

// 题型是多选,或者子题型是多选(innerType是用于投票)
if (/checkbox/.test(type) || innerType === 'checkbox') {
if (/checkbox/.test(type) || innerType === QUESTION_TYPE.CHECKBOX) {
value = value ? [value] : []
}
formValues[key] = value
Expand Down
4 changes: 2 additions & 2 deletions web/src/render/adapter/question.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,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
Expand All @@ -13,7 +13,7 @@ function handleOptions(item) {
const cleanOption = {}

// 投票逻辑处理
if (type.indexOf('vote') > -1) {
if (type.indexOf(QUESTION_TYPE.VOTE) > -1) {
cleanOption.voteCount = 0
}

Expand Down
11 changes: 5 additions & 6 deletions web/src/render/adapter/rules.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
keys as _keys,
set as _set
} from 'lodash-es'
import { INPUT, RATES, QUESTION_TYPE } from '@/common/typeEnum.ts'

const regexpMap = {
nd: /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/,
Expand All @@ -28,13 +29,11 @@ const msgMap = {
e: '请输入邮箱',
licensePlate: '请输入车牌号'
}
const inputType = ['text', 'textarea']
const checkBoxTip = '至少选择#min#项,少选择了#less#项'
const checkBoxTipSame = '请选择#min#项,少选择了#less#项'
const textRangeMinTip = '至少输入#min#字'
const numberRangeMinTip = '数字最小为#min#'
const numberRangeMaxTip = '数字最大为#max#'
const radioType = ['radio-star', 'radio-nps']

// 多选题的选项数目限制
export function optionValidator(value, minNum, maxNum) {
Expand Down Expand Up @@ -88,7 +87,7 @@ export function generateValidArr(
numberRangeMax
) {
const validArr = []
const isInput = inputType.indexOf(type) !== -1
const isInput = INPUT.indexOf(type) !== -1
if (isRequired || valid === '*') {
// 输入框的必填校验做trim
if (!isInput) {
Expand Down Expand Up @@ -199,14 +198,14 @@ const generateOthersKeyMap = (question) => {
const { type, field, options, rangeConfig } = question
let othersKeyMap = undefined

if (radioType.includes(type)) {
if (RATES.includes(type)) {
othersKeyMap = {}
for (const key in rangeConfig) {
if (rangeConfig[key].isShowInput) {
othersKeyMap[`${field}_${key}`] = key
}
}
} else if (type.includes('radio') || type.includes('checkbox')) {
} else if (type.includes(QUESTION_TYPE.RADIO) || type.includes(QUESTION_TYPE.CHECKBOX)) {
othersKeyMap = {}
options
.filter((op) => op.others)
Expand Down Expand Up @@ -258,7 +257,7 @@ export default function (questionConfig) {

// 对于选择题支持填写更多信息的,需要做是否必填的校验
if (_keys(othersKeyMap).length) {
if (radioType.includes(type)) {
if (RATES.includes(type)) {
if (rangeConfig) {
for (const key in rangeConfig) {
if (rangeConfig[key].isShowInput && rangeConfig[key].required) {
Expand Down
7 changes: 4 additions & 3 deletions web/src/render/components/QuestionWrapper.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ import { useShowInput } from '@/render/hooks/useShowInput'
import store from '@/render/store'
import { cloneDeep } from 'lodash-es'
import { ruleEngine } from '@/render/hooks/useRuleEngine.js'
import { QUESTION_TYPE } from '@/render/constant/index'

import { NORMAL_CHOICES, RATES, QUESTION_TYPE } from '@/common/typeEnum.ts'

const props = defineProps({
indexNumber: {
Expand Down Expand Up @@ -48,7 +49,7 @@ const questionConfig = computed(() => {
moduleConfig.voteTotal = unref(voteTotal)
}
if (
QUESTION_TYPE.CHOICES.includes(type) &&
NORMAL_CHOICES.includes(type) &&
options.filter((optionItem) => optionItem.others).length > 0
) {
let { options, othersValue } = useShowOthers(field)
Expand All @@ -57,7 +58,7 @@ const questionConfig = computed(() => {
moduleConfig.othersValue = unref(othersValue)
}
if (
QUESTION_TYPE.RATES.includes(type) &&
RATES.includes(type) &&
Object.keys(rest.rangeConfig).filter((index) => rest.rangeConfig[index].isShowInput).length > 0
) {
let { rangeConfig, othersValue } = useShowInput(field)
Expand Down
14 changes: 0 additions & 14 deletions web/src/render/constant/index.js

This file was deleted.