mirror of
https://github.com/continew-org/continew-starter.git
synced 2025-09-08 16:57:09 +08:00
feat(extension/crud): CRUD API 新增 DICT(字典列表(下拉选项等场景))、DICT_TREE(字典树列表(树型结构下拉选项等场景))
This commit is contained in:
@@ -39,5 +39,5 @@ public @interface CrudRequestMapping {
|
||||
/**
|
||||
* API 列表
|
||||
*/
|
||||
Api[] api() default {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.DELETE, Api.EXPORT};
|
||||
Api[] api() default {Api.PAGE, Api.GET, Api.CREATE, Api.UPDATE, Api.BATCH_DELETE, Api.EXPORT, Api.DICT};
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@ import top.continew.starter.extension.crud.model.query.SortQuery;
|
||||
import top.continew.starter.extension.crud.model.req.IdsReq;
|
||||
import top.continew.starter.extension.crud.model.resp.IdResp;
|
||||
import top.continew.starter.extension.crud.model.resp.BasePageResp;
|
||||
import top.continew.starter.extension.crud.model.resp.LabelValueResp;
|
||||
import top.continew.starter.extension.crud.service.CrudService;
|
||||
import top.continew.starter.extension.crud.validation.CrudValidationGroup;
|
||||
|
||||
@@ -187,4 +188,32 @@ public abstract class AbstractCrudController<S extends CrudService<L, D, Q, C>,
|
||||
public void export(@Valid Q query, @Valid SortQuery sortQuery, HttpServletResponse response) {
|
||||
baseService.export(query, sortQuery, response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 字典列表信息
|
||||
*/
|
||||
@CrudApi(Api.DICT)
|
||||
@Operation(summary = "查询字典列表", description = "查询字典列表(下拉选项等场景)")
|
||||
@GetMapping("/dict")
|
||||
public List<LabelValueResp> dict(@Valid Q query, @Valid SortQuery sortQuery) {
|
||||
return baseService.dict(query, sortQuery);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询字典树列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 字典树列表信息
|
||||
*/
|
||||
@CrudApi(Api.DICT_TREE)
|
||||
@Operation(summary = "查询字典树列表", description = "查询树型结构字典列表(树型结构下拉选项等场景)")
|
||||
@GetMapping("/dict/tree")
|
||||
public List<Tree<Long>> dictTree(@Valid Q query, @Valid SortQuery sortQuery) {
|
||||
return baseService.tree(query, sortQuery, true);
|
||||
}
|
||||
}
|
||||
|
@@ -68,4 +68,14 @@ public enum Api {
|
||||
* 批量删除
|
||||
*/
|
||||
BATCH_DELETE,
|
||||
|
||||
/**
|
||||
* 字典列表(下拉选项等场景)
|
||||
*/
|
||||
DICT,
|
||||
|
||||
/**
|
||||
* 字典树列表(树型结构下拉选项等场景)
|
||||
*/
|
||||
DICT_TREE
|
||||
}
|
@@ -93,17 +93,6 @@ public interface CrudService<L, D, Q, C> {
|
||||
*/
|
||||
D get(Long id);
|
||||
|
||||
/**
|
||||
* 查询字典列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 字典列表信息
|
||||
* @since 2.1.0
|
||||
* @see top.continew.starter.extension.crud.annotation.DictModel
|
||||
*/
|
||||
List<LabelValueResp> listDict(@Valid Q query, @Valid SortQuery sortQuery);
|
||||
|
||||
/**
|
||||
* 创建
|
||||
*
|
||||
@@ -137,4 +126,15 @@ public interface CrudService<L, D, Q, C> {
|
||||
* @param response 响应对象
|
||||
*/
|
||||
void export(@Valid Q query, @Valid SortQuery sortQuery, HttpServletResponse response);
|
||||
|
||||
/**
|
||||
* 查询字典列表
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param sortQuery 排序查询条件
|
||||
* @return 字典列表信息
|
||||
* @since 2.1.0
|
||||
* @see top.continew.starter.extension.crud.annotation.DictModel
|
||||
*/
|
||||
List<LabelValueResp> dict(@Valid Q query, @Valid SortQuery sortQuery);
|
||||
}
|
||||
|
@@ -19,9 +19,11 @@ package top.continew.starter.extension.crud.service;
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import cn.hutool.core.bean.copier.CopyOptions;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.tree.Tree;
|
||||
import cn.hutool.core.lang.tree.TreeNodeConfig;
|
||||
import cn.hutool.core.lang.tree.TreeUtil;
|
||||
import cn.hutool.core.map.MapUtil;
|
||||
import cn.hutool.core.text.CharSequenceUtil;
|
||||
import cn.hutool.core.util.ReflectUtil;
|
||||
import cn.hutool.extra.spring.SpringUtil;
|
||||
@@ -33,11 +35,13 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import top.continew.starter.core.constant.StringConstants;
|
||||
import top.continew.starter.core.util.ReflectUtils;
|
||||
import top.continew.starter.core.util.TreeUtils;
|
||||
import top.continew.starter.core.util.validation.CheckUtils;
|
||||
import top.continew.starter.core.util.validation.ValidationUtils;
|
||||
import top.continew.starter.data.base.BaseMapper;
|
||||
import top.continew.starter.data.service.impl.ServiceImpl;
|
||||
import top.continew.starter.data.util.QueryWrapperHelper;
|
||||
import top.continew.starter.excel.util.ExcelUtils;
|
||||
import top.continew.starter.extension.crud.annotation.DictModel;
|
||||
import top.continew.starter.extension.crud.annotation.TreeField;
|
||||
import top.continew.starter.extension.crud.autoconfigure.CrudProperties;
|
||||
import top.continew.starter.extension.crud.autoconfigure.CrudTreeProperties;
|
||||
@@ -48,8 +52,7 @@ import top.continew.starter.extension.crud.model.resp.LabelValueResp;
|
||||
import top.continew.starter.extension.crud.model.resp.PageResp;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
import java.util.function.Function;
|
||||
|
||||
/**
|
||||
@@ -135,11 +138,6 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
||||
return detail;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelValueResp> listDict(Q query, SortQuery sortQuery) {
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(C req) {
|
||||
@@ -175,6 +173,44 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
||||
ExcelUtils.export(list, "导出数据", detailClass, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelValueResp> dict(Q query, SortQuery sortQuery) {
|
||||
DictModel dictModel = entityClass.getDeclaredAnnotation(DictModel.class);
|
||||
CheckUtils.throwIfNull(dictModel, "请添加并配置 @DictModel 字典结构信息");
|
||||
List<L> list = this.list(query, sortQuery);
|
||||
// 解析映射
|
||||
List<LabelValueResp> respList = new ArrayList<>(list.size());
|
||||
String labelKey = dictModel.labelKey().contains(StringConstants.DOT)
|
||||
? CharSequenceUtil.subAfter(dictModel.labelKey(), StringConstants.DOT, true)
|
||||
: dictModel.labelKey();
|
||||
String valueKey = dictModel.valueKey().contains(StringConstants.DOT)
|
||||
? CharSequenceUtil.subAfter(dictModel.valueKey(), StringConstants.DOT, true)
|
||||
: dictModel.valueKey();
|
||||
List<String> extraFieldNames = Arrays.stream(dictModel.extraKeys())
|
||||
.map(extraKey -> extraKey.contains(StringConstants.DOT)
|
||||
? CharSequenceUtil.subAfter(extraKey, StringConstants.DOT, true)
|
||||
: extraKey)
|
||||
.map(CharSequenceUtil::toCamelCase)
|
||||
.toList();
|
||||
for (L entity : list) {
|
||||
LabelValueResp<Object> labelValueResp = new LabelValueResp<>();
|
||||
labelValueResp.setLabel(Convert.toStr(ReflectUtil.getFieldValue(entity, CharSequenceUtil
|
||||
.toCamelCase(labelKey))));
|
||||
labelValueResp.setValue(ReflectUtil.getFieldValue(entity, CharSequenceUtil.toCamelCase(valueKey)));
|
||||
respList.add(labelValueResp);
|
||||
if (CollUtil.isEmpty(extraFieldNames)) {
|
||||
continue;
|
||||
}
|
||||
// 额外数据
|
||||
Map<String, Object> extraMap = MapUtil.newHashMap(dictModel.extraKeys().length);
|
||||
for (String extraFieldName : extraFieldNames) {
|
||||
extraMap.put(extraFieldName, ReflectUtil.getFieldValue(entity, extraFieldName));
|
||||
}
|
||||
labelValueResp.setExtra(extraMap);
|
||||
}
|
||||
return respList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询列表
|
||||
*
|
||||
|
@@ -141,7 +141,42 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelValueResp> listDict(Q query, SortQuery sortQuery) {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(C req) {
|
||||
this.beforeCreate(req);
|
||||
T entity = BeanUtil.copyProperties(req, super.getEntityClass());
|
||||
baseMapper.insert(entity);
|
||||
this.afterCreate(req, entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(C req, Long id) {
|
||||
this.beforeUpdate(req, id);
|
||||
T entity = this.getById(id);
|
||||
BeanUtil.copyProperties(req, entity, CopyOptions.create().ignoreNullValue());
|
||||
baseMapper.updateById(entity);
|
||||
this.afterUpdate(req, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(List<Long> ids) {
|
||||
this.beforeDelete(ids);
|
||||
baseMapper.deleteByIds(ids);
|
||||
this.afterDelete(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
|
||||
List<D> list = this.list(query, sortQuery, this.getDetailClass());
|
||||
list.forEach(this::fill);
|
||||
ExcelUtils.export(list, "导出数据", this.getDetailClass(), response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<LabelValueResp> dict(Q query, SortQuery sortQuery) {
|
||||
DictModel dictModel = super.getEntityClass().getDeclaredAnnotation(DictModel.class);
|
||||
CheckUtils.throwIfNull(dictModel, "请添加并配置 @DictModel 字典结构信息");
|
||||
List<L> list = this.list(query, sortQuery);
|
||||
@@ -178,41 +213,6 @@ public class CrudServiceImpl<M extends BaseMapper<T>, T extends BaseIdDO, L, D,
|
||||
return respList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Long create(C req) {
|
||||
this.beforeCreate(req);
|
||||
T entity = BeanUtil.copyProperties(req, super.getEntityClass());
|
||||
baseMapper.insert(entity);
|
||||
this.afterCreate(req, entity);
|
||||
return entity.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void update(C req, Long id) {
|
||||
this.beforeUpdate(req, id);
|
||||
T entity = this.getById(id);
|
||||
BeanUtil.copyProperties(req, entity, CopyOptions.create().ignoreNullValue());
|
||||
baseMapper.updateById(entity);
|
||||
this.afterUpdate(req, entity);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void delete(List<Long> ids) {
|
||||
this.beforeDelete(ids);
|
||||
baseMapper.deleteByIds(ids);
|
||||
this.afterDelete(ids);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export(Q query, SortQuery sortQuery, HttpServletResponse response) {
|
||||
List<D> list = this.list(query, sortQuery, this.getDetailClass());
|
||||
list.forEach(this::fill);
|
||||
ExcelUtils.export(list, "导出数据", this.getDetailClass(), response);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前列表信息类型
|
||||
*
|
||||
|
Reference in New Issue
Block a user