Pre Merge pull request !458 from janeywong/master

pull/458/MERGE
janeywong 2024-09-28 12:33:52 +00:00 committed by Gitee
commit d864793b6d
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
7 changed files with 81 additions and 1 deletions

View File

@ -12,11 +12,26 @@ export interface SmsLoginVO {
code: string
}
export interface ImpersonateReqVO {
tenantId?: number
userId?: number
}
// 登录
export const login = (data: UserLoginVO) => {
return request.post({ url: '/system/auth/login', data })
}
// 模拟身份登录
export const loginImpersonate = (data: ImpersonateReqVO) => {
return request.post({ url: '/system/auth/login/impersonate', data})
}
// 退出身份模拟
export const stopImpersonation = () => {
return request.post({ url: '/system/auth/stop-impersonation'})
}
// 刷新访问令牌
export const refreshToken = () => {
return request.post({ url: '/system/auth/refresh-token?refreshToken=' + getRefreshToken() })

View File

@ -8,6 +8,8 @@ import { useUserStore } from '@/store/modules/user'
import LockDialog from './components/LockDialog.vue'
import LockPage from './components/LockPage.vue'
import { useLockStore } from '@/store/modules/lock'
import * as LoginApi from '@/api/login'
import * as authUtil from "@/utils/auth"
defineOptions({ name: 'UserInfo' })
@ -34,6 +36,18 @@ const lockScreen = () => {
dialogVisible.value = true
}
const stopImpersonation = async () => {
const res = await LoginApi.stopImpersonation()
if(!res){
return
}
await userStore.loginOut()
tagsViewStore.delAllViews()
authUtil.setToken(res)
authUtil.setTenantId(res.tenantId)
push({ path: authUtil.getImpersonateRefererPath() || '' })
}
const loginOut = async () => {
try {
await ElMessageBox.confirm(t('common.loginOutMessage'), t('common.reminder'), {
@ -76,6 +90,10 @@ const toDocument = () => {
<Icon icon="ep:lock" />
<div @click="lockScreen">{{ t('lock.lockScreen') }}</div>
</ElDropdownItem>
<ElDropdownItem divided v-if="userStore.getUser.impersonated">
<Icon icon="humbleicons:incognito" />
<div @click="stopImpersonation">{{ t('common.stopImpersonation') }}</div>
</ElDropdownItem>
<ElDropdownItem divided @click="loginOut">
<Icon icon="ep:switch-button" />
<div>{{ t('common.loginOut') }}</div>

View File

@ -7,6 +7,7 @@ export default {
login: 'Login',
required: 'This is required',
loginOut: 'Login out',
stopImpersonation: 'Stop impersonation',
document: 'Document',
profile: 'User Center',
reminder: 'Reminder',

View File

@ -7,6 +7,7 @@ export default {
login: '登录',
required: '该项为必填项',
loginOut: '退出系统',
stopImpersonation: '退出身份模拟',
document: '项目文档',
profile: '个人中心',
reminder: '温馨提示',

View File

@ -11,6 +11,7 @@ interface UserVO {
avatar: string
nickname: string
deptId: number
impersonated: boolean
}
interface UserInfoVO {

View File

@ -6,6 +6,7 @@ const { wsCache } = useCache()
const AccessTokenKey = 'ACCESS_TOKEN'
const RefreshTokenKey = 'REFRESH_TOKEN'
const ImpersonateRefererKey = 'IMPERSONATED_REFERER'
// 获取token
export const getAccessToken = () => {
@ -24,6 +25,16 @@ export const setToken = (token: TokenType) => {
wsCache.set(AccessTokenKey, token.accessToken)
}
// 设置退出模拟身份登录后的跳转路径
export const setImpersonateRefererPath = (path: string) => {
wsCache.set(ImpersonateRefererKey, path)
}
// 获取退出模拟身份登录后的跳转路径
export const getImpersonateRefererPath = () => {
return wsCache.get(ImpersonateRefererKey)
}
// 删除token
export const removeToken = () => {
wsCache.delete(AccessTokenKey)

View File

@ -140,6 +140,16 @@
/>
<el-table-column label="操作" align="center" min-width="110" fixed="right">
<template #default="scope">
<el-button
link
type="primary"
@click="handleImpersonate(scope.row)"
v-if="authUtil.getTenantId() !== scope.row.id"
v-hasPermi="['system:login:impersonate']"
v-hasRole="['super_admin']"
>
模拟身份
</el-button>
<el-button
link
type="primary"
@ -176,14 +186,20 @@ import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { dateFormatter } from '@/utils/formatTime'
import download from '@/utils/download'
import * as TenantApi from '@/api/system/tenant'
import * as LoginApi from '@/api/login'
import * as authUtil from '@/utils/auth'
const { currentRoute, push } = useRouter()
import { useUserStore } from '@/store/modules/user'
import * as TenantPackageApi from '@/api/system/tenantPackage'
import TenantForm from './TenantForm.vue'
import { useTagsViewStore } from '@/store/modules/tagsView'
defineOptions({ name: 'SystemTenant' })
const message = useMessage() //
const { t } = useI18n() //
const userStore = useUserStore()
const loading = ref(true) //
const total = ref(0) //
const list = ref([]) //
@ -199,7 +215,7 @@ const queryParams = reactive({
const queryFormRef = ref() //
const exportLoading = ref(false) //
const packageList = ref([] as TenantPackageApi.TenantPackageVO[]) //
const tagsViewStore = useTagsViewStore()
/** 查询列表 */
const getList = async () => {
loading.value = true
@ -243,6 +259,23 @@ const handleDelete = async (id: number) => {
} catch {}
}
/** 模拟身份登录 */
const handleImpersonate = async (row) => {
try {
const res = await LoginApi.loginImpersonate({tenantId: row.id, userId: row.contactUserId})
if (!res) {
return
}
await userStore.loginOut()
authUtil.setToken(res)
authUtil.setTenantId(row.id)
authUtil.setImpersonateRefererPath(currentRoute.value.path)
tagsViewStore.delAllViews()
push({ path: '/' })
} finally {
}
}
/** 导出按钮操作 */
const handleExport = async () => {
try {