Przeglądaj źródła

房间信息批量导入功能

bing 1 rok temu
rodzic
commit
65875d2cf2

+ 32 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/controller/PtRoomController.java

@@ -1,11 +1,19 @@
 package org.dromara.backstage.basics.controller;
 
+import java.util.ArrayList;
 import java.util.List;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.collection.CollectionUtil;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.apache.commons.collections4.CollectionUtils;
+import org.dromara.backstage.basics.domain.vo.PtRoomTempImportVo;
+import org.dromara.backstage.basics.listener.PtRoomImportListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -21,6 +29,7 @@ import org.dromara.backstage.basics.domain.vo.PtRoomVo;
 import org.dromara.backstage.basics.domain.bo.PtRoomBo;
 import org.dromara.backstage.basics.service.IPtRoomService;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 房间定义
@@ -57,6 +66,29 @@ public class PtRoomController extends BaseController {
         ExcelUtil.exportExcel(list, "房间定义", PtRoomVo.class, response);
     }
 
+    /**
+     * 导出房间定义的导入模板
+     */
+    @SaCheckPermission("room:ptRoom:export")
+    @Log(title = "房间定义的导入模板", businessType = BusinessType.EXPORT)
+    @PostMapping("/exportTemplate")
+    public void exportTemplate(HttpServletResponse response) {
+        List<PtRoomTempImportVo> list = new ArrayList<>();
+        ExcelUtil.exportExcel(list, "房间信息导入模板", PtRoomTempImportVo.class, response);
+    }
+
+    /**
+     * 导出房间定义的导入模板
+     */
+    @SaCheckPermission("room:ptRoom:import")
+    @Log(title = "房间定义的导入模板", businessType = BusinessType.IMPORT)
+    @PostMapping(value="/importData",consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<Void> importData(@RequestPart("file") MultipartFile file, boolean updateSupport) throws Exception{
+        ExcelResult<PtRoomTempImportVo> rs = ExcelUtil.importExcel(file.getInputStream(), PtRoomTempImportVo.class, new PtRoomImportListener(updateSupport));
+        return R.ok(rs.getAnalysis());
+    }
+
+
     /**
      * 获取房间定义详细信息
      *

+ 105 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/domain/vo/PtRoomTempImportVo.java

@@ -0,0 +1,105 @@
+package org.dromara.backstage.basics.domain.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import jakarta.validation.constraints.NotBlank;
+import lombok.Data;
+import org.dromara.backstage.basics.domain.PtRoom;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 房间定义视图对象 t_pt_room
+ *
+ * @author bing
+ * @date 2024-08-09
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = PtRoom.class)
+public class PtRoomTempImportVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 房间Id,主键
+     */
+//    @ExcelProperty(value = "房间Id,主键")
+    private Long roomId;
+
+    /**
+     * 所属区域id
+     */
+//    @ExcelProperty(value = "所属区域id")
+    private Long areaId;
+
+    @ExcelProperty(value = "所属区域名称")
+    @NotBlank(message = "所属区域名称不能为空")
+    private String areaName;
+
+    @ExcelProperty(value = "所属区域编码")
+    @NotBlank(message = "所属区域编码不能为空")
+    private String areaCode;
+
+    /**
+     * 房间编码
+     */
+    @ExcelProperty(value = "房间编码")
+    @NotBlank(message = "房间编码不能为空")
+    private String roomCode;
+
+    /**
+     * 房间名称
+     */
+    @ExcelProperty(value = "房间名称")
+    @NotBlank(message = "房间名称不能为空")
+    private String roomName;
+
+    /**
+     * 房间类型,见FJLX字典类型
+     */
+    @ExcelProperty(value = "房间类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "FJLX")
+    private String roomType;
+
+    /**
+     * 门牌号1
+     */
+    @ExcelProperty(value = "门牌号1")
+    @NotBlank(message = "门牌号1不能为空")
+    private String codeOne;
+
+    /**
+     * 门牌号2
+     */
+//    @ExcelProperty(value = "门牌号2")
+    private String codeTwo;
+
+    /**
+     * 门牌号3
+     */
+//    @ExcelProperty(value = "门牌号3")
+    private String codeThree;
+
+    /**
+     * 门牌号4
+     */
+//    @ExcelProperty(value = "门牌号4")
+    private String codeFour;
+
+    /**
+     * 门牌号5
+     */
+//    @ExcelProperty(value = "门牌号5")
+    private String codeFive;
+
+
+
+
+}

+ 128 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/listener/PtRoomImportListener.java

@@ -0,0 +1,128 @@
+package org.dromara.backstage.basics.listener;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.excel.context.AnalysisContext;
+import com.alibaba.excel.event.AnalysisEventListener;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.backstage.basics.domain.bo.PtAreaBo;
+import org.dromara.backstage.basics.domain.bo.PtRoomBo;
+import org.dromara.backstage.basics.domain.vo.PtAreaVo;
+import org.dromara.backstage.basics.domain.vo.PtRoomTempImportVo;
+import org.dromara.backstage.basics.domain.vo.PtRoomVo;
+import org.dromara.backstage.basics.service.IPtAreaService;
+import org.dromara.backstage.basics.service.IPtRoomService;
+import org.dromara.common.core.exception.ServiceException;
+import org.dromara.common.core.utils.SpringUtils;
+import org.dromara.common.core.utils.ValidatorUtils;
+import org.dromara.common.excel.core.ExcelListener;
+import org.dromara.common.excel.core.ExcelResult;
+import org.dromara.common.satoken.utils.LoginHelper;
+
+import java.util.List;
+
+@Slf4j
+public class PtRoomImportListener extends AnalysisEventListener<PtRoomTempImportVo> implements ExcelListener<PtRoomTempImportVo> {
+
+    private final IPtRoomService ptRoomService;
+
+    private final IPtAreaService ptAreaService;
+
+    private final Boolean isUpdateSupport;
+
+    private final Long operUserId;
+
+    private int successNum = 0;
+    private int failureNum = 0;
+    private final StringBuilder successMsg = new StringBuilder();
+    private final StringBuilder failureMsg = new StringBuilder();
+
+    public PtRoomImportListener(Boolean isUpdateSupport) {
+        this.ptRoomService = SpringUtils.getBean(IPtRoomService.class);
+        this.ptAreaService = SpringUtils.getBean(IPtAreaService.class);
+        this.operUserId = LoginHelper.getUserId();
+        this.isUpdateSupport = isUpdateSupport;
+    }
+
+    @Override
+    public ExcelResult<PtRoomTempImportVo> getExcelResult() {
+        return new ExcelResult<>(){
+
+            @Override
+            public List<PtRoomTempImportVo> getList() {
+                return null;
+            }
+
+            @Override
+            public List<String> getErrorList() {
+                return null;
+            }
+
+            @Override
+            public String getAnalysis() {
+                if (failureNum > 0) {
+                    failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
+                    throw new ServiceException(failureMsg.toString());
+                } else {
+                    successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据如下:");
+                }
+                return successMsg.toString();
+            }
+        };
+    }
+
+    @Override
+    public void invoke(PtRoomTempImportVo ptRoomTempImportVo, AnalysisContext analysisContext) {
+        //1.查询区域是否存在
+        Integer rowIndex = analysisContext.readRowHolder().getRowIndex() + 1;
+        try{
+            //先验证数据
+            ValidatorUtils.validate(ptRoomTempImportVo);
+            PtAreaBo ptAreaBo = new PtAreaBo();
+            ptAreaBo.setAreaCode(ptRoomTempImportVo.getAreaCode());
+            ptAreaBo.setAreaName(ptRoomTempImportVo.getAreaName());
+            List<PtAreaVo> ptAreaVos = ptAreaService.queryList(ptAreaBo);
+            if (ptAreaVos.size() != 1) {
+                failureMsg.append("<br/>").append("第").append(rowIndex).append("行,区域不存在或存在多个;");
+                failureNum++;
+                return;
+            }
+            Long areaId = ptAreaVos.get(0).getAreaId();
+            ptRoomTempImportVo.setAreaId(areaId);
+            //2.查询房间是否存在
+            List<PtRoomVo> ptRoomVos =
+                ptRoomService.queryByNameOrCode(areaId, ptRoomTempImportVo.getRoomName(), ptRoomTempImportVo.getRoomCode());
+            if (CollectionUtil.isEmpty(ptRoomVos)) {
+                PtRoomBo ptRoomBo = BeanUtil.toBean(ptRoomTempImportVo, PtRoomBo.class);
+                ptRoomBo.setCreateBy(operUserId);
+
+                ptRoomService.insertByBo(ptRoomBo);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("、第 ").append(rowIndex).append("行,导入成功");
+            } else if (isUpdateSupport && ptRoomVos.size() == 1) {
+                PtRoomVo ptRoomVo = ptRoomVos.get(0);
+                PtRoomBo ptRoomBo = BeanUtil.toBean(ptRoomVo, PtRoomBo.class);
+                ptRoomBo.setCreateBy(operUserId);
+
+                ptRoomService.updateByBo(ptRoomBo);
+                successNum++;
+                successMsg.append("<br/>").append(successNum).append("、第 ").append(rowIndex).append("行,更新成功");
+
+            }else{
+                failureNum++;
+                failureMsg.append("<br/>").append(failureNum).append("、第 ").append(rowIndex).append("行,已存在;");
+            }
+
+        } catch (Exception e) {
+            failureNum++;
+            String msg = "<br/>" +"第 " + rowIndex + "行,导入失败:";
+            failureMsg.append(msg).append(e.getMessage());
+            log.error(msg, e);
+        }
+    }
+
+    @Override
+    public void doAfterAllAnalysed(AnalysisContext analysisContext) {
+
+    }
+}

+ 2 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/service/IPtRoomService.java

@@ -66,4 +66,6 @@ public interface IPtRoomService {
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    List<PtRoomVo> queryByNameOrCode(Long areaId, String roomName, String roomCode);
 }

+ 1 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/service/impl/PtAreaServiceImpl.java

@@ -97,6 +97,7 @@ public class PtAreaServiceImpl implements IPtAreaService {
         LambdaQueryWrapper<PtArea> lqw = Wrappers.lambdaQuery();
         lqw.like(StringUtils.isNotBlank(bo.getAreaName()), PtArea::getAreaName, bo.getAreaName());
         lqw.eq(StringUtils.isNotBlank(bo.getAreaType()), PtArea::getAreaType, bo.getAreaType());
+        lqw.eq(StringUtils.isNotBlank(bo.getAreaCode()), PtArea::getAreaCode, bo.getAreaCode());
         return lqw;
     }
 

+ 15 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/basics/service/impl/PtRoomServiceImpl.java

@@ -154,6 +154,21 @@ public class PtRoomServiceImpl implements IPtRoomService {
         return baseMapper.updateById(update) > 0;
     }
 
+    /**
+     * 根据条件查询区域下的房间
+     * @param areaId 区域
+     * @param roomName
+     * @param roomCode
+     * @return
+     */
+    public List<PtRoomVo> queryByNameOrCode(Long areaId, String roomName, String roomCode){
+        return baseMapper.selectVoList(Wrappers.<PtRoom>lambdaQuery()
+            .eq(PtRoom::getAreaId, areaId)
+            .and(
+                queryWrapper -> queryWrapper.eq(PtRoom::getRoomName, roomName).or().eq(PtRoom::getRoomCode, roomCode)
+            ));
+    }
+
     /**
      * 保存前的数据校验
      */