feat: infra 模块新增批量删除接口

This commit is contained in:
puhui999 2025-06-15 13:55:24 +08:00
parent 39d1954ec9
commit 777d64f065
18 changed files with 252 additions and 0 deletions

View File

@ -122,6 +122,15 @@ public class CodegenController {
return success(true); return success(true);
} }
@Operation(summary = "批量删除数据库的表和字段定义")
@DeleteMapping("/delete-list")
@Parameter(name = "tableIds", description = "表编号列表", required = true)
@PreAuthorize("@ss.hasPermission('infra:codegen:delete')")
public CommonResult<Boolean> deleteCodegenList(@RequestParam("tableIds") List<Long> tableIds) {
codegenService.deleteCodegenList(tableIds);
return success(true);
}
@Operation(summary = "预览生成代码") @Operation(summary = "预览生成代码")
@GetMapping("/preview") @GetMapping("/preview")
@Parameter(name = "tableId", description = "表编号", required = true, example = "1024") @Parameter(name = "tableId", description = "表编号", required = true, example = "1024")

View File

@ -62,6 +62,15 @@ public class ConfigController {
return success(true); return success(true);
} }
@DeleteMapping("/delete-list")
@Operation(summary = "批量删除参数配置")
@Parameter(name = "ids", description = "编号列表", required = true)
@PreAuthorize("@ss.hasPermission('infra:config:delete')")
public CommonResult<Boolean> deleteConfigList(@RequestParam("ids") List<Long> ids) {
configService.deleteConfigList(ids);
return success(true);
}
@GetMapping(value = "/get") @GetMapping(value = "/get")
@Operation(summary = "获得参数配置") @Operation(summary = "获得参数配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")

View File

@ -52,6 +52,15 @@ public class DataSourceConfigController {
return success(true); return success(true);
} }
@DeleteMapping("/delete-list")
@Operation(summary = "批量删除数据源配置")
@Parameter(name = "ids", description = "编号列表", required = true)
@PreAuthorize("@ss.hasPermission('infra:data-source-config:delete')")
public CommonResult<Boolean> deleteDataSourceConfigList(@RequestParam("ids") List<Long> ids) {
dataSourceConfigService.deleteDataSourceConfigList(ids);
return success(true);
}
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得数据源配置") @Operation(summary = "获得数据源配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")

View File

@ -17,6 +17,8 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 文件配置") @Tag(name = "管理后台 - 文件配置")
@ -60,6 +62,15 @@ public class FileConfigController {
return success(true); return success(true);
} }
@DeleteMapping("/delete-list")
@Operation(summary = "批量删除文件配置")
@Parameter(name = "ids", description = "编号列表", required = true)
@PreAuthorize("@ss.hasPermission('infra:file-config:delete')")
public CommonResult<Boolean> deleteFileConfigList(@RequestParam("ids") List<Long> ids) {
fileConfigService.deleteFileConfigList(ids);
return success(true);
}
@GetMapping("/get") @GetMapping("/get")
@Operation(summary = "获得文件配置") @Operation(summary = "获得文件配置")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")

View File

@ -26,6 +26,8 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment; import static cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils.writeAttachment;
@ -75,6 +77,15 @@ public class FileController {
return success(true); return success(true);
} }
@DeleteMapping("/delete-list")
@Operation(summary = "批量删除文件")
@Parameter(name = "ids", description = "编号列表", required = true)
@PreAuthorize("@ss.hasPermission('infra:file:delete')")
public CommonResult<Boolean> deleteFileList(@RequestParam("ids") List<Long> ids) throws Exception {
fileService.deleteFileList(ids);
return success(true);
}
@GetMapping("/{configId}/get/**") @GetMapping("/{configId}/get/**")
@PermitAll @PermitAll
@TenantIgnore @TenantIgnore

View File

@ -81,6 +81,16 @@ public class JobController {
return success(true); return success(true);
} }
@DeleteMapping("/delete-list")
@Operation(summary = "批量删除定时任务")
@Parameter(name = "ids", description = "编号列表", required = true)
@PreAuthorize("@ss.hasPermission('infra:job:delete')")
public CommonResult<Boolean> deleteJobList(@RequestParam("ids") List<Long> ids)
throws SchedulerException {
jobService.deleteJobList(ids);
return success(true);
}
@PutMapping("/trigger") @PutMapping("/trigger")
@Operation(summary = "触发定时任务") @Operation(summary = "触发定时任务")
@Parameter(name = "id", description = "编号", required = true, example = "1024") @Parameter(name = "id", description = "编号", required = true, example = "1024")

View File

@ -48,6 +48,13 @@ public interface CodegenService {
*/ */
void deleteCodegen(Long tableId); void deleteCodegen(Long tableId);
/**
* 批量删除数据库的表和字段定义
*
* @param tableIds 数据编号列表
*/
void deleteCodegenList(List<Long> tableIds);
/** /**
* 获得表定义列表 * 获得表定义列表
* *

View File

@ -222,6 +222,25 @@ public class CodegenServiceImpl implements CodegenService {
codegenColumnMapper.deleteListByTableId(tableId); codegenColumnMapper.deleteListByTableId(tableId);
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteCodegenList(List<Long> tableIds) {
if (CollUtil.isEmpty(tableIds)) {
return;
}
// 校验是否都存在
List<CodegenTableDO> tables = codegenTableMapper.selectByIds(tableIds);
if (tables.size() != tableIds.size()) {
throw exception(CODEGEN_TABLE_NOT_EXISTS);
}
// 批量删除 table 表定义
codegenTableMapper.deleteByIds(tableIds);
// 批量删除 column 字段定义
tableIds.forEach(tableId -> codegenColumnMapper.deleteListByTableId(tableId));
}
@Override @Override
public List<CodegenTableDO> getCodegenTableList(Long dataSourceConfigId) { public List<CodegenTableDO> getCodegenTableList(Long dataSourceConfigId) {
return codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId); return codegenTableMapper.selectListByDataSourceConfigId(dataSourceConfigId);

View File

@ -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 cn.iocoder.yudao.module.infra.dal.dataobject.config.ConfigDO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.List;
/** /**
* 参数配置 Service 接口 * 参数配置 Service 接口
* *
@ -35,6 +37,13 @@ public interface ConfigService {
*/ */
void deleteConfig(Long id); void deleteConfig(Long id);
/**
* 批量删除参数配置
*
* @param ids 配置编号列表
*/
void deleteConfigList(List<Long> ids);
/** /**
* 获得参数配置 * 获得参数配置
* *

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.infra.service.config; package cn.iocoder.yudao.module.infra.service.config;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO; import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigPageReqVO;
import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigSaveReqVO; import cn.iocoder.yudao.module.infra.controller.admin.config.vo.ConfigSaveReqVO;
@ -13,6 +14,8 @@ import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated; 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.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.*;
@ -63,6 +66,28 @@ public class ConfigServiceImpl implements ConfigService {
configMapper.deleteById(id); configMapper.deleteById(id);
} }
@Override
public void deleteConfigList(List<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 校验配置存在
List<ConfigDO> configs = configMapper.selectByIds(ids);
if (configs.size() != ids.size()) {
throw exception(CONFIG_NOT_EXISTS);
}
// 校验是否有内置配置
for (ConfigDO config : configs) {
if (ConfigTypeEnum.SYSTEM.getType().equals(config.getType())) {
throw exception(CONFIG_CAN_NOT_DELETE_SYSTEM_TYPE);
}
}
// 批量删除
configMapper.deleteByIds(ids);
}
@Override @Override
public ConfigDO getConfig(Long id) { public ConfigDO getConfig(Long id) {
return configMapper.selectById(id); return configMapper.selectById(id);

View File

@ -35,6 +35,13 @@ public interface DataSourceConfigService {
*/ */
void deleteDataSourceConfig(Long id); void deleteDataSourceConfig(Long id);
/**
* 批量删除数据源配置
*
* @param ids 编号列表
*/
void deleteDataSourceConfigList(List<Long> ids);
/** /**
* 获得数据源配置 * 获得数据源配置
* *

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.infra.service.db; package cn.iocoder.yudao.module.infra.service.db;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils; import cn.iocoder.yudao.framework.mybatis.core.util.JdbcUtils;
import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigSaveReqVO; import cn.iocoder.yudao.module.infra.controller.admin.db.vo.DataSourceConfigSaveReqVO;
@ -63,6 +64,17 @@ public class DataSourceConfigServiceImpl implements DataSourceConfigService {
dataSourceConfigMapper.deleteById(id); dataSourceConfigMapper.deleteById(id);
} }
@Override
public void deleteDataSourceConfigList(List<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 校验存在
ids.forEach(this::validateDataSourceConfigExists);
// 批量删除
dataSourceConfigMapper.deleteByIds(ids);
}
private void validateDataSourceConfigExists(Long id) { private void validateDataSourceConfigExists(Long id) {
if (dataSourceConfigMapper.selectById(id) == null) { if (dataSourceConfigMapper.selectById(id) == null) {
throw exception(DATA_SOURCE_CONFIG_NOT_EXISTS); throw exception(DATA_SOURCE_CONFIG_NOT_EXISTS);

View File

@ -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 cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import java.util.List;
/** /**
* 文件配置 Service 接口 * 文件配置 Service 接口
* *
@ -43,6 +45,13 @@ public interface FileConfigService {
*/ */
void deleteFileConfig(Long id); void deleteFileConfig(Long id);
/**
* 批量删除文件配置
*
* @param ids 编号列表
*/
void deleteFileConfigList(List<Long> ids);
/** /**
* 获得文件配置 * 获得文件配置
* *

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.infra.service.file; package cn.iocoder.yudao.module.infra.service.file;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.resource.ResourceUtil; import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
@ -25,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import java.time.Duration; import java.time.Duration;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -134,6 +136,34 @@ public class FileConfigServiceImpl implements FileConfigService {
clearCache(id, null); clearCache(id, null);
} }
@Override
public void deleteFileConfigList(List<Long> ids) {
if (CollUtil.isEmpty(ids)) {
return;
}
// 校验存在
List<FileConfigDO> configs = fileConfigMapper.selectByIds(ids);
if (configs.size() != ids.size()) {
throw exception(FILE_CONFIG_NOT_EXISTS);
}
// 校验是否有主配置
for (FileConfigDO config : configs) {
if (Boolean.TRUE.equals(config.getMaster())) {
throw exception(FILE_CONFIG_DELETE_FAIL_MASTER);
}
}
// 批量删除
fileConfigMapper.deleteByIds(ids);
// 清空缓存
for (Long id : ids) {
clearCache(id, null);
}
}
/** /**
* 清空指定文件配置 * 清空指定文件配置
* *

View File

@ -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 cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotEmpty;
import java.util.List;
/** /**
* 文件 Service 接口 * 文件 Service 接口
* *
@ -59,6 +61,13 @@ public interface FileService {
*/ */
void deleteFile(Long id) throws Exception; void deleteFile(Long id) throws Exception;
/**
* 批量删除文件
*
* @param ids 编号列表
*/
void deleteFileList(List<Long> ids) throws Exception;
/** /**
* 获得文件内容 * 获得文件内容
* *

View File

@ -1,5 +1,6 @@
package cn.iocoder.yudao.module.infra.service.file; package cn.iocoder.yudao.module.infra.service.file;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.io.FileUtil; import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert; import cn.hutool.core.lang.Assert;
@ -20,6 +21,10 @@ import jakarta.annotation.Resource;
import lombok.SneakyThrows; import lombok.SneakyThrows;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN; import static cn.hutool.core.date.DatePattern.PURE_DATE_PATTERN;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS; import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
@ -156,6 +161,36 @@ public class FileServiceImpl implements FileService {
fileMapper.deleteById(id); fileMapper.deleteById(id);
} }
@Override
public void deleteFileList(List<Long> ids) throws Exception {
if (CollUtil.isEmpty(ids)) {
return;
}
// 校验存在
List<FileDO> files = fileMapper.selectByIds(ids);
if (files.size() != ids.size()) {
throw exception(FILE_NOT_EXISTS);
}
// 按照配置分组批量删除
Map<Long, List<FileDO>> configFiles = files.stream()
.collect(Collectors.groupingBy(FileDO::getConfigId));
for (Map.Entry<Long, List<FileDO>> entry : configFiles.entrySet()) {
// 获取客户端
FileClient client = fileConfigService.getFileClient(entry.getKey());
Assert.notNull(client, "客户端({}) 不能为空", entry.getKey());
// 批量删除文件
for (FileDO file : entry.getValue()) {
client.delete(file.getPath());
}
}
// 删除记录
fileMapper.deleteByIds(ids);
}
private FileDO validateFileExists(Long id) { private FileDO validateFileExists(Long id) {
FileDO fileDO = fileMapper.selectById(id); FileDO fileDO = fileMapper.selectById(id);
if (fileDO == null) { if (fileDO == null) {

View File

@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.job.JobDO;
import jakarta.validation.Valid; import jakarta.validation.Valid;
import org.quartz.SchedulerException; import org.quartz.SchedulerException;
import java.util.List;
/** /**
* 定时任务 Service 接口 * 定时任务 Service 接口
* *
@ -58,6 +60,13 @@ public interface JobService {
*/ */
void deleteJob(Long id) throws SchedulerException; void deleteJob(Long id) throws SchedulerException;
/**
* 批量删除定时任务
*
* @param ids 编号列表
*/
void deleteJobList(List<Long> ids) throws SchedulerException;
/** /**
* 获得定时任务 * 获得定时任务
* *

View File

@ -169,6 +169,28 @@ public class JobServiceImpl implements JobService {
schedulerManager.deleteJob(job.getHandlerName()); schedulerManager.deleteJob(job.getHandlerName());
} }
@Override
@Transactional(rollbackFor = Exception.class)
public void deleteJobList(List<Long> ids) throws SchedulerException {
if (ids == null || ids.isEmpty()) {
return;
}
// 校验存在
List<JobDO> jobs = jobMapper.selectByIds(ids);
if (jobs.size() != ids.size()) {
throw exception(JOB_NOT_EXISTS);
}
// 批量删除
jobMapper.deleteByIds(ids);
// 删除 Job Quartz
for (JobDO job : jobs) {
schedulerManager.deleteJob(job.getHandlerName());
}
}
private JobDO validateJobExists(Long id) { private JobDO validateJobExists(Long id) {
JobDO job = jobMapper.selectById(id); JobDO job = jobMapper.selectById(id);
if (job == null) { if (job == null) {