|
|
@@ -0,0 +1,240 @@
|
|
|
+package org.dromara.physical.service.impl;
|
|
|
+
|
|
|
+import cn.idev.excel.EasyExcel;
|
|
|
+import cn.idev.excel.context.AnalysisContext;
|
|
|
+import cn.idev.excel.event.AnalysisEventListener;
|
|
|
+import org.apache.commons.collections4.CollectionUtils;
|
|
|
+import org.dromara.business.utils.JudgeCodeGeneratorUtils;
|
|
|
+import org.dromara.common.core.domain.R;
|
|
|
+import org.dromara.common.core.utils.MapstructUtils;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
+import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.dromara.physical.domain.PhysicalJudge;
|
|
|
+import org.dromara.physical.domain.bo.PhysicalJudgeBo;
|
|
|
+import org.dromara.physical.domain.vo.PhysicalBlindLevelsImportVo;
|
|
|
+import org.dromara.physical.domain.vo.PhysicalJudgeImportVo;
|
|
|
+import org.dromara.physical.domain.vo.PhysicalJudgeVo;
|
|
|
+import org.dromara.physical.mapper.PhysicalJudgeMapper;
|
|
|
+import org.dromara.physical.service.IPhysicalJudgeService;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.Collection;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 裁判管理Service业务层处理
|
|
|
+ *
|
|
|
+ * @author Lion Li
|
|
|
+ * @date 2025-12-24
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Service
|
|
|
+public class PhysicalJudgeServiceImpl implements IPhysicalJudgeService {
|
|
|
+
|
|
|
+ private final PhysicalJudgeMapper baseMapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询裁判管理
|
|
|
+ *
|
|
|
+ * @param id 主键
|
|
|
+ * @return 裁判管理
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public PhysicalJudgeVo queryById(Long id){
|
|
|
+ return baseMapper.selectPhysicalJudgeById(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 分页查询裁判管理列表
|
|
|
+ *
|
|
|
+ * @param bo 查询条件
|
|
|
+ * @param pageQuery 分页参数
|
|
|
+ * @return 裁判管理分页列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public TableDataInfo<PhysicalJudgeVo> queryPageList(PhysicalJudgeBo bo, PageQuery pageQuery) {
|
|
|
+ LambdaQueryWrapper<PhysicalJudge> lqw = buildQueryWrapper(bo);
|
|
|
+ Page<PhysicalJudgeVo> result = baseMapper.selectPhysicalJudgePage(pageQuery.build(), lqw);
|
|
|
+ return TableDataInfo.build(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 查询符合条件的裁判管理列表
|
|
|
+ *
|
|
|
+ * @param bo 查询条件
|
|
|
+ * @return 裁判管理列表
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public List<PhysicalJudgeVo> queryList(PhysicalJudgeBo bo) {
|
|
|
+ LambdaQueryWrapper<PhysicalJudge> lqw = buildQueryWrapper(bo);
|
|
|
+ return baseMapper.selectPhysicalJudgeList(lqw);
|
|
|
+ }
|
|
|
+
|
|
|
+ private LambdaQueryWrapper<PhysicalJudge> buildQueryWrapper(PhysicalJudgeBo bo) {
|
|
|
+ Map<String, Object> params = bo.getParams();
|
|
|
+ LambdaQueryWrapper<PhysicalJudge> lqw = Wrappers.lambdaQuery();
|
|
|
+ lqw.orderByAsc(PhysicalJudge::getId);
|
|
|
+ lqw.like(StringUtils.isNotBlank(bo.getName()), PhysicalJudge::getName, bo.getName());
|
|
|
+ lqw.eq(StringUtils.isNotBlank(bo.getPeopleIconUrl()), PhysicalJudge::getPeopleIconUrl, bo.getPeopleIconUrl());
|
|
|
+ lqw.eq(bo.getWorkYears() != null, PhysicalJudge::getWorkYears, bo.getWorkYears());
|
|
|
+ return lqw;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 新增裁判管理
|
|
|
+ *
|
|
|
+ * @param bo 裁判管理
|
|
|
+ * @return 是否新增成功
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean insertByBo(PhysicalJudgeBo bo) {
|
|
|
+ PhysicalJudge add = MapstructUtils.convert(bo, PhysicalJudge.class);
|
|
|
+ validEntityBeforeSave(add);
|
|
|
+ assert add != null;
|
|
|
+ add.setJudgeNumber(JudgeCodeGeneratorUtils.generateRandomCode());
|
|
|
+ boolean flag = baseMapper.insertPhysicalJudge(add) > 0;
|
|
|
+ if (flag) {
|
|
|
+ bo.setId(add.getId());
|
|
|
+ }
|
|
|
+ return flag;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 修改裁判管理
|
|
|
+ *
|
|
|
+ * @param bo 裁判管理
|
|
|
+ * @return 是否修改成功
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean updateByBo(PhysicalJudgeBo bo) {
|
|
|
+ PhysicalJudge update = MapstructUtils.convert(bo, PhysicalJudge.class);
|
|
|
+ validEntityBeforeSave(update);
|
|
|
+ return baseMapper.updatePhysicalJudgeById(update) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存前的数据校验
|
|
|
+ */
|
|
|
+ private void validEntityBeforeSave(PhysicalJudge entity){
|
|
|
+ //TODO 做一些数据校验,如唯一约束
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验并批量删除裁判管理信息
|
|
|
+ *
|
|
|
+ * @param ids 待删除的主键集合
|
|
|
+ * @param isValid 是否进行有效性校验
|
|
|
+ * @return 是否删除成功
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
|
|
|
+ if(isValid){
|
|
|
+ //TODO 做一些业务上的校验,判断是否需要校验
|
|
|
+ }
|
|
|
+ return baseMapper.deletePhysicalJudge(ids) > 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 导出裁判信息
|
|
|
+ *
|
|
|
+ * @param file 上传的文件
|
|
|
+ * @return 返回结果
|
|
|
+ */
|
|
|
+ @Override
|
|
|
+ public R<Boolean> exportJudge(MultipartFile file) {
|
|
|
+ // 1. 验证文件是否为空
|
|
|
+ if (file == null || file.isEmpty()) {
|
|
|
+ return R.fail("文件不能为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 验证文件类型
|
|
|
+ String contentType = file.getContentType();
|
|
|
+ if (!contentType.startsWith("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet") &&
|
|
|
+ !contentType.startsWith("application/vnd.ms-excel")) {
|
|
|
+ return R.fail("文件格式不正确,请上传Excel文件");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 3. 解析 Excel 文件
|
|
|
+ List<PhysicalJudgeImportVo> dataList;
|
|
|
+ try (InputStream inputStream = file.getInputStream()) {
|
|
|
+ dataList = parseExcel(inputStream);
|
|
|
+ } catch (IOException e) {
|
|
|
+ log.error("读取文件失败", e);
|
|
|
+ return R.fail("读取文件失败:" + e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // 4. 验证解析后的数据
|
|
|
+ if (CollectionUtils.isEmpty(dataList)) {
|
|
|
+ return R.fail("导入数据为空");
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 批量插入数据,记录失败的条目
|
|
|
+ List<String> failedNames = new ArrayList<>();
|
|
|
+ int successCount = 0;
|
|
|
+
|
|
|
+ for (PhysicalJudgeImportVo physicalJudgeImportVo : dataList) {
|
|
|
+ // 验证单个数据项
|
|
|
+ if (StringUtils.isBlank(physicalJudgeImportVo.getName())) {
|
|
|
+ failedNames.add("姓名为空的记录");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (physicalJudgeImportVo.getWorkYears() == null || physicalJudgeImportVo.getWorkYears() < 0) {
|
|
|
+ failedNames.add("工作年限无效的记录");
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 插入数据
|
|
|
+ PhysicalJudge add = new PhysicalJudge();
|
|
|
+ add.setName(physicalJudgeImportVo.getName());
|
|
|
+ add.setWorkYears(physicalJudgeImportVo.getWorkYears());
|
|
|
+ add.setJudgeNumber(JudgeCodeGeneratorUtils.generateRandomCode());
|
|
|
+
|
|
|
+ try {
|
|
|
+ baseMapper.insertPhysicalJudge(add);
|
|
|
+ successCount++;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("插入裁判信息失败,姓名:{}", physicalJudgeImportVo.getName(), e);
|
|
|
+ failedNames.add("姓名为" + physicalJudgeImportVo.getName() + "的记录");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 6. 返回结果
|
|
|
+ if (failedNames.isEmpty()) {
|
|
|
+ return R.ok("成功导入" + successCount + "条记录");
|
|
|
+ } else {
|
|
|
+ return R.fail("部分记录导入失败:" + String.join(",", failedNames));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 解析 Excel 方法
|
|
|
+ private List<PhysicalJudgeImportVo> parseExcel(InputStream inputStream) {
|
|
|
+ List<PhysicalJudgeImportVo> list = new ArrayList<>();
|
|
|
+ EasyExcel.read(inputStream, PhysicalJudgeImportVo.class, new AnalysisEventListener<PhysicalJudgeImportVo>() {
|
|
|
+ @Override
|
|
|
+ public void invoke(PhysicalJudgeImportVo data, AnalysisContext context) {
|
|
|
+ list.add(data);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void doAfterAllAnalysed(AnalysisContext context) {
|
|
|
+ // 解析完成
|
|
|
+ }
|
|
|
+ }).sheet().doRead();
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|