提交新增接口

This commit is contained in:
weitang 2025-06-04 13:52:12 +08:00
parent 5e03d7ea5e
commit d14849903c
6 changed files with 233 additions and 77 deletions

View File

@ -1,5 +1,8 @@
package com.stdproject.common; 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.fasterxml.jackson.databind.ObjectMapper;
import com.stdproject.entity.AppOptLog; import com.stdproject.entity.AppOptLog;
import com.stdproject.service.IAppOptLogService; import com.stdproject.service.IAppOptLogService;
@ -90,7 +93,7 @@ public class OperationLogAspect {
optLog.setDescription(operationLog.description()); optLog.setDescription(operationLog.description());
optLog.setMethod(request.getMethod() + " " + request.getRequestURI()); optLog.setMethod(request.getMethod() + " " + request.getRequestURI());
optLog.setRequestip(getIpAddress(request)); optLog.setRequestip(getIpAddress(request));
optLog.setBrowser(request.getHeader("User-Agent")); optLog.setBrowser(getBrowser(request));
optLog.setLogtime(LocalDateTime.now()); 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地址 * 获取客户端IP地址
*/ */

View File

@ -2,6 +2,7 @@ package com.stdproject.config;
import cn.hutool.cache.Cache; import cn.hutool.cache.Cache;
import cn.hutool.cache.CacheUtil; import cn.hutool.cache.CacheUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
@ -15,12 +16,15 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration @Configuration
public class WebConfig implements WebMvcConfigurer { public class WebConfig implements WebMvcConfigurer {
@Value("${spring.security.jwt.expiration-ms}")
private Long expirationMs;
/** /**
* 用户缓存 * 用户缓存
*/ */
@Bean @Bean
public Cache<String, String> loginuserCache() { public Cache<String, String> loginuserCache() {
return CacheUtil.newLRUCache(200); return CacheUtil.newTimedCache(expirationMs);
} }
/** /**

View File

@ -1,6 +1,7 @@
package com.stdproject.controller; package com.stdproject.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.stdproject.common.OperationLog; import com.stdproject.common.OperationLog;
@ -41,7 +42,6 @@ public class AppMenuController {
@Autowired @Autowired
private IAppUserService appUserService; private IAppUserService appUserService;
@Operation(summary = "分页查询菜单列表") @Operation(summary = "分页查询菜单列表")
@PostMapping("/page") @PostMapping("/page")
@OperationLog(type = "06", module = "菜单管理", description = "分页查询菜单列表") @OperationLog(type = "06", module = "菜单管理", description = "分页查询菜单列表")
@ -207,6 +207,33 @@ public class AppMenuController {
return success ? Result.success("修改成功") : Result.error("修改失败"); 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 = "删除菜单") @Operation(summary = "删除菜单")
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
@OperationLog(type = "03", module = "菜单管理", description = "删除菜单") @OperationLog(type = "03", module = "菜单管理", description = "删除菜单")
@ -330,6 +357,7 @@ public class AppMenuController {
* 菜单树节点 * 菜单树节点
*/ */
public static class MenuTreeNode { public static class MenuTreeNode {
private String id; private String id;
private String code; private String code;
private String name; private String name;
@ -344,42 +372,125 @@ public class AppMenuController {
private List<MenuTreeNode> children = new ArrayList<>(); private List<MenuTreeNode> children = new ArrayList<>();
// Getters and Setters // Getters and Setters
public String getId() { return id; } public String getId() {
public void setId(String id) { this.id = id; } return id;
public String getCode() { return code; } }
public void setCode(String code) { this.code = code; }
public String getName() { return name; } public void setId(String id) {
public void setName(String name) { this.name = name; } this.id = id;
public String getIcon() { return icon; } }
public void setIcon(String icon) { this.icon = icon; }
public String getUrl() { return url; } public String getCode() {
public void setUrl(String url) { this.url = url; } return code;
public String getType() { return type; } }
public void setType(String type) { this.type = type; }
public String getIslink() { return islink; } public void setCode(String code) {
public void setIslink(String islink) { this.islink = islink; } this.code = code;
public String getIsdisplay() { return isdisplay; } }
public void setIsdisplay(String isdisplay) { this.isdisplay = isdisplay; }
public Integer getOrderno() { return orderno; } public String getName() {
public void setOrderno(Integer orderno) { this.orderno = orderno; } return name;
public String getParentid() { return parentid; } }
public void setParentid(String parentid) { this.parentid = parentid; }
public String getModuleId() { return moduleId; } public void setName(String name) {
public void setModuleId(String moduleId) { this.moduleId = moduleId; } this.name = name;
public List<MenuTreeNode> getChildren() { return children; } }
public void setChildren(List<MenuTreeNode> children) { this.children = children; }
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 { public static class MenuOrderRequest {
private String id; private String id;
private Integer orderno; private Integer orderno;
public String getId() { return id; } public String getId() {
public void setId(String id) { this.id = id; } return id;
public Integer getOrderno() { return orderno; } }
public void setOrderno(Integer orderno) { this.orderno = orderno; }
public void setId(String id) {
this.id = id;
}
public Integer getOrderno() {
return orderno;
}
public void setOrderno(Integer orderno) {
this.orderno = orderno;
}
} }
} }

View File

@ -13,6 +13,7 @@ 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;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -33,6 +34,7 @@ import java.util.List;
@Tag(name = "操作日志管理", description = "操作日志查询、操作日志删除等功能") @Tag(name = "操作日志管理", description = "操作日志查询、操作日志删除等功能")
@RestController @RestController
@RequestMapping("/api/optlog") @RequestMapping("/api/optlog")
@Slf4j
public class AppOptLogController { public class AppOptLogController {
@Autowired @Autowired
@ -173,11 +175,21 @@ public class AppOptLogController {
@DeleteMapping("/clean/{days}") @DeleteMapping("/clean/{days}")
@OperationLog(type = "03", module = "操作日志管理", description = "清理历史操作日志") @OperationLog(type = "03", module = "操作日志管理", description = "清理历史操作日志")
public Result<String> cleanOldLogs(@Parameter(description = "保留天数") @PathVariable Integer days) { public Result<String> cleanOldLogs(@Parameter(description = "保留天数") @PathVariable Integer days) {
try {
// 参数校验
if (days == null || days < 0 || days > 3650) {
return Result.error("保留天数必须在0到3650之间");
}
LocalDateTime cutoff = LocalDateTime.now().minusDays(days); LocalDateTime cutoff = LocalDateTime.now().minusDays(days);
LambdaQueryWrapper<AppOptLog> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<AppOptLog> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.lt(AppOptLog::getLogtime, cutoff); queryWrapper.lt(AppOptLog::getLogtime, cutoff);
boolean success = appOptLogService.remove(queryWrapper); boolean success = appOptLogService.remove(queryWrapper);
return success ? Result.success("清理成功") : Result.error("清理失败"); return success ? Result.success("清理成功") : Result.error("清理失败");
} catch (Exception e) {
// 记录异常日志以便排查
log.error("清理操作日志失败", e);
return Result.error("系统异常,请稍后再试");
}
} }
@Operation(summary = "获取操作日志统计信息") @Operation(summary = "获取操作日志统计信息")

View File

@ -2,12 +2,14 @@ package com.stdproject.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 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.OperationLog;
import com.stdproject.common.Result; import com.stdproject.common.Result;
import com.stdproject.entity.AppOrganization; import com.stdproject.entity.AppOrganization;
import com.stdproject.service.IAppOrganizationService; import com.stdproject.service.IAppOrganizationService;
import com.stdproject.service.IAppUserService; import com.stdproject.service.IAppUserService;
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.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -68,8 +70,6 @@ public class AppOrganizationController {
return Result.success(children); return Result.success(children);
} }
@Operation(summary = "根据ID查询组织详情") @Operation(summary = "根据ID查询组织详情")
@GetMapping("getDetailById/{id}") @GetMapping("getDetailById/{id}")
@OperationLog(type = "06", module = "组织管理", description = "根据ID查询组织详情") @OperationLog(type = "06", module = "组织管理", description = "根据ID查询组织详情")
@ -78,7 +78,6 @@ public class AppOrganizationController {
return Result.success(organization); return Result.success(organization);
} }
@Operation(summary = "新增组织") @Operation(summary = "新增组织")
@PostMapping("add") @PostMapping("add")
@OperationLog(type = "01", module = "组织管理", description = "新增组织") @OperationLog(type = "01", module = "组织管理", description = "新增组织")
@ -126,6 +125,19 @@ public class AppOrganizationController {
return success ? Result.success("修改成功") : Result.error("修改失败"); 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 = "删除组织") @Operation(summary = "删除组织")
@PostMapping("delete/{id}") @PostMapping("delete/{id}")
@OperationLog(type = "03", module = "组织管理", description = "删除组织") @OperationLog(type = "03", module = "组织管理", description = "删除组织")
@ -203,7 +215,6 @@ public class AppOrganizationController {
} }
} }
private String getMaxCodeByParentId(String orgType, String parentId) { private String getMaxCodeByParentId(String orgType, String parentId) {
LambdaQueryWrapper<AppOrganization> queryWrapper = new LambdaQueryWrapper<AppOrganization>() LambdaQueryWrapper<AppOrganization> queryWrapper = new LambdaQueryWrapper<AppOrganization>()
.eq(AppOrganization::getOrgtype, orgType) .eq(AppOrganization::getOrgtype, orgType)

View File

@ -212,10 +212,19 @@ public class AuthController {
String token = request.getHeader(Constants.JWT_HEADER); String token = request.getHeader(Constants.JWT_HEADER);
if (token != null && token.startsWith(Constants.JWT_PREFIX)) { if (token != null && token.startsWith(Constants.JWT_PREFIX)) {
token = token.substring(Constants.JWT_PREFIX.length()); token = token.substring(Constants.JWT_PREFIX.length());
// 注意在实际应用中应该实现Token失效机制 // 实现token失效
// 可以考虑使用短期Token或其他方式实现Token失效 Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token);
// 此处省略Token黑名单实现 // 获取当前时间的时间戳毫秒
webConfig.loginuserCache().put(token, "1"); long nowMillis = System.currentTimeMillis();
// 获取 Token 过期时间的时间戳毫秒
long expirationMillis = expirationDateFromToken.getTime();
// 计算剩余有效时间毫秒
long remainingMillis = expirationMillis - nowMillis;
if (remainingMillis > 0) {
webConfig.loginuserCache().put(token, "1", remainingMillis);
}
} }
// 清除安全上下文 // 清除安全上下文
@ -281,6 +290,7 @@ public class AuthController {
} }
@PostMapping("/refreshToken") @PostMapping("/refreshToken")
@Operation(summary = "刷新令牌", description = "刷新当前用户的令牌")
public Result<String> refreshToken(@RequestBody Map<String, String> params) { public Result<String> refreshToken(@RequestBody Map<String, String> params) {
String refreshToken = params.get("refreshToken"); String refreshToken = params.get("refreshToken");
@ -309,5 +319,4 @@ public class AuthController {
Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token); Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token);
return Result.success(expirationDateFromToken); return Result.success(expirationDateFromToken);
} }
} }