Commit 04757222 by yuzhenWang

添加跳转逻辑

parent 9a317de9
# 页面标题
VITE_APP_TITLE = 若依管理系统
VITE_APP_TITLE = CSF-CORE
# 开发环境配置
VITE_APP_ENV = 'development'
......
# 页面标题
VITE_APP_TITLE = 若依管理系统
VITE_APP_TITLE = CSF-CORE
# 生产环境配置
VITE_APP_ENV = 'production'
......
# 页面标题
VITE_APP_TITLE = 若依管理系统
VITE_APP_TITLE = CSF-CORE
# 生产环境配置
VITE_APP_ENV = 'staging'
......
......@@ -6,8 +6,8 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="renderer" content="webkit">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<link rel="icon" href="/favicon.ico">
<title>若依管理系统</title>
<link rel="icon" href="/csfLogo.png">
<title>CSF-CORE</title>
<!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
<style>
html,
......
{
"name": "ruoyi",
"version": "3.9.0",
"description": "若依管理系统",
"description": "CSF-CORE",
"author": "若依",
"license": "MIT",
"type": "module",
......
// base color
$blue: #324157;
$light-blue: #333c46;
$red: #C03639;
$pink: #E65D6E;
$green: #30B08F;
$tiffany: #4AB7BD;
$yellow: #FEC171;
$panGreen: #30B08F;
$red: #c03639;
$pink: #e65d6e;
$green: #30b08f;
$tiffany: #4ab7bd;
$yellow: #fec171;
$panGreen: #30b08f;
// 默认主题变量
$menuText: #bfcbd9;
$menuText: #bfcbd9; //原来的颜色
// $menuText: #333;
$menuActiveText: #409eff;
$menuBg: #304156;
$menuBg: #304156; //原来的颜色
// $menuBg: #fff;
$menuHover: #263445;
// 浅色主题theme-light
$menuLightBg: #ffffff;
$menuLightHover: #f0f1f5;
$menuLightText: #303133;
$menuLightActiveText: #409EFF;
$menuLightActiveText: #409eff;
// 基础变量
$base-sidebar-width: 200px;
......@@ -32,10 +34,10 @@ $base-sub-menu-background: #1f2d3d;
$base-sub-menu-hover: #001528;
// 组件变量
$--color-primary: #409EFF;
$--color-success: #67C23A;
$--color-warning: #E6A23C;
$--color-danger: #F56C6C;
$--color-primary: #409eff;
$--color-success: #67c23a;
$--color-warning: #e6a23c;
$--color-danger: #f56c6c;
$--color-info: #909399;
:export {
......@@ -77,7 +79,6 @@ $--color-info: #909399;
/* splitpanes default-theme 变量 */
--splitpanes-default-bg: #ffffff;
}
// 暗黑模式变量
......@@ -128,10 +129,11 @@ html.dark {
/* 侧边栏菜单覆盖 */
.sidebar-container {
.el-menu-item, .menu-title {
.el-menu-item,
.menu-title {
color: var(--el-text-color-regular);
}
& .theme-dark .nest-menu .el-sub-menu>.el-sub-menu__title,
& .theme-dark .nest-menu .el-sub-menu > .el-sub-menu__title,
& .theme-dark .el-sub-menu .el-menu-item {
background-color: var(--el-bg-color) !important;
}
......@@ -180,7 +182,8 @@ html.dark {
--el-table-border-color: var(--el-border-color-light) !important;
--el-table-row-hover-bg-color: var(--el-bg-color-overlay) !important;
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
.el-table__header-wrapper,
.el-table__fixed-header-wrapper {
th {
background-color: var(--el-bg-color-overlay, #f8f8f9) !important;
color: var(--el-text-color-regular, #515a6e);
......@@ -201,7 +204,8 @@ html.dark {
}
/* 下拉菜单样式覆盖 */
.el-dropdown-menu__item:not(.is-disabled):focus, .el-dropdown-menu__item:not(.is-disabled):hover{
.el-dropdown-menu__item:not(.is-disabled):focus,
.el-dropdown-menu__item:not(.is-disabled):hover {
background-color: var(--navbar-hover) !important;
}
......@@ -216,6 +220,4 @@ html.dark {
.popup-result .title {
background: var(--cron-border);
}
}
<template>
<div class="navbar">
<hamburger id="hamburger-container" :is-active="appStore.sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
<breadcrumb v-if="!settingsStore.topNav" id="breadcrumb-container" class="breadcrumb-container" />
<hamburger
id="hamburger-container"
:is-active="appStore.sidebar.opened"
class="hamburger-container"
@toggleClick="toggleSideBar"
/>
<breadcrumb
v-if="!settingsStore.topNav"
id="breadcrumb-container"
class="breadcrumb-container"
/>
<top-nav v-if="settingsStore.topNav" id="topmenu-container" class="topmenu-container" />
<div class="right-menu">
<!-- 添加租户选择器 -->
<!-- <tenant-select class="right-menu-item hover-effect" v-if="userStore.tenants.length >= 1" />-->
<el-dropdown class="tenant-selector" @command="handleTenantChange">
<!-- <tenant-select class="right-menu-item hover-effect" v-if="userStore.tenants.length >= 1" />-->
<!-- <el-dropdown class="tenant-selector" @command="handleTenantChange">
<span class="el-dropdown-link">
{{ currentTenantName }}<el-icon class="el-icon--right"><arrow-down /></el-icon>
</span>
......@@ -22,17 +31,17 @@
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-dropdown> -->
<template v-if="appStore.device !== 'mobile'">
<header-search id="header-search" class="right-menu-item" />
<el-tooltip content="源码地址" effect="dark" placement="bottom">
<!-- <el-tooltip content="源码地址" effect="dark" placement="bottom">
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
</el-tooltip>
</el-tooltip> -->
<el-tooltip content="文档地址" effect="dark" placement="bottom">
<!-- <el-tooltip content="文档地址" effect="dark" placement="bottom">
<ruo-yi-doc id="ruoyi-doc" class="right-menu-item hover-effect" />
</el-tooltip>
</el-tooltip> -->
<screenfull id="screenfull" class="right-menu-item hover-effect" />
......@@ -48,23 +57,31 @@
</el-tooltip>
</template>
<el-dropdown @command="handleCommand" class="avatar-container right-menu-item hover-effect" trigger="hover">
<el-dropdown
@command="handleCommand"
class="avatar-container right-menu-item hover-effect"
trigger="hover"
>
<div class="avatar-wrapper">
<img :src="userStore.avatar" class="user-avatar" />
<span class="user-nickname"> {{ userStore.nickName }} </span>
</div>
<template #dropdown>
<el-dropdown-menu>
<router-link to="/user/profile">
<!-- <router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item>
</router-link>
</router-link> -->
<el-dropdown-item divided command="logout">
<span>退出登录</span>
</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<div class="right-menu-item hover-effect setting" @click="setLayout" v-if="settingsStore.showSettings">
<div
class="right-menu-item hover-effect setting"
@click="setLayout"
v-if="settingsStore.showSettings"
>
<svg-icon icon-class="more-up" />
</div>
</div>
......@@ -98,9 +115,10 @@ const availableTenants = computed(() => {
// 添加空值检查
if (!userStore.tenants) return []
return userStore.tenants.filter(tenant =>
return userStore.tenants.filter(
tenant =>
// (tenant.apiLoginProjectInfoResponseList && tenant.apiLoginProjectInfoResponseList.length > 0) &&
(tenant.apiLoginTenantInfoResponse && tenant.apiLoginTenantInfoResponse.status === 1)
tenant.apiLoginTenantInfoResponse && tenant.apiLoginTenantInfoResponse.status === 1
)
})
......@@ -115,7 +133,7 @@ const currentTenantName = computed(() => {
})
// 切换租户处理
const handleTenantChange = (tenant) => {
const handleTenantChange = tenant => {
userStore.switchTenant(tenant)
}
......@@ -125,10 +143,10 @@ function toggleSideBar() {
function handleCommand(command) {
switch (command) {
case "setLayout":
case 'setLayout':
setLayout()
break
case "logout":
case 'logout':
logout()
break
default:
......@@ -141,11 +159,13 @@ function logout() {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
})
.then(() => {
userStore.logOut().then(() => {
location.href = '/index'
})
}).catch(() => { })
})
.catch(() => {})
}
const emits = defineEmits(['setLayout'])
......@@ -158,7 +178,7 @@ function toggleTheme() {
}
</script>
<style lang='scss' scoped>
<style lang="scss" scoped>
.tenant-selector {
margin-left: 20px;
cursor: pointer;
......@@ -260,7 +280,7 @@ function toggleTheme() {
border-radius: 50%;
}
.user-nickname{
.user-nickname {
position: relative;
left: 5px;
bottom: 10px;
......
<template>
<div class="sidebar-logo-container" :class="{ 'collapse': collapse }">
<div class="sidebar-logo-container" :class="{ collapse: collapse }">
<transition name="sidebarLogoFade">
<router-link v-if="collapse" key="collapse" class="sidebar-logo-link" to="/">
<img v-if="logo" :src="logo" class="sidebar-logo" />
......@@ -14,7 +14,7 @@
</template>
<script setup>
import logo from '@/assets/logo/logo.png'
import logo from '@/assets/logo/csfLogo.png'
import useSettingsStore from '@/store/modules/settings'
import variables from '@/assets/styles/variables.module.scss'
......@@ -68,6 +68,7 @@ const getLogoTextColor = computed(() => {
& .sidebar-logo-link {
height: 100%;
width: 100%;
text-align: center;
& .sidebar-logo {
width: 32px;
......
......@@ -2,22 +2,32 @@ import router from './router'
import { ElMessage } from 'element-plus'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
import { getToken } from '@/utils/auth'
import { isHttp, isPathMatch } from '@/utils/validate'
import { isRelogin } from '@/utils/request'
import useUserStore from '@/store/modules/user' // 使用命名导入
import useSettingsStore from '@/store/modules/settings' // 使用命名导入
import usePermissionStore from '@/store/modules/permission' // 使用命名导入
import { getToken, setToken, removeToken } from '@/utils/auth'
NProgress.configure({ showSpinner: false })
const whiteList = ['/login', '/register']
const isWhiteList = (path) => {
const isWhiteList = path => {
return whiteList.some(pattern => isPathMatch(pattern, path))
}
router.beforeEach((to, from, next) => {
console.log('跳转进来了', to)
// 带token是从外部跳转进系统的
if (to.query.token) {
setToken(to.query.token)
useUserStore().setProjectInfo({
tenantBizId: to.query.tenantBizId,
projectBizId: to.query.projectBizId
})
}
NProgress.start()
if (getToken()) {
to.meta.title && useSettingsStore().setTitle(to.meta.title)
......@@ -28,13 +38,19 @@ router.beforeEach((to, from, next) => {
} else if (isWhiteList(to.path)) {
next()
} else {
console.log('roles', useUserStore().roles.length)
if (useUserStore().roles.length === 0) {
isRelogin.show = true
// 判断当前用户是否已拉取完user_info信息
useUserStore().getInfo().then(() => {
useUserStore()
.getInfo()
.then(() => {
isRelogin.show = false
usePermissionStore().generateRoutes().then(accessRoutes => {
usePermissionStore()
.generateRoutes()
.then(accessRoutes => {
// 根据roles权限生成可访问的路由表
accessRoutes.forEach(route => {
if (!isHttp(route.path)) {
......@@ -43,13 +59,15 @@ router.beforeEach((to, from, next) => {
})
next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
})
}).catch(err => {
useUserStore().logOut().then(() => {
})
.catch(err => {
useUserStore()
.logOut()
.then(() => {
ElMessage.error(err)
next({ path: '/' })
})
})
} else {
next()
}
......
......@@ -9,9 +9,7 @@ import useUserStore from '@/store/modules/user'
// 匹配views里面所有的.vue文件
const modules = import.meta.glob('./../../views/**/*.vue')
const usePermissionStore = defineStore(
'permission',
{
const usePermissionStore = defineStore('permission', {
state: () => ({
routes: [],
addRoutes: [],
......@@ -23,6 +21,9 @@ const usePermissionStore = defineStore(
setRoutes(routes) {
this.addRoutes = routes
this.routes = constantRoutes.concat(routes)
console.log('====================================')
console.log('this.routes', this.routes)
console.log('====================================')
},
setDefaultRoutes(routes) {
this.defaultRoutes = constantRoutes.concat(routes)
......@@ -36,7 +37,8 @@ const usePermissionStore = defineStore(
generateRoutes() {
return new Promise(resolve => {
const userStore = useUserStore()
const tenantBizId = userStore.currentTenant.apiLoginTenantInfoResponse.tenantBizId || "tenant_1001"
const tenantBizId =
userStore.currentTenant.apiLoginTenantInfoResponse.tenantBizId || 'tenant_1001'
getRouters(tenantBizId).then(res => {
const sdata = JSON.parse(JSON.stringify(res.data))
......@@ -57,7 +59,7 @@ const usePermissionStore = defineStore(
})
}
}
})
})
// export default usePermissionStore
......@@ -66,28 +68,28 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
return asyncRouterMap.filter(route => {
// 确保路由有有效路径
if (!route.path || route.path.trim() === '') {
console.warn('忽略无效路由项(缺少路径):', route);
return false;
console.warn('忽略无效路由项(缺少路径):', route)
return false
}
// 只处理目录(1)和菜单(2)类型
if (route.menuType !== 1 && route.menuType !== 2) {
return false;
return false
}
// 创建必要的元信息
if (!route.meta) {
route.meta = {};
route.meta = {}
}
// 设置菜单标题
route.meta.title = route.menuName;
route.meta.icon = route.icon;
route.meta.isCache = route.isCache === 1;
route.meta.title = route.menuName
route.meta.icon = route.icon
route.meta.isCache = route.isCache === 1
//确保单子菜单的父菜单也显示
if (route.menuType === 1) {
route.alwaysShow = true; // 强制显示父菜单
route.alwaysShow = true // 强制显示父菜单
}
// 新增:添加标签页显示属性(关键修改)
......@@ -96,36 +98,36 @@ function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
// 确保顶级菜单有布局组件
if (route.parentBizId === '0' && !route.component) {
route.component = 'Layout';
route.component = 'Layout'
}
// 组件映射处理
if (route.component) {
if (route.component === 'Layout') {
route.component = Layout;
route.component = Layout
} else if (route.component === 'ParentView') {
route.component = ParentView;
route.component = ParentView
} else if (route.component === 'InnerLink') {
route.component = InnerLink;
route.component = InnerLink
} else {
route.component = loadView(route.component);
route.component = loadView(route.component)
}
}
// 递归处理子路由
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, route, type);
route.children = filterAsyncRouter(route.children, route, type)
// 设置重定向到第一个子路由(对于目录类型)
if (route.menuType === 1 && route.children.length > 0) {
route.redirect = route.children[0].path;
route.redirect = route.children[0].path
}
} else {
delete route.children;
delete route.children
}
return true;
});
return true
})
}
// // 遍历后台传来的路由字符串,转换为组件对象
// function filterAsyncRouter(asyncRouterMap, lastRouter = false, type = false) {
......@@ -185,7 +187,7 @@ export function filterDynamicRoutes(routes) {
return res
}
export const loadView = (view) => {
export const loadView = view => {
let res
for (const path in modules) {
const dir = path.split('views/')[1].split('.vue')[0]
......
import router from '@/router'
import { ElMessageBox, } from 'element-plus'
import { ElMessageBox } from 'element-plus'
import { login, logout, getInfo } from '@/api/login'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { isHttp, isEmpty } from "@/utils/validate"
import { isHttp, isEmpty } from '@/utils/validate'
import defAva from '@/assets/images/profile.jpg'
import usePermissionStore from '@/store/modules/permission'
const useUserStore = defineStore(
'user',
{
const useUserStore = defineStore('user', {
state: () => ({
token: getToken(),
id: '',
......@@ -19,7 +17,8 @@ const useUserStore = defineStore(
roles: [],
permissions: [],
tenants: [], // 新增租户列表
currentTenant: null // 新增当前租户
currentTenant: null, // 新增当前租户
projectInfo:null //保存从中台跳转过来的项目信息
}),
actions: {
// 登录
......@@ -29,11 +28,13 @@ const useUserStore = defineStore(
const code = userInfo.code
const uuid = userInfo.uuid
return new Promise((resolve, reject) => {
login(username, password, code, uuid).then(res => {
login(username, password, code, uuid)
.then(res => {
setToken(res.data.token)
this.token = res.data.token
resolve()
}).catch(error => {
})
.catch(error => {
reject(error)
})
})
......@@ -41,19 +42,19 @@ const useUserStore = defineStore(
// 获取用户信息
getInfo() {
return new Promise((resolve, reject) => {
getInfo().then(res => {
getInfo()
.then(res => {
const user = res.data.apiLoginUserInfoResponse
let avatar = user.avatar || ""
let avatar = user.avatar || ''
if (!isHttp(avatar)) {
avatar = (isEmpty(avatar)) ? defAva : import.meta.env.VITE_APP_BASE_API + avatar
avatar = isEmpty(avatar) ? defAva : import.meta.env.VITE_APP_BASE_API + avatar
}
// 设置租户列表
this.tenants = res.data.apiLoginTenantResponseList || []
// 尝试从本地存储获取当前租户,否则使用第一个
const savedTenant = JSON.parse(localStorage.getItem('' +
''))
const savedTenant = JSON.parse(localStorage.getItem('' + ''))
const currentTenant = savedTenant || (this.tenants.length > 0 ? this.tenants[0] : null)
if (currentTenant) {
......@@ -76,34 +77,39 @@ const useUserStore = defineStore(
this.isSuperAdmin = user.isSuperAdmin
/* 初始密码提示 */
if(res.data.isDefaultModifyPwd) {
if (res.data.isDefaultModifyPwd) {
ElMessageBox.confirm('您的密码还是初始密码,请修改密码!', '安全提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
})
.then(() => {
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
}).catch(() => {})
})
.catch(() => {})
}
/* 过期密码提示 */
if(!res.data.isDefaultModifyPwd && res.isPasswordExpired) {
if (!res.data.isDefaultModifyPwd && res.isPasswordExpired) {
ElMessageBox.confirm('您的密码已过期,请尽快修改密码!', '安全提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
})
.then(() => {
router.push({ name: 'Profile', params: { activeTab: 'resetPwd' } })
}).catch(() => {})
})
.catch(() => {})
}
resolve(res)
}).catch(error => {
})
.catch(error => {
reject(error)
})
})
},
//切换租户
switchTenant(tenant) {
return new Promise((resolve) => {
return new Promise(resolve => {
this.currentTenant = tenant
localStorage.setItem('currentTenant', JSON.stringify(tenant))
......@@ -118,7 +124,9 @@ const useUserStore = defineStore(
this.roles = ['ROLE_DEFAULT']
}
usePermissionStore().generateRoutes().then(accessRoutes => {
usePermissionStore()
.generateRoutes()
.then(accessRoutes => {
// 移除旧路由
const currentRoutes = router.getRoutes()
currentRoutes.forEach(route => {
......@@ -166,8 +174,14 @@ const useUserStore = defineStore(
// reject(error)
// })
})
},
clearRoles() {
this.roles = []
},
setProjectInfo(project) {
this.projectInfo = project
}
}
})
})
export default useUserStore
......@@ -20,10 +20,7 @@
@click="goTarget('https://gitee.com/y_project/RuoYi-Vue')"
>访问码云</el-button
>
<el-button
icon="HomeFilled"
plain
@click="goTarget('http://ruoyi.vip')"
<el-button icon="HomeFilled" plain @click="goTarget('http://ruoyi.vip')"
>访问主页</el-button
>
</p>
......@@ -87,18 +84,16 @@
<s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s>
<s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <s> 满174951577 </s>
<s> 满161281055 </s> <s> 满138988063 </s> <s> 满151450850 </s> <s> 满224622315 </s>
<s> 满287842588 </s> <s> 满187944233 </s> <s> 满228578329 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766" target="_blank">191164766</a>
</p>
<p>
<i class="el-icon-chat-dot-round"></i> 微信:<a
href="javascript:;"
>/ *若依</a
<s> 满287842588 </s> <s> 满187944233 </s> <s> 满228578329 </s>
<a
href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766"
target="_blank"
>191164766</a
>
</p>
<p><i class="el-icon-chat-dot-round"></i> 微信:<a href="javascript:;">/ *若依</a></p>
<p>
<i class="el-icon-money"></i> 支付宝:<a
href="javascript:;"
class="支付宝信息"
<i class="el-icon-money"></i> 支付宝:<a href="javascript:;" class="支付宝信息"
>/ *若依</a
>
</p>
......@@ -878,9 +873,7 @@
<li>调整表头固定列默认样式</li>
<li>代码生成模板调整,字段为String并且必填则加空串条件</li>
<li>代码生成字典Integer/Long使用parseInt</li>
<li>
修复dict_sort不可update为0的问题&查询返回增加dict_sort升序排序
</li>
<li>修复dict_sort不可update为0的问题&查询返回增加dict_sort升序排序</li>
<li>修正岗位导出权限注解</li>
<li>禁止加密密文返回前端</li>
<li>修复代码生成页面中的查询条件创建时间未生效的问题</li>
......@@ -1042,11 +1035,7 @@
</div>
</template>
<div class="body">
<img
src="@/assets/images/pay.png"
alt="donate"
style="width:100%"
/>
<img src="@/assets/images/pay.png" alt="donate" style="width: 100%" />
<span style="display: inline-block; height: 30px; line-height: 30px"
>你可以请作者喝杯咖啡表示鼓励</span
>
......@@ -1088,7 +1077,7 @@ function goTarget(url) {
margin: 0;
}
font-family: "open sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
font-family: 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif;
font-size: 13px;
color: #676a6c;
overflow-x: hidden;
......@@ -1128,4 +1117,3 @@ function goTarget(url) {
}
}
</style>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment