Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
C
custom-server
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lizhonghong
custom-server
Commits
7ad10679
Commit
7ad10679
authored
Jul 13, 2026
by
Lizh
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
docs: 添加 /api/v2 全量迁移设计文档
Co-Authored-By: Claude <noreply@anthropic.com>
parent
19bcc9c2
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
428 additions
and
0 deletions
+428
-0
docs/superpowers/specs/2026-07-13-api-v2-migration-design.md
+428
-0
No files found.
docs/superpowers/specs/2026-07-13-api-v2-migration-design.md
0 → 100644
View file @
7ad10679
# /api/v2 全量迁移设计文档
> **编制日期**:2026-07-13
> **来源项目**:`custom-back`(Spring Boot 2.5.15 / Java 8 / RuoYi)
> **目标项目**:`custom-server`(Spring Boot 4.0.5 / Java 17 / DDD)
> **迁移范围**:全部 64 个 `/api/v2` 端点
---
## 一、总体方案
### 执行顺序
```
Step 0 → Step 1 → Step 2 → Step 3 → Step 4
目录 P0 P1 P2 P3
重构 登录鉴权 RBAC Compose 仓库+国家
```
### 关键决策
| 决策 | 结论 |
|------|------|
| API 前缀 |
`/api/v2/*`
(与 custom-back 一致,前端无需改动) |
| 目录结构 | 迁移前先重构:controller/appService/domainService 按业务域分包 |
| 不迁移的功能 | 验证码、注册、监控、字典、配置、定时任务(不在 64 端点范围) |
| 数据权限
`@DataScope`
| 暂不实现,后续按需迁移 |
---
## 二、Step 0:目录重构
### 2.1 目标结构
**controller 层**
(
`custom-server-webapp`
):
```
webapp/controller/
├── product/
│ ├── CustomProductInfoController.java
│ ├── CustomProductItemController.java
│ ├── ProductTemplateInfoController.java
│ ├── SysBillRuleController.java
│ └── LogCustomProductController.java
├── system/ ← 迁移时新增
├── warehouse/ ← 迁移时新增
└── HealthController.java (保留顶层)
```
**app/service 层**
(
`custom-server-app`
):
```
app/service/
├── product/
│ ├── CustomProductInfoService.java
│ ├── CustomProductItemService.java
│ ├── ProductTemplateInfoService.java
│ ├── SysBillRuleService.java
│ ├── LogCustomProductService.java
│ ├── DiyUserService.java
│ └── impl/
├── system/ ← 迁移时新增
├── warehouse/ ← 迁移时新增
└── PermissionService.java (保留顶层)
```
**domain/service 层**
(
`custom-server-domain`
):
```
domain/service/
├── product/ (13 组:商品相关的 DomainService)
├── system/ (8 组:SysUser/SysRole/SysMenu/SysUserRole/SysRoleMenu/SysRoleDept/SysUserOld/SysBillRule)
├── diy/ (3 组:DbDiy/DbDiyXiaoguotu/DbDiyUser)
├── warehouse/ (2 组:CustomWarehouseInfo + CustomProductWarehouseRel)
└── misc/ (其余零散:CraftCenter/LogCustomProduct/LogProductTemplate/ProductFactoryRel)
```
**不调整的模块**
:
| 模块 | 原因 |
|------|------|
|
`domain/dal/entity`
| 33 个 Entity,与表一一对应,平铺更易查找 |
|
`domain/dal/mapper`
| 与 Entity 对应,平铺即可 |
|
`domain/resources/mapper`
| Mapper XML,平铺即可 |
|
`custom-server-core`
| 公共层,与业务域无关 |
|
`custom-server-integrate`
| 已有子包划分 |
|
`custom-server-starter/config`
| 全局 @Configuration,不按域拆分 |
### 2.2 改动量
| 动作 | 文件数 |
|------|--------|
| controller 移动 | 5 |
| app service 移动 | 6 组(12 文件) |
| domain service 移动 | 33 组(66 文件) |
| import 路径修正 | ~100 处 |
|
**总计**
|
**~83 文件移动**
|
---
## 三、Step 1:P0 登录鉴权(4 端点)
### 3.1 端点清单
| 方法 | URL | 说明 |
|------|-----|------|
| POST |
`/api/v2/login`
| 用户名密码登录,返回 JWT token |
| GET |
`/api/v2/getInfo`
| 获取当前用户信息 + 角色 + 权限 |
| GET |
`/api/v2/getRouters`
| 根据用户权限返回前端路由菜单 |
| POST |
`/api/v2/logout`
| 退出登录 |
### 3.2 新增/修改文件
| 文件 | 层 | 动作 |
|------|-----|------|
|
`core/.../security/TokenHandle.java`
| core | 修改:新增
`createToken(LoginUser)`
|
|
`starter/.../config/SecurityConfig.java`
| starter | 新增:
`PasswordEncoder`
Bean |
|
`app/service/system/SysLoginService.java`
| app | 新增:登录/登出/用户信息逻辑 |
|
`app/service/system/impl/SysLoginServiceImpl.java`
| app | 新增 |
|
`webapp/controller/system/SysLoginController.java`
| webapp | 新增 |
### 3.3 登录流程
```
POST /api/v2/login { username, password }
→ SysLoginService.login()
→ SysUserDomainService.getOne(Wrappers.lambdaQuery(SysUserEntity.class).eq(SysUserEntity::getUserName, username))
→ PasswordEncoder.matches(password, user.password)
→ SysMenuDomainService.selectMenuPermsByUserId(userId) // 查权限
→ SysRoleDomainService 查用户角色 // 已有
→ TokenHandle.createToken(loginUser) // 新增:JWT 生成
→ Redis 存储 login_tokens:{uuid} // custom-back 兼容
→ 返回 { "token": "..." }
```
### 3.4 Token 生成策略
custom-server 使用
**JJWT 0.12.x 标准格式**
生成新 token:
```
JWT Claims:
- id: userId
- account: username
- deptId: deptId
- permissions: ["system:user:list", ...]
- exp: 过期时间
签名: HS512,密钥 = token.secret("custom")
```
**兼容性**
:
`TokenCompatibilityParser`
已支持解析 custom-back 旧格式 token(从 Redis 或 JWT claims 读取),无需修改。
### 3.5 RouterVO 路由构建
`SysLoginService.getRouters()`
从
`sys_menu`
表查询菜单,递归构建
`RouterVO`
树:
```
RouterVO:
- name: String // 路由名称
- path: String // 路由路径
- component: String // 前端组件
- meta: MetaVO // { title, icon, isCache, isFrame }
- children: List<RouterVO>
构建规则:
- 过滤 menuType == 'F'(按钮),不显示在路由中
- isFrame == 1 → 外链,path 为完整 URL
- 按 parentId 递归构建父子树
- 按 orderNum 排序
```
### 3.6 不迁移的部分
-
`captchaImage`
(验证码)— 前端未使用
-
`register`
(注册)— 前端未使用
-
Spring Security 过滤器链 — custom-server 已有
`SecurityInterceptor`
体系
-
`@Anonymous`
注解 — 用
`server.needAuthentication`
配置控制
---
## 四、Step 2:P1 RBAC(46 端点)
### 4.1 已有基础
| 层 | 已有(直接复用) |
|----|------------------|
| Entity |
`SysUserEntity`
,
`SysRoleEntity`
,
`SysMenuEntity`
,
`SysUserRoleEntity`
,
`SysRoleMenuEntity`
,
`SysRoleDeptEntity`
|
| Mapper + XML | 对应 6 个 Mapper |
| DomainService |
`SysUserDomainService`
,
`SysRoleDomainService`
,
`SysMenuDomainService`
,
`SysUserRoleDomainService`
,
`SysRoleMenuDomainService`
,
`SysRoleDeptDomainService`
|
### 4.2 需要新建
#### 全栈新建(Entity → Mapper → DomainService → AppService → Controller)
| 模块 | Entity | 端点数 |
|------|--------|--------|
| 部门管理 |
`SysDeptEntity`
(
`sys_dept`
) | 6 |
| 岗位管理 |
`SysPostEntity`
(
`sys_post`
) | 5 |
| 用户-岗位关联 |
`SysUserPostEntity`
(
`sys_user_post`
) | — |
> `SysUserPostEntity` 用于用户-岗位多对多关联,custom-back 中有此表。
#### 补齐上层(AppService + Controller)
| 模块 | 端点数 |
|------|--------|
| 用户管理 | 14 |
| 角色管理 | 13 |
| 菜单管理 | 7 |
### 4.3 各 Controller 端点
#### SysUserController (`/api/v2/system/user`)
```
GET /list → 分页查询(deptId/userName/phonenumber/status 筛选)
GET /{userId} → 查询详情(含角色、岗位)
POST / → 新增(BCrypt 密码 + 角色/岗位关联)
PUT / → 修改(角色/岗位同步更新)
DELETE /{userIds} → 批量删除(逻辑删 delFlag = 1)
PUT /resetPwd → 重置密码
PUT /changeStatus → 状态切换
GET /profile → 个人信息
PUT /profile → 修改个人信息
PUT /profile/updatePwd → 修改密码(验证旧密码)
POST /profile/avatar → 头像上传
GET /authRole/{userId} → 已授权 + 未授权角色
PUT /authRole → 保存授权角色(先删后插)
GET /deptTree → 部门下拉树
```
#### SysRoleController (`/api/v2/system/role`)
```
GET /list → 分页查询
GET /{roleId} → 查询详情
POST / → 新增(含 role_menu 关联)
PUT / → 修改(含 role_menu 更新)
PUT /dataScope → 数据权限(更新 role_dept)
PUT /changeStatus → 状态切换
DELETE /{roleIds} → 批量删除
GET /authUser/allocatedList → 已授权用户分页
GET /authUser/unallocatedList → 未授权用户分页
PUT /authUser/cancel → 取消单个授权
PUT /authUser/cancelAll → 批量取消授权
PUT /authUser/selectAll → 批量授权
GET /deptTree/{roleId} → 角色部门树
```
#### SysMenuController (`/api/v2/system/menu`)
```
GET /list → 菜单树列表
GET /{menuId} → 详情
GET /treeselect → 菜单下拉树
GET /roleMenuTreeselect/{roleId} → 角色菜单树(含 checkedKeys)
POST / → 新增
PUT / → 修改
DELETE /{menuId} → 删除(检测子菜单)
```
#### SysDeptController (`/api/v2/system/dept`)
```
GET /list → 部门树
GET /list/exclude/{deptId} → 排除节点的部门树
GET /{deptId} → 详情
POST / → 新增
PUT / → 修改
DELETE /{deptId} → 删除(检测子部门 + 用户)
```
#### SysPostController (`/api/v2/system/post`)
```
GET /list → 分页查询
GET /{postId} → 详情
POST / → 新增
PUT / → 修改
DELETE /{postIds} → 批量删除
```
### 4.4 文件清单
```
新增 Entity: SysDeptEntity, SysPostEntity, SysUserPostEntity
新增 Mapper: SysDeptMapper, SysPostMapper, SysUserPostMapper + 3 XML
新增 DomainSvc: SysDeptDomainService, SysPostDomainService + 2 Impl
新增 AppSvc: SysUserService, SysRoleService, SysMenuService,
SysDeptService, SysPostService + 5 Impl
新增 VO/DTO: ~10 个
新增 Controller: 5 个
总计:~40 个新文件
```
---
## 五、Step 3:P2 ComposeServer + Log(8 端点)
### 5.1 端点清单
#### SysComposeServerController (`/api/v2/system/composeServer`)
```
POST /list → 分页查询(含 status0Count/status1Count 统计)
POST /add → 新增(校验 title/host 非空)
POST /updateById → 修改
GET /deleteById?id={id} → 删除
GET /updateStatusById?id={id}&status= → 状态切换
GET /getAllServerHost → 全部主机地址
```
#### SysComposeServerLogController (`/api/v2/system/composeServerLog`)
```
POST /list → 分页查询(composeServerId/status 筛选,JOIN host)
POST /deleteByIdList → 批量删除
```
### 5.2 新建内容
```
新增 Entity: SysComposeServerEntity, SysComposeServerLogEntity
新增 Mapper: SysComposeServerMapper, SysComposeServerLogMapper + 2 XML
新增 DomainSvc: 接口 + Impl × 2 = 4
新增 AppSvc: SysComposeServerService + Impl, SysComposeServerLogService + Impl
新增 VO: 按需
新增 Controller: SysComposeServerController, SysComposeServerLogController
总计:~16 个新文件
```
### 5.3 修正 custom-back 中的问题
| 问题 | 修正 |
|------|------|
|
`SysComposeServerLogMapper.deleteByIdList`
SQL 误删
`compose_server`
表 | 正确删除
`compose_server_log`
表 |
|
`selectServerLogList`
的
`getServerLogById`
参数命名误导 | 正确命名为
`id`
|
| 删除 Server 时未级联删除 Log | 删除 Server 时同步删除关联 Log |
---
## 六、Step 4:P3 CountryCode + Warehouse(6 端点)
### 6.1 CountryCode(2 端点)
```
GET /api/v2/countryCode/map → Map<String, String> (countryCode → nameCn)
GET /api/v2/countryCode/all → List<BaseCountryCodeVO>
```
**数据来源**
:对接外部 manage 服务 API + Redis 缓存(与 custom-back 一致),复用
`custom-server-integrate`
模块的 WebClient 模式。
```
Controller → AppService → integrate/SaasAdminService (新增方法) → 外部 API
→ Redis 缓存 1h
```
**新建文件**
(~8 个):
```
新增 integrate: SaasAdminService 新增 getCountryCodeAll() 方法
新增 VO: BaseCountryCodeVO
新增 AppSvc: BaseCountryCodeService + Impl
新增 Controller: BaseCountryCodeController
```
### 6.2 Warehouse(5 端点)
```
GET /api/v2/customWarehouse/statusList → 状态枚举
GET /api/v2/customWarehouse/list → 分页查询
POST /api/v2/customWarehouse → 新增
PUT /api/v2/customWarehouse → 修改
DELETE /api/v2/customWarehouse/{ids} → 批量删除
```
**已有基础**
:Entity、Mapper、DomainService 均已存在。
**新建文件**
(~4 个):
```
新增 AppSvc: CustomWarehouseInfoService + Impl
新增 Controller: CustomWarehouseInfoController
```
> custom-back 中还有 6 个 `/rest/customWarehouse/*` 对外 REST API,不在本次迁移范围。
---
## 七、关键技术对齐
| 差异点 | custom-back | custom-server |
|--------|-------------|---------------|
| 响应格式 |
`AjaxResult`
+
`TableDataInfo`
|
`R<T>`
+
`IPage<T>`
|
| 分页 |
`PageHelper.startPage()`
| MyBatis-Plus
`Page<T>`
|
| 鉴权 |
`@PreAuthorize("@ss.hasPermi(...)")`
|
`@RequiresPermissions("...")`
|
| JWT 生成 | JJWT 0.9.1 旧格式 | JJWT 0.12.x 标准格式 |
| JWT 解析 | 仅旧格式 |
`TokenCompatibilityParser`
兼容新旧 |
| 密码 | Spring Security BCryptPasswordEncoder | 新增
`PasswordEncoder`
Bean |
| 实体映射 | 手动 getter/setter |
`BeanMapper`
(Jackson SNAKE_CASE) |
| 数据权限 |
`@DataScope`
AOP + SQL 注入 | 暂不实现 |
| 外部 HTTP |
`RestTemplate`
|
`WebClient`
(integrate 模块已有) |
---
## 八、文件统计
| 步骤 | 内容 | 新建文件 | 修改文件 | 移动文件 |
|------|------|----------|----------|----------|
| Step 0 | 目录重构 | 0 | 0 | ~83 |
| Step 1 | P0 登录鉴权 | ~8 | 2 | 0 |
| Step 2 | P1 RBAC | ~40 | 0 | 0 |
| Step 3 | P2 ComposeServer | ~16 | 0 | 0 |
| Step 4 | P3 CountryCode + Warehouse | ~12 | 0 | 0 |
|
**合计**
| |
**~76**
|
**2**
|
**~83**
|
---
## 九、风险与对策
| 风险 | 对策 |
|------|------|
| 目录重构导致编译错误 | 重构完成后立即
`mvn compile`
验证 |
| JJWT 新格式 token 不被 custom-back 识别 | 两套系统独立运行,不影响;
`TokenCompatibilityParser`
已兼容旧格式读取 |
| 密码编码器不兼容 | 新生成的密码用 BCrypt 编码,旧密码(custom-back 也是 BCrypt)直接兼容 |
| 前端 baseURL 指向 | 前端
`requestV2.ts`
的 baseURL 已指向
`/api/v2`
,迁移后无变化 |
| 体量较大(64 端点) | 按 Step 0-4 分步执行,每步完成后验证 |
| CountryCode 外部服务不可用 | Redis 缓存 1 小时降级,返回缓存数据 |
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment