From 540692c2c84beb3c7d56b46749349fb187027adb Mon Sep 17 00:00:00 2001 From: wangxianzhang Date: Tue, 12 Apr 2022 12:50:17 +0800 Subject: [PATCH 1/7] =?UTF-8?q?=E4=BF=AE=E6=94=B9=EF=BC=9A=E5=B1=85?= =?UTF-8?q?=E6=B0=91=E4=BF=A1=E6=81=AF=E5=AF=BC=E5=85=A5=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=20=E4=BF=AE=E6=94=B9=EF=BC=9A=E5=B1=85?= =?UTF-8?q?=E6=B0=91=E4=BF=A1=E6=81=AF=E5=AF=BC=E5=85=A5=EF=BC=8C=E5=A6=82?= =?UTF-8?q?=E6=9E=9C=E6=9C=AA=E5=85=A8=E6=88=90=E5=8A=9F=EF=BC=8C=E9=82=A3?= =?UTF-8?q?=E4=B9=88=E4=BF=9D=E7=95=99=E4=B8=B4=E6=97=B6=E4=B8=8A=E4=BC=A0?= =?UTF-8?q?=E7=9A=84=E9=82=A3=E4=B8=AAexcel=E6=96=87=E4=BB=B6=EF=BC=8C?= =?UTF-8?q?=E4=BE=9B=E6=8E=92=E6=9F=A5=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/IcResiUserController.java | 53 +++++++++--------- .../service/IcResiUserImportService.java | 2 +- .../impl/IcResiUserImportServiceImpl.java | 9 ++- ..._excel.xls => ic_resi_import_template.xls} | Bin 4 files changed, 35 insertions(+), 29 deletions(-) rename epmet-user/epmet-user-server/src/main/resources/excel/{ic_resi_info_import_cid_for_easy_excel.xls => ic_resi_import_template.xls} (100%) diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java index 0bfc2fa442..f054e77608 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java @@ -72,6 +72,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; @@ -135,7 +136,7 @@ public class IcResiUserController implements ResultDataResolver { * 模板枚举 */ public enum IcUserTemplateEnums { - IC_RESI_IMPORT_TEMPLATE("excel/ic_resi_info_import_cid_for_easy_excel.xls", "居民信息导入模板.xls"), + IC_RESI_IMPORT_TEMPLATE("excel/ic_resi_import_template.xls", "居民信息导入模板.xls"), IC_RESI_EXPORT_TEMPLATE("excel/ic_resi_info_cid_for_easy_excel.xlsx", "居民信息导出模板.xlsx"); private String pathInApp; @@ -157,18 +158,13 @@ public class IcResiUserController implements ResultDataResolver { { // 初始化上传目录 - String home = System.getProperty("user.home"); - Path importDir = Paths.get(home, "epmet_files", "ic_user_import"); - if (Files.notExists(importDir)) { - try { - Files.createDirectories(importDir); - } catch (IOException e) { - log.error("创建数字赋能平台上传目录失败"); - } + try { + IC_RESI_UPLOAD_DIR = com.epmet.commons.tools.utils.FileUtils.getAndCreateDirUnderEpmetFilesDir("ic_user_import"); + } catch (IOException e) { + log.error("初始化居民信息上传目录失败:{}", ExceptionUtils.getErrorStackTrace(e)); } - IC_RESI_UPLOAD_DIR = importDir; - Path exportDir = Paths.get(home, "epmet_files", "ic_user_export"); + Path exportDir = Paths.get(System.getProperty("user.home"), "epmet_files", "ic_user_export"); if (Files.notExists(exportDir)) { try { Files.createDirectories(exportDir); @@ -469,10 +465,10 @@ public class IcResiUserController implements ResultDataResolver { // 三.异步执行导入 executorService.execute(() -> { - + boolean isAllSuccess = false; try { List formItemList = icResiUserService.listFormItems(customerId,IcFormCodeEnum.RESI_BASE_INFO.getCode()); - icResiUserImportService.importIcResiInfoFromExcel(importTaskId, formItemList, importTempFileSavePath.toString(), response, IC_RESI_UPLOAD_DIR); + isAllSuccess = icResiUserImportService.importIcResiInfoFromExcel(importTaskId, formItemList, importTempFileSavePath.toString(), response, IC_RESI_UPLOAD_DIR); } catch (Throwable e) { String errorMsg = ExceptionUtils.getThrowableErrorStackTrace(e); log.error("【导入居民信息失败】导入失败:{}", errorMsg); @@ -488,8 +484,13 @@ public class IcResiUserController implements ResultDataResolver { icResiUserImportService.finishImportTask(importTaskId, operatorId, ImportTaskConstants.PROCESS_STATUS_FINISHED_FAIL, resultDesc, null); } finally { try { + // 都导入成功了没问题,才删除 if (importTempFileSavePath != null){ - Files.delete(importTempFileSavePath); + if (isAllSuccess) { + Files.delete(importTempFileSavePath); + } else { + log.error("【导入居民信息】未完全成功,上传文件:{}", importTempFileSavePath); + } } } catch (IOException e) { log.error("【导入居民信息失败】清理上传的文件失败:{}", ExceptionUtils.getErrorStackTrace(e)); @@ -585,28 +586,30 @@ public class IcResiUserController implements ResultDataResolver { /** * 下载ic居民信息导入excel模板 - * @param loginUserInfo * @return */ @PostMapping("import/download-template") - public ResponseEntity downloadIcResiDownloadTemplate(@LoginUser TokenDto loginUserInfo) { - String customerId = loginUserInfo.getCustomerId(); - + public void downloadIcResiDownloadTemplate(HttpServletResponse response) { + InputStream is = null; + ServletOutputStream os = null; try { - File icResiImportTemplateFile = getIcResiTemplateFile(customerId, IcUserTemplateEnums.IC_RESI_IMPORT_TEMPLATE); + os = response.getOutputStream(); + + is = this.getClass().getClassLoader().getResourceAsStream(IcUserTemplateEnums.IC_RESI_IMPORT_TEMPLATE.getPathInApp()); - HttpHeaders headers = new HttpHeaders(); - headers.add("Access-Control-Expose-Headers", "Content-Disposition"); - headers.add("content-Type", "application/vnd.ms-excel"); - headers.add("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(IcUserTemplateEnums.IC_RESI_IMPORT_TEMPLATE.getTemplateName(), "UTF-8")); + response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); + response.setHeader("content-Type", "application/vnd.ms-excel"); + response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(IcUserTemplateEnums.IC_RESI_IMPORT_TEMPLATE.getTemplateName(), "UTF-8")); - return new ResponseEntity<>(FileUtil.readBytes(icResiImportTemplateFile), headers, HttpStatus.OK); + IOUtils.copy(is, os); } catch (Exception e) { String errorStackTrace = ExceptionUtils.getErrorStackTrace(e); - log.error("下载IC居民信息导入模板失败:{}", errorStackTrace); throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), "下载IC居民信息导入模板失败"); + } finally { + org.apache.poi.util.IOUtils.closeQuietly(is); + org.apache.poi.util.IOUtils.closeQuietly(os); } } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java index 05fb431c32..f3451f3e13 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java @@ -13,7 +13,7 @@ import java.util.List; */ public interface IcResiUserImportService { - void importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response, Path importTempPath); + boolean importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response, Path importTempPath); /** * 创建导入任务 diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java index 44a6ee7a63..f17c6ad2d4 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java @@ -13,7 +13,6 @@ import com.epmet.bean.ResiImportChangedData; import com.epmet.commons.tools.constant.AppClientConstant; import com.epmet.commons.tools.constant.ServiceConstant; import com.epmet.commons.tools.constant.StrConstant; -import com.epmet.commons.tools.constant.ThreadLocalConstant; import com.epmet.commons.tools.dto.result.CustomerStaffInfoCacheResult; import com.epmet.commons.tools.dto.result.OptionResultDTO; import com.epmet.commons.tools.exception.EpmetErrorCode; @@ -24,7 +23,6 @@ import com.epmet.commons.tools.feign.ResultDataResolver; import com.epmet.commons.tools.redis.RedisKeys; import com.epmet.commons.tools.redis.RedisUtils; import com.epmet.commons.tools.redis.common.CustomerStaffRedis; -import com.epmet.commons.tools.security.user.LoginUserUtil; import com.epmet.commons.tools.utils.ConvertUtils; import com.epmet.commons.tools.utils.EpmetRequestHolder; import com.epmet.commons.tools.utils.Result; @@ -211,9 +209,11 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res * @param formItemList item列表 * @param excelPathName excel缓存路径 * @param response 响应对象 + * @return */ @Override - public void importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response, Path importTempPath) { + public boolean importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response, Path importTempPath) { + boolean isAllSuccess = false; String app = EpmetRequestHolder.getHeader(AppClientConstant.APP); String client = EpmetRequestHolder.getHeader(AppClientConstant.CLIENT); @@ -276,6 +276,7 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res } finishImportTask(importTaskId, loginUserId, ImportTaskConstants.PROCESS_STATUS_FINISHED_FAIL,null, resultDescFilePath); } else { + isAllSuccess = true; finishImportTask(importTaskId, loginUserId, ImportTaskConstants.PROCESS_STATUS_FINISHED_SUCCESS,null, null); } @@ -298,6 +299,8 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res resiCategoryColumnNameAndLabel.remove(); itemIdAndOptionsCache.invalidateAll(); } + + return isAllSuccess; } /** diff --git a/epmet-user/epmet-user-server/src/main/resources/excel/ic_resi_info_import_cid_for_easy_excel.xls b/epmet-user/epmet-user-server/src/main/resources/excel/ic_resi_import_template.xls similarity index 100% rename from epmet-user/epmet-user-server/src/main/resources/excel/ic_resi_info_import_cid_for_easy_excel.xls rename to epmet-user/epmet-user-server/src/main/resources/excel/ic_resi_import_template.xls From 83226ebd048f9eb8cd0e604ad3dd3215b632ad88 Mon Sep 17 00:00:00 2001 From: wangxianzhang Date: Tue, 12 Apr 2022 15:46:31 +0800 Subject: [PATCH 2/7] =?UTF-8?q?=E5=B1=85=E6=B0=91=E5=AF=BC=E5=85=A5?= =?UTF-8?q?=EF=BC=9Aidcard=E4=B8=BA=E7=A9=BA=EF=BC=8C=E5=AF=BC=E8=87=B4sel?= =?UTF-8?q?ectOne=20return=20many?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/impl/IcResiUserImportServiceImpl.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java index f17c6ad2d4..722fb93cd2 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java @@ -539,10 +539,18 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res private void specifiedCheck(LinkedHashMap columnAndValues) { String idCard = columnAndValues.get("ID_CARD"); String mobile = columnAndValues.get("MOBILE"); + String name = columnAndValues.get("NAME"); List errors = new ArrayList<>(); - if (StringUtils.isNotBlank(idCard) && idCard.length() > 18) { + if (StringUtils.isBlank(idCard)) { + log.debug("【居民信息导入】specifiedCheck身份证号为空的:{},{}", mobile, name); + + String errorMsg = "身份证号不能为空"; + throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(), errorMsg, errorMsg); + } + + if (idCard.length() > 18) { // 身份证号超长了哦,不可以的 errors.add("身份证号过长"); } @@ -573,9 +581,6 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res LinkedHashMap columnAndValues = new LinkedHashMap<>(); - String loginUserApp = EpmetRequestHolder.getHeader(AppClientConstant.APP); - String loginUserClient = EpmetRequestHolder.getHeader(AppClientConstant.CLIENT); - String loginUserId = EpmetRequestHolder.getHeader(AppClientConstant.USER_ID.toLowerCase()); String loginUserCustomerId = EpmetRequestHolder.getHeader(AppClientConstant.CUSTOMER_ID.toLowerCase()); // 遍历每一行,将行内容转化为 From 5e0ae7d48361fbf3063f4898e8a21d4f4fdb9843 Mon Sep 17 00:00:00 2001 From: jianjun Date: Tue, 12 Apr 2022 18:30:45 +0800 Subject: [PATCH 3/7] =?UTF-8?q?=E7=BD=91=E6=A0=BC=E5=91=98=E5=B7=A1?= =?UTF-8?q?=E6=9F=A5=E5=9C=A8=E7=BA=BF=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../epmet/commons/tools/redis/RedisKeys.java | 14 ++++ .../java/com/epmet/OpenDataApplication.java | 3 +- .../opendata/dao/GriderOnlineNumDao.java | 33 +++++++++ .../entity/GriderOnlineNumEntity.java | 61 ++++++++++++++++ .../service/GriderOnlineNumService.java | 38 ++++++++++ .../impl/GriderOnlineNumServiceImpl.java | 69 ++++++++++++++++++ .../task/ExtractBizDataToOpenData.java | 71 +++++++++++++++++++ .../V0.0.1__add_grider_online_num.sql | 13 ++++ .../resources/mapper/GriderOnlineNumDao.xml | 6 ++ 9 files changed, 307 insertions(+), 1 deletion(-) create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/dao/GriderOnlineNumDao.java create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/entity/GriderOnlineNumEntity.java create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/GriderOnlineNumService.java create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/impl/GriderOnlineNumServiceImpl.java create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/task/ExtractBizDataToOpenData.java create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/resources/db/migration/V0.0.1__add_grider_online_num.sql create mode 100644 epmet-module/open-data-worker/open-data-worker-server/src/main/resources/mapper/GriderOnlineNumDao.xml diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java index 04db67cfed..05e5c200a4 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/RedisKeys.java @@ -10,6 +10,8 @@ package com.epmet.commons.tools.redis; import com.epmet.commons.tools.constant.NumConstant; import com.epmet.commons.tools.constant.StrConstant; +import com.epmet.commons.tools.exception.EpmetErrorCode; +import com.epmet.commons.tools.exception.EpmetException; import com.epmet.commons.tools.utils.DateUtils; import org.apache.commons.lang3.StringUtils; @@ -763,4 +765,16 @@ public class RedisKeys { public static String getNextAreaCodeKey(String areaCode) { return rootPrefix.concat("areaCode:parentCode:").concat(areaCode); } + + /** + * desc:获取分布式锁key + * @param methodName + * @return + */ + public static String getLockByMethodName(String methodName) { + if (StringUtils.isBlank(methodName)){ + throw new EpmetException(EpmetErrorCode.EPMET_COMMON_OPERATION_FAIL.getCode(),"参数错误"); + } + return rootPrefix.concat("lock:").concat(methodName); + } } diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/OpenDataApplication.java b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/OpenDataApplication.java index 532877cf4b..c786abb9ba 100644 --- a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/OpenDataApplication.java +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/OpenDataApplication.java @@ -5,7 +5,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.openfeign.EnableFeignClients; -import org.springframework.context.annotation.ComponentScan; +import org.springframework.scheduling.annotation.EnableScheduling; /** * @Description OpenData服务启动类 @@ -14,6 +14,7 @@ import org.springframework.context.annotation.ComponentScan; * @author wxz * @date 2021.10.13 15:16:05 */ +@EnableScheduling @SpringBootApplication @EnableDiscoveryClient @EnableFeignClients diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/dao/GriderOnlineNumDao.java b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/dao/GriderOnlineNumDao.java new file mode 100644 index 0000000000..9f4080c054 --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/dao/GriderOnlineNumDao.java @@ -0,0 +1,33 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.epmet.opendata.dao; + +import com.epmet.commons.mybatis.dao.BaseDao; +import com.epmet.opendata.entity.GriderOnlineNumEntity; +import org.apache.ibatis.annotations.Mapper; + +/** + * 在线网格员人数 + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2021-10-14 + */ +@Mapper +public interface GriderOnlineNumDao extends BaseDao { + +} diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/entity/GriderOnlineNumEntity.java b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/entity/GriderOnlineNumEntity.java new file mode 100644 index 0000000000..ca707865cf --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/entity/GriderOnlineNumEntity.java @@ -0,0 +1,61 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.epmet.opendata.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.epmet.commons.mybatis.entity.BaseEpmetEntity; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.util.Date; + +/** + * 用户巡查主记录 + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2021-10-14 + */ +@Data +@EqualsAndHashCode(callSuper=false) +@TableName("grider_online_num") +public class GriderOnlineNumEntity extends BaseEpmetEntity { + + private static final long serialVersionUID = 1L; + + /** + * 客户Id + */ + private String customerId; + + private String qxGridId; + + /** + * 推送时间 + */ + @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date pushTime; + + /** + * 在线数 + */ + private Integer onlineNum; + + + +} diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/GriderOnlineNumService.java b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/GriderOnlineNumService.java new file mode 100644 index 0000000000..55112c1d8d --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/GriderOnlineNumService.java @@ -0,0 +1,38 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.epmet.opendata.service; + +import com.epmet.commons.mybatis.service.BaseService; +import com.epmet.opendata.entity.GriderOnlineNumEntity; + +/** + * 用户巡查主记录 + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2021-10-14 + */ +public interface GriderOnlineNumService extends BaseService { + + /** + * desc:插入巡查中的网格员数据 + * @return boolean + */ + Boolean insertData(String agencyId); + + +} diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/impl/GriderOnlineNumServiceImpl.java b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/impl/GriderOnlineNumServiceImpl.java new file mode 100644 index 0000000000..b024c1436e --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/service/impl/GriderOnlineNumServiceImpl.java @@ -0,0 +1,69 @@ +/** + * Copyright 2018 人人开源 https://www.renren.io + *

+ * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + *

+ * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + *

+ * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.epmet.opendata.service.impl; + +import com.alibaba.fastjson.JSON; +import com.epmet.commons.mybatis.service.impl.BaseServiceImpl; +import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.constant.StrConstant; +import com.epmet.commons.tools.utils.Result; +import com.epmet.dto.form.PatrolCountFormDTO; +import com.epmet.dto.result.PatrolCountResultDTO; +import com.epmet.feign.EpmetUserOpenFeignClient; +import com.epmet.opendata.dao.GriderOnlineNumDao; +import com.epmet.opendata.entity.GriderOnlineNumEntity; +import com.epmet.opendata.service.GriderOnlineNumService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import java.util.Date; + + +/** + * 用户巡查主记录 + * + * @author generator generator@elink-cn.com + * @since v1.0.0 2021-10-14 + */ +@Slf4j +@Service +public class GriderOnlineNumServiceImpl extends BaseServiceImpl implements GriderOnlineNumService { +@Autowired +private EpmetUserOpenFeignClient epmetUserOpenFeignClient; + @Override + public Boolean insertData(String agencyId) { + PatrolCountFormDTO param = new PatrolCountFormDTO(); + param.setAgencyId(agencyId); + Result patrolCountResult = epmetUserOpenFeignClient.patrolCount(param); + + log.debug("insertData patrolCountResult return:{}", JSON.toJSONString(patrolCountResult)); + if (patrolCountResult == null || !patrolCountResult.success()) { + log.warn("insertData patrolCount fail,return null"); + return false; + } + PatrolCountResultDTO data = patrolCountResult.getData(); + int count = data.getPatrollingCount() == null ? NumConstant.ZERO : data.getPatrollingCount(); + GriderOnlineNumEntity entity = new GriderOnlineNumEntity(); + entity.setCustomerId(StrConstant.PY_CUSTOMER); + entity.setPushTime(new Date()); + entity.setOnlineNum(count); + baseDao.insert(entity); + return true; + } +} diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/task/ExtractBizDataToOpenData.java b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/task/ExtractBizDataToOpenData.java new file mode 100644 index 0000000000..ebcd5aa27d --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/java/com/epmet/opendata/task/ExtractBizDataToOpenData.java @@ -0,0 +1,71 @@ +package com.epmet.opendata.task; + +import com.epmet.commons.tools.constant.NumConstant; +import com.epmet.commons.tools.constant.StrConstant; +import com.epmet.commons.tools.distributedlock.DistributedLock; +import com.epmet.commons.tools.redis.RedisKeys; +import com.epmet.commons.tools.utils.DateUtils; +import com.epmet.opendata.service.GriderOnlineNumService; +import lombok.extern.slf4j.Slf4j; +import org.redisson.api.RLock; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import java.util.Date; + +/** + * desc: + * + * @author: LiuJanJun + * @date: 2022/4/12 4:21 下午 + * @version: 1.0 + */ +@Slf4j +@Component +public class ExtractBizDataToOpenData { + + @Autowired + private DistributedLock distributedLock; + + @Autowired + private GriderOnlineNumService griderOnlineNumService; + + @Scheduled(cron = "0 30 */2 * * *") + //@Scheduled(cron = "0/15 * * * * *") + public void extractGridMemberPatrollingCount() { + String currentTime = DateUtils.format(new Date(), DateUtils.DATE_TIME_PATTERN); + log.info("extractGridMemberPatrollingCount start,date:{}", currentTime); + RLock rLock = null; + try { + rLock = distributedLock.tryLock(RedisKeys.getLockByMethodName("extractGridMemberPatrollingCount")); + if (rLock == null || !rLock.isLocked()) { + log.warn("tryLock method extractGridMemberPatrollingCount fail"); + return; + } + boolean patrolCountResult; + int retryTime = NumConstant.THREE; + do { + //StrConstant.PY_ROOT_AGENCY + patrolCountResult = griderOnlineNumService.insertData(StrConstant.PY_ROOT_AGENCY); + if (!patrolCountResult) { + break; + } + //如果 重试次数为1了 就让歇个 5分钟 + if (retryTime == 1) { + Thread.sleep(NumConstant.FIVE * NumConstant.SIXTY * NumConstant.ONE_THOUSAND); + } + } while (retryTime-- > 0); + if (!patrolCountResult) { + log.error("插入网格员在线人数失败,请检查原因,时间:{}", currentTime); + } + + } catch (Exception e) { + log.warn("tryLock method extractGridMemberPatrollingCount fail"); + } finally { + distributedLock.unLock(rLock); + } + log.info("extractGridMemberPatrollingCount end"); + } + +} diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/resources/db/migration/V0.0.1__add_grider_online_num.sql b/epmet-module/open-data-worker/open-data-worker-server/src/main/resources/db/migration/V0.0.1__add_grider_online_num.sql new file mode 100644 index 0000000000..d4fd9ca93f --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/resources/db/migration/V0.0.1__add_grider_online_num.sql @@ -0,0 +1,13 @@ +CREATE TABLE `grider_online_num` ( + `ID` varchar(64) NOT NULL COMMENT '主键', + `CUSTOMER_ID` varchar(64) NOT NULL COMMENT '客户Id', + `ONLINE_NUM` int(11) NOT NULL COMMENT '在线人数', + `PUSH_TIME` datetime NOT NULL COMMENT '推送时间', + `DEL_FLAG` bigint(1) NOT NULL DEFAULT '0' COMMENT '删除标识 0.未删除 1.已删除', + `REVISION` int(11) NOT NULL COMMENT '乐观锁', + `CREATED_BY` varchar(64) NOT NULL COMMENT '创建人', + `CREATED_TIME` datetime NOT NULL COMMENT '创建时间', + `UPDATED_BY` varchar(64) NOT NULL COMMENT '更新人', + `UPDATED_TIME` datetime NOT NULL COMMENT '更新时间', + PRIMARY KEY (`ID`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='网格员在线人数'; diff --git a/epmet-module/open-data-worker/open-data-worker-server/src/main/resources/mapper/GriderOnlineNumDao.xml b/epmet-module/open-data-worker/open-data-worker-server/src/main/resources/mapper/GriderOnlineNumDao.xml new file mode 100644 index 0000000000..27c636d525 --- /dev/null +++ b/epmet-module/open-data-worker/open-data-worker-server/src/main/resources/mapper/GriderOnlineNumDao.xml @@ -0,0 +1,6 @@ + + + + + + From 9e91c954a61dfe3e520f292eacebd8a11abd45ac Mon Sep 17 00:00:00 2001 From: wangxianzhang Date: Wed, 13 Apr 2022 14:24:56 +0800 Subject: [PATCH 4/7] =?UTF-8?q?=E5=A2=9E=E5=8A=A0"=E5=B1=85=E6=B0=91?= =?UTF-8?q?=E4=BF=A1=E6=81=AF-=E6=98=AF=E5=90=A6=E7=A7=9F=E6=88=B7"sql?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/resources/db/migration/V0.0.40__member_huji.sql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/epmet-user/epmet-user-server/src/main/resources/db/migration/V0.0.40__member_huji.sql b/epmet-user/epmet-user-server/src/main/resources/db/migration/V0.0.40__member_huji.sql index 03a2a4bc23..b3f04f8c3c 100644 --- a/epmet-user/epmet-user-server/src/main/resources/db/migration/V0.0.40__member_huji.sql +++ b/epmet-user/epmet-user-server/src/main/resources/db/migration/V0.0.40__member_huji.sql @@ -1,2 +1,6 @@ alter table ic_resi_member add COLUMN DOMICILE_PLACE VARCHAR(128) comment '户籍所在地' AFTER YMJZ; alter table ic_resi_member add COLUMN WORK_PLACE VARCHAR(128) comment '单位或学校' AFTER DOMICILE_PLACE; + +-- 居民信息表添加租户列 +alter table ic_resi_user add column IS_TENANT char(1) comment '是否租户【是:1 否:0】' after IS_SPECIAL; +update ic_resi_user set ic_resi_user.IS_TENANT='0' where ic_resi_user.IS_TENANT is null or ic_resi_user.IS_TENANT=''; \ No newline at end of file From 10fc17df91a430924aaf41c1c7990817ba9805d7 Mon Sep 17 00:00:00 2001 From: yinzuomei <576302893@qq.com> Date: Wed, 13 Apr 2022 14:25:26 +0800 Subject: [PATCH 5/7] =?UTF-8?q?CustomerAgencyDTO=3D=E3=80=8BAgencyInfoCach?= =?UTF-8?q?e?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../redis/common/bean/AgencyInfoCache.java | 22 ++++++++ .../com/epmet/redis/CustomerAgencyRedis.java | 8 +-- .../epmet/service/impl/AgencyServiceImpl.java | 50 ++++++++++++++++--- 3 files changed, 70 insertions(+), 10 deletions(-) diff --git a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/AgencyInfoCache.java b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/AgencyInfoCache.java index 1a842d3987..c9e908d7da 100644 --- a/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/AgencyInfoCache.java +++ b/epmet-commons/epmet-commons-tools/src/main/java/com/epmet/commons/tools/redis/common/bean/AgencyInfoCache.java @@ -145,4 +145,26 @@ public class AgencyInfoCache implements Serializable { * 中心位置纬度 */ private String latitude; + + /** + * 组织编码 + */ + private String code; + + /** + * 负责人姓名 + */ + private String contacts; + + /** + * 联系电话 + */ + private String mobile; + + + //内部接口使用 + /** + * open:当前客户新增组织需要选择areaCode;closed: 无需选择区域编码 + */ + private String areaCodeSwitch; } diff --git a/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/redis/CustomerAgencyRedis.java b/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/redis/CustomerAgencyRedis.java index fb65a508d5..a4be0f2703 100644 --- a/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/redis/CustomerAgencyRedis.java +++ b/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/redis/CustomerAgencyRedis.java @@ -20,7 +20,7 @@ package com.epmet.redis; import cn.hutool.core.bean.BeanUtil; import com.epmet.commons.tools.redis.RedisKeys; import com.epmet.commons.tools.redis.RedisUtils; -import com.epmet.dto.CustomerAgencyDTO; +import com.epmet.commons.tools.redis.common.bean.AgencyInfoCache; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; @@ -44,19 +44,19 @@ public class CustomerAgencyRedis { redisUtils.delete(key); } - public void set(String agencyId, CustomerAgencyDTO value){ + public void set(String agencyId, AgencyInfoCache value){ String key = RedisKeys.getAgencyByIdKey(agencyId); Map map = BeanUtil.beanToMap(value, false, true); redisUtils.hMSet(key, map); } - public CustomerAgencyDTO get(String agencyId){ + public AgencyInfoCache get(String agencyId){ String key = RedisKeys.getAgencyByIdKey(agencyId); Map resultMap = redisUtils.hGetAll(key); if (CollectionUtils.isEmpty(resultMap)) { return null; } - return BeanUtil.mapToBean(resultMap, CustomerAgencyDTO.class, true); + return BeanUtil.mapToBean(resultMap, AgencyInfoCache.class, true); } } diff --git a/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/service/impl/AgencyServiceImpl.java b/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/service/impl/AgencyServiceImpl.java index 7a81bd7fd0..c07985347c 100644 --- a/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/service/impl/AgencyServiceImpl.java +++ b/epmet-module/gov-org/gov-org-server/src/main/java/com/epmet/service/impl/AgencyServiceImpl.java @@ -20,6 +20,7 @@ package com.epmet.service.impl; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; +import com.epmet.commons.tools.constant.Constant; import com.epmet.commons.tools.constant.NumConstant; import com.epmet.commons.tools.constant.StrConstant; import com.epmet.commons.tools.dto.result.CustomerStaffInfoCacheResult; @@ -490,16 +491,53 @@ public class AgencyServiceImpl implements AgencyService { @Override public CustomerAgencyDTO getAgencyById(String agencyId) { - CustomerAgencyDTO cachedAgency = customerAgencyRedis.get(agencyId); - if (cachedAgency == null) { - cachedAgency = new CustomerAgencyDTO(); + AgencyInfoCache agencyInfoCache = customerAgencyRedis.get(agencyId); + if (agencyInfoCache == null) { + agencyInfoCache = new AgencyInfoCache(); CustomerAgencyEntity agencyEntity = customerAgencyDao.selectById(agencyId); if (agencyEntity != null) { - BeanUtils.copyProperties(agencyEntity, cachedAgency); + //设置行政地区编码全路径 + if (StringUtils.isNotBlank(agencyEntity.getAreaCode()) && StringUtils.isNotBlank(agencyEntity.getParentAreaCode())) { + agencyInfoCache.setAreaCodePath(queryAreaCodePath(agencyEntity)); + } + BeanUtils.copyProperties(agencyEntity, agencyInfoCache); } - customerAgencyRedis.set(agencyId, cachedAgency); + customerAgencyRedis.set(agencyId, agencyInfoCache); + } + CustomerAgencyDTO customerAgencyDTO=ConvertUtils.sourceToTarget(agencyInfoCache,CustomerAgencyDTO.class); + return customerAgencyDTO; + } + + private List queryAreaCodePath(CustomerAgencyEntity customerAgencyEntity) { + List areaCodePath = new ArrayList<>(); + switch (customerAgencyEntity.getLevel()) { + case Constant.COMMUNITY: + areaCodePath.add(customerAgencyEntity.getAreaCode().substring(NumConstant.ZERO, NumConstant.TWO)); + areaCodePath.add(customerAgencyEntity.getAreaCode().substring(NumConstant.ZERO, NumConstant.FOUR)); + areaCodePath.add(customerAgencyEntity.getAreaCode().substring(NumConstant.ZERO, NumConstant.SIX)); + areaCodePath.add(customerAgencyEntity.getParentAreaCode()); + areaCodePath.add(customerAgencyEntity.getAreaCode()); + break; + case Constant.STREET: + areaCodePath.add(customerAgencyEntity.getAreaCode().substring(NumConstant.ZERO, NumConstant.TWO)); + areaCodePath.add(customerAgencyEntity.getAreaCode().substring(NumConstant.ZERO, NumConstant.FOUR)); + areaCodePath.add(customerAgencyEntity.getParentAreaCode()); + areaCodePath.add(customerAgencyEntity.getAreaCode()); + break; + case Constant.DISTRICT: + areaCodePath.add(customerAgencyEntity.getAreaCode().substring(NumConstant.ZERO, NumConstant.TWO)); + areaCodePath.add(customerAgencyEntity.getParentAreaCode()); + areaCodePath.add(customerAgencyEntity.getAreaCode()); + break; + case Constant.CITY: + areaCodePath.add(customerAgencyEntity.getParentAreaCode()); + areaCodePath.add(customerAgencyEntity.getAreaCode()); + break; + case Constant.PROVINCE: + areaCodePath.add(customerAgencyEntity.getAreaCode()); + break; } - return cachedAgency; + return areaCodePath; } @Override From c47b5312b977d68a4349d1e04f33d46ff969b785 Mon Sep 17 00:00:00 2001 From: zhaoqifeng Date: Wed, 13 Apr 2022 14:25:38 +0800 Subject: [PATCH 6/7] =?UTF-8?q?=E5=85=9A=E5=91=98=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E5=AF=BC=E5=87=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../epmet/excel/PartyMemberAgeExportExcel.java | 16 +++++++++++++--- .../excel/PartyMemberEducationExportExcel.java | 16 +++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberAgeExportExcel.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberAgeExportExcel.java index c8a6e6f8d0..6e0a65afc3 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberAgeExportExcel.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberAgeExportExcel.java @@ -1,6 +1,10 @@ package com.epmet.excel; import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; import lombok.Data; /** @@ -9,13 +13,19 @@ import lombok.Data; * @Date 2022/4/13 10:46 */ @Data +@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 44) public class PartyMemberAgeExportExcel { - @Excel(name = "序号", width = 10) + @ColumnWidth(8) + @ExcelProperty(value = "序号",order = 1) private Integer index; - @Excel(name = "姓名", width = 20) + @ColumnWidth(15) + @ExcelProperty(value = "姓名",order = 2) private String name; - @Excel(name = "年龄", width = 10) + @ColumnWidth(8) + @ExcelProperty(value = "年龄",order = 3) private String age; + @ColumnWidth(20) + @ExcelProperty(value = "手机号码",order = 4) @Excel(name = "手机号码", width = 30) private String mobile; } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberEducationExportExcel.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberEducationExportExcel.java index 1ec5f8033d..1a6955ede2 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberEducationExportExcel.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/excel/PartyMemberEducationExportExcel.java @@ -1,6 +1,10 @@ package com.epmet.excel; import cn.afterturn.easypoi.excel.annotation.Excel; +import com.alibaba.excel.annotation.ExcelProperty; +import com.alibaba.excel.annotation.write.style.ColumnWidth; +import com.alibaba.excel.annotation.write.style.HeadStyle; +import com.alibaba.excel.enums.poi.FillPatternTypeEnum; import lombok.Data; /** @@ -9,13 +13,19 @@ import lombok.Data; * @Date 2022/4/13 10:46 */ @Data +@HeadStyle(fillPatternType = FillPatternTypeEnum.SOLID_FOREGROUND, fillForegroundColor = 44) public class PartyMemberEducationExportExcel { - @Excel(name = "序号", width = 10) + @ColumnWidth(8) + @ExcelProperty(value = "序号",order = 1) private Integer index; - @Excel(name = "姓名", width = 20) + @ColumnWidth(15) + @ExcelProperty(value = "姓名",order = 2) private String name; - @Excel(name = "学历", width = 10) + @ColumnWidth(11) + @ExcelProperty(value = "学历",order = 3) private String education; + @ColumnWidth(20) + @ExcelProperty(value = "手机号码",order = 4) @Excel(name = "手机号码", width = 30) private String mobile; } From eab2335e59e1c19df4420182a9a157a37dd4f52b Mon Sep 17 00:00:00 2001 From: sunyuchao Date: Wed, 13 Apr 2022 14:42:24 +0800 Subject: [PATCH 7/7] =?UTF-8?q?=E6=88=BF=E5=B1=8B=E5=87=BA=E7=A7=9F?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=88=BF=E5=B1=8B=E7=8A=B6=E6=80=81=E5=BC=95?= =?UTF-8?q?=E8=B5=B7=E7=9A=84=E5=AF=BC=E5=85=A5=E5=AF=BC=E5=87=BA=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E5=8F=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/resources/excel/house_export.xlsx | Bin 11453 -> 10570 bytes .../main/resources/excel/house_template.xlsx | Bin 10458 -> 9581 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/epmet-module/gov-org/gov-org-server/src/main/resources/excel/house_export.xlsx b/epmet-module/gov-org/gov-org-server/src/main/resources/excel/house_export.xlsx index 9460a651dab7de2c80bb9af0fb3d65f06b3d94ee..815e222273064b3f0651c75516a1a48211948211 100644 GIT binary patch literal 10570 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 ZyVr73;LlYIAW5JC#RK-7Mg08N{{Y8v8-4%) literal 11453 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 diff --git a/epmet-module/gov-org/gov-org-server/src/main/resources/excel/house_template.xlsx b/epmet-module/gov-org/gov-org-server/src/main/resources/excel/house_template.xlsx index 027f37bcad185979d8358f47b5fdff58f2264a32..0f58eff1d818ecc93cc9e8a4737978f4e447e075 100644 GIT binary patch delta 6758 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