refactor: 重构 management/pages/edit 目录下组件, 使用 Vue3 组合式 API 写法 (#251)
This commit is contained in:
parent
d9255db8a9
commit
cffe037269
@ -14,22 +14,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { get as _get } from 'lodash-es'
|
||||||
|
|
||||||
import BackPanel from '../modules/generalModule/BackPanel.vue'
|
import BackPanel from '../modules/generalModule/BackPanel.vue'
|
||||||
import TitlePanel from '../modules/generalModule/TitlePanel.vue'
|
import TitlePanel from '../modules/generalModule/TitlePanel.vue'
|
||||||
import NavPanel from '../modules/generalModule/NavPanel.vue'
|
import NavPanel from '../modules/generalModule/NavPanel.vue'
|
||||||
import HistoryPanel from '../modules/contentModule/HistoryPanel.vue'
|
import HistoryPanel from '../modules/contentModule/HistoryPanel.vue'
|
||||||
import SavePanel from '../modules/contentModule/SavePanel.vue'
|
import SavePanel from '../modules/contentModule/SavePanel.vue'
|
||||||
import PublishPanel from '../modules/contentModule/PublishPanel.vue'
|
import PublishPanel from '../modules/contentModule/PublishPanel.vue'
|
||||||
import { useStore } from 'vuex'
|
|
||||||
import { get as _get } from 'lodash-es'
|
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
const title = computed(() => _get(store.state, 'edit.schema.metaData.title'))
|
const title = computed(() => _get(store.state, 'edit.schema.metaData.title'))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.nav {
|
.nav {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -16,28 +16,28 @@
|
|||||||
:form-config="content"
|
:form-config="content"
|
||||||
>
|
>
|
||||||
<Component
|
<Component
|
||||||
:is="content.type"
|
:is="components[content.type]"
|
||||||
:form-config="content"
|
:form-config="content"
|
||||||
:module-config="moduleConfig"
|
:module-config="moduleConfig"
|
||||||
@form-change="onFormChange($event, content)"
|
@form-change="handleFormChange($event, content)"
|
||||||
:class="content.contentClass"
|
:class="content.contentClass"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</template>
|
</template>
|
||||||
<FormItem v-else :form-config="item">
|
<FormItem v-else :form-config="item">
|
||||||
<Component
|
<Component
|
||||||
:is="item.type"
|
:is="components[item.type]"
|
||||||
:form-config="item"
|
:form-config="item"
|
||||||
:module-config="moduleConfig"
|
:module-config="moduleConfig"
|
||||||
@form-change="onFormChange($event, item)"
|
@form-change="handleFormChange($event, item)"
|
||||||
:class="item.contentClass"
|
:class="item.contentClass"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</div>
|
</div>
|
||||||
</el-form>
|
</el-form>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { watch, ref, shallowRef } 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 } from 'lodash-es'
|
||||||
|
|
||||||
import FormItem from '@/materials/setters/widgets/FormItem.vue'
|
import FormItem from '@/materials/setters/widgets/FormItem.vue'
|
||||||
@ -45,8 +45,20 @@ import setterLoader from '@/materials/setters/setterLoader'
|
|||||||
|
|
||||||
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
|
import { FORM_CHANGE_EVENT_KEY } from '@/materials/setters/constant'
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
formConfigList: Array<any>
|
||||||
|
moduleConfig: any
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Emit {
|
||||||
|
(ev: typeof FORM_CHANGE_EVENT_KEY, arg: { key: string; value: any }): void
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const emit = defineEmits<Emit>()
|
||||||
|
|
||||||
// 静态配置设置动态值
|
// 静态配置设置动态值
|
||||||
const formatValue = ({ item, moduleConfig }) => {
|
const formatValue = ({ item, moduleConfig }: any) => {
|
||||||
if (_isFunction(item.valueAdapter)) {
|
if (_isFunction(item.valueAdapter)) {
|
||||||
const value = item.valueAdapter({ moduleConfig })
|
const value = item.valueAdapter({ moduleConfig })
|
||||||
|
|
||||||
@ -65,89 +77,64 @@ const formatValue = ({ item, moduleConfig }) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
const formFieldData = ref<Array<any>>([])
|
||||||
name: 'SettersField',
|
const init = ref<boolean>(true)
|
||||||
props: {
|
const components = shallowRef<any>({})
|
||||||
formConfigList: Array, // 对应题型组件的meta.js内容
|
|
||||||
moduleConfig: Object
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
register: {},
|
|
||||||
formFieldData: [],
|
|
||||||
init: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
FormItem
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
formConfigList: {
|
|
||||||
deep: true,
|
|
||||||
immediate: true,
|
|
||||||
async handler(newVal) {
|
|
||||||
this.init = true
|
|
||||||
if (!newVal || !newVal.length) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// 组件注册
|
const handleFormChange = (data: any, formConfig: any) => {
|
||||||
await this.handleComponentRegister(newVal)
|
if (_isFunction(formConfig?.setterAdapter)) {
|
||||||
|
const resultData = formConfig.setterAdapter(data)
|
||||||
|
|
||||||
this.init = false
|
if (Array.isArray(resultData)) {
|
||||||
this.formFieldData = this.setValues(this.formConfigList)
|
resultData.forEach((item) => {
|
||||||
|
emit(FORM_CHANGE_EVENT_KEY, item)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
emit(FORM_CHANGE_EVENT_KEY, resultData)
|
||||||
}
|
}
|
||||||
},
|
} else {
|
||||||
// schema变化联动
|
emit(FORM_CHANGE_EVENT_KEY, data)
|
||||||
moduleConfig: {
|
|
||||||
deep: true,
|
|
||||||
async handler() {
|
|
||||||
// 配置变化后初次不监听value变化(如题型切换场景避免多次计算)
|
|
||||||
if (this.init) {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: 优化,依赖的schema变化时,均会重新计算
|
const normalizationValues = (configList: Array<any> = []) => {
|
||||||
this.formFieldData = this.setValues(this.formConfigList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
setValues(configList = []) {
|
|
||||||
return configList
|
return configList
|
||||||
.filter((item) => {
|
.filter((item: any) => {
|
||||||
// 组件组
|
// 组件组
|
||||||
if (item.type === 'Customed') {
|
if (item.type === 'Customed') {
|
||||||
item.content = this.setValues(item.content)
|
item.content = normalizationValues(item.content)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!item.type) {
|
if (!item.type) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item.hidden) {
|
if (item.hidden) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态显隐设置器
|
// 动态显隐设置器
|
||||||
if (_isFunction(item.relyFunc)) {
|
if (_isFunction(item.relyFunc)) {
|
||||||
return item.relyFunc(this.moduleConfig)
|
return item.relyFunc(props.moduleConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
.map((item) => {
|
.map((item: any) => {
|
||||||
return {
|
return {
|
||||||
...item,
|
...item,
|
||||||
value: formatValue({ item, moduleConfig: this.moduleConfig }) // 动态复值
|
value: formatValue({ item, moduleConfig: props.moduleConfig }) // 动态复值
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
async handleComponentRegister(formFieldData) {
|
|
||||||
let innerSetters = []
|
const registerComponents = async (formFieldData: any) => {
|
||||||
const setters = formFieldData.map((item) => {
|
let innerSetters: Array<any> = []
|
||||||
|
|
||||||
|
const setters = formFieldData.map((item: any) => {
|
||||||
if (item.type === 'Customed') {
|
if (item.type === 'Customed') {
|
||||||
innerSetters.push(...(item.content || []).map((content) => content.type))
|
innerSetters.push(...(item.content || []).map((content: any) => content.type))
|
||||||
}
|
}
|
||||||
|
|
||||||
return item.type
|
return item.type
|
||||||
@ -155,51 +142,65 @@ export default {
|
|||||||
|
|
||||||
const settersSet = new Set([...setters, ...innerSetters])
|
const settersSet = new Set([...setters, ...innerSetters])
|
||||||
const settersArr = Array.from(settersSet)
|
const settersArr = Array.from(settersSet)
|
||||||
const allSetters = settersArr.map((item) => {
|
const allSetters = settersArr.map((item) => ({
|
||||||
return {
|
|
||||||
type: item,
|
type: item,
|
||||||
path: item
|
path: item
|
||||||
}
|
}))
|
||||||
})
|
|
||||||
try {
|
try {
|
||||||
const comps = await setterLoader.loadComponents(allSetters)
|
const comps = await setterLoader.loadComponents(allSetters)
|
||||||
|
|
||||||
for (const comp of comps) {
|
for (const comp of comps) {
|
||||||
if (!comp) {
|
if (!comp) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, component, err } = comp
|
const { type, component, err } = comp
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
const componentName = component.name
|
components.value[type] = component
|
||||||
if (!this.$options.components) {
|
|
||||||
this.$options.components = {}
|
|
||||||
}
|
|
||||||
this.$options.components[componentName] = component
|
|
||||||
this.register[type] = componentName
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
onFormChange(data, formConfig) {
|
|
||||||
if (_isFunction(formConfig?.setterAdapter)) {
|
|
||||||
const resultData = formConfig.setterAdapter(data)
|
|
||||||
if (Array.isArray(resultData)) {
|
|
||||||
resultData.forEach((item) => {
|
|
||||||
this.$emit(FORM_CHANGE_EVENT_KEY, item)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
this.$emit(FORM_CHANGE_EVENT_KEY, resultData)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.$emit(FORM_CHANGE_EVENT_KEY, data)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.formConfigList,
|
||||||
|
async (newVal: Array<any>) => {
|
||||||
|
init.value = true
|
||||||
|
|
||||||
|
if (!newVal || !newVal.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await registerComponents(newVal)
|
||||||
|
init.value = false
|
||||||
|
formFieldData.value = normalizationValues(newVal)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true,
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.moduleConfig,
|
||||||
|
() => {
|
||||||
|
// 配置变化后初次不监听value变化(如题型切换场景避免多次计算)
|
||||||
|
if (init.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: 优化,依赖的schema变化时,均会重新计算
|
||||||
|
formFieldData.value = normalizationValues(props.formConfigList)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
deep: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.config-form {
|
.config-form {
|
||||||
padding: 15px 0;
|
padding: 15px 0;
|
||||||
|
@ -13,42 +13,38 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { onMounted } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import 'element-plus/theme-chalk/src/message.scss'
|
import 'element-plus/theme-chalk/src/message.scss'
|
||||||
|
|
||||||
import LeftMenu from '@/management/components/LeftMenu.vue'
|
import LeftMenu from '@/management/components/LeftMenu.vue'
|
||||||
|
|
||||||
import CommonTemplate from './components/CommonTemplate.vue'
|
import CommonTemplate from './components/CommonTemplate.vue'
|
||||||
import Navbar from './components/ModuleNavbar.vue'
|
import Navbar from './components/ModuleNavbar.vue'
|
||||||
|
|
||||||
import { initShowLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
import { initShowLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
||||||
export default {
|
|
||||||
name: 'questionEditPage',
|
const store = useStore()
|
||||||
components: {
|
const router = useRouter()
|
||||||
CommonTemplate,
|
const route = useRoute()
|
||||||
Navbar,
|
|
||||||
LeftMenu
|
onMounted(async () => {
|
||||||
},
|
store.commit('edit/setSurveyId', route.params.id)
|
||||||
async created() {
|
|
||||||
this.$store.commit('edit/setSurveyId', this.$route.params.id)
|
|
||||||
try {
|
try {
|
||||||
await this.$store.dispatch('edit/init')
|
await store.dispatch('edit/init')
|
||||||
// await this.$store.dispatch('logic/initShowLogic', this.$store.state.edit.schema.logicConf.showLogicConf || {})
|
await initShowLogicEngine(store.state.edit.schema.logicConf.showLogicConf || {})
|
||||||
await initShowLogicEngine(this.$store.state.edit.schema.logicConf.showLogicConf || {})
|
} catch (err: any) {
|
||||||
} catch (error) {
|
ElMessage.error(err.message)
|
||||||
ElMessage.error(error.message)
|
|
||||||
// 自动跳转回列表页
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
this.$router.replace({
|
router.replace({ name: 'survey' })
|
||||||
name: 'survey'
|
|
||||||
})
|
|
||||||
}, 1000)
|
}, 1000)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.edit-index {
|
.edit-index {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-popover placement="top" trigger="click" @show="onShow" :width="320">
|
<el-popover placement="top" trigger="click" @show="handlePopoverShow" :width="320">
|
||||||
<el-tabs v-model="currentTab" class="custom-tab" v-if="visible" v-loading="paneLoading">
|
<el-tabs v-model="currentTab" class="custom-tab" v-if="visible" v-loading="loading">
|
||||||
<el-tab-pane label="修改历史" name="daily" class="custom-tab-pane">
|
<el-tab-pane label="修改历史" name="daily" class="custom-tab-pane">
|
||||||
<div class="line" v-for="(his, index) in dailyList" :key="index">
|
<div class="line" v-for="(his, index) in dailyList" :key="index">
|
||||||
<span class="operator">{{ his.operator }}</span>
|
<span class="operator">{{ his.operator }}</span>
|
||||||
@ -24,100 +24,77 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-popover>
|
</el-popover>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { ref, computed, watch } from 'vue'
|
||||||
import { getSurveyHistory } from '@/management/api/survey'
|
import { useStore } from 'vuex'
|
||||||
|
import { get as _get } from 'lodash-es'
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
// 引入中文
|
|
||||||
import 'moment/locale/zh-cn'
|
import 'moment/locale/zh-cn'
|
||||||
// 设置中文
|
|
||||||
moment.locale('zh-cn')
|
moment.locale('zh-cn')
|
||||||
|
|
||||||
import { mapState } from 'vuex'
|
import { getSurveyHistory } from '@/management/api/survey'
|
||||||
import { get as _get } from 'lodash-es'
|
|
||||||
|
|
||||||
const getItemData = (item) => ({
|
const getItemData = (item: any) => ({
|
||||||
operator: item?.operator?.username || '未知用户',
|
operator: item?.operator?.username || '未知用户',
|
||||||
time: moment(item.createDate).format('YYYY-MM-DD HH:mm:ss')
|
time: moment(item.createDate).format('YYYY-MM-DD HH:mm:ss')
|
||||||
})
|
})
|
||||||
|
|
||||||
export default {
|
const dailyList = ref<Array<any>>([])
|
||||||
name: 'HistoryPanel',
|
const publishList = ref<Array<any>>([])
|
||||||
computed: {
|
const currentTab = ref<'daily' | 'publish'>('daily')
|
||||||
...mapState({
|
const visible = ref<boolean>(false)
|
||||||
surveyId: (state) => _get(state, 'edit.surveyId')
|
|
||||||
}),
|
|
||||||
dailyList() {
|
|
||||||
return this.dailyHis.map(getItemData)
|
|
||||||
},
|
|
||||||
publishList() {
|
|
||||||
return this.publishHis.map(getItemData)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
dailyHis: [],
|
|
||||||
publishHis: [],
|
|
||||||
currentTab: 'daily',
|
|
||||||
visible: false,
|
|
||||||
paneLoading: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible: {
|
|
||||||
async handler(newVal) {
|
|
||||||
if (this.visible && newVal) {
|
|
||||||
this.fetchHis()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
currentTab: {
|
|
||||||
immediate: true,
|
|
||||||
async handler(newVal) {
|
|
||||||
if (this.visible && newVal) {
|
|
||||||
this.fetchHis()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onShow() {
|
|
||||||
this.visible = true
|
|
||||||
},
|
|
||||||
fetchHis() {
|
|
||||||
this.paneLoading = true
|
|
||||||
switch (this.currentTab) {
|
|
||||||
case 'daily':
|
|
||||||
getSurveyHistory({
|
|
||||||
surveyId: this.surveyId,
|
|
||||||
historyType: 'dailyHis'
|
|
||||||
})
|
|
||||||
.then((dailyHis) => {
|
|
||||||
this.dailyHis = dailyHis.data || []
|
|
||||||
})
|
|
||||||
.finally(() => {
|
|
||||||
this.paneLoading = false
|
|
||||||
})
|
|
||||||
break
|
|
||||||
|
|
||||||
case 'publish':
|
const store = useStore()
|
||||||
|
|
||||||
|
const queryHistories = async () => {
|
||||||
|
if (dirtyMonitor.value) {
|
||||||
|
loading.value = true
|
||||||
|
dirtyMonitor.value = false
|
||||||
|
|
||||||
|
const surveyId = _get(store.state, 'edit.surveyId')
|
||||||
|
const [dHis, pHis] = await Promise.all([
|
||||||
getSurveyHistory({
|
getSurveyHistory({
|
||||||
surveyId: this.surveyId,
|
surveyId,
|
||||||
|
historyType: 'dailyHis'
|
||||||
|
}),
|
||||||
|
getSurveyHistory({
|
||||||
|
surveyId,
|
||||||
historyType: 'publishHis'
|
historyType: 'publishHis'
|
||||||
})
|
})
|
||||||
.then((publishHis) => {
|
]).finally(() => {
|
||||||
this.publishHis = publishHis.data || []
|
loading.value = false
|
||||||
})
|
})
|
||||||
.finally(() => {
|
|
||||||
this.paneLoading = false
|
if ((dHis.data || []).length !== dailyList.value.length) {
|
||||||
})
|
dailyList.value = (dHis.data || []).map(getItemData)
|
||||||
break
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((pHis.data || []).length !== publishList.value.length) {
|
||||||
|
publishList.value = (pHis.data || []).map(getItemData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
const handlePopoverShow = async () => {
|
||||||
|
visible.value = true
|
||||||
|
queryHistories()
|
||||||
|
}
|
||||||
|
const loading = ref<boolean>(false)
|
||||||
|
const dirtyMonitor = ref<boolean>(true)
|
||||||
|
const schemaUpdateTime = computed(() => _get(store.state, 'edit.schemaUpdateTime'))
|
||||||
|
|
||||||
|
watch(
|
||||||
|
schemaUpdateTime,
|
||||||
|
() => {
|
||||||
|
if (!dirtyMonitor.value) {
|
||||||
|
dirtyMonitor.value = true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
immediate: true
|
||||||
|
}
|
||||||
|
)
|
||||||
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import url('@/management/styles/edit-btn.scss');
|
@import url('@/management/styles/edit-btn.scss');
|
||||||
|
|
||||||
|
@ -1,80 +1,81 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-button type="primary" :loading="isPublishing" class="publish-btn" @click="onPublish">
|
<el-button type="primary" :loading="isPublishing" class="publish-btn" @click="handlePublish">
|
||||||
发布
|
发布
|
||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { ref } from 'vue'
|
||||||
import { get as _get } from 'lodash-es'
|
import { useStore } from 'vuex'
|
||||||
import { mapState } from 'vuex'
|
import { useRouter } from 'vue-router'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import 'element-plus/theme-chalk/src/message.scss'
|
import 'element-plus/theme-chalk/src/message.scss'
|
||||||
|
|
||||||
import { publishSurvey, saveSurvey } from '@/management/api/survey'
|
import { publishSurvey, saveSurvey } from '@/management/api/survey'
|
||||||
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
||||||
import buildData from './buildData'
|
import buildData from './buildData'
|
||||||
|
|
||||||
export default {
|
const isPublishing = ref<boolean>(false)
|
||||||
name: 'PublishPanel',
|
const store = useStore()
|
||||||
data() {
|
const router = useRouter()
|
||||||
return {
|
|
||||||
isPublishing: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
surveyId: (state) => _get(state, 'edit.surveyId')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async onPublish() {
|
|
||||||
try {
|
|
||||||
this.updateLogicConf()
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage.error('请检查逻辑配置是否有误')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const saveData = buildData(this.$store.state.edit.schema)
|
|
||||||
if (!saveData.surveyId) {
|
|
||||||
ElMessage.error('未获取到问卷id')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (this.isPublishing) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
const updateLogicConf = () => {
|
||||||
this.isPublishing = true
|
if (
|
||||||
const saveRes = await saveSurvey(saveData)
|
showLogicEngine.value &&
|
||||||
if (saveRes.code !== 200) {
|
showLogicEngine.value.rules &&
|
||||||
ElMessage.error(saveRes.errmsg || '问卷保存失败')
|
showLogicEngine.value.rules.length !== 0
|
||||||
return
|
) {
|
||||||
}
|
|
||||||
const publishRes = await publishSurvey({ surveyId: this.surveyId })
|
|
||||||
if (publishRes.code === 200) {
|
|
||||||
ElMessage.success('发布成功')
|
|
||||||
this.$store.dispatch('edit/getSchemaFromRemote')
|
|
||||||
this.$router.push({ name: 'publish' })
|
|
||||||
} else {
|
|
||||||
ElMessage.error(`发布失败 ${publishRes.errmsg}`)
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
ElMessage.error(`发布失败`)
|
|
||||||
} finally {
|
|
||||||
this.isPublishing = false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateLogicConf() {
|
|
||||||
if (showLogicEngine.value) {
|
|
||||||
showLogicEngine.value.validateSchema()
|
showLogicEngine.value.validateSchema()
|
||||||
const showLogicConf = showLogicEngine.value.toJson()
|
const showLogicConf = showLogicEngine.value.toJson()
|
||||||
// 更新逻辑配置
|
// 更新逻辑配置
|
||||||
this.$store.dispatch('edit/changeSchema', { key: 'logicConf', value: { showLogicConf } })
|
store.dispatch('edit/changeSchema', { key: 'logicConf', value: { showLogicConf } })
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handlePublish = async () => {
|
||||||
|
if (isPublishing.value) {
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isPublishing.value = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
updateLogicConf()
|
||||||
|
} catch (err) {
|
||||||
|
isPublishing.value = false
|
||||||
|
ElMessage.error('请检查逻辑配置是否有误')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveData = buildData(store.state.edit.schema)
|
||||||
|
if (!saveData.surveyId) {
|
||||||
|
isPublishing.value = false
|
||||||
|
ElMessage.error('未获取到问卷id')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const saveRes: any = await saveSurvey(saveData)
|
||||||
|
if (saveRes.code !== 200) {
|
||||||
|
isPublishing.value = false
|
||||||
|
ElMessage.error(saveRes.errmsg || '问卷保存失败')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const publishRes: any = await publishSurvey({ surveyId: saveData.surveyId })
|
||||||
|
if (publishRes.code === 200) {
|
||||||
|
ElMessage.success('发布成功')
|
||||||
|
store.dispatch('edit/getSchemaFromRemote')
|
||||||
|
router.push({ name: 'publish' })
|
||||||
|
} else {
|
||||||
|
ElMessage.error(`发布失败 ${publishRes.errmsg}`)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
ElMessage.error(`发布失败`)
|
||||||
|
} finally {
|
||||||
|
isPublishing.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.publish-btn {
|
.publish-btn {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="btn" @click="onSave" v-loading="isSaving">
|
<div class="btn" @click="handleSave" v-loading="isSaving">
|
||||||
<i class="iconfont icon-baocun"></i>
|
<i class="iconfont icon-baocun"></i>
|
||||||
<span class="btn-txt">保存</span>
|
<span class="btn-txt">保存</span>
|
||||||
<transition name="fade">
|
<transition name="fade">
|
||||||
@ -13,115 +13,109 @@
|
|||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { ref, computed, nextTick, watch } from 'vue'
|
||||||
import { mapState } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { get as _get } from 'lodash-es'
|
import { get as _get } from 'lodash-es'
|
||||||
|
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import 'element-plus/theme-chalk/src/message.scss'
|
import 'element-plus/theme-chalk/src/message.scss'
|
||||||
|
|
||||||
import { saveSurvey } from '@/management/api/survey'
|
import { saveSurvey } from '@/management/api/survey'
|
||||||
import buildData from './buildData'
|
|
||||||
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
import { showLogicEngine } from '@/management/hooks/useShowLogicEngine'
|
||||||
|
import buildData from './buildData'
|
||||||
|
|
||||||
export default {
|
const isSaving = ref<boolean>(false)
|
||||||
components: {},
|
const isShowAutoSave = ref<boolean>(false)
|
||||||
name: 'SavePanel',
|
const autoSaveStatus = ref<'succeed' | 'saving' | 'failed'>('succeed')
|
||||||
data() {
|
const saveText = computed(
|
||||||
return {
|
() =>
|
||||||
isSaving: false,
|
({
|
||||||
isShowAutoSave: false,
|
|
||||||
autoSaveStatus: 'succeed'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
schemaUpdateTime: (state) => _get(state, 'edit.schemaUpdateTime')
|
|
||||||
}),
|
|
||||||
saveText() {
|
|
||||||
const statusMap = {
|
|
||||||
saving: '保存中',
|
saving: '保存中',
|
||||||
succeed: '保存成功',
|
succeed: '保存成功',
|
||||||
failed: '保存失败'
|
failed: '保存失败'
|
||||||
}
|
})[autoSaveStatus.value]
|
||||||
return statusMap[this.autoSaveStatus]
|
)
|
||||||
}
|
|
||||||
},
|
const store = useStore()
|
||||||
watch: {
|
|
||||||
schemaUpdateTime() {
|
const saveData = async () => {
|
||||||
this.triggerAutoSave()
|
const saveData = buildData(store.state.edit.schema)
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
triggerAutoSave() {
|
|
||||||
if (this.autoSaveStatus === 'saving') {
|
|
||||||
// 正在调用接口
|
|
||||||
setTimeout(() => {
|
|
||||||
this.triggerAutoSave()
|
|
||||||
}, 1000)
|
|
||||||
} else {
|
|
||||||
if (this.timer) {
|
|
||||||
clearTimeout(this.timer)
|
|
||||||
}
|
|
||||||
this.timer = setTimeout(() => {
|
|
||||||
this.autoSaveStatus = 'saving'
|
|
||||||
this.isShowAutoSave = true
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.saveData()
|
|
||||||
.then((res) => {
|
|
||||||
if (res.code === 200) {
|
|
||||||
this.autoSaveStatus = 'succeed'
|
|
||||||
} else {
|
|
||||||
this.autoSaveStatus = 'failed'
|
|
||||||
}
|
|
||||||
setTimeout(() => {
|
|
||||||
this.isShowAutoSave = false
|
|
||||||
this.timer = null
|
|
||||||
}, 300)
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
this.timer = null
|
|
||||||
this.autoSaveStatus = 'failed'
|
|
||||||
this.isShowAutoSave = true
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
updateLogicConf() {
|
|
||||||
if (showLogicEngine.value) {
|
|
||||||
showLogicEngine.value.validateSchema()
|
|
||||||
const showLogicConf = showLogicEngine.value.toJson()
|
|
||||||
// 更新逻辑配置
|
|
||||||
this.$store.dispatch('edit/changeSchema', { key: 'logicConf', value: { showLogicConf } })
|
|
||||||
}
|
|
||||||
},
|
|
||||||
async saveData() {
|
|
||||||
const saveData = buildData(this.$store.state.edit.schema)
|
|
||||||
if (!saveData.surveyId) {
|
if (!saveData.surveyId) {
|
||||||
ElMessage.error('未获取到问卷id')
|
ElMessage.error('未获取到问卷id')
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await saveSurvey(saveData)
|
const res = await saveSurvey(saveData)
|
||||||
return res
|
return res
|
||||||
},
|
}
|
||||||
async onSave() {
|
|
||||||
if (this.isSaving) {
|
const updateLogicConf = () => {
|
||||||
|
if (
|
||||||
|
showLogicEngine.value &&
|
||||||
|
showLogicEngine.value.rules &&
|
||||||
|
showLogicEngine.value.rules.length !== 0
|
||||||
|
) {
|
||||||
|
showLogicEngine.value.validateSchema()
|
||||||
|
const showLogicConf = showLogicEngine.value.toJson()
|
||||||
|
// 更新逻辑配置
|
||||||
|
store.dispatch('edit/changeSchema', { key: 'logicConf', value: { showLogicConf } })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const timerHandle = ref<NodeJS.Timeout | number | null>(null)
|
||||||
|
const triggerAutoSave = () => {
|
||||||
|
if (autoSaveStatus.value === 'saving') {
|
||||||
|
setTimeout(() => triggerAutoSave(), 1000)
|
||||||
|
} else {
|
||||||
|
if (timerHandle.value) {
|
||||||
|
clearTimeout(timerHandle.value)
|
||||||
|
timerHandle.value = null
|
||||||
|
}
|
||||||
|
|
||||||
|
timerHandle.value = setTimeout(() => {
|
||||||
|
autoSaveStatus.value = 'saving'
|
||||||
|
isShowAutoSave.value = true
|
||||||
|
nextTick(async () => {
|
||||||
|
try {
|
||||||
|
const res: any = await saveData()
|
||||||
|
if (res.code === 200) {
|
||||||
|
autoSaveStatus.value = 'succeed'
|
||||||
|
} else {
|
||||||
|
autoSaveStatus.value = 'failed'
|
||||||
|
}
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
isShowAutoSave.value = false
|
||||||
|
timerHandle.value = null
|
||||||
|
}, 300)
|
||||||
|
} catch (err) {
|
||||||
|
autoSaveStatus.value = 'failed'
|
||||||
|
isShowAutoSave.value = true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 2000)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSave = async () => {
|
||||||
|
if (isSaving.value) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.isShowAutoSave = false
|
|
||||||
|
isSaving.value = true
|
||||||
|
isShowAutoSave.value = false
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.updateLogicConf()
|
updateLogicConf()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// console.error(error)
|
isSaving.value = false
|
||||||
ElMessage.error('请检查逻辑配置是否有误')
|
ElMessage.error('请检查逻辑配置是否有误')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.isSaving = true
|
const res: any = await saveData()
|
||||||
const res = await this.saveData()
|
|
||||||
if (res.code === 200) {
|
if (res.code === 200) {
|
||||||
ElMessage.success('保存成功')
|
ElMessage.success('保存成功')
|
||||||
} else {
|
} else {
|
||||||
@ -130,13 +124,15 @@ export default {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
ElMessage.error('保存问卷失败')
|
ElMessage.error('保存问卷失败')
|
||||||
} finally {
|
} finally {
|
||||||
this.isSaving = false
|
isSaving.value = false
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
const schemaUpdateTime = computed(() => _get(store.state, 'edit.schemaUpdateTime'))
|
||||||
|
watch(schemaUpdateTime, () => {
|
||||||
|
triggerAutoSave()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@import url('@/management/styles/edit-btn.scss');
|
@import url('@/management/styles/edit-btn.scss');
|
||||||
|
|
||||||
|
@ -1,16 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="back-btn" @click="onBack">
|
<div class="back-btn" @click="handleNavigateHome">
|
||||||
<i class="iconfont icon-fanhui"></i>
|
<i class="iconfont icon-fanhui"></i>
|
||||||
<span>返回</span>
|
<span>返回</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const onBack = () => {
|
const handleNavigateHome = () => window.open('/survey', '_self')
|
||||||
window.open('/survey', '_self')
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.back-btn {
|
.back-btn {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<template v-for="btnItem in btnList" :key="btnItem.key">
|
<template v-for="route in routes" :key="route.key">
|
||||||
<router-link
|
<router-link
|
||||||
:to="{ name: btnItem.router }"
|
:to="{ name: route.router }"
|
||||||
replace
|
replace
|
||||||
v-slot="{ href, navigate, isActive, isExactActive }"
|
v-slot="{ href, navigate, isActive, isExactActive }"
|
||||||
custom
|
custom
|
||||||
@ -10,25 +10,22 @@
|
|||||||
<div
|
<div
|
||||||
:class="[
|
:class="[
|
||||||
'navbar-btn',
|
'navbar-btn',
|
||||||
(isActive && ['skinsettings', 'edit'].includes(btnItem.key)) || isExactActive
|
(isActive && ['skinsettings', 'edit'].includes(route.key)) || isExactActive
|
||||||
? 'router-link-exact-active'
|
? 'router-link-exact-active'
|
||||||
: ''
|
: ''
|
||||||
]"
|
]"
|
||||||
>
|
>
|
||||||
<i class="iconfont" :class="[btnItem.icon]"></i>
|
<i class="iconfont" :class="[route.icon]"></i>
|
||||||
<a :href="href" @click="navigate"
|
<a :href="href" @click="navigate"
|
||||||
><span>{{ btnItem.text }}</span></a
|
><span>{{ route.text }}</span></a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive } from 'vue'
|
const routes = [
|
||||||
|
|
||||||
const btnList = reactive([
|
|
||||||
{
|
{
|
||||||
icon: 'icon-wenjuanbianji',
|
icon: 'icon-wenjuanbianji',
|
||||||
text: '问卷编辑',
|
text: '问卷编辑',
|
||||||
@ -50,9 +47,8 @@ const btnList = reactive([
|
|||||||
key: 'skinsettings',
|
key: 'skinsettings',
|
||||||
next: true
|
next: true
|
||||||
}
|
}
|
||||||
])
|
]
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.content {
|
.content {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -46,7 +46,6 @@ const hideFullTitle = () => {
|
|||||||
tooltipVisible.value = false
|
tooltipVisible.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.title-container {
|
.title-container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -8,26 +8,14 @@
|
|||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
</el-tabs>
|
</el-tabs>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
<script>
|
|
||||||
import TypeList from './components/TypeList.vue'
|
import TypeList from './components/TypeList.vue'
|
||||||
import QuestionCatalog from './components/QuestionCatalog.vue'
|
import QuestionCatalog from './components/QuestionCatalog.vue'
|
||||||
|
|
||||||
export default {
|
const tabSelected = ref<string>('0')
|
||||||
name: 'CatalogPanel',
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
tabSelected: '0'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
TypeList,
|
|
||||||
QuestionCatalog
|
|
||||||
},
|
|
||||||
methods: {}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tab-box {
|
.tab-box {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
@ -11,47 +11,31 @@
|
|||||||
class="question-config-form"
|
class="question-config-form"
|
||||||
:form-config-list="formConfigList"
|
:form-config-list="formConfigList"
|
||||||
:module-config="moduleConfig"
|
:module-config="moduleConfig"
|
||||||
@form-change="onFormChange"
|
@form-change="handleFormChange"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
<script>
|
|
||||||
import SetterField from '@/management/pages/edit/components/SetterField.vue'
|
import SetterField from '@/management/pages/edit/components/SetterField.vue'
|
||||||
import { mapGetters } from 'vuex'
|
|
||||||
|
|
||||||
export default {
|
const store = useStore()
|
||||||
name: 'SetterPanel',
|
|
||||||
data() {
|
const currentEditOne = computed(() => store.state?.edit?.currentEditOne)
|
||||||
return {
|
const formConfigList = computed(() => store.getters['edit/formConfigList'])
|
||||||
tabSelected: '0'
|
const moduleConfig = computed(() => store.getters['edit/moduleConfig'])
|
||||||
}
|
const currentEditKey = computed(() => store.getters['edit/currentEditKey'])
|
||||||
},
|
const currentEditMeta = computed(() => store.getters['edit/currentEditMeta'])
|
||||||
computed: {
|
|
||||||
currentEditOne() {
|
const handleFormChange = (data: any) => {
|
||||||
return this.$store.state?.edit?.currentEditOne
|
|
||||||
},
|
|
||||||
...mapGetters({
|
|
||||||
formConfigList: 'edit/formConfigList',
|
|
||||||
moduleConfig: 'edit/moduleConfig',
|
|
||||||
currentEditKey: 'edit/currentEditKey',
|
|
||||||
currentEditMeta: 'edit/currentEditMeta'
|
|
||||||
})
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
SetterField
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onFormChange(data) {
|
|
||||||
const { key, value } = data
|
const { key, value } = data
|
||||||
const resultKey = `${this.currentEditKey}.${key}`
|
const resultKey = `${currentEditKey.value}.${key}`
|
||||||
this.$store.dispatch('edit/changeSchema', { key: resultKey, value })
|
store.dispatch('edit/changeSchema', { key: resultKey, value })
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.setter-wrapper {
|
.setter-wrapper {
|
||||||
width: 360px;
|
width: 360px;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="question-catalog-item" @click="onSelect()">
|
<div class="question-catalog-item" @click="handleSelect()">
|
||||||
<div class="iconfont icon-tuodong draggHandle"></div>
|
<div class="iconfont icon-tuodong draggHandle"></div>
|
||||||
<div class="catalog-item-body">
|
<div class="catalog-item-body">
|
||||||
<div class="catalog-item-index" v-if="showIndex">{{ indexNumber }}.</div>
|
<div class="catalog-item-index" v-if="showIndex">{{ indexNumber }}.</div>
|
||||||
@ -7,37 +7,29 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
interface Props {
|
||||||
|
title: string
|
||||||
|
indexNumber: string | number
|
||||||
|
showIndex: boolean
|
||||||
|
}
|
||||||
|
|
||||||
<script>
|
interface Emit {
|
||||||
export default {
|
(ev: 'select'): void
|
||||||
name: 'CatalogItem',
|
}
|
||||||
data() {
|
|
||||||
return {}
|
withDefaults(defineProps<Props>(), {
|
||||||
},
|
title: '',
|
||||||
computed: {},
|
indexNumber: '',
|
||||||
props: {
|
showIndex: false
|
||||||
title: {
|
})
|
||||||
type: String,
|
|
||||||
default: ''
|
const emit = defineEmits<Emit>()
|
||||||
},
|
|
||||||
indexNumber: {
|
const handleSelect = () => {
|
||||||
type: [String, Number],
|
emit('select')
|
||||||
default: ''
|
|
||||||
},
|
|
||||||
showIndex: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {},
|
|
||||||
methods: {
|
|
||||||
onSelect() {
|
|
||||||
this.$emit('select')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.question-catalog-item {
|
.question-catalog-item {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div class="question-catalog-wrapper">
|
<div class="question-catalog-wrapper">
|
||||||
<draggable
|
<draggable
|
||||||
:list="renderData"
|
:list="renderData"
|
||||||
@end="onDragEnd"
|
@end="handleDragEnd"
|
||||||
itemKey="field"
|
itemKey="field"
|
||||||
handle=".draggHandle"
|
handle=".draggHandle"
|
||||||
host-class="catalog-item-ghost"
|
host-class="catalog-item-ghost"
|
||||||
@ -12,50 +12,43 @@
|
|||||||
:title="element.title"
|
:title="element.title"
|
||||||
:indexNumber="element.indexNumber"
|
:indexNumber="element.indexNumber"
|
||||||
:showIndex="element.showIndex"
|
:showIndex="element.showIndex"
|
||||||
@select="onSelect(index)"
|
@select="handleSelect(index)"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
</draggable>
|
</draggable>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { computed } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
import draggable from 'vuedraggable'
|
import draggable from 'vuedraggable'
|
||||||
|
|
||||||
import CatalogItem from './CatalogItem.vue'
|
import CatalogItem from './CatalogItem.vue'
|
||||||
import { filterQuestionPreviewData } from '@/management/utils/index'
|
import { filterQuestionPreviewData } from '@/management/utils/index'
|
||||||
|
|
||||||
export default {
|
const store = useStore()
|
||||||
name: 'QuestionCatalog',
|
const renderData = computed(() => {
|
||||||
data() {
|
const questions = store.state.edit.schema.questionDataList
|
||||||
return {}
|
return filterQuestionPreviewData(questions) || []
|
||||||
},
|
})
|
||||||
computed: {
|
|
||||||
questionDataList() {
|
const handleDragEnd = ({ newIndex, oldIndex }: any) => {
|
||||||
return this.$store.state.edit.schema.questionDataList
|
const currentActivityKey = store.state.edit.currentEditOne
|
||||||
},
|
|
||||||
renderData() {
|
if (currentActivityKey === oldIndex) {
|
||||||
return filterQuestionPreviewData(this.questionDataList) || []
|
handleSelect(newIndex)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
components: {
|
store.dispatch('edit/moveQuestion', {
|
||||||
draggable,
|
|
||||||
CatalogItem
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onDragEnd(data) {
|
|
||||||
const { newIndex, oldIndex } = data
|
|
||||||
this.$store.dispatch('edit/moveQuestion', {
|
|
||||||
index: oldIndex,
|
index: oldIndex,
|
||||||
range: newIndex - oldIndex
|
range: newIndex - oldIndex
|
||||||
})
|
})
|
||||||
},
|
}
|
||||||
onSelect(index) {
|
|
||||||
this.$store.commit('edit/setCurrentEditOne', index)
|
const handleSelect = (idx: number) => {
|
||||||
}
|
store.commit('edit/setCurrentEditOne', idx)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.question-catalog-wrapper {
|
.question-catalog-wrapper {
|
||||||
padding-bottom: 400px; // 考试题有个上拉框会盖住,改成和题型一致的
|
padding-bottom: 400px; // 考试题有个上拉框会盖住,改成和题型一致的
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<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 renderData" :key="form.key" class="config-item">
|
<div v-for="form of setterList" :key="form.key" class="config-item">
|
||||||
<div class="config-title">
|
<div class="config-title">
|
||||||
<span>
|
<span>
|
||||||
{{ form.title }}
|
{{ form.title }}
|
||||||
@ -16,17 +16,17 @@
|
|||||||
>
|
>
|
||||||
<template v-for="(item, index) in form.formList">
|
<template v-for="(item, index) in form.formList">
|
||||||
<FormItem
|
<FormItem
|
||||||
v-if="item.type && !item.hidden && Boolean(register[item.type])"
|
v-if="item.type && !item.hidden && Boolean(registerTypes[item.type])"
|
||||||
:key="index"
|
:key="index"
|
||||||
:form-config="item"
|
:form-config="item"
|
||||||
:style="item.style"
|
:style="item.style"
|
||||||
>
|
>
|
||||||
<Component
|
<Component
|
||||||
v-if="Boolean(register[item.type])"
|
v-if="Boolean(registerTypes[item.type])"
|
||||||
:is="item.type"
|
:is="components[item.type]"
|
||||||
:module-config="form.dataConfig"
|
:module-config="form.dataConfig"
|
||||||
:form-config="item"
|
:form-config="item"
|
||||||
@form-change="onFormChange"
|
@form-change="handleFormChange"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</template>
|
</template>
|
||||||
@ -36,92 +36,83 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, onMounted, shallowRef } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { cloneDeep as _cloneDeep, isArray as _isArray, get as _get } from 'lodash-es'
|
||||||
|
|
||||||
<script>
|
|
||||||
import baseConfig from './config/baseConfig'
|
import baseConfig from './config/baseConfig'
|
||||||
import baseFormConfig from './config/baseFormConfig'
|
import baseFormConfig from './config/baseFormConfig'
|
||||||
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'
|
||||||
import { cloneDeep as _cloneDeep, isArray as _isArray, get as _get } from 'lodash-es'
|
|
||||||
|
|
||||||
export default {
|
const formConfigList = ref<Array<any>>([])
|
||||||
name: 'SettingPanel',
|
const components = shallowRef<any>({})
|
||||||
components: {
|
const registerTypes = ref<any>({})
|
||||||
FormItem
|
const setterList = computed(() => {
|
||||||
},
|
const list = _cloneDeep(formConfigList.value)
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
formConfigList: [],
|
|
||||||
register: {}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onFormChange(data) {
|
|
||||||
this.$store.dispatch('edit/changeSchema', {
|
|
||||||
key: data.key,
|
|
||||||
value: data.value
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
allSetters() {
|
|
||||||
const formList = this.formConfigList.map((item) => item.formList).flat()
|
|
||||||
const typeList = formList.map((item) => ({
|
|
||||||
type: item.type,
|
|
||||||
path: item.path || item.type
|
|
||||||
}))
|
|
||||||
|
|
||||||
return typeList
|
return list.map((form) => {
|
||||||
},
|
const dataConfig: any = {}
|
||||||
renderData() {
|
|
||||||
// todo: 1、给formConfig组装value;2、新增dataConfig字段
|
|
||||||
const formConfigList = _cloneDeep(this.formConfigList)
|
|
||||||
|
|
||||||
return formConfigList.map((form) => {
|
|
||||||
const dataConfig = {}
|
|
||||||
for (const formItem of form.formList) {
|
for (const formItem of form.formList) {
|
||||||
const formKey = formItem.key ? formItem.key : formItem.keys
|
const formKey = formItem.key ? formItem.key : formItem.keys
|
||||||
let formValue
|
let formValue
|
||||||
if (_isArray(formKey)) {
|
if (_isArray(formKey)) {
|
||||||
formValue = []
|
formValue = []
|
||||||
for (const key of formKey) {
|
for (const key of formKey) {
|
||||||
const val = _get(this.$store.state.edit.schema, key, formItem.value)
|
const val = _get(store.state.edit.schema, key, formItem.value)
|
||||||
formValue.push(val)
|
formValue.push(val)
|
||||||
dataConfig[key] = val
|
dataConfig[key] = val
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
formValue = _get(this.$store.state.edit.schema, formKey, formItem.value)
|
formValue = _get(store.state.edit.schema, formKey, formItem.value)
|
||||||
dataConfig[formKey] = formValue
|
dataConfig[formKey] = formValue
|
||||||
}
|
}
|
||||||
formItem.value = formValue
|
formItem.value = formValue
|
||||||
}
|
}
|
||||||
|
|
||||||
form.dataConfig = dataConfig
|
form.dataConfig = dataConfig
|
||||||
|
|
||||||
return form
|
return form
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
},
|
|
||||||
async created() {
|
|
||||||
this.formConfigList = baseConfig.map((item) => {
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
formList: item.formList.map((key) => baseFormConfig[key]).filter((config) => !!config)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const comps = await setterLoader.loadComponents(this.allSetters)
|
const store = useStore()
|
||||||
|
const handleFormChange = (data: any) => {
|
||||||
|
store.dispatch('edit/changeSchema', {
|
||||||
|
key: data.key,
|
||||||
|
value: data.value
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
formConfigList.value = baseConfig.map((item) => ({
|
||||||
|
...item,
|
||||||
|
formList: item.formList.map((key) => (baseFormConfig as any)[key]).filter((config) => !!config)
|
||||||
|
}))
|
||||||
|
|
||||||
|
const formList = formConfigList.value.map((item) => item.formList).flat()
|
||||||
|
const typeList = formList.map((item) => ({
|
||||||
|
type: item.type,
|
||||||
|
path: item.path || item.type
|
||||||
|
}))
|
||||||
|
|
||||||
|
const comps = await setterLoader.loadComponents(typeList)
|
||||||
for (const comp of comps) {
|
for (const comp of comps) {
|
||||||
if (!comp) {
|
if (!comp) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, component, err } = comp
|
const { type, component, err } = comp
|
||||||
if (!err) {
|
if (!err) {
|
||||||
const componentName = component.name
|
const componentName = component.name
|
||||||
this.$options.components[componentName] = component
|
|
||||||
this.register[type] = componentName
|
components.value[type] = component
|
||||||
|
registerTypes.value[type] = componentName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -4,24 +4,15 @@
|
|||||||
<p class="title-msg" v-safe-html="resultText"></p>
|
<p class="title-msg" v-safe-html="resultText"></p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
<script>
|
interface Props {
|
||||||
export default {
|
moduleConfig: any
|
||||||
name: 'OverTime',
|
|
||||||
props: {
|
|
||||||
moduleConfig: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
resultText() {
|
|
||||||
return this.moduleConfig?.submitConf?.msgContent?.msg_9001 || '问卷已过期'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const resultText = computed(() => props.moduleConfig?.msgContent?.msg_9001 || '问卷已过期')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.over-time {
|
.over-time {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -9,24 +9,15 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
|
||||||
<script>
|
interface Props {
|
||||||
export default {
|
moduleConfig: any
|
||||||
name: 'SuccessContent',
|
|
||||||
props: {
|
|
||||||
moduleConfig: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
successText() {
|
|
||||||
return this.moduleConfig?.submitConf?.msgContent?.msg_200 || ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
const props = defineProps<Props>()
|
||||||
|
const successText = computed(() => props.moduleConfig?.msgContent?.msg_200 || '')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
/*成功页面跳转全屏展示浮层*/
|
/*成功页面跳转全屏展示浮层*/
|
||||||
.suc-page {
|
.suc-page {
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
v-for="(status, index) in statusList"
|
v-for="(status, index) in statusList"
|
||||||
:key="index"
|
:key="index"
|
||||||
class="status-item"
|
class="status-item"
|
||||||
@click="filterDisabledStatus({ type: status.type })"
|
@click="handleChangePreview({ type: status.type })"
|
||||||
>
|
>
|
||||||
<span>{{ status.title }}</span>
|
<span>{{ status.title }}</span>
|
||||||
<div class="preview-item">
|
<div class="preview-item">
|
||||||
@ -16,16 +16,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
import { useStore } from 'vuex'
|
||||||
import { mapMutations } from 'vuex'
|
|
||||||
import { EDIT_STATUS_MAP } from '../enum'
|
import { EDIT_STATUS_MAP } from '../enum'
|
||||||
|
|
||||||
export default {
|
const store = useStore()
|
||||||
name: 'CatalogPanel',
|
const statusList = [
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
statusList: [
|
|
||||||
{
|
{
|
||||||
type: EDIT_STATUS_MAP.SUCCESS,
|
type: EDIT_STATUS_MAP.SUCCESS,
|
||||||
title: '提交成功',
|
title: '提交成功',
|
||||||
@ -36,21 +32,16 @@ export default {
|
|||||||
title: '问卷过期',
|
title: '问卷过期',
|
||||||
previewImg: '/imgs/icons/overtime.webp'
|
previewImg: '/imgs/icons/overtime.webp'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
|
||||||
},
|
const handleChangePreview = (data: any) => {
|
||||||
computed: {},
|
const currentStatus = store.state?.edit?.currentEditStatus
|
||||||
methods: {
|
|
||||||
...mapMutations({
|
if (currentStatus && currentStatus !== data.type) {
|
||||||
changeStatusPreview: 'edit/changeStatusPreview'
|
store.commit('edit/changeStatusPreview', data)
|
||||||
}),
|
|
||||||
filterDisabledStatus(data) {
|
|
||||||
this.changeStatusPreview(data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.tab-box {
|
.tab-box {
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
@ -2,43 +2,35 @@
|
|||||||
<div class="result-config-preview">
|
<div class="result-config-preview">
|
||||||
<div class="result-page-wrap">
|
<div class="result-page-wrap">
|
||||||
<div class="result-page">
|
<div class="result-page">
|
||||||
<component :is="currentEditStatus" :key="currentEditStatus" :module-config="moduleConfig" />
|
<component
|
||||||
|
:is="components[currentEditStatus]"
|
||||||
|
:key="currentEditStatus"
|
||||||
|
:module-config="moduleConfig"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { get as _get } from 'lodash-es'
|
||||||
|
|
||||||
<script>
|
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import SuccessContent from '../components/SuccessContent.vue'
|
import SuccessContent from '../components/SuccessContent.vue'
|
||||||
import OverTime from '../components/OverTime.vue'
|
import OverTime from '../components/OverTime.vue'
|
||||||
import { EDIT_STATUS_MAP } from '../enum'
|
import { EDIT_STATUS_MAP } from '../enum'
|
||||||
import { get as _get } from 'lodash-es'
|
|
||||||
|
|
||||||
export default {
|
const components = {
|
||||||
name: 'PreviewPanel',
|
|
||||||
props: {},
|
|
||||||
data() {
|
|
||||||
return {}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
currentEditStatus: (state) => state.edit.currentEditStatus,
|
|
||||||
submitConf: (state) => _get(state, 'edit.schema.submitConf')
|
|
||||||
}),
|
|
||||||
moduleConfig() {
|
|
||||||
return {
|
|
||||||
submitConf: this.submitConf
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
components: {
|
|
||||||
[EDIT_STATUS_MAP.SUCCESS]: SuccessContent,
|
[EDIT_STATUS_MAP.SUCCESS]: SuccessContent,
|
||||||
[EDIT_STATUS_MAP.OVERTIME]: OverTime
|
[EDIT_STATUS_MAP.OVERTIME]: OverTime
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
|
||||||
|
const store = useStore()
|
||||||
|
const currentEditStatus = computed(() => store.state?.edit?.currentEditStatus)
|
||||||
|
const moduleConfig = computed(() => {
|
||||||
|
return _get(store.state, 'edit.schema.submitConf')
|
||||||
|
})
|
||||||
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.result-config-preview {
|
.result-config-preview {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -4,82 +4,67 @@
|
|||||||
{{ currentEditText }}
|
{{ currentEditText }}
|
||||||
</div>
|
</div>
|
||||||
<el-form class="question-config-form" label-position="top" @submit.prevent>
|
<el-form class="question-config-form" label-position="top" @submit.prevent>
|
||||||
<template v-for="(item, index) in formFieldData" :key="index">
|
<template v-for="(item, index) in formFields" :key="index">
|
||||||
<FormItem
|
<FormItem
|
||||||
v-if="item.type && !item.hidden && Boolean(register[item.type])"
|
v-if="item.type && !item.hidden && Boolean(registerTypes[item.type])"
|
||||||
:form-config="item"
|
:form-config="item"
|
||||||
:style="item.style"
|
:style="item.style"
|
||||||
>
|
>
|
||||||
<Component
|
<Component
|
||||||
v-if="Boolean(register[item.type])"
|
v-if="Boolean(registerTypes[item.type])"
|
||||||
:is="item.type"
|
:is="components[item.type]"
|
||||||
:module-config="moduleConfig"
|
:module-config="moduleConfig"
|
||||||
:form-config="item"
|
:form-config="item"
|
||||||
@form-change="onFormChange"
|
@form-change="handleFormChange"
|
||||||
/>
|
/>
|
||||||
</FormItem>
|
</FormItem>
|
||||||
</template>
|
</template>
|
||||||
</el-form>
|
</el-form>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, ref, shallowRef } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { get as _get } from 'lodash-es'
|
||||||
|
|
||||||
<script>
|
|
||||||
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'
|
||||||
import statusConfig from '../config/statusConfig'
|
import statusConfig from '../config/statusConfig'
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import { get as _get, pick as _pick } from 'lodash-es'
|
|
||||||
|
|
||||||
const textMap = {
|
const textMap = {
|
||||||
Success: '提交成功页面配置',
|
Success: '提交成功页面配置',
|
||||||
OverTime: '问卷过期页面配置'
|
OverTime: '问卷过期页面配置'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
const store = useStore()
|
||||||
name: 'SetterPanel',
|
|
||||||
components: {
|
const components = shallowRef<any>({})
|
||||||
FormItem
|
const registerTypes = ref<any>({})
|
||||||
},
|
const moduleConfig = computed(() => _get(store.state, 'edit.schema.submitConf'))
|
||||||
data() {
|
const currentEditText = computed(() => (textMap as any)[store.state.edit.currentEditStatus])
|
||||||
return {
|
const formFields = computed(() => {
|
||||||
register: {}
|
const currentStatus = store.state.edit.currentEditStatus
|
||||||
}
|
const formList = (statusConfig as any)[currentStatus] || []
|
||||||
},
|
const list = formList.map((item: any) => {
|
||||||
computed: {
|
const value = _get(moduleConfig.value, item.key, item.value)
|
||||||
formFieldData() {
|
|
||||||
const formList = statusConfig[this.currentEditStatus] || []
|
return { ...item, value }
|
||||||
return formList.map((item) => {
|
|
||||||
const value = _get(this.moduleConfig, item.key, item.value)
|
|
||||||
return {
|
|
||||||
...item,
|
|
||||||
value
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
},
|
|
||||||
currentEditText() {
|
registerComponents(list)
|
||||||
return textMap[this.currentEditStatus] || ''
|
|
||||||
},
|
return list
|
||||||
...mapState({
|
})
|
||||||
currentEditStatus: (state) => state.edit.currentEditStatus,
|
|
||||||
submitConf: (state) => _get(state, 'edit.schema.submitConf')
|
const handleFormChange = ({ key, value }: any) => {
|
||||||
}),
|
store.dispatch('edit/changeSchema', {
|
||||||
moduleConfig() {
|
key: `submitConf.${key}`,
|
||||||
return this.submitConf
|
value
|
||||||
}
|
})
|
||||||
},
|
}
|
||||||
watch: {
|
|
||||||
formFieldData: {
|
const registerComponents = async (formFieldData: any) => {
|
||||||
immediate: true,
|
const setters = formFieldData.map((item: any) => item.type)
|
||||||
handler(newVal) {
|
|
||||||
if (Array.isArray(newVal)) {
|
|
||||||
this.handleComponentRegister(newVal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async handleComponentRegister(formFieldData) {
|
|
||||||
const setters = formFieldData.map((item) => item.type)
|
|
||||||
const settersSet = new Set(setters)
|
const settersSet = new Set(setters)
|
||||||
const settersArr = Array.from(settersSet)
|
const settersArr = Array.from(settersSet)
|
||||||
const allSetters = settersArr.map((item) => {
|
const allSetters = settersArr.map((item) => {
|
||||||
@ -88,50 +73,29 @@ export default {
|
|||||||
path: item
|
path: item
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const comps = await setterLoader.loadComponents(allSetters)
|
const comps = await setterLoader.loadComponents(allSetters)
|
||||||
|
|
||||||
for (const comp of comps) {
|
for (const comp of comps) {
|
||||||
if (!comp) {
|
if (!comp) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
const { type, component, err } = comp
|
const { type, component, err } = comp
|
||||||
|
|
||||||
if (!err) {
|
if (!err) {
|
||||||
const componentName = component.name
|
const componentName = component.name
|
||||||
this.$options.components[componentName] = component
|
|
||||||
this.register[type] = componentName
|
components.value[type] = component
|
||||||
|
registerTypes.value[type] = componentName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
}
|
}
|
||||||
},
|
|
||||||
getValueFromModuleConfig(item) {
|
|
||||||
const { key, keys } = item
|
|
||||||
const moduleConfig = this.moduleConfig
|
|
||||||
let result = item
|
|
||||||
if (key) {
|
|
||||||
result = {
|
|
||||||
...item,
|
|
||||||
value: _get(moduleConfig, key, item.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (keys) {
|
|
||||||
result = {
|
|
||||||
...item,
|
|
||||||
value: _pick(moduleConfig, keys)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
},
|
|
||||||
onFormChange(data) {
|
|
||||||
const { key, value } = data
|
|
||||||
const resultKey = `submitConf.${key}`
|
|
||||||
this.$store.dispatch('edit/changeSchema', { key: resultKey, value })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.question-edit-form {
|
.question-edit-form {
|
||||||
width: 360px;
|
width: 360px;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
:class="[groupName === item.value ? 'current' : '', 'tag']"
|
:class="[groupName === item.value ? 'current' : '', 'tag']"
|
||||||
type="info"
|
type="info"
|
||||||
:key="item.value"
|
:key="item.value"
|
||||||
@click="() => changeGroup(item.value)"
|
@click="() => handleChangeGroup(item.value)"
|
||||||
>
|
>
|
||||||
{{ item.label }}
|
{{ item.label }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
@ -25,75 +25,63 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import { mapActions } from 'vuex'
|
import { computed, ref } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
import skinPresets from '@/management/config/skinPresets.js'
|
import skinPresets from '@/management/config/skinPresets.js'
|
||||||
export default {
|
|
||||||
name: 'CatalogPanel',
|
const store = useStore()
|
||||||
data() {
|
const groupName = ref<string>('temp')
|
||||||
return {
|
const bannerList = computed(() => store?.state?.bannerList || [])
|
||||||
skinPresets: [],
|
const groupList = computed(() =>
|
||||||
groupName: 'temp'
|
Object.keys(bannerList.value).map((key) => ({
|
||||||
}
|
label: bannerList.value[key].name,
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
bannerList() {
|
|
||||||
return this.$store?.state?.bannerList || []
|
|
||||||
},
|
|
||||||
groupList() {
|
|
||||||
return Object.keys(this.bannerList).map((key) => {
|
|
||||||
return {
|
|
||||||
label: this.bannerList[key].name,
|
|
||||||
value: key
|
value: key
|
||||||
}
|
}))
|
||||||
})
|
)
|
||||||
},
|
const currentBannerList = computed(() => {
|
||||||
currentBannerList() {
|
const arr = Object.keys(bannerList.value)
|
||||||
const arr = Object.keys(this.bannerList)
|
|
||||||
.map((key) => {
|
.map((key) => {
|
||||||
return this.bannerList[key]
|
return bannerList.value[key]
|
||||||
})
|
})
|
||||||
.map((data) => {
|
.map((data) => {
|
||||||
return data.list.map((item) => {
|
return data.list.map((item: any) => {
|
||||||
item.group = data.key
|
item.group = data.key
|
||||||
return item
|
return item
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const allbanner = arr.reduce((acc, curr) => {
|
const allbanner = arr.reduce((acc, curr) => {
|
||||||
return acc.concat(curr)
|
return acc.concat(curr)
|
||||||
}, [])
|
}, [])
|
||||||
return allbanner.filter((item) => {
|
|
||||||
if (this.groupName === 'temp') {
|
return allbanner.filter((item: any) => {
|
||||||
|
if (groupName.value === 'temp') {
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
return item.group === this.groupName
|
return item.group === groupName.value
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
},
|
|
||||||
mounted() {},
|
const handleChangeGroup = (value: string) => {
|
||||||
methods: {
|
groupName.value = value
|
||||||
...mapActions({
|
}
|
||||||
changeThemePreset: 'edit/changeThemePreset'
|
|
||||||
}),
|
const changePreset = (banner: any) => {
|
||||||
changeGroup(value) {
|
|
||||||
this.groupName = value
|
|
||||||
},
|
|
||||||
changePreset(banner) {
|
|
||||||
const name = banner.group + '-' + banner.title
|
const name = banner.group + '-' + banner.title
|
||||||
let presets = {
|
let presets = {
|
||||||
'bannerConf.bannerConfig.bgImage': banner.src,
|
'bannerConf.bannerConfig.bgImage': banner.src,
|
||||||
'skinConf.themeConf.color': '#FAA600',
|
'skinConf.themeConf.color': '#FAA600',
|
||||||
'skinConf.backgroundConf.color': '#fff'
|
'skinConf.backgroundConf.color': '#fff'
|
||||||
}
|
}
|
||||||
if (skinPresets[name]) {
|
|
||||||
presets = Object.assign(presets, skinPresets[name])
|
if ((skinPresets as any)[name]) {
|
||||||
|
presets = Object.assign(presets, (skinPresets as any)[name])
|
||||||
}
|
}
|
||||||
|
|
||||||
this.changeThemePreset(presets)
|
store.dispatch('edit/changeThemePreset', presets)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
:module-config="_get(schema, collapse.key, {})"
|
:module-config="_get(schema, collapse.key, {})"
|
||||||
@form-change="
|
@form-change="
|
||||||
(key) => {
|
(key) => {
|
||||||
onFormChange(key, collapse.key)
|
handleFormChange(key, collapse.key)
|
||||||
}
|
}
|
||||||
"
|
"
|
||||||
/>
|
/>
|
||||||
@ -23,37 +23,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
|
import { computed, ref } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
import { get as _get } from 'lodash-es'
|
||||||
|
|
||||||
import skinConfig from '@/management/config/setterConfig/skinConfig'
|
import skinConfig from '@/management/config/setterConfig/skinConfig'
|
||||||
import SetterField from '@/management/pages/edit/components/SetterField.vue'
|
import SetterField from '@/management/pages/edit/components/SetterField.vue'
|
||||||
import { mapState } from 'vuex'
|
|
||||||
import { get as _get } from 'lodash-es'
|
const store = useStore()
|
||||||
export default {
|
const collapse = ref<string>('')
|
||||||
name: 'SetterPanel',
|
const schema = computed(() => _get(store.state, 'edit.schema'))
|
||||||
components: {
|
|
||||||
SetterField
|
const handleFormChange = (data: any, collapse: string) => {
|
||||||
},
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
collapse: '',
|
|
||||||
skinConfig
|
|
||||||
}
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
skinConf: (state) => _get(state, 'edit.schema.skinConf'),
|
|
||||||
schema: (state) => _get(state, 'edit.schema')
|
|
||||||
})
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
_get,
|
|
||||||
onFormChange(data, collapse) {
|
|
||||||
const { key, value } = data
|
const { key, value } = data
|
||||||
const currentEditKey = `${collapse}`
|
const currentEditKey = `${collapse}`
|
||||||
const resultKey = `${currentEditKey}.${key}`
|
const resultKey = `${currentEditKey}.${key}`
|
||||||
this.$store.dispatch('edit/changeSchema', { key: resultKey, value })
|
|
||||||
}
|
store.dispatch('edit/changeSchema', { key: resultKey, value })
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -5,15 +5,18 @@
|
|||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, provide } from 'vue'
|
import { computed, provide } from 'vue'
|
||||||
import RulePanel from '../../modules/logicModule/RulePanel.vue'
|
|
||||||
import { filterQuestionPreviewData } from '@/management/utils/index'
|
|
||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
|
|
||||||
|
import RulePanel from '../../modules/logicModule/RulePanel.vue'
|
||||||
|
import { filterQuestionPreviewData } from '@/management/utils/index'
|
||||||
|
|
||||||
const store = useStore()
|
const store = useStore()
|
||||||
|
|
||||||
const questionDataList = computed(() => {
|
const questionDataList = computed(() => {
|
||||||
return store.state.edit.schema.questionDataList
|
return store.state.edit.schema.questionDataList
|
||||||
})
|
})
|
||||||
|
|
||||||
const renderData = computed(() => {
|
const renderData = computed(() => {
|
||||||
return filterQuestionPreviewData(cloneDeep(questionDataList.value))
|
return filterQuestionPreviewData(cloneDeep(questionDataList.value))
|
||||||
})
|
})
|
||||||
|
@ -11,20 +11,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</CommonTemplate>
|
</CommonTemplate>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
import CommonTemplate from '../../components/CommonTemplate.vue'
|
import CommonTemplate from '../../components/CommonTemplate.vue'
|
||||||
import CatalogPanel from '../../modules/questionModule/CatalogPanel.vue'
|
import CatalogPanel from '../../modules/questionModule/CatalogPanel.vue'
|
||||||
import PreviewPanel from '../../modules/questionModule/PreviewPanel.vue'
|
import PreviewPanel from '../../modules/questionModule/PreviewPanel.vue'
|
||||||
import SetterPanel from '../../modules/questionModule/SetterPanel.vue'
|
import SetterPanel from '../../modules/questionModule/SetterPanel.vue'
|
||||||
export default {
|
|
||||||
name: 'editIndex',
|
|
||||||
components: {
|
|
||||||
CommonTemplate,
|
|
||||||
CatalogPanel,
|
|
||||||
PreviewPanel,
|
|
||||||
SetterPanel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.navbar {
|
.navbar {
|
||||||
|
@ -3,24 +3,21 @@
|
|||||||
<div class="navbar-tab">
|
<div class="navbar-tab">
|
||||||
<el-radio-group v-model="activeRouter">
|
<el-radio-group v-model="activeRouter">
|
||||||
<el-radio-button
|
<el-radio-button
|
||||||
v-for="btnItem in btnList"
|
v-for="item in routes"
|
||||||
:key="btnItem.router"
|
:key="item.router"
|
||||||
:label="btnItem.text"
|
:label="item.text"
|
||||||
:value="btnItem.router"
|
:value="item.router"
|
||||||
/>
|
/>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
export default {
|
import { watch, ref } from 'vue'
|
||||||
name: 'QuestionPage',
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
props: {},
|
|
||||||
data() {
|
const routes = [
|
||||||
return {
|
|
||||||
activeRouter: this.$route.name,
|
|
||||||
btnList: [
|
|
||||||
{
|
{
|
||||||
text: '内容设置',
|
text: '内容设置',
|
||||||
router: 'QuestionEditIndex',
|
router: 'QuestionEditIndex',
|
||||||
@ -31,17 +28,21 @@ export default {
|
|||||||
router: 'LogicIndex',
|
router: 'LogicIndex',
|
||||||
key: 'logicEdit'
|
key: 'logicEdit'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const activeRouter = ref(route.name)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
activeRouter,
|
||||||
|
(val: any) => {
|
||||||
|
router.push({ name: val })
|
||||||
},
|
},
|
||||||
watch: {
|
{
|
||||||
activeRouter: {
|
immediate: true
|
||||||
handler(val) {
|
|
||||||
this.$router.push({ name: val })
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.question-content {
|
.question-content {
|
||||||
|
@ -3,17 +3,9 @@
|
|||||||
<SettingPanel></SettingPanel>
|
<SettingPanel></SettingPanel>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
|
||||||
import SettingPanel from '../../modules/settingModule/SettingPanel.vue'
|
import SettingPanel from '../../modules/settingModule/SettingPanel.vue'
|
||||||
export default {
|
|
||||||
name: 'SettingPage',
|
|
||||||
components: {
|
|
||||||
SettingPanel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.setting-page {
|
.setting-page {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -11,24 +11,20 @@
|
|||||||
</template>
|
</template>
|
||||||
</CommonTemplate>
|
</CommonTemplate>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
|
import { onMounted } from 'vue'
|
||||||
|
import { useStore } from 'vuex'
|
||||||
|
|
||||||
import CommonTemplate from '../../components/CommonTemplate.vue'
|
import CommonTemplate from '../../components/CommonTemplate.vue'
|
||||||
import CatalogPanel from '../../modules/settingModule/skin/CatalogPanel.vue'
|
import CatalogPanel from '../../modules/settingModule/skin/CatalogPanel.vue'
|
||||||
import PreviewPanel from '../../modules/settingModule/skin/PreviewPanel.vue'
|
import PreviewPanel from '../../modules/settingModule/skin/PreviewPanel.vue'
|
||||||
import SetterPanel from '../../modules/settingModule/skin/SetterPanel.vue'
|
import SetterPanel from '../../modules/settingModule/skin/SetterPanel.vue'
|
||||||
|
|
||||||
export default {
|
const store = useStore()
|
||||||
name: 'ContentPage',
|
|
||||||
components: {
|
onMounted(() => {
|
||||||
CommonTemplate,
|
store.dispatch('getBannerData')
|
||||||
CatalogPanel,
|
})
|
||||||
PreviewPanel,
|
|
||||||
SetterPanel
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.$store.dispatch('getBannerData')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.navbar {
|
.navbar {
|
||||||
|
@ -11,20 +11,9 @@
|
|||||||
</template>
|
</template>
|
||||||
</CommonTemplate>
|
</CommonTemplate>
|
||||||
</template>
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
<script>
|
|
||||||
import CommonTemplate from '../../components/CommonTemplate.vue'
|
import CommonTemplate from '../../components/CommonTemplate.vue'
|
||||||
import ResultCatalog from '../../modules/settingModule/result/CatalogPanel.vue'
|
import ResultCatalog from '../../modules/settingModule/result/CatalogPanel.vue'
|
||||||
import ResultPreview from '../../modules/settingModule/result/PreviewPanel.vue'
|
import ResultPreview from '../../modules/settingModule/result/PreviewPanel.vue'
|
||||||
import ResultSetter from '../../modules/settingModule/result/SetterPanel.vue'
|
import ResultSetter from '../../modules/settingModule/result/SetterPanel.vue'
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'ResultPage',
|
|
||||||
components: {
|
|
||||||
CommonTemplate,
|
|
||||||
ResultCatalog,
|
|
||||||
ResultPreview,
|
|
||||||
ResultSetter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,24 +3,21 @@
|
|||||||
<div class="navbar-tab">
|
<div class="navbar-tab">
|
||||||
<el-radio-group v-model="activeRouter">
|
<el-radio-group v-model="activeRouter">
|
||||||
<el-radio-button
|
<el-radio-button
|
||||||
v-for="btnItem in btnList"
|
v-for="item in routes"
|
||||||
:key="btnItem.router"
|
:key="item.router"
|
||||||
:label="btnItem.text"
|
:label="item.text"
|
||||||
:value="btnItem.router"
|
:value="item.router"
|
||||||
/>
|
/>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</div>
|
</div>
|
||||||
<router-view></router-view>
|
<router-view></router-view>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script setup lang="ts">
|
||||||
export default {
|
import { watch, ref } from 'vue'
|
||||||
name: 'skinPage',
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
props: {},
|
|
||||||
data() {
|
const routes = [
|
||||||
return {
|
|
||||||
activeRouter: this.$route.name,
|
|
||||||
btnList: [
|
|
||||||
{
|
{
|
||||||
text: '内容页',
|
text: '内容页',
|
||||||
router: 'QuestionSkinSetting',
|
router: 'QuestionSkinSetting',
|
||||||
@ -32,17 +29,21 @@ export default {
|
|||||||
router: 'QuestionEditResultConfig',
|
router: 'QuestionEditResultConfig',
|
||||||
key: 'status'
|
key: 'status'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
|
||||||
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
const activeRouter = ref(route.name)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
activeRouter,
|
||||||
|
(val: any) => {
|
||||||
|
router.push({ name: val })
|
||||||
},
|
},
|
||||||
watch: {
|
{
|
||||||
activeRouter: {
|
immediate: true
|
||||||
handler(val) {
|
|
||||||
this.$router.push({ name: val })
|
|
||||||
}
|
}
|
||||||
}
|
)
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.skin-content {
|
.skin-content {
|
||||||
|
Loading…
Reference in New Issue
Block a user