|
@@ -1,7 +1,6 @@
|
|
|
<script setup lang="ts">
|
|
|
import {ref} from "vue";
|
|
|
-import {isDev} from "@/utils/public";
|
|
|
-import {IntergrationMenu} from "@/api/settings/menu-settings";
|
|
|
+import {IntergrationMenu, updateMenuSettings} from "@/api/settings/menu-settings";
|
|
|
import {
|
|
|
ElButton,
|
|
|
ElCascader,
|
|
@@ -13,21 +12,28 @@ import {
|
|
|
ElInput,
|
|
|
ElPopover,
|
|
|
ElInputNumber,
|
|
|
- ElSwitch
|
|
|
+ ElSwitch,
|
|
|
+ FormRules,
|
|
|
+ ElSelectV2
|
|
|
} from "element-plus";
|
|
|
import XEUtils from "xe-utils";
|
|
|
import icon from '@/icons/iconfont.css'
|
|
|
import {eachAndReturnList} from "@/utils/cyRefList";
|
|
|
+import {useCompRef} from "@/utils/useCompRef";
|
|
|
|
|
|
const props = defineProps<{
|
|
|
- menuTreeData: any[],
|
|
|
+ cascaderData: any[],
|
|
|
+}>()
|
|
|
+
|
|
|
+const emits = defineEmits<{
|
|
|
+ (e: "saveCallback"): void,
|
|
|
}>()
|
|
|
|
|
|
declare type VueIntergrationPlatformMenu = {
|
|
|
- parentCascader: number[]
|
|
|
+ cascaders: number[]
|
|
|
} & IntergrationMenu
|
|
|
|
|
|
-const showDialog = ref(isDev)
|
|
|
+const showDialog = ref(false)
|
|
|
const currentData = ref<VueIntergrationPlatformMenu>({
|
|
|
children: [],
|
|
|
component: "",
|
|
@@ -37,7 +43,7 @@ const currentData = ref<VueIntergrationPlatformMenu>({
|
|
|
metaPassRule: false,
|
|
|
metaTitle: "",
|
|
|
name: "",
|
|
|
- parentCascader: [],
|
|
|
+ cascaders: [],
|
|
|
parentId: 0,
|
|
|
path: "",
|
|
|
pathParams: "",
|
|
@@ -46,18 +52,65 @@ const currentData = ref<VueIntergrationPlatformMenu>({
|
|
|
type: 0
|
|
|
})
|
|
|
|
|
|
-function save() {
|
|
|
- if (currentData.value.parentCascader.length > 0) {
|
|
|
- currentData.value.parentId = currentData.value.parentCascader[currentData.value.parentCascader.length - 1]
|
|
|
+const fromRef = useCompRef(ElForm)
|
|
|
+
|
|
|
+
|
|
|
+const rules: FormRules<VueIntergrationPlatformMenu> = reactive({})
|
|
|
+type D = keyof VueIntergrationPlatformMenu
|
|
|
+
|
|
|
+function addRequired(key: D[]) {
|
|
|
+ key.forEach(item => {
|
|
|
+ rules[item] = [{required: true, trigger: 'change', message: '必填'}]
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+addRequired(['path', 'component', 'name', 'metaTitle'])
|
|
|
+
|
|
|
+async function save() {
|
|
|
+ await fromRef.value?.validate()
|
|
|
+ if (currentData.value.cascaders.length > 0) {
|
|
|
+ currentData.value.parentId = currentData.value.cascaders[currentData.value.cascaders.length - 1]
|
|
|
}
|
|
|
+ await updateMenuSettings(currentData.value)
|
|
|
+ emits('saveCallback')
|
|
|
+ showDialog.value = false
|
|
|
}
|
|
|
|
|
|
+const icons = ref([])
|
|
|
+const routerKey = ref([])
|
|
|
+
|
|
|
+const layout = [
|
|
|
+ {
|
|
|
+ value: 'Layout',
|
|
|
+ label: 'Layout'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 'EmptyRouter',
|
|
|
+ label: 'EmptyRouter'
|
|
|
+ }
|
|
|
+]
|
|
|
+
|
|
|
+function dialogOpen() {
|
|
|
+ const regex = /.(?<icon>.*):before/g;
|
|
|
+ const matches = (icon as string).matchAll(regex);
|
|
|
+ icons.value = eachAndReturnList((matches as string[]), (item) => {
|
|
|
+ return item[1]
|
|
|
+ })
|
|
|
+
|
|
|
+ const view = import.meta.glob('/src/views/**/*.{vue,tsx}');
|
|
|
+
|
|
|
+ routerKey.value = eachAndReturnList(Object.keys(view), (item) => {
|
|
|
+ const tmp = item.replace("/src", "..")
|
|
|
+ return {
|
|
|
+ value: tmp,
|
|
|
+ label: tmp,
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ routerKey.value.push(...layout)
|
|
|
+
|
|
|
+}
|
|
|
|
|
|
-const regex = /.(?<icon>.*):before/g;
|
|
|
-const matches = (icon as string).matchAll(regex);
|
|
|
-const icons = ref(eachAndReturnList((matches as string[]), (item) => {
|
|
|
- return item[1]
|
|
|
-}))
|
|
|
|
|
|
function iconClick(icon) {
|
|
|
currentData.value.icon = `iconfont ${icon}`
|
|
@@ -66,7 +119,6 @@ function iconClick(icon) {
|
|
|
defineExpose({
|
|
|
openDialog: (row: VueIntergrationPlatformMenu) => {
|
|
|
currentData.value = XEUtils.clone(row, true)
|
|
|
- currentData.value.parentCascader = []
|
|
|
showDialog.value = true;
|
|
|
}
|
|
|
})
|
|
@@ -75,43 +127,54 @@ defineExpose({
|
|
|
|
|
|
<template>
|
|
|
<el-dialog v-model="showDialog"
|
|
|
+ @open="dialogOpen"
|
|
|
title="菜单编辑"
|
|
|
destroy-on-close
|
|
|
draggable>
|
|
|
- <el-form label-width="80px" size="default">
|
|
|
+ <el-form
|
|
|
+ ref="fromRef"
|
|
|
+ :model="currentData"
|
|
|
+ :rules="rules"
|
|
|
+ label-width="80px"
|
|
|
+ size="default">
|
|
|
<el-row :gutter="10">
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="父节点">
|
|
|
+ <el-form-item label="父节点" prop="cascaders">
|
|
|
<el-cascader
|
|
|
- v-model="currentData.parentCascader"
|
|
|
+ v-model="currentData.cascaders"
|
|
|
style="width: 100%"
|
|
|
:props="{ checkStrictly: true, value: 'id', label: 'metaTitle' }"
|
|
|
- :options="menuTreeData"
|
|
|
+ :options="cascaderData"
|
|
|
clearable/>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
-
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="完整路径">
|
|
|
+ <el-form-item label="路径" prop="path">
|
|
|
<el-input v-model="currentData.path"/>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="组件路径">
|
|
|
- <el-input v-model="currentData.component"/>
|
|
|
+ <el-form-item label="组件路径" prop="component">
|
|
|
+ <el-select-v2
|
|
|
+ v-model="currentData.component"
|
|
|
+ :options="routerKey"
|
|
|
+ style="width: 100%"
|
|
|
+ filterable
|
|
|
+ />
|
|
|
+
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="24">
|
|
|
- <el-form-item label="路径参数">
|
|
|
+ <el-form-item label="路径参数" prop="pathParams">
|
|
|
<el-input v-model="currentData.pathParams"/>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="类型">
|
|
|
+ <el-form-item label="类型" prop="type">
|
|
|
<el-switch v-model="currentData.type"
|
|
|
:active-value="1"
|
|
|
:inactive-value="2"
|
|
@@ -122,7 +185,7 @@ defineExpose({
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="路由名称">
|
|
|
+ <el-form-item label="路由名称" prop="name">
|
|
|
<el-input v-model="currentData.name"
|
|
|
clearable maxlength="50"/>
|
|
|
</el-form-item>
|
|
@@ -155,7 +218,7 @@ defineExpose({
|
|
|
</el-col>
|
|
|
|
|
|
<el-col :span="12">
|
|
|
- <el-form-item label="菜单名称">
|
|
|
+ <el-form-item label="菜单名称" prop="metaTitle">
|
|
|
<el-input v-model="currentData.metaTitle"
|
|
|
clearable maxlength="50"/>
|
|
|
</el-form-item>
|
|
@@ -196,6 +259,38 @@ defineExpose({
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="卡片类型">
|
|
|
+ <el-switch v-model="currentData.mainCard"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ active-text="是"
|
|
|
+ inactive-text="否"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="超出滚动">
|
|
|
+ <el-switch v-model="currentData.mainOverflowAuto"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ active-text="是"
|
|
|
+ inactive-text="否"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <el-col :span="12">
|
|
|
+ <el-form-item label="无需登录">
|
|
|
+ <el-switch v-model="currentData.metaNeedToken"
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="0"
|
|
|
+ active-text="是"
|
|
|
+ inactive-text="否"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-col>
|
|
|
|
|
|
</el-row>
|
|
|
</el-form>
|