package com.linghu.controller; import com.alibaba.excel.EasyExcel; import com.alibaba.excel.ExcelWriter; import com.alibaba.excel.write.handler.SheetWriteHandler; import com.alibaba.excel.write.metadata.WriteSheet; import com.alibaba.excel.write.metadata.holder.WriteSheetHolder; import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.linghu.listener.PlatformExcelListener; import com.linghu.listener.TypeDropdownWriteHandler; import com.linghu.mapper.ReferenceMapper; import com.linghu.model.common.ResponseResult; import com.linghu.model.entity.Platform; import com.linghu.model.entity.Reference; import com.linghu.model.entity.Sectionalization; import com.linghu.model.entity.Type; import com.linghu.model.excel.ExcelDataWithRow; import com.linghu.model.excel.PlatformExcel; import com.linghu.model.excel.UserExcel; import com.linghu.model.page.CustomPage; import com.linghu.service.PlatformService; import com.linghu.service.TypeService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.log4j.Log4j; import lombok.extern.slf4j.Slf4j; import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.DataValidationConstraint; import org.apache.poi.ss.usermodel.DataValidationHelper; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.util.CellRangeAddressList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.time.LocalDateTime; import java.util.*; import java.util.Objects; import java.util.stream.Collectors; @RestController @RequestMapping("/platform") @Api(value = "平台相关接口", tags = "设置-平台") @Slf4j public class PlatformController { @Autowired private PlatformService platformService; @Autowired private TypeService typeService; @Autowired private ReferenceMapper referenceMapper; @PostMapping @ApiOperation(value = "添加平台") public ResponseResult add(@RequestBody Platform platform) { // 校验平台名称和域名不能为空 if (!StringUtils.hasText(platform.getPlatform_name())) { return ResponseResult.error("平台名称不能为空"); } if (!StringUtils.hasText(platform.getDomain())) { return ResponseResult.error("平台域名不能为空"); } platform.setCreate_time(LocalDateTime.now()); boolean success = platformService.save(platform); if (success) { return ResponseResult.success(platform); } return ResponseResult.error("添加平台失败"); } @DeleteMapping("/{platformId}") @ApiOperation(value = "删除平台") public ResponseResult delete(@PathVariable Integer platformId) { //平台被引用了没 Integer count = referenceMapper.selectCount(new LambdaQueryWrapper().eq(Reference::getPlatform_id, platformId)); if (count > 0) { return ResponseResult.error("该平台被引用中,不能删除"); } boolean success = platformService.removeById(platformId); if (success) { return ResponseResult.success(); } return ResponseResult.error("删除平台失败"); } @PutMapping @ApiOperation(value = "更新平台") public ResponseResult update(@RequestBody Platform platform) { // 校验平台名称和域名不能为空 if (!StringUtils.hasText(platform.getPlatform_name())) { return ResponseResult.error("平台名称不能为空"); } if (!StringUtils.hasText(platform.getDomain())) { return ResponseResult.error("平台域名不能为空"); } platformService.updateById(platform); return ResponseResult.success(); } @GetMapping("/{platformId}") @ApiOperation("根据id获取平台") public ResponseResult getById(@PathVariable Integer platformId) { Platform platform = platformService.getById(platformId); if (platform != null) { return ResponseResult.success(platform); } return ResponseResult.error("平台不存在"); } @GetMapping("/list") @ApiOperation("查询平台列表,不传页数和大小就查全部") public ResponseResult> list( @RequestParam(required = false) Integer page, @RequestParam(required = false) Integer pageSize, @RequestParam(required = false) Integer type_id) { // 构建查询条件并添加排序(按创建时间倒序) LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.orderByDesc(Platform::getCreate_time); // 新增的排序条件 if (type_id != null) { queryWrapper.eq(Platform::getType_id, type_id); } if (page != null && pageSize != null) { Page pageInfo = new Page<>(page, pageSize); Page result = platformService.page(pageInfo, queryWrapper); return ResponseResult.success(new CustomPage<>(result)); } else { List list = platformService.list(queryWrapper); CustomPage customPage = new CustomPage<>(new Page<>()); customPage.setRecords(list); customPage.setTotal(list.size()); return ResponseResult.success(customPage); } } @GetMapping("/download") @ApiOperation("下载平台模板") public ResponseEntity downloadTemplate() throws IOException { // 获取所有类型名称 List typeList = typeService.list(); List typeNames = typeList.stream() .map(Type::getType_name) .collect(Collectors.toList()); ByteArrayOutputStream out = new ByteArrayOutputStream(); // 注册下拉框拦截器 EasyExcel.write(out, PlatformExcel.class) .registerWriteHandler(new TypeDropdownWriteHandler(typeNames)) .sheet("平台模板") .doWrite(new ArrayList<>()); return ResponseEntity.ok() .header(HttpHeaders.CONTENT_DISPOSITION, "attachment;filename=platform_template.xlsx") .contentType(MediaType.APPLICATION_OCTET_STREAM) .body(out.toByteArray()); } @PostMapping("/import") @ApiOperation("导入平台数据") public ResponseResult importPlatforms(@RequestParam("file") MultipartFile file) { try { if (file.isEmpty()) { return ResponseResult.error("上传文件不能为空"); } // 获取数据库中的旧数据 List oldPlatforms = platformService.list(); // 使用自定义监听器读取数据(包含行号) PlatformExcelListener listener = new PlatformExcelListener(); EasyExcel.read(file.getInputStream()) .head(PlatformExcel.class) .sheet() .registerReadListener(listener) .doRead(); List> excelList = listener.getDataList(); List platforms = new ArrayList<>(); List errorMessages = new ArrayList<>(); // 遍历数据并验证 for (ExcelDataWithRow excelData : excelList) { int rowNum = excelData.getRowNumber(); PlatformExcel excel = excelData.getData(); List rowErrors = new ArrayList<>(); // 验证逻辑 if (!StringUtils.hasText(excel.getPlatform_name())) { rowErrors.add("平台名称不能为空"); } if (!StringUtils.hasText(excel.getDomain())) { rowErrors.add("平台域名不能为空"); } // 查找类型(仅当类型名称不为空时检查,避免空指针) Integer typeId = null; if (StringUtils.hasText(excel.getType_name())) { Type typeByName = typeService.getTypeByName(excel.getType_name()); if (typeByName == null) { rowErrors.add("未知的平台类型: " + excel.getType_name()); } else { typeId = typeByName.getType_id(); } } else { rowErrors.add("平台类型不能为空"); } if (!rowErrors.isEmpty()) { errorMessages.add(String.format("第%d行错误: %s", rowNum, String.join(";", rowErrors))); } else { // 构建Platform对象 Platform platform = new Platform(); platform.setPlatform_name(excel.getPlatform_name()); platform.setDomain(excel.getDomain()); platform.setType_id(typeId); platform.setCreate_time(LocalDateTime.now()); // 检查重复性 boolean isDuplicate = false; for (Platform oldPlatform : oldPlatforms) { // 判断重复的条件,这里假设平台名称和域名都相同才算重复 if (oldPlatform.getPlatform_name().equals(platform.getPlatform_name()) && oldPlatform.getDomain().equals(platform.getDomain())) { isDuplicate = true; break; } } // 如果不重复才添加到导入列表 if (!isDuplicate) { platforms.add(platform); } } } // 错误处理 if (!errorMessages.isEmpty()) { StringBuilder errorMsg = new StringBuilder(); errorMsg.append("导入失败,共").append(errorMessages.size()).append("条数据存在错误:\n"); errorMessages.forEach(msg -> errorMsg.append(msg).append("\n")); return ResponseResult.error(400, errorMsg.toString()); } // 无错误时导入 if (!platforms.isEmpty()) { platformService.saveBatch(platforms); return ResponseResult.success("导入成功,新增" + platforms.size() + "条数据"); } else { return ResponseResult.success("导入完成,没有新增数据(所有数据均已存在)"); } } catch (Exception e) { log.error("文件解析失败", e); return ResponseResult.error("文件解析失败:" + e.getMessage()); } } }