Commit 0fda78e4 by Performance System

1

parent 4c5265c1
Pipeline #3260 failed with stage
in 2 minutes 9 seconds
# ========================================
# 绩效计分系统 - 生产环境配置
# ========================================
# ==================== 前端配置 ====================
# API 服务地址 - 生产环境使用相对路径,通过Nginx代理
# 前端和后端在同一域名下,通过Nginx代理/api路径到后端
VITE_API_BASE_URL=
# ==================== 后端配置 ====================
# 数据库配置
# 格式: postgresql://用户名:密码@主机:端口/数据库名
DATABASE_URL=postgresql://performance_user:performance_pass@postgres:5432/performance_db
# API 服务配置
API_HOST=0.0.0.0
API_PORT=8000
# CORS 配置(生产环境允许所有来源,因为通过Nginx代理)
CORS_ORIGINS=*
# 安全配置
# 生产环境请务必更改为强密码
SECRET_KEY=your-production-secret-key-change-this
# JWT配置
JWT_SECRET_KEY=your-production-jwt-secret-key-change-this
JWT_ALGORITHM=HS256
JWT_EXPIRE_HOURS=24
# 日志配置
LOG_LEVEL=INFO
LOG_FILE=logs/api.log
# 数据迁移配置
MIGRATION_BATCH_SIZE=100
......@@ -56,7 +56,8 @@ services:
context: .
dockerfile: Dockerfile
args:
VITE_API_BASE_URL: ${VITE_API_BASE_URL}
# 生产环境使用空字符串,让前端使用相对路径通过Nginx代理
VITE_API_BASE_URL: ""
container_name: performance_frontend
ports:
- "4001:80"
......
......@@ -15,16 +15,28 @@ server {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# CORS 头部
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
# 超时设置(处理大文件上传)
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
# 请求体大小限制(允许上传大图片)
client_max_body_size 10M;
# CORS 头部(后端已处理CORS,这里作为备份)
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Allow-Credentials "true" always;
# 处理 OPTIONS 预检请求
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "Content-Type, Authorization" always;
add_header Access-Control-Allow-Credentials "true" always;
add_header Content-Length 0;
add_header Content-Type text/plain;
return 204;
}
}
......
......@@ -74,8 +74,10 @@ router.beforeEach(async (to, from, next) => {
return
}
// 检查角色权限
if (to.meta.roles && !to.meta.roles.includes(authStore.currentUser.role)) {
// 检查角色权限 - 使用 effectiveUser 而不是 currentUser
// 这样管理员切换到用户视图时,会使用 viewAsUser 的角色
const effectiveRole = authStore.effectiveUser?.role || authStore.currentUser?.role
if (to.meta.roles && !to.meta.roles.includes(effectiveRole)) {
// 权限不足,跳转到用户面板
next('/user')
return
......@@ -84,7 +86,10 @@ router.beforeEach(async (to, from, next) => {
// 已登录用户访问登录页,直接跳转到对应面板
if (to.path === '/login' && authStore.isAuthenticated) {
if (authStore.currentUser.role === 'admin') {
// 如果正在查看用户视图,跳转到用户面板
if (authStore.isViewingAsUser) {
next('/user')
} else if (authStore.currentUser.role === 'admin') {
next('/admin')
} else {
next('/user')
......
......@@ -4,8 +4,12 @@
* 替换原有的 localStorage 存储机制
*/
// API 基础配置 - 直接使用后端API地址
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://localhost:8000'
// API 基础配置
// 生产环境:VITE_API_BASE_URL 为空字符串,使用相对路径通过Nginx代理
// 开发环境:VITE_API_BASE_URL 为 http://localhost:8000,直接访问后端
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL !== undefined
? import.meta.env.VITE_API_BASE_URL
: 'http://localhost:8000'
/**
* HTTP 请求封装类
......
......@@ -97,6 +97,10 @@ export const useAuthStore = defineStore('auth', () => {
currentUser.value = null
localStorage.removeItem('currentUser')
// 清除用户视图状态
viewAsUser.value = null
localStorage.removeItem('viewAsUser')
// 清除tokens
apiClient.clearTokens()
......
......@@ -10,6 +10,14 @@
<p class="period-info">当前统计周期:{{ currentPeriod }}</p>
</div>
<div class="header-actions">
<!-- 如果是管理员查看用户视图,显示返回按钮 -->
<el-button
v-if="authStore.isViewingAsUser"
type="primary"
@click="handleSwitchBackToAdmin"
>
返回管理员视图
</el-button>
<el-button @click="handleLogout">退出登录</el-button>
</div>
</div>
......@@ -750,6 +758,15 @@ const refreshData = async () => {
/**
* 返回管理员视图
*/
const handleSwitchBackToAdmin = () => {
authStore.switchBackToAdmin()
router.push('/admin')
ElMessage.success('已返回管理员视图')
}
/**
* 退出登录
*/
const handleLogout = async () => {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment