feat: 代码format、升级ts和lint

This commit is contained in:
sudoooooo 2024-07-15 22:38:14 +08:00
parent 5bc5eb8719
commit da1749fb53
34 changed files with 244 additions and 282 deletions

View File

@ -61,8 +61,8 @@
"@types/node": "^20.3.1", "@types/node": "^20.3.1",
"@types/node-forge": "^1.3.11", "@types/node-forge": "^1.3.11",
"@types/supertest": "^2.0.12", "@types/supertest": "^2.0.12",
"@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/eslint-plugin": "^7.16.0",
"@typescript-eslint/parser": "^6.0.0", "@typescript-eslint/parser": "^7.16.0",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",
"eslint": "^8.42.0", "eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0", "eslint-config-prettier": "^9.0.0",
@ -76,7 +76,7 @@
"ts-loader": "^9.4.3", "ts-loader": "^9.4.3",
"ts-node": "^10.9.1", "ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3" "typescript": "^5.5.3"
}, },
"jest": { "jest": {
"moduleFileExtensions": [ "moduleFileExtensions": [

View File

@ -1,55 +1,55 @@
{ {
"bannerConf": { "bannerConf": {
"titleConfig": { "titleConfig": {
"mainTitle": "<h3 style=\"text-align: center\">欢迎填写问卷</h3><p>为了给您提供更好的服务,希望您能抽出几分钟时间,将您的感受和建议告诉我们,<span style=\"color: rgb(204, 0, 0)\">期待您的参与!</span></p>", "mainTitle": "<h3 style=\"text-align: center\">欢迎填写问卷</h3><p>为了给您提供更好的服务,希望您能抽出几分钟时间,将您的感受和建议告诉我们,<span style=\"color: rgb(204, 0, 0)\">期待您的参与!</span></p>",
"subTitle": "" "subTitle": ""
},
"bannerConfig": {
"bgImage": "/imgs/skin/17e06b7604a007e1d3e1453b9ddadc3c.webp",
"videoLink": "",
"postImg": ""
}
}, },
"submitConf": { "bannerConfig": {
"submitTitle": "提交", "bgImage": "/imgs/skin/17e06b7604a007e1d3e1453b9ddadc3c.webp",
"confirmAgain": { "videoLink": "",
"is_again": true, "postImg": ""
"again_text": "确认要提交吗?"
},
"msgContent": {
"msg_200": "提交成功",
"msg_9001": "您来晚了,感谢支持问卷~",
"msg_9002": "请勿多次提交!",
"msg_9003": "您来晚了,已经满额!",
"msg_9004": "提交失败!"
}
},
"bottomConf": {
"logoImage": "/imgs/Logo.webp",
"logoImageWidth": "60%"
},
"baseConf": {
"begTime": "2024-01-01 00:00:00",
"endTime": "2034-01-01 00:00:00",
"tLimit": 0,
"language": "chinese",
"answerBegTime": "00:00:00",
"answerEndTime": "23:59:59"
},
"skinConf": {
"skinColor": "#4a4c5b",
"inputBgColor": "#ffffff",
"backgroundConf": {
"color": "#fff"
},
"themeConf": {
"color": "#ffa600"
},
"contentConf": {
"opacity": 100
}
},
"logicConf": {
"showLogicConf": []
} }
},
"submitConf": {
"submitTitle": "提交",
"confirmAgain": {
"is_again": true,
"again_text": "确认要提交吗?"
},
"msgContent": {
"msg_200": "提交成功",
"msg_9001": "您来晚了,感谢支持问卷~",
"msg_9002": "请勿多次提交!",
"msg_9003": "您来晚了,已经满额!",
"msg_9004": "提交失败!"
}
},
"bottomConf": {
"logoImage": "/imgs/Logo.webp",
"logoImageWidth": "60%"
},
"baseConf": {
"begTime": "2024-01-01 00:00:00",
"endTime": "2034-01-01 00:00:00",
"tLimit": 0,
"language": "chinese",
"answerBegTime": "00:00:00",
"answerEndTime": "23:59:59"
},
"skinConf": {
"skinColor": "#4a4c5b",
"inputBgColor": "#ffffff",
"backgroundConf": {
"color": "#ffffff"
},
"themeConf": {
"color": "#ffa600"
},
"contentConf": {
"opacity": 100
}
},
"logicConf": {
"showLogicConf": []
} }
}

View File

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

View File

@ -154,10 +154,12 @@ describe('WorkspaceController', () => {
count: workspaces.length, count: workspaces.length,
}); });
jest.spyOn(userService, 'getUserListByIds').mockResolvedValue([]); jest.spyOn(userService, 'getUserListByIds').mockResolvedValue([]);
const result = await controller.findAll(req, {curPage:1,pageSize:10}); const result = await controller.findAll(req, {
curPage: 1,
pageSize: 10,
});
expect(result.code).toEqual(200); expect(result.code).toEqual(200);
expect(workspaceMemberService.findAllByUserId).toHaveBeenCalledWith({ expect(workspaceMemberService.findAllByUserId).toHaveBeenCalledWith({
@ -167,7 +169,7 @@ describe('WorkspaceController', () => {
workspaceIdList: memberList.map((item) => item.workspaceId), workspaceIdList: memberList.map((item) => item.workspaceId),
page: 1, page: 1,
limit: 10, limit: 10,
name: undefined name: undefined,
}); });
}); });
}); });

View File

@ -102,6 +102,9 @@ export class WorkspaceService {
where: query, where: query,
skip, skip,
take: limit, take: limit,
order: {
createDate: -1,
},
}); });
return { list: data, count }; return { list: data, count };
} }

View File

@ -7,7 +7,7 @@ export enum QUESTION_TYPE {
BINARY_CHOICE = 'binary-choice', BINARY_CHOICE = 'binary-choice',
RADIO_STAR = 'radio-star', RADIO_STAR = 'radio-star',
RADIO_NPS = 'radio-nps', RADIO_NPS = 'radio-nps',
VOTE = 'vote', VOTE = 'vote'
} }
// 题目类型标签映射对象 // 题目类型标签映射对象
@ -23,19 +23,13 @@ export const typeTagLabels: Record<QUESTION_TYPE, string> = {
} }
// 输入类题型 // 输入类题型
export const INPUT = [ export const INPUT = [QUESTION_TYPE.TEXT, QUESTION_TYPE.TEXTAREA]
QUESTION_TYPE.TEXT,
QUESTION_TYPE.TEXTAREA
]
// 选择类题型分类 // 选择类题型分类
export const NORMAL_CHOICES = [ export const NORMAL_CHOICES = [QUESTION_TYPE.RADIO, QUESTION_TYPE.CHECKBOX]
QUESTION_TYPE.RADIO,
QUESTION_TYPE.CHECKBOX
]
// 选择类题型分类 // 选择类题型分类
export const CHOICES = [ export const CHOICES = [
QUESTION_TYPE.RADIO, QUESTION_TYPE.RADIO,
QUESTION_TYPE.CHECKBOX, QUESTION_TYPE.CHECKBOX,
QUESTION_TYPE.BINARY_CHOICE, QUESTION_TYPE.BINARY_CHOICE,
@ -43,8 +37,4 @@ export const CHOICES = [
] ]
// 评分题题型分类 // 评分题题型分类
export const RATES = [ export const RATES = [QUESTION_TYPE.RADIO_STAR, QUESTION_TYPE.RADIO_NPS]
QUESTION_TYPE.RADIO_STAR,
QUESTION_TYPE.RADIO_NPS
]

View File

@ -58,18 +58,22 @@ const tabArr = [
} }
] ]
const tabs = ref([]) const tabs = ref([])
watch(() => store.state.cooperPermissions, (newVal) => { watch(
tabs.value = [] () => store.state.cooperPermissions,
// (newVal) => {
if (newVal.includes(SurveyPermissions.SurveyManage)) { tabs.value = []
tabs.value.push(tabArr[0]) //
tabs.value.push(tabArr[1]) if (newVal.includes(SurveyPermissions.SurveyManage)) {
} tabs.value.push(tabArr[0])
// tabs.value.push(tabArr[1])
if (newVal.includes(SurveyPermissions.DataManage)) { }
tabs.value.push(tabArr[2]) //
} if (newVal.includes(SurveyPermissions.DataManage)) {
}, { immediate: true }) tabs.value.push(tabArr[2])
}
},
{ immediate: true }
)
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.nav { .nav {

View File

@ -163,7 +163,7 @@ const onMove = () => {}
padding: 0.36rem 0 0.36rem; padding: 0.36rem 0 0.36rem;
border: 1px solid transparent; border: 1px solid transparent;
&.spliter { &.spliter {
border-bottom: 0.12rem solid var(--primary-background-color); border-bottom: 0.1rem solid $spliter-color;
} }
&.mouse-hover { &.mouse-hover {

View File

@ -125,7 +125,7 @@ const closedDialog = () => {
&.pc { &.pc {
display: flex; display: flex;
justify-content: center; justify-content: center;
background: #ffffff; background: #f7f7f7;
box-shadow: 0px 2px 10px -2px rgba(82, 82, 102, 0.2); box-shadow: 0px 2px 10px -2px rgba(82, 82, 102, 0.2);
height: 726px; height: 726px;
.wrapper { .wrapper {

View File

@ -157,7 +157,7 @@ const props = defineProps({
default: 0 default: 0
} }
}) })
const emit = defineEmits(['reflush']) const emit = defineEmits(['refresh'])
const fields = ['type', 'title', 'remark', 'owner', 'state', 'createDate', 'updateDate'] const fields = ['type', 'title', 'remark', 'owner', 'state', 'createDate', 'updateDate']
const showModify = ref(false) const showModify = ref(false)
const modifyType = ref('') const modifyType = ref('')
@ -251,7 +251,7 @@ const workSpaceId = computed(() => {
return store.state.list.workSpaceId return store.state.list.workSpaceId
}) })
const onReflush = async () => { const onRefresh = async () => {
const filterString = JSON.stringify( const filterString = JSON.stringify(
filter.value.filter((item) => { filter.value.filter((item) => {
return item.condition[0].value return item.condition[0].value
@ -265,7 +265,7 @@ const onReflush = async () => {
if (workSpaceId.value) { if (workSpaceId.value) {
params.workspaceId = workSpaceId.value params.workspaceId = workSpaceId.value
} }
emit('reflush', params) emit('refresh', params)
} }
const getToolConfig = (row) => { const getToolConfig = (row) => {
@ -400,14 +400,14 @@ const onDelete = async (row) => {
const res = await deleteSurvey(row._id) const res = await deleteSurvey(row._id)
if (res.code === CODE_MAP.SUCCESS) { if (res.code === CODE_MAP.SUCCESS) {
ElMessage.success('删除成功') ElMessage.success('删除成功')
onReflush() onRefresh()
} else { } else {
ElMessage.error(res.errmsg || '删除失败') ElMessage.error(res.errmsg || '删除失败')
} }
} }
const handleCurrentChange = (current) => { const handleCurrentChange = (current) => {
currentPage.value = current currentPage.value = current
onReflush() onRefresh()
} }
const onModify = (data, type = QOP_MAP.EDIT) => { const onModify = (data, type = QOP_MAP.EDIT) => {
showModify.value = true showModify.value = true
@ -418,7 +418,7 @@ const onCloseModify = (type) => {
showModify.value = false showModify.value = false
questionInfo.value = {} questionInfo.value = {}
if (type === 'update') { if (type === 'update') {
onReflush() onRefresh()
} }
} }
const onRowClick = (row) => { const onRowClick = (row) => {
@ -432,18 +432,18 @@ const onRowClick = (row) => {
const onSearchText = (e) => { const onSearchText = (e) => {
store.commit('list/setSearchVal', e) store.commit('list/setSearchVal', e)
currentPage.value = 1 currentPage.value = 1
onReflush() onRefresh()
} }
const onSelectChange = (selectKey, selectValue) => { const onSelectChange = (selectKey, selectValue) => {
store.commit('list/changeSelectValueMap', { key: selectKey, value: selectValue }) store.commit('list/changeSelectValueMap', { key: selectKey, value: selectValue })
// selectValueMap.value[selectKey] = selectValue // selectValueMap.value[selectKey] = selectValue
currentPage.value = 1 currentPage.value = 1
onReflush() onRefresh()
} }
const onButtonChange = (effectKey, effectValue) => { const onButtonChange = (effectKey, effectValue) => {
store.commit('list/reserButtonValueMap') store.commit('list/resetButtonValueMap')
store.commit('list/changeButtonValueMap', { key: effectKey, value: effectValue }) store.commit('list/changeButtonValueMap', { key: effectKey, value: effectValue })
onReflush() onRefresh()
} }
const cooperModify = ref(false) const cooperModify = ref(false)

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="search"> <div class="search">
<TextSearch placeholder="请输入问卷标题" :value="searchVal" @search="onSearchText" /> <TextSearch placeholder="请输入空间名称" :value="searchVal" @search="onSearchText" />
</div> </div>
<div class="list-wrap" v-if="props.total > 0"> <div class="list-wrap" v-if="props.total > 0">
<el-table <el-table
@ -75,7 +75,7 @@
/> />
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, watch } from 'vue' import { ref, computed } from 'vue'
import { useStore } from 'vuex' import { useStore } from 'vuex'
import { ElMessageBox } from 'element-plus' import { ElMessageBox } from 'element-plus'
import 'element-plus/theme-chalk/src/message-box.scss' import 'element-plus/theme-chalk/src/message-box.scss'
@ -91,7 +91,6 @@ import EmptyIndex from '@/management/components/EmptyIndex.vue'
import ToolBar from './ToolBar.vue' import ToolBar from './ToolBar.vue'
import { UserRole } from '@/management/utils/types/workSpace' import { UserRole } from '@/management/utils/types/workSpace'
const showSpaceModify = ref(false) const showSpaceModify = ref(false)
const modifyType = ref('edit') const modifyType = ref('edit')
const store = useStore() const store = useStore()
@ -109,7 +108,7 @@ const props = defineProps({
default: 0 default: 0
} }
}) })
const emit = defineEmits(['reflush']) const emit = defineEmits(['refresh'])
const fields = ['name', 'surveyTotal', 'memberTotal', 'owner', 'createDate'] const fields = ['name', 'surveyTotal', 'memberTotal', 'owner', 'createDate']
const fieldList = computed(() => { const fieldList = computed(() => {
return map(fields, (f) => { return map(fields, (f) => {
@ -128,19 +127,19 @@ const data = computed(() => {
}) })
let searchVal = ref('') let searchVal = ref('')
let curPage = ref(1) let curPage = ref(1)
const emitReflush = (page: number, name: string) => { const emitRefresh = (page: number, name: string) => {
curPage.value = page curPage.value = page
emit('reflush', { emit('refresh', {
curPage: page, curPage: page,
name name
}) })
} }
const handleCurrentChange = async (val: number) => { const handleCurrentChange = async (val: number) => {
emitReflush(val, searchVal.value) emitRefresh(val, searchVal.value)
} }
const onSearchText = async (e: string) => { const onSearchText = async (value: string) => {
searchVal.value = e searchVal.value = value
emitReflush(1, e) emitRefresh(1, value)
} }
const getTools = (data: any) => { const getTools = (data: any) => {

View File

@ -30,7 +30,7 @@
<i class="iconfont icon-chuangjian"></i> <i class="iconfont icon-chuangjian"></i>
<span>创建团队空间</span> <span>创建团队空间</span>
</el-button> </el-button>
<el-button type="default" @click="onSetGroup" v-if="workSpaceId"> <el-button type="default" class="btn" @click="onSetGroup" v-if="workSpaceId">
<i class="iconfont icon-shujuliebiao"></i> <i class="iconfont icon-shujuliebiao"></i>
<span>团队管理</span> <span>团队管理</span>
</el-button> </el-button>
@ -49,13 +49,13 @@
:loading="loading" :loading="loading"
:data="surveyList" :data="surveyList"
:total="surveyTotal" :total="surveyTotal"
@reflush="fetchSurveyList" @refresh="fetchSurveyList"
v-if="spaceType !== SpaceType.Group" v-if="spaceType !== SpaceType.Group"
></BaseList> ></BaseList>
<SpaceList <SpaceList
ref="spaceListRef" ref="spaceListRef"
@reflush="fetchSpaceList" @refresh="fetchSpaceList"
:loading="loading2" :loading="spaceLoading"
:data="spaceList" :data="spaceList"
:total="spaceTotal" :total="spaceTotal"
v-if="spaceType === SpaceType.Group" v-if="spaceType === SpaceType.Group"
@ -93,8 +93,8 @@ const surveyList = computed(() => {
const surveyTotal = computed(() => { const surveyTotal = computed(() => {
return store.state.list.surveyTotal return store.state.list.surveyTotal
}) })
let spaceListRef = ref<InstanceType<typeof SpaceList> | null>(null) const spaceListRef = ref<InstanceType | null>(null)
const loading2 = ref(false) const spaceLoading = ref(false)
const spaceList = computed(() => { const spaceList = computed(() => {
return store.state.list.teamSpaceList return store.state.list.teamSpaceList
}) })
@ -102,10 +102,10 @@ const spaceTotal = computed(() => {
return store.state.list.teamSpaceListTotal return store.state.list.teamSpaceListTotal
}) })
const fetchSpaceList = async (params?: any) => { const fetchSpaceList = async (params?: any) => {
loading2.value = true spaceLoading.value = true
store.commit('list/changeWorkSpace', '') store.commit('list/changeWorkSpace', '')
await store.dispatch('list/getSpaceList', params) await store.dispatch('list/getSpaceList', params)
loading2.value = false spaceLoading.value = false
} }
const activeIndex = ref('1') const activeIndex = ref('1')
@ -277,8 +277,9 @@ const handleLogout = () => {
.create-btn { .create-btn {
background: #4a4c5b; background: #4a4c5b;
color: #fff;
} }
.btn { .btn {
width: 132px; width: 132px;
height: 32px; height: 32px;
@ -286,10 +287,9 @@ const handleLogout = () => {
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: #fff; .icon-shujuliebiao,
.icon-chuangjian { .icon-chuangjian {
padding-right: 8px; padding-right: 5px;
font-size: 14px; font-size: 14px;
} }

View File

@ -1,4 +1,9 @@
import { createRouter, createWebHistory, type RouteLocationNormalized, type NavigationGuardNext } from 'vue-router' import {
createRouter,
createWebHistory,
type RouteLocationNormalized,
type NavigationGuardNext
} from 'vue-router'
import type { RouteRecordRaw } from 'vue-router' import type { RouteRecordRaw } from 'vue-router'
import { useStore, type Store } from 'vuex' import { useStore, type Store } from 'vuex'
import { SurveyPermissions } from '@/management/utils/types/workSpace' import { SurveyPermissions } from '@/management/utils/types/workSpace'
@ -156,35 +161,45 @@ const router = createRouter({
}) })
router.beforeEach(async (to, from, next) => { router.beforeEach(async (to, from, next) => {
const store = useStore(); const store = useStore()
// 初始化用户信息 // 初始化用户信息
if (!store.state.user?.initialized) { if (!store.state.user?.initialized) {
await store.dispatch('user/init'); await store.dispatch('user/init')
} }
// 更新页面标题 // 更新页面标题
if (to.meta.title) { if (to.meta.title) {
document.title = to.meta.title as string; document.title = to.meta.title as string
} }
if (to.meta.needLogin) { if (to.meta.needLogin) {
await handleLoginGuard(to, from, next, store); await handleLoginGuard(to, from, next, store)
} else { } else {
next(); next()
} }
}); })
async function handleLoginGuard(to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext, store: Store<any>) { async function handleLoginGuard(
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext,
store: Store<any>
) {
if (store.state.user?.hasLogined) { if (store.state.user?.hasLogined) {
await handlePermissionsGuard(to, from, next, store); await handlePermissionsGuard(to, from, next, store)
} else { } else {
next({ next({
name: 'login', name: 'login',
query: { redirect: encodeURIComponent(to.path) }, query: { redirect: encodeURIComponent(to.path) }
}); })
} }
} }
async function handlePermissionsGuard(to: RouteLocationNormalized, from: RouteLocationNormalized, next: NavigationGuardNext, store: Store<any>) { async function handlePermissionsGuard(
to: RouteLocationNormalized,
from: RouteLocationNormalized,
next: NavigationGuardNext,
store: Store<any>
) {
const currSurveyId = to?.params?.id || '' const currSurveyId = to?.params?.id || ''
const prevSurveyId = from?.params?.id || '' const prevSurveyId = from?.params?.id || ''
// 如果跳转页面不存在surveyId 或者不需要页面权限,则直接跳转 // 如果跳转页面不存在surveyId 或者不需要页面权限,则直接跳转
@ -195,21 +210,19 @@ async function handlePermissionsGuard(to: RouteLocationNormalized, from: RouteLo
if (currSurveyId !== prevSurveyId) { if (currSurveyId !== prevSurveyId) {
await store.dispatch('fetchCooperPermissions', currSurveyId) await store.dispatch('fetchCooperPermissions', currSurveyId)
if (hasRequiredPermissions(to.meta.permissions as string[], store.state.cooperPermissions)) { if (hasRequiredPermissions(to.meta.permissions as string[], store.state.cooperPermissions)) {
next(); next()
} else { } else {
ElMessage.warning('您没有该问卷的相关协作权限'); ElMessage.warning('您没有该问卷的相关协作权限')
next({ name: 'survey' }); next({ name: 'survey' })
} }
} else { } else {
next(); next()
} }
} }
} }
function hasRequiredPermissions(requiredPermissions: string[], userPermissions: string[]) { function hasRequiredPermissions(requiredPermissions: string[], userPermissions: string[]) {
return requiredPermissions.some(permission => userPermissions.includes(permission)); return requiredPermissions.some((permission) => userPermissions.includes(permission))
} }
export default router export default router

View File

@ -107,8 +107,8 @@ export default {
}, },
changeWorkSpace(state, workSpaceId) { changeWorkSpace(state, workSpaceId) {
// 切换空间清除筛选条件 // 切换空间清除筛选条件
this.commit('list/reserSelectValueMap') this.commit('list/resetSelectValueMap')
this.commit('list/reserButtonValueMap') this.commit('list/resetButtonValueMap')
this.commit('list/setSearchVal', '') this.commit('list/setSearchVal', '')
state.workSpaceId = workSpaceId state.workSpaceId = workSpaceId
}, },
@ -130,7 +130,7 @@ export default {
setSearchVal(state, data) { setSearchVal(state, data) {
state.searchVal = data state.searchVal = data
}, },
reserSelectValueMap(state) { resetSelectValueMap(state) {
state.selectValueMap = { state.selectValueMap = {
surveyType: '', surveyType: '',
'curStatus.status': '' 'curStatus.status': ''
@ -139,7 +139,7 @@ export default {
changeSelectValueMap(state, { key, value }) { changeSelectValueMap(state, { key, value }) {
state.selectValueMap[key] = value state.selectValueMap[key] = value
}, },
reserButtonValueMap(state) { resetButtonValueMap(state) {
state.buttonValueMap = { state.buttonValueMap = {
'curStatus.date': '', 'curStatus.date': '',
createDate: -1 createDate: -1

View File

@ -33,7 +33,7 @@ $remark-color: #4a4c5b;
$placeholder-color: #c8c9cd; $placeholder-color: #c8c9cd;
$light-focus-color: #666666; $light-focus-color: #666666;
$spliter-color: #f7f7f7; $spliter-color: hsl(0, 0%, 97%, 0.5);
$error-color: #ec4e29; $error-color: #ec4e29;

View File

@ -39,19 +39,20 @@ export const getQuestionByType = (type, fields) => {
const questionMeta = questionLoader.getMeta(type) const questionMeta = questionLoader.getMeta(type)
const { attrs } = questionMeta const { attrs } = questionMeta
let newQuestion = defaultQuestionConfig let newQuestion = defaultQuestionConfig
if( attrs ) { if (attrs) {
let questionSchema = {} let questionSchema = {}
attrs.forEach(element => { attrs.forEach((element) => {
questionSchema[element.name] = element.defaultValue questionSchema[element.name] = element.defaultValue
}); })
newQuestion = questionSchema newQuestion = questionSchema
} else { } else {
newQuestion = defaultQuestionConfig newQuestion = defaultQuestionConfig
newQuestion.type = type newQuestion.type = type
} }
newQuestion.field = getNewField(fields) // 动态生成题目id newQuestion.field = getNewField(fields) // 动态生成题目id
if('options ' in newQuestion) { // 动态更新选项的hash-id if ('options ' in newQuestion) {
// 动态更新选项的hash-id
const hashList = [] const hashList = []
for (const option of newQuestion.options) { for (const option of newQuestion.options) {
const hash = generateHash(hashList) const hash = generateHash(hashList)
@ -59,7 +60,7 @@ export const getQuestionByType = (type, fields) => {
option.hash = hash option.hash = hash
} }
} }
return newQuestion return newQuestion
} }

View File

@ -111,20 +111,10 @@ export default defineComponent({
editConfigure={questionMeta?.editConfigure} editConfigure={questionMeta?.editConfigure}
onChange={this.onChange} onChange={this.onChange}
> >
<dynamicComponent <dynamicComponent readonly {...props} onBlur={this.onBlur} onFocus={this.onFocus} />
readonly
{...props}
onBlur={this.onBlur}
onFocus={this.onFocus}
/>
</EditOptions> </EditOptions>
) : ( ) : (
<dynamicComponent <dynamicComponent readonly {...props} onBlur={this.onBlur} onFocus={this.onFocus} />
readonly
{...props}
onBlur={this.onBlur}
onFocus={this.onFocus}
/>
)} )}
</div> </div>
</div> </div>

View File

@ -94,7 +94,7 @@
} }
&.spliter { &.spliter {
border-bottom: 0.12rem solid var(--primary-background-color); border-bottom: 0.1rem solid $spliter-color;
} }
.sort-tip { .sort-tip {

View File

@ -11,7 +11,7 @@ $light-focus-color: #666666;
$disable-color: #f2f4f7; $disable-color: #f2f4f7;
$border-color: #dee2e6; $border-color: #dee2e6;
$spliter-color: #f7f7f7; $spliter-color: hsl(0, 0%, 97%, 0.5);
$error-color: #ec4e29; $error-color: #ec4e29;

View File

@ -53,25 +53,25 @@ const meta = {
description: '这是用于描述选项', description: '这是用于描述选项',
defaultValue: [ defaultValue: [
{ {
"text": "对", text: '对',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115019" hash: '115019'
}, },
{ {
"text": "错", text: '错',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115020" hash: '115020'
} }
] ]
}, }
], ],
formConfig: [basicConfig], formConfig: [basicConfig],
editConfigure: { editConfigure: {

View File

@ -53,22 +53,22 @@ const meta = {
description: '这是用于描述选项', description: '这是用于描述选项',
defaultValue: [ defaultValue: [
{ {
"text": "选项1", text: '选项1',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115019" hash: '115019'
}, },
{ {
"text": "选项2", text: '选项2',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115020" hash: '115020'
} }
] ]
}, },

View File

@ -19,7 +19,7 @@
} }
} }
.question-block { .question-block {
padding: 0!important; padding: 0 !important;
} }
.radio-nps-hover { .radio-nps-hover {
.rate-item { .rate-item {

View File

@ -53,29 +53,27 @@ const meta = {
description: '这是用于描述选项', description: '这是用于描述选项',
defaultValue: [ defaultValue: [
{ {
"text": "选项1", text: '选项1',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115019" hash: '115019'
}, },
{ {
"text": "选项2", text: '选项2',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115020" hash: '115020'
} }
] ]
}, }
],
formConfig: [
basicConfig,
], ],
formConfig: [basicConfig],
editConfigure: { editConfigure: {
optionEdit: { optionEdit: {
show: true show: true

View File

@ -63,14 +63,14 @@ const meta = {
name: 'starStyle', name: 'starStyle',
propType: String, propType: String,
description: '', description: '',
defaultValue: 'star', defaultValue: 'star'
}, },
{ {
name: 'rangeConfig', name: 'rangeConfig',
propType: Object, propType: Object,
description: '这是用于描述评分高级设置', description: '这是用于描述评分高级设置',
defaultValue: {} defaultValue: {}
}, }
], ],
formConfig: [ formConfig: [
basicConfig, basicConfig,

View File

@ -70,11 +70,9 @@ export default defineComponent({
class="rich-editor" class="rich-editor"
modelValue={filterXSS(this.title)} modelValue={filterXSS(this.title)}
onChange={this.handleChange} onChange={this.handleChange}
onCreated={ onCreated={(editor) => {
(editor) => { editor?.focus()
editor?.focus() }}
}
}
/> />
) )
} }

View File

@ -53,22 +53,22 @@ const meta = {
description: '这是用于描述选项', description: '这是用于描述选项',
defaultValue: [ defaultValue: [
{ {
"text": "选项1", text: '选项1',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115019" hash: '115019'
}, },
{ {
"text": "选项2", text: '选项2',
"imageUrl": "", imageUrl: '',
"others": false, others: false,
"mustOthers": false, mustOthers: false,
"othersKey": "", othersKey: '',
"placeholderDesc": "", placeholderDesc: '',
"hash": "115020" hash: '115020'
} }
] ]
}, },

View File

@ -15,12 +15,7 @@ interface Props {
formConfig: any formConfig: any
} }
interface Emit { const emit = defineEmits([FORM_CHANGE_EVENT_KEY, 'change', 'input'])
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: string }): void
(ev: 'change' | 'input', value: string): void
}
const emit = defineEmits<Emit>()
const props = withDefaults(defineProps<Props>(), { formConfig: {} }) const props = withDefaults(defineProps<Props>(), { formConfig: {} })
const handleEditorValueChange = (eventType: 'change' | 'input', value: string) => { const handleEditorValueChange = (eventType: 'change' | 'input', value: string) => {

View File

@ -199,7 +199,7 @@ const generateOthersKeyMap = (question) => {
let othersKeyMap = undefined let othersKeyMap = undefined
if (RATES.includes(type)) { if (RATES.includes(type)) {
const { rangeConfig } = question const { rangeConfig } = question
othersKeyMap = {} othersKeyMap = {}
for (const key in rangeConfig) { for (const key in rangeConfig) {
if (rangeConfig[key].isShowInput) { if (rangeConfig[key].isShowInput) {
@ -207,7 +207,7 @@ const generateOthersKeyMap = (question) => {
} }
} }
} 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 const { options } = question
othersKeyMap = {} othersKeyMap = {}
options options
.filter((op) => op.others) .filter((op) => op.others)

View File

@ -57,8 +57,10 @@ const questionConfig = computed(() => {
moduleConfig.othersValue = unref(othersValue) moduleConfig.othersValue = unref(othersValue)
} }
if ( if (
RATES.includes(type) && rest?.rangeConfig && RATES.includes(type) &&
Object.keys(rest?.rangeConfig).filter((index) => rest?.rangeConfig[index].isShowInput).length > 0 rest?.rangeConfig &&
Object.keys(rest?.rangeConfig).filter((index) => rest?.rangeConfig[index].isShowInput).length >
0
) { ) {
let { rangeConfig, othersValue } = useShowInput(field) let { rangeConfig, othersValue } = useShowInput(field)
moduleConfig.rangeConfig = unref(rangeConfig) moduleConfig.rangeConfig = unref(rangeConfig)

View File

@ -7,9 +7,7 @@
</div> </div>
</template> </template>
<script setup> <script setup></script>
</script>
<style scoped> <style scoped>
.container { .container {

View File

@ -17,15 +17,8 @@ const route = useRoute()
const loadData = (res: any, surveyPath: string) => { const loadData = (res: any, surveyPath: string) => {
if (res.code === 200) { if (res.code === 200) {
const data = res.data const data = res.data
const { const { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf, logicConf } =
bannerConf, data.code
baseConf,
bottomConf,
dataConf,
skinConf,
submitConf,
logicConf
} = data.code
const questionData = { const questionData = {
bannerConf, bannerConf,
baseConf, baseConf,

View File

@ -18,10 +18,7 @@ const VOTE_INFO_KEY = 'voteinfo'
import router from '../router' import router from '../router'
export default { export default {
// 初始化 // 初始化
init( init({ commit, dispatch }, { bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }) {
{ commit, dispatch },
{ bannerConf, baseConf, bottomConf, dataConf, skinConf, submitConf }
) {
commit('setEnterTime') commit('setEnterTime')
const { begTime, endTime, answerBegTime, answerEndTime } = baseConf const { begTime, endTime, answerBegTime, answerEndTime } = baseConf
const { msgContent } = submitConf const { msgContent } = submitConf
@ -58,7 +55,6 @@ export default {
} }
router.push({ name: 'renderPage' }) router.push({ name: 'renderPage' })
// 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段 // 根据初始的schema生成questionData, questionSeq, rules, formValues, 这四个字段
const { questionData, questionSeq, rules, formValues } = adapter.generateData({ const { questionData, questionSeq, rules, formValues } = adapter.generateData({
bannerConf, bannerConf,

View File

@ -1,22 +0,0 @@
$primary-color: #faa600;
$primary-color-light: hsl(48, 100%, 97%);
$title-color-deep: #292a36;
$title-color: #4a4c5b;
$font-color: #6e707c;
$remark-color: #4a4c5b;
$placeholder-color: #c8c9cd;
$light-focus-color: #666666;
$disable-color: #f2f4f7;
$border-color: #dee2e6;
$spliter-color: #f7f7f7;
$error-color: #ec4e29;
@import './variable';
$title-size: 0.32rem;
$font-size: 0.28rem;
$tip-size: 0.22rem;

View File

@ -10,6 +10,6 @@ $placeholder-color: #c8c9cd;
$disable-color: #f2f4f7; $disable-color: #f2f4f7;
$border-color: #dee2e6; $border-color: #dee2e6;
$spliter-color: #f7f7f7; $spliter-color: hsl(0, 0%, 97%, 0.5);
$error-color: #ec4e29; $error-color: #ec4e29;