From 3b821041a31e49cf2926809bb910547df66cc120 Mon Sep 17 00:00:00 2001 From: Shikong <919411476@qq.com> Date: Mon, 8 May 2023 20:17:37 +0800 Subject: [PATCH] =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=20Claim=20HandlerMe?= =?UTF-8?q?thodArgumentResolver?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inspectionProfiles/Project_Default.xml | 12 +++++++ .../matrix/v2/advice/ExceptionAdvice.java | 10 +++++- .../record/LocationRecordController.java | 35 ++++++++++++++++--- .../interceptor/AuthorizationInterceptor.java | 2 ++ .../convert/LocationRecordConvertor.java | 6 ++-- .../record/dto/LocationRecordParams.java | 2 ++ .../record/dto/PageLocationRecordParams.java | 22 ++++++++++++ .../cn/skcks/matrix/v2/auth/claims/Claim.java | 21 +++++++++++ .../matrix/v2/auth/claims/ClaimException.java | 7 ++++ .../matrix/v2/auth/claims/ClaimResolver.java | 32 +++++++++++++++++ .../cn/skcks/matrix/v2/config/WebConfig.java | 9 +++++ .../record/LocationRecordService.java | 8 +++-- .../record/LocationRecordServiceImpl.java | 27 ++++++++++++-- 13 files changed, 179 insertions(+), 14 deletions(-) create mode 100644 backend/java/sk-matrix-service/.idea/inspectionProfiles/Project_Default.xml create mode 100644 backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/PageLocationRecordParams.java create mode 100644 backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/Claim.java create mode 100644 backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimException.java create mode 100644 backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimResolver.java diff --git a/backend/java/sk-matrix-service/.idea/inspectionProfiles/Project_Default.xml b/backend/java/sk-matrix-service/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..83e6c53 --- /dev/null +++ b/backend/java/sk-matrix-service/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,12 @@ + + + + \ No newline at end of file diff --git a/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/advice/ExceptionAdvice.java b/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/advice/ExceptionAdvice.java index 92f0e31..bb7e677 100644 --- a/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/advice/ExceptionAdvice.java +++ b/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/advice/ExceptionAdvice.java @@ -1,6 +1,9 @@ package cn.skcks.matrix.v2.advice; +import cn.skcks.matrix.v2.auth.claims.ClaimException; +import cn.skcks.matrix.v2.model.casbin.CasbinConstant; import cn.skcks.matrix.v2.utils.json.JsonResponse; +import cn.skcks.matrix.v2.utils.json.ResponseStatus; import jakarta.validation.ConstraintViolationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,8 +28,13 @@ import java.util.Objects; public class ExceptionAdvice { private final static Logger logger = LoggerFactory.getLogger(ExceptionAdvice.class); + @ExceptionHandler(ClaimException.class) + public JsonResponse ClaimException(ClaimException e){ + return JsonResponse.build(ResponseStatus.UNAUTHORIZED, e.getMessage()); + } + @ExceptionHandler(MissingServletRequestParameterException.class) - public JsonResponse MissingServletRequestParameterException(MissingServletRequestParameterException e) { + public JsonResponse missingServletRequestParameterException(MissingServletRequestParameterException e) { return JsonResponse.error(e.getMessage()); } diff --git a/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/api/locatioin/record/LocationRecordController.java b/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/api/locatioin/record/LocationRecordController.java index 5630eea..3a5c158 100644 --- a/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/api/locatioin/record/LocationRecordController.java +++ b/backend/java/sk-matrix-service/api/src/main/java/cn/skcks/matrix/v2/api/locatioin/record/LocationRecordController.java @@ -1,29 +1,42 @@ package cn.skcks.matrix.v2.api.locatioin.record; import cn.skcks.matrix.v2.annotation.web.JsonMapping; +import cn.skcks.matrix.v2.annotation.web.auth.Auth; +import cn.skcks.matrix.v2.auth.claims.Claim; import cn.skcks.matrix.v2.annotation.web.methods.PostJson; import cn.skcks.matrix.v2.config.swagger.SwaggerConfig; +import cn.skcks.matrix.v2.model.jwt.dto.Claims; +import cn.skcks.matrix.v2.model.location.record.convert.LocationRecordConvertor; import cn.skcks.matrix.v2.model.location.record.dto.LocationRecordParams; +import cn.skcks.matrix.v2.model.location.record.dto.PageLocationRecordParams; import cn.skcks.matrix.v2.model.location.record.vo.LocationRecordVo; +import cn.skcks.matrix.v2.model.services.ServiceResult; +import cn.skcks.matrix.v2.orm.mybatis.dynamic.model.LocationRecord; +import cn.skcks.matrix.v2.services.jwt.JwtService; import cn.skcks.matrix.v2.services.location.record.LocationRecordService; import cn.skcks.matrix.v2.utils.json.JsonResponse; +import cn.skcks.matrix.v2.utils.page.PageWrapper; +import com.github.pagehelper.PageInfo; import io.swagger.v3.oas.annotations.Operation; -import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springdoc.core.models.GroupedOpenApi; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import java.util.Collection; -import java.util.List; +@Auth @Tag(name = "定位记录") @RestController @JsonMapping("/location/record") @RequiredArgsConstructor +@Slf4j public class LocationRecordController { + private final JwtService jwtService; private final LocationRecordService locationRecordService; @Bean @@ -31,9 +44,21 @@ public class LocationRecordController { return SwaggerConfig.api("Location Record", "/location/record"); } - @PostJson("/") + @PostJson("/list") @Operation(summary = "查询记录") - public JsonResponse> getLocationRecord(@RequestBody LocationRecordParams params){ - return locationRecordService.getLocationRecord(params).parseResponse(); + public JsonResponse> getLocationRecord(@Claim Claims claims, @RequestBody LocationRecordParams params){ + log.info("claims {}", claims); + ServiceResult> result = locationRecordService.getLocationRecord(params, claims.getUserId()); + return JsonResponse.success(LocationRecordConvertor.INSTANCE.daoToVo(result.getResult())); + } + + @PostJson("/page") + @Operation(summary = "分页查询记录") + public JsonResponse> getPageLocationRecord(@RequestBody PageLocationRecordParams params, @RequestHeader("token") String token){ + Claims claims = jwtService.parseToken(token); + PageInfo pageInfo = + LocationRecordConvertor.INSTANCE.daoToVo(locationRecordService.getPageLocationRecord(params, claims.getUserId()).getResult()); + + return JsonResponse.success(PageWrapper.of(pageInfo)); } } diff --git a/backend/java/sk-matrix-service/auth/src/main/java/cn/skcks/matrix/v2/interceptor/AuthorizationInterceptor.java b/backend/java/sk-matrix-service/auth/src/main/java/cn/skcks/matrix/v2/interceptor/AuthorizationInterceptor.java index d4cff63..13119c5 100644 --- a/backend/java/sk-matrix-service/auth/src/main/java/cn/skcks/matrix/v2/interceptor/AuthorizationInterceptor.java +++ b/backend/java/sk-matrix-service/auth/src/main/java/cn/skcks/matrix/v2/interceptor/AuthorizationInterceptor.java @@ -5,6 +5,7 @@ import cn.skcks.matrix.v2.annotation.web.auth.UnAuth; import cn.skcks.matrix.v2.handler.AuthHandler; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.lang.NonNull; @@ -20,6 +21,7 @@ import java.util.List; @Component @SuppressWarnings({"unused"}) @ConditionalOnClass({Auth.class, UnAuth.class}) +@RequiredArgsConstructor public class AuthorizationInterceptor implements HandlerInterceptor { private final List authHandlers = new ArrayList<>(); diff --git a/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/convert/LocationRecordConvertor.java b/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/convert/LocationRecordConvertor.java index e82212d..a17670e 100644 --- a/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/convert/LocationRecordConvertor.java +++ b/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/convert/LocationRecordConvertor.java @@ -18,9 +18,9 @@ public abstract class LocationRecordConvertor { @Mapping(source = "id", target = "id"), @Mapping(source = "userId", target = "userId") }) - abstract public LocationRecordVo daoToVo(LocationRecord user); + abstract public LocationRecordVo daoToVo(LocationRecord dao); - abstract public Collection daoToVo(Collection users); + abstract public Collection daoToVo(Collection dao); - abstract public PageInfo daoToVo(PageInfo userPageInfo); + abstract public PageInfo daoToVo(PageInfo daoPageInfo); } diff --git a/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/LocationRecordParams.java b/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/LocationRecordParams.java index a2e01d5..3d5fb9b 100644 --- a/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/LocationRecordParams.java +++ b/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/LocationRecordParams.java @@ -1,11 +1,13 @@ package cn.skcks.matrix.v2.model.location.record.dto; import com.fasterxml.jackson.annotation.JsonFormat; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.util.Date; +@Schema(title = "按时间段 查询定位记录列表") @Data public class LocationRecordParams { @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") diff --git a/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/PageLocationRecordParams.java b/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/PageLocationRecordParams.java new file mode 100644 index 0000000..8a70ba4 --- /dev/null +++ b/backend/java/sk-matrix-service/model/src/main/java/cn/skcks/matrix/v2/model/location/record/dto/PageLocationRecordParams.java @@ -0,0 +1,22 @@ +package cn.skcks.matrix.v2.model.location.record.dto; + +import io.swagger.v3.oas.annotations.media.Schema; +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import lombok.EqualsAndHashCode; + +@Schema(title = "按时间段 分页查询定位记录列表") +@EqualsAndHashCode(callSuper = true) +@Data +public class PageLocationRecordParams extends LocationRecordParams{ + @Schema(description = "页数") + @NotNull(message = "page 不能为空") + @Min(value = 1, message = "page 必须为正整数") + int page; + + @Schema(description = "每页条数", example = "10") + @NotNull(message = "size 不能为空") + @Min(value = 1, message = "size 必须为正整数") + int size; +} diff --git a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/Claim.java b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/Claim.java new file mode 100644 index 0000000..9272cd0 --- /dev/null +++ b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/Claim.java @@ -0,0 +1,21 @@ +package cn.skcks.matrix.v2.auth.claims; + +import io.swagger.v3.oas.annotations.Hidden; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * 向 Controller 参数 注入 Claims + * 从请求头的 token 解析 Claims 并注入到 Controller 参数中 + * @author Shikong + */ +@Target({ElementType.PARAMETER}) +@Retention(RetentionPolicy.RUNTIME) +@Hidden +@SuppressWarnings({"unused"}) +public @interface Claim { + boolean required() default true; +} diff --git a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimException.java b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimException.java new file mode 100644 index 0000000..f7893b9 --- /dev/null +++ b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimException.java @@ -0,0 +1,7 @@ +package cn.skcks.matrix.v2.auth.claims; + +public class ClaimException extends Exception{ + ClaimException(){ + super("未登录"); + } +} diff --git a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimResolver.java b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimResolver.java new file mode 100644 index 0000000..4c5558a --- /dev/null +++ b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/auth/claims/ClaimResolver.java @@ -0,0 +1,32 @@ +package cn.skcks.matrix.v2.auth.claims; + +import cn.skcks.matrix.v2.model.jwt.dto.Claims; +import cn.skcks.matrix.v2.services.jwt.JwtService; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.StringUtils; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@RequiredArgsConstructor +@Component +public class ClaimResolver implements HandlerMethodArgumentResolver { + private final JwtService jwtService; + @Override + public boolean supportsParameter(MethodParameter methodParameter) { + return methodParameter.hasMethodAnnotation(Claim.class) || methodParameter.getParameterType().equals(Claims.class); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + String token = webRequest.getHeader("token"); + if(StringUtils.isBlank(token)){ + throw new ClaimException(); + } + + return jwtService.parseToken(token); + } +} diff --git a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/config/WebConfig.java b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/config/WebConfig.java index 559ec89..866fbda 100644 --- a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/config/WebConfig.java +++ b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/config/WebConfig.java @@ -1,5 +1,6 @@ package cn.skcks.matrix.v2.config; +import cn.skcks.matrix.v2.auth.claims.ClaimResolver; import cn.skcks.matrix.v2.interceptor.AuthorizationInterceptor; import cn.skcks.matrix.v2.model.jwt.dto.Claims; import cn.skcks.matrix.v2.services.auth.AuthService; @@ -16,6 +17,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @@ -34,12 +36,18 @@ public class WebConfig implements WebMvcConfigurer { private final AuthService authService; private final CasbinService casbinService; + private final ClaimResolver claimResolver; private final static JsonResponse NO_LOGIN = JsonResponse.build( ResponseStatus.UNAUTHORIZED,"未登录"); private final static JsonResponse TOKEN_EXPIRE = JsonResponse.build(ResponseStatus.UNAUTHORIZED,"认证失效 请重新登录"); private final static JsonResponse NO_PERMISSION = JsonResponse.build(ResponseStatus.FORBIDDEN,"无权访问"); + @Override + public void addArgumentResolvers(List resolvers) { + resolvers.add(claimResolver); + } + @Override public void addInterceptors(InterceptorRegistry registry) { // 添加请求 权限校验 拦截器 @@ -93,6 +101,7 @@ public class WebConfig implements WebMvcConfigurer { } Claims claims = jwtService.parseToken(token); + request.setAttribute("claims", claims); log.info("[解析的令牌信息] {}", claims); if (claims == null) { log.info("[认证失败] 无效 token => {}", token); diff --git a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordService.java b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordService.java index de100aa..90edd99 100644 --- a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordService.java +++ b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordService.java @@ -1,11 +1,15 @@ package cn.skcks.matrix.v2.services.location.record; import cn.skcks.matrix.v2.model.location.record.dto.LocationRecordParams; -import cn.skcks.matrix.v2.model.location.record.vo.LocationRecordVo; +import cn.skcks.matrix.v2.model.location.record.dto.PageLocationRecordParams; import cn.skcks.matrix.v2.model.services.ServiceResult; +import cn.skcks.matrix.v2.orm.mybatis.dynamic.model.LocationRecord; +import com.github.pagehelper.PageInfo; import java.util.Collection; public interface LocationRecordService { - ServiceResult> getLocationRecord(LocationRecordParams params); + ServiceResult> getLocationRecord(LocationRecordParams params, String userId); + + ServiceResult> getPageLocationRecord(PageLocationRecordParams params, String userId); } diff --git a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordServiceImpl.java b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordServiceImpl.java index 401f0aa..f06da65 100644 --- a/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordServiceImpl.java +++ b/backend/java/sk-matrix-service/services/src/main/java/cn/skcks/matrix/v2/services/location/record/LocationRecordServiceImpl.java @@ -2,16 +2,22 @@ package cn.skcks.matrix.v2.services.location.record; import cn.skcks.matrix.v2.model.location.record.convert.LocationRecordConvertor; import cn.skcks.matrix.v2.model.location.record.dto.LocationRecordParams; +import cn.skcks.matrix.v2.model.location.record.dto.PageLocationRecordParams; import cn.skcks.matrix.v2.model.location.record.vo.LocationRecordVo; import cn.skcks.matrix.v2.model.services.ServiceResult; import cn.skcks.matrix.v2.orm.mybatis.dynamic.mapper.LocationRecordDynamicSqlSupport; import cn.skcks.matrix.v2.orm.mybatis.dynamic.mapper.LocationRecordMapper; import cn.skcks.matrix.v2.orm.mybatis.dynamic.mapper.RoleDynamicSqlSupport; import cn.skcks.matrix.v2.orm.mybatis.dynamic.model.LocationRecord; +import cn.skcks.matrix.v2.utils.page.PageWrapper; +import com.github.pagehelper.Page; +import com.github.pagehelper.PageHelper; +import com.github.pagehelper.PageInfo; import lombok.RequiredArgsConstructor; import org.mybatis.dynamic.sql.SqlBuilder; import org.springframework.stereotype.Service; +import java.math.BigInteger; import java.util.Collection; import java.util.List; @@ -20,7 +26,7 @@ import java.util.List; public class LocationRecordServiceImpl implements LocationRecordService{ private final LocationRecordMapper locationRecordMapper; @Override - public ServiceResult> getLocationRecord(LocationRecordParams params) { + public ServiceResult> getLocationRecord(LocationRecordParams params, String userId) { List recordList = locationRecordMapper.select((s)-> s.applyWhere(dsl -> { if (params.getStartTime() != null) { dsl.and(LocationRecordDynamicSqlSupport.locationTime, SqlBuilder.isGreaterThanOrEqualTo(params.getStartTime())); @@ -30,11 +36,26 @@ public class LocationRecordServiceImpl implements LocationRecordService{ dsl.and(LocationRecordDynamicSqlSupport.locationTime,SqlBuilder.isLessThanOrEqualTo(params.getEndTime())); } + dsl.and(LocationRecordDynamicSqlSupport.userId, SqlBuilder.isEqualTo(Long.valueOf(userId))); dsl.and(LocationRecordDynamicSqlSupport.id, SqlBuilder.isNotNull()); }).orderBy((LocationRecordDynamicSqlSupport.id))); - return ServiceResult.>builder() - .result(recordList.stream().map(LocationRecordConvertor.INSTANCE::daoToVo).toList()) + return ServiceResult.>builder() + .result(recordList) + .build(); + } + + @Override + public ServiceResult> getPageLocationRecord(PageLocationRecordParams params, String userId) { + PageInfo pageInfo; + try(Page page = PageHelper.startPage(params.getPage(),params.getSize())){ + pageInfo = page.doSelectPageInfo(()->{ + getLocationRecord(params, userId); + }); + } + + return ServiceResult.>builder() + .result(pageInfo) .build(); } }