diff --git a/src/main/java/com/cm/systemcity/controller/apis/buildinghouse/BuildingHouseController.java b/src/main/java/com/cm/systemcity/controller/apis/buildinghouse/BuildingHouseController.java index 7362702..3f655c7 100644 --- a/src/main/java/com/cm/systemcity/controller/apis/buildinghouse/BuildingHouseController.java +++ b/src/main/java/com/cm/systemcity/controller/apis/buildinghouse/BuildingHouseController.java @@ -1,5 +1,9 @@ package com.cm.systemcity.controller.apis.buildinghouse; +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.ExcelReader; +import com.alibaba.excel.read.builder.ExcelReaderBuilder; +import com.alibaba.excel.read.metadata.ReadSheet; import com.cm.common.annotation.CheckRequestBodyAnnotation; import com.cm.common.base.AbstractController; import com.cm.common.constants.ISystemConstant; @@ -8,13 +12,24 @@ import com.cm.common.result.ErrorResult; import com.cm.common.result.SuccessResult; import com.cm.common.result.SuccessResultData; import com.cm.common.result.SuccessResultList; +import com.cm.systemcity.listener.ImportExcelListener; import com.cm.systemcity.pojo.dtos.buildinghouse.BuildingHouseDTO; +import com.cm.systemcity.pojo.dtos.excel.ImportFailDto; +import com.cm.systemcity.pojo.model.buildinghouse.BuildingHouseModel; import com.cm.systemcity.pojo.vos.buildinghouse.BuildingHouseVO; import com.cm.systemcity.service.buildinghouse.IBuildingHouseService; +import com.cm.systemcity.service.handleimportexcel.IHandleImportExcelService; +import com.cm.systemcity.utils.ExcelUtil; import io.swagger.annotations.*; +import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.net.URLEncoder; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; @@ -33,6 +48,9 @@ public class BuildingHouseController extends AbstractController { @Autowired private IBuildingHouseService buildingHouseService; + @Autowired + private IHandleImportExcelService handleImportExcelService; + private List failDtoList; @ApiOperation(value = "新增房屋管理表", notes = "新增房屋管理表接口") @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) @@ -108,4 +126,108 @@ public class BuildingHouseController extends AbstractController { return new SuccessResultData<>(buildingHouseService.count(params)); } + @ApiOperation(value = "导入房屋信息", notes = "导入房屋信息接口") + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @PostMapping("importexcel") + public SuccessResultData importExcel(@RequestParam("file") MultipartFile file, HttpServletResponse response) throws Exception { + ImportExcelListener listener = new ImportExcelListener(handleImportExcelService, BuildingHouseModel.class); + File newFile = multipartFileToFile(file); + ExcelReaderBuilder excelReaderBuilder = EasyExcel.read(newFile); + ExcelReader excelReader = excelReaderBuilder.build(); + List sheets = excelReader.excelExecutor().sheetList(); + for (ReadSheet sheet : sheets) { + // 读取数据 + ExcelUtil.readExcel(file, sheet.getSheetNo(), 1, listener, BuildingHouseModel.class); + } + newFile.delete(); + + // 错误集 + List importFailDtoList = listener.getImportFailDtoList(); + if(!importFailDtoList.isEmpty()) { + failDtoList = importFailDtoList; + return new SuccessResultData(importFailDtoList.size()); + } + return new SuccessResultData("success"); + } + + /** + * 导出失败数据 + * @param response + * + */ + @ApiOperation(value = "导出房屋信息失败信息", notes = "导出房屋信息失败接口") + @ApiResponses({@ApiResponse(code = 400, message = "请求失败", response = ErrorResult.class)}) + @GetMapping("exportexcel") + public void exportExcel(HttpServletResponse response) throws IOException { + String excelName = "出租房失败数据"; + String fileName = URLEncoder.encode(excelName, "UTF-8"); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + + String [] headers = {"序号", "小区名称(必填)", "楼宇名称", "房屋编号(必填)", "房屋状态(必填)", "房主姓名(必填)", "房主身份证号(必填)", "房主联系方式(必填)", "住户身份证号(多个用逗号隔开)"}; + List> listHeader = new ArrayList<>(); + for(String item : headers) { + List title = new ArrayList<>(); + title.add(item); + listHeader.add(title); + } + + List> listData = new ArrayList<>(); + int i = 0; + for (ImportFailDto dto : failDtoList) { + i++; + List data = new ArrayList<>(); + BuildingHouseModel buildingHouseModel = new BuildingHouseModel(); + BeanUtils.copyProperties(dto.getObject(), buildingHouseModel); + data.add(i); + data.add(buildingHouseModel.getCityBuildingName()); + data.add(buildingHouseModel.getDistrictName()); + data.add(buildingHouseModel.getHouseNumber()); + data.add(buildingHouseModel.getHouseStatus()); + data.add(buildingHouseModel.getOwnerName()); + data.add(buildingHouseModel.getOwnerCard()); + data.add(buildingHouseModel.getOwnerPhone()); + data.add(buildingHouseModel.getCardNumbers()); + data.add(dto.getErrMsg()); + listData.add(data); + } + EasyExcel.write(response.getOutputStream()).sheet("房屋信息导出失败数据").head(listHeader).doWrite(listData); + } + + /** + * MultipartFile 转 File + * + * @param file + * @throws Exception + */ + public File multipartFileToFile(MultipartFile file) throws Exception { + + File toFile = null; + if (file.equals("") || file.getSize() <= 0) { + file = null; + } else { + InputStream ins = null; + ins = file.getInputStream(); + toFile = new File(file.getOriginalFilename()); + inputStreamToFile(ins, toFile); + ins.close(); + } + return toFile; + } + + //获取流文件 + private void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } \ No newline at end of file diff --git a/src/main/java/com/cm/systemcity/listener/ImportExcelListener.java b/src/main/java/com/cm/systemcity/listener/ImportExcelListener.java new file mode 100644 index 0000000..2a235c9 --- /dev/null +++ b/src/main/java/com/cm/systemcity/listener/ImportExcelListener.java @@ -0,0 +1,231 @@ +package com.cm.systemcity.listener; + +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.context.AnalysisContext; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.exception.ExcelAnalysisException; +import com.cm.systemcity.pojo.dtos.excel.ImportFailDto; +import com.cm.systemcity.pojo.dtos.excel.ImportSuccessDto; +import com.cm.systemcity.pojo.model.buildinghouse.BuildingHouseModel; +import com.cm.systemcity.service.handleimportexcel.IHandleImportExcelService; +import com.cm.systemcity.utils.ImportExcelHelper; + +import java.lang.reflect.Field; +import java.util.*; +import java.util.stream.Collectors; + +/** + * 导入excel的监听处理类 + * @author renpc + */ +public class ImportExcelListener extends AnalysisEventListener{ + + private static final int BATCH_COUNT = 1000; + + /** + * 导入成功的数据 + */ + private List importSuccessDtoList = new ArrayList<>(); + /** + * 导入失败的数据 + */ + private List importFailDtoList = new ArrayList<>(); + + /** + * 保存数据库专用list + */ + private List list = new ArrayList<>(); + + /** + * 去重专用list + */ + private List listForDistinct = new ArrayList<>(); + + /** + * 处理导入数据的逻辑 + */ + private IHandleImportExcelService handleImportExcelService; + + private Class tClass; + + public List getImportSuccessDtoList() { + return importSuccessDtoList; + } + + public void setImportSuccessDtoList(List importSuccessDtoList) { + this.importSuccessDtoList = importSuccessDtoList; + } + + public List getImportFailDtoList() { + return importFailDtoList; + } + + public void setImportFailDtoList(List importFailDtoList) { + this.importFailDtoList = importFailDtoList; + } + + public List getList() { + return list; + } + + public void setList(List list) { + this.list = list; + } + + public IHandleImportExcelService getHandleImportExcelService() { + return handleImportExcelService; + } + + public void setHandleImportExcelService(IHandleImportExcelService handleImportExcelService) { + this.handleImportExcelService = handleImportExcelService; + } + + public Class gettClass() { + return tClass; + } + + public void settClass(Class tClass) { + this.tClass = tClass; + } + + public ImportExcelListener(IHandleImportExcelService handleImportExcelService) { + this.handleImportExcelService = handleImportExcelService; + } + + public ImportExcelListener(IHandleImportExcelService handleImportExcelService, Class tClass) { + this.handleImportExcelService = handleImportExcelService; + this.tClass = tClass; + } + + /** + * 导入数据的处理逻辑 + * @param t + * @param analysisContext + */ + @Override + public void invoke(T t, AnalysisContext analysisContext) { + // 错误提示 + String msg = ""; + try { + msg = ImportExcelHelper.checkDataValid(t); + }catch (Exception e){ + msg = "存在空数据"; + e.printStackTrace(); + } + + // 如果校验失败 + if(msg.length() != 0){ + ImportFailDto importFailDto = new ImportFailDto(t, msg); + importFailDtoList.add(importFailDto); + }else{ + ImportExcelHelper.checkDataFromDatabase(t); + list.add(t); + listForDistinct.add(t); + } + + if(list.size() > BATCH_COUNT){ + try { + insertData(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 所有数据处理完之后的处理方法 + * @param analysisContext + */ + @Override + public void doAfterAllAnalysed(AnalysisContext analysisContext) { + // PS:之所以最后这里还进行处理是防止最后一次的数据量没有达到批量值 + if(list.size() > 0) { + try { + insertData(); + } catch (NoSuchMethodException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + /** + * 校验导入的表格的头是否匹配 + * @param headMap + * @param analysisContext + */ + @Override + public void invokeHeadMap(Map headMap, AnalysisContext analysisContext){ + super.invokeHeadMap(headMap, analysisContext); + if(tClass != null){ + try { + // 获取Excel导入实体的单元格内容 + Map indexNameMap = getIndexName(tClass); + Set keySet = indexNameMap.keySet(); + for (Integer key: keySet) { + // 头表是否存在空值 + if(headMap.get(key).length() == 0){ + throw new ExcelAnalysisException("Excel格式非法"); + } + // 对比导入Excel实体模板和当前上传Excel是否匹配 + /*if(!headMap.get(key).equals(indexNameMap.get(key))){ + throw new ExcelAnalysisException("Excel格式非法"); + }*/ + } + }catch (Exception e){ + e.printStackTrace(); + } + } + } + + private Map getIndexName(Class tClass) throws NoSuchFieldException { + Map result = new HashMap<>(); + Field[] declaredFields = tClass.getDeclaredFields(); + for (Field currentField: declaredFields) { + currentField.setAccessible(true); + ExcelProperty annotation = currentField.getAnnotation(ExcelProperty.class); + if(annotation != null){ + int index =annotation.index(); + String[] value = annotation.value(); + StringBuilder sb = new StringBuilder(); + for (String cur : value) { + sb.append(cur); + } + result.put(index, sb.toString()); + } + } + return result; + } + + /** + * 将数据插入数据库操作 + */ + private void insertData() throws Exception { + String value = ""; + // 房屋信息 + if(list.get(0) instanceof BuildingHouseModel) { + List buildingHouseModelList = (List) list; + /*// 用来临时储存数据 + List houseNumber = new ArrayList<>(); + // 过滤去重 + List buildingHouseModelList1 = buildingHouseModelList.stream().filter( + v -> { + boolean flag = !houseNumber.contains(v.getHouseNumber()); + houseNumber.add(v.getHouseNumber()); + if(!flag) { + String msg = "房屋编号重复"; + ImportFailDto importFailDto = new ImportFailDto(v, msg); + importFailDtoList.add(importFailDto); + } + return flag; + } + ).collect(Collectors.toList());*/ + handleImportExcelService.saveBuildingHouse(buildingHouseModelList, importFailDtoList); + } + listForDistinct.clear(); + list.clear(); + } + + +} \ No newline at end of file diff --git a/src/main/java/com/cm/systemcity/pojo/dtos/buildinghouseuser/BuildingHouseUserDTO.java b/src/main/java/com/cm/systemcity/pojo/dtos/buildinghouseuser/BuildingHouseUserDTO.java index a2b683a..896a422 100644 --- a/src/main/java/com/cm/systemcity/pojo/dtos/buildinghouseuser/BuildingHouseUserDTO.java +++ b/src/main/java/com/cm/systemcity/pojo/dtos/buildinghouseuser/BuildingHouseUserDTO.java @@ -30,6 +30,8 @@ public class BuildingHouseUserDTO { private String phone; @ApiModelProperty(name = "buildingHouseId", value = "房屋ID") private String buildingHouseId; + @ApiModelProperty(name = "userType", value = "人员类型") + private String userType; public String getBuildingHouseUserId() { return buildingHouseUserId == null ? "" : buildingHouseUserId.trim(); @@ -95,4 +97,11 @@ public class BuildingHouseUserDTO { this.buildingHouseId = buildingHouseId; } + public String getUserType() { + return userType; + } + + public void setUserType(String userType) { + this.userType = userType; + } } diff --git a/src/main/java/com/cm/systemcity/pojo/dtos/excel/ExcelDTO.java b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ExcelDTO.java new file mode 100644 index 0000000..5d0a2e7 --- /dev/null +++ b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ExcelDTO.java @@ -0,0 +1,57 @@ +package com.cm.systemcity.pojo.dtos.excel; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; + +/** + * + * @ClassName: ExcelDTO + * @Description: 导入excel相关DTO + * @Author: renpc + * @Date: 2021-02-28 15:38 + * @Version: 1.0 + **/ +@ApiModel +public class ExcelDTO { + + @ApiModelProperty(name = "dictId", value = "字典表ID") + private String dictId; + @ApiModelProperty(name = "dictName", value = "字典表名称") + private String dictName; + @ApiModelProperty(name = "areaId", value = "区域表ID") + private String areaId; + @ApiModelProperty(name = "areaName", value = "字典表名称") + private String areaName; + + public String getDictId() { + return dictId == null ? "" : dictId; + } + + public void setDictId(String dictId) { + this.dictId = dictId; + } + + public String getDictName() { + return dictName == null ? "" : dictName; + } + + public void setDictName(String dictName) { + this.dictName = dictName; + } + + public String getAreaId() { + return areaId == null ? "" : areaId; + } + + public void setAreaId(String areaId) { + this.areaId = areaId; + } + + public String getAreaName() { + return areaName == null ? "" : areaName; + } + + public void setAreaName(String areaName) { + this.areaName = areaName; + } +} diff --git a/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportFailDto.java b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportFailDto.java new file mode 100644 index 0000000..e15e92c --- /dev/null +++ b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportFailDto.java @@ -0,0 +1,40 @@ +package com.cm.systemcity.pojo.dtos.excel; + +import java.io.Serializable; + +/** + * 批量导入失败实体类 + * @author renpc + */ +public class ImportFailDto implements Serializable { + + /** + *导入实体信息 + */ + private Object object; + /** + * 导入错误提示 + */ + private String errMsg; + + public ImportFailDto(Object object, String errMsg) { + this.object = object; + this.errMsg = errMsg; + } + + public Object getObject() { + return object; + } + + public void setObject(Object object) { + this.object = object; + } + + public String getErrMsg() { + return errMsg == null ? "" : errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } +} diff --git a/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportResultDto.java b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportResultDto.java new file mode 100644 index 0000000..78ab6d7 --- /dev/null +++ b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportResultDto.java @@ -0,0 +1,53 @@ +package com.cm.systemcity.pojo.dtos.excel; + +import java.util.ArrayList; +import java.util.List; + +/** + * 批量导入结果实体类 + * @author renpc + */ +public class ImportResultDto { + + /** + * 导入成功的消息列表 + */ + private List successDtoList; + + /** + * 导入失败的消息列表 + */ + private List failDtoList; + + public ImportResultDto(List successDtoList, List failDtoList) { + this.successDtoList = successDtoList; + this.failDtoList = failDtoList; + } + + public ImportResultDto(List failDtoList) { + this.failDtoList = failDtoList; + this.successDtoList = new ArrayList<>(); + } + + public List getSuccessDtoList() { + if (successDtoList == null) { + return new ArrayList<>(); + } + return successDtoList; + } + + public void setSuccessDtoList(List successDtoList) { + this.successDtoList = successDtoList; + } + + public List getFailDtoList() { + if (failDtoList == null) { + return new ArrayList<>(); + } + return failDtoList; + } + + public void setFailDtoList(List failDtoList) { + this.failDtoList = failDtoList; + } +} diff --git a/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportSuccessDto.java b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportSuccessDto.java new file mode 100644 index 0000000..8dc5279 --- /dev/null +++ b/src/main/java/com/cm/systemcity/pojo/dtos/excel/ImportSuccessDto.java @@ -0,0 +1,17 @@ +package com.cm.systemcity.pojo.dtos.excel; + +import java.io.Serializable; + +/** + * 批量导入成功实体类 + * @author renpc + */ +public class ImportSuccessDto implements Serializable { + + private Object object; + + public ImportSuccessDto(Object object) { + this.object = object; + } + +} diff --git a/src/main/java/com/cm/systemcity/pojo/model/buildinghouse/BuildingHouseModel.java b/src/main/java/com/cm/systemcity/pojo/model/buildinghouse/BuildingHouseModel.java new file mode 100644 index 0000000..6d3ce4d --- /dev/null +++ b/src/main/java/com/cm/systemcity/pojo/model/buildinghouse/BuildingHouseModel.java @@ -0,0 +1,121 @@ +package com.cm.systemcity.pojo.model.buildinghouse; + +import com.alibaba.excel.annotation.ExcelProperty; +import io.swagger.annotations.ApiModel; + +/** + * @author 29492 + */ +@ApiModel +public class BuildingHouseModel { + + @ExcelProperty(index = 0) + private String index; + @ExcelProperty(index = 1) + private String districtName; + @ExcelProperty(index = 2) + private String cityBuildingName; + @ExcelProperty(index = 3) + private String houseNumber; + @ExcelProperty(index = 4) + private String houseStatus; + @ExcelProperty(index = 5) + private String ownerName; + @ExcelProperty(index = 6) + private String ownerCard; + @ExcelProperty(index = 7) + private String ownerPhone; + @ExcelProperty(index = 8) + private String cardNumbers; + + private String districtId; + private String cityBuildingId; + + public String getIndex() { + return index; + } + + public void setIndex(String index) { + this.index = index; + } + + public String getDistrictName() { + return districtName; + } + + public void setDistrictName(String districtName) { + this.districtName = districtName; + } + + public String getCityBuildingName() { + return cityBuildingName; + } + + public void setCityBuildingName(String cityBuildingName) { + this.cityBuildingName = cityBuildingName; + } + + public String getHouseNumber() { + return houseNumber; + } + + public void setHouseNumber(String houseNumber) { + this.houseNumber = houseNumber; + } + + public String getHouseStatus() { + return houseStatus; + } + + public void setHouseStatus(String houseStatus) { + this.houseStatus = houseStatus; + } + + public String getOwnerName() { + return ownerName; + } + + public void setOwnerName(String ownerName) { + this.ownerName = ownerName; + } + + public String getOwnerCard() { + return ownerCard; + } + + public void setOwnerCard(String ownerCard) { + this.ownerCard = ownerCard; + } + + public String getOwnerPhone() { + return ownerPhone; + } + + public void setOwnerPhone(String ownerPhone) { + this.ownerPhone = ownerPhone; + } + + public String getCardNumbers() { + return cardNumbers; + } + + public void setCardNumbers(String cardNumbers) { + this.cardNumbers = cardNumbers; + } + + public String getDistrictId() { + return districtId; + } + + public void setDistrictId(String districtId) { + this.districtId = districtId; + } + + public String getCityBuildingId() { + return cityBuildingId; + } + + public void setCityBuildingId(String cityBuildingId) { + this.cityBuildingId = cityBuildingId; + } +} diff --git a/src/main/java/com/cm/systemcity/pojo/vos/buildinghouseuser/BuildingHouseUserVO.java b/src/main/java/com/cm/systemcity/pojo/vos/buildinghouseuser/BuildingHouseUserVO.java index 850f3f7..2427a10 100644 --- a/src/main/java/com/cm/systemcity/pojo/vos/buildinghouseuser/BuildingHouseUserVO.java +++ b/src/main/java/com/cm/systemcity/pojo/vos/buildinghouseuser/BuildingHouseUserVO.java @@ -28,6 +28,8 @@ public class BuildingHouseUserVO { private String phone; @ApiModelProperty(name = "buildingHouseId", value = "房屋ID") private String buildingHouseId; + @ApiModelProperty(name = "userType", value = "人员类型") + private String userType; public String getCardType() { return cardType == null ? "" : cardType.trim(); @@ -85,5 +87,11 @@ public class BuildingHouseUserVO { this.buildingHouseId = buildingHouseId; } + public String getUserType() { + return userType; + } + public void setUserType(String userType) { + this.userType = userType; + } } diff --git a/src/main/java/com/cm/systemcity/service/handleimportexcel/IHandleImportExcelService.java b/src/main/java/com/cm/systemcity/service/handleimportexcel/IHandleImportExcelService.java new file mode 100644 index 0000000..61d3fdc --- /dev/null +++ b/src/main/java/com/cm/systemcity/service/handleimportexcel/IHandleImportExcelService.java @@ -0,0 +1,46 @@ +package com.cm.systemcity.service.handleimportexcel; + +import com.cm.systemcity.pojo.dtos.excel.ImportFailDto; +import com.cm.systemcity.pojo.dtos.excel.ImportResultDto; +import com.cm.systemcity.pojo.model.buildinghouse.BuildingHouseModel; + +import java.util.List; +import java.util.Map; + +/** + * @ClassName: IHandleImportExcelService + * @Description: 导入excel service + * @Author: renpc + * @Date: 2021-02-27 14:40 + * @Version: 1.0 + **/ +public interface IHandleImportExcelService { + + /** + * 数据校验 + * + * @param list + * @return + * @throws Exception + */ + public ImportResultDto checkImportData(List list); + + /** + * 字段比对数据库(字典) + * @param params + */ + public void checkDataFromDict(Map params); + + /** + * 字段比对数据库(区域) + * @param params + */ + public void checkDataFromArea(Map params); + + /** + * 批量保存房屋信息 + * @param buildingHouseModelList + * @param importFailDtoList + */ + void saveBuildingHouse(List buildingHouseModelList, List importFailDtoList) throws Exception; +} diff --git a/src/main/java/com/cm/systemcity/service/handleimportexcel/impl/HandleImportExcelServiceImpl.java b/src/main/java/com/cm/systemcity/service/handleimportexcel/impl/HandleImportExcelServiceImpl.java new file mode 100644 index 0000000..544aab6 --- /dev/null +++ b/src/main/java/com/cm/systemcity/service/handleimportexcel/impl/HandleImportExcelServiceImpl.java @@ -0,0 +1,214 @@ +package com.cm.systemcity.service.handleimportexcel.impl; + +import com.alibaba.excel.util.StringUtils; +import com.alibaba.fastjson.JSONObject; +import com.cm.common.base.AbstractService; +import com.cm.common.plugin.oauth.token.ClientTokenManager; +import com.cm.common.plugin.pojo.bos.ClientTokenBO; +import com.cm.common.result.SuccessResultData; +import com.cm.systemcity.config.properties.ProjectProperties; +import com.cm.systemcity.dao.buildinghouse.IBuildingHouseDao; +import com.cm.systemcity.pojo.dtos.buildinghouse.BuildingHouseDTO; +import com.cm.systemcity.pojo.dtos.buildinghouseuser.BuildingHouseUserDTO; +import com.cm.systemcity.pojo.dtos.excel.ImportFailDto; +import com.cm.systemcity.pojo.dtos.excel.ImportResultDto; +import com.cm.systemcity.pojo.model.buildinghouse.BuildingHouseModel; +import com.cm.systemcity.pojo.vos.buildinghouse.BuildingHouseVO; +import com.cm.systemcity.pojo.vos.buildinghouseuser.BuildingHouseUserVO; +import com.cm.systemcity.service.buildinghouse.IBuildingHouseService; +import com.cm.systemcity.service.buildinghouseuser.IBuildingHouseUserService; +import com.cm.systemcity.service.handleimportexcel.IHandleImportExcelService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpMethod; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.client.RestTemplate; +import org.springframework.web.util.UriComponentsBuilder; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * @ClassName: HandleImportExcelServiceImpl + * @Description: 导入excel service + * @Author: renpc + * @Date: 2021-02-27 14:40 + * @Version: 1.0 + **/ +@Service +public class HandleImportExcelServiceImpl extends AbstractService implements IHandleImportExcelService { + + @Autowired + private IBuildingHouseDao buildingHouseDao; + @Autowired + private IBuildingHouseService buildingHouseService; + @Autowired + private IBuildingHouseUserService buildingHouseUserService; + @Autowired + private ProjectProperties projectProperties; + + @Override + public ImportResultDto checkImportData(List list) { + return new ImportResultDto(null); + } + + @Override + public void checkDataFromDict(Map params) { + + } + + @Override + public void checkDataFromArea(Map params) { + + } + + @Override + public void saveBuildingHouse(List buildingHouseModelList, List importFailDtoList) throws Exception { + if(null != buildingHouseModelList && buildingHouseModelList.size() > 0) { + Map params = new HashMap<>(); + for(BuildingHouseModel buildingHouseModel: buildingHouseModelList) { + params.put("houseNumber", buildingHouseModel.getHouseNumber()); + params.put("districtName", buildingHouseModel.getDistrictName()); + BuildingHouseDTO buildinghouseDTO = buildingHouseDao.get(params); + params = new HashMap<>(); + if(null != buildinghouseDTO) { + /*params.put("cityBuildingId",buildingHouseModel.getCityBuildingId()); + params.put("cityBuildingName",buildingHouseModel.getCityBuildingName()); + params.put("houseNumber",buildingHouseModel.getHouseNumber()); + params.put("districtName",buildingHouseModel.getDistrictName()); + params.put("districtId",buildingHouseModel.getDistrictId()); + params.put("houseStatus",buildingHouseModel.getHouseStatus()); + params.put("dataType",3); + params.put("ownerName",buildingHouseModel.getOwnerName()); + params.put("ownerCard",buildingHouseModel.getOwnerCard()); + params.put("ownerPhone",buildingHouseModel.getOwnerPhone()); + buildingHouseDao.update(params);*/ + saveHouseUser(buildingHouseModel, buildinghouseDTO.getBuildingHouseId()); + }else { + BuildingHouseVO buildingHouseVO = new BuildingHouseVO(); + buildingHouseVO.setCityBuildingId(buildingHouseModel.getCityBuildingId()); + buildingHouseVO.setCityBuildingName(buildingHouseModel.getCityBuildingName()); + buildingHouseVO.setHouseNumber(buildingHouseModel.getHouseNumber()); + buildingHouseVO.setHouseStatus(buildingHouseModel.getHouseStatus()); + buildingHouseVO.setDistrictId(buildingHouseModel.getDistrictId()); + buildingHouseVO.setDistrictName(buildingHouseModel.getDistrictName()); + buildingHouseVO.setDataType(3); + buildingHouseVO.setOwnerName(buildingHouseModel.getOwnerName()); + buildingHouseVO.setOwnerCard(buildingHouseModel.getOwnerCard()); + buildingHouseVO.setOwnerPhone(buildingHouseModel.getOwnerPhone()); + String buildingHouseId = buildingHouseService.saveReturnId(buildingHouseVO); + saveHouseUser(buildingHouseModel, buildingHouseId); + } + } + } + } + + private void saveHouseUser(BuildingHouseModel buildingHouseModel, String buildingHouseId) throws Exception { + String userIds = buildingHouseModel.getCardNumbers(); + if(!StringUtils.isEmpty(userIds)) { + Map params = new HashMap<>(); + // 将所有的非英文半角逗号都转为英文半角 + userIds = userIds.replaceAll("\\n", ","); + userIds = userIds.replaceAll("\\r", ","); + userIds = userIds.replaceAll(" ", ","); + userIds = userIds.replaceAll(",", ","); + + userIds = userIds.replaceAll("[\\s]*[,][\\s]*[,]{1,}([\\s]+|[,]+)*", ","); + + String[] userIdArr = userIds.split(","); + for(String s: userIdArr) { + params.put("cardNumber", s); + params.put("buildingHouseId", buildingHouseId); + SuccessResultData> data = userMsg(s); + Map userParam = data.getData(); + if(null == userParam || userParam.isEmpty()) { + continue; + } + BuildingHouseUserVO buildingHouseUserVO = new BuildingHouseUserVO(); + buildingHouseUserVO.setBuildingHouseId(buildingHouseId); + buildingHouseUserVO.setCardNumber(s); + buildingHouseUserVO.setName(userParam.get("name") == null ? "" : userParam.get("name").toString()); + buildingHouseUserVO.setSex(userParam.get("sex") == null ? "" : userParam.get("sex").toString()); + buildingHouseUserVO.setPhone(userParam.get("phone") == null ? "" : userParam.get("phone").toString()); + List buildingHouseUserDTOList = buildingHouseUserService.list(params); + BuildingHouseUserDTO updateDto = null; + Boolean userDo = false; + if(null == buildingHouseUserDTOList) { + for(BuildingHouseUserDTO buildingHouseUserDTO: buildingHouseUserDTOList) { + if(buildingHouseUserDTO.getCardNumber().equals(s) || buildingHouseUserDTO.getName().equals(userParam.get("name"))) { + userDo = true; + updateDto = buildingHouseUserDTO; + } + } + } + if(userDo) { + buildingHouseUserService.update(updateDto.getBuildingHouseUserId(), buildingHouseUserVO); + }else { + buildingHouseUserService.save(buildingHouseUserVO); + } + } + } + + String ownerName = buildingHouseModel.getOwnerName(); + String ownerCard = buildingHouseModel.getOwnerCard(); + if(!StringUtils.isEmpty(ownerName)) { + saveUserMsg(buildingHouseId, buildingHouseModel); + }else { + if(!StringUtils.isEmpty(ownerCard)) { + saveUserMsg(buildingHouseId, buildingHouseModel); + } + } + } + + private void saveUserMsg(String buildingHouseId, BuildingHouseModel buildingHouseModel) throws Exception { + String ownerName = buildingHouseModel.getOwnerName(); + String ownerCard = buildingHouseModel.getOwnerCard(); + Map params = new HashMap<>(); + params.put("cardNumber", ownerCard); + params.put("buildingHouseId", buildingHouseId); + BuildingHouseUserVO buildingHouseUserVO = new BuildingHouseUserVO(); + buildingHouseUserVO.setBuildingHouseId(buildingHouseId); + buildingHouseUserVO.setName(ownerName); + buildingHouseUserVO.setCardNumber(ownerCard); + buildingHouseUserVO.setPhone(buildingHouseModel.getOwnerPhone()); + List buildingHouseUserDTOList = buildingHouseUserService.list(params); + BuildingHouseUserDTO updateDto = null; + Boolean userDo = false; + if(null == buildingHouseUserDTOList) { + for(BuildingHouseUserDTO buildingHouseUserDTO: buildingHouseUserDTOList) { + if(buildingHouseUserDTO.getCardNumber().equals(ownerCard) || buildingHouseUserDTO.getName().equals(ownerName)) { + userDo = true; + updateDto = buildingHouseUserDTO; + } + } + } + if(userDo) { + buildingHouseUserService.update(updateDto.getBuildingHouseUserId(), buildingHouseUserVO); + }else { + buildingHouseUserService.save(buildingHouseUserVO); + } + } + + private SuccessResultData> userMsg(String idCard) { + ClientTokenBO token = ClientTokenManager.getInstance().getClientToken(); + RestTemplate restTemplate = new RestTemplate(); + String url = projectProperties.getPopulationUrl(); + url += "/resource/personMsg/userMsg/" + idCard; + UriComponentsBuilder builder = UriComponentsBuilder.fromHttpUrl(url) + .queryParam("access_token", token.getAccessToken()); + ResponseEntity responseEntity = restTemplate.exchange(builder.build().encode().toUri(), HttpMethod.GET, null, String.class); + String str = responseEntity.getBody(); + if(org.springframework.util.StringUtils.isEmpty(str)) { + return new SuccessResultData<>(new HashMap<>()); + } + JSONObject jsonObject = null; + jsonObject = JSONObject.parseObject(str).getJSONObject("data"); + if(null == jsonObject || jsonObject.size() <= 0) { + return new SuccessResultData<>(new HashMap<>()); + } + return new SuccessResultData<>(jsonObject); + } + +} diff --git a/src/main/java/com/cm/systemcity/utils/ExcelUtil.java b/src/main/java/com/cm/systemcity/utils/ExcelUtil.java new file mode 100644 index 0000000..2cc4c48 --- /dev/null +++ b/src/main/java/com/cm/systemcity/utils/ExcelUtil.java @@ -0,0 +1,77 @@ +package com.cm.systemcity.utils; + +import com.alibaba.excel.EasyExcel; +import com.alibaba.excel.event.AnalysisEventListener; +import com.alibaba.excel.support.ExcelTypeEnum; +import org.springframework.util.StringUtils; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.InputStream; +import java.net.URLEncoder; +import java.util.List; + +/** + * excel工具类 + * @author renpc + */ +public class ExcelUtil { + + /** + * 默认excel文件名和单元sheet名一样的 Excel文件导出 + * @param httpServletResponse + * @param data + * @param fileName + * @param clazz + * @throws IOException + */ + public static void writeExcel(HttpServletResponse httpServletResponse, List data, String fileName, Class clazz) throws IOException { + writeExcel(httpServletResponse, data, fileName, fileName, clazz); + } + + /** + * 导出数据为Excel文件 + * @param response 响应实体 + * @param data 导出数据 + * @param fileName 文件名 + * @param sheetName 单元格名 + * @param clazz 定义excel导出的实体 + * @throws IOException + */ + public static void writeExcel(HttpServletResponse response, List data, String fileName, String sheetName, Class clazz) throws IOException { + //防止中文乱码 + fileName = URLEncoder.encode(fileName, "UTF-8"); + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding("utf-8"); + //防止导入excel文件名中文不乱码 + response.setHeader("Content-disposition", "attachment;fileName=" + fileName + ".xlsx" + ";fileName*=utf-8''" + fileName + ".xlsx"); + EasyExcel.write(response.getOutputStream(), clazz).sheet(sheetName).doWrite(data); + } + + /** + * easyExcel处理上传的文件 + * @param sheetNo 单元格 + * @param rowNumber 行数 + * @param analysisEventListener 上传处理监听 + * @param clazz 上传处理excel类 + * @return + * @throws Exception + */ + public static List readExcel(MultipartFile file, Integer sheetNo, Integer rowNumber, AnalysisEventListener analysisEventListener, Class clazz) throws Exception { + if(null != file) { + String originalFilename = file.getOriginalFilename(); + if(StringUtils.isEmpty(originalFilename)){ + throw new Exception("上传的文件不能为空"); + } + if(!originalFilename.toLowerCase().endsWith(ExcelTypeEnum.XLS.getValue()) && + !originalFilename.toLowerCase().endsWith(ExcelTypeEnum.XLSX.getValue())){ + throw new Exception("上传的文件格式不匹配"); + } + InputStream inputStream = file.getInputStream(); + return EasyExcel.read(inputStream, clazz, analysisEventListener).sheet(sheetNo).headRowNumber(rowNumber).doReadSync(); + } + throw new Exception("上传的文件不能为空"); + } + +} diff --git a/src/main/java/com/cm/systemcity/utils/ImportErrorData.java b/src/main/java/com/cm/systemcity/utils/ImportErrorData.java new file mode 100644 index 0000000..6beac78 --- /dev/null +++ b/src/main/java/com/cm/systemcity/utils/ImportErrorData.java @@ -0,0 +1,15 @@ +package com.cm.systemcity.utils; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author xwangs + * @create 2021-03-23 17:52 + * @description + */ +public class ImportErrorData { + + public static Map errorData = new HashMap<>(36); + +} diff --git a/src/main/java/com/cm/systemcity/utils/ImportExcelHelper.java b/src/main/java/com/cm/systemcity/utils/ImportExcelHelper.java new file mode 100644 index 0000000..493ad08 --- /dev/null +++ b/src/main/java/com/cm/systemcity/utils/ImportExcelHelper.java @@ -0,0 +1,133 @@ +package com.cm.systemcity.utils; + +import com.cm.systemcity.pojo.dtos.citybuilding.CityBuildingDTO; +import com.cm.systemcity.pojo.dtos.citydistrict.CityDistrictDTO; +import com.cm.systemcity.pojo.model.buildinghouse.BuildingHouseModel; +import com.cm.systemcity.service.citybuilding.ICityBuildingService; +import com.cm.systemcity.service.citydistrict.ICityDistrictService; +import com.cm.systemcity.service.handleimportexcel.IHandleImportExcelService; +import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.HashMap; +import java.util.Map; + +/** + * 导入excel数据的校验类 + * @author renpc + */ +@Component +public class ImportExcelHelper { + + @Autowired + private IHandleImportExcelService handleImportExcelService; + @Autowired + private static ICityDistrictService cityDistrictService; + @Autowired + private static ICityBuildingService cityBuildingService; + + @Autowired + public void init(ICityDistrictService cityDistrictService) { + ImportExcelHelper.cityDistrictService = cityDistrictService; + } + + @Autowired + public void init(ICityBuildingService cityBuildingService) { + ImportExcelHelper.cityBuildingService = cityBuildingService; + } + + public static String checkDataValid(T obj) { + if(null == obj) { + return null; + } + String returnStr = isMustInput(obj); + return returnStr; + } + + /** + * 检查数据是否必填项缺失 + * @param obj + * @param + * @return + */ + private static String isMustInput(T obj) { + // 房屋信息 + if(obj instanceof BuildingHouseModel) { + Object temp = obj; + BuildingHouseModel buildingHouseModel = (BuildingHouseModel) temp; + return checkBuildingHouseData(buildingHouseModel); + } + return ""; + } + + /** + * 检查数据是否必填项缺失(房屋管理) + * @param buildingHouseModel + * @return + */ + private static String checkBuildingHouseData(BuildingHouseModel buildingHouseModel) { + /*if(StringUtils.isEmpty(buildingHouseModel.getHouseNumber())) { + buildingHouseModel.setHouseNumber("" + Math.random() * 1000000); + // return "房屋编号必填"; + }*/ + if(StringUtils.isEmpty(buildingHouseModel.getDistrictName())) { + return "小区名称必填"; + } + if(StringUtils.isEmpty(buildingHouseModel.getHouseNumber())) { + return "房屋编号必填"; + } + /*if(StringUtils.isEmpty(buildingHouseModel.getHouseStatus())) { + return "房屋状态必填"; + } + if(StringUtils.isEmpty(buildingHouseModel.getOwnerName())) { + return "房主姓名必填"; + } + if(StringUtils.isEmpty(buildingHouseModel.getOwnerCard())) { + return "房主身份证号必填"; + } + if(StringUtils.isEmpty(buildingHouseModel.getOwnerPhone())) { + return "房主联系方式必填"; + }*/ + return ""; + } + + /** + * 从数据库比对数据,并转换为数据库数据 + * @param obj + * @param + */ + public static void checkDataFromDatabase(T obj) { + // 出租房 + if(obj instanceof BuildingHouseModel) { + Object temp = obj; + BuildingHouseModel buildingHouseModel = (BuildingHouseModel) temp; + buildingHouseCheck(buildingHouseModel); + temp = buildingHouseModel; + obj = (T) temp; + } + } + + /** + * 从数据库比对数据,并转换为数据库数据(房屋管理) + * @param buildingHouseModel + */ + private static void buildingHouseCheck(BuildingHouseModel buildingHouseModel) { + if(!StringUtils.isEmpty(buildingHouseModel.getOwnerCard())) { + if(buildingHouseModel.getOwnerCard().startsWith("'")) { + buildingHouseModel.setOwnerCard(buildingHouseModel.getOwnerCard().replaceAll("'", "")); + } + } + Map param = new HashMap<>(); + param.put("districtName", buildingHouseModel.getDistrictName()); + CityDistrictDTO cityDistrictDTO = cityDistrictService.getCityDistrictByName(buildingHouseModel.getDistrictName()); + if(null != cityDistrictDTO) { + buildingHouseModel.setDistrictId(cityDistrictDTO.getCityDistrictId()); + } + CityBuildingDTO cityBuildingDTO = cityBuildingService.getCityBuildingByName(buildingHouseModel.getCityBuildingName()); + if(null != cityBuildingDTO) { + buildingHouseModel.setCityBuildingId(cityBuildingDTO.getCityBuildingId()); + } + } + +} diff --git a/src/main/resources/mybatis/mapper/buildinghouse/building-house-mapper.xml b/src/main/resources/mybatis/mapper/buildinghouse/building-house-mapper.xml index 27680a7..52facb4 100644 --- a/src/main/resources/mybatis/mapper/buildinghouse/building-house-mapper.xml +++ b/src/main/resources/mybatis/mapper/buildinghouse/building-house-mapper.xml @@ -105,6 +105,9 @@ city_building_name = #{cityBuildingName}, + + city_building_id = #{cityBuildingId}, + house_number = #{houseNumber}, @@ -151,6 +154,9 @@ AND city_building_id = #{cityBuildingId} + + AND house_number = #{houseNumber} + @@ -174,9 +180,18 @@ WHERE t1.is_delete = 0 - AND - t1.building_house_id = #{buildingHouseId} + AND + t1.building_house_id = #{buildingHouseId} + + AND + t1.district_name = #{districtName} + + + AND + t1.house_number = #{houseNumber} + + LIMIT 0, 1 diff --git a/src/main/resources/mybatis/mapper/buildinghouseuser/building-house-user-mapper.xml b/src/main/resources/mybatis/mapper/buildinghouseuser/building-house-user-mapper.xml index 60833eb..f7c8251 100644 --- a/src/main/resources/mybatis/mapper/buildinghouseuser/building-house-user-mapper.xml +++ b/src/main/resources/mybatis/mapper/buildinghouseuser/building-house-user-mapper.xml @@ -11,30 +11,27 @@ - - - - - + - INSERT INTO city_building_house_user( + INSERT IGNORE INTO city_building_house_user ( building_house_user_id, card_type, card_type_name, card_number, - name, + NAME, sex, phone, building_house_id, + user_type, creator, gmt_create, modifier, gmt_modified, is_delete - ) VALUES( + ) SELECT #{buildingHouseUserId}, #{cardType}, #{cardTypeName}, @@ -43,12 +40,28 @@ #{sex}, #{phone}, #{buildingHouseId}, + #{userType}, #{creator}, #{gmtCreate}, #{modifier}, #{gmtModified}, #{isDelete} - ) + FROM + DUAL + WHERE + NOT EXISTS ( + SELECT + * + FROM + city_building_house_user + WHERE + is_delete = 0 + AND card_number = #{cardNumber} + + AND + building_house_id = #{buildingHouseId} + + ) @@ -100,8 +113,8 @@ phone = #{phone}, - - building_house_id = #{buildingHouseId}, + + user_type = #{userType}, gmt_modified = #{gmtModified}, modifier = #{modifier}, @@ -120,14 +133,23 @@ t1.sex, t1.phone, t1.building_house_id, + t1.user_type, t1.building_house_user_id FROM city_building_house_user t1 WHERE t1.is_delete = 0 - AND - t1.building_house_user_id = #{buildingHouseUserId} + AND + t1.building_house_user_id = #{buildingHouseUserId} + + + AND + t1.building_house_id = #{buildingHouseId} + + + AND + t1.card_number = #{cardNumber} @@ -141,6 +163,7 @@ t1.name, t1.sex, t1.phone, + t1.user_type, t1.building_house_id, 1 FROM @@ -156,6 +179,14 @@ AND t1.building_house_id = #{buildingHouseId} + + AND + t1.building_house_user_id = #{buildingHouseUserId} + + + AND + t1.card_number = #{cardNumber} + AND LEFT(t1.gmt_create, 10) = ]]> #{startTime} diff --git a/src/main/resources/static/route/buildinghouse/list.html b/src/main/resources/static/route/buildinghouse/list.html index 357e957..c49298a 100644 --- a/src/main/resources/static/route/buildinghouse/list.html +++ b/src/main/resources/static/route/buildinghouse/list.html @@ -29,6 +29,10 @@ + +
@@ -184,7 +188,7 @@ base: 'assets/layuiadmin/' }).extend({ index: 'lib/index' - }).use(['index', 'table', 'laydate', 'common'], function() { + }).use(['index', 'table', 'laydate', 'common','upload'], function() { var $ = layui.$; var $win = $(window); var table = layui.table; @@ -195,6 +199,41 @@ var resizeTimeout = null; var tableUrl = 'api/buildinghouse/listpage'; + // 导入功能 + function importExcel() { + var uploadLoading; + layui.upload.render({ + elem: '#importExcel' + ,url: 'api/buildinghouse/importexcel' + ,accept: 'file' + ,exts: 'xls|xlsx' + ,before: function() { + uploadLoading = layer.msg('正在上传,请稍后...', {icon: 16, time: 0, shade: 0.3}); + } + ,done: function(data) { + layer.close(uploadLoading); + if(data.data != 'success') { + layer.msg('导入成功,存在' + data.data + '条失败数据', {time: 2000}, function() { + window.open(top.restAjax.path('api/buildinghouse/exportexcel', [])); + }); + } else { + layer.msg('导入成功', {time: 2000}, function() { + closeBox(); + reloadTable(); + }); + } + } + ,error: function(data, index){ + layer.close(uploadLoading); + if(data != null) { + top.dialog.msg(data.msg); + } + }, + }); + } + + importExcel() + // 初始化表格 function initTable() { table.render({