lzq 2025-12-12 14:54:45 +08:00
parent 211b60e526
commit 0c07672e1f
24 changed files with 312 additions and 104 deletions

View File

@ -6,7 +6,7 @@ var dc = toDashCase(lcc);
var pageVueName = ucc + ".vue"; var pageVueName = ucc + ".vue";
var formVueName = ucc + "Form.vue"; var formVueName = ucc + "Form.vue";
var pageTsName = dc + ".ts"; var pageTsName = "page.ts";
var apiTsName = dc + "-api.ts"; var apiTsName = dc + "-api.ts";
var dTsName = dc + ".d.ts"; var dTsName = dc + ".d.ts";
%> %>

View File

@ -6,7 +6,7 @@ var dc = toDashCase(lcc);
var pageVueName = ucc + ".vue"; var pageVueName = ucc + ".vue";
var formVueName = ucc + "Form.vue"; var formVueName = ucc + "Form.vue";
var pageTsName = dc + ".ts"; var pageTsName = "page.ts";
var apiTsName = dc + "-api.ts"; var apiTsName = dc + "-api.ts";
var dTsName = dc + ".d.ts"; var dTsName = dc + ".d.ts";
%> %>

View File

@ -6,7 +6,7 @@ var dc = toDashCase(lcc);
var pageVueName = ucc + ".vue"; var pageVueName = ucc + ".vue";
var formVueName = ucc + "Form.vue"; var formVueName = ucc + "Form.vue";
var pageTsName = dc + ".ts"; var pageTsName = "page.ts";
var apiTsName = dc + "-api.ts"; var apiTsName = dc + "-api.ts";
var dTsName = dc + ".d.ts"; var dTsName = dc + ".d.ts";
%> %>

View File

@ -6,7 +6,7 @@ var dc = toDashCase(lcc);
var pageVueName = ucc + ".vue"; var pageVueName = ucc + ".vue";
var formVueName = ucc + "Form.vue"; var formVueName = ucc + "Form.vue";
var pageTsName = dc + ".ts"; var pageTsName = "page.ts";
var apiTsName = dc + "-api.ts"; var apiTsName = dc + "-api.ts";
var dTsName = dc + ".d.ts"; var dTsName = dc + ".d.ts";
%> %>

View File

@ -6,7 +6,7 @@ var dc = toDashCase(lcc);
var pageVueName = ucc + ".vue"; var pageVueName = ucc + ".vue";
var formVueName = ucc + "Form.vue"; var formVueName = ucc + "Form.vue";
var pageTsName = dc + ".ts"; var pageTsName = "page.ts";
var apiTsName = dc + "-api.ts"; var apiTsName = dc + "-api.ts";
var dTsName = dc + ".d.ts"; var dTsName = dc + ".d.ts";
%> %>

View File

@ -1,5 +1,7 @@
package com.njzscloud.common.mvc.validator; package com.njzscloud.common.mvc.validator;
public interface Constrained { public interface Constrained {
ValidRule[] rules(); default ValidRule[] rules() {
return new ValidRule[0];
}
} }

View File

@ -3,6 +3,7 @@ package com.njzscloud.common.security.config;
import cn.hutool.core.collection.CollUtil; import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import com.njzscloud.common.security.controller.PermissionController; import com.njzscloud.common.security.controller.PermissionController;
import com.njzscloud.common.security.controller.VerificationCodeController;
import com.njzscloud.common.security.handler.AccessDeniedExceptionHandler; import com.njzscloud.common.security.handler.AccessDeniedExceptionHandler;
import com.njzscloud.common.security.handler.AuthExceptionHandler; import com.njzscloud.common.security.handler.AuthExceptionHandler;
import com.njzscloud.common.security.handler.LogoutPostHandler; import com.njzscloud.common.security.handler.LogoutPostHandler;
@ -16,7 +17,6 @@ import com.njzscloud.common.security.permission.DefaultPermissionLoader;
import com.njzscloud.common.security.permission.PermissionLoader; import com.njzscloud.common.security.permission.PermissionLoader;
import com.njzscloud.common.security.permission.PermissionManager; import com.njzscloud.common.security.permission.PermissionManager;
import com.njzscloud.common.security.support.*; import com.njzscloud.common.security.support.*;
import com.njzscloud.common.security.support.controller.VerificationCodeController;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;

View File

@ -1,4 +1,4 @@
package com.njzscloud.common.security.support.controller; package com.njzscloud.common.security.controller;
import com.njzscloud.common.core.utils.R; import com.njzscloud.common.core.utils.R;
import com.njzscloud.common.security.support.VerificationCodeService; import com.njzscloud.common.security.support.VerificationCodeService;

View File

@ -18,6 +18,7 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.aop.support.AopUtils; import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnBooleanProperty;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -26,12 +27,14 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener; import org.springframework.context.event.EventListener;
import javax.sql.DataSource;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashSet; import java.util.HashSet;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@Slf4j @Slf4j
@Configuration @Configuration
@ConditionalOnBean(DataSource.class)
@MapperScan("com.njzscloud.common.sichen.mapper") @MapperScan("com.njzscloud.common.sichen.mapper")
@ConditionalOnBooleanProperty(prefix = "sichen.task", name = "enable") @ConditionalOnBooleanProperty(prefix = "sichen.task", name = "enable")
@EnableConfigurationProperties(TaskProperties.class) @EnableConfigurationProperties(TaskProperties.class)

View File

@ -28,10 +28,9 @@ public class WechatUtil {
public synchronized static void auth() { public synchronized static void auth() {
if (tokenExpTime <= new Date().getTime() / 1000 + 60) { if (tokenExpTime <= new Date().getTime() / 1000 + 60) {
GetAccessTokenResult getAccessTokenResult = API.getAccessToken(new GetAccessTokenParam()); GetAccessTokenResult getAccessTokenResult = API.getAccessToken(new GetAccessTokenParam());
Assert.isTrue(getAccessTokenResult.isSucc(), () -> Exceptions.error("微信登录失败"));
accessToken = getAccessTokenResult.getAccess_token(); accessToken = getAccessTokenResult.getAccess_token();
Integer expiresIn = getAccessTokenResult.getExpires_in(); Integer expiresIn = getAccessTokenResult.getExpires_in();
Assert.notBlank(accessToken, () -> Exceptions.error("微信登录失败"));
Assert.notNull(expiresIn, () -> Exceptions.error("微信登录失败"));
tokenExpTime = new Date().getTime() / 1000 + expiresIn; tokenExpTime = new Date().getTime() / 1000 + expiresIn;
} }
} }

View File

@ -1,5 +1,6 @@
package com.njzscloud.common.wechat.result; package com.njzscloud.common.wechat.result;
import cn.hutool.core.util.StrUtil;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@ -17,6 +18,6 @@ public class Code2SessionResult {
private Integer errcode; private Integer errcode;
public boolean isSucc() { public boolean isSucc() {
return errcode != null && errcode == 0; return (errcode != null && errcode == 0) || StrUtil.isNotBlank(openid);
} }
} }

View File

@ -1,5 +1,6 @@
package com.njzscloud.common.wechat.result; package com.njzscloud.common.wechat.result;
import cn.hutool.core.util.StrUtil;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.ToString; import lombok.ToString;
@ -12,4 +13,8 @@ import lombok.experimental.Accessors;
public class GetAccessTokenResult { public class GetAccessTokenResult {
private String access_token; private String access_token;
private Integer expires_in; private Integer expires_in;
public boolean isSucc() {
return StrUtil.isNotBlank(access_token) && (expires_in != null && expires_in > 0);
}
} }

View File

@ -1,20 +1,18 @@
package com.njzscloud.dispose.sys.endpoint.controller; package com.njzscloud.dispose.sys.endpoint.controller;
import com.njzscloud.common.core.utils.R; import com.njzscloud.common.core.utils.R;
import com.njzscloud.dispose.sys.endpoint.pojo.entity.EndpointEntity; import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.dispose.sys.endpoint.pojo.param.AddEndpointParam;
import com.njzscloud.dispose.sys.endpoint.pojo.param.EndpointSearchParam; import com.njzscloud.dispose.sys.endpoint.pojo.param.EndpointSearchParam;
import com.njzscloud.dispose.sys.endpoint.pojo.param.ModifyEndpointParam;
import com.njzscloud.dispose.sys.endpoint.pojo.result.EndpointDetailResult; import com.njzscloud.dispose.sys.endpoint.pojo.result.EndpointDetailResult;
import com.njzscloud.dispose.sys.endpoint.service.EndpointService; import com.njzscloud.dispose.sys.endpoint.service.EndpointService;
import com.njzscloud.dispose.sys.resource.pojo.result.ControllerMappingResult;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.*; import java.util.List;
/** /**
* *
@ -26,71 +24,13 @@ import java.util.*;
public class EndpointController { public class EndpointController {
private final EndpointService endpointService; private final EndpointService endpointService;
private final RequestMappingHandlerMapping requestMappingHandlerMapping;
public List<ControllerMappingResult> scanAllControllerMappings() {
List<ControllerMappingResult> result = new ArrayList<>();
// 1. 获取所有RequestMappingInfo包含映射规则和对应的HandlerMethod
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
// 2. 遍历解析每个映射规则
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
RequestMappingInfo requestMappingInfo = entry.getKey();
HandlerMethod handlerMethod = entry.getValue();
// 封装DTO
ControllerMappingResult dto = new ControllerMappingResult();
// === 解析控制器类信息 ===
Class<?> controllerClass = handlerMethod.getBeanType();
dto.setControllerClassName(controllerClass.getCanonicalName());
// === 解析类级@RequestMapping路径 ===
RequestMapping classRequestMapping = controllerClass.getAnnotation(RequestMapping.class);
String classPath = "";
if (classRequestMapping != null && classRequestMapping.value().length > 0) {
classPath = classRequestMapping.value()[0]; // 取第一个路径(支持数组,通常只用一个)
// 处理路径格式:确保以/开头避免拼接错误如类路径是endpoint → 补为/endpoint
if (!classPath.startsWith("/")) {
classPath = "/" + classPath;
}
}
// === 解析方法级路径 ===
Set<String> methodPatterns = requestMappingInfo.getPatternValues();
// 方法路径通常只有一个,取第一个即可
String methodPath = methodPatterns.iterator().next();
// === 拼接完整URL ===
String fullUrl = classPath + methodPath;
// 处理重复的/(如类路径/endpoint + 方法路径/add → /endpoint/add类路径/endpoint/ + 方法路径/add → /endpoint/add
fullUrl = fullUrl.replaceAll("//+", "/");
dto.setFullUrl(fullUrl);
// === 解析请求方法GET/POST等 ===
RequestMethodsRequestCondition methodsCondition = requestMappingInfo.getMethodsCondition();
Set<RequestMethod> methods = methodsCondition.getMethods();
Optional<RequestMethod> first = methods.stream().findFirst();
Optional<String> s = first.map(Enum::name);
dto.setHttpMethods(s.orElse(""));
// === 解析方法名 ===
dto.setMethodName(handlerMethod.getMethod().getName());
result.add(dto);
}
return result;
}
/** /**
* *
*/ */
@PostMapping("/add") @PostMapping("/add")
public R<?> add(@RequestBody EndpointEntity endpointEntity) { public R<?> add(@RequestBody AddEndpointParam addEndpointParam) {
endpointService.add(endpointEntity); endpointService.add(addEndpointParam);
return R.success(); return R.success();
} }
@ -98,8 +38,8 @@ public class EndpointController {
* *
*/ */
@PostMapping("/modify") @PostMapping("/modify")
public R<?> modify(@RequestBody EndpointEntity endpointEntity) { public R<?> modify(@RequestBody ModifyEndpointParam modifyEndpointParam) {
endpointService.modify(endpointEntity); endpointService.modify(modifyEndpointParam);
return R.success(); return R.success();
} }
@ -116,7 +56,7 @@ public class EndpointController {
* *
*/ */
@GetMapping("/detail") @GetMapping("/detail")
public R<EndpointEntity> detail(@RequestParam Long id) { public R<EndpointDetailResult> detail(@RequestParam("id") Long id) {
return R.success(endpointService.detail(id)); return R.success(endpointService.detail(id));
} }
@ -128,12 +68,19 @@ public class EndpointController {
return R.success(endpointService.listAll(endpointSearchParam)); return R.success(endpointService.listAll(endpointSearchParam));
} }
/**
*
*/
@GetMapping("/paging")
public R<PageResult<EndpointDetailResult>> paging(PageParam pageParam, EndpointSearchParam endpointSearchParam) {
return R.success(endpointService.paging(pageParam, endpointSearchParam));
}
/** /**
* *
*/ */
@GetMapping("/reload") @GetMapping("/reload")
public R<?> reload() { public R<?> reload() {
endpointService.saveAll(scanAllControllerMappings()); endpointService.saveAll();
return R.success(); return R.success();
} }

View File

@ -0,0 +1,49 @@
package com.njzscloud.dispose.sys.endpoint.pojo.param;
import com.njzscloud.common.security.contant.EndpointAccessModel;
import com.njzscloud.dispose.sys.endpoint.contant.RequestMethod;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
/**
*
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class AddEndpointParam {
/**
* ; request_method
*/
@NotNull(message = "请求方式不能为空")
private RequestMethod requestMethod;
/**
* ; /
*/
private String routingPath;
/**
* ; / , Ant
*/
@NotBlank(message = "端点地址不能为空")
private String endpointPath;
/**
* 访; endpoint_access_model
*/
@NotNull(message = "访问模式不能为空")
private EndpointAccessModel accessModel;
/**
*
*/
private String memo;
}

View File

@ -0,0 +1,55 @@
package com.njzscloud.dispose.sys.endpoint.pojo.param;
import com.njzscloud.common.security.contant.EndpointAccessModel;
import com.njzscloud.dispose.sys.endpoint.contant.RequestMethod;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.Accessors;
/**
*
*/
@Getter
@Setter
@ToString
@Accessors(chain = true)
public class ModifyEndpointParam {
/**
* Id
*/
@NotNull
private Long id;
/**
* ; request_method
*/
@NotNull(message = "请求方式不能为空")
private RequestMethod requestMethod;
/**
* ; /
*/
private String routingPath;
/**
* ; / , Ant
*/
@NotBlank(message = "端点地址不能为空")
private String endpointPath;
/**
* 访; endpoint_access_model
*/
@NotNull(message = "访问模式不能为空")
private EndpointAccessModel accessModel;
/**
*
*/
private String memo;
}

View File

@ -1,25 +1,37 @@
package com.njzscloud.dispose.sys.endpoint.service; package com.njzscloud.dispose.sys.endpoint.service;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.njzscloud.common.core.ex.Exceptions;
import com.njzscloud.common.core.utils.GroupUtil; import com.njzscloud.common.core.utils.GroupUtil;
import com.njzscloud.common.mp.support.PageParam;
import com.njzscloud.common.mp.support.PageResult;
import com.njzscloud.common.security.contant.EndpointAccessModel; import com.njzscloud.common.security.contant.EndpointAccessModel;
import com.njzscloud.dispose.sys.endpoint.contant.RequestMethod; import com.njzscloud.dispose.sys.endpoint.contant.RequestMethod;
import com.njzscloud.dispose.sys.endpoint.mapper.EndpointMapper; import com.njzscloud.dispose.sys.endpoint.mapper.EndpointMapper;
import com.njzscloud.dispose.sys.endpoint.pojo.entity.EndpointEntity; import com.njzscloud.dispose.sys.endpoint.pojo.entity.EndpointEntity;
import com.njzscloud.dispose.sys.endpoint.pojo.param.AddEndpointParam;
import com.njzscloud.dispose.sys.endpoint.pojo.param.EndpointSearchParam; import com.njzscloud.dispose.sys.endpoint.pojo.param.EndpointSearchParam;
import com.njzscloud.dispose.sys.endpoint.pojo.param.ModifyEndpointParam;
import com.njzscloud.dispose.sys.endpoint.pojo.result.EndpointDetailResult; import com.njzscloud.dispose.sys.endpoint.pojo.result.EndpointDetailResult;
import com.njzscloud.dispose.sys.resource.contant.ResourceOrigin;
import com.njzscloud.dispose.sys.resource.pojo.entity.ResourceEntity;
import com.njzscloud.dispose.sys.resource.pojo.result.ControllerMappingResult; import com.njzscloud.dispose.sys.resource.pojo.result.ControllerMappingResult;
import com.njzscloud.dispose.sys.resource.service.ResourceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.util.List; import java.util.*;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
/** /**
@ -27,20 +39,65 @@ import java.util.stream.Collectors;
*/ */
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor
public class EndpointService extends ServiceImpl<EndpointMapper, EndpointEntity> implements IService<EndpointEntity> { public class EndpointService extends ServiceImpl<EndpointMapper, EndpointEntity> implements IService<EndpointEntity> {
private final ResourceService resourceService;
private final RequestMappingHandlerMapping requestMappingHandlerMapping;
/** /**
* *
*/ */
public void add(EndpointEntity endpointEntity) { @Transactional(rollbackFor = Exception.class)
public void add(AddEndpointParam addEndpointParam) {
EndpointEntity endpointEntity = BeanUtil.copyProperties(addEndpointParam, EndpointEntity.class);
RequestMethod requestMethod = addEndpointParam.getRequestMethod();
String endpointPath = addEndpointParam.getEndpointPath();
boolean exists = this.exists(Wrappers.<EndpointEntity>lambdaQuery()
.eq(EndpointEntity::getRequestMethod, requestMethod)
.eq(EndpointEntity::getEndpointPath, endpointPath)
);
Assert.isFalse(exists, () -> Exceptions.exception("端点重复"));
this.save(endpointEntity); this.save(endpointEntity);
String sn = requestMethod + endpointPath;
resourceService.save(new ResourceEntity()
.setSn(sn)
.setDataId(endpointEntity.getId())
.setTableName(ResourceOrigin.Endpoint.getVal())
.setMemo("端点资源-" + requestMethod + " " + endpointPath));
} }
/** /**
* *
*/ */
public void modify(EndpointEntity endpointEntity) { @Transactional(rollbackFor = Exception.class)
public void modify(ModifyEndpointParam modifyEndpointParam) {
Long id = modifyEndpointParam.getId();
EndpointEntity oldData = this.getById(id);
Assert.notNull(oldData, () -> Exceptions.exception("要修改的数据不存在"));
RequestMethod requestMethod = modifyEndpointParam.getRequestMethod();
String endpointPath = modifyEndpointParam.getEndpointPath();
boolean exists = this.exists(Wrappers.<EndpointEntity>lambdaQuery()
.eq(EndpointEntity::getRequestMethod, requestMethod)
.eq(EndpointEntity::getEndpointPath, endpointPath)
.ne(EndpointEntity::getId, id)
);
Assert.isFalse(exists, () -> Exceptions.exception("端点重复"));
EndpointEntity endpointEntity = BeanUtil.copyProperties(modifyEndpointParam, EndpointEntity.class);
this.updateById(endpointEntity); this.updateById(endpointEntity);
String sn = requestMethod + endpointPath;
resourceService.update(Wrappers.<ResourceEntity>lambdaUpdate()
.eq(ResourceEntity::getTableName, ResourceOrigin.Endpoint.getVal())
.eq(ResourceEntity::getDataId, id)
.set(ResourceEntity::getMemo, "端点资源-" + requestMethod + " " + endpointPath)
.set(ResourceEntity::getSn, sn)
);
} }
/** /**
@ -48,22 +105,39 @@ public class EndpointService extends ServiceImpl<EndpointMapper, EndpointEntity>
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void del(List<Long> ids) { public void del(List<Long> ids) {
boolean occupied = resourceService.occupied(ids, ResourceOrigin.Endpoint);
Assert.isFalse(occupied, () -> Exceptions.exception("端点已被分配,不能删除"));
this.removeBatchByIds(ids); this.removeBatchByIds(ids);
resourceService.delRes(ids, ResourceOrigin.Endpoint);
} }
/** /**
* *
*/ */
public EndpointEntity detail(Long id) { public EndpointDetailResult detail(Long id) {
return this.getById(id); EndpointEntity endpointEntity = this.getById(id);
return BeanUtil.copyProperties(endpointEntity, EndpointDetailResult.class);
}
/**
*
*/
public PageResult<EndpointDetailResult> paging(PageParam pageParam, EndpointSearchParam endpointSearchParam) {
String endpointPath = endpointSearchParam.getEndpointPath();
return PageResult.of(this.page(pageParam.toPage(), Wrappers.<EndpointEntity>lambdaQuery()
.like(StrUtil.isNotBlank(endpointPath), EndpointEntity::getEndpointPath, endpointPath)
.orderByAsc(EndpointEntity::getRequestMethod, EndpointEntity::getRoutingPath, EndpointEntity::getEndpointPath)
).convert(it -> BeanUtil.copyProperties(it, EndpointDetailResult.class)));
} }
/** /**
* *
*/ */
public List<EndpointDetailResult> listAll(EndpointSearchParam endpointSearchParam) { public List<EndpointDetailResult> listAll(EndpointSearchParam endpointSearchParam) {
String endpointPath = endpointSearchParam.getEndpointPath();
return this.list(Wrappers.<EndpointEntity>lambdaQuery() return this.list(Wrappers.<EndpointEntity>lambdaQuery()
.like(StrUtil.isNotBlank(endpointSearchParam.getEndpointPath()), EndpointEntity::getEndpointPath, endpointSearchParam.getEndpointPath()) .like(StrUtil.isNotBlank(endpointPath), EndpointEntity::getEndpointPath, endpointPath)
.orderByAsc(EndpointEntity::getRequestMethod, EndpointEntity::getRoutingPath, EndpointEntity::getEndpointPath) .orderByAsc(EndpointEntity::getRequestMethod, EndpointEntity::getRoutingPath, EndpointEntity::getEndpointPath)
) )
.stream() .stream()
@ -72,7 +146,8 @@ public class EndpointService extends ServiceImpl<EndpointMapper, EndpointEntity>
} }
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void saveAll(List<ControllerMappingResult> controllerMappingResults) { public void saveAll() {
List<ControllerMappingResult> controllerMappingResults = scanAllControllerMappings();
List<EndpointEntity> oldEndpoints = this.list(); List<EndpointEntity> oldEndpoints = this.list();
Map<String, EndpointEntity> map = GroupUtil.k_o(oldEndpoints, it -> it.getRequestMethod() + it.getEndpointPath()); Map<String, EndpointEntity> map = GroupUtil.k_o(oldEndpoints, it -> it.getRequestMethod() + it.getEndpointPath());
Set<String> endpointPaths = map.keySet(); Set<String> endpointPaths = map.keySet();
@ -89,5 +164,62 @@ public class EndpointService extends ServiceImpl<EndpointMapper, EndpointEntity>
.toList(); .toList();
this.saveBatch(list); this.saveBatch(list);
List<ResourceEntity> resourceEntities = list.stream().map(it -> {
RequestMethod requestMethod = it.getRequestMethod();
String endpointPath = it.getEndpointPath();
return new ResourceEntity()
.setSn(requestMethod + endpointPath)
.setDataId(it.getId())
.setTableName(ResourceOrigin.Endpoint.getVal())
.setMemo("接口资源-" + requestMethod + " " + endpointPath)
;
}).toList();
resourceService.saveBatch(resourceEntities);
}
public List<ControllerMappingResult> scanAllControllerMappings() {
List<ControllerMappingResult> result = new ArrayList<>();
// 1. 获取所有RequestMappingInfo包含映射规则和对应的HandlerMethod
Map<RequestMappingInfo, HandlerMethod> handlerMethods = requestMappingHandlerMapping.getHandlerMethods();
// 2. 遍历解析每个映射规则
for (Map.Entry<RequestMappingInfo, HandlerMethod> entry : handlerMethods.entrySet()) {
RequestMappingInfo requestMappingInfo = entry.getKey();
HandlerMethod handlerMethod = entry.getValue();
// 封装DTO
ControllerMappingResult dto = new ControllerMappingResult();
// === 解析控制器类信息 ===
Class<?> controllerClass = handlerMethod.getBeanType();
dto.setControllerClassName(controllerClass.getCanonicalName());
// === 解析方法级路径 ===
Set<String> methodPatterns = requestMappingInfo.getPatternValues();
// 方法路径通常只有一个,取第一个即可
// === 拼接完整URL ===
String fullUrl = methodPatterns.iterator().next();
// 处理重复的/(如类路径/endpoint + 方法路径/add → /endpoint/add类路径/endpoint/ + 方法路径/add → /endpoint/add
fullUrl = fullUrl.replaceAll("//+", "/");
dto.setFullUrl(fullUrl);
// === 解析请求方法GET/POST等 ===
RequestMethodsRequestCondition methodsCondition = requestMappingInfo.getMethodsCondition();
Set<org.springframework.web.bind.annotation.RequestMethod> methods = methodsCondition.getMethods();
Optional<org.springframework.web.bind.annotation.RequestMethod> first = methods.stream().findFirst();
Optional<String> s = first.map(Enum::name);
dto.setHttpMethods(s.orElse(""));
// === 解析方法名 ===
dto.setMethodName(handlerMethod.getMethod().getName());
result.add(dto);
}
return result;
} }
} }

View File

@ -21,8 +21,8 @@ import com.njzscloud.dispose.sys.menu.pojo.result.MenuDetailResult;
import com.njzscloud.dispose.sys.resource.contant.ResourceOrigin; import com.njzscloud.dispose.sys.resource.contant.ResourceOrigin;
import com.njzscloud.dispose.sys.resource.pojo.entity.ResourceEntity; import com.njzscloud.dispose.sys.resource.pojo.entity.ResourceEntity;
import com.njzscloud.dispose.sys.resource.service.ResourceService; import com.njzscloud.dispose.sys.resource.service.ResourceService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -35,10 +35,10 @@ import java.util.stream.Collectors;
*/ */
@Slf4j @Slf4j
@Service @Service
@RequiredArgsConstructor
public class MenuService extends ServiceImpl<MenuMapper, MenuEntity> implements IService<MenuEntity> { public class MenuService extends ServiceImpl<MenuMapper, MenuEntity> implements IService<MenuEntity> {
@Autowired private final ResourceService resourceService;
private ResourceService resourceService;
/** /**
* *

View File

@ -11,7 +11,7 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor @RequiredArgsConstructor
public enum ResourceOrigin implements DictStr { public enum ResourceOrigin implements DictStr {
Menu("sys_menu", "菜单"), Menu("sys_menu", "菜单"),
Endpoint("sys_endpoint", "接口"), Endpoint("sys_endpoint", "端点"),
; ;
private final String val; private final String val;

View File

@ -37,8 +37,11 @@ public class ResourceController {
} }
@GetMapping("/list_role_res") @GetMapping("/list_role_res")
public R<List<ResourceEntity>> listRoleRes(@RequestParam(value = "roleId") String roleId) { public R<List<ResourceEntity>> listRoleRes(
return R.success(resourceService.listRoleRes(roleId)); @RequestParam(value = "roleId") String roleId,
@RequestParam(value = "tableName", required = false) String tableName
) {
return R.success(resourceService.listRoleRes(roleId, tableName));
} }
} }

View File

@ -17,7 +17,7 @@ import java.util.List;
public interface ResourceMapper extends BaseMapper<ResourceEntity> { public interface ResourceMapper extends BaseMapper<ResourceEntity> {
List<String> occupied(@Param(Constants.WRAPPER) QueryWrapper<Object> ew); List<String> occupied(@Param(Constants.WRAPPER) QueryWrapper<Object> ew);
List<ResourceEntity> listRoleRes(@Param("roleId") String roleId); List<ResourceEntity> listRoleRes(@Param("ew") QueryWrapper<?> ew);
List<RolePermission> loadPermission(); List<RolePermission> loadPermission();

View File

@ -1,5 +1,6 @@
package com.njzscloud.dispose.sys.resource.service; package com.njzscloud.dispose.sys.resource.service;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -43,8 +44,10 @@ public class ResourceService extends ServiceImpl<ResourceMapper, ResourceEntity>
return !roles.isEmpty(); return !roles.isEmpty();
} }
public List<ResourceEntity> listRoleRes(String roleId) { public List<ResourceEntity> listRoleRes(String roleId, String tableName) {
return baseMapper.listRoleRes(roleId); return baseMapper.listRoleRes(Wrappers.query()
.eq("b.role_id", roleId)
.eq(StrUtil.isNotBlank(tableName), "a.table_name", tableName));
} }
@Override @Override

View File

@ -25,10 +25,12 @@ import java.util.List;
@ToString @ToString
@Accessors(chain = true) @Accessors(chain = true)
public class UserRegisterParam implements Constrained { public class UserRegisterParam implements Constrained {
@NotNull(message = "鉴权方式不能为空")
private AuthWay authWay; private AuthWay authWay;
/** /**
* *
*/ */
@NotBlank(message = "姓名不能为空")
private String nickname; private String nickname;
/** /**
* *
@ -37,6 +39,7 @@ public class UserRegisterParam implements Constrained {
/** /**
* *
*/ */
@NotBlank(message = "手机号不能为空")
private String phone; private String phone;
/** /**
* *
@ -56,12 +59,14 @@ public class UserRegisterParam implements Constrained {
/** /**
* *
*/ */
@Valid
@NotNull(message = "客户信息不能为空") @NotNull(message = "客户信息不能为空")
private Customer customer; private Customer customer;
/** /**
* *
*/ */
@Valid
private Org org; private Org org;
/** /**
@ -72,7 +77,6 @@ public class UserRegisterParam implements Constrained {
@Override @Override
public ValidRule[] rules() { public ValidRule[] rules() {
return new ValidRule[]{ return new ValidRule[]{
ValidRule.of(() -> StrUtil.isNotBlank(nickname), "用户昵称不能为空"),
ValidRule.of(() -> account != null, "账号信息不能为空"), ValidRule.of(() -> account != null, "账号信息不能为空"),
ValidRule.of(() -> !customer.getManager() || org != null, "组织信息不能为空"), ValidRule.of(() -> !customer.getManager() || org != null, "组织信息不能为空"),
}; };
@ -90,6 +94,7 @@ public class UserRegisterParam implements Constrained {
/** /**
* *
*/ */
@NotBlank(message = "账号不能为空")
private String username; private String username;
/** /**
* *
@ -98,6 +103,7 @@ public class UserRegisterParam implements Constrained {
/** /**
* *
*/ */
@NotBlank(message = "密码不能为空")
private String secret; private String secret;
/** /**
* openid * openid
@ -124,7 +130,7 @@ public class UserRegisterParam implements Constrained {
@Setter @Setter
@Constraint @Constraint
@Accessors(chain = true) @Accessors(chain = true)
public static class Customer { public static class Customer implements Constrained {
private Long userId; private Long userId;
/** /**
@ -161,7 +167,7 @@ public class UserRegisterParam implements Constrained {
@Setter @Setter
@Constraint @Constraint
@Accessors(chain = true) @Accessors(chain = true)
public static class Org { public static class Org implements Constrained {
/** /**
* Id * Id

View File

@ -7,6 +7,7 @@ spring:
auth-allows: auth-allows:
- /oss/** - /oss/**
- /endpoint/reload - /endpoint/reload
- /permission/refresh_cache
oss: oss:
type: ali type: ali

View File

@ -19,7 +19,9 @@
a.memo a.memo
FROM sys_resource a FROM sys_resource a
INNER JOIN sys_role_resource b ON b.res_id = a.id INNER JOIN sys_role_resource b ON b.res_id = a.id
WHERE b.role_id = ${roleId} <if test="ew.customSqlSegment != null and ew.customSqlSegment != ''">
${ew.customSqlSegment}
</if>
</select> </select>
<select id="loadPermission" resultType="com.njzscloud.common.security.permission.RolePermission"> <select id="loadPermission" resultType="com.njzscloud.common.security.permission.RolePermission">
SELECT b.request_method, SELECT b.request_method,