1
This commit is contained in:
31
src/App.vue
31
src/App.vue
@@ -4,7 +4,7 @@
|
|||||||
<LockScreen v-if="themeConfig.isLockScreen" />
|
<LockScreen v-if="themeConfig.isLockScreen" />
|
||||||
<Settings ref="settingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
<Settings ref="settingsRef" v-show="themeConfig.lockScreenTime > 1" />
|
||||||
<CloseFull v-if="!themeConfig.isLockScreen" />
|
<CloseFull v-if="!themeConfig.isLockScreen" />
|
||||||
<ChangeRoleFir ref="changeRoleFirRef" />
|
<ChangeRole ref="changeRoleFirRef" title="首次登录请选择角色" :require-select-to-close="true" />
|
||||||
</el-config-provider>
|
</el-config-provider>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -22,7 +22,7 @@ import setIntroduction from '/@/utils/setIconfont';
|
|||||||
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
|
const LockScreen = defineAsyncComponent(() => import('/@/layout/lockScreen/index.vue'));
|
||||||
const Settings = defineAsyncComponent(() => import('./layout/navBars/breadcrumb/settings.vue'));
|
const Settings = defineAsyncComponent(() => import('./layout/navBars/breadcrumb/settings.vue'));
|
||||||
const CloseFull = defineAsyncComponent(() => import('/@/layout/navBars/breadcrumb/closeFull.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();
|
const { messages, locale } = useI18n();
|
||||||
@@ -56,10 +56,19 @@ onBeforeMount(() => {
|
|||||||
// 设置批量第三方 js
|
// 设置批量第三方 js
|
||||||
setIntroduction.jsCdn();
|
setIntroduction.jsCdn();
|
||||||
});
|
});
|
||||||
// 页面加载时
|
// 角色选择弹框是否已在本轮打开过(防止事件被触发两次)
|
||||||
|
let roleDialogOpenedThisSession = false
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
// 唯一入口:只通过事件打开,且只打开一次;延迟打开以等待异步组件挂载
|
||||||
|
mittBus.on('openRoleSelectDialog', () => {
|
||||||
|
if (roleDialogOpenedThisSession) return
|
||||||
|
roleDialogOpenedThisSession = true
|
||||||
|
setTimeout(() => {
|
||||||
|
changeRoleFirRef.value?.open()
|
||||||
|
}, 300)
|
||||||
|
})
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 监听布局配'置弹窗点击打开
|
// 监听布局配置弹窗点击打开
|
||||||
mittBus.on('openSettingsDrawer', () => {
|
mittBus.on('openSettingsDrawer', () => {
|
||||||
settingsRef.value.openDrawer();
|
settingsRef.value.openDrawer();
|
||||||
});
|
});
|
||||||
@@ -72,18 +81,12 @@ onMounted(() => {
|
|||||||
if (Session.get('isTagsViewCurrenFull')) {
|
if (Session.get('isTagsViewCurrenFull')) {
|
||||||
stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
|
stores.setCurrenFullscreen(Session.get('isTagsViewCurrenFull'));
|
||||||
}
|
}
|
||||||
// 全局判断:已登录但 Local 缺少角色信息时弹出角色选择;弹框已触发则不再重复弹出
|
// 与请求拦截器共用同一逻辑:先设标志再 emit,由监听器统一打开(监听器内会延迟 300ms 以等待异步组件挂载)
|
||||||
if (Session.getToken() && needRoleSelection() && !isRoleDialogTriggered()) {
|
if (Session.getToken() && needRoleSelection() && !isRoleDialogTriggered()) {
|
||||||
setRoleDialogTriggered(true);
|
setRoleDialogTriggered(true)
|
||||||
setTimeout(() => {
|
mittBus.emit('openRoleSelectDialog')
|
||||||
changeRoleFirRef.value?.open();
|
|
||||||
}, 300);
|
|
||||||
}
|
}
|
||||||
// 请求拦截器里也会在发送请求时判断并 emit,此处统一监听打开弹框
|
})
|
||||||
mittBus.on('openRoleSelectDialog', () => {
|
|
||||||
changeRoleFirRef.value?.open();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
// 页面销毁时,关闭监听
|
// 页面销毁时,关闭监听
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
|||||||
@@ -253,15 +253,7 @@ const getIsDot = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// 登录后若存储中无角色信息则弹出角色切换框
|
// 首次登录缺角色时由 App.vue + 请求拦截器统一弹出「首次登录请选择角色」弹框,此处不再自动打开
|
||||||
const openChangeRoleIfMissing = () => {
|
|
||||||
const hasRole = Local.get('roleCode') && Local.get('roleName') && Local.get('roleId')
|
|
||||||
if (!hasRole) {
|
|
||||||
nextTick(() => {
|
|
||||||
setTimeout(() => ChangeRoleRef.value?.open(), 100)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 页面加载时
|
// 页面加载时
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@@ -271,7 +263,6 @@ onMounted(() => {
|
|||||||
}
|
}
|
||||||
useFlowJob().topJobList()
|
useFlowJob().topJobList()
|
||||||
getIsDot()
|
getIsDot()
|
||||||
openChangeRoleIfMissing()
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,56 +1,79 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="visible"
|
v-model="visible"
|
||||||
title="角色切换"
|
:title="dialogTitle"
|
||||||
width="50%"
|
width="50%"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
:close-on-press-escape="false"
|
:close-on-press-escape="false"
|
||||||
:before-close="handleBeforeClose"
|
:before-close="handleBeforeClose"
|
||||||
|
center
|
||||||
>
|
>
|
||||||
<el-form>
|
<el-form>
|
||||||
<!-- <el-form-item label="学校">-->
|
<el-form-item class="role-form-item">
|
||||||
<!-- <el-tag>{{schoolName}}</el-tag>-->
|
|
||||||
<!-- </el-form-item>-->
|
|
||||||
<el-form-item label="角色" class="role-form-item">
|
|
||||||
<el-radio-group v-model="radio" class="role-radio-group" @change="handleChangeRole">
|
<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
|
<el-radio-button
|
||||||
v-for="item in allRole"
|
v-for="item in roles"
|
||||||
:key="item.roleCode"
|
:key="item.roleCode"
|
||||||
:label="item.roleCode"
|
:label="item.roleCode"
|
||||||
>
|
>
|
||||||
{{ item.roleName }}
|
{{ item.roleName }}
|
||||||
</el-radio-button>
|
</el-radio-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|
||||||
|
<template v-if="!requireSelectToClose" #footer>
|
||||||
<template #footer>
|
|
||||||
<!-- <el-button type="primary" @click="handleChangeRole">切换</el-button>-->
|
|
||||||
<el-button @click="handleFooterClose">关 闭</el-button>
|
<el-button @click="handleFooterClose">关 闭</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
import { ref, computed, toRef } from 'vue'
|
||||||
import { listAllRole } from '/@/api/admin/role'
|
import { listAllRole } from '/@/api/admin/role'
|
||||||
import { Local } from '/@/utils/storage'
|
import { Local } from '/@/utils/storage'
|
||||||
import { useMessage } from '/@/hooks/message'
|
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 visible = ref(false)
|
||||||
const radio = ref('')
|
const radio = ref('')
|
||||||
const allRole = reactive<any[]>([])
|
/** 按分组名分组的角色列表:{ "未分组": [{ roleId, roleName, roleCode, ... }], ... } */
|
||||||
|
const allRoleGroups = ref<Record<string, any[]>>({})
|
||||||
|
const requireSelectToClose = toRef(props, 'requireSelectToClose')
|
||||||
|
|
||||||
const open = () => {
|
const open = () => {
|
||||||
|
if (visible.value) return
|
||||||
visible.value = true
|
visible.value = true
|
||||||
listAllRole().then((res) => {
|
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')
|
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 = () => {
|
const canClose = () => {
|
||||||
if (!radio.value) {
|
if (!radio.value) {
|
||||||
useMessage().warning('请选择一个角色')
|
useMessage().warning('请选择一个角色')
|
||||||
@@ -60,6 +83,10 @@ const canClose = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleBeforeClose = (done: () => void) => {
|
const handleBeforeClose = (done: () => void) => {
|
||||||
|
if (requireSelectToClose.value) {
|
||||||
|
useMessage().warning('请先选择登录角色')
|
||||||
|
return
|
||||||
|
}
|
||||||
if (!canClose()) return
|
if (!canClose()) return
|
||||||
done()
|
done()
|
||||||
}
|
}
|
||||||
@@ -70,7 +97,7 @@ const handleFooterClose = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleChangeRole = (label: string) => {
|
const handleChangeRole = (label: string) => {
|
||||||
const obj = allRole.find((v: any) => v.roleCode === label)
|
const obj = findRoleByCode(label)
|
||||||
if (!obj) return
|
if (!obj) return
|
||||||
Local.set('roleCode', obj.roleCode)
|
Local.set('roleCode', obj.roleCode)
|
||||||
Local.set('roleName', obj.roleName)
|
Local.set('roleName', obj.roleName)
|
||||||
@@ -94,6 +121,18 @@ defineExpose({
|
|||||||
flex-wrap: wrap;
|
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 {
|
.role-radio-group {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
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