diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java index 6d19a3cc75..8d18479c81 100644 --- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java +++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/date/LocalDateTimeUtils.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.common.util.date; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.LocalDateTimeUtil; +import cn.hutool.core.date.TemporalAccessorUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.enums.DateIntervalEnum; @@ -19,7 +20,7 @@ import static cn.hutool.core.date.DatePattern.UTC_MS_WITH_XXX_OFFSET_PATTERN; import static cn.hutool.core.date.DatePattern.createFormatter; /** - * 时间工具类,用于 {@link java.time.LocalDateTime} + * 时间工具类,用于 {@link LocalDateTime} * * @author 芋道源码 */ @@ -312,4 +313,16 @@ public class LocalDateTimeUtils { } } + /** + * 将给定的 {@link LocalDateTime} 转换为自 Unix 纪元时间(1970-01-01T00:00:00Z)以来的秒数。 + * + * @param sourceDateTime 需要转换的本地日期时间,不能为空 + * @return 自 1970-01-01T00:00:00Z 起的秒数(epoch second) + * @throws NullPointerException 如果 {@code sourceDateTime} 为 {@code null} + * @throws DateTimeException 如果转换过程中发生时间超出范围或其他时间处理异常 + */ + public static Long toEpochSecond(LocalDateTime sourceDateTime) { + return TemporalAccessorUtil.toInstant(sourceDateTime).getEpochSecond(); + } + } diff --git a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java index ef1eb65bcd..8e3e28eb44 100644 --- a/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java +++ b/yudao-framework/yudao-spring-boot-starter-excel/src/main/java/cn/iocoder/yudao/framework/excel/core/handler/SelectSheetWriteHandler.java @@ -3,6 +3,7 @@ package cn.iocoder.yudao.framework.excel.core.handler; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.Assert; import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.ReflectUtil; import cn.hutool.core.util.StrUtil; import cn.hutool.extra.spring.SpringUtil; import cn.hutool.poi.excel.ExcelUtil; @@ -10,6 +11,8 @@ import cn.iocoder.yudao.framework.common.core.KeyValue; import cn.iocoder.yudao.framework.dict.core.DictFrameworkUtils; import cn.iocoder.yudao.framework.excel.core.annotations.ExcelColumnSelect; import cn.iocoder.yudao.framework.excel.core.function.ExcelColumnSelectFunction; +import com.alibaba.excel.annotation.ExcelIgnore; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; @@ -20,6 +23,7 @@ import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.util.CellRangeAddressList; import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import java.util.Comparator; import java.util.HashMap; import java.util.List; @@ -56,7 +60,20 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { public SelectSheetWriteHandler(Class head) { // 解析下拉数据 int colIndex = 0; + boolean ignoreUnannotated = head.isAnnotationPresent(ExcelIgnoreUnannotated.class); for (Field field : head.getDeclaredFields()) { + // 关联 https://github.com/YunaiV/ruoyi-vue-pro/pull/853 + // 1.1 忽略 static final 或 transient 的字段 + if (isStaticFinalOrTransient(field) ) { + continue; + } + // 1.2 忽略的字段跳过 + if ((ignoreUnannotated && !field.isAnnotationPresent(ExcelProperty.class)) + || field.isAnnotationPresent(ExcelIgnore.class)) { + continue; + } + + // 2. 核心:处理有 ExcelColumnSelect 注解的字段 if (field.isAnnotationPresent(ExcelColumnSelect.class)) { ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class); if (excelProperty != null && excelProperty.index() != -1) { @@ -68,6 +85,19 @@ public class SelectSheetWriteHandler implements SheetWriteHandler { } } + /** + * 判断字段是否是静态的、最终的、 transient 的 + * 原因:EasyExcel 默认是忽略 static final 或 transient 的字段,所以需要判断 + * + * @param field 字段 + * @return 是否是静态的、最终的、transient 的 + */ + private boolean isStaticFinalOrTransient(Field field) { + return (Modifier.isStatic(field.getModifiers()) && Modifier.isFinal(field.getModifiers())) + || Modifier.isTransient(field.getModifiers()); + } + + /** * 获得下拉数据,并添加到 {@link #selectMap} 中 * diff --git a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java index ccd9412a48..784f699e44 100644 --- a/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java +++ b/yudao-framework/yudao-spring-boot-starter-mybatis/src/main/java/cn/iocoder/yudao/framework/mybatis/core/util/MyBatisUtils.java @@ -1,6 +1,8 @@ package cn.iocoder.yudao.framework.mybatis.core.util; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.lang.func.Func1; +import cn.hutool.core.lang.func.LambdaUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.SortingField; @@ -103,4 +105,18 @@ public class MyBatisUtils { .replace("#{value}", StrUtil.toString(value)); } + /** + * 将驼峰命名转换为下划线命名 + * + * 使用场景: + * 1. fix:修复"商品统计聚合函数的别名与排序字段不符"导致的 SQL 异常 + * + * @param func 字段名函数(驼峰命名) + * @return 字段名(下划线命名) + */ + public static String toUnderlineCase(Func1 func) { + String fieldName = LambdaUtil.getFieldName(func); + return StrUtil.toUnderlineCase(fieldName); + } + } diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java index 9df1344edd..d4693396ee 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/codegen/CodegenController.java @@ -122,6 +122,15 @@ public class CodegenController { return success(true); } + @Operation(summary = "批量删除数据库的表和字段定义") + @DeleteMapping("/delete-list") + @Parameter(name = "tableIds", description = "表编号列表", required = true) + @PreAuthorize("@ss.hasPermission('infra:codegen:delete')") + public CommonResult deleteCodegenList(@RequestParam("tableIds") List tableIds) { + codegenService.deleteCodegenList(tableIds); + return success(true); + } + @Operation(summary = "预览生成代码") @GetMapping("/preview") @Parameter(name = "tableId", description = "表编号", required = true, example = "1024") diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java index ebfaf1de5a..30037b872f 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/config/ConfigController.java @@ -62,6 +62,15 @@ public class ConfigController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除参数配置") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('infra:config:delete')") + public CommonResult deleteConfigList(@RequestParam("ids") List ids) { + configService.deleteConfigList(ids); + return success(true); + } + @GetMapping(value = "/get") @Operation(summary = "获得参数配置") @Parameter(name = "id", description = "编号", required = true, example = "1024") @@ -92,7 +101,7 @@ public class ConfigController { return success(ConfigConvert.INSTANCE.convertPage(page)); } - @GetMapping("/export") + @GetMapping("/export-excel") @Operation(summary = "导出参数配置") @PreAuthorize("@ss.hasPermission('infra:config:export')") @ApiAccessLog(operateType = EXPORT) diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java index 85a12279e8..2464586482 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/DataSourceConfigController.java @@ -52,6 +52,15 @@ public class DataSourceConfigController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除数据源配置") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')") + public CommonResult deleteDataSourceConfigList(@RequestParam("ids") List ids) { + dataSourceConfigService.deleteDataSourceConfigList(ids); + return success(true); + } + @GetMapping("/get") @Operation(summary = "获得数据源配置") @Parameter(name = "id", description = "编号", required = true, example = "1024") diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java index f979528734..def8ce0cfe 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/db/vo/DataSourceConfigRespVO.java @@ -10,7 +10,7 @@ import java.time.LocalDateTime; public class DataSourceConfigRespVO { @Schema(description = "主键编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024") - private Integer id; + private Long id; @Schema(description = "数据源名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "test") private String name; diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java index eb51f08c3a..c593f4bb6a 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileConfigController.java @@ -11,12 +11,13 @@ import cn.iocoder.yudao.module.infra.service.file.FileConfigService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import javax.validation.Valid; +import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; @@ -61,6 +62,15 @@ public class FileConfigController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除文件配置") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('infra:file-config:delete')") + public CommonResult deleteFileConfigList(@RequestParam("ids") List ids) { + fileConfigService.deleteFileConfigList(ids); + return success(true); + } + @GetMapping("/get") @Operation(summary = "获得文件配置") @Parameter(name = "id", description = "编号", required = true, example = "1024") diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java index 75a6d92a71..d5611b7a06 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java @@ -14,6 +14,11 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.annotation.security.PermitAll; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.validation.Valid; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.security.access.prepost.PreAuthorize; @@ -21,11 +26,7 @@ import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; -import javax.annotation.Resource; -import javax.annotation.security.PermitAll; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.validation.Valid; +import java.util.List; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment; @@ -76,6 +77,15 @@ public class FileController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除文件") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('infra:file:delete')") + public CommonResult deleteFileList(@RequestParam("ids") List ids) throws Exception { + fileService.deleteFileList(ids); + return success(true); + } + @GetMapping("/{configId}/get/**") @PermitAll @TenantIgnore diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java index b03eae21a7..17d37c9ae8 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/job/JobController.java @@ -81,6 +81,16 @@ public class JobController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除定时任务") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('infra:job:delete')") + public CommonResult deleteJobList(@RequestParam("ids") List ids) + throws SchedulerException { + jobService.deleteJobList(ids); + return success(true); + } + @PutMapping("/trigger") @Operation(summary = "触发定时任务") @Parameter(name = "id", description = "编号", required = true, example = "1024") diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenColumnMapper.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenColumnMapper.java index ea5a9bb631..28a705ffea 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenColumnMapper.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/codegen/CodegenColumnMapper.java @@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO; import org.apache.ibatis.annotations.Mapper; +import java.util.Collection; import java.util.List; @Mapper @@ -17,8 +18,12 @@ public interface CodegenColumnMapper extends BaseMapperX { } default void deleteListByTableId(Long tableId) { + delete(CodegenColumnDO::getTableId, tableId); + } + + default void deleteListByTableId(Collection tableIds) { delete(new LambdaQueryWrapperX() - .eq(CodegenColumnDO::getTableId, tableId)); + .in(CodegenColumnDO::getTableId, tableIds)); } } diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenService.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenService.java index 7adc9f7f1c..ca22021a8f 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenService.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenService.java @@ -48,6 +48,13 @@ public interface CodegenService { */ void deleteCodegen(Long tableId); + /** + * 批量删除数据库的表和字段定义 + * + * @param tableIds 数据编号列表 + */ + void deleteCodegenList(List tableIds); + /** * 获得表定义列表 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java index 8458da691a..f6ff655194 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/codegen/CodegenServiceImpl.java @@ -222,6 +222,15 @@ public class CodegenServiceImpl implements CodegenService { codegenColumnMapper.deleteListByTableId(tableId); } + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteCodegenList(List tableIds) { + // 批量删除 table 表定义 + codegenTableMapper.deleteByIds(tableIds); + // 批量删除 column 字段定义 + codegenColumnMapper.deleteListByTableId(tableIds); + } + @Override public List getCodegenTableList(Long dataSourceConfigId) { return codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId); diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigService.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigService.java index 345bd2bf76..f317e56a25 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigService.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigService.java @@ -6,6 +6,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigSaveReqVO; import cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO; import javax.validation.Valid; +import java.util.List; + /** * 参数配置 Service 接口 * @@ -35,6 +37,13 @@ public interface ConfigService { */ void deleteConfig(Long id); + /** + * 批量删除参数配置 + * + * @param ids 配置编号列表 + */ + void deleteConfigList(List ids); + /** * 获得参数配置 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java index a76f3ab3dc..f0a185f2bc 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/config/ConfigServiceImpl.java @@ -13,6 +13,8 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; +import java.util.List; + import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*; @@ -63,6 +65,20 @@ public class ConfigServiceImpl implements ConfigService { configMapper.deleteById(id); } + @Override + public void deleteConfigList(List ids) { + // 校验是否有内置配置 + List configs = configMapper.selectByIds(ids); + configs.forEach(config -> { + if (ConfigTypeEnum.SYSTEM.getType().equals(config.getType())) { + throw exception(CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE); + } + }); + + // 批量删除 + configMapper.deleteByIds(ids); + } + @Override public ConfigDO getConfig(Long id) { return configMapper.selectById(id); diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigService.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigService.java index 8517db93b0..83d2a5d5ce 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigService.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigService.java @@ -35,6 +35,13 @@ public interface DataSourceConfigService { */ void deleteDataSourceConfig(Long id); + /** + * 批量删除数据源配置 + * + * @param ids 编号列表 + */ + void deleteDataSourceConfigList(List ids); + /** * 获得数据源配置 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java index 9e537f83d7..fb3cb502cc 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/db/DataSourceConfigServiceImpl.java @@ -63,6 +63,11 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService { dataSourceConfigMapper.deleteById(id); } + @Override + public void deleteDataSourceConfigList(List ids) { + dataSourceConfigMapper.deleteByIds(ids); + } + private void validateDataSourceConfigExists(Long id) { if (dataSourceConfigMapper.selectById(id) == null) { throw exception(DATA_SOURCE_CONFIG_NOT_EXISTS); diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java index 11dd630b51..e7a58eabf8 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO; import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient; import javax.validation.Valid; +import java.util.List; + /** * 文件配置 Service 接口 * @@ -43,6 +45,13 @@ public interface FileConfigService { */ void deleteFileConfig(Long id); + /** + * 批量删除文件配置 + * + * @param ids 编号列表 + */ + void deleteFileConfigList(List ids); + /** * 获得文件配置 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java index 6a046ea620..9c1f100013 100755 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigServiceImpl.java @@ -25,6 +25,7 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.validation.annotation.Validated; import java.time.Duration; +import java.util.List; import java.util.Map; import java.util.Objects; @@ -134,6 +135,23 @@ public class FileConfigServiceImpl implements FileConfigService { clearCache(id, null); } + @Override + public void deleteFileConfigList(List ids) { + // 校验是否有主配置 + List configs = fileConfigMapper.selectByIds(ids); + for (FileConfigDO config : configs) { + if (Boolean.TRUE.equals(config.getMaster())) { + throw exception(FILE_CONFIG_DELETE_FAIL_MASTER); + } + } + + // 批量删除 + fileConfigMapper.deleteByIds(ids); + + // 清空缓存 + ids.forEach(id -> clearCache(id, null)); + } + /** * 清空指定文件配置 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java index 3e7519017c..6a80818fcc 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileService.java @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresigned import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO; import javax.validation.constraints.NotEmpty; +import java.util.List; + /** * 文件 Service 接口 * @@ -59,6 +61,13 @@ public interface FileService { */ void deleteFile(Long id) throws Exception; + /** + * 批量删除文件 + * + * @param ids 编号列表 + */ + void deleteFileList(List ids) throws Exception; + /** * 获得文件内容 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java index 4da1608e03..98447fb370 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java @@ -16,10 +16,11 @@ import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient; import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO; import cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils; import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; import lombok.SneakyThrows; import org.springframework.stereotype.Service; -import javax.annotation.Resource; +import java.util.List; import static cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; @@ -157,6 +158,23 @@ public class FileServiceImpl implements FileService { fileMapper.deleteById(id); } + @Override + @SneakyThrows + public void deleteFileList(List ids) { + // 删除文件 + List files = fileMapper.selectByIds(ids); + for (FileDO file : files) { + // 获取客户端 + FileClient client = fileConfigService.getFileClient(file.getConfigId()); + Assert.notNull(client, "客户端({}) 不能为空", file.getPath()); + // 删除文件 + client.delete(file.getPath()); + } + + // 删除记录 + fileMapper.deleteByIds(ids); + } + private FileDO validateFileExists(Long id) { FileDO fileDO = fileMapper.selectById(id); if (fileDO == null) { diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobService.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobService.java index a8e839cad3..132d230efb 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobService.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobService.java @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO; import javax.validation.Valid; import org.quartz.SchedulerException; +import java.util.List; + /** * 定时任务 Service 接口 * @@ -58,6 +60,13 @@ public interface JobService { */ void deleteJob(Long id) throws SchedulerException; + /** + * 批量删除定时任务 + * + * @param ids 编号列表 + */ + void deleteJobList(List ids) throws SchedulerException; + /** * 获得定时任务 * diff --git a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java index 8d180dbaa7..c81d5b30ab 100644 --- a/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java +++ b/yudao-module-infra/src/main/java/cn/iocoder/yudao/module/infra/service/job/JobServiceImpl.java @@ -169,6 +169,19 @@ public class JobServiceImpl implements JobService { schedulerManager.deleteJob(job.getHandlerName()); } + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteJobList(List ids) throws SchedulerException { + // 批量删除 + List jobs = jobMapper.selectByIds(ids); + jobMapper.deleteByIds(ids); + + // 删除 Job 到 Quartz 中 + for (JobDO job : jobs) { + schedulerManager.deleteJob(job.getHandlerName()); + } + } + private JobDO validateJobExists(Long id) { JobDO job = jobMapper.selectById(id); if (job == null) { diff --git a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java index 0c3089781d..ce261411c2 100755 --- a/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java +++ b/yudao-module-mall/yudao-module-product/src/main/java/cn/iocoder/yudao/module/product/controller/admin/spu/ProductSpuController.java @@ -124,7 +124,7 @@ public class ProductSpuController { return success(productSpuService.getTabsCount()); } - @GetMapping("/export") + @GetMapping("/export-excel") @Operation(summary = "导出商品") @PreAuthorize("@ss.hasPermission('product:spu:export')") @ApiAccessLog(operateType = EXPORT) diff --git a/yudao-module-mall/yudao-module-statistics/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java b/yudao-module-mall/yudao-module-statistics/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java index 600296f669..c1b21e8423 100644 --- a/yudao-module-mall/yudao-module-statistics/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java +++ b/yudao-module-mall/yudao-module-statistics/src/main/java/cn/iocoder/yudao/module/statistics/dal/mysql/product/ProductStatisticsMapper.java @@ -15,6 +15,8 @@ import org.apache.ibatis.annotations.Param; import java.time.LocalDateTime; import java.util.List; +import static cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils.toUnderlineCase; + /** * 商品统计 Mapper * @@ -49,16 +51,16 @@ public interface ProductStatisticsMapper extends BaseMapperX buildWrapper(ProductStatisticsReqVO reqVO) { return new MPJLambdaWrapperX() .betweenIfPresent(ProductStatisticsDO::getTime, reqVO.getTimes()) - .selectSum(ProductStatisticsDO::getBrowseCount) - .selectSum(ProductStatisticsDO::getBrowseUserCount) - .selectSum(ProductStatisticsDO::getFavoriteCount) - .selectSum(ProductStatisticsDO::getCartCount) - .selectSum(ProductStatisticsDO::getOrderCount) - .selectSum(ProductStatisticsDO::getOrderPayCount) - .selectSum(ProductStatisticsDO::getOrderPayPrice) - .selectSum(ProductStatisticsDO::getAfterSaleCount) - .selectSum(ProductStatisticsDO::getAfterSaleRefundPrice) - .selectAvg(ProductStatisticsDO::getBrowseConvertPercent); + .selectSum(ProductStatisticsDO::getBrowseCount, toUnderlineCase(ProductStatisticsDO::getBrowseCount)) + .selectSum(ProductStatisticsDO::getBrowseUserCount, toUnderlineCase(ProductStatisticsDO::getBrowseUserCount)) + .selectSum(ProductStatisticsDO::getFavoriteCount, toUnderlineCase(ProductStatisticsDO::getFavoriteCount)) + .selectSum(ProductStatisticsDO::getCartCount, toUnderlineCase(ProductStatisticsDO::getCartCount)) + .selectSum(ProductStatisticsDO::getOrderCount, toUnderlineCase(ProductStatisticsDO::getOrderCount)) + .selectSum(ProductStatisticsDO::getOrderPayCount, toUnderlineCase(ProductStatisticsDO::getOrderPayCount)) + .selectSum(ProductStatisticsDO::getOrderPayPrice, toUnderlineCase(ProductStatisticsDO::getOrderPayPrice)) + .selectSum(ProductStatisticsDO::getAfterSaleCount, toUnderlineCase(ProductStatisticsDO::getAfterSaleCount)) + .selectSum(ProductStatisticsDO::getAfterSaleRefundPrice, toUnderlineCase(ProductStatisticsDO::getAfterSaleRefundPrice)) + .selectAvg(ProductStatisticsDO::getBrowseConvertPercent, toUnderlineCase(ProductStatisticsDO::getBrowseConvertPercent)); } /** diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java index 6c4a3a9d5c..86815b7a6a 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/PostController.java @@ -91,7 +91,7 @@ public class PostController { return success(BeanUtils.toBean(pageResult, PostRespVO.class)); } - @GetMapping("/export") + @GetMapping("/export-excel") @Operation(summary = "岗位管理") @PreAuthorize("@ss.hasPermission('system:post:export')") @ApiAccessLog(operateType = EXPORT) diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java index d7402a1749..0c9b5e11e1 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictDataController.java @@ -58,11 +58,20 @@ public class DictDataController { @Operation(summary = "删除字典数据") @Parameter(name = "id", description = "编号", required = true, example = "1024") @PreAuthorize("@ss.hasPermission('system:dict:delete')") - public CommonResult deleteDictData(Long id) { + public CommonResult deleteDictData(@RequestParam("id") Long id) { dictDataService.deleteDictData(id); return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除字典数据") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('system:dict:delete')") + public CommonResult deleteDictDataList(@RequestParam("ids") List ids) { + dictDataService.deleteDictDataList(ids); + return success(true); + } + @GetMapping(value = {"/list-all-simple", "simple-list"}) @Operation(summary = "获得全部字典数据列表", description = "一般用于管理后台缓存字典数据在本地") // 无需添加权限认证,因为前端全局都需要 @@ -73,7 +82,7 @@ public class DictDataController { } @GetMapping("/page") - @Operation(summary = "/获得字典类型的分页列表") + @Operation(summary = "获得字典类型的分页") @PreAuthorize("@ss.hasPermission('system:dict:query')") public CommonResult> getDictTypePage(@Valid DictDataPageReqVO pageReqVO) { PageResult pageResult = dictDataService.getDictDataPage(pageReqVO); @@ -89,7 +98,7 @@ public class DictDataController { return success(BeanUtils.toBean(dictData, DictDataRespVO.class)); } - @GetMapping("/export") + @GetMapping("/export-excel") @Operation(summary = "导出字典数据") @PreAuthorize("@ss.hasPermission('system:dict:export')") @ApiAccessLog(operateType = EXPORT) diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java index 65f8e7daeb..e6246d550b 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dict/DictTypeController.java @@ -62,6 +62,15 @@ public class DictTypeController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除字典类型") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('system:dict:delete')") + public CommonResult deleteDictTypeList(@RequestParam("ids") List ids) { + dictTypeService.deleteDictTypeList(ids); + return success(true); + } + @GetMapping("/page") @Operation(summary = "获得字典类型的分页列表") @PreAuthorize("@ss.hasPermission('system:dict:query')") @@ -88,7 +97,7 @@ public class DictTypeController { } @Operation(summary = "导出数据类型") - @GetMapping("/export") + @GetMapping("/export-excel") @PreAuthorize("@ss.hasPermission('system:dict:query')") @ApiAccessLog(operateType = EXPORT) public void export(HttpServletResponse response, @Valid DictTypePageReqVO exportReqVO) throws IOException { diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java index 9fa4dc1b80..8fe089a742 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/LoginLogController.java @@ -44,7 +44,7 @@ public class LoginLogController { return success(BeanUtils.toBean(pageResult, LoginLogRespVO.class)); } - @GetMapping("/export") + @GetMapping("/export-excel") @Operation(summary = "导出登录日志 Excel") @PreAuthorize("@ss.hasPermission('system:login-log:export')") @ApiAccessLog(operateType = EXPORT) diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java index e926f0b539..9d557bd2dd 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/logger/OperateLogController.java @@ -46,7 +46,7 @@ public class OperateLogController { } @Operation(summary = "导出操作日志") - @GetMapping("/export") + @GetMapping("/export-excel") @PreAuthorize("@ss.hasPermission('system:operate-log:export')") @ApiAccessLog(operateType = EXPORT) public void exportOperateLog(HttpServletResponse response, @Valid OperateLogPageReqVO exportReqVO) throws IOException { diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java index 0ddd9243b9..e19e28500e 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/MenuController.java @@ -12,12 +12,12 @@ import cn.iocoder.yudao.module.system.service.permission.MenuService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.annotation.Resource; +import jakarta.validation.Valid; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; -import javax.annotation.Resource; -import javax.validation.Valid; import java.util.Comparator; import java.util.List; @@ -57,6 +57,15 @@ public class MenuController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除菜单") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('system:menu:delete')") + public CommonResult deleteMenuList(@RequestParam("ids") List ids) { + menuService.deleteMenuList(ids); + return success(true); + } + @GetMapping("/list") @Operation(summary = "获取菜单列表", description = "用于【菜单管理】界面") @PreAuthorize("@ss.hasPermission('system:menu:query')") diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java index c667a7ee3c..0cb3093e0e 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/permission/RoleController.java @@ -7,7 +7,9 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.*; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleRespVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; import cn.iocoder.yudao.module.system.service.permission.RoleService; import io.swagger.v3.oas.annotations.Operation; @@ -61,6 +63,15 @@ public class RoleController { return success(true); } + @DeleteMapping("/delete-list") + @Operation(summary = "批量删除角色") + @Parameter(name = "ids", description = "编号列表", required = true) + @PreAuthorize("@ss.hasPermission('system:role:delete')") + public CommonResult deleteRoleList(@RequestParam("ids") List ids) { + roleService.deleteRoleList(ids); + return success(true); + } + @GetMapping("/get") @Operation(summary = "获得角色信息") @PreAuthorize("@ss.hasPermission('system:role:query')") diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java index 979ee2aa8c..93d0ca16df 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/controller/admin/user/UserController.java @@ -136,7 +136,7 @@ public class UserController { return success(UserConvert.INSTANCE.convert(user, dept)); } - @GetMapping("/export") + @GetMapping("/export-excel") @Operation(summary = "导出用户") @PreAuthorize("@ss.hasPermission('system:user:export')") @ApiAccessLog(operateType = EXPORT) diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java index 25604ceb33..7fd6699b30 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostService.java @@ -38,6 +38,13 @@ public interface PostService { */ void deletePost(Long id); + /** + * 批量删除岗位信息 + * + * @param ids 岗位编号数组 + */ + void deletePostList(List ids); + /** * 获得岗位列表 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java index e93cfa06df..c90308a11b 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dept/PostServiceImpl.java @@ -8,10 +8,10 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostPageReqV import cn.iocoder.yudao.module.system.controller.admin.dept.vo.post.PostSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.dept.PostDO; import cn.iocoder.yudao.module.system.dal.mysql.dept.PostMapper; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.validation.annotation.Validated; -import javax.annotation.Resource; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -58,10 +58,15 @@ public class PostServiceImpl implements PostService { public void deletePost(Long id) { // 校验是否存在 validatePostExists(id); - // 删除部门 + // 删除岗位 postMapper.deleteById(id); } + @Override + public void deletePostList(List ids) { + postMapper.deleteByIds(ids); + } + private void validatePostForCreateOrUpdate(Long id, String name, String code) { // 校验自己存在 validatePostExists(id); diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java index fc2498f1b8..3f4a3b9d0c 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataService.java @@ -38,6 +38,13 @@ public interface DictDataService { */ void deleteDictData(Long id); + /** + * 批量删除字典数据 + * + * @param ids 字典数据编号列表 + */ + void deleteDictDataList(List ids); + /** * 获得字典数据列表 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java index e9f215de86..f20513f7d5 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictDataServiceImpl.java @@ -98,6 +98,11 @@ public class DictDataServiceImpl implements DictDataService { dictDataMapper.deleteById(id); } + @Override + public void deleteDictDataList(List ids) { + dictDataMapper.deleteByIds(ids); + } + @Override public long getDictDataCountByDictType(String dictType) { return dictDataMapper.selectCountByDictType(dictType); diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeService.java index 40911891c5..5f617e7542 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeService.java @@ -36,6 +36,13 @@ public interface DictTypeService { */ void deleteDictType(Long id); + /** + * 批量删除字典类型 + * + * @param ids 字典类型编号列表 + */ + void deleteDictTypeList(List ids); + /** * 获得字典类型分页列表 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java index 5e7f27e55a..1da442ea84 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/dict/DictTypeServiceImpl.java @@ -9,9 +9,9 @@ import cn.iocoder.yudao.module.system.controller.admin.dict.vo.type.DictTypeSave import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictTypeDO; import cn.iocoder.yudao.module.system.dal.mysql.dict.DictTypeMapper; import com.google.common.annotations.VisibleForTesting; +import jakarta.annotation.Resource; import org.springframework.stereotype.Service; -import javax.annotation.Resource; import java.time.LocalDateTime; import java.util.List; @@ -87,6 +87,21 @@ public class DictTypeServiceImpl implements DictTypeService { dictTypeMapper.updateToDelete(id, LocalDateTime.now()); } + @Override + public void deleteDictTypeList(List ids) { + // 1. 校验是否有字典数据 + List dictTypes = dictTypeMapper.selectByIds(ids); + dictTypes.forEach(dictType -> { + if (dictDataService.getDictDataCountByDictType(dictType.getType()) > 0) { + throw exception(DICT_TYPE_HAS_CHILDREN); + } + }); + + // 2. 批量删除字典类型 + LocalDateTime now = LocalDateTime.now(); + ids.forEach(id -> dictTypeMapper.updateToDelete(id, now)); + } + @Override public List getDictTypeList() { return dictTypeMapper.selectList(); diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java index d74dc61340..0d5f0fd841 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuService.java @@ -1,7 +1,7 @@ package cn.iocoder.yudao.module.system.service.permission; -import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuSaveVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuListReqVO; +import cn.iocoder.yudao.module.system.controller.admin.permission.vo.menu.MenuSaveVO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.MenuDO; import java.util.Collection; @@ -36,6 +36,13 @@ public interface MenuService { */ void deleteMenu(Long id); + /** + * 批量删除菜单 + * + * @param ids 菜单编号数组 + */ + void deleteMenuList(List ids); + /** * 获得所有菜单列表 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java index 90c992bc91..d9d0ea2d41 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/MenuServiceImpl.java @@ -104,6 +104,24 @@ public class MenuServiceImpl implements MenuService { permissionService.processMenuDeleted(id); } + @Override + @Transactional(rollbackFor = Exception.class) + @CacheEvict(value = RedisKeyConstants.PERMISSION_MENU_ID_LIST, + allEntries = true) // allEntries 清空所有缓存,因为 Spring Cache 不支持按照 ids 批量删除 + public void deleteMenuList(List ids) { + // 校验是否还有子菜单 + ids.forEach(id -> { + if (menuMapper.selectCountByParentId(id) > 0) { + throw exception(MENU_EXISTS_CHILDREN); + } + }); + + // 标记删除 + menuMapper.deleteByIds(ids); + // 删除授予给角色的权限 + ids.forEach(id -> permissionService.processMenuDeleted(id)); + } + @Override public List getMenuList() { return menuMapper.selectList(); diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java index 44ec11003d..7426d981a6 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleService.java @@ -4,8 +4,8 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RolePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; +import jakarta.validation.Valid; -import javax.validation.Valid; import java.util.Collection; import java.util.List; import java.util.Set; @@ -40,6 +40,13 @@ public interface RoleService { */ void deleteRole(Long id); + /** + * 批量删除角色 + * + * @param ids 角色编号数组 + */ + void deleteRoleList(List ids); + /** * 设置角色的数据权限 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java index e0cfd2600f..06d0c7edf3 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java @@ -122,6 +122,18 @@ public class RoleServiceImpl implements RoleService { LogRecordContext.putVariable("role", role); } + @Override + @Transactional(rollbackFor = Exception.class) + public void deleteRoleList(List ids) { + // 1. 校验是否可以删除 + ids.forEach(this::validateRoleForUpdate); + + // 2.1 标记删除 + roleMapper.deleteByIds(ids); + // 2.2 删除相关数据 + ids.forEach(id -> permissionService.processRoleDeleted(id)); + } + /** * 校验角色的唯一字段是否重复 * diff --git a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java index 770e754dd7..e03bd208e1 100644 --- a/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java +++ b/yudao-module-system/src/main/java/cn/iocoder/yudao/module/system/service/social/SocialClientServiceImpl.java @@ -69,6 +69,7 @@ import java.util.Objects; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.MapUtils.findAndThen; import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.UTC_MS_WITH_XXX_OFFSET_FORMATTER; +import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.toEpochSecond; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*; import static java.util.Collections.singletonList; @@ -381,7 +382,7 @@ public class SocialClientServiceImpl implements SocialClientService { WxMaService service = getWxMaService(userType); WxMaOrderShippingInfoNotifyConfirmRequest request = WxMaOrderShippingInfoNotifyConfirmRequest.builder() .transactionId(reqDTO.getTransactionId()) - .receivedTime(LocalDateTimeUtil.toEpochMilli(reqDTO.getReceivedTime())) + .receivedTime(toEpochSecond(reqDTO.getReceivedTime())) .build(); try { WxMaOrderShippingInfoBaseResponse response = service.getWxMaOrderShippingService().notifyConfirmReceive(request);