# 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:7001/;
}

# Workcase 工单服务
location /workcase/ {
    proxy_pass http://localhost:7003/;
}

# Bidding 招标服务
location /bidding/ {
    proxy_pass http://localhost:7002/;
}

# 后端 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:7001',
    workcaseUrl: 'http://localhost:7003',
    biddingUrl: 'http://localhost:7002'
  }
  ```
- 直接访问 http://localhost:7001, http://localhost:7003

## 常见问题

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