268 lines
5.6 KiB
Markdown
268 lines
5.6 KiB
Markdown
# Nginx单点登录配置说明
|
||
|
||
## 架构概述
|
||
|
||
本系统使用 **Platform** 作为统一入口和单点登录服务,其他服务(Workcase、Bidding)通过 Nginx 代理访问。
|
||
|
||
## 访问方式
|
||
|
||
### 开发环境(推荐通过Nginx访问)
|
||
|
||
1. **启动Nginx**
|
||
```bash
|
||
# Windows
|
||
cd f:\Environment\Nginx\nginx-1.28.0
|
||
start nginx
|
||
```
|
||
|
||
2. **启动各服务**
|
||
```bash
|
||
# Platform (5001端口)
|
||
pnpm --filter platform dev
|
||
|
||
# Workcase (5003端口)
|
||
pnpm --filter workcase dev
|
||
|
||
# Bidding (5002端口)
|
||
pnpm --filter bidding dev
|
||
|
||
# 后端API (8180端口)
|
||
# 启动Spring Boot应用
|
||
```
|
||
|
||
3. **访问地址**
|
||
- **统一入口**: http://localhost (Nginx 80端口)
|
||
- Platform: http://localhost/
|
||
- Workcase: http://localhost/workcase
|
||
- Bidding: http://localhost/bidding
|
||
- 后端API: http://localhost/api
|
||
|
||
### 生产环境
|
||
|
||
与开发环境配置完全一致,只需将各服务构建后部署即可。
|
||
|
||
```bash
|
||
# 构建所有服务
|
||
pnpm build
|
||
|
||
# Nginx配置已经就绪,直接启动即可
|
||
```
|
||
|
||
## Nginx配置详解
|
||
|
||
### 核心配置 (nginx.conf)
|
||
|
||
```nginx
|
||
# Platform 主应用(单点登录入口)
|
||
location / {
|
||
proxy_pass http://localhost:5001/;
|
||
}
|
||
|
||
# Workcase 工单服务
|
||
location /workcase/ {
|
||
proxy_pass http://localhost:5003/;
|
||
}
|
||
|
||
# Bidding 招标服务
|
||
location /bidding/ {
|
||
proxy_pass http://localhost:5002/;
|
||
}
|
||
|
||
# 后端 API 统一入口
|
||
location /api/ {
|
||
proxy_pass http://localhost:8180/;
|
||
}
|
||
```
|
||
|
||
## 单点登录流程
|
||
|
||
### 1. 用户访问流程
|
||
|
||
```
|
||
用户访问 http://localhost
|
||
↓
|
||
Nginx代理到 Platform (5001)
|
||
↓
|
||
Platform检查token
|
||
↓
|
||
未登录 → 显示登录页
|
||
已登录 → 显示主页和菜单
|
||
```
|
||
|
||
### 2. 子服务访问流程
|
||
|
||
```
|
||
用户点击"泰豪小电"菜单
|
||
↓
|
||
Platform iframe加载 http://localhost/workcase
|
||
↓
|
||
Nginx代理到 Workcase (5003)
|
||
↓
|
||
Workcase从LocalStorage读取token
|
||
↓
|
||
有token → 加载workcase路由
|
||
无token → 重定向到 /login (Platform登录页)
|
||
```
|
||
|
||
### 3. Token共享机制
|
||
|
||
所有服务共享同一个LocalStorage(因为都在同一个域名下),因此:
|
||
|
||
- **Token存储**: `localStorage.setItem('token', ...)`
|
||
- **用户信息**: `localStorage.setItem('loginDomain', ...)`
|
||
- **视图数据**: `loginDomain.userViews`
|
||
|
||
每个服务根据 `service` 字段筛选自己的视图:
|
||
```typescript
|
||
// Workcase筛选
|
||
const workcaseViews = allViews.filter(view => view.service === 'workcase')
|
||
|
||
// Platform筛选
|
||
const platformViews = allViews.filter(view => view.service === 'platform')
|
||
```
|
||
|
||
## 配置文件
|
||
|
||
### 1. Shared配置 (`packages/shared/src/config/index.ts`)
|
||
|
||
```typescript
|
||
sso: {
|
||
platformUrl: '/', // Platform地址(相对路径)
|
||
workcaseUrl: '/workcase', // Workcase地址
|
||
biddingUrl: '/bidding' // Bidding地址
|
||
}
|
||
```
|
||
|
||
### 2. App-config.js(各服务)
|
||
|
||
**Platform** (`packages/platform/public/app-config.js`):
|
||
```javascript
|
||
sso: {
|
||
platformUrl: '/',
|
||
workcaseUrl: '/workcase',
|
||
biddingUrl: '/bidding'
|
||
}
|
||
```
|
||
|
||
**Workcase** (`packages/workcase/public/app-config.js`):
|
||
```javascript
|
||
sso: {
|
||
platformUrl: '/',
|
||
workcaseUrl: '/workcase',
|
||
biddingUrl: '/bidding'
|
||
}
|
||
```
|
||
|
||
## 路由配置
|
||
|
||
### Workcase路由守卫
|
||
|
||
```typescript
|
||
// 未登录重定向到Platform登录页
|
||
if (requiresAuth && !hasToken) {
|
||
const platformUrl = APP_CONFIG.sso?.platformUrl || '/'
|
||
const loginPath = platformUrl.endsWith('/')
|
||
? `${platformUrl}login`
|
||
: `${platformUrl}/login`
|
||
const platformLoginUrl = `${loginPath}?redirect=${encodeURIComponent(window.location.href)}`
|
||
window.location.href = platformLoginUrl
|
||
}
|
||
```
|
||
|
||
### 动态路由加载
|
||
|
||
```typescript
|
||
// 从LocalStorage加载并筛选本服务的视图
|
||
const allViews = loadViewsFromStorage('loginDomain', 'userViews')
|
||
const workcaseViews = allViews.filter(view => view.service === 'workcase')
|
||
addDynamicRoutes(workcaseViews)
|
||
```
|
||
|
||
## 数据库配置
|
||
|
||
### 视图表service字段
|
||
|
||
确保 `tb_sys_view` 表的视图数据正确设置了 `service` 字段:
|
||
|
||
```sql
|
||
-- Platform视图
|
||
('VIEW-P001', 'view_platform_home', '全部应用', NULL, '/agents', ...,
|
||
'route', NULL, 'platform', 'SidebarLayout', ...)
|
||
|
||
-- Workcase视图
|
||
('VIEW-W001', 'view_workcase_home', '工单首页', NULL, '/home', ...,
|
||
'route', NULL, 'workcase', 'SidebarLayout', ...)
|
||
|
||
-- Bidding视图
|
||
('VIEW-B001', 'view_bidding_home', '首页', NULL, '/home', ...,
|
||
'route', NULL, 'bidding', 'DefaultLayout', ...)
|
||
```
|
||
|
||
## 开发建议
|
||
|
||
### 方式一:通过Nginx访问(推荐)
|
||
|
||
**优点**:
|
||
- 与生产环境完全一致
|
||
- 测试单点登录功能
|
||
- 避免跨域问题
|
||
|
||
**配置**:
|
||
- 所有服务使用相对路径 `/`, `/workcase`, `/bidding`
|
||
- 通过 http://localhost 访问
|
||
|
||
### 方式二:直接访问各服务端口
|
||
|
||
**优点**:
|
||
- 独立开发调试
|
||
- HMR更快
|
||
|
||
**配置**:
|
||
- 修改 `devConfig.sso` 为绝对URL
|
||
```typescript
|
||
sso: {
|
||
platformUrl: 'http://localhost:5001',
|
||
workcaseUrl: 'http://localhost:5003',
|
||
biddingUrl: 'http://localhost:5002'
|
||
}
|
||
```
|
||
- 直接访问 http://localhost:5001, http://localhost:5003
|
||
|
||
## 常见问题
|
||
|
||
### 1. 登录后跳转到错误的地址
|
||
|
||
**原因**: `platformUrl` 配置不正确
|
||
|
||
**解决**: 检查 `app-config.js` 中的 `sso.platformUrl` 配置
|
||
|
||
### 2. Token无法共享
|
||
|
||
**原因**: 不同端口访问导致LocalStorage隔离
|
||
|
||
**解决**: 统一通过Nginx访问(http://localhost)
|
||
|
||
### 3. Nginx无法启动
|
||
|
||
**检查**:
|
||
- 80端口是否被占用
|
||
- nginx.conf配置是否正确
|
||
|
||
### 4. 子服务路由404
|
||
|
||
**检查**:
|
||
- Vite配置中的 `base` 是否正确设置
|
||
- Workcase: `base: '/workcase'`
|
||
- Bidding: `base: '/bidding'`
|
||
|
||
## 重启服务
|
||
|
||
```bash
|
||
# 重启Nginx(Windows)
|
||
nginx -s reload
|
||
|
||
# 或完全重启
|
||
nginx -s quit
|
||
start nginx
|
||
```
|