v2.6.6版本发布 (#1784)
* 前端支持顶部菜单栏模式 * 自动化代码单条获取方法不再需要取data.xxx直接取用data * 自动化代码支持选择索引 * 自动化代码回滚支持自行选择是否删除菜单、API、表 * 日志增加定期清理功能 * 权限配置API部分,支持根据API真实path进行筛选 * 修复了一些已知bug * 修复了一个sql注入漏洞 --------- Co-authored-by: xuedinge <781408517@qq.com> Co-authored-by: Qing Liang <106448173+xue-ding-e@users.noreply.github.com> Co-authored-by: wall-js <wall_js@foxmail.com> Co-authored-by: Wall <307606056@qq.com> Co-authored-by: leooza <leooza@163.com> Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com> Co-authored-by: hxl <52553624@qq.com> Co-authored-by: zsc1003 <11476303+zsc1003@user.noreply.gitee.com>
This commit is contained in:
co-authored by
xuedinge
Qing Liang
wall-js
Wall
leooza
piexlMax(奇淼
hxl
zsc1003
parent
b336529d42
commit
03e5bc515f
@@ -2,7 +2,7 @@
|
||||
<el-sub-menu
|
||||
ref="subMenu"
|
||||
:index="routerInfo.name"
|
||||
class="gva-sub-menu dark:text-slate-300"
|
||||
class="gva-sub-menu dark:text-slate-300 relative"
|
||||
>
|
||||
<template #title>
|
||||
<div
|
||||
@@ -52,7 +52,9 @@ const isCollapse = inject('isCollapse', {
|
||||
default: false,
|
||||
})
|
||||
|
||||
const sideHeight = computed(() => config.value.layout_side_item_height + 'px')
|
||||
const sideHeight = computed(() => {
|
||||
return config.value.layout_side_item_height + 'px'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -29,6 +29,10 @@ const props = defineProps({
|
||||
type: Object,
|
||||
default: () => null,
|
||||
},
|
||||
mode :{
|
||||
type : String,
|
||||
default: "vertical"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -36,7 +36,9 @@ defineProps({
|
||||
},
|
||||
})
|
||||
|
||||
const sideHeight = computed(() => config.value.layout_side_item_height + 'px')
|
||||
const sideHeight = computed(() => {
|
||||
return config.value.layout_side_item_height + 'px'
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
<template>
|
||||
<div class="bg-white h-[calc(100%-4px)] text-slate-700 dark:text-slate-300 mx-2 dark:bg-slate-900 flex items-center w-full overflow-auto">
|
||||
<el-menu
|
||||
:default-active="active"
|
||||
mode="horizontal"
|
||||
class="border-r-0 w-[calc(100%-100px)] flex gap-1 items-center box-border h-[calc(100%-1px)]"
|
||||
unique-opened
|
||||
@select="selectMenuItem"
|
||||
>
|
||||
<template v-for="item in routerStore.asyncRouters[0].children">
|
||||
<aside-component
|
||||
v-if="!item.hidden"
|
||||
:key="item.name"
|
||||
:router-info="item"
|
||||
mode="horizontal"
|
||||
/>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AsideComponent from "@/view/layout/aside/asideComponent/index.vue";
|
||||
import { ref, provide, watchEffect, computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useRouterStore } from "@/pinia/modules/router";
|
||||
import { useAppStore } from "@/pinia";
|
||||
import { storeToRefs } from "pinia";
|
||||
const appStore = useAppStore();
|
||||
const { device, config } = storeToRefs(appStore);
|
||||
|
||||
defineOptions({
|
||||
name: "GvaAside",
|
||||
});
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const routerStore = useRouterStore();
|
||||
const isCollapse = ref(false);
|
||||
const active = ref("");
|
||||
watchEffect(() => {
|
||||
active.value = route.meta.activeName || route.name;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (device.value === "mobile") {
|
||||
isCollapse.value = true;
|
||||
} else {
|
||||
isCollapse.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
provide("isCollapse", isCollapse);
|
||||
|
||||
const selectMenuItem = (index, _, ele, aaa) => {
|
||||
const query = {};
|
||||
const params = {};
|
||||
routerStore.routeMap[index]?.parameters &&
|
||||
routerStore.routeMap[index]?.parameters.forEach((item) => {
|
||||
if (item.type === "query") {
|
||||
query[item.key] = item.value;
|
||||
} else {
|
||||
params[item.key] = item.value;
|
||||
}
|
||||
});
|
||||
if (index === route.name) return;
|
||||
if (index.indexOf("http://") > -1 || index.indexOf("https://") > -1) {
|
||||
window.open(index);
|
||||
} else {
|
||||
router.push({ name: index, query, params });
|
||||
}
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.el-menu--horizontal.el-menu,
|
||||
.el-menu--horizontal > .el-menu-item.is-active{
|
||||
border-bottom : none !important;
|
||||
|
||||
}
|
||||
|
||||
.el-menu-item.is-active{
|
||||
background-color: var(--el-color-primary-light-8) !important;
|
||||
}
|
||||
|
||||
.dark{
|
||||
.el-menu-item.is-active{
|
||||
background-color: var(--el-color-primary-bg) !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,116 +1,15 @@
|
||||
<template>
|
||||
<div
|
||||
class="relative h-full bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 border-r shadow dark:shadow-gray-700"
|
||||
:class="isCollapse ? '' : ' px-2'"
|
||||
:style="{
|
||||
width : layoutSideWidth + 'px',
|
||||
}"
|
||||
>
|
||||
<el-scrollbar>
|
||||
<transition
|
||||
:duration="{ enter: 800, leave: 100 }"
|
||||
mode="out-in"
|
||||
name="el-fade-in-linear"
|
||||
>
|
||||
<el-menu
|
||||
:collapse="isCollapse"
|
||||
:collapse-transition="false"
|
||||
:default-active="active"
|
||||
class="border-r-0 w-full"
|
||||
unique-opened
|
||||
@select="selectMenuItem"
|
||||
>
|
||||
<template v-for="item in routerStore.asyncRouters[0].children">
|
||||
<aside-component
|
||||
v-if="!item.hidden"
|
||||
:key="item.name"
|
||||
:router-info="item"
|
||||
/>
|
||||
</template>
|
||||
</el-menu>
|
||||
</transition>
|
||||
</el-scrollbar>
|
||||
<div
|
||||
class="absolute bottom-8 right-2 w-8 h-8 bg-gray-50 dark:bg-slate-800 flex items-center justify-center rounded cursor-pointer "
|
||||
:class="isCollapse ? 'right-0 left-0 mx-auto' : 'right-2'"
|
||||
@click="toggleCollapse"
|
||||
>
|
||||
<el-icon v-if="!isCollapse">
|
||||
<DArrowLeft />
|
||||
</el-icon>
|
||||
<el-icon v-else>
|
||||
<DArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
<div>
|
||||
<normal-mode v-if="config.side_mode != 'head' || (device === 'mobile'&& config.side_mode == 'head' )" />
|
||||
<head-mode v-if="config.side_mode === 'head' && device !== 'mobile'" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AsideComponent from "@/view/layout/aside/asideComponent/index.vue";
|
||||
import { ref, provide, watchEffect, computed} from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useRouterStore } from "@/pinia/modules/router";
|
||||
import { useAppStore } from "@/pinia"
|
||||
import { storeToRefs } from "pinia"
|
||||
const appStore = useAppStore()
|
||||
const { device, config } = storeToRefs(appStore)
|
||||
|
||||
defineOptions({
|
||||
name: "GvaAside",
|
||||
});
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const routerStore = useRouterStore();
|
||||
const isCollapse = ref(false)
|
||||
const active = ref("");
|
||||
const layoutSideWidth = computed(() =>{
|
||||
if (!isCollapse.value) {
|
||||
return config.value.layout_side_width
|
||||
}else{
|
||||
return config.value.layout_side_collapsed_width
|
||||
}
|
||||
})
|
||||
watchEffect(() => {
|
||||
active.value = route.meta.activeName || route.name;
|
||||
});
|
||||
|
||||
watchEffect(() =>{
|
||||
if (device.value === 'mobile') {
|
||||
isCollapse.value = true
|
||||
}else{
|
||||
isCollapse.value = false
|
||||
}
|
||||
})
|
||||
|
||||
provide("isCollapse", isCollapse);
|
||||
|
||||
|
||||
|
||||
const selectMenuItem = (index, _, ele, aaa) => {
|
||||
const query = {};
|
||||
const params = {};
|
||||
routerStore.routeMap[index]?.parameters &&
|
||||
routerStore.routeMap[index]?.parameters.forEach((item) => {
|
||||
if (item.type === "query") {
|
||||
query[item.key] = item.value;
|
||||
} else {
|
||||
params[item.key] = item.value;
|
||||
}
|
||||
});
|
||||
if (index === route.name) return;
|
||||
if (index.indexOf("http://") > -1 || index.indexOf("https://") > -1) {
|
||||
window.open(index);
|
||||
} else {
|
||||
router.push({ name: index, query, params });
|
||||
}
|
||||
};
|
||||
|
||||
const toggleCollapse = () => {
|
||||
isCollapse.value = !isCollapse.value;
|
||||
};
|
||||
|
||||
import NormalMode from "./normalMode.vue"
|
||||
import HeadMode from "./headMode.vue"
|
||||
import { storeToRefs } from "pinia";
|
||||
import { useAppStore } from "@/pinia";
|
||||
const appStore = useAppStore();
|
||||
const { config, device } = storeToRefs(appStore);
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
<template>
|
||||
<div
|
||||
class="relative h-full bg-white text-slate-700 dark:text-slate-300 dark:bg-slate-900 border-r shadow dark:shadow-gray-700"
|
||||
:class="isCollapse ? '' : ' px-2'"
|
||||
:style="{
|
||||
width: layoutSideWidth + 'px',
|
||||
}"
|
||||
>
|
||||
<el-menu
|
||||
:collapse="isCollapse"
|
||||
:collapse-transition="false"
|
||||
:default-active="active"
|
||||
class="border-r-0 w-full"
|
||||
unique-opened
|
||||
@select="selectMenuItem"
|
||||
>
|
||||
<template v-for="item in routerStore.asyncRouters[0].children">
|
||||
<aside-component
|
||||
v-if="!item.hidden"
|
||||
:key="item.name"
|
||||
:router-info="item"
|
||||
/>
|
||||
</template>
|
||||
</el-menu>
|
||||
<div
|
||||
class="absolute bottom-8 right-2 w-8 h-8 bg-gray-50 dark:bg-slate-800 flex items-center justify-center rounded cursor-pointer"
|
||||
:class="isCollapse ? 'right-0 left-0 mx-auto' : 'right-2'"
|
||||
@click="toggleCollapse"
|
||||
>
|
||||
<el-icon v-if="!isCollapse">
|
||||
<DArrowLeft />
|
||||
</el-icon>
|
||||
<el-icon v-else>
|
||||
<DArrowRight />
|
||||
</el-icon>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import AsideComponent from "@/view/layout/aside/asideComponent/index.vue";
|
||||
import { ref, provide, watchEffect, computed } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { useRouterStore } from "@/pinia/modules/router";
|
||||
import { useAppStore } from "@/pinia";
|
||||
import { storeToRefs } from "pinia";
|
||||
const appStore = useAppStore();
|
||||
const { device, config } = storeToRefs(appStore);
|
||||
|
||||
defineOptions({
|
||||
name: "GvaAside",
|
||||
});
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const routerStore = useRouterStore();
|
||||
const isCollapse = ref(false);
|
||||
const active = ref("");
|
||||
const layoutSideWidth = computed(() => {
|
||||
if (!isCollapse.value) {
|
||||
return config.value.layout_side_width;
|
||||
} else {
|
||||
return config.value.layout_side_collapsed_width;
|
||||
}
|
||||
});
|
||||
watchEffect(() => {
|
||||
active.value = route.meta.activeName || route.name;
|
||||
});
|
||||
|
||||
watchEffect(() => {
|
||||
if (device.value === "mobile") {
|
||||
isCollapse.value = true;
|
||||
} else {
|
||||
isCollapse.value = false;
|
||||
}
|
||||
});
|
||||
|
||||
provide("isCollapse", isCollapse);
|
||||
|
||||
const selectMenuItem = (index, _, ele, aaa) => {
|
||||
const query = {};
|
||||
const params = {};
|
||||
routerStore.routeMap[index]?.parameters &&
|
||||
routerStore.routeMap[index]?.parameters.forEach((item) => {
|
||||
if (item.type === "query") {
|
||||
query[item.key] = item.value;
|
||||
} else {
|
||||
params[item.key] = item.value;
|
||||
}
|
||||
});
|
||||
if (index === route.name) return;
|
||||
if (index.indexOf("http://") > -1 || index.indexOf("https://") > -1) {
|
||||
window.open(index);
|
||||
} else {
|
||||
router.push({ name: index, query, params });
|
||||
}
|
||||
};
|
||||
|
||||
const toggleCollapse = () => {
|
||||
isCollapse.value = !isCollapse.value;
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss"></style>
|
||||
|
||||
Reference in New Issue
Block a user