fix: 修复Token管理、代码生成模板及文档问题
This commit is contained in:
@@ -162,7 +162,7 @@ youlai-boot/
|
|||||||
| **📖 完整文档站** | [docs.youlai.tech](https://www.youlai.tech/docs/admin/) |
|
| **📖 完整文档站** | [docs.youlai.tech](https://www.youlai.tech/docs/admin/) |
|
||||||
| **🖥️ 在线预览(前端)** | [vue.youlai.tech](https://vue.youlai.tech) |
|
| **🖥️ 在线预览(前端)** | [vue.youlai.tech](https://vue.youlai.tech) |
|
||||||
| **📱 在线预览(移动端)** | [app.youlai.tech](https://app.youlai.tech) |
|
| **📱 在线预览(移动端)** | [app.youlai.tech](https://app.youlai.tech) |
|
||||||
| **🔗 接口文档** | 启动后访问 `/doc.html` |
|
| **🔗 接口文档** | 启动后访问 [http://localhost:8000/doc.html](http://localhost:8000/doc.html) |
|
||||||
|
|
||||||
## 📊 项目统计
|
## 📊 项目统计
|
||||||
|
|
||||||
|
|||||||
@@ -323,6 +323,7 @@ public class CodegenServiceImpl implements CodegenService {
|
|||||||
bindMap.put("entityKebab", entityKebab);
|
bindMap.put("entityKebab", entityKebab);
|
||||||
bindMap.put("entityUpperSnake", entityUpperSnake);
|
bindMap.put("entityUpperSnake", entityUpperSnake);
|
||||||
bindMap.put("businessName", genTable.getBusinessName());
|
bindMap.put("businessName", genTable.getBusinessName());
|
||||||
|
bindMap.put("entityComment", genTable.getBusinessName());
|
||||||
bindMap.put("fieldConfigs", fieldConfigs);
|
bindMap.put("fieldConfigs", fieldConfigs);
|
||||||
|
|
||||||
boolean hasLocalDateTime = false;
|
boolean hasLocalDateTime = false;
|
||||||
|
|||||||
@@ -168,18 +168,18 @@ public class RedisTokenManager implements TokenManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 使访问令牌失效
|
* Make access token invalid
|
||||||
|
* <p>
|
||||||
|
* Only deletes the current token, not all sessions for the user.
|
||||||
|
* This ensures single-device logout doesn't affect other devices when allowMultiLogin=true.
|
||||||
*
|
*
|
||||||
* @param token 访问令牌
|
* @param token Access token
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void invalidateToken(String token) {
|
public void invalidateToken(String token) {
|
||||||
String cleanToken = cleanBearerPrefix(token);
|
String cleanToken = cleanBearerPrefix(token);
|
||||||
Object value = redisTemplate.opsForValue().get(formatTokenKey(cleanToken));
|
// Only delete the current token, not all user sessions
|
||||||
if (value instanceof UserSession userSession) {
|
redisTemplate.delete(formatTokenKey(cleanToken));
|
||||||
Long userId = userSession.getUserId();
|
|
||||||
invalidateUserSessions(userId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import com.youlai.boot.system.model.vo.CurrentUserVO;
|
|||||||
import com.youlai.boot.system.model.vo.UserPageVO;
|
import com.youlai.boot.system.model.vo.UserPageVO;
|
||||||
import com.youlai.boot.system.model.vo.UserProfileVO;
|
import com.youlai.boot.system.model.vo.UserProfileVO;
|
||||||
import com.youlai.boot.system.service.UserService;
|
import com.youlai.boot.system.service.UserService;
|
||||||
|
import com.youlai.boot.framework.security.token.TokenManager;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
@@ -54,6 +55,8 @@ import java.util.List;
|
|||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public class UserController {
|
public class UserController {
|
||||||
|
|
||||||
|
private final TokenManager tokenManager;
|
||||||
|
|
||||||
private final UserService userService;
|
private final UserService userService;
|
||||||
|
|
||||||
@Operation(summary = "用户列表")
|
@Operation(summary = "用户列表")
|
||||||
@@ -122,6 +125,10 @@ public class UserController {
|
|||||||
.eq(SysUser::getId, userId)
|
.eq(SysUser::getId, userId)
|
||||||
.set(SysUser::getStatus, status)
|
.set(SysUser::getStatus, status)
|
||||||
);
|
);
|
||||||
|
// 用户禁用时立即失效其会话
|
||||||
|
if (result && status == 0) {
|
||||||
|
tokenManager.invalidateUserSessions(userId);
|
||||||
|
}
|
||||||
return Result.judge(result);
|
return Result.judge(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,14 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
|||||||
if (result) {
|
if (result) {
|
||||||
// 刷新角色的权限缓存
|
// 刷新角色的权限缓存
|
||||||
roleMenuService.refreshRolePermsCache(role.getCode());
|
roleMenuService.refreshRolePermsCache(role.getCode());
|
||||||
|
|
||||||
|
// When role is disabled, invalidate sessions of all users with this role
|
||||||
|
if (status == 0) {
|
||||||
|
List<Long> userIds = userRoleService.listUserIdsByRoleId(roleId);
|
||||||
|
for (Long userId : userIds) {
|
||||||
|
tokenManager.invalidateUserSessions(userId);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import ${packageName}.${moduleName}.model.form.${entityName}Form;
|
|||||||
import ${packageName}.${moduleName}.model.query.${entityName}Query;
|
import ${packageName}.${moduleName}.model.query.${entityName}Query;
|
||||||
import ${packageName}.${moduleName}.model.vo.${entityName}Vo;
|
import ${packageName}.${moduleName}.model.vo.${entityName}Vo;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.youlai.boot.common.result.PageResult;
|
import ${packageName}.common.result.PageResult;
|
||||||
import com.youlai.boot.common.result.Result;
|
import ${packageName}.common.result.Result;
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import java.time.LocalDateTime;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
#end
|
#end
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.youlai.boot.common.base.BaseEntity;
|
import ${packageName}.common.base.BaseEntity;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* $!{businessName}实体对象
|
* $!{businessName}实体对象
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
package ${packageName}.${moduleName}.${subpackageName};
|
package ${packageName}.${moduleName}.${subpackageName};
|
||||||
|
|
||||||
import com.youlai.boot.common.base.BaseQuery;
|
import ${packageName}.common.base.BaseQuery;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package ${packageName}.${moduleName}.model.vo;
|
|||||||
|
|
||||||
import java.io.Serial;
|
import java.io.Serial;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.time.LocalDateTime;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|||||||
Reference in New Issue
Block a user