201 lines
4.7 KiB
Vue
201 lines
4.7 KiB
Vue
|
|
<template>
|
||
|
|
<div class="complaint-system-login">
|
||
|
|
<div class="login-container">
|
||
|
|
<div class="login-card">
|
||
|
|
<h1>投诉系统登录</h1>
|
||
|
|
<p class="description">正在为您跳转到投诉系统...</p>
|
||
|
|
|
||
|
|
<div class="button-group">
|
||
|
|
<el-button
|
||
|
|
type="primary"
|
||
|
|
size="large"
|
||
|
|
@click="handleSSO"
|
||
|
|
:loading="isLoading"
|
||
|
|
>
|
||
|
|
{{ isLoading ? '正在跳转...' : '点击跳转到投诉系统' }}
|
||
|
|
</el-button>
|
||
|
|
|
||
|
|
<el-button
|
||
|
|
size="large"
|
||
|
|
@click="handleCancel"
|
||
|
|
>
|
||
|
|
取消
|
||
|
|
</el-button>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<div v-if="errorMessage" class="error-message">
|
||
|
|
<el-alert
|
||
|
|
:title="errorMessage"
|
||
|
|
type="error"
|
||
|
|
:closable="true"
|
||
|
|
@close="errorMessage = ''"
|
||
|
|
/>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { ref, onMounted } from 'vue';
|
||
|
|
import { ElMessage } from 'element-plus';
|
||
|
|
import { SignJWT } from 'jose';
|
||
|
|
import { useUserStore } from '@/stores/modules/user';
|
||
|
|
// 投诉系统配置
|
||
|
|
const COMPLAINT_SYSTEM_URL = 'https://auth.xa.12350.work/backend.auth/zhzf_login'
|
||
|
|
const SSO_SECRET_KEY = import.meta.env.VITE_SSO_SECRET_KEY || 'default-secret-key-change-in-production'
|
||
|
|
|
||
|
|
const isLoading = ref(false)
|
||
|
|
const errorMessage = ref('')
|
||
|
|
const userStore = useUserStore()
|
||
|
|
/**
|
||
|
|
* 生成 SSO JWT 令牌
|
||
|
|
*/
|
||
|
|
async function generateSSOToken(userInfo) {
|
||
|
|
try {
|
||
|
|
// 将密钥转换为 Uint8Array
|
||
|
|
const encoder = new TextEncoder();
|
||
|
|
const secret = encoder.encode(SSO_SECRET_KEY);
|
||
|
|
|
||
|
|
const now = Math.floor(Date.now() / 1000);
|
||
|
|
|
||
|
|
const token = await new SignJWT({
|
||
|
|
userId: userInfo.userId,
|
||
|
|
officerName: userInfo.officerName,
|
||
|
|
officerMobilePhone: userInfo.officerMobilePhone
|
||
|
|
})
|
||
|
|
.setProtectedHeader({ alg: 'HS256' })
|
||
|
|
.setIssuedAt(now)
|
||
|
|
.setExpirationTime(now + 86400) // 24小时有效期
|
||
|
|
.sign(secret);
|
||
|
|
|
||
|
|
return token;
|
||
|
|
} catch (error) {
|
||
|
|
console.error('生成 SSO 令牌失败:', error);
|
||
|
|
throw new Error('生成 SSO 令牌失败: ' + error.message);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 生成投诉系统的重定向 URL
|
||
|
|
*/
|
||
|
|
async function generateRedirectURL(userInfo) {
|
||
|
|
try {
|
||
|
|
const token = await generateSSOToken(userInfo);
|
||
|
|
const redirectURL = `${COMPLAINT_SYSTEM_URL}?token=${encodeURIComponent(token)}`;
|
||
|
|
return redirectURL;
|
||
|
|
} catch (error) {
|
||
|
|
console.error('生成重定向 URL 失败:', error);
|
||
|
|
throw error;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 执行 SSO 跳转
|
||
|
|
*/
|
||
|
|
async function handleSSO() {
|
||
|
|
isLoading.value = true;
|
||
|
|
errorMessage.value = '';
|
||
|
|
|
||
|
|
try {
|
||
|
|
// 使用测试用户信息
|
||
|
|
const testUserInfo = {
|
||
|
|
userId: userStore.userInfo.yhwybs,
|
||
|
|
officerName: userStore.username,
|
||
|
|
officerMobilePhone: userStore.mobile,
|
||
|
|
iat: Math.floor(Date.now() / 1000),
|
||
|
|
exp: Math.floor(Date.now() / 1000) + 86400
|
||
|
|
};
|
||
|
|
|
||
|
|
const redirectURL = await generateRedirectURL(testUserInfo);
|
||
|
|
|
||
|
|
console.log('生成的重定向 URL:', redirectURL);
|
||
|
|
console.log('用户信息:', testUserInfo);
|
||
|
|
|
||
|
|
// 在当前窗口跳转到投诉系统(登录组件通常已在新窗口中打开)
|
||
|
|
window.location.href = redirectURL;
|
||
|
|
|
||
|
|
ElMessage.success('已为您打开投诉系统,请等待加载。');
|
||
|
|
} catch (error) {
|
||
|
|
console.error('SSO 跳转失败:', error);
|
||
|
|
errorMessage.value = error.message || '跳转失败,请稍后重试';
|
||
|
|
ElMessage.error(errorMessage.value);
|
||
|
|
} finally {
|
||
|
|
isLoading.value = false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 取消操作
|
||
|
|
*/
|
||
|
|
function handleCancel() {
|
||
|
|
window.history.back();
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* 组件挂载时的初始化
|
||
|
|
*/
|
||
|
|
onMounted(() => {
|
||
|
|
console.log('投诉系统登录挂载完成');
|
||
|
|
handleSSO();
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
|
||
|
|
<style scoped lang="scss">
|
||
|
|
.complaint-system-login {
|
||
|
|
width: 100%;
|
||
|
|
height: 100vh;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
|
|
|
||
|
|
.login-container {
|
||
|
|
width: 100%;
|
||
|
|
height: 100%;
|
||
|
|
display: flex;
|
||
|
|
align-items: center;
|
||
|
|
justify-content: center;
|
||
|
|
padding: 20px;
|
||
|
|
|
||
|
|
.login-card {
|
||
|
|
background: white;
|
||
|
|
border-radius: 8px;
|
||
|
|
box-shadow: 0 10px 40px rgba(0, 0, 0, 0.2);
|
||
|
|
padding: 40px;
|
||
|
|
max-width: 500px;
|
||
|
|
width: 100%;
|
||
|
|
text-align: center;
|
||
|
|
|
||
|
|
h1 {
|
||
|
|
margin: 0 0 10px 0;
|
||
|
|
color: #333;
|
||
|
|
font-size: 28px;
|
||
|
|
font-weight: 600;
|
||
|
|
}
|
||
|
|
|
||
|
|
.description {
|
||
|
|
color: #666;
|
||
|
|
font-size: 14px;
|
||
|
|
margin-bottom: 30px;
|
||
|
|
line-height: 1.6;
|
||
|
|
}
|
||
|
|
|
||
|
|
.button-group {
|
||
|
|
display: flex;
|
||
|
|
gap: 12px;
|
||
|
|
margin-bottom: 20px;
|
||
|
|
|
||
|
|
:deep(.el-button) {
|
||
|
|
flex: 1;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
.error-message {
|
||
|
|
margin-top: 20px;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
</style>
|