Compare commits
5 Commits
2d736e8f3d
...
8434098c39
Author | SHA1 | Date | |
---|---|---|---|
![]() |
8434098c39 | ||
![]() |
099b308c5e | ||
![]() |
e1221dd1f9 | ||
![]() |
d14849903c | ||
![]() |
5e03d7ea5e |
@ -0,0 +1,12 @@
|
||||
package com.stdproject.common;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FilterCondition {
|
||||
|
||||
private String field;
|
||||
private String operator; // eq, ne, gt, ge, lt, le
|
||||
private Object value;
|
||||
|
||||
}
|
@ -1,5 +1,8 @@
|
||||
package com.stdproject.common;
|
||||
|
||||
import cn.hutool.http.useragent.Browser;
|
||||
import cn.hutool.http.useragent.UserAgent;
|
||||
import cn.hutool.http.useragent.UserAgentUtil;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.stdproject.entity.AppOptLog;
|
||||
import com.stdproject.service.IAppOptLogService;
|
||||
@ -90,7 +93,7 @@ public class OperationLogAspect {
|
||||
optLog.setDescription(operationLog.description());
|
||||
optLog.setMethod(request.getMethod() + " " + request.getRequestURI());
|
||||
optLog.setRequestip(getIpAddress(request));
|
||||
optLog.setBrowser(request.getHeader("User-Agent"));
|
||||
optLog.setBrowser(getBrowser(request));
|
||||
optLog.setLogtime(LocalDateTime.now());
|
||||
|
||||
// 设置操作用户
|
||||
@ -147,6 +150,12 @@ public class OperationLogAspect {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getBrowser(HttpServletRequest request) {
|
||||
UserAgent userAgent = UserAgentUtil.parse(request.getHeader("User-Agent"));
|
||||
Browser browser = userAgent.getBrowser();
|
||||
return browser.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取客户端IP地址
|
||||
*/
|
||||
|
@ -4,7 +4,7 @@ import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.Data;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 分页查询请求类
|
||||
@ -43,6 +43,11 @@ public class PageRequest {
|
||||
*/
|
||||
private String keyword;
|
||||
|
||||
/**
|
||||
* 条件过滤器
|
||||
*/
|
||||
private List<FilterCondition> filters;
|
||||
|
||||
/**
|
||||
* 获取偏移量
|
||||
*
|
||||
|
@ -0,0 +1,92 @@
|
||||
package com.stdproject.common;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @Date: 2025/6/5 9:21
|
||||
* @Description:
|
||||
*/
|
||||
public class QueryWrapperBuilder {
|
||||
|
||||
public static <T> QueryWrapper<T> buildQueryWrapper(PageRequest pageRequest) {
|
||||
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
// 过滤条件
|
||||
if (pageRequest.getFilters() != null && !pageRequest.getFilters().isEmpty()) {
|
||||
for (FilterCondition condition : pageRequest.getFilters()) {
|
||||
String field = condition.getField();
|
||||
String op = condition.getOperator();
|
||||
Object val = condition.getValue();
|
||||
|
||||
if (!StringUtils.hasText(field) || ObjectUtil.isEmpty(val)) continue;
|
||||
switch (op.toLowerCase()) {
|
||||
case "eq":
|
||||
queryWrapper.eq(field, val);
|
||||
break;
|
||||
case "like":
|
||||
queryWrapper.like(field, val);
|
||||
break;
|
||||
case "left_like":
|
||||
queryWrapper.likeLeft(field, val);
|
||||
break;
|
||||
case "right_like":
|
||||
queryWrapper.likeRight(field, val);
|
||||
break;
|
||||
case "ne":
|
||||
queryWrapper.ne(field, val);
|
||||
break;
|
||||
case "gt":
|
||||
queryWrapper.gt(field, val);
|
||||
break;
|
||||
case "ge":
|
||||
queryWrapper.ge(field, val);
|
||||
break;
|
||||
case "lt":
|
||||
queryWrapper.lt(field, val);
|
||||
break;
|
||||
case "le":
|
||||
queryWrapper.le(field, val);
|
||||
break;
|
||||
case "in":
|
||||
if (val instanceof Collection) {
|
||||
queryWrapper.in(field, (Collection<?>) val);
|
||||
}
|
||||
break;
|
||||
case "notin":
|
||||
if (val instanceof Collection) {
|
||||
queryWrapper.notIn(field, (Collection<?>) val);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// 忽略不支持的操作符
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 排序字段白名单校验
|
||||
// String orderBy = pageRequest.getOrderBy();
|
||||
// if (StringUtils.hasText(orderBy) && isAllowedOrderField(orderBy)) {
|
||||
// if ("asc".equalsIgnoreCase(pageRequest.getOrderDirection())) {
|
||||
// queryWrapper.orderByAsc(orderBy);
|
||||
// } else {
|
||||
// queryWrapper.orderByDesc(orderBy);
|
||||
// }
|
||||
// }
|
||||
return queryWrapper;
|
||||
}
|
||||
|
||||
private static final Set<String> ALLOWED_ORDER_FIELDS = Set.of(
|
||||
"username", "nickname", "email", "phone", "lastmodifydate", "age"
|
||||
);
|
||||
|
||||
private static boolean isAllowedOrderField(String field) {
|
||||
return ALLOWED_ORDER_FIELDS.contains(field);
|
||||
}
|
||||
|
||||
}
|
@ -34,6 +34,9 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
@Autowired
|
||||
private UserDetailsService userDetailsService;
|
||||
|
||||
@Autowired
|
||||
private WebConfig webConfig;
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
@ -41,6 +44,11 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
||||
try {
|
||||
String jwt = getJwtFromRequest(request);
|
||||
|
||||
// 拦截器中校验
|
||||
if (webConfig.loginuserCache().get(jwt) != null) {
|
||||
response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Token 已失效");
|
||||
return;
|
||||
}
|
||||
if (StringUtils.hasText(jwt) && SecurityContextHolder.getContext().getAuthentication() == null) {
|
||||
String username = jwtUtils.getUsernameFromToken(jwt);
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
package com.stdproject.config;
|
||||
|
||||
import cn.hutool.cache.Cache;
|
||||
import cn.hutool.cache.CacheUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
@ -12,6 +16,17 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
@Configuration
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
@Value("${spring.security.jwt.expiration-ms}")
|
||||
private Long expirationMs;
|
||||
|
||||
/**
|
||||
* 用户缓存
|
||||
*/
|
||||
@Bean
|
||||
public Cache<String, String> loginuserCache() {
|
||||
return CacheUtil.newTimedCache(expirationMs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 静态资源处理
|
||||
*/
|
||||
|
@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -128,7 +129,7 @@ public class AppDictionaryController {
|
||||
if (appDictionary.getOrderno() == null) {
|
||||
// 获取同一字典编码下的最大序号
|
||||
QueryWrapper<AppDictionary> orderQuery = new QueryWrapper<>();
|
||||
orderQuery.eq("dictcode", appDictionary.getDictcode());
|
||||
orderQuery.eq("app_id", appDictionary.getAppId());
|
||||
orderQuery.orderByDesc("orderno");
|
||||
orderQuery.last("LIMIT 1");
|
||||
AppDictionary lastDict = appDictionaryService.getOne(orderQuery);
|
||||
@ -244,7 +245,7 @@ public class AppDictionaryController {
|
||||
@Operation(summary = "根据字典编码分组查询字典项")
|
||||
@GetMapping("/grouped")
|
||||
@OperationLog(type = "06", module = "数据字典管理", description = "根据字典编码分组查询字典项")
|
||||
public Result<java.util.Map<String, List<AppDictionary>>> getGroupedDictionaries() {
|
||||
public Result<Map<String, List<AppDictionary>>> getGroupedDictionaries() {
|
||||
QueryWrapper<AppDictionary> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.orderByAsc("dictcode", "orderno");
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.stdproject.common.OperationLog;
|
||||
@ -8,6 +10,7 @@ import com.stdproject.common.PageRequest;
|
||||
import com.stdproject.common.Result;
|
||||
import com.stdproject.entity.AppMenu;
|
||||
import com.stdproject.service.IAppMenuService;
|
||||
import com.stdproject.service.IAppUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
@ -37,6 +40,9 @@ public class AppMenuController {
|
||||
@Autowired
|
||||
private IAppMenuService appMenuService;
|
||||
|
||||
@Autowired
|
||||
private IAppUserService appUserService;
|
||||
|
||||
@Operation(summary = "分页查询菜单列表")
|
||||
@PostMapping("/page")
|
||||
@OperationLog(type = "06", module = "菜单管理", description = "分页查询菜单列表")
|
||||
@ -82,8 +88,10 @@ public class AppMenuController {
|
||||
@Operation(summary = "获取菜单树形结构")
|
||||
@GetMapping("/tree")
|
||||
@OperationLog(type = "06", module = "菜单管理", description = "获取菜单树形结构")
|
||||
public Result<List<MenuTreeNode>> getMenuTree() {
|
||||
public Result<List<MenuTreeNode>> getMenuTree(@RequestParam String appId,@RequestParam String name) {
|
||||
QueryWrapper<AppMenu> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq(StrUtil.isNotBlank(appId),"app_id", appId);
|
||||
queryWrapper.like(StrUtil.isNotBlank(name),"name", name);
|
||||
queryWrapper.orderByAsc("parentid", "orderno");
|
||||
|
||||
List<AppMenu> allMenus = appMenuService.list(queryWrapper);
|
||||
@ -155,6 +163,7 @@ public class AppMenuController {
|
||||
}
|
||||
|
||||
appMenu.setLastmodifydate(LocalDateTime.now());
|
||||
appMenu.setLastmodifier(appUserService.getCurrentUsername());
|
||||
boolean success = appMenuService.save(appMenu);
|
||||
return success ? Result.success("新增成功") : Result.error("新增失败");
|
||||
}
|
||||
@ -187,7 +196,7 @@ public class AppMenuController {
|
||||
}
|
||||
|
||||
// 检查父级菜单是否存在(如果不是顶级菜单)
|
||||
if (!"0".equals(appMenu.getParentid())) {
|
||||
if (!"0".equals(existMenu.getParentid())) {
|
||||
AppMenu parentMenu = appMenuService.getById(appMenu.getParentid());
|
||||
if (parentMenu == null) {
|
||||
return Result.error("父级菜单不存在");
|
||||
@ -196,10 +205,38 @@ public class AppMenuController {
|
||||
}
|
||||
|
||||
appMenu.setLastmodifydate(LocalDateTime.now());
|
||||
appMenu.setLastmodifier(appUserService.getCurrentUsername());
|
||||
boolean success = appMenuService.updateById(appMenu);
|
||||
return success ? Result.success("修改成功") : Result.error("修改失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "更新菜单及按钮是否有效")
|
||||
@PutMapping("/display/{id}")
|
||||
@OperationLog(type = "02", module = "菜单管理", description = "更新菜单及按钮是否有效")
|
||||
public Result<String> setIsDisplay(
|
||||
@Parameter(description = "菜单ID") @PathVariable String id,
|
||||
@RequestParam String isDisplay) {
|
||||
LambdaUpdateWrapper<AppMenu> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(AppMenu::getId, id).set(AppMenu::getIsdisplay, isDisplay).set(AppMenu::getLastmodifydate,
|
||||
LocalDateTime.now()).set(AppMenu::getLastmodifier, appUserService.getCurrentUsername());
|
||||
boolean success = appMenuService.update(updateWrapper);
|
||||
return success ? Result.success("更新成功") : Result.error("更新失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "更新关联模块ID")
|
||||
@PutMapping("/module/{id}")
|
||||
@OperationLog(type = "02", module = "菜单管理", description = "更新关联模块ID")
|
||||
public Result<String> setModuleId(
|
||||
@Parameter(description = "菜单ID") @PathVariable String id,
|
||||
@RequestParam String moduleId) {
|
||||
LambdaUpdateWrapper<AppMenu> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(AppMenu::getId, id).set(AppMenu::getModuleId, moduleId).set(AppMenu::getLastmodifydate,
|
||||
LocalDateTime.now()).set(AppMenu::getLastmodifier, appUserService.getCurrentUsername());
|
||||
boolean success = appMenuService.update(updateWrapper);
|
||||
return success ? Result.success("更新成功") : Result.error("更新失败");
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "删除菜单")
|
||||
@DeleteMapping("/{id}")
|
||||
@OperationLog(type = "03", module = "菜单管理", description = "删除菜单")
|
||||
@ -323,6 +360,7 @@ public class AppMenuController {
|
||||
* 菜单树节点
|
||||
*/
|
||||
public static class MenuTreeNode {
|
||||
|
||||
private String id;
|
||||
private String code;
|
||||
private String name;
|
||||
@ -337,42 +375,125 @@ public class AppMenuController {
|
||||
private List<MenuTreeNode> children = new ArrayList<>();
|
||||
|
||||
// Getters and Setters
|
||||
public String getId() { return id; }
|
||||
public void setId(String id) { this.id = id; }
|
||||
public String getCode() { return code; }
|
||||
public void setCode(String code) { this.code = code; }
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
public String getIcon() { return icon; }
|
||||
public void setIcon(String icon) { this.icon = icon; }
|
||||
public String getUrl() { return url; }
|
||||
public void setUrl(String url) { this.url = url; }
|
||||
public String getType() { return type; }
|
||||
public void setType(String type) { this.type = type; }
|
||||
public String getIslink() { return islink; }
|
||||
public void setIslink(String islink) { this.islink = islink; }
|
||||
public String getIsdisplay() { return isdisplay; }
|
||||
public void setIsdisplay(String isdisplay) { this.isdisplay = isdisplay; }
|
||||
public Integer getOrderno() { return orderno; }
|
||||
public void setOrderno(Integer orderno) { this.orderno = orderno; }
|
||||
public String getParentid() { return parentid; }
|
||||
public void setParentid(String parentid) { this.parentid = parentid; }
|
||||
public String getModuleId() { return moduleId; }
|
||||
public void setModuleId(String moduleId) { this.moduleId = moduleId; }
|
||||
public List<MenuTreeNode> getChildren() { return children; }
|
||||
public void setChildren(List<MenuTreeNode> children) { this.children = children; }
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public void setIcon(String icon) {
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getIslink() {
|
||||
return islink;
|
||||
}
|
||||
|
||||
public void setIslink(String islink) {
|
||||
this.islink = islink;
|
||||
}
|
||||
|
||||
public String getIsdisplay() {
|
||||
return isdisplay;
|
||||
}
|
||||
|
||||
public void setIsdisplay(String isdisplay) {
|
||||
this.isdisplay = isdisplay;
|
||||
}
|
||||
|
||||
public Integer getOrderno() {
|
||||
return orderno;
|
||||
}
|
||||
|
||||
public void setOrderno(Integer orderno) {
|
||||
this.orderno = orderno;
|
||||
}
|
||||
|
||||
public String getParentid() {
|
||||
return parentid;
|
||||
}
|
||||
|
||||
public void setParentid(String parentid) {
|
||||
this.parentid = parentid;
|
||||
}
|
||||
|
||||
public String getModuleId() {
|
||||
return moduleId;
|
||||
}
|
||||
|
||||
public void setModuleId(String moduleId) {
|
||||
this.moduleId = moduleId;
|
||||
}
|
||||
|
||||
public List<MenuTreeNode> getChildren() {
|
||||
return children;
|
||||
}
|
||||
|
||||
public void setChildren(List<MenuTreeNode> children) {
|
||||
this.children = children;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单排序请求
|
||||
*/
|
||||
public static class MenuOrderRequest {
|
||||
|
||||
private String id;
|
||||
private Integer orderno;
|
||||
|
||||
public String getId() { return id; }
|
||||
public void setId(String id) { this.id = id; }
|
||||
public Integer getOrderno() { return orderno; }
|
||||
public void setOrderno(Integer orderno) { this.orderno = orderno; }
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public Integer getOrderno() {
|
||||
return orderno;
|
||||
}
|
||||
|
||||
public void setOrderno(Integer orderno) {
|
||||
this.orderno = orderno;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
@ -12,12 +13,14 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -31,6 +34,7 @@ import java.util.List;
|
||||
@Tag(name = "操作日志管理", description = "操作日志查询、操作日志删除等功能")
|
||||
@RestController
|
||||
@RequestMapping("/api/optlog")
|
||||
@Slf4j
|
||||
public class AppOptLogController {
|
||||
|
||||
@Autowired
|
||||
@ -113,7 +117,7 @@ public class AppOptLogController {
|
||||
@Parameter(description = "限制条数") @RequestParam(defaultValue = "100") Integer limit) {
|
||||
QueryWrapper<AppOptLog> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("module", module);
|
||||
queryWrapper.orderByDesc("opttime");
|
||||
queryWrapper.orderByDesc("logtime");
|
||||
queryWrapper.last("LIMIT " + limit);
|
||||
|
||||
List<AppOptLog> logs = appOptLogService.list(queryWrapper);
|
||||
@ -128,8 +132,8 @@ public class AppOptLogController {
|
||||
@Parameter(description = "结束时间") @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime endTime,
|
||||
@Parameter(description = "限制条数") @RequestParam(defaultValue = "1000") Integer limit) {
|
||||
QueryWrapper<AppOptLog> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.between("opttime", startTime, endTime);
|
||||
queryWrapper.orderByDesc("opttime");
|
||||
queryWrapper.between("logtime", startTime, endTime);
|
||||
queryWrapper.orderByDesc("logtime");
|
||||
queryWrapper.last("LIMIT " + limit);
|
||||
|
||||
List<AppOptLog> logs = appOptLogService.list(queryWrapper);
|
||||
@ -144,14 +148,13 @@ public class AppOptLogController {
|
||||
@Parameter(description = "限制条数") @RequestParam(defaultValue = "100") Integer limit) {
|
||||
QueryWrapper<AppOptLog> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("ip", ip);
|
||||
queryWrapper.orderByDesc("opttime");
|
||||
queryWrapper.orderByDesc("logtime");
|
||||
queryWrapper.last("LIMIT " + limit);
|
||||
|
||||
List<AppOptLog> logs = appOptLogService.list(queryWrapper);
|
||||
return Result.success(logs);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "删除操作日志")
|
||||
@DeleteMapping("/{id}")
|
||||
@OperationLog(type = "03", module = "操作日志管理", description = "删除操作日志")
|
||||
@ -172,12 +175,21 @@ public class AppOptLogController {
|
||||
@DeleteMapping("/clean/{days}")
|
||||
@OperationLog(type = "03", module = "操作日志管理", description = "清理历史操作日志")
|
||||
public Result<String> cleanOldLogs(@Parameter(description = "保留天数") @PathVariable Integer days) {
|
||||
LocalDateTime cutoffTime = LocalDateTime.now().minusDays(days);
|
||||
QueryWrapper<AppOptLog> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.lt("logtime", cutoffTime);
|
||||
|
||||
try {
|
||||
// 参数校验
|
||||
if (days == null || days < 0 || days > 3650) {
|
||||
return Result.error("保留天数必须在0到3650之间");
|
||||
}
|
||||
LocalDateTime cutoff = LocalDateTime.now().minusDays(days);
|
||||
LambdaQueryWrapper<AppOptLog> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.lt(AppOptLog::getLogtime, cutoff);
|
||||
boolean success = appOptLogService.remove(queryWrapper);
|
||||
return success ? Result.success("清理成功") : Result.error("清理失败");
|
||||
} catch (Exception e) {
|
||||
// 记录异常日志以便排查
|
||||
log.error("清理操作日志失败", e);
|
||||
return Result.error("系统异常,请稍后再试");
|
||||
}
|
||||
}
|
||||
|
||||
@Operation(summary = "获取操作日志统计信息")
|
||||
@ -190,17 +202,17 @@ public class AppOptLogController {
|
||||
// 今日日志数
|
||||
LocalDateTime todayStart = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0).withNano(0);
|
||||
QueryWrapper<AppOptLog> todayQuery = new QueryWrapper<>();
|
||||
todayQuery.ge("opttime", todayStart);
|
||||
todayQuery.ge("logtime", todayStart);
|
||||
long todayCount = appOptLogService.count(todayQuery);
|
||||
|
||||
// 本周日志数
|
||||
LocalDateTime weekStart = LocalDateTime.now().minusDays(7);
|
||||
LocalDateTime weekStart = LocalDateTime.now().minusDays(7).withNano(0);
|
||||
QueryWrapper<AppOptLog> weekQuery = new QueryWrapper<>();
|
||||
weekQuery.ge("logtime", weekStart);
|
||||
long weekCount = appOptLogService.count(weekQuery);
|
||||
|
||||
// 本月日志数
|
||||
LocalDateTime monthStart = LocalDateTime.now().minusDays(30);
|
||||
LocalDateTime monthStart = LocalDateTime.now().minusDays(30).withNano(0);
|
||||
QueryWrapper<AppOptLog> monthQuery = new QueryWrapper<>();
|
||||
monthQuery.ge("logtime", monthStart);
|
||||
long monthCount = appOptLogService.count(monthQuery);
|
||||
@ -231,18 +243,42 @@ public class AppOptLogController {
|
||||
* 日志统计信息
|
||||
*/
|
||||
public static class LogStatistics {
|
||||
|
||||
private Long totalCount;
|
||||
private Long todayCount;
|
||||
private Long weekCount;
|
||||
private Long monthCount;
|
||||
|
||||
public Long getTotalCount() { return totalCount; }
|
||||
public void setTotalCount(Long totalCount) { this.totalCount = totalCount; }
|
||||
public Long getTodayCount() { return todayCount; }
|
||||
public void setTodayCount(Long todayCount) { this.todayCount = todayCount; }
|
||||
public Long getWeekCount() { return weekCount; }
|
||||
public void setWeekCount(Long weekCount) { this.weekCount = weekCount; }
|
||||
public Long getMonthCount() { return monthCount; }
|
||||
public void setMonthCount(Long monthCount) { this.monthCount = monthCount; }
|
||||
public Long getTotalCount() {
|
||||
return totalCount;
|
||||
}
|
||||
|
||||
public void setTotalCount(Long totalCount) {
|
||||
this.totalCount = totalCount;
|
||||
}
|
||||
|
||||
public Long getTodayCount() {
|
||||
return todayCount;
|
||||
}
|
||||
|
||||
public void setTodayCount(Long todayCount) {
|
||||
this.todayCount = todayCount;
|
||||
}
|
||||
|
||||
public Long getWeekCount() {
|
||||
return weekCount;
|
||||
}
|
||||
|
||||
public void setWeekCount(Long weekCount) {
|
||||
this.weekCount = weekCount;
|
||||
}
|
||||
|
||||
public Long getMonthCount() {
|
||||
return monthCount;
|
||||
}
|
||||
|
||||
public void setMonthCount(Long monthCount) {
|
||||
this.monthCount = monthCount;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,21 +1,27 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.stdproject.common.OperationLog;
|
||||
import com.stdproject.common.Result;
|
||||
import com.stdproject.entity.AppOrganization;
|
||||
import com.stdproject.service.IAppOrganizationService;
|
||||
import com.stdproject.service.IAppUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.Data;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
@ -39,21 +45,24 @@ public class AppOrganizationController {
|
||||
@Operation(summary = "查询公司结构树")
|
||||
@GetMapping("/getCompanyTree")
|
||||
@OperationLog(type = "06", module = "组织管理", description = "查询公司结构树")
|
||||
public Result<List<AppOrganization>> getCompanyTree() {
|
||||
public Result<List<OrganizationTreeNode>> getCompanyTree(@RequestParam String appId) {
|
||||
QueryWrapper<AppOrganization> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("orgtype", "01");
|
||||
queryWrapper.eq(StrUtil.isNotBlank(appId),"app_id", appId);
|
||||
queryWrapper.eq("isvaild", "1");
|
||||
queryWrapper.orderByAsc("orgcode");
|
||||
List<AppOrganization> children = appOrganizationService.list(queryWrapper);
|
||||
return Result.success(children);
|
||||
List<OrganizationTreeNode> organizationTreeNodes = buildOrganizationTree(children, "0");
|
||||
return Result.success(organizationTreeNodes);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询部门列表")
|
||||
@Operation(summary = "查询公司/部门列表")
|
||||
@GetMapping("/getDepartmentList")
|
||||
@OperationLog(type = "06", module = "组织管理", description = "查询部门列表")
|
||||
public Result<List<AppOrganization>> getDepartmentList(@RequestParam String parentid,@RequestParam String keystr) {
|
||||
@OperationLog(type = "06", module = "组织管理", description = "查询公司/部门列表")
|
||||
public Result<List<AppOrganization>> getDepartmentList(@RequestParam String appId, @RequestParam String orgtype,
|
||||
@RequestParam String parentid, @RequestParam String keystr) {
|
||||
QueryWrapper<AppOrganization> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("orgtype", "02");
|
||||
queryWrapper.eq(StrUtil.isNotBlank(appId), "app_id", appId);
|
||||
queryWrapper.eq(StrUtil.isNotBlank(orgtype), "orgtype", orgtype);
|
||||
queryWrapper.eq("parentid", parentid);
|
||||
queryWrapper.eq("isvaild", "1");
|
||||
if (StringUtils.hasText(keystr)) {
|
||||
@ -68,8 +77,6 @@ public class AppOrganizationController {
|
||||
return Result.success(children);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Operation(summary = "根据ID查询组织详情")
|
||||
@GetMapping("getDetailById/{id}")
|
||||
@OperationLog(type = "06", module = "组织管理", description = "根据ID查询组织详情")
|
||||
@ -78,7 +85,6 @@ public class AppOrganizationController {
|
||||
return Result.success(organization);
|
||||
}
|
||||
|
||||
|
||||
@Operation(summary = "新增组织")
|
||||
@PostMapping("add")
|
||||
@OperationLog(type = "01", module = "组织管理", description = "新增组织")
|
||||
@ -126,6 +132,19 @@ public class AppOrganizationController {
|
||||
return success ? Result.success("修改成功") : Result.error("修改失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "设置组织是否有效")
|
||||
@PutMapping("/isValid/{id}")
|
||||
@OperationLog(type = "02", module = "组织管理", description = "设置组织是否有效")
|
||||
public Result<String> setIsValid(
|
||||
@Parameter(description = "组织ID") @PathVariable String id,
|
||||
@RequestParam String isValid) {
|
||||
LambdaUpdateWrapper<AppOrganization> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.eq(AppOrganization::getId, id).set(AppOrganization::getIsvaild, isValid).set(AppOrganization::getLastmodifydate,
|
||||
LocalDateTime.now()).set(AppOrganization::getLastmodifier, appUserService.getCurrentUsername());
|
||||
boolean success = appOrganizationService.update(updateWrapper);
|
||||
return success ? Result.success("设置成功") : Result.error("设置失败");
|
||||
}
|
||||
|
||||
@Operation(summary = "删除组织")
|
||||
@PostMapping("delete/{id}")
|
||||
@OperationLog(type = "03", module = "组织管理", description = "删除组织")
|
||||
@ -203,7 +222,6 @@ public class AppOrganizationController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private String getMaxCodeByParentId(String orgType, String parentId) {
|
||||
LambdaQueryWrapper<AppOrganization> queryWrapper = new LambdaQueryWrapper<AppOrganization>()
|
||||
.eq(AppOrganization::getOrgtype, orgType)
|
||||
@ -217,5 +235,99 @@ public class AppOrganizationController {
|
||||
// 如果列表不为空,返回第一个记录的orgcode
|
||||
return list.isEmpty() ? null : list.get(0).getOrgcode();
|
||||
}
|
||||
/**
|
||||
* 构建菜单树
|
||||
*/
|
||||
private List<OrganizationTreeNode> buildOrganizationTree(List<AppOrganization> allOrganizations, String parentId) {
|
||||
return allOrganizations.stream()
|
||||
.filter(organization -> parentId.equals(organization.getParentid()))
|
||||
.map(organization -> {
|
||||
OrganizationTreeNode node = new OrganizationTreeNode();
|
||||
node.setId(organization.getId());
|
||||
node.setAppId(organization.getAppId());
|
||||
node.setOrgtype(organization.getOrgtype());
|
||||
node.setOrgcode(organization.getOrgcode());
|
||||
node.setOrgname(organization.getOrgname());
|
||||
node.setParentid(organization.getParentid());
|
||||
node.setManager(organization.getManager());
|
||||
node.setDescription(organization.getDescription());
|
||||
node.setAddress(organization.getAddress());
|
||||
node.setContactPhone(organization.getContactPhone());
|
||||
node.setContactPerson(organization.getContactPerson());
|
||||
node.setIsvaild(organization.getIsvaild());
|
||||
node.setChildren(buildOrganizationTree(allOrganizations, organization.getId()));
|
||||
return node;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 组织树节点
|
||||
*/
|
||||
@Data
|
||||
public static class OrganizationTreeNode {
|
||||
|
||||
/**
|
||||
* ID
|
||||
*/
|
||||
private String id;
|
||||
|
||||
/**
|
||||
* 应用ID 关联应用系统
|
||||
*/
|
||||
private String appId;
|
||||
|
||||
/**
|
||||
* 组织类型:01-公司 02-部门
|
||||
*/
|
||||
private String orgtype;
|
||||
|
||||
/**
|
||||
* 组织编号
|
||||
*/
|
||||
private String orgcode;
|
||||
|
||||
/**
|
||||
* 组织名称
|
||||
*/
|
||||
private String orgname;
|
||||
|
||||
/**
|
||||
* 上级ID
|
||||
*/
|
||||
private String parentid;
|
||||
|
||||
/**
|
||||
* 组织负责人
|
||||
*/
|
||||
private String manager;
|
||||
|
||||
/**
|
||||
* 组织详情
|
||||
*/
|
||||
private String description;
|
||||
|
||||
/**
|
||||
* 联系地址
|
||||
*/
|
||||
private String address;
|
||||
|
||||
/**
|
||||
* 联系电话
|
||||
*/
|
||||
private String contactPhone;
|
||||
|
||||
/**
|
||||
* 联系人
|
||||
*/
|
||||
private String contactPerson;
|
||||
|
||||
/**
|
||||
* 是否有效 1-是 0-否
|
||||
*/
|
||||
private String isvaild;
|
||||
|
||||
private List<OrganizationTreeNode> children = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
@ -49,12 +50,13 @@ public class AppRoleController {
|
||||
private IAppRoleUserService appRoleUserService;
|
||||
|
||||
@Operation(summary = "分页查询角色列表")
|
||||
@PostMapping("/page")
|
||||
@PostMapping("/page/{appId}")
|
||||
@OperationLog(type = "06", module = "角色管理", description = "分页查询角色列表")
|
||||
public Result<IPage<AppRole>> page(@RequestBody @Valid PageRequest pageRequest) {
|
||||
public Result<IPage<AppRole>> page(@Parameter(description = "用户ID") @PathVariable String appId,
|
||||
@RequestBody @Valid PageRequest pageRequest) {
|
||||
Page<AppRole> page = new Page<>(pageRequest.getCurrent(), pageRequest.getSize());
|
||||
QueryWrapper<AppRole> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
queryWrapper.eq(StrUtil.isNotBlank(appId),"app_id",appId);
|
||||
// 关键字搜索
|
||||
if (StringUtils.hasText(pageRequest.getKeyword())) {
|
||||
queryWrapper.and(wrapper -> wrapper
|
||||
@ -101,6 +103,7 @@ public class AppRoleController {
|
||||
AppRole role = appRoleService.getById(id);
|
||||
return Result.success(role);
|
||||
}
|
||||
|
||||
@Operation(summary = "新增角色")
|
||||
@PostMapping
|
||||
@OperationLog(type = "01", module = "角色管理", description = "新增角色")
|
||||
@ -133,6 +136,7 @@ public class AppRoleController {
|
||||
|
||||
/**
|
||||
* 获取最大的角色编号
|
||||
*
|
||||
* @return 最大角色编号
|
||||
*/
|
||||
private String getMaxRoleCode() {
|
||||
@ -204,8 +208,6 @@ public class AppRoleController {
|
||||
return Result.error("角色不存在");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Operation(summary = "根据角色类型查询角色列表")
|
||||
@GetMapping("/type/{type}")
|
||||
@OperationLog(type = "06", module = "角色管理", description = "根据角色类型查询角色列表")
|
||||
|
@ -1,10 +1,12 @@
|
||||
package com.stdproject.controller;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.stdproject.common.OperationLog;
|
||||
import com.stdproject.common.PageRequest;
|
||||
import com.stdproject.common.QueryWrapperBuilder;
|
||||
import com.stdproject.common.Result;
|
||||
import com.stdproject.entity.AppUser;
|
||||
import com.stdproject.service.IAppUserService;
|
||||
@ -37,12 +39,15 @@ public class AppUserController {
|
||||
private IAppUserService appUserService;
|
||||
|
||||
@Operation(summary = "分页查询用户列表")
|
||||
@PostMapping("/page")
|
||||
@PostMapping("/page/{orgId}/{appId}")
|
||||
@OperationLog(type = "06", module = "用户管理", description = "分页查询用户列表")
|
||||
public Result<IPage<AppUser>> page(@RequestBody @Valid PageRequest pageRequest) {
|
||||
public Result<IPage<AppUser>> page(@Parameter(description = "用户ID") @PathVariable String orgId,
|
||||
@Parameter(description = "用户ID") @PathVariable String appId,
|
||||
@RequestBody @Valid PageRequest pageRequest) {
|
||||
Page<AppUser> page = new Page<>(pageRequest.getCurrent(), pageRequest.getSize());
|
||||
QueryWrapper<AppUser> queryWrapper = new QueryWrapper<>();
|
||||
|
||||
queryWrapper.eq(StrUtil.isNotBlank(orgId),"orgid",orgId);
|
||||
queryWrapper.eq(StrUtil.isNotBlank(appId),"app_id",appId);
|
||||
// 关键字搜索
|
||||
if (StringUtils.hasText(pageRequest.getKeyword())) {
|
||||
queryWrapper.and(wrapper -> wrapper
|
||||
@ -254,24 +259,42 @@ public class AppUserController {
|
||||
* 密码修改请求类
|
||||
*/
|
||||
public static class PasswordUpdateRequest {
|
||||
|
||||
private String oldPassword;
|
||||
private String newPassword;
|
||||
|
||||
// getters and setters
|
||||
public String getOldPassword() { return oldPassword; }
|
||||
public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
|
||||
public String getNewPassword() { return newPassword; }
|
||||
public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
|
||||
public String getOldPassword() {
|
||||
return oldPassword;
|
||||
}
|
||||
|
||||
public void setOldPassword(String oldPassword) {
|
||||
this.oldPassword = oldPassword;
|
||||
}
|
||||
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码重置请求类
|
||||
*/
|
||||
public static class PasswordResetRequest {
|
||||
|
||||
private String newPassword;
|
||||
|
||||
// getters and setters
|
||||
public String getNewPassword() { return newPassword; }
|
||||
public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@ package com.stdproject.controller;
|
||||
import com.stdproject.common.Constants;
|
||||
import com.stdproject.common.OperationLog;
|
||||
import com.stdproject.common.Result;
|
||||
import com.stdproject.config.WebConfig;
|
||||
import com.stdproject.entity.AppUser;
|
||||
import com.stdproject.service.IAppUserService;
|
||||
import com.stdproject.utils.CaptchaUtils;
|
||||
@ -20,6 +21,7 @@ import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
@ -48,12 +50,14 @@ public class AuthController {
|
||||
@Autowired
|
||||
private IAppUserService appUserService;
|
||||
|
||||
|
||||
@Autowired
|
||||
private WebConfig webConfig;
|
||||
|
||||
/**
|
||||
* 登录请求类
|
||||
*/
|
||||
public static class LoginRequest {
|
||||
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
@ -67,20 +71,44 @@ public class AuthController {
|
||||
private String captchaKey;
|
||||
|
||||
// Getters and Setters
|
||||
public String getUsername() { return username; }
|
||||
public void setUsername(String username) { this.username = username; }
|
||||
public String getPassword() { return password; }
|
||||
public void setPassword(String password) { this.password = password; }
|
||||
public String getCaptcha() { return captcha; }
|
||||
public void setCaptcha(String captcha) { this.captcha = captcha; }
|
||||
public String getCaptchaKey() { return captchaKey; }
|
||||
public void setCaptchaKey(String captchaKey) { this.captchaKey = captchaKey; }
|
||||
public String getUsername() {
|
||||
return username;
|
||||
}
|
||||
|
||||
public void setUsername(String username) {
|
||||
this.username = username;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
||||
public String getCaptcha() {
|
||||
return captcha;
|
||||
}
|
||||
|
||||
public void setCaptcha(String captcha) {
|
||||
this.captcha = captcha;
|
||||
}
|
||||
|
||||
public String getCaptchaKey() {
|
||||
return captchaKey;
|
||||
}
|
||||
|
||||
public void setCaptchaKey(String captchaKey) {
|
||||
this.captchaKey = captchaKey;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码请求类
|
||||
*/
|
||||
public static class ChangePasswordRequest {
|
||||
|
||||
@NotBlank(message = "原密码不能为空")
|
||||
private String oldPassword;
|
||||
|
||||
@ -88,10 +116,21 @@ public class AuthController {
|
||||
private String newPassword;
|
||||
|
||||
// Getters and Setters
|
||||
public String getOldPassword() { return oldPassword; }
|
||||
public void setOldPassword(String oldPassword) { this.oldPassword = oldPassword; }
|
||||
public String getNewPassword() { return newPassword; }
|
||||
public void setNewPassword(String newPassword) { this.newPassword = newPassword; }
|
||||
public String getOldPassword() {
|
||||
return oldPassword;
|
||||
}
|
||||
|
||||
public void setOldPassword(String oldPassword) {
|
||||
this.oldPassword = oldPassword;
|
||||
}
|
||||
|
||||
public String getNewPassword() {
|
||||
return newPassword;
|
||||
}
|
||||
|
||||
public void setNewPassword(String newPassword) {
|
||||
this.newPassword = newPassword;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,7 +167,8 @@ public class AuthController {
|
||||
@Operation(summary = "用户登录", description = "用户登录认证")
|
||||
@PostMapping("/login")
|
||||
@OperationLog(type = Constants.OPT_TYPE_LOGIN, module = "认证管理", description = "用户登录")
|
||||
public Result<Map<String, Object>> login(@Valid @RequestBody LoginRequest loginRequest, HttpServletRequest request) {
|
||||
public Result<Map<String, Object>> login(@Valid @RequestBody LoginRequest loginRequest,
|
||||
HttpServletRequest request) {
|
||||
try {
|
||||
// 注意:在实际应用中,应该从会话或其他存储中获取验证码进行验证
|
||||
// 此处简化处理,假设验证码已通过(实际应用中需要实现验证逻辑)
|
||||
@ -172,10 +212,19 @@ public class AuthController {
|
||||
String token = request.getHeader(Constants.JWT_HEADER);
|
||||
if (token != null && token.startsWith(Constants.JWT_PREFIX)) {
|
||||
token = token.substring(Constants.JWT_PREFIX.length());
|
||||
// 实现token失效
|
||||
Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token);
|
||||
// 获取当前时间的时间戳(毫秒)
|
||||
long nowMillis = System.currentTimeMillis();
|
||||
|
||||
// 注意:在实际应用中,应该实现Token失效机制
|
||||
// 可以考虑使用短期Token或其他方式实现Token失效
|
||||
// 此处省略Token黑名单实现
|
||||
// 获取 Token 过期时间的时间戳(毫秒)
|
||||
long expirationMillis = expirationDateFromToken.getTime();
|
||||
|
||||
// 计算剩余有效时间(毫秒)
|
||||
long remainingMillis = expirationMillis - nowMillis;
|
||||
if (remainingMillis > 0) {
|
||||
webConfig.loginuserCache().put(token, "1", remainingMillis);
|
||||
}
|
||||
}
|
||||
|
||||
// 清除安全上下文
|
||||
@ -216,14 +265,16 @@ public class AuthController {
|
||||
@Operation(summary = "修改密码", description = "修改当前用户密码")
|
||||
@PostMapping("/changePassword")
|
||||
@OperationLog(type = Constants.OPT_TYPE_UPDATE, module = "认证管理", description = "修改密码")
|
||||
public Result<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request, HttpServletRequest httpRequest) {
|
||||
public Result<Void> changePassword(@Valid @RequestBody ChangePasswordRequest request,
|
||||
HttpServletRequest httpRequest) {
|
||||
try {
|
||||
String token = httpRequest.getHeader(Constants.JWT_HEADER);
|
||||
if (token != null && token.startsWith(Constants.JWT_PREFIX)) {
|
||||
token = token.substring(Constants.JWT_PREFIX.length());
|
||||
String username = jwtUtils.getUsernameFromToken(token);
|
||||
|
||||
boolean success = appUserService.changePassword(username, request.getOldPassword(), request.getNewPassword());
|
||||
boolean success = appUserService.changePassword(username, request.getOldPassword(),
|
||||
request.getNewPassword());
|
||||
if (success) {
|
||||
return Result.success();
|
||||
} else {
|
||||
@ -239,6 +290,7 @@ public class AuthController {
|
||||
}
|
||||
|
||||
@PostMapping("/refreshToken")
|
||||
@Operation(summary = "刷新令牌", description = "刷新当前用户的令牌")
|
||||
public Result<String> refreshToken(@RequestBody Map<String, String> params) {
|
||||
String refreshToken = params.get("refreshToken");
|
||||
|
||||
@ -262,5 +314,9 @@ public class AuthController {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@GetMapping("/getExpirationDateFromToken")
|
||||
public Result<Date> getExpirationDateFromToken(String token) {
|
||||
Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token);
|
||||
return Result.success(expirationDateFromToken);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.stdproject.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.stdproject.entity.AppOptLog;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
|
@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.stdproject.entity.AppOptLog;
|
||||
import com.stdproject.mapper.AppOptLogMapper;
|
||||
import com.stdproject.service.IAppOptLogService;
|
||||
import org.apache.ibatis.annotations.Delete;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user