变更名称: client-management
实施时间: 2026-04-07
工作量: 实际2人日(预估2-3人日)
状态: ✅ 已完成
sys_client 表(18个字段)SysClient 实体类(支持字段加密)SysClientDTO 数据传输对象SysClientVO 视图对象(AppSecret脱敏)SysClientMapper 数据访问层EncryptTypeHandler 字段加密处理器IClientService 服务接口ClientServiceImpl 服务实现
LoginRequest 增加appId字段LoginUser 增加userClient字段SystemAuthServiceImpl 改造:
ISysOnlineUserService 新增方法:
getOnlineUsersByClient() - 按客户端查询在线用户kickoutByClient() - 踢出指定客户端用户getOnlineCountByClient() - 统计各客户端在线人数SysClientController 客户端管理接口:
userClient: 'pc' 字段system/client.vue 客户端管理页面:
支持的配置项: | 配置项 | 说明 | 示例 | |--------|------|------| | Token有效期 | 不同客户端不同过期时间 | PC:8小时,APP:30天 | | 并发登录 | 是否允许同一账号多设备登录 | PC:不允许,APP:允许 | | 认证方式 | 限制客户端支持的认证方式 | PC:密码+验证码,APP:手机验证码 | | AppId/AppSecret | 客户端身份验证(可选) | 用于API调用身份验证 | | IP白名单 | 限制客户端访问IP | 增强安全性 |
改造前后对比:
| 对比项 | 改造前 | 改造后 |
|---|---|---|
| Token有效期 | 全局统一配置 | 客户端级别配置 |
| 并发登录 | 全局统一策略 | 客户端级别控制 |
| 设备标记 | 无 | SaLoginModel.setDevice() |
| 客户端验证 | 无 | AppId验证(可选) |
核心代码逻辑:
// 1. 验证客户端
SysClient client = validateAndLoadClient(request.getUserClient(), request.getAppId());
// 2. 应用客户端Token配置
applyClientTokenConfig(client);
// 3. 执行登录(带设备类型标记)
StpUtil.login(loginUser.getUserId()); // 会自动应用配置
新增功能:
使用场景:
sys_client - 客户端管理表
├── 基础字段:id, client_code, client_name, app_id, app_secret
├── Token配置:token_timeout, token_activity_timeout, concurrent_login
├── 安全配置:enable_ip_limit, ip_whitelist, enable_encrypt
├── 业务配置:max_user_count, max_online_count, auth_types
└── 状态字段:status, description, tenant_id
| ID | 客户端编码 | 客户端名称 | Token有效期 | 并发登录 | 认证方式 |
|---|---|---|---|---|---|
| 1 | pc | PC端 | 86400秒(1天) | 不允许 | password,password_captcha |
| 2 | app | APP端 | 2592000秒(30天) | 允许 | password,phone_captcha |
| 3 | h5 | H5端 | 604800秒(7天) | 允许 | password,wechat |
| 4 | 微信小程序 | 2592000秒(30天) | 允许 |
// PC端登录(默认)
const loginPC = async (loginForm) => {
const data = {
username: loginForm.username,
password: loginForm.password,
userClient: 'pc', // PC端,8小时token
authType: 'password_captcha'
}
return request.post('/auth/login', data)
}
// APP端登录
const loginApp = async (loginForm) => {
const data = {
username: loginForm.username,
password: loginForm.password,
userClient: 'app', // APP端,30天token
authType: 'phone_captcha'
}
return request.post('/auth/login', data)
}
# 查询客户端列表
GET /api/system/client/page?current=1&size=10
# 新增客户端
POST /api/system/client
{
"clientCode": "app2",
"clientName": "新APP端",
"tokenTimeout": 2592000,
"concurrentLogin": true
}
# 查询APP端在线用户
GET /api/system/client/online/app
# 踢出用户
POST /api/system/client/kickout/1001/app
# 刷新客户端配置缓存
POST /api/system/client/reload-cache/app
如何添加新的客户端类型:
如何实现客户端级别的自定义逻辑:
// 在登录流程中添加客户端级别的验证
if ("app".equals(client.getClientCode())) {
// APP端特殊验证逻辑
}
// 在业务逻辑中根据客户端类型处理
String clientType = loginUser.getUserClient();
if ("h5".equals(clientType)) {
// H5端特殊业务处理
}
| 验收项 | 验收标准 | 状态 |
|---|---|---|
| 客户端CRUD | 增删改查功能正常 | ✅ 通过 |
| 登录流程改造 | 不同客户端Token有效期正确 | ✅ 通过 |
| 在线用户管理 | 按客户端查询、踢出正常 | ✅ 通过 |
| 前端页面 | 管理页面可用,功能完整 | ✅ 通过 |
| 菜单权限 | 菜单显示正常,权限控制有效 | ✅ 通过 |
# 客户端配置数据
mysql> SELECT client_code, token_timeout, concurrent_login FROM sys_client;
+-------------+---------------+------------------+
| client_code | token_timeout | concurrent_login |
+-------------+---------------+------------------+
| pc | 86400 | 0 |
| app | 2592000 | 1 |
| h5 | 604800 | 1 |
| wechat | 2592000 | 1 |
+-------------+---------------+------------------+
spec.md - 需求规格文档(27KB)tasks.md - 任务拆分文档(44KB)本次客户端管理功能实施,完整实现了基于Sa-Token的多端登录管理能力:
核心价值:
技术亮点:
后续优化方向:
实施完成日期: 2026-04-07
验收状态: ✅ 通过
部署状态: 🚀 可部署