- 重构sys模块架构,严格按admin/api/core分层 - 对齐所有sys实体与数据库表结构 - 实现完整的adminapi控制器,匹配PHP/Java契约 - 修复依赖注入问题,确保服务正确注册 - 添加自动迁移工具和契约验证 - 完善多租户支持和审计功能 - 统一命名规范,与PHP业务逻辑保持一致
346 lines
9.2 KiB
Markdown
346 lines
9.2 KiB
Markdown
# 共享前端验证NestJS后端迁移方案
|
||
|
||
## 🎯 方案概述
|
||
|
||
使用PHP框架的现有前端(Vue.js + Element Plus)来验证NestJS后端API的完整性和兼容性,确保功能迁移的准确性。
|
||
|
||
## 🏗️ 技术架构
|
||
|
||
```
|
||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||
│ Vue.js前端 │ │ NestJS后端 │ │ 共享数据库 │
|
||
│ (niucloud-php) │◄──►│ (wwjcloud) │◄──►│ (MySQL) │
|
||
│ │ │ │ │ │
|
||
│ • 管理后台界面 │ │ • RESTful API │ │ • 业务数据 │
|
||
│ • 用户端界面 │ │ • 认证授权 │ │ • 配置数据 │
|
||
│ • 移动端应用 │ │ • 业务逻辑 │ │ • 用户数据 │
|
||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||
```
|
||
|
||
## 🔧 实施步骤
|
||
|
||
### Step 1: 配置前端API端点
|
||
|
||
#### 1.1 创建环境配置文件
|
||
|
||
在 `niucloud-php/admin/` 目录下创建以下环境配置文件:
|
||
|
||
**`.env.development`**
|
||
```bash
|
||
# 开发环境配置 - 连接NestJS后端
|
||
VITE_APP_BASE_URL=http://localhost:3000
|
||
VITE_REQUEST_HEADER_TOKEN_KEY=Authorization
|
||
VITE_REQUEST_HEADER_SITEID_KEY=site-id
|
||
VITE_APP_TITLE=NiuCloud Admin (NestJS Backend)
|
||
VITE_APP_VERSION=v0.3.0
|
||
```
|
||
|
||
**`.env.production`**
|
||
```bash
|
||
# 生产环境配置
|
||
VITE_APP_BASE_URL=https://your-nestjs-domain.com
|
||
VITE_REQUEST_HEADER_TOKEN_KEY=Authorization
|
||
VITE_REQUEST_HEADER_SITEID_KEY=site-id
|
||
VITE_APP_TITLE=NiuCloud Admin (NestJS Backend)
|
||
VITE_APP_VERSION=v0.3.0
|
||
```
|
||
|
||
#### 1.2 修改请求拦截器
|
||
|
||
需要修改 `niucloud-php/admin/src/utils/request.ts` 中的响应处理逻辑:
|
||
|
||
```typescript
|
||
// 修改响应拦截器以兼容NestJS响应格式
|
||
this.instance.interceptors.response.use(
|
||
(response: requestResponse) => {
|
||
if (response.request.responseType != 'blob') {
|
||
const res = response.data
|
||
// NestJS使用 code: 0 表示成功,PHP使用 code: 1
|
||
if (res.code !== 0 && res.code !== 1) {
|
||
this.handleAuthError(res.code)
|
||
if (res.code != 401 && response.config.showErrorMessage !== false) {
|
||
this.showElMessage({
|
||
message: res.message || res.msg,
|
||
type: 'error',
|
||
dangerouslyUseHTMLString: true,
|
||
duration: 5000
|
||
})
|
||
}
|
||
return Promise.reject(new Error(res.message || res.msg || 'Error'))
|
||
} else {
|
||
if (response.config.showSuccessMessage) {
|
||
ElMessage({
|
||
message: res.message || res.msg,
|
||
type: 'success'
|
||
})
|
||
}
|
||
return res
|
||
}
|
||
}
|
||
return response.data
|
||
},
|
||
(err: any) => {
|
||
this.handleNetworkError(err)
|
||
return Promise.reject(err)
|
||
}
|
||
)
|
||
```
|
||
|
||
### Step 2: API路由映射
|
||
|
||
#### 2.1 创建API路由映射表
|
||
|
||
创建 `niucloud-php/admin/src/config/api-mapping.ts`:
|
||
|
||
```typescript
|
||
// API路由映射配置
|
||
export const API_MAPPING = {
|
||
// 系统管理
|
||
'sys/role': 'admin/sys/role',
|
||
'sys/menu': 'admin/sys/menu',
|
||
'sys/config': 'admin/sys/config',
|
||
'sys/area': 'admin/sys/area',
|
||
'sys/attachment': 'admin/sys/attachment',
|
||
'sys/schedule': 'admin/sys/schedule',
|
||
'sys/agreement': 'admin/sys/agreement',
|
||
|
||
// 站点管理
|
||
'site/site': 'admin/site/site',
|
||
'site/user': 'admin/site/user',
|
||
'site/group': 'admin/site/group',
|
||
|
||
// 会员管理
|
||
'member/member': 'admin/member/member',
|
||
'member/level': 'admin/member/level',
|
||
'member/address': 'admin/member/address',
|
||
|
||
// 支付管理
|
||
'pay/pay': 'admin/pay/pay',
|
||
'pay/channel': 'admin/pay/channel',
|
||
'pay/transfer': 'adminapi/pay/transfer',
|
||
|
||
// 微信管理
|
||
'wechat/config': 'admin/wechat/config',
|
||
'wechat/menu': 'admin/wechat/menu',
|
||
'wechat/template': 'admin/wechat/template',
|
||
|
||
// 小程序管理
|
||
'weapp/config': 'admin/weapp/config',
|
||
'weapp/version': 'admin/weapp/version',
|
||
|
||
// 插件管理
|
||
'addon/addon': 'adminapi/addon/addon',
|
||
'addon/backup': 'adminapi/addon/backup',
|
||
|
||
// 认证相关
|
||
'auth/login': 'adminapi/auth/login',
|
||
'auth/captcha': 'adminapi/auth/captcha',
|
||
|
||
// 文件上传
|
||
'upload/upload': 'adminapi/upload/upload',
|
||
'upload/storage': 'adminapi/upload/storage',
|
||
}
|
||
|
||
// API路由转换函数
|
||
export function mapApiRoute(originalRoute: string): string {
|
||
return API_MAPPING[originalRoute] || originalRoute
|
||
}
|
||
```
|
||
|
||
#### 2.2 修改API调用
|
||
|
||
修改 `niucloud-php/admin/src/app/api/sys.ts` 等API文件:
|
||
|
||
```typescript
|
||
import { mapApiRoute } from '@/config/api-mapping'
|
||
|
||
// 修改所有API调用
|
||
export function getRoleList(params: Record<string, any>) {
|
||
return request.get(mapApiRoute('sys/role'), { params })
|
||
}
|
||
|
||
export function addRole(params: Record<string, any>) {
|
||
return request.post(mapApiRoute('sys/role'), params, { showSuccessMessage: true })
|
||
}
|
||
```
|
||
|
||
### Step 3: 认证适配
|
||
|
||
#### 3.1 修改认证头
|
||
|
||
在 `niucloud-php/admin/src/utils/request.ts` 中修改请求头:
|
||
|
||
```typescript
|
||
// 全局请求拦截器
|
||
this.instance.interceptors.request.use(
|
||
(config: InternalRequestConfig) => {
|
||
// 携带token和site-id
|
||
if (getToken()) {
|
||
// NestJS使用 Bearer token 格式
|
||
config.headers[import.meta.env.VITE_REQUEST_HEADER_TOKEN_KEY] = `Bearer ${getToken()}`
|
||
}
|
||
config.headers[import.meta.env.VITE_REQUEST_HEADER_SITEID_KEY] = storage.get('siteId') || 0
|
||
return config
|
||
},
|
||
(err: any) => {
|
||
return Promise.reject(err)
|
||
}
|
||
)
|
||
```
|
||
|
||
#### 3.2 修改认证错误处理
|
||
|
||
```typescript
|
||
private handleAuthError(code: number) {
|
||
switch (code) {
|
||
case 401:
|
||
// NestJS返回401时跳转到登录页
|
||
useUserStore().logout()
|
||
break;
|
||
case 403:
|
||
// 权限不足
|
||
this.showElMessage({
|
||
message: '权限不足',
|
||
type: 'error'
|
||
})
|
||
break;
|
||
}
|
||
}
|
||
```
|
||
|
||
### Step 4: 数据格式适配
|
||
|
||
#### 4.1 响应数据格式转换
|
||
|
||
创建 `niucloud-php/admin/src/utils/data-adapter.ts`:
|
||
|
||
```typescript
|
||
// 数据格式适配器
|
||
export class DataAdapter {
|
||
// 转换分页数据格式
|
||
static adaptPaginationData(nestjsData: any) {
|
||
return {
|
||
data: nestjsData.data || nestjsData.list || [],
|
||
total: nestjsData.total || 0,
|
||
page: nestjsData.page || 1,
|
||
limit: nestjsData.limit || 10
|
||
}
|
||
}
|
||
|
||
// 转换列表数据格式
|
||
static adaptListData(nestjsData: any) {
|
||
return nestjsData.data || nestjsData.list || nestjsData
|
||
}
|
||
|
||
// 转换详情数据格式
|
||
static adaptDetailData(nestjsData: any) {
|
||
return nestjsData.data || nestjsData
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 4.2 在API调用中使用适配器
|
||
|
||
```typescript
|
||
import { DataAdapter } from '@/utils/data-adapter'
|
||
|
||
export function getRoleList(params: Record<string, any>) {
|
||
return request.get(mapApiRoute('sys/role'), { params })
|
||
.then(res => DataAdapter.adaptPaginationData(res))
|
||
}
|
||
```
|
||
|
||
### Step 5: 启动和测试
|
||
|
||
#### 5.1 启动NestJS后端
|
||
|
||
```bash
|
||
cd wwjcloud
|
||
npm run start:dev
|
||
```
|
||
|
||
#### 5.2 启动Vue.js前端
|
||
|
||
```bash
|
||
cd niucloud-php/admin
|
||
npm run dev
|
||
```
|
||
|
||
#### 5.3 测试验证
|
||
|
||
1. **基础功能测试**
|
||
- 用户登录/登出
|
||
- 菜单加载
|
||
- 权限验证
|
||
|
||
2. **业务功能测试**
|
||
- 系统配置管理
|
||
- 用户角色管理
|
||
- 站点管理
|
||
- 会员管理
|
||
|
||
3. **数据一致性测试**
|
||
- 数据CRUD操作
|
||
- 分页查询
|
||
- 数据验证
|
||
|
||
## 📊 验证清单
|
||
|
||
### ✅ 基础功能验证
|
||
- [ ] 用户认证和授权
|
||
- [ ] 菜单和路由加载
|
||
- [ ] 权限控制
|
||
- [ ] 文件上传下载
|
||
|
||
### ✅ 业务功能验证
|
||
- [ ] 系统配置管理
|
||
- [ ] 用户角色管理
|
||
- [ ] 站点管理
|
||
- [ ] 会员管理
|
||
- [ ] 支付管理
|
||
- [ ] 微信集成
|
||
- [ ] 小程序管理
|
||
|
||
### ✅ 数据一致性验证
|
||
- [ ] 数据CRUD操作
|
||
- [ ] 分页查询
|
||
- [ ] 数据验证
|
||
- [ ] 错误处理
|
||
|
||
### ✅ 性能验证
|
||
- [ ] 接口响应时间
|
||
- [ ] 数据加载速度
|
||
- [ ] 并发处理能力
|
||
|
||
## 🚨 注意事项
|
||
|
||
1. **响应格式差异**
|
||
- PHP: `{ code: 1, data: {}, msg: '' }`
|
||
- NestJS: `{ code: 0, data: {}, message: '' }`
|
||
|
||
2. **认证方式差异**
|
||
- PHP: 直接token
|
||
- NestJS: Bearer token
|
||
|
||
3. **错误处理差异**
|
||
- 需要统一错误码和错误信息格式
|
||
|
||
4. **数据格式差异**
|
||
- 需要适配分页、列表等数据格式
|
||
|
||
## 🎯 预期结果
|
||
|
||
通过这个方案,我们可以:
|
||
|
||
1. **验证API完整性** - 确保所有前端功能都有对应的后端API
|
||
2. **验证数据一致性** - 确保数据格式和业务逻辑一致
|
||
3. **验证功能完整性** - 确保所有业务功能正常工作
|
||
4. **验证性能表现** - 确保系统性能满足要求
|
||
|
||
## 📈 后续计划
|
||
|
||
1. **完善缺失功能** - 根据验证结果补充缺失的API
|
||
2. **优化性能** - 根据测试结果优化系统性能
|
||
3. **完善文档** - 更新API文档和使用说明
|
||
4. **部署上线** - 完成验证后部署到生产环境
|