diff --git a/coder-common-thin-modules/coder-common-thin-system/src/main/java/org/leocoder/thin/system/controller/dictdata/SysDictDataController.java b/coder-common-thin-modules/coder-common-thin-system/src/main/java/org/leocoder/thin/system/controller/dictdata/SysDictDataController.java new file mode 100644 index 0000000..87fc3f7 --- /dev/null +++ b/coder-common-thin-modules/coder-common-thin-system/src/main/java/org/leocoder/thin/system/controller/dictdata/SysDictDataController.java @@ -0,0 +1,239 @@ +package org.leocoder.thin.system.controller.dictdata; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.leocoder.thin.common.constants.CoderCacheConstants; +import org.leocoder.thin.common.constants.CoderConstants; +import org.leocoder.thin.common.exception.coder.YUtil; +import org.leocoder.thin.common.satoken.CoderLoginUtil; +import org.leocoder.thin.common.utils.cache.RedisUtil; +import org.leocoder.thin.domain.enums.oper.OperType; +import org.leocoder.thin.domain.model.vo.system.SysDictDataVo; +import org.leocoder.thin.domain.pojo.system.SysDictData; +import org.leocoder.thin.operlog.annotation.OperLog; +import org.leocoder.thin.system.service.dictdata.SysDictDataService; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.List; + +/** + * @author Leocoder + * @description [字典数据表-控制层] + */ +@Tag(name = "字典数据管理", description = "系统字典数据的增删改查操作") +@Validated +@RequestMapping("/coder") +@RequiredArgsConstructor +@RestController +public class SysDictDataController { + + private final SysDictDataService sysDictDataService; + + private final RedisUtil redisUtil; + + /** + * @description [分页查询] + * @author Leocoder + */ + @Operation(summary = "分页查询字典数据列表", description = "根据查询条件分页获取字典数据信息") + @SaCheckPermission("system:dict:list") + @GetMapping("/sysDictData/listPage") + public IPage listPage(SysDictDataVo vo) { + // 分页构造器 + Page page = new Page<>(vo.getPageNo(), vo.getPageSize()); + // 条件构造器 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(StringUtils.isNotBlank(vo.getDictType()), SysDictData::getDictType, vo.getDictType()); + wrapper.like(StringUtils.isNotBlank(vo.getDictLabel()), SysDictData::getDictLabel, vo.getDictLabel()); + wrapper.eq(StringUtils.isNotBlank(vo.getDictStatus()), SysDictData::getDictStatus, vo.getDictStatus()); + wrapper.orderByDesc(SysDictData::getDictType); + wrapper.orderByAsc(SysDictData::getSorted); + // 进行分页查询 + page = sysDictDataService.page(page, wrapper); + return page; + } + + /** + * @description [查询所有] + * @author Leocoder + */ + @Operation(summary = "查询所有字典数据", description = "获取所有字典数据信息") + @SaCheckPermission("system:dict:list") + @GetMapping("/sysDictData/list") + public List list() { + return sysDictDataService.list(); + } + + /** + * @description [根据主键进行查询] + * @author Leocoder + */ + @Operation(summary = "根据ID查询字典数据", description = "通过ID获取字典数据详细信息") + @GetMapping("/sysDictData/getById/{id}") + public SysDictData getById(@PathVariable Long id) { + return sysDictDataService.getById(id); + } + + /** + * @description [新增] + * @author Leocoder + */ + @Operation(summary = "新增字典数据", description = "创建新的字典数据") + @SaCheckPermission("system:dict:add") + @PostMapping("/sysDictData/add") + @OperLog(value = "新增字典数据", operType = OperType.INSERT) + public void add(@Validated @RequestBody SysDictData sysDictData) { + // 查询是否已经存在字典名称 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDictData::getDictLabel, sysDictData.getDictLabel()); + wrapper.eq(SysDictData::getDictType, sysDictData.getDictType()); + long count = sysDictDataService.count(wrapper); + YUtil.isTrue(count > 0, "该字典名称已存在,请重新输入"); + if (StringUtils.isNotBlank(CoderLoginUtil.getUserName())) { + sysDictData.setCreateBy(CoderLoginUtil.getUserName()); + } + YUtil.isTrue(!sysDictDataService.save(sysDictData), "新增失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [获取最新排序] + * @author Leocoder + */ + @Operation(summary = "获取最新排序", description = "根据字典类型获取最新的排序号") + @GetMapping("/sysDictData/getSorted/{dictType}") + public int getSorted(@PathVariable("dictType") String dictType) { + YUtil.isTrue(StringUtils.isBlank(dictType), "请传递参数"); + LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper<>(); + lambdaQueryWrapper.select(SysDictData::getSorted); + lambdaQueryWrapper.eq(SysDictData::getDictType, dictType); + lambdaQueryWrapper.orderByDesc(SysDictData::getSorted); + lambdaQueryWrapper.last("LIMIT 1"); + SysDictData sysDictData = sysDictDataService.getOne(lambdaQueryWrapper); + if (ObjectUtils.isEmpty(sysDictData)) return CoderConstants.ONE_NUMBER; + return sysDictData.getSorted() != null ? sysDictData.getSorted() + CoderConstants.ONE_NUMBER : CoderConstants.ONE_NUMBER; + } + + /** + * @description [修改] + * @author Leocoder + */ + @Operation(summary = "修改字典数据", description = "更新字典数据信息") + @SaCheckPermission("system:dict:update") + @PostMapping("/sysDictData/update") + @OperLog(value = "修改字典数据", operType = OperType.UPDATE) + public void update(@Validated @RequestBody SysDictData sysDictData) { + // 查询是否已经存在字典名称 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDictData::getDictLabel, sysDictData.getDictLabel()); + wrapper.eq(SysDictData::getDictType, sysDictData.getDictType()); + SysDictData dictData = sysDictDataService.getOne(wrapper); + YUtil.isTrue(ObjectUtils.isNotEmpty(dictData) && !dictData.getDictId().equals(sysDictData.getDictId()), "该字典名称已存在,请重新输入"); + if (StringUtils.isNotBlank(CoderLoginUtil.getUserName())) { + sysDictData.setUpdateBy(CoderLoginUtil.getUserName()); + } + YUtil.isTrue(!sysDictDataService.updateById(sysDictData), "修改失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [删除] + * @author Leocoder + */ + @Operation(summary = "删除字典数据", description = "根据ID删除字典数据") + @SaCheckPermission("system:dict:delete") + @PostMapping("/sysDictData/deleteById/{id}") + @OperLog(value = "删除字典数据", operType = OperType.DELETE) + public void delete(@PathVariable Long id) { + YUtil.isTrue(!sysDictDataService.removeById(id), "删除失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [批量删除] + * @author Leocoder + */ + @Operation(summary = "批量删除字典数据", description = "根据ID列表批量删除字典数据") + @SaCheckPermission("system:dict:delete") + @PostMapping("/sysDictData/batchDelete") + @OperLog(value = "批量删除字典数据", operType = OperType.DELETE) + public void batchDelete(@NotNull(message = "请选择需要删除的数据") @RequestBody List ids) { + YUtil.isTrue(!sysDictDataService.removeBatchByIds(ids), "批量删除失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [修改状态] + * @author Leocoder + */ + @Operation(summary = "修改字典数据状态", description = "启用或停用字典数据") + @SaCheckPermission("system:dict:update") + @PostMapping("/sysDictData/updateStatus/{dictId}/{dictStatus}") + @OperLog(value = "修改字典数据状态", operType = OperType.UPDATE) + public void updateStatus(@PathVariable("dictId") Long dictId, @PathVariable("dictStatus") String dictStatus) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("dict_status", dictStatus).eq("dict_id", dictId); + YUtil.isTrue(!sysDictDataService.update(updateWrapper), "修改失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [根据类型查询字典数据] + * @author Leocoder + */ + @Operation(summary = "根据类型查询字典数据", description = "通过字典类型获取对应的字典数据列表") + @GetMapping("/sysDictData/listDataByType/{dictType}") + public List listDataByType(@PathVariable("dictType") String dictType) { + Boolean isExist = redisUtil.hasKey(CoderCacheConstants.DICT_REDIS_KEY + dictType); + if (!isExist) { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + // 查询指定字段 + wrapper.select(SysDictData::getDictLabel, SysDictData::getDictValue, SysDictData::getDictType, SysDictData::getDictTag, SysDictData::getDictColor); + wrapper.eq(StringUtils.isNotBlank(dictType), SysDictData::getDictType, dictType); + wrapper.eq(SysDictData::getDictStatus, CoderConstants.ZERO_STRING); + List dictDataList = sysDictDataService.list(wrapper); + if (CollectionUtils.isNotEmpty(dictDataList)) { + return dictDataList; + } else { + return Collections.emptyList(); + } + } else { + List redisDictData = redisUtil.getKey(CoderCacheConstants.DICT_REDIS_KEY + dictType); + if (CollectionUtils.isNotEmpty(redisDictData)) { + return redisDictData; + } else { + return Collections.emptyList(); + } + } + } + + /** + * @description [字典数据同步Redis进行缓存] + * @author Leocoder + */ + @Operation(summary = "同步字典缓存", description = "手动同步所有字典数据到Redis缓存") + @SaCheckPermission("system:dict:update") + @GetMapping("/sysDictData/listDictCacheRedis") + @OperLog(value = "字典数据同步缓存", operType = OperType.UPDATE) + public void listDictCacheRedis() { + sysDictDataService.listDictCacheRedis(); + } + +} \ No newline at end of file diff --git a/coder-common-thin-modules/coder-common-thin-system/src/main/java/org/leocoder/thin/system/controller/dicttype/SysDictTypeController.java b/coder-common-thin-modules/coder-common-thin-system/src/main/java/org/leocoder/thin/system/controller/dicttype/SysDictTypeController.java new file mode 100644 index 0000000..3936afa --- /dev/null +++ b/coder-common-thin-modules/coder-common-thin-system/src/main/java/org/leocoder/thin/system/controller/dicttype/SysDictTypeController.java @@ -0,0 +1,234 @@ +package org.leocoder.thin.system.controller.dicttype; + +import cn.dev33.satoken.annotation.SaCheckPermission; +import cn.hutool.core.collection.CollectionUtil; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.apache.commons.lang3.StringUtils; +import org.leocoder.thin.common.constants.CoderCacheConstants; +import org.leocoder.thin.common.constants.CoderConstants; +import org.leocoder.thin.common.exception.coder.YUtil; +import org.leocoder.thin.common.satoken.CoderLoginUtil; +import org.leocoder.thin.common.utils.cache.RedisUtil; +import org.leocoder.thin.domain.enums.oper.OperType; +import org.leocoder.thin.domain.model.vo.system.SysDictTypeVo; +import org.leocoder.thin.domain.pojo.system.SysDictData; +import org.leocoder.thin.domain.pojo.system.SysDictType; +import org.leocoder.thin.operlog.annotation.OperLog; +import org.leocoder.thin.system.service.dictdata.SysDictDataService; +import org.leocoder.thin.system.service.dicttype.SysDictTypeService; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; + +import java.util.Collections; +import java.util.List; + +/** + * @author Leocoder + * @description [字典类型表-控制层] + */ +@Tag(name = "字典类型管理", description = "系统字典类型的增删改查操作") +@Validated +@RequestMapping("/coder") +@RequiredArgsConstructor +@RestController +public class SysDictTypeController { + + private final SysDictTypeService sysDictTypeService; + + private final SysDictDataService sysDictDataService; + + private final RedisUtil redisUtil; + + /** + * @description [分页查询] + * @author Leocoder + */ + @Operation(summary = "分页查询字典类型列表", description = "根据查询条件分页获取字典类型信息") + @SaCheckPermission("system:dict:list") + @GetMapping("/sysDictType/listPage") + public IPage listPage(SysDictTypeVo vo) { + // 分页构造器 + Page page = new Page<>(vo.getPageNo(), vo.getPageSize()); + // 条件构造器 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.like(StringUtils.isNotBlank(vo.getDictName()), SysDictType::getDictName, vo.getDictName()); + wrapper.like(StringUtils.isNotBlank(vo.getDictType()), SysDictType::getDictType, vo.getDictType()); + wrapper.eq(StringUtils.isNotBlank(vo.getDictStatus()), SysDictType::getDictStatus, vo.getDictStatus()); + wrapper.orderByDesc(SysDictType::getCreateTime); + // 进行分页查询 + page = sysDictTypeService.page(page, wrapper); + return page; + } + + /** + * @description [查询所有] + * @author Leocoder + */ + @Operation(summary = "查询所有字典类型", description = "获取所有字典类型信息") + @SaCheckPermission("system:dict:list") + @GetMapping("/sysDictType/list") + public List list() { + return sysDictTypeService.list(); + } + + /** + * @description [根据主键查询] + * @author Leocoder + */ + @Operation(summary = "根据ID查询字典类型", description = "通过ID获取字典类型详细信息") + @GetMapping("/sysDictType/getById/{id}") + public SysDictType getById(@PathVariable Long id) { + return sysDictTypeService.getById(id); + } + + /** + * @description [新增] + * @author Leocoder + */ + @Operation(summary = "新增字典类型", description = "创建新的字典类型") + @SaCheckPermission("system:dict:add") + @PostMapping("/sysDictType/add") + @OperLog(value = "新增字典类型", operType = OperType.INSERT) + public void add(@Validated @RequestBody SysDictType sysDictType) { + // 查询是否已经存在字典名称 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDictType::getDictType, sysDictType.getDictType()); + long count = sysDictTypeService.count(wrapper); + YUtil.isTrue(count > 0, "该字典类型已存在,请重新输入"); + if (StringUtils.isNotBlank(CoderLoginUtil.getUserName())) { + sysDictType.setCreateBy(CoderLoginUtil.getUserName()); + } + YUtil.isTrue(!sysDictTypeService.save(sysDictType), "新增失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [修改] + * @author Leocoder + */ + @Operation(summary = "修改字典类型", description = "更新字典类型信息") + @SaCheckPermission("system:dict:update") + @PostMapping("/sysDictType/update") + @OperLog(value = "修改字典类型", operType = OperType.UPDATE) + public void update(@Validated @RequestBody SysDictType sysDictType) { + // 根据ID进行查询,用来同步修改字典数据类型 + SysDictType sysDictTypeModel = sysDictTypeService.getById(sysDictType.getDictId()); + // 查询是否已经存在字典名称 + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDictType::getDictType, sysDictType.getDictType()); + SysDictType dictType = sysDictTypeService.getOne(wrapper); + YUtil.isTrue(ObjectUtils.isNotEmpty(dictType) && !dictType.getDictId().equals(sysDictType.getDictId()), "该字典类型已存在,请重新输入"); + if (StringUtils.isNotBlank(CoderLoginUtil.getUserName())) { + sysDictType.setUpdateBy(CoderLoginUtil.getUserName()); + } + YUtil.isTrue(!sysDictTypeService.updateById(sysDictType), "修改失败,请稍后重试"); + if(!sysDictTypeModel.getDictType().equals(sysDictType.getDictType())) { + // 将字典数据的类型也同步修改 + LambdaUpdateWrapper updateWrapper = new LambdaUpdateWrapper<>(); + updateWrapper.set(SysDictData::getDictType, sysDictType.getDictType()); + updateWrapper.eq(SysDictData::getDictType, sysDictTypeModel.getDictType()); + sysDictDataService.update(updateWrapper); + } + // 先删除该缓存 + redisUtil.deleteKey(CoderCacheConstants.DICT_REDIS_KEY + sysDictTypeModel.getDictType()); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [删除] + * @author Leocoder + */ + @Operation(summary = "删除字典类型", description = "根据ID删除字典类型及其关联的字典数据") + @SaCheckPermission("system:dict:delete") + @Transactional(rollbackFor = Exception.class) + @PostMapping("/sysDictType/deleteById/{id}") + @OperLog(value = "删除字典类型", operType = OperType.DELETE) + public void delete(@PathVariable("id") Long id) { + SysDictType sysDictType = sysDictTypeService.getById(id); + YUtil.isTrue(ObjectUtils.isEmpty(sysDictType) || StringUtils.isBlank(sysDictType.getDictType()), "请检查该数据是否存在"); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDictData::getDictType, sysDictType.getDictType()); + // 删除字典详情 + sysDictDataService.remove(wrapper); + YUtil.isTrue(!sysDictTypeService.removeById(id), "删除失败,请稍后重试"); + // 删除缓存 + redisUtil.deleteKey(CoderCacheConstants.DICT_REDIS_KEY + sysDictType.getDictType()); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [批量删除] + * @author Leocoder + */ + @Operation(summary = "批量删除字典类型", description = "根据ID列表批量删除字典类型") + @SaCheckPermission("system:dict:delete") + @Transactional(rollbackFor = Exception.class) + @PostMapping("/sysDictType/batchDelete") + @OperLog(value = "批量删除字典类型", operType = OperType.DELETE) + public void batchDelete(@NotNull(message = "请选择需要删除的数据") @RequestBody List ids) { + if (CollectionUtil.isNotEmpty(ids)) { + for (Long id : ids) { + SysDictType sysDictType = sysDictTypeService.getById(id); + YUtil.isTrue(ObjectUtils.isEmpty(sysDictType) || StringUtils.isBlank(sysDictType.getDictType()), "请检查该数据是否存在"); + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(SysDictData::getDictType, sysDictType.getDictType()); + YUtil.isTrue(!sysDictDataService.remove(wrapper), "删除失败,请稍后重试"); + // 删除缓存 + redisUtil.deleteKey(CoderCacheConstants.DICT_REDIS_KEY + sysDictType.getDictType()); + } + } + YUtil.isTrue(!sysDictTypeService.removeBatchByIds(ids), "批量删除失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [修改状态] + * @author Leocoder + */ + @Operation(summary = "修改字典类型状态", description = "启用或停用字典类型") + @SaCheckPermission("system:dict:update") + @PostMapping("/sysDictType/updateStatus/{dictId}/{dictStatus}") + @OperLog(value = "修改字典类型状态", operType = OperType.UPDATE) + public void updateStatus(@PathVariable("dictId") Long dictId, @PathVariable("dictStatus") String dictStatus) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.set("dict_status", dictStatus).eq("dict_id", dictId); + YUtil.isTrue(!sysDictTypeService.update(updateWrapper), "修改失败,请稍后重试"); + // 同步缓存 + sysDictDataService.listDictCacheRedis(); + } + + /** + * @description [查询字典类型下拉框] + * @author Leocoder + */ + @Operation(summary = "查询字典类型下拉框", description = "获取启用状态的字典类型列表,用于下拉选择") + @GetMapping("/sysDictType/listDictType") + public List listDictType() { + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + // 按需加载 + wrapper.select(SysDictType::getDictType, SysDictType::getDictName); + wrapper.eq(SysDictType::getDictStatus, CoderConstants.ZERO_STRING); + List dictTypeList = sysDictTypeService.list(wrapper); + if (CollectionUtils.isNotEmpty(dictTypeList)) { + return dictTypeList; + } else { + return Collections.emptyList(); + } + } + +} \ No newline at end of file