提交新增接口

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;
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地址
*/

View File

@ -2,6 +2,7 @@ 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;
@ -15,12 +16,15 @@ 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.newLRUCache(200);
return CacheUtil.newTimedCache(expirationMs);
}
/**

View File

@ -1,6 +1,7 @@
package com.stdproject.controller;
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;
@ -41,7 +42,6 @@ public class AppMenuController {
@Autowired
private IAppUserService appUserService;
@Operation(summary = "分页查询菜单列表")
@PostMapping("/page")
@OperationLog(type = "06", module = "菜单管理", description = "分页查询菜单列表")
@ -207,6 +207,33 @@ public class AppMenuController {
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 = "删除菜单")
@ -330,6 +357,7 @@ public class AppMenuController {
* 菜单树节点
*/
public static class MenuTreeNode {
private String id;
private String code;
private String name;
@ -344,42 +372,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;
}
}
}

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.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;
@ -33,6 +34,7 @@ import java.util.List;
@Tag(name = "操作日志管理", description = "操作日志查询、操作日志删除等功能")
@RestController
@RequestMapping("/api/optlog")
@Slf4j
public class AppOptLogController {
@Autowired
@ -173,11 +175,21 @@ public class AppOptLogController {
@DeleteMapping("/clean/{days}")
@OperationLog(type = "03", module = "操作日志管理", description = "清理历史操作日志")
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);
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 = "获取操作日志统计信息")

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.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 org.springframework.beans.factory.annotation.Autowired;
@ -51,7 +53,7 @@ public class AppOrganizationController {
@Operation(summary = "查询部门列表")
@GetMapping("/getDepartmentList")
@OperationLog(type = "06", module = "组织管理", description = "查询部门列表")
public Result<List<AppOrganization>> getDepartmentList(@RequestParam String parentid,@RequestParam String keystr) {
public Result<List<AppOrganization>> getDepartmentList(@RequestParam String parentid, @RequestParam String keystr) {
QueryWrapper<AppOrganization> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("orgtype", "02");
queryWrapper.eq("parentid", parentid);
@ -68,8 +70,6 @@ public class AppOrganizationController {
return Result.success(children);
}
@Operation(summary = "根据ID查询组织详情")
@GetMapping("getDetailById/{id}")
@OperationLog(type = "06", module = "组织管理", description = "根据ID查询组织详情")
@ -78,7 +78,6 @@ public class AppOrganizationController {
return Result.success(organization);
}
@Operation(summary = "新增组织")
@PostMapping("add")
@OperationLog(type = "01", module = "组织管理", description = "新增组织")
@ -126,6 +125,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 = "删除组织")
@ -156,7 +168,7 @@ public class AppOrganizationController {
String parentCode = parentOrg != null ? parentOrg.getOrgcode() : "01";
// 获取当前父节点下的最大子节点编码
String maxCompanyCode = getMaxCodeByParentId("01",parentId);
String maxCompanyCode = getMaxCodeByParentId("01", parentId);
int nextLevel = 1;
if (maxCompanyCode != null && !maxCompanyCode.isEmpty()) {
@ -182,7 +194,7 @@ public class AppOrganizationController {
}
// 获取该父节点下最大部门编号
String maxDeptCodeStr = getMaxCodeByParentId("02",parentId);
String maxDeptCodeStr = getMaxCodeByParentId("02", parentId);
int nextSeq = 1;
if (maxDeptCodeStr != null && !maxDeptCodeStr.isEmpty()) {
@ -203,8 +215,7 @@ public class AppOrganizationController {
}
}
private String getMaxCodeByParentId(String orgType,String parentId) {
private String getMaxCodeByParentId(String orgType, String parentId) {
LambdaQueryWrapper<AppOrganization> queryWrapper = new LambdaQueryWrapper<AppOrganization>()
.eq(AppOrganization::getOrgtype, orgType)
.eq(AppOrganization::getParentid, parentId)

View File

@ -212,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失效机制
// 可以考虑使用短期Token或其他方式实现Token失效
// 此处省略Token黑名单实现
webConfig.loginuserCache().put(token, "1");
// 实现token失效
Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token);
// 获取当前时间的时间戳毫秒
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")
@Operation(summary = "刷新令牌", description = "刷新当前用户的令牌")
public Result<String> refreshToken(@RequestBody Map<String, String> params) {
String refreshToken = params.get("refreshToken");
@ -309,5 +319,4 @@ public class AuthController {
Date expirationDateFromToken = jwtUtils.getExpirationDateFromToken(token);
return Result.success(expirationDateFromToken);
}
}