1
This commit is contained in:
31
src/App.vue
31
src/App.vue
@@ -4,7 +4,7 @@
|
||||
<LockScreen v-if="themeConfig.isLockScreen" />
|
||||
<Settings ref="settingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
||||
<CloseFull v-if="!themeConfig.isLockScreen" />
|
||||
<ChangeRoleFir ref="changeRoleFirRef" />
|
||||
<ChangeRole ref="changeRoleFirRef" title="首次登录请选择角色" :require-select-to-close="true" />
|
||||
</el-config-provider>
|
||||
</template>
|
||||
|
||||
@@ -22,7 +22,7 @@ import setIntroduction from '/@/utils/setIconfont';
|
||||
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
|
||||
const Settings = defineAsyncComponent(() => import('./layout/navBars/breadcrumb/settings.vue'));
|
||||
const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.vue'));
|
||||
const ChangeRoleFir = defineAsyncComponent(() => import('/@/views/admin/system/role/changeRole-fir.vue'));
|
||||
const ChangeRole = defineAsyncComponent(() => import('/@/views/admin/system/role/change-role.vue'));
|
||||
|
||||
// 定义变量内容
|
||||
const { messages, locale } = useI18n();
|
||||
@@ -56,10 +56,19 @@ onBeforeMount(() => {
|
||||
// 设置批量第三方 js
|
||||
setIntroduction.jsCdn();
|
||||
});
|
||||
// 页面加载时
|
||||
// 角色选择弹框是否已在本轮打开过(防止事件被触发两次)
|
||||
let roleDialogOpenedThisSession = false
|
||||
onMounted(() => {
|
||||
// 唯一入口:只通过事件打开,且只打开一次;延迟打开以等待异步组件挂载
|
||||
mittBus.on('openRoleSelectDialog', () => {
|
||||
if (roleDialogOpenedThisSession) return
|
||||
roleDialogOpenedThisSession = true
|
||||
setTimeout(() => {
|
||||
changeRoleFirRef.value?.open()
|
||||
}, 300)
|
||||
})
|
||||
nextTick(() => {
|
||||
// 监听布局配'置弹窗点击打开
|
||||
// 监听布局配置弹窗点击打开
|
||||
mittBus.on('openSettingsDrawer', () => {
|
||||
settingsRef.value.openDrawer();
|
||||
});
|
||||
@@ -72,18 +81,12 @@ onMounted(() => {
|
||||
if (Session.get('isTagsViewCurrenFull')) {
|
||||
stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
|
||||
}
|
||||
// 全局判断:已登录但 Local 缺少角色信息时弹出角色选择;弹框已触发则不再重复弹出
|
||||
// 与请求拦截器共用同一逻辑:先设标志再 emit,由监听器统一打开(监听器内会延迟 300ms 以等待异步组件挂载)
|
||||
if (Session.getToken() && needRoleSelection() && !isRoleDialogTriggered()) {
|
||||
setRoleDialogTriggered(true);
|
||||
setTimeout(() => {
|
||||
changeRoleFirRef.value?.open();
|
||||
}, 300);
|
||||
setRoleDialogTriggered(true)
|
||||
mittBus.emit('openRoleSelectDialog')
|
||||
}
|
||||
// 请求拦截器里也会在发送请求时判断并 emit,此处统一监听打开弹框
|
||||
mittBus.on('openRoleSelectDialog', () => {
|
||||
changeRoleFirRef.value?.open();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
// 页面销毁时,关闭监听
|
||||
onUnmounted(() => {
|
||||
|
||||
@@ -253,15 +253,7 @@ const getIsDot = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 登录后若存储中无角色信息则弹出角色切换框
|
||||
const openChangeRoleIfMissing = () => {
|
||||
const hasRole = Local.get('roleCode') && Local.get('roleName') && Local.get('roleId')
|
||||
if (!hasRole) {
|
||||
nextTick(() => {
|
||||
setTimeout(() => ChangeRoleRef.value?.open(), 100)
|
||||
})
|
||||
}
|
||||
}
|
||||
// 首次登录缺角色时由 App.vue + 请求拦截器统一弹出「首次登录请选择角色」弹框,此处不再自动打开
|
||||
|
||||
// 页面加载时
|
||||
onMounted(() => {
|
||||
@@ -271,7 +263,6 @@ onMounted(() => {
|
||||
}
|
||||
useFlowJob().topJobList()
|
||||
getIsDot()
|
||||
openChangeRoleIfMissing()
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,56 +1,79 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="角色切换"
|
||||
:title="dialogTitle"
|
||||
width="50%"
|
||||
:show-close="false"
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
:before-close="handleBeforeClose"
|
||||
center
|
||||
>
|
||||
<el-form>
|
||||
<!-- <el-form-item label="学校">-->
|
||||
<!-- <el-tag>{{schoolName}}</el-tag>-->
|
||||
<!-- </el-form-item>-->
|
||||
<el-form-item label="角色" class="role-form-item">
|
||||
<el-form-item class="role-form-item">
|
||||
<el-radio-group v-model="radio" class="role-radio-group" @change="handleChangeRole">
|
||||
<template v-for="(roles, groupName) in allRoleGroups" :key="groupName">
|
||||
<div class="role-group">
|
||||
<el-divider>{{ groupName }}</el-divider>
|
||||
<el-radio-button
|
||||
v-for="item in allRole"
|
||||
v-for="item in roles"
|
||||
:key="item.roleCode"
|
||||
:label="item.roleCode"
|
||||
>
|
||||
{{ item.roleName }}
|
||||
</el-radio-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
||||
<template #footer>
|
||||
<!-- <el-button type="primary" @click="handleChangeRole">切换</el-button>-->
|
||||
<template v-if="!requireSelectToClose" #footer>
|
||||
<el-button @click="handleFooterClose">关 闭</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, toRef } from 'vue'
|
||||
import { listAllRole } from '/@/api/admin/role'
|
||||
import { Local } from '/@/utils/storage'
|
||||
import { useMessage } from '/@/hooks/message'
|
||||
|
||||
/** 弹框标题,如「角色切换」「登录角色选择」 */
|
||||
const props = withDefaults(
|
||||
defineProps<{ title?: string; requireSelectToClose?: boolean }>(),
|
||||
{ title: '角色切换', requireSelectToClose: false }
|
||||
)
|
||||
const dialogTitle = computed(() => props.title)
|
||||
|
||||
const visible = ref(false)
|
||||
const radio = ref('')
|
||||
const allRole = reactive<any[]>([])
|
||||
/** 按分组名分组的角色列表:{ "未分组": [{ roleId, roleName, roleCode, ... }], ... } */
|
||||
const allRoleGroups = ref<Record<string, any[]>>({})
|
||||
const requireSelectToClose = toRef(props, 'requireSelectToClose')
|
||||
|
||||
const open = () => {
|
||||
if (visible.value) return
|
||||
visible.value = true
|
||||
listAllRole().then((res) => {
|
||||
Object.assign(allRole, res.data)
|
||||
allRoleGroups.value = res.data && typeof res.data === 'object' && !Array.isArray(res.data)
|
||||
? res.data
|
||||
: { '未分组': Array.isArray(res.data) ? res.data : [] }
|
||||
radio.value = Local.get('roleCode')
|
||||
visible.value = true
|
||||
})
|
||||
}
|
||||
|
||||
/** 根据 roleCode 从分组数据中查找角色 */
|
||||
const findRoleByCode = (code: string) => {
|
||||
for (const roles of Object.values(allRoleGroups.value)) {
|
||||
if (!Array.isArray(roles)) continue
|
||||
const found = roles.find((r: any) => r.roleCode === code)
|
||||
if (found) return found
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
const canClose = () => {
|
||||
if (!radio.value) {
|
||||
useMessage().warning('请选择一个角色')
|
||||
@@ -60,6 +83,10 @@ const canClose = () => {
|
||||
}
|
||||
|
||||
const handleBeforeClose = (done: () => void) => {
|
||||
if (requireSelectToClose.value) {
|
||||
useMessage().warning('请先选择登录角色')
|
||||
return
|
||||
}
|
||||
if (!canClose()) return
|
||||
done()
|
||||
}
|
||||
@@ -70,7 +97,7 @@ const handleFooterClose = () => {
|
||||
}
|
||||
|
||||
const handleChangeRole = (label: string) => {
|
||||
const obj = allRole.find((v: any) => v.roleCode === label)
|
||||
const obj = findRoleByCode(label)
|
||||
if (!obj) return
|
||||
Local.set('roleCode', obj.roleCode)
|
||||
Local.set('roleName', obj.roleName)
|
||||
@@ -94,6 +121,18 @@ defineExpose({
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
.role-group {
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
.group-name {
|
||||
font-size: 13px;
|
||||
color: var(--el-text-color-secondary);
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
.role-radio-group {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
<template>
|
||||
<el-dialog v-model="visible" width="50%" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false" center>
|
||||
<template #title>
|
||||
<div style="margin: 0 auto;width:100%;text-align:center;font-size:18px;font-weight:bold;">
|
||||
登录角色选择
|
||||
</div>
|
||||
</template>
|
||||
<div style="margin: 0 auto;width:100%;text-align:center;font-size:18px;font-weight:bold;">
|
||||
<el-radio-group v-model="radio">
|
||||
<el-radio-button v-for="(item,index) in allRole" :key="index" :label="item.roleCode" @click.native="handleChangeRole(item.roleCode)">{{item.roleName}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {listAllRole} from '/@/api/admin/role'
|
||||
import {Local, Session} from '/@/utils/storage';
|
||||
import {useMessage} from "/@/hooks/message";
|
||||
// import {querySchoolName} from "/@/api/admin/tenant"
|
||||
|
||||
const visible=ref(false)
|
||||
const radio=ref('')
|
||||
const allRole = reactive<any[]>([])
|
||||
const schoolName=ref('')
|
||||
|
||||
const open = () => {
|
||||
listAllRole().then(res => {
|
||||
Object.assign(allRole, res.data)
|
||||
radio.value = Local.get('roleCode')
|
||||
visible.value = true
|
||||
})
|
||||
}
|
||||
|
||||
// 必须选择角色后才能关闭,禁止点击遮罩/ESC 关闭(不调用 done 即不关闭)
|
||||
const handleBeforeClose = (_done: () => void) => {
|
||||
useMessage().warning('请先选择登录角色')
|
||||
}
|
||||
|
||||
const handleChangeRole = (label: any) => {
|
||||
let obj:any=allRole.find((v:any) => v.roleCode == label)
|
||||
Local.set("roleCode",obj.roleCode)
|
||||
Local.set("roleName",obj.roleName)
|
||||
Local.set("roleId",obj.roleId)
|
||||
useMessage().success("操作成功")
|
||||
setTimeout(()=>{
|
||||
window.location.reload()
|
||||
},500)
|
||||
}
|
||||
|
||||
// const handleQuerySchoolName=()=>{
|
||||
// querySchoolName({id:Session.get("tenantId")}).then((res:any)=>{
|
||||
// schoolName.value=res.data
|
||||
// })
|
||||
// }
|
||||
|
||||
defineExpose({
|
||||
open
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user