This commit is contained in:
van
2026-04-30 17:30:42 +08:00
parent d8cae128fa
commit 77712048d4
6 changed files with 90 additions and 26 deletions

View File

@@ -59,7 +59,7 @@ export default {
return mainRoutes return mainRoutes
} }
return [ return [
{ path: '/sloworder/index', label: '首页', icon: 'el-icon-s-home' } { path: '/user/profile', label: '我的', icon: 'el-icon-s-home' }
] ]
} }
}, },

View File

@@ -26,6 +26,8 @@ import ResizeMixin from './mixin/ResizeHandler'
import { mapState, mapGetters } from 'vuex' import { mapState, mapGetters } from 'vuex'
import variables from '@/assets/styles/variables.scss' import variables from '@/assets/styles/variables.scss'
import auth from '@/plugins/auth'
export default { export default {
name: 'Layout', name: 'Layout',
components: { components: {
@@ -55,13 +57,14 @@ export default {
return `${len}-${firstPath}` return `${len}-${firstPath}`
}, },
mobileNavItems() { mobileNavItems() {
return [ const items = [
{ path: '/sloworder/index', label: '慢单', icon: 'el-icon-tickets' }, { path: '/sloworder/index', label: '慢单', icon: 'el-icon-tickets', permissions: ['jdorder:sloworder:list'] },
{ path: '/jd-instruction/index', label: '中控', icon: 'el-icon-s-operation' }, { path: '/jd-instruction/index', label: '中控', icon: 'el-icon-s-operation', permissions: ['jdorder:instruction:list'] },
{ path: '/mobile/fadan', label: '发单', icon: 'el-icon-edit-outline' }, { path: '/mobile/fadan', label: '发单', icon: 'el-icon-edit-outline' },
{ path: '/mobile/xianyu-publish', label: '发品', icon: 'el-icon-goods' }, { path: '/mobile/xianyu-publish', label: '发品', icon: 'el-icon-goods' },
{ path: '/mobile/zhongcao', label: '种草', icon: 'el-icon-chat-dot-round' } { path: '/mobile/zhongcao', label: '种草', icon: 'el-icon-chat-dot-round' }
] ]
return items.filter(it => !it.permissions || auth.hasPermiOr(it.permissions))
}, },
classObj() { classObj() {
return { return {

View File

@@ -63,7 +63,16 @@ export const constantRoutes = [
}, },
{ {
path: '/', path: '/',
redirect: '/sloworder/index' redirect: () => {
const store = require('@/store').default
const { firstLeafPathFromSidebarRoutes } = require('@/utils/route-nav')
const roles = store.getters.roles
if (roles && roles.length > 0) {
const p = firstLeafPathFromSidebarRoutes(store.getters.sidebarRouters)
if (p) return p
}
return '/user/profile'
}
}, },
{ {
path: '/user', path: '/user',
@@ -103,22 +112,6 @@ export const constantRoutes = [
component: () => import('@/views/public/order-submit/index'), component: () => import('@/views/public/order-submit/index'),
hidden: true hidden: true
}, },
// 慢单管理(移到公共路由,无需权限)
{
path: '/sloworder',
component: Layout,
redirect: 'noredirect',
name: 'SlowOrder',
meta: { title: '下好的慢单', icon: 'list' },
children: [
{
path: 'index',
component: () => import('@/views/system/jdorder/orderList'),
name: 'SlowOrderIndex',
meta: { title: '下好的慢单', icon: 'list' }
}
]
},
// 移动端专用入口(隐藏菜单,底部导航直达) // 移动端专用入口(隐藏菜单,底部导航直达)
{ {
path: '/mobile', path: '/mobile',
@@ -149,6 +142,23 @@ export const constantRoutes = [
// 动态路由,基于用户权限动态去加载 // 动态路由,基于用户权限动态去加载
export const dynamicRoutes = [ export const dynamicRoutes = [
// 下好的慢单(需菜单/按钮权限 jdorder:sloworder:list
{
path: '/sloworder',
component: Layout,
redirect: 'noredirect',
name: 'SlowOrder',
meta: { title: '下好的慢单', icon: 'list' },
permissions: ['jdorder:sloworder:list'],
children: [
{
path: 'index',
component: () => import('@/views/system/jdorder/orderList'),
name: 'SlowOrderIndex',
meta: { title: '下好的慢单', icon: 'list' }
}
]
},
// 京粉订单管理 // 京粉订单管理
{ {
path: '/order', path: '/order',

View File

@@ -5,6 +5,19 @@ import Layout from '@/layout/index'
import ParentView from '@/components/ParentView' import ParentView from '@/components/ParentView'
import InnerLink from '@/layout/components/InnerLink' import InnerLink from '@/layout/components/InnerLink'
/** 按顶级 path 去重合并,保留先出现的项 */
function mergeDistinctTopLevelRoutes(primary, secondary) {
const paths = new Set(primary.map(r => r.path))
const out = primary.slice()
secondary.forEach(r => {
if (r && r.path != null && r.path !== '' && !paths.has(r.path)) {
paths.add(r.path)
out.push(r)
}
})
return out
}
const permission = { const permission = {
state: { state: {
routes: [], routes: [],
@@ -42,7 +55,9 @@ const permission = {
rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true }) rewriteRoutes.push({ path: '*', redirect: '/404', hidden: true })
router.addRoutes(asyncRoutes) router.addRoutes(asyncRoutes)
commit('SET_ROUTES', rewriteRoutes) commit('SET_ROUTES', rewriteRoutes)
commit('SET_SIDEBAR_ROUTERS', constantRoutes.concat(sidebarRoutes)) let sidebarMerged = mergeDistinctTopLevelRoutes([...constantRoutes], asyncRoutes)
sidebarMerged = mergeDistinctTopLevelRoutes(sidebarMerged, sidebarRoutes)
commit('SET_SIDEBAR_ROUTERS', sidebarMerged)
commit('SET_DEFAULT_ROUTES', sidebarRoutes) commit('SET_DEFAULT_ROUTES', sidebarRoutes)
commit('SET_TOPBAR_ROUTES', sidebarRoutes) commit('SET_TOPBAR_ROUTES', sidebarRoutes)
resolve(rewriteRoutes) resolve(rewriteRoutes)

35
src/utils/route-nav.js Normal file
View File

@@ -0,0 +1,35 @@
/** 扁平化侧边栏用语义路径,顺序与侧边栏自上而下一致(与 MobileBottomNav 逻辑对齐) */
export function flattenNavigableRoutes(routes, parentPath = '') {
if (!routes || !Array.isArray(routes)) return []
const result = []
routes.forEach(route => {
if (route.hidden) return
let fullPath = (route.path || '').trim()
if (parentPath) {
if (!fullPath.startsWith('/')) {
const base = parentPath.endsWith('/') ? parentPath.slice(0, -1) : parentPath
fullPath = `${base}/${fullPath}`.replace(/\/+/g, '/')
}
}
if (fullPath && !fullPath.startsWith('/')) fullPath = '/' + fullPath
if (route.children && route.children.length > 0) {
result.push(...flattenNavigableRoutes(route.children, fullPath || parentPath))
} else if (route.meta && route.meta.title && fullPath && fullPath !== '/') {
result.push({ path: fullPath, meta: route.meta })
}
})
return result
}
/** 侧边栏路由中首个可打开的叶子路径(用于默认首页);无则 null */
export function firstLeafPathFromSidebarRoutes(sidebarRoutes) {
const flat = flattenNavigableRoutes(sidebarRoutes)
const exclude = ['/redirect', '/login', '/register', '/404', '/401', '/user/profile']
for (const { path } of flat) {
if (!path) continue
if (exclude.some(p => path === p || path.startsWith(p + '/'))) continue
return path
}
return null
}

View File

@@ -67,6 +67,8 @@
import { getCodeImg } from "@/api/login" import { getCodeImg } from "@/api/login"
import Cookies from "js-cookie" import Cookies from "js-cookie"
import { encrypt, decrypt } from '@/utils/jsencrypt' import { encrypt, decrypt } from '@/utils/jsencrypt'
import store from '@/store'
import { firstLeafPathFromSidebarRoutes } from '@/utils/route-nav'
export default { export default {
name: "Login", name: "Login",
@@ -147,11 +149,10 @@ export default {
// 先获取用户信息和生成路由,然后再跳转 // 先获取用户信息和生成路由,然后再跳转
this.$store.dispatch('GetInfo').then(() => { this.$store.dispatch('GetInfo').then(() => {
this.$store.dispatch('GenerateRoutes').then(() => { this.$store.dispatch('GenerateRoutes').then(() => {
// 使用 replace 而不是 push避免路由历史问题 const fallback = firstLeafPathFromSidebarRoutes(store.getters.sidebarRouters) || '/user/profile'
const redirectPath = this.redirect || "/sloworder/index" const redirectPath = this.redirect || fallback
this.$router.replace(redirectPath).catch(() => { this.$router.replace(redirectPath).catch(() => {
// 如果目标路由不存在,跳转到默认路由 this.$router.replace(fallback)
this.$router.replace("/sloworder/index")
}) })
}) })
}) })