zhzf/client/src/views/jbts/login.vue

201 lines
4.7 KiB
Vue
Raw Normal View History

<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>