mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-09 08:57:17 +08:00
refactor(extension/crud): 重构 BaseController 内权限校验
1.移除 SaToken 依赖 2.移除 checkPermission 方法 3.新增 CrudApi 注解
This commit is contained in:
@@ -30,18 +30,6 @@
|
||||
<artifactId>continew-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<!-- 认证模块 - SaToken -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
<artifactId>continew-starter-auth-satoken</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
|
||||
<!-- 数据访问模块 - 核心模块 -->
|
||||
<dependency>
|
||||
<groupId>top.continew</groupId>
|
||||
|
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.annotation;
|
||||
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* CRUD(增删改查)API
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.7.5
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface CrudApi {
|
||||
|
||||
/**
|
||||
* API 类型
|
||||
*/
|
||||
Api value() default Api.LIST;
|
||||
}
|
@@ -17,6 +17,7 @@
|
||||
package top.continew.starter.extension.crud.annotation;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
import top.continew.starter.extension.crud.autoconfigure.CrudRequestMappingAutoConfiguration;
|
||||
import top.continew.starter.extension.crud.autoconfigure.CrudRestControllerAutoConfiguration;
|
||||
|
||||
import java.lang.annotation.*;
|
||||
@@ -30,5 +31,5 @@ import java.lang.annotation.*;
|
||||
@Target({ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Import({CrudRestControllerAutoConfiguration.class})
|
||||
@Import({CrudRequestMappingAutoConfiguration.class, CrudRestControllerAutoConfiguration.class})
|
||||
public @interface EnableCrudRestController {}
|
||||
|
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.aop;
|
||||
|
||||
import org.aopalliance.aop.Advice;
|
||||
import org.springframework.aop.Pointcut;
|
||||
import org.springframework.aop.support.AbstractPointcutAdvisor;
|
||||
import org.springframework.aop.support.ComposablePointcut;
|
||||
import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactory;
|
||||
import org.springframework.beans.factory.BeanFactoryAware;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* CRUD API 注解通知
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class CrudApiAnnotationAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
|
||||
|
||||
private final Advice advice;
|
||||
private final Pointcut pointcut;
|
||||
|
||||
public CrudApiAnnotationAdvisor(CrudApiAnnotationInterceptor advice, Class<? extends Annotation> annotation) {
|
||||
this.advice = advice;
|
||||
this.pointcut = new ComposablePointcut(AnnotationMatchingPointcut.forMethodAnnotation(annotation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pointcut getPointcut() {
|
||||
return this.pointcut;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Advice getAdvice() {
|
||||
return this.advice;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
|
||||
if (this.advice instanceof BeanFactoryAware beanFactoryAware) {
|
||||
beanFactoryAware.setBeanFactory(beanFactory);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.aop;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.core.BridgeMethodResolver;
|
||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import top.continew.starter.extension.crud.annotation.CrudApi;
|
||||
import top.continew.starter.extension.crud.handler.CrudApiHandler;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* CRUD API 注解拦截器
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class CrudApiAnnotationInterceptor implements MethodInterceptor {
|
||||
|
||||
private final CrudApiHandler handler;
|
||||
|
||||
public CrudApiAnnotationInterceptor(CrudApiHandler handler) {
|
||||
this.handler = handler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
// 获取目标类
|
||||
Class<?> targetClass = AopUtils.getTargetClass(Objects.requireNonNull(invocation.getThis()));
|
||||
// 获取目标方法
|
||||
Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass);
|
||||
Method targetMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);
|
||||
// 获取 @CrudApi 注解
|
||||
CrudApi crudApi = AnnotatedElementUtils.findMergedAnnotation(targetMethod, CrudApi.class);
|
||||
handler.preHandle(crudApi, targetMethod, targetClass);
|
||||
return invocation.proceed();
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.autoconfigure;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.ResourceUrlProvider;
|
||||
|
||||
/**
|
||||
* CRUD Request Mapping 自动配置
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties(CrudProperties.class)
|
||||
public class CrudRequestMappingAutoConfiguration extends DelegatingWebMvcConfiguration {
|
||||
|
||||
/**
|
||||
* CRUD 请求映射器处理器映射器(覆盖默认 RequestMappingHandlerMapping)
|
||||
*/
|
||||
@Override
|
||||
public RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
|
||||
return new CrudRequestMappingHandlerMapping();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
@Override
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
|
||||
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||
return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService, resourceUrlProvider);
|
||||
}
|
||||
}
|
@@ -19,44 +19,53 @@ package top.continew.starter.extension.crud.autoconfigure;
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.web.accept.ContentNegotiationManager;
|
||||
import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.ResourceUrlProvider;
|
||||
import top.continew.starter.extension.crud.annotation.CrudApi;
|
||||
import top.continew.starter.extension.crud.aop.CrudApiAnnotationAdvisor;
|
||||
import top.continew.starter.extension.crud.aop.CrudApiAnnotationInterceptor;
|
||||
import top.continew.starter.extension.crud.handler.CrudApiHandler;
|
||||
import top.continew.starter.extension.crud.handler.DefaultCrudApiHandler;
|
||||
|
||||
/**
|
||||
* CRUD REST Controller 自动配置
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 1.0.0
|
||||
* @since 2.7.5
|
||||
*/
|
||||
@Configuration
|
||||
@AutoConfiguration
|
||||
@EnableConfigurationProperties(CrudProperties.class)
|
||||
public class CrudRestControllerAutoConfiguration extends DelegatingWebMvcConfiguration {
|
||||
public class CrudRestControllerAutoConfiguration {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(CrudRestControllerAutoConfiguration.class);
|
||||
|
||||
/**
|
||||
* CRUD 请求映射器处理器映射器(覆盖默认 RequestMappingHandlerMapping)
|
||||
* CRUD API 注解通知
|
||||
*/
|
||||
@Override
|
||||
public RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
|
||||
return new CrudRequestMappingHandlerMapping();
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CrudApiAnnotationAdvisor crudApiAnnotationAdvisor(CrudApiAnnotationInterceptor crudApiAnnotationInterceptor) {
|
||||
return new CrudApiAnnotationAdvisor(crudApiAnnotationInterceptor, CrudApi.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* CRUD API 注解拦截器
|
||||
*/
|
||||
@Bean
|
||||
@Primary
|
||||
@Override
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping(@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
|
||||
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
|
||||
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
|
||||
return super.requestMappingHandlerMapping(contentNegotiationManager, conversionService, resourceUrlProvider);
|
||||
@ConditionalOnMissingBean
|
||||
public CrudApiAnnotationInterceptor crudApiAnnotationInterceptor(CrudApiHandler crudApiHandler) {
|
||||
return new CrudApiAnnotationInterceptor(crudApiHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* CRUD API 处理器(默认)
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public CrudApiHandler crudApiHandler() {
|
||||
return new DefaultCrudApiHandler();
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
|
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.handler;
|
||||
|
||||
import top.continew.starter.extension.crud.annotation.CrudApi;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* CRUD API 处理器
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public interface CrudApiHandler {
|
||||
|
||||
/**
|
||||
* 前置处理
|
||||
*
|
||||
* @param crudApi CRUD API 注解
|
||||
* @param targetMethod 目标方法
|
||||
* @param targetClass 目标类
|
||||
* @throws Exception 处理异常
|
||||
*/
|
||||
void preHandle(CrudApi crudApi, Method targetMethod, Class<?> targetClass) throws Exception;
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2022-present Charles7c Authors. All Rights Reserved.
|
||||
* <p>
|
||||
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p>
|
||||
* http://www.gnu.org/licenses/lgpl.html
|
||||
* <p>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package top.continew.starter.extension.crud.handler;
|
||||
|
||||
import top.continew.starter.extension.crud.annotation.CrudApi;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
/**
|
||||
* CRUD API 处理器(默认)
|
||||
*
|
||||
* @author Charles7c
|
||||
* @since 2.7.5
|
||||
*/
|
||||
public class DefaultCrudApiHandler implements CrudApiHandler {
|
||||
|
||||
@Override
|
||||
public void preHandle(CrudApi crudApi, Method targetMethod, Class<?> targetClass) {
|
||||
// do nothing
|
||||
}
|
||||
}
|
@@ -16,9 +16,7 @@
|
||||
|
||||
package top.continew.starter.extension.crud.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import com.feiniaojin.gracefulresponse.api.ExcludeFromGracefulResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -27,8 +25,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.continew.starter.extension.crud.annotation.CrudApi;
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||
@@ -63,11 +60,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param pageQuery 分页查询条件
|
||||
* @return 分页信息
|
||||
*/
|
||||
@CrudApi(Api.PAGE)
|
||||
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
||||
@ResponseBody
|
||||
@GetMapping
|
||||
public PageResp<L> page(Q query, @Validated PageQuery pageQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.page(query, pageQuery);
|
||||
}
|
||||
|
||||
@@ -78,11 +75,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 列表信息
|
||||
*/
|
||||
@CrudApi(Api.LIST)
|
||||
@Operation(summary = "查询列表", description = "查询列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
public List<L> list(Q query, SortQuery sortQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.list(query, sortQuery);
|
||||
}
|
||||
|
||||
@@ -93,11 +90,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 树列表信息
|
||||
*/
|
||||
@CrudApi(Api.TREE)
|
||||
@Operation(summary = "查询树列表", description = "查询树列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/tree")
|
||||
public List<Tree<Long>> tree(Q query, SortQuery sortQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.tree(query, sortQuery, false);
|
||||
}
|
||||
|
||||
@@ -107,41 +104,41 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param id ID
|
||||
* @return 详情信息
|
||||
*/
|
||||
@CrudApi(Api.DETAIL)
|
||||
@Operation(summary = "查询详情", description = "查询详情")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@GetMapping("/{id}")
|
||||
public D detail(@PathVariable("id") Long id) {
|
||||
this.checkPermission(Api.DETAIL);
|
||||
return baseService.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
* @param req 创建信息
|
||||
* @return 自增 ID
|
||||
* @param req 创建参数
|
||||
* @return ID
|
||||
*/
|
||||
@CrudApi(Api.ADD)
|
||||
@Operation(summary = "新增数据", description = "新增数据")
|
||||
@ResponseBody
|
||||
@PostMapping
|
||||
public BaseIdResp<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody C req) {
|
||||
this.checkPermission(Api.ADD);
|
||||
return new BaseIdResp<>(baseService.add(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param req 修改信息
|
||||
* @param req 修改参数
|
||||
* @param id ID
|
||||
*/
|
||||
@CrudApi(Api.UPDATE)
|
||||
@Operation(summary = "修改数据", description = "修改数据")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@PutMapping("/{id}")
|
||||
public void update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody C req, @PathVariable("id") Long id) {
|
||||
this.checkPermission(Api.UPDATE);
|
||||
baseService.update(req, id);
|
||||
}
|
||||
|
||||
@@ -150,12 +147,12 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
*
|
||||
* @param ids ID 列表
|
||||
*/
|
||||
@CrudApi(Api.DELETE)
|
||||
@Operation(summary = "删除数据", description = "删除数据")
|
||||
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@DeleteMapping("/{ids}")
|
||||
public void delete(@PathVariable("ids") List<Long> ids) {
|
||||
this.checkPermission(Api.DELETE);
|
||||
baseService.delete(ids);
|
||||
}
|
||||
|
||||
@@ -166,24 +163,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param sortQuery 排序查询条件
|
||||
* @param response 响应对象
|
||||
*/
|
||||
@CrudApi(Api.EXPORT)
|
||||
@ExcludeFromGracefulResponse
|
||||
@Operation(summary = "导出数据", description = "导出数据")
|
||||
@GetMapping("/export")
|
||||
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
|
||||
this.checkPermission(Api.EXPORT);
|
||||
baseService.export(query, sortQuery, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 API 类型进行权限验证
|
||||
*
|
||||
* @param api API 类型
|
||||
*/
|
||||
protected void checkPermission(Api api) {
|
||||
CrudRequestMapping crudRequestMapping = this.getClass().getDeclaredAnnotation(CrudRequestMapping.class);
|
||||
String path = crudRequestMapping.value();
|
||||
String permissionPrefix = String.join(StringConstants.COLON, CharSequenceUtil
|
||||
.splitTrim(path, StringConstants.SLASH));
|
||||
StpUtil.checkPermission("%s:%s".formatted(permissionPrefix, api.name().toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
@@ -16,9 +16,7 @@
|
||||
|
||||
package top.continew.starter.extension.crud.controller;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import com.feiniaojin.gracefulresponse.api.ExcludeFromGracefulResponse;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
@@ -27,8 +25,7 @@ import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.extension.crud.annotation.CrudRequestMapping;
|
||||
import top.continew.starter.extension.crud.annotation.CrudApi;
|
||||
import top.continew.starter.extension.crud.enums.Api;
|
||||
import top.continew.starter.extension.crud.model.query.PageQuery;
|
||||
import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||
@@ -63,11 +60,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param pageQuery 分页查询条件
|
||||
* @return 分页信息
|
||||
*/
|
||||
@CrudApi(Api.PAGE)
|
||||
@Operation(summary = "分页查询列表", description = "分页查询列表")
|
||||
@ResponseBody
|
||||
@GetMapping
|
||||
public PageResp<L> page(Q query, @Validated PageQuery pageQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.page(query, pageQuery);
|
||||
}
|
||||
|
||||
@@ -78,11 +75,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 列表信息
|
||||
*/
|
||||
@CrudApi(Api.LIST)
|
||||
@Operation(summary = "查询列表", description = "查询列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/list")
|
||||
public List<L> list(Q query, SortQuery sortQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.list(query, sortQuery);
|
||||
}
|
||||
|
||||
@@ -93,11 +90,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 树列表信息
|
||||
*/
|
||||
@CrudApi(Api.TREE)
|
||||
@Operation(summary = "查询树列表", description = "查询树列表")
|
||||
@ResponseBody
|
||||
@GetMapping("/tree")
|
||||
public List<Tree<Long>> tree(Q query, SortQuery sortQuery) {
|
||||
this.checkPermission(Api.LIST);
|
||||
return baseService.tree(query, sortQuery, false);
|
||||
}
|
||||
|
||||
@@ -107,41 +104,41 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param id ID
|
||||
* @return 详情信息
|
||||
*/
|
||||
@CrudApi(Api.DETAIL)
|
||||
@Operation(summary = "查询详情", description = "查询详情")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@GetMapping("/{id}")
|
||||
public D detail(@PathVariable("id") Long id) {
|
||||
this.checkPermission(Api.DETAIL);
|
||||
return baseService.get(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*
|
||||
* @param req 创建信息
|
||||
* @return 自增 ID
|
||||
* @param req 创建参数
|
||||
* @return ID
|
||||
*/
|
||||
@CrudApi(Api.ADD)
|
||||
@Operation(summary = "新增数据", description = "新增数据")
|
||||
@ResponseBody
|
||||
@PostMapping
|
||||
public BaseIdResp<Long> add(@Validated(ValidateGroup.Crud.Add.class) @RequestBody C req) {
|
||||
this.checkPermission(Api.ADD);
|
||||
return new BaseIdResp<>(baseService.add(req));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param req 修改信息
|
||||
* @param req 修改参数
|
||||
* @param id ID
|
||||
*/
|
||||
@CrudApi(Api.UPDATE)
|
||||
@Operation(summary = "修改数据", description = "修改数据")
|
||||
@Parameter(name = "id", description = "ID", example = "1", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@PutMapping("/{id}")
|
||||
public void update(@Validated(ValidateGroup.Crud.Update.class) @RequestBody C req, @PathVariable("id") Long id) {
|
||||
this.checkPermission(Api.UPDATE);
|
||||
baseService.update(req, id);
|
||||
}
|
||||
|
||||
@@ -150,12 +147,12 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
*
|
||||
* @param ids ID 列表
|
||||
*/
|
||||
@CrudApi(Api.DELETE)
|
||||
@Operation(summary = "删除数据", description = "删除数据")
|
||||
@Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH)
|
||||
@ResponseBody
|
||||
@DeleteMapping("/{ids}")
|
||||
public void delete(@PathVariable("ids") List<Long> ids) {
|
||||
this.checkPermission(Api.DELETE);
|
||||
baseService.delete(ids);
|
||||
}
|
||||
|
||||
@@ -166,24 +163,11 @@ public abstract class BaseController<S extends BaseService<L, D, Q, C>, L, D, Q,
|
||||
* @param sortQuery 排序查询条件
|
||||
* @param response 响应对象
|
||||
*/
|
||||
@CrudApi(Api.EXPORT)
|
||||
@ExcludeFromGracefulResponse
|
||||
@Operation(summary = "导出数据", description = "导出数据")
|
||||
@GetMapping("/export")
|
||||
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
|
||||
this.checkPermission(Api.EXPORT);
|
||||
baseService.export(query, sortQuery, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 API 类型进行权限验证
|
||||
*
|
||||
* @param api API 类型
|
||||
*/
|
||||
protected void checkPermission(Api api) {
|
||||
CrudRequestMapping crudRequestMapping = this.getClass().getDeclaredAnnotation(CrudRequestMapping.class);
|
||||
String path = crudRequestMapping.value();
|
||||
String permissionPrefix = String.join(StringConstants.COLON, CharSequenceUtil
|
||||
.splitTrim(path, StringConstants.SLASH));
|
||||
StpUtil.checkPermission("%s:%s".formatted(permissionPrefix, api.name().toLowerCase()));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user