mirror of
https://gitcode.com/flipped-aurora/gin-vue-admin.git
synced 2025-12-30 03:42:26 +00:00
* feat(mcp): 新增gva_review工具并优化字典和代码生成逻辑 * fix: 调整mcp整体逻辑 * chore: 更新.gitignore,添加对本地配置文件的忽略 * feat(logo): 新增Logo组件并在多个页面中替换原有logo实现 * fix: 修复菜单 Logo 部分删除文本后显示异常的问题 * fix:添加字典列表搜索,支持中英文搜索.添加字典详情搜索 * style: 优化部分视觉样式 * feat: 增强错误预览组件的暗黑模式支持 * feat: 优化请求错误消息获取逻辑,增加状态文本优先级 * feat: 添加前端登录验证码静态验证逻辑 * feat: 添加开发环境启动脚本 * feat: 更新 SvgIcon 组件,支持本地图标和 Iconify 图标、移除未使用的 unocss 依赖 * fix:字典支持 tree 结构 * feat: 优化动态路由注册方式 * feat: 添加配置控制标签页keep-alive功能 * feat: 添加全局错误处理机制,捕获 Vue 和 JS 错误 * refactor: 移除API和菜单创建结果中的权限分配提醒,优化输出信息 * feat: 更新 reset.scss,优化全局样式重置,增强兼容性和可读性 * refactor(字典详情): 优化字典详情查询逻辑,移除预加载改为按需加载 * refactor(路由管理): 优化路由添加逻辑,增强路径处理和顶级路由注册 * refactor(系统配置): 将auto-migrate修改为disable-auto-migrate,保证用户升级的兼容性 * feat(utils): 优化字典数据递归查找功能并替换select为tree-select * fix(deps): 修复在字段类型为file生成搜索条件无法运行的bug * fix: 修复header的tools中icon不展示的问题 --------- Co-authored-by: piexlMax(奇淼 <qimiaojiangjizhao@gmail.com> Co-authored-by: Azir-11 <2075125282@qq.com> Co-authored-by: bypanghu <bypanghu@163.com> Co-authored-by: feitianbubu <feitianbubu@qq.com> Co-authored-by: 青菜白玉汤 <79054161+Azir-11@users.noreply.github.com> Co-authored-by: krank <emosick@qq.com>
119 lines
3.5 KiB
Vue
119 lines
3.5 KiB
Vue
<template>
|
|
<div
|
|
class="bg-gray-50 text-slate-700 dark:text-slate-500 dark:bg-slate-800 w-screen h-screen"
|
|
>
|
|
<el-watermark
|
|
v-if="config.show_watermark"
|
|
:font="font"
|
|
:z-index="9999"
|
|
:gap="[180, 150]"
|
|
class="!absolute !inset-0 !pointer-events-none"
|
|
:content="userStore.userInfo.nickName"
|
|
/>
|
|
<gva-header />
|
|
<div class="flex flex-row w-full gva-container pt-16 box-border !h-full">
|
|
<gva-aside
|
|
v-if="
|
|
config.side_mode === 'normal' ||
|
|
config.side_mode === 'sidebar' ||
|
|
(device === 'mobile' && config.side_mode == 'head') ||
|
|
(device === 'mobile' && config.side_mode == 'combination')
|
|
"
|
|
/>
|
|
<gva-aside
|
|
v-if="config.side_mode === 'combination' && device !== 'mobile'"
|
|
mode="normal"
|
|
/>
|
|
<div class="flex-1 w-0 h-full">
|
|
<gva-tabs v-if="config.showTabs" />
|
|
<div
|
|
class="overflow-auto px-2"
|
|
:class="config.showTabs ? 'gva-container2' : 'gva-container pt-1'"
|
|
>
|
|
<router-view v-if="reloadFlag" v-slot="{ Component, route }">
|
|
<div
|
|
id="gva-base-load-dom"
|
|
class="gva-body-h bg-gray-50 dark:bg-slate-800"
|
|
>
|
|
<transition
|
|
mode="out-in"
|
|
:name="route.meta.transitionType || config.transition_type"
|
|
>
|
|
<keep-alive :include="routerStore.keepAliveRouters">
|
|
<component :is="Component" :key="route.fullPath" />
|
|
</keep-alive>
|
|
</transition>
|
|
</div>
|
|
</router-view>
|
|
<BottomInfo />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import GvaAside from '@/view/layout/aside/index.vue'
|
|
import GvaHeader from '@/view/layout/header/index.vue'
|
|
import useResponsive from '@/hooks/responsive'
|
|
import GvaTabs from './tabs/index.vue'
|
|
import BottomInfo from '@/components/bottomInfo/bottomInfo.vue'
|
|
import { emitter } from '@/utils/bus.js'
|
|
import { ref, onMounted, nextTick, reactive, watchEffect } from 'vue'
|
|
import { useRouter, useRoute } from 'vue-router'
|
|
import { useRouterStore } from '@/pinia/modules/router'
|
|
import { useUserStore } from '@/pinia/modules/user'
|
|
import { useAppStore } from '@/pinia'
|
|
import { storeToRefs } from 'pinia'
|
|
import '@/style/transition.scss'
|
|
const appStore = useAppStore()
|
|
const { config, isDark, device } = storeToRefs(appStore)
|
|
|
|
defineOptions({
|
|
name: 'GvaLayout'
|
|
})
|
|
|
|
useResponsive(true)
|
|
const font = reactive({
|
|
color: 'rgba(0, 0, 0, .15)'
|
|
})
|
|
|
|
watchEffect(() => {
|
|
font.color = isDark.value ? 'rgba(255,255,255, .15)' : 'rgba(0, 0, 0, .15)'
|
|
})
|
|
|
|
const router = useRouter()
|
|
const route = useRoute()
|
|
const routerStore = useRouterStore()
|
|
|
|
onMounted(() => {
|
|
// 挂载一些通用的事件
|
|
emitter.on('reload', reload)
|
|
if (userStore.loadingInstance) {
|
|
userStore.loadingInstance.close()
|
|
}
|
|
})
|
|
|
|
const userStore = useUserStore()
|
|
|
|
const reloadFlag = ref(true)
|
|
let reloadTimer = null
|
|
const reload = async () => {
|
|
if (reloadTimer) {
|
|
window.clearTimeout(reloadTimer)
|
|
}
|
|
reloadTimer = window.setTimeout(async () => {
|
|
if (route.meta.keepAlive) {
|
|
reloadFlag.value = false
|
|
await nextTick()
|
|
reloadFlag.value = true
|
|
} else {
|
|
const title = route.meta.title
|
|
router.push({ name: 'Reload', params: { title } })
|
|
}
|
|
}, 400)
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss"></style>
|