feat(auth): 实现自动登录功能并优化API请求配置
- 在App.vue中添加onMounted钩子自动执行autoLogin函数 - 新增auth.js工具模块实现自动登录逻辑 - 配置API请求优先从localStorage获取Token - 添加对localStorage和Cookie中Token的兼容性处理 - 集成echarts-china-map依赖包 - 移除测试用硬编码Token和调试日志 - 统一API基础路径为/api - 添加Docker部署配置文件和nginx反向代理设置
This commit is contained in:
11
.dockerignore
Normal file
11
.dockerignore
Normal file
@@ -0,0 +1,11 @@
|
||||
node_modules
|
||||
.git
|
||||
.gitignore
|
||||
.idea
|
||||
*.md
|
||||
deploy.sh
|
||||
.env
|
||||
src
|
||||
public
|
||||
scripts
|
||||
node_modules
|
||||
16
Dockerfile
Normal file
16
Dockerfile
Normal file
@@ -0,0 +1,16 @@
|
||||
# ============================================
|
||||
# Docker 部署 - 数据大屏管理系统
|
||||
# 使用 Nginx 托管前端 + 反向代理 API
|
||||
# ============================================
|
||||
|
||||
FROM nginx:alpine
|
||||
|
||||
# 将构建好的前端静态文件复制到 Nginx
|
||||
COPY dist/ /usr/share/nginx/html/
|
||||
|
||||
# 替换 Nginx 配置
|
||||
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||
|
||||
EXPOSE 18800
|
||||
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
20
nginx.conf
Normal file
20
nginx.conf
Normal file
@@ -0,0 +1,20 @@
|
||||
server {
|
||||
listen 18800;
|
||||
server_name localhost;
|
||||
|
||||
# 前端静态文件
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html;
|
||||
try_files $uri $uri/ /index.html; # Vue Router 历史模式支持
|
||||
}
|
||||
|
||||
# API 反向代理到真实后端
|
||||
location /api/ {
|
||||
proxy_pass http://140.143.206.120/prod-api/;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
"axios": "^1.6.7",
|
||||
"cors": "^2.8.6",
|
||||
"echarts": "^5.6.0",
|
||||
"echarts-china-map": "^1.0.4",
|
||||
"element-plus": "^2.6.1",
|
||||
"express": "^5.2.1",
|
||||
"mysql2": "^3.22.3",
|
||||
|
||||
@@ -3,6 +3,12 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { onMounted } from 'vue'
|
||||
import { autoLogin } from '@/utils/auth'
|
||||
|
||||
onMounted(() => {
|
||||
autoLogin()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import axios from 'axios'
|
||||
|
||||
const baseURL = process.env.VUE_APP_API_BASE_URL || '/api'
|
||||
const baseURL = '/api'
|
||||
|
||||
const service = axios.create({
|
||||
baseURL,
|
||||
@@ -10,31 +10,27 @@ const service = axios.create({
|
||||
}
|
||||
})
|
||||
|
||||
// 从 Cookies 获取 Token(与 klp-ui 保持一致)
|
||||
// Token 获取顺序:localStorage(自动登录) > Cookie(主系统登录)
|
||||
const getToken = () => {
|
||||
// 1. 优先取自动登录存的 token
|
||||
const localToken = localStorage.getItem('Admin-Token')
|
||||
if (localToken) return localToken
|
||||
|
||||
// 2. 其次从 Cookie 取(主系统登录)
|
||||
const name = 'Admin-Token'
|
||||
const value = `; ${document.cookie}`
|
||||
const parts = value.split(`; ${name}=`)
|
||||
if (parts.length === 2) return parts.pop().split(';').shift()
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
let token = getToken()
|
||||
// ========== 测试用:临时硬编码 Token ==========
|
||||
// 如果没有从 Cookies 获取到 Token,使用测试 Token
|
||||
if (!token) {
|
||||
token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJzeXNfdXNlcjoxIiwicm5TdHIiOiJGM2w5Nm5ncGV4ZDA4d1BUYWlvVmFreWhCUDdlc2gyeCIsInVzZXJJZCI6MX0.aP06S-5aJtukzMjmYW3d5zK3v10TOKcdNpROniv5lr8'
|
||||
}
|
||||
// ========== 测试用结束 ==========
|
||||
|
||||
console.log('请求URL:', config.url)
|
||||
console.log('使用的Token:', token ? '已设置' : '未设置')
|
||||
const token = getToken()
|
||||
|
||||
if (token) {
|
||||
// 尝试两种格式:Bearer 和 直接使用Token
|
||||
config.headers['Authorization'] = token // 直接使用Token(不带Bearer前缀)
|
||||
config.headers['Authorization'] = token
|
||||
}
|
||||
return config
|
||||
},
|
||||
@@ -45,8 +41,6 @@ service.interceptors.request.use(
|
||||
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
console.log('响应数据:', response.data)
|
||||
|
||||
let res = response.data
|
||||
|
||||
// 如果响应数据为空
|
||||
|
||||
57
src/utils/auth.js
Normal file
57
src/utils/auth.js
Normal file
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* 自动登录模块
|
||||
* 应用启动时用账号密码获取 Token,存到 localStorage
|
||||
* 后续所有 API 请求从 localStorage 取 Token
|
||||
*/
|
||||
|
||||
const LOGIN_URL = '/api/login'
|
||||
const STORAGE_KEY = 'Admin-Token'
|
||||
|
||||
/**
|
||||
* 调用登录接口获取 Token
|
||||
*/
|
||||
export async function autoLogin() {
|
||||
// 如果已有 Token,跳过
|
||||
const existing = localStorage.getItem(STORAGE_KEY)
|
||||
if (existing) {
|
||||
console.log('[Auth] 已有 Token,跳过自动登录')
|
||||
return existing
|
||||
}
|
||||
|
||||
console.log('[Auth] 正在自动登录获取 Token...')
|
||||
|
||||
try {
|
||||
const response = await fetch(LOGIN_URL, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
username: 'admin',
|
||||
password: 'FAD888888'
|
||||
})
|
||||
})
|
||||
|
||||
const data = await response.json()
|
||||
|
||||
// 兼容多种返回格式
|
||||
const token = data.token || data.data?.token || data.data
|
||||
|
||||
if (token) {
|
||||
localStorage.setItem(STORAGE_KEY, token)
|
||||
console.log('[Auth] Token 获取成功')
|
||||
return token
|
||||
} else {
|
||||
console.warn('[Auth] 登录接口返回中未找到 token:', data)
|
||||
return null
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('[Auth] 自动登录失败:', err.message)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除 Token(登出时调用)
|
||||
*/
|
||||
export function clearToken() {
|
||||
localStorage.removeItem(STORAGE_KEY)
|
||||
}
|
||||
@@ -1,39 +1,33 @@
|
||||
import axios from 'axios'
|
||||
|
||||
// klp-oa线上API地址(测试环境)
|
||||
const baseURL = 'http://140.143.206.120:8080'
|
||||
// 走 Nginx 代理,同域名请求
|
||||
const baseURL = '/api'
|
||||
|
||||
const service = axios.create({
|
||||
baseURL: baseURL,
|
||||
timeout: 30000
|
||||
})
|
||||
|
||||
// 从 Cookies 获取 Token(与 klp-ui 保持一致)
|
||||
// Token 获取顺序:localStorage(自动登录) > Cookie(主系统登录)
|
||||
const getToken = () => {
|
||||
// 1. 优先取自动登录存的 token
|
||||
const localToken = localStorage.getItem('Admin-Token')
|
||||
if (localToken) return localToken
|
||||
|
||||
// 2. 其次从 Cookie 取(主系统登录)
|
||||
const name = 'Admin-Token'
|
||||
const value = `; ${document.cookie}`
|
||||
const parts = value.split(`; ${name}=`)
|
||||
if (parts.length === 2) return parts.pop().split(';').shift()
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
// 携带Token
|
||||
let token = getToken()
|
||||
|
||||
// ========== 测试用:临时硬编码 Token ==========
|
||||
// 如果没有从 Cookies 获取到 Token,使用测试 Token
|
||||
if (!token) {
|
||||
token = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJsb2dpblR5cGUiOiJsb2dpbiIsImxvZ2luSWQiOiJzeXNfdXNlcjoxIiwicm5TdHIiOiJGM2w5Nm5ncGV4ZDA4d1BUYWlvVmFreWhCUDdlc2gyeCIsInVzZXJJZCI6MX0.aP06S-5aJtukzMjmYW3d5zK3v10TOKcdNpROniv5lr8'
|
||||
}
|
||||
// ========== 测试用结束 ==========
|
||||
|
||||
console.log('请求URL:', config.url)
|
||||
console.log('使用的Token:', token ? '已设置' : '未设置')
|
||||
const token = getToken()
|
||||
|
||||
if (token) {
|
||||
// 直接使用Token(不带Bearer前缀)
|
||||
config.headers['Authorization'] = "Bearer " + token
|
||||
}
|
||||
return config
|
||||
|
||||
Reference in New Issue
Block a user