refactor(extension/crud): 适配 Crane4j 数据填充组件

This commit is contained in:
2024-01-12 23:15:26 +08:00
parent ea986ba315
commit 5d26f343da
8 changed files with 115 additions and 72 deletions

View File

@@ -22,7 +22,7 @@
<artifactId>easy-captcha</artifactId>
</dependency>
<!-- Js 引擎(一个纯编译的 JavaScript 引擎) -->
<!-- JS 引擎(一个纯编译的 JavaScript 引擎) -->
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>

View File

@@ -55,9 +55,8 @@
<properties>
<revision>1.2.0-SNAPSHOT</revision>
<crane4j.version>2.3.1</crane4j.version>
<just-auth.version>1.16.6</just-auth.version>
<sa-token.version>1.37.0</sa-token.version>
<just-auth.version>1.16.6</just-auth.version>
<mybatis-plus.version>3.5.5</mybatis-plus.version>
<dynamic-datasource.version>4.2.0</dynamic-datasource.version>
<p6spy.version>3.9.1</p6spy.version>
@@ -69,6 +68,7 @@
<nashorn.version>15.4</nashorn.version>
<x-file-storage.version>2.0.0</x-file-storage.version>
<aws-s3.version>1.12.626</aws-s3.version>
<crane4j.version>2.3.1</crane4j.version>
<knife4j.version>4.4.0</knife4j.version>
<ttl.version>2.14.4</ttl.version>
<ip2region.version>3.1.6</ip2region.version>
@@ -77,11 +77,24 @@
<dependencyManagement>
<dependencies>
<!-- Crane4j一个基于注解的用于完成一切 “根据 A 的 key 值拿到 B再把 B 的属性映射到 A” 这类需求的字段填充框架 -->
<!-- Sa-Token轻量级 Java 权限认证框架,让鉴权变得简单、优雅 -->
<dependency>
<groupId>cn.crane4j</groupId>
<artifactId>crane4j-spring-boot-starter</artifactId>
<version>${crane4j.version}</version>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 JWT -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>${sa-token.version}</version>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Just Auth开箱即用的整合第三方登录的开源组件脱离繁琐的第三方登录 SDK让登录变得 So easy! -->
@@ -106,26 +119,6 @@
</exclusions>
</dependency>
<!-- Sa-Token轻量级 Java 权限认证框架,让鉴权变得简单、优雅) -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<!-- Sa-Token 整合 JWT -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId>
<version>${sa-token.version}</version>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- MyBatis PlusMyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,简化开发、提高效率) -->
<dependency>
<groupId>com.baomidou</groupId>
@@ -175,7 +168,7 @@
<version>${easy-captcha.version}</version>
</dependency>
<!-- Js 引擎(一个纯编译的 JavaScript 引擎) -->
<!-- JS 引擎(一个纯编译的 JavaScript 引擎) -->
<dependency>
<groupId>org.openjdk.nashorn</groupId>
<artifactId>nashorn-core</artifactId>
@@ -203,6 +196,13 @@
<version>${aws-s3.version}</version>
</dependency>
<!-- Crane4j一个基于注解的用于完成一切 “根据 A 的 key 值拿到 B再把 B 的属性映射到 A” 这类需求的字段填充框架) -->
<dependency>
<groupId>cn.crane4j</groupId>
<artifactId>crane4j-spring-boot-starter</artifactId>
<version>${crane4j.version}</version>
</dependency>
<!-- Knife4j前身是 swagger-bootstrap-ui集 Swagger2 和 OpenAPI3 为一体的增强解决方案) -->
<dependency>
<groupId>com.github.xiaoymin</groupId>

View File

@@ -44,5 +44,11 @@
<groupId>top.charles7c.continew</groupId>
<artifactId>continew-starter-api-doc</artifactId>
</dependency>
<!-- Crane4j一个基于注解的用于完成一切 “根据 A 的 key 值拿到 B再把 B 的属性映射到 A” 这类需求的字段填充框架) -->
<dependency>
<groupId>cn.crane4j</groupId>
<artifactId>crane4j-spring-boot-starter</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -21,6 +21,7 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.accept.ContentNegotiationManager;
@@ -37,6 +38,7 @@ import top.charles7c.continew.starter.extension.crud.handler.CrudRequestMappingH
*/
@Slf4j
@AutoConfiguration
@Import({UserNicknameContainer.class})
public class CrudAutoConfiguration extends DelegatingWebMvcConfiguration {
/**

View File

@@ -0,0 +1,52 @@
/*
* 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.charles7c.continew.starter.extension.crud.autoconfigure;
import cn.crane4j.core.container.Container;
import cn.hutool.core.collection.CollUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;
import top.charles7c.continew.starter.extension.crud.base.CommonUserService;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
/**
* 用户昵称容器
*
* @author Charles7c
* @since 1.2.0
*/
@Component
@RequiredArgsConstructor
public class UserNicknameContainer implements Container<Long> {
private final CommonUserService userService;
@Override
public String getNamespace() {
return "userNickname";
}
@Override
public Map<Long, String> get(Collection<Long> ids) {
Long id = CollUtil.getFirst(ids);
String name = userService.getNicknameById(id);
return Collections.singletonMap(id, name);
}
}

View File

@@ -16,6 +16,8 @@
package top.charles7c.continew.starter.extension.crud.base;
import cn.crane4j.annotation.Assemble;
import cn.crane4j.annotation.Mapping;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import io.swagger.v3.oas.annotations.media.Schema;
@@ -42,6 +44,7 @@ public class BaseDetailResp extends BaseResp {
* 修改人
*/
@JsonIgnore
@Assemble(container = "userNickname", props = @Mapping(ref = "updateUserString"))
private Long updateUser;
/**

View File

@@ -16,6 +16,8 @@
package top.charles7c.continew.starter.extension.crud.base;
import cn.crane4j.annotation.Assemble;
import cn.crane4j.annotation.Mapping;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
@@ -47,6 +49,7 @@ public class BaseResp implements Serializable {
* 创建人
*/
@JsonIgnore
@Assemble(container = "userNickname", props = @Mapping(ref = "createUserString"))
private Long createUser;
/**

View File

@@ -16,6 +16,7 @@
package top.charles7c.continew.starter.extension.crud.base;
import cn.crane4j.core.support.OperateTemplate;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.collection.CollUtil;
@@ -34,7 +35,6 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.transaction.annotation.Transactional;
import top.charles7c.continew.starter.core.util.ClassUtils;
import top.charles7c.continew.starter.core.util.ExceptionUtils;
import top.charles7c.continew.starter.core.util.ReflectUtils;
import top.charles7c.continew.starter.core.util.validate.CheckUtils;
import top.charles7c.continew.starter.data.mybatis.plus.base.BaseMapper;
@@ -137,26 +137,11 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseDO,
return BeanUtil.copyToList(entityList, targetClass);
}
/**
* 设置排序
*
* @param queryWrapper 查询 Wrapper
* @param sortQuery 排序查询条件
*/
protected void sort(QueryWrapper<T> queryWrapper, SortQuery sortQuery) {
Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort();
for (Sort.Order order : sort) {
if (null != order) {
queryWrapper.orderBy(true, order.isAscending(), StrUtil.toUnderlineCase(order.getProperty()));
}
}
}
@Override
public D get(Long id) {
T entity = this.getById(id);
D detail = BeanUtil.copyProperties(entity, detailClass);
this.fillDetail(detail);
this.fill(detail);
return detail;
}
@@ -186,10 +171,20 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseDO,
@Override
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
List<D> list = this.list(query, sortQuery, detailClass);
list.forEach(this::fillDetail);
list.forEach(this::fill);
ExcelUtils.export(list, "导出数据", detailClass, response);
}
/**
* 填充数据
*
* @param obj 待填充信息
*/
protected void fill(Object obj) {
OperateTemplate operateTemplate = SpringUtil.getBean(OperateTemplate.class);
operateTemplate.execute(obj);
}
/**
* 根据 ID 查询
*
@@ -203,35 +198,17 @@ public abstract class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseDO,
}
/**
* 填充数据
* 设置排序
*
* @param baseObj 待填充列表信息
* @param queryWrapper 查询 Wrapper
* @param sortQuery 排序查询条件
*/
protected void fill(Object baseObj) {
if (baseObj instanceof BaseResp baseResp) {
Long createUser = baseResp.getCreateUser();
if (null == createUser) {
return;
protected void sort(QueryWrapper<T> queryWrapper, SortQuery sortQuery) {
Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort();
for (Sort.Order order : sort) {
if (null != order) {
queryWrapper.orderBy(true, order.isAscending(), StrUtil.toUnderlineCase(order.getProperty()));
}
CommonUserService userService = SpringUtil.getBean(CommonUserService.class);
baseResp.setCreateUserString(ExceptionUtils.exToNull(() -> userService.getNicknameById(createUser)));
}
}
/**
* 填充详情数据
*
* @param detailObj 待填充详情信息
*/
public void fillDetail(Object detailObj) {
if (detailObj instanceof BaseDetailResp detailResp) {
this.fill(detailResp);
Long updateUser = detailResp.getUpdateUser();
if (null == updateUser) {
return;
}
CommonUserService userService = SpringUtil.getBean(CommonUserService.class);
detailResp.setUpdateUserString(ExceptionUtils.exToNull(() -> userService.getNicknameById(updateUser)));
}
}