From 916071814ae60cc5f740417305303282be33c7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Wed, 20 Dec 2023 23:43:32 +0800 Subject: [PATCH 01/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG:=201.=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=8A=A5=E9=94=99=E5=90=8E,=E7=BB=A7=E7=BB=AD?= =?UTF-8?q?=E9=80=9A=E8=BF=87=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/application/settings.py | 6 ++++++ web/src/utils/service.ts | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/backend/application/settings.py b/backend/application/settings.py index 590c144..fb79ad6 100644 --- a/backend/application/settings.py +++ b/backend/application/settings.py @@ -154,6 +154,11 @@ STATICFILES_DIRS = [ MEDIA_ROOT = "media" # 项目下的目录 MEDIA_URL = "/media/" # 跟STATIC_URL类似,指定用户可以通过这个url找到文件 +#添加以下代码以后就不用写{% load staticfiles %},可以直接引用 +STATICFILES_FINDERS = ( + "django.contrib.staticfiles.finders.FileSystemFinder", + "django.contrib.staticfiles.finders.AppDirectoriesFinder" +) # 收集静态文件,必须将 MEDIA_ROOT,STATICFILES_DIRS先注释 # python manage.py collectstatic # STATIC_ROOT=os.path.join(BASE_DIR,'static') @@ -402,5 +407,6 @@ PLUGINS_URL_PATTERNS = [] # from dvadmin_third.settings import * # 第三方用户管理 # from dvadmin_ak_sk.settings import * # 秘钥管理管理 # from dvadmin_tenants.settings import * # 租户管理 +from dvadmin_social_auth.settings import * # ... # ********** 一键导入插件配置结束 ********** diff --git a/web/src/utils/service.ts b/web/src/utils/service.ts index 6253446..aaed7ff 100644 --- a/web/src/utils/service.ts +++ b/web/src/utils/service.ts @@ -96,12 +96,13 @@ function createService() { return dataAxios; case 4000: errorCreate(`${dataAxios.msg}: ${response.config.url}`); - return dataAxios; + break; default: // 不是正确的 code errorCreate(`${dataAxios.msg}: ${response.config.url}`); - return dataAxios; + break; } + return Promise.reject(); } }, (error) => { From 7d315a7d28ad43eb62b09a37e6be8377122de5ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Wed, 20 Dec 2023 23:44:45 +0800 Subject: [PATCH 02/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG:=201.=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E4=B8=8A=E4=BC=A0=E8=BF=94=E5=9B=9E=E5=80=BC=E7=BC=BA?= =?UTF-8?q?=E5=B0=91=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/.env | 2 +- web/src/settings.ts | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/web/.env b/web/.env index 6bc4ce9..0d828a7 100644 --- a/web/.env +++ b/web/.env @@ -1,6 +1,6 @@ # port 端口号 VITE_PORT = 8080 - +VITE_API_URL = 'http://dvadmin3api.django.icu:8001' # open 运行 npm run dev 时自动打开浏览器 VITE_OPEN = false diff --git a/web/src/settings.ts b/web/src/settings.ts index 7426ad1..c70fb38 100644 --- a/web/src/settings.ts +++ b/web/src/settings.ts @@ -104,7 +104,8 @@ export default { // 上传完成后的结果处理, 此处应返回格式为{url:xxx,key:xxx} return { url: getBaseURL() + ret.data.url, - key: ret.data.id + key: ret.data.id, + ...ret.data }; } } From ba4a580bb0be7e6f3de8e78cb08dc82c3c949b24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Wed, 20 Dec 2023 23:56:09 +0800 Subject: [PATCH 03/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG:=201.=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=9B=B4=E6=96=B0=E6=8F=90=E7=A4=BA,=E6=8B=92?= =?UTF-8?q?=E7=BB=9D=E5=90=8E=E4=BB=8D=E7=84=B6=E5=BC=B9=E5=87=BA=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/layout/upgrade/index.vue | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/web/src/layout/upgrade/index.vue b/web/src/layout/upgrade/index.vue index a107954..9419fcc 100644 --- a/web/src/layout/upgrade/index.vue +++ b/web/src/layout/upgrade/index.vue @@ -36,7 +36,7 @@ import { reactive, computed, onMounted } from 'vue'; import { useI18n } from 'vue-i18n'; import { storeToRefs } from 'pinia'; import { useThemeConfig } from '/@/stores/themeConfig'; -import { Local } from '/@/utils/storage'; +import { Local,Session } from '/@/utils/storage'; // 定义变量内容 const { t } = useI18n(); @@ -57,6 +57,7 @@ const getThemeConfig = computed(() => { // 残忍拒绝 const onCancel = () => { state.isUpgrade = false; + Session.set('isUpgrade', false) }; // 马上更新 const onUpgrade = () => { @@ -66,13 +67,17 @@ const onUpgrade = () => { Local.clear(); window.location.reload(); Local.set('version', state.version); + Session.set('isUpgrade', false) }, 2000); }; // 延迟显示,防止刷新时界面显示太快 const delayShow = () => { - setTimeout(() => { - state.isUpgrade = true; - }, 2000); + const isUpgrade = Session.get('isUpgrade')===false?Session.get('isUpgrade'):true + if(isUpgrade){ + setTimeout(() => { + state.isUpgrade = true; + }, 2000); + } }; // 页面加载时 onMounted(() => { From 2826cafa7532c011b27c3725a7b30810cfef16ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Sun, 24 Dec 2023 11:04:28 +0800 Subject: [PATCH 04/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG:=201.=E9=AA=8C?= =?UTF-8?q?=E8=AF=81=E7=A0=81=E8=BE=93=E5=85=A5=E9=94=99=E8=AF=AF=E4=B8=8D?= =?UTF-8?q?=E5=88=B7=E6=96=B0=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/utils/service.ts | 2 +- web/src/views/system/login/component/account.vue | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/web/src/utils/service.ts b/web/src/utils/service.ts index 1e88e75..0dfe45a 100644 --- a/web/src/utils/service.ts +++ b/web/src/utils/service.ts @@ -102,7 +102,7 @@ function createService() { errorCreate(`${dataAxios.msg}: ${response.config.url}`); break; } - return Promise.reject(); + return Promise.reject(dataAxios); } }, (error) => { diff --git a/web/src/views/system/login/component/account.vue b/web/src/views/system/login/component/account.vue index 88debdc..c4b1247 100644 --- a/web/src/views/system/login/component/account.vue +++ b/web/src/views/system/login/component/account.vue @@ -126,6 +126,7 @@ export default defineComponent({ }); }; const refreshCaptcha = async () => { + state.ruleForm.captcha='' loginApi.getCaptcha().then((ret: any) => { state.ruleForm.captchaImgBase = ret.data.image_base; state.ruleForm.captchaKey = ret.data.key; @@ -150,11 +151,11 @@ export default defineComponent({ // 执行完 initBackEndControlRoutes,再执行 signInSuccess loginSuccess(); } - } else if (res.code === 4000) { - // 登录错误之后,刷新验证码 - refreshCaptcha(); } - }); + }).catch((err: any) => { + // 登录错误之后,刷新验证码 + refreshCaptcha(); + }); } else { errorMessage("请填写登录信息") } From 68b3d479caa963b8dcc18c51b7e88787386e8409 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Sun, 24 Dec 2023 12:09:15 +0800 Subject: [PATCH 05/10] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.菜单新增是否固定配置; 2.菜单新增框外显示配置 --- backend/dvadmin/system/models.py | 2 + web/src/utils/menu.ts | 42 ++++++++++++++++--- .../menu/components/MenuFormCom/index.vue | 16 ++++++- web/src/views/system/menu/types.ts | 8 +++- 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index ea7224d..e2bf262 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -171,6 +171,8 @@ class Menu(CoreModel): cache = models.BooleanField(default=False, blank=True, verbose_name="是否页面缓存", help_text="是否页面缓存") visible = models.BooleanField(default=True, blank=True, verbose_name="侧边栏中是否显示", help_text="侧边栏中是否显示") + is_iframe = models.BooleanField(default=False, blank=True, verbose_name="框架外显示", help_text="框架外显示") + is_affix = models.BooleanField(default=False, blank=True, verbose_name="是否固定", help_text="是否固定") class Meta: db_table = table_prefix + "system_menu" diff --git a/web/src/utils/menu.ts b/web/src/utils/menu.ts index 42ff823..34b76c1 100644 --- a/web/src/utils/menu.ts +++ b/web/src/utils/menu.ts @@ -1,4 +1,5 @@ import XEUtils from "xe-utils" +import {dynamicRoutes, staticRoutes} from "/@/router/route"; /** * @description: 处理后端菜单数据格式 @@ -13,20 +14,51 @@ export const handleMenu = (menuData: Array) => { isLink: item.is_link, isHide: !item.visible, isKeepAlive: item.cache, - isAffix: false, - isIframe: false, + isAffix: item.is_affix, + isIframe: item.is_iframe, roles: ['admin'], icon: item.icon } item.name = item.component_name + item.path = item.web_path return item } + + // 处理框架外的路由 + const handleFrame = (item: any) => { + if (item.is_iframe) { + item.meta = { + title: item.title, + isLink: item.is_link, + isHide: !item.visible, + isKeepAlive: item.cache, + isAffix: item.is_affix, + isIframe: item.is_iframe, + roles: ['admin'], + icon: item.icon + } + item.name = item.component_name + item.path = item.web_path + } + return item + } + + // 框架内路由 + const dynamicRoutes:Array = [] + // 框架外路由 + const staticRoutes:Array = [] + menuData.forEach((val) => { - handleMeta(val) - val.path = val.web_path + console.log(111,val.is_iframe) + if(val.is_iframe){ + staticRoutes.push(handleFrame(val)) + console.log(staticRoutes) + }else{ + dynamicRoutes.push(handleMeta(val)) + } }) - const data = XEUtils.toArrayTree(menuData, { + const data = XEUtils.toArrayTree(dynamicRoutes, { parentKey: 'parent', strict: true, }) diff --git a/web/src/views/system/menu/components/MenuFormCom/index.vue b/web/src/views/system/menu/components/MenuFormCom/index.vue index a75e908..95273ea 100644 --- a/web/src/views/system/menu/components/MenuFormCom/index.vue +++ b/web/src/views/system/menu/components/MenuFormCom/index.vue @@ -24,7 +24,7 @@ /> - + @@ -56,6 +56,16 @@ + + + + + + + + + + @@ -168,6 +178,8 @@ let menuFormData = reactive({ description: '', is_catalog: false, is_link: false, + is_iframe: false, + is_affix: false, }); let menuBtnLoading = ref(false); @@ -186,6 +198,8 @@ const setMenuFormData = () => { menuFormData.description = props.initFormData?.description || ''; menuFormData.is_catalog = !!props.initFormData.is_catalog; menuFormData.is_link = !!props.initFormData.is_link; + menuFormData.is_iframe =!!props.initFormData.is_iframe; + menuFormData.is_affix =!!props.initFormData.is_affix; } }; diff --git a/web/src/views/system/menu/types.ts b/web/src/views/system/menu/types.ts index a89150c..6e6d5e3 100644 --- a/web/src/views/system/menu/types.ts +++ b/web/src/views/system/menu/types.ts @@ -44,6 +44,8 @@ export interface MenuTreeItemType { visible: boolean; creator: string; parent: number | string; + is_iframe:boolean; + is_affix:boolean; } export interface MenuFormDataType { @@ -60,4 +62,8 @@ export interface MenuFormDataType { description: string; is_catalog: boolean; is_link: boolean; -} \ No newline at end of file + + is_iframe:boolean; + + is_affix:boolean; +} From 7ae15022c04265484a61713133833b9306e9184e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Sun, 24 Dec 2023 23:05:00 +0800 Subject: [PATCH 06/10] =?UTF-8?q?=E6=96=B0=E5=8A=9F=E8=83=BD:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.菜单新增框架外显示字段 --- backend/dvadmin/system/models.py | 1 + backend/dvadmin/system/views/menu.py | 4 +- web/src/router/backEnd.ts | 42 +++++++++++++++++-- web/src/router/index.ts | 27 ++++++------ web/src/router/route.ts | 16 +++++++ web/src/stores/routesList.ts | 3 ++ web/src/utils/menu.ts | 28 ++++++------- .../menu/components/MenuFormCom/index.vue | 23 +++++++--- web/src/views/system/menu/types.ts | 4 +- 9 files changed, 106 insertions(+), 42 deletions(-) diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index e2bf262..c2ba698 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -162,6 +162,7 @@ class Menu(CoreModel): (1, "是"), ) is_link = models.BooleanField(default=False, verbose_name="是否外链", help_text="是否外链") + link_url = models.CharField(max_length=255, verbose_name="链接地址", null=True, blank=True, help_text="链接地址") is_catalog = models.BooleanField(default=False, verbose_name="是否目录", help_text="是否目录") web_path = models.CharField(max_length=128, verbose_name="路由地址", null=True, blank=True, help_text="路由地址") component = models.CharField(max_length=128, verbose_name="组件地址", null=True, blank=True, help_text="组件地址") diff --git a/backend/dvadmin/system/views/menu.py b/backend/dvadmin/system/views/menu.py index 7ac3c40..28dce62 100644 --- a/backend/dvadmin/system/views/menu.py +++ b/backend/dvadmin/system/views/menu.py @@ -71,8 +71,8 @@ class WebRouterSerializer(CustomModelSerializer): class Meta: model = Menu fields = ( - 'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link', 'is_catalog', 'web_path', 'component', - 'component_name', 'cache', 'visible', 'status') + 'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link','link_url', 'is_catalog', 'web_path', 'component', + 'component_name', 'cache', 'visible','is_iframe','is_affix', 'status') read_only_fields = ["id"] diff --git a/web/src/router/backEnd.ts b/web/src/router/backEnd.ts index 7efe7c8..dc42d87 100644 --- a/web/src/router/backEnd.ts +++ b/web/src/router/backEnd.ts @@ -18,8 +18,6 @@ const menuApi = useMenuApi(); const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}'); const viewsModules: any = import.meta.glob('../views/**/*.{vue,tsx}'); -// 后端控制路由 - /** * 获取目录下的 .vue、.tsx 全部文件 * @method import.meta.glob @@ -45,9 +43,12 @@ export async function initBackEndControlRoutes() { await useUserInfo().setUserInfos(); // 获取路由菜单数据 const res = await getBackEndControlRoutes(); - + // 无登录权限时,添加判断 + // https://gitee.com/lyt-top/vue-next-admin/issues/I64HVO + if (res.data.length <= 0) return Promise.resolve(true); // 处理路由(component),替换 dynamicRoutes(/@/router/route)第一个顶级 children 的路由 - dynamicRoutes[0].children = await backEndComponent(handleMenu(res.data)); + const {frameIn,frameOut} = handleMenu(res.data) + dynamicRoutes[0].children = await backEndComponent(frameIn); // 添加动态路由 await setAddRoute(); // 设置路由到 vuex routesList 中(已处理成多级嵌套路由)及缓存多级嵌套数组处理后的一维数组 @@ -80,7 +81,10 @@ export function setCacheTagsViewRoutes() { * @returns 返回替换后的路由数组 */ export function setFilterRouteEnd() { + console.log(dynamicRoutes) let filterRouteEnd: any = formatTwoStageRoutes(formatFlatteningRoutes(dynamicRoutes)); + // notFoundAndNoPower 防止 404、401 不在 layout 布局中,不设置的话,404、401 界面将全屏显示 + // 关联问题 No match found for location with path 'xxx' filterRouteEnd[0].children = [...filterRouteEnd[0].children, ...notFoundAndNoPower]; return filterRouteEnd; } @@ -92,9 +96,11 @@ export function setFilterRouteEnd() { * @link 参考:https://next.router.vuejs.org/zh/api/#addroute */ export async function setAddRoute() { + console.log("默认路由",router.getRoutes()) await setFilterRouteEnd().forEach((route: RouteRecordRaw) => { router.addRoute(route); }); + console.log("全部路由",router.getRoutes()) } /** @@ -126,6 +132,34 @@ export function backEndComponent(routes: any) { if (!routes) return; return routes.map((item: any) => { if (item.component) item.component = dynamicImport(dynamicViewsModules, item.component as string); + if(item.is_catalog){ + // 对目录的处理 + item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/parent') + } + if(item.is_link){ + // 对外链接的处理 + item.meta.isIframe = !item.is_iframe + if(item.is_iframe){ + item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/link') + }else { + item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/iframes') + } + }else{ + console.log(item.is_iframe,item.web_path) + if(item.is_iframe){ + const iframeRoute:RouteRecordRaw = { + ...item + } + item.meta.isLink = item.path + item.path = `${item.path}Link` + item.name = `${item.name}Link` + item.component = dynamicImport(dynamicViewsModules, 'layout/routerView/link.vue') + item.meta.isIframe = !item.is_iframe + item.meta.isKeepAlive = false + item.meta.isIframeOpen = true + + } + } item.children && backEndComponent(item.children); return item; }); diff --git a/web/src/router/index.ts b/web/src/router/index.ts index b1dba30..b864473 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -7,7 +7,7 @@ import {useKeepALiveNames} from '/@/stores/keepAliveNames'; import {useRoutesList} from '/@/stores/routesList'; import {useThemeConfig} from '/@/stores/themeConfig'; import {Session} from '/@/utils/storage'; -import {staticRoutes} from '/@/router/route'; +import {notFoundAndNoPower,staticRoutes} from '/@/router/route'; import {initFrontEndControlRoutes} from '/@/router/frontEnd'; import {initBackEndControlRoutes} from '/@/router/backEnd'; @@ -32,7 +32,13 @@ const {isRequestRoutes} = themeConfig.value; */ export const router = createRouter({ history: createWebHashHistory(), - routes: staticRoutes, + /** + * 说明: + * 1、notFoundAndNoPower 默认添加 404、401 界面,防止一直提示 No match found for location with path 'xxx' + * 2、backEnd.ts(后端控制路由)、frontEnd.ts(前端控制路由) 中也需要加 notFoundAndNoPower 404、401 界面。 + * 防止 404、401 不在 layout 布局中,不设置的话,404、401 界面将全屏显示 + */ + routes: [...notFoundAndNoPower, ...staticRoutes] }); /** @@ -63,14 +69,7 @@ export function formatTwoStageRoutes(arr: any) { const cacheList: Array = []; arr.forEach((v: any) => { if (v.path === '/') { - newArr.push({ - component: v.component, - name: v.name, - path: v.path, - redirect: v.redirect, - meta: v.meta, - children: [] - }); + newArr.push({component: v.component,name: v.name,path: v.path,redirect: v.redirect,meta: v.meta,children: []}); } else { // 判断是否是动态路由(xx/:id/:name),用于 tagsView 等中使用 // 修复:https://gitee.com/lyt-top/vue-next-admin/issues/I3YX6G @@ -114,13 +113,13 @@ router.beforeEach(async (to, from, next) => { if (isRequestRoutes) { // 后端控制路由:路由数据初始化,防止刷新时丢失 await initBackEndControlRoutes(); - // 动态添加路由:防止非首页刷新时跳转回首页的问题 - // 确保 addRoute() 时动态添加的路由已经被完全加载上去 - next({...to, replace: true}); + // 解决刷新时,一直跳 404 页面问题,关联问题 No match found for location with path 'xxx' + // to.query 防止页面刷新时,普通路由带参数时,参数丢失。动态路由(xxx/:id/:name")isDynamic 无需处理 + next({ path: to.path, query: to.query }); } else { // https://gitee.com/lyt-top/vue-next-admin/issues/I5F1HP await initFrontEndControlRoutes(); - next({...to, replace: true}); + next({ path: to.path, query: to.query }); } } else { next(); diff --git a/web/src/router/route.ts b/web/src/router/route.ts index 1c0b1a5..9557d5c 100644 --- a/web/src/router/route.ts +++ b/web/src/router/route.ts @@ -88,4 +88,20 @@ export const staticRoutes: Array = [ title: '登录', }, }, + { + path: '/operationLog', + name: 'operationLog', + component: () => import('/@/views/system/personal/index.vue'), + meta: { + title: 'message.router.personal' + }, + }, + // { + // path: '/demo', + // name: 'demo', + // component: () => import('/@/views/system/demo/index.vue'), + // meta: { + // title: 'message.router.personal' + // }, + // } ]; diff --git a/web/src/stores/routesList.ts b/web/src/stores/routesList.ts index 5e3a249..2481bf0 100644 --- a/web/src/stores/routesList.ts +++ b/web/src/stores/routesList.ts @@ -22,5 +22,8 @@ export const useRoutesList = defineStore('routesList', { async setColumnsNavHover(bool: Boolean) { this.isColumnsNavHover = bool; }, + async addRoutesList(data: Array) { + this.routesList.push(data); + } }, }); diff --git a/web/src/utils/menu.ts b/web/src/utils/menu.ts index 34b76c1..2911230 100644 --- a/web/src/utils/menu.ts +++ b/web/src/utils/menu.ts @@ -11,7 +11,7 @@ export const handleMenu = (menuData: Array) => { const handleMeta = (item: any) => { item.meta = { title: item.title, - isLink: item.is_link, + isLink: item.link_url, isHide: !item.visible, isKeepAlive: item.cache, isAffix: item.is_affix, @@ -29,7 +29,7 @@ export const handleMenu = (menuData: Array) => { if (item.is_iframe) { item.meta = { title: item.title, - isLink: item.is_link, + isLink: item.link_url, isHide: !item.visible, isKeepAlive: item.cache, isAffix: item.is_affix, @@ -44,25 +44,23 @@ export const handleMenu = (menuData: Array) => { } // 框架内路由 - const dynamicRoutes:Array = [] + const defaultRoutes:Array = [] // 框架外路由 - const staticRoutes:Array = [] + const iframeRoutes:Array = [] menuData.forEach((val) => { - console.log(111,val.is_iframe) - if(val.is_iframe){ - staticRoutes.push(handleFrame(val)) - console.log(staticRoutes) - }else{ - dynamicRoutes.push(handleMeta(val)) - } + // if (val.is_iframe) { + // // iframeRoutes.push(handleFrame(val)) + // } else { + // defaultRoutes.push(handleMeta(val)) + // } + defaultRoutes.push(handleMeta(val)) }) - - const data = XEUtils.toArrayTree(dynamicRoutes, { + const data = XEUtils.toArrayTree(defaultRoutes, { parentKey: 'parent', strict: true, }) - const menu = [ + const dynamicRoutes = [ { path: '/home', name: 'home', component: '/system/home/index', meta: { title: 'message.router.home', @@ -77,5 +75,5 @@ export const handleMenu = (menuData: Array) => { }, ...data ] - return menu + return {frameIn:dynamicRoutes,frameOut:iframeRoutes} } diff --git a/web/src/views/system/menu/components/MenuFormCom/index.vue b/web/src/views/system/menu/components/MenuFormCom/index.vue index 95273ea..491f4ce 100644 --- a/web/src/views/system/menu/components/MenuFormCom/index.vue +++ b/web/src/views/system/menu/components/MenuFormCom/index.vue @@ -24,7 +24,7 @@ /> - + @@ -91,8 +91,8 @@ - - + + @@ -139,8 +139,7 @@ const defaultTreeProps: any = { }; const validateWebPath = (rule: any, value: string, callback: Function) => { let pattern = /^\/.*?/; - let patternUrl = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; - const reg = menuFormData.is_link ? patternUrl.test(value) : pattern.test(value); + const reg = pattern.test(value); if (reg) { callback(); } else { @@ -148,6 +147,17 @@ const validateWebPath = (rule: any, value: string, callback: Function) => { } }; +const validateLinkUrl = (rule: any, value: string, callback: Function) => { + let pattern = /^\/.*?/; + let patternUrl = /http(s)?:\/\/([\w-]+\.)+[\w-]+(\/[\w- .\/?%&=]*)?/; + const reg = pattern.test(value) || patternUrl.test(value) + if (reg) { + callback(); + } else { + callback(new Error('请输入正确的地址')); + } +}; + const props = withDefaults(defineProps(), { initFormData: () => null, treeData: () => [], @@ -162,6 +172,7 @@ const rules = reactive({ name: [{ required: true, message: '菜单名称必填', trigger: 'blur' }], component: [{ required: true, message: '请输入组件地址', trigger: 'blur' }], component_name: [{ required: true, message: '请输入组件名称', trigger: 'blur' }], + link_url: [{ required: true, message: '请输入外链接地址',validator:validateLinkUrl, trigger: 'blur' }], }); let deptDefaultList = ref([]); @@ -180,6 +191,7 @@ let menuFormData = reactive({ is_link: false, is_iframe: false, is_affix: false, + link_url:'' }); let menuBtnLoading = ref(false); @@ -200,6 +212,7 @@ const setMenuFormData = () => { menuFormData.is_link = !!props.initFormData.is_link; menuFormData.is_iframe =!!props.initFormData.is_iframe; menuFormData.is_affix =!!props.initFormData.is_affix; + menuFormData.link_url =props.initFormData.link_url; } }; diff --git a/web/src/views/system/menu/types.ts b/web/src/views/system/menu/types.ts index 6e6d5e3..7975478 100644 --- a/web/src/views/system/menu/types.ts +++ b/web/src/views/system/menu/types.ts @@ -46,6 +46,7 @@ export interface MenuTreeItemType { parent: number | string; is_iframe:boolean; is_affix:boolean; + link_url:string; } export interface MenuFormDataType { @@ -62,8 +63,7 @@ export interface MenuFormDataType { description: string; is_catalog: boolean; is_link: boolean; - is_iframe:boolean; - is_affix:boolean; + link_url: string; } From c99eb1a9bc3d517bb0c3c8a35973029be2c1fb97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8C=BF=E5=B0=8F=E5=A4=A9?= <1638245306@qq.com> Date: Mon, 25 Dec 2023 18:48:11 +0800 Subject: [PATCH 07/10] =?UTF-8?q?=E4=BF=AE=E5=A4=8DBUG:=201.=E7=B3=BB?= =?UTF-8?q?=E7=BB=9F=E9=85=8D=E7=BD=AE=E6=B2=A1=E6=9C=89=E5=9C=A8=E5=88=B7?= =?UTF-8?q?=E6=96=B0=E9=A1=B5=E9=9D=A2=E7=9A=84=E6=97=B6=E5=80=99=E8=8E=B7?= =?UTF-8?q?=E5=8F=96;=202.=E7=99=BB=E5=BD=95=E9=A1=B5=E9=9D=A2=E7=BD=91?= =?UTF-8?q?=E7=AB=99=E6=A0=87=E9=A2=98=E7=AD=89=E4=BF=A1=E6=81=AF=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E5=90=8D=E5=AD=97=E4=B8=8D=E5=88=B7=E6=96=B0;=203.?= =?UTF-8?q?=E5=88=97=E6=9D=83=E9=99=90=E6=8E=92=E5=BA=8F=EF=BC=8C=E4=B8=94?= =?UTF-8?q?=E9=9C=80=E5=8F=AF=E4=BB=A5=E6=90=9C=E7=B4=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/src/layout/logo/index.vue | 10 ++- web/src/router/backEnd.ts | 10 ++- web/src/views/system/login/index.vue | 2 +- .../menu/components/MenuFieldCom/crud.tsx | 90 +++---------------- 4 files changed, 30 insertions(+), 82 deletions(-) diff --git a/web/src/layout/logo/index.vue b/web/src/layout/logo/index.vue index 9317333..d71010c 100644 --- a/web/src/layout/logo/index.vue +++ b/web/src/layout/logo/index.vue @@ -1,7 +1,7 @@