|
|
@ -1,7 +1,11 @@ |
|
|
|
package com.epmet.service.impl; |
|
|
|
|
|
|
|
import cn.afterturn.easypoi.excel.ExcelExportUtil; |
|
|
|
import cn.afterturn.easypoi.excel.entity.ExportParams; |
|
|
|
import com.alibaba.excel.EasyExcel; |
|
|
|
import com.alibaba.excel.ExcelWriter; |
|
|
|
import com.alibaba.excel.annotation.ExcelProperty; |
|
|
|
import com.alibaba.excel.annotation.write.style.ColumnWidth; |
|
|
|
import com.alibaba.excel.write.metadata.WriteSheet; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
|
|
@ -9,41 +13,61 @@ import com.baomidou.mybatisplus.core.metadata.IPage; |
|
|
|
import com.epmet.commons.mybatis.service.impl.BaseServiceImpl; |
|
|
|
import com.epmet.commons.tools.constant.FieldConstant; |
|
|
|
import com.epmet.commons.tools.constant.ServiceConstant; |
|
|
|
import com.epmet.commons.tools.dto.result.OptionResultDTO; |
|
|
|
import com.epmet.commons.tools.exception.EpmetErrorCode; |
|
|
|
import com.epmet.commons.tools.exception.EpmetException; |
|
|
|
import com.epmet.commons.tools.exception.ExceptionUtils; |
|
|
|
import com.epmet.commons.tools.exception.ValidateException; |
|
|
|
import com.epmet.commons.tools.feign.ResultDataResolver; |
|
|
|
import com.epmet.commons.tools.page.PageData; |
|
|
|
import com.epmet.commons.tools.redis.common.CustomerOrgRedis; |
|
|
|
import com.epmet.commons.tools.utils.ConvertUtils; |
|
|
|
import com.epmet.commons.tools.utils.EpmetRequestHolder; |
|
|
|
import com.epmet.commons.tools.utils.ExcelUtils; |
|
|
|
import com.epmet.commons.tools.utils.SpringContextUtils; |
|
|
|
import com.epmet.commons.tools.security.user.LoginUserUtil; |
|
|
|
import com.epmet.commons.tools.utils.*; |
|
|
|
import com.epmet.commons.tools.validator.ValidatorUtils; |
|
|
|
import com.epmet.constants.ImportTaskConstants; |
|
|
|
import com.epmet.dao.WorkdiaryServiceRecordDao; |
|
|
|
import com.epmet.dao.WorkdiaryServiceTypeDao; |
|
|
|
import com.epmet.dto.IcResiUserDTO; |
|
|
|
import com.epmet.dto.WorkdiaryServiceTypeDTO; |
|
|
|
import com.epmet.dto.result.WorkdiaryServiceRecordDTO; |
|
|
|
import com.epmet.dto.*; |
|
|
|
import com.epmet.dto.form.GridOptionFormDTO; |
|
|
|
import com.epmet.dto.form.LoginUserDetailsFormDTO; |
|
|
|
import com.epmet.dto.form.resi.IcResiPageNonDynamicFormDTO; |
|
|
|
import com.epmet.dto.result.*; |
|
|
|
import com.epmet.dto.result.resi.IcResiNonDynamicResultDTO; |
|
|
|
import com.epmet.entity.WorkdiaryServiceRecordEntity; |
|
|
|
import com.epmet.excel.WorkdiaryServiceRecordExcel; |
|
|
|
import com.epmet.excel.listener.WorkdiaryServiceImportListener; |
|
|
|
import com.epmet.feign.EpmetUserOpenFeignClient; |
|
|
|
import com.epmet.feign.GovOrgOpenFeignClient; |
|
|
|
import com.epmet.feign.OssFeignClient; |
|
|
|
import com.epmet.redis.WorkdiaryServiceRecordRedis; |
|
|
|
import com.epmet.service.WorkdiaryServiceRecordService; |
|
|
|
import com.epmet.service.WorkdiaryServiceTypeService; |
|
|
|
import com.epmet.utils.ImportTaskUtils; |
|
|
|
import com.github.pagehelper.PageHelper; |
|
|
|
import com.github.pagehelper.PageInfo; |
|
|
|
import lombok.AllArgsConstructor; |
|
|
|
import lombok.Data; |
|
|
|
import lombok.NoArgsConstructor; |
|
|
|
import org.apache.commons.collections4.CollectionUtils; |
|
|
|
import org.apache.commons.fileupload.FileItem; |
|
|
|
import org.apache.commons.fileupload.disk.DiskFileItemFactory; |
|
|
|
import org.apache.commons.lang3.StringUtils; |
|
|
|
import org.apache.http.entity.ContentType; |
|
|
|
import org.apache.poi.ss.usermodel.Workbook; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
import org.springframework.transaction.annotation.Transactional; |
|
|
|
import org.springframework.web.multipart.commons.CommonsMultipartFile; |
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletResponse; |
|
|
|
import java.io.IOException; |
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import java.util.Optional; |
|
|
|
import java.io.OutputStream; |
|
|
|
import java.nio.file.Files; |
|
|
|
import java.nio.file.Path; |
|
|
|
import java.time.LocalDateTime; |
|
|
|
import java.time.format.DateTimeFormatter; |
|
|
|
import java.util.*; |
|
|
|
import java.util.function.Function; |
|
|
|
import java.util.stream.Collectors; |
|
|
|
|
|
|
|
/** |
|
|
@ -64,6 +88,34 @@ public class WorkdiaryServiceRecordServiceImpl extends BaseServiceImpl<Workdiary |
|
|
|
@Autowired |
|
|
|
private EpmetUserOpenFeignClient userOpenFeignClient; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private GovOrgOpenFeignClient govOrgOpenFeignClient; |
|
|
|
|
|
|
|
@Autowired |
|
|
|
private OssFeignClient ossFeignClient; |
|
|
|
|
|
|
|
private ThreadLocal<List<ImportResultDesc>> importResultDescTl = new ThreadLocal<>(); |
|
|
|
|
|
|
|
/** |
|
|
|
* 导入结果描述 |
|
|
|
*/ |
|
|
|
@Data |
|
|
|
@NoArgsConstructor |
|
|
|
@AllArgsConstructor |
|
|
|
public static class ImportResultDesc { |
|
|
|
@ColumnWidth(20) |
|
|
|
@ExcelProperty(value = "申请人") |
|
|
|
private String applicantName; |
|
|
|
|
|
|
|
@ColumnWidth(30) |
|
|
|
@ExcelProperty(value = "服务内容") |
|
|
|
private String serviceContent; |
|
|
|
|
|
|
|
@ColumnWidth(30) |
|
|
|
@ExcelProperty(value = "描述") |
|
|
|
private String desc; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public PageData<WorkdiaryServiceRecordDTO> page(Map<String, Object> params) { |
|
|
|
IPage<WorkdiaryServiceRecordEntity> page = baseDao.selectPage( |
|
|
@ -77,14 +129,18 @@ public class WorkdiaryServiceRecordServiceImpl extends BaseServiceImpl<Workdiary |
|
|
|
public PageData<WorkdiaryServiceRecordDTO> page(String gridId, Short serviceType, String applicantName, String applicantAddress, |
|
|
|
String serviceContent, String applicantMobile, Integer pageNo, Integer pageSize) { |
|
|
|
|
|
|
|
LoginUserDetailsResultDTO currentStaff = getResultDataOrThrowsException(userOpenFeignClient.getLoginUserDetails(new LoginUserDetailsFormDTO( |
|
|
|
EpmetRequestHolder.getLoginUserApp(), EpmetRequestHolder.getLoginUserClient(), EpmetRequestHolder.getLoginUserId() |
|
|
|
)), ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "查询工作人员信息失败", "查询工作人员信息失败"); |
|
|
|
|
|
|
|
LambdaQueryWrapper<WorkdiaryServiceRecordEntity> query = new LambdaQueryWrapper<>(); |
|
|
|
query.eq(StringUtils.isNotBlank(gridId), WorkdiaryServiceRecordEntity::getGridId, gridId); |
|
|
|
query.eq(serviceType != null, WorkdiaryServiceRecordEntity::getServiceType, serviceType); |
|
|
|
query.eq(WorkdiaryServiceRecordEntity::getCreatedBy, EpmetRequestHolder.getLoginUserId()); |
|
|
|
query.like(StringUtils.isNotBlank(applicantName), WorkdiaryServiceRecordEntity::getApplicantName, applicantName); |
|
|
|
query.like(StringUtils.isNotBlank(applicantAddress), WorkdiaryServiceRecordEntity::getApplicantAddress, applicantAddress); |
|
|
|
query.like(StringUtils.isNotBlank(serviceContent), WorkdiaryServiceRecordEntity::getServiceContent, serviceContent); |
|
|
|
query.like(StringUtils.isNotBlank(applicantMobile), WorkdiaryServiceRecordEntity::getApplicantMobile, applicantMobile); |
|
|
|
query.likeRight(WorkdiaryServiceRecordEntity::getOrgIdPath, currentStaff.getOrgIdPath()); |
|
|
|
|
|
|
|
// 查找类型列表
|
|
|
|
List<WorkdiaryServiceTypeDTO> stList = SpringContextUtils.getBean(WorkdiaryServiceTypeService.class).list(null, 1, 100); |
|
|
@ -246,4 +302,189 @@ public class WorkdiaryServiceRecordServiceImpl extends BaseServiceImpl<Workdiary |
|
|
|
query.eq(WorkdiaryServiceRecordEntity::getServiceType, serviceType); |
|
|
|
return baseDao.selectCount(query); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 创建导入任务并且执行导入 |
|
|
|
* @param fileSavePath |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public void createImportTaskAndExecuteImport(Path fileSavePath, String originFileName, String taskId) { |
|
|
|
String resultDescFileUtl = null; |
|
|
|
// 执行导入操作
|
|
|
|
try { |
|
|
|
importResultDescTl.set(new ArrayList<>()); |
|
|
|
WorkdiaryServiceImportListener listener = new WorkdiaryServiceImportListener(this); |
|
|
|
EasyExcel.read(fileSavePath.toFile(), WorkdiaryServiceRecordExcel.class,listener).headRowNumber(1).sheet(0).doRead(); |
|
|
|
} catch (Exception e) { |
|
|
|
logger.error("【工作日志】-导入-未知错误:{}", ExceptionUtils.getErrorStackTrace(e)); |
|
|
|
} finally { |
|
|
|
// 清理临时文件
|
|
|
|
try { |
|
|
|
Files.deleteIfExists(fileSavePath); |
|
|
|
} catch (IOException e) { |
|
|
|
logger.error("【书记日志】-导入-删除导入临时文件失败,staffId:{}, 文件名称:{}, 错误信息:{}", |
|
|
|
EpmetRequestHolder.getLoginUserId(), fileSavePath.toString(), ExceptionUtils.getErrorStackTrace(e)); |
|
|
|
} |
|
|
|
|
|
|
|
// 上传错误描述文件
|
|
|
|
try { |
|
|
|
resultDescFileUtl = buildAndUploadResultDescFile(importResultDescTl.get()); |
|
|
|
} catch (IOException e) { |
|
|
|
logger.error("【工作日志】导入-生成和上传错误描述文件失败:{}", ExceptionUtils.getErrorStackTrace(e)); |
|
|
|
} |
|
|
|
|
|
|
|
// 清理错误结果描述缓存
|
|
|
|
importResultDescTl.remove(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 修改导入记录状态为已完成
|
|
|
|
ImportTaskUtils.finishImportTask(taskId, ImportTaskConstants.PROCESS_STATUS_FINISHED_SUCCESS, resultDescFileUtl, ""); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 生成和上传错误描述文件 |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
private String buildAndUploadResultDescFile(List<ImportResultDesc> descs) throws IOException { |
|
|
|
if(CollectionUtils.isEmpty(descs)) { |
|
|
|
return null; |
|
|
|
} |
|
|
|
//Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("导入失败的数据列表","导入失败的数据列表"),
|
|
|
|
// ImportResultDesc.class, descs);
|
|
|
|
|
|
|
|
String fileName = System.currentTimeMillis() + "_" + EpmetRequestHolder.getLoginUserId() + ".xlsx"; |
|
|
|
|
|
|
|
FileItem fileItem = new DiskFileItemFactory(DiskFileItemFactory.DEFAULT_SIZE_THRESHOLD, FileUtils.getAndCreateDirUnderEpmetFilesDir("workdiary", "result_desc").toFile()) |
|
|
|
.createItem("file", ContentType.APPLICATION_OCTET_STREAM.toString(), false, fileName); |
|
|
|
|
|
|
|
// 为了自动关闭流
|
|
|
|
try (OutputStream os = fileItem.getOutputStream()) { |
|
|
|
EasyExcel.write(os, ImportResultDesc.class).sheet("失败列表").doWrite(descs); |
|
|
|
} |
|
|
|
|
|
|
|
UploadImgResultDTO result = getResultDataOrThrowsException(ossFeignClient.uploadImportTaskDescFile(new CommonsMultipartFile(fileItem)), |
|
|
|
ServiceConstant.EPMET_OSS_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "上传结果描述文件失败", "上传结果描述文件失败"); |
|
|
|
|
|
|
|
if (!fileItem.isInMemory()) { |
|
|
|
fileItem.delete(); |
|
|
|
} |
|
|
|
return result.getUrl(); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 执行批量插入 |
|
|
|
* @param datas |
|
|
|
*/ |
|
|
|
@Override |
|
|
|
public void executeBatchImport(List<WorkdiaryServiceRecordExcel> datas) { |
|
|
|
if (CollectionUtils.isEmpty(datas)) { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
// 当前登录人
|
|
|
|
LoginUserDetailsResultDTO currentStaff = getResultDataOrThrowsException(userOpenFeignClient.getLoginUserDetails( |
|
|
|
new LoginUserDetailsFormDTO(EpmetRequestHolder.getLoginUserApp(), EpmetRequestHolder.getLoginUserClient(), EpmetRequestHolder.getLoginUserId())), |
|
|
|
ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【工作日志】-导入-没有找到当前登录人信息", "【工作日志】-导入-没有找到当前登录人信息"); |
|
|
|
|
|
|
|
// 服务类型字典。key:养老 value:object
|
|
|
|
List<WorkdiaryServiceTypeDTO> serviceTypes = SpringContextUtils.getBean(WorkdiaryServiceTypeService.class).page(null, 1, 100).getList(); |
|
|
|
Map<String, WorkdiaryServiceTypeDTO> serviceTypeMap = serviceTypes.stream().collect(Collectors.toMap(WorkdiaryServiceTypeDTO::getServiceTypeName, Function.identity())); |
|
|
|
|
|
|
|
ArrayList<WorkdiaryServiceRecordEntity> diaryRecordList = new ArrayList<>(); |
|
|
|
|
|
|
|
// 循环校验和填充数据
|
|
|
|
for (WorkdiaryServiceRecordExcel row : datas) { |
|
|
|
|
|
|
|
String gridName = row.getGridName(); |
|
|
|
String serviceTypeName = row.getServiceTypeName(); |
|
|
|
String applicantName = row.getApplicantName(); |
|
|
|
|
|
|
|
try { |
|
|
|
// 校验必填
|
|
|
|
ValidatorUtils.validateEntity(row); |
|
|
|
|
|
|
|
// 检查服务类型
|
|
|
|
WorkdiaryServiceTypeDTO serviceType = serviceTypeMap.get(serviceTypeName); |
|
|
|
if (serviceType == null || serviceType.getEnabled().shortValue() == 0) { |
|
|
|
throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "所选服务类型不存在或已禁用", "所选服务类型不存在或已禁用"); |
|
|
|
} |
|
|
|
|
|
|
|
// 检查网格
|
|
|
|
OptionResultDTO grid = findGrid(currentStaff.getAgencyId(), gridName); |
|
|
|
if (grid == null) { |
|
|
|
throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "网格不存在,或不在您所属的组织下", "网格不存在,或不在您所属的组织下"); |
|
|
|
} |
|
|
|
|
|
|
|
// 查找居民
|
|
|
|
IcResiNonDynamicResultDTO resi = findResi(grid.getValue(), row.getApplicantName(), row.getApplicantMobile()); |
|
|
|
|
|
|
|
if (StringUtils.isBlank(row.getApplicantMobile())) { |
|
|
|
row.setApplicantMobile(resi.getMobile()); |
|
|
|
} |
|
|
|
|
|
|
|
// 没填写住址的,到系统查询
|
|
|
|
if (StringUtils.isBlank(row.getApplicantAddress())) { |
|
|
|
|
|
|
|
HouseAgencyInfoResultDTO house = getResultDataOrThrowsException(govOrgOpenFeignClient.getHouseAgencyInfo(resi.getHomeId()), |
|
|
|
ServiceConstant.GOV_ORG_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "查询房屋失败", "查询房屋失败"); |
|
|
|
|
|
|
|
if (house == null) { |
|
|
|
throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "居民住址未找到", "居民未找到"); |
|
|
|
} |
|
|
|
|
|
|
|
row.setApplicantAddress(house.getFullName()); |
|
|
|
} |
|
|
|
// 填充到entity
|
|
|
|
WorkdiaryServiceRecordEntity record = new WorkdiaryServiceRecordEntity(EpmetRequestHolder.getLoginUserCustomerId(), serviceType.getServiceType(), currentStaff.getAgencyId(), |
|
|
|
grid.getValue(), currentStaff.getOrgIdPath().concat(":").concat(grid.getValue()), resi.getId(), row.getApplicantName(), |
|
|
|
row.getApplicantAddress(), row.getApplicantMobile(), row.getServiceContent(), row.getServiceTime(), row.getPrincipal(), row.getRemark()); |
|
|
|
|
|
|
|
diaryRecordList.add(record); |
|
|
|
} catch (ValidateException ve) { |
|
|
|
importResultDescTl.get().add(new ImportResultDesc(applicantName, row.getServiceContent(), ve.getMsg())); |
|
|
|
} catch (EpmetException ee) { |
|
|
|
importResultDescTl.get().add(new ImportResultDesc(applicantName, row.getServiceContent(), ee.getMsg())); |
|
|
|
} catch (Throwable t) { |
|
|
|
logger.error(ExceptionUtils.getThrowableErrorStackTrace(t)); |
|
|
|
importResultDescTl.get().add(new ImportResultDesc(applicantName, row.getServiceContent(), "未知错误")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 批量持久化
|
|
|
|
insertBatch(diaryRecordList, 50); |
|
|
|
} |
|
|
|
|
|
|
|
private IcResiNonDynamicResultDTO findResi(String gridId, String applicantName, String mobile) { |
|
|
|
PageData<IcResiNonDynamicResultDTO> page = getResultDataOrThrowsException(userOpenFeignClient.listResiNonDynamic(new IcResiPageNonDynamicFormDTO(gridId, applicantName, mobile, false)), |
|
|
|
ServiceConstant.EPMET_USER_SERVER, EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "居民未找到", "居民未找到"); |
|
|
|
|
|
|
|
List<IcResiNonDynamicResultDTO> list = page.getList(); |
|
|
|
|
|
|
|
if (page == null || CollectionUtils.isEmpty(page.getList())) { |
|
|
|
throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "居民未找到", "居民未找到"); |
|
|
|
} |
|
|
|
|
|
|
|
return list.get(0); |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 从组织下查找指定的网格名称,得到网格数据 |
|
|
|
* @param agencyId |
|
|
|
* @param gridName |
|
|
|
* @return |
|
|
|
*/ |
|
|
|
private OptionResultDTO findGrid(String agencyId, String gridName) { |
|
|
|
List<OptionResultDTO> gridOptions = getResultDataOrThrowsException(govOrgOpenFeignClient.getGridOption(new GridOptionFormDTO(agencyId, "saveOrUpdate")), |
|
|
|
ServiceConstant.GOV_ORG_SERVER, EpmetErrorCode.SERVER_ERROR.getCode(), "【工作日志】-导入-网格查询失败", "【工作日志】-导入-网格查询失败"); |
|
|
|
|
|
|
|
for (OptionResultDTO grid : gridOptions) { |
|
|
|
if (gridName.equals(grid.getLabel())) { |
|
|
|
return grid; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|