|
@@ -0,0 +1,246 @@
|
|
|
|
+package com.nokia.finance.tasks.jobs.house;
|
|
|
|
+
|
|
|
|
+import com.nokia.finance.tasks.common.exception.MyRuntimeException;
|
|
|
|
+import com.nokia.finance.tasks.config.HouseReportConfig;
|
|
|
|
+import com.nokia.finance.tasks.dao.house.HouseReportDao;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseBuildingHighSporadicRepairPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseBuildingIdleStrategyPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseBuildingSameRepairFrequencyPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseBuildingStatPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseFangWuWeiXiuZongTiQingKuangPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseNoticesPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseRentOutIncomeStatPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.po.house_report.HouseReportsPo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseCqqfczhtjkclVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseDelxwxjkclVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseDeqfczhtjkclVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseFcczztqkVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseFczyztsyxlTableVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseFczyztsyxlVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseFwwxztqkVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseFwxzjzmjjkclVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseGpwxjkclVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HousePjczdjhlxclVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseReportVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseZyztqkTableVo;
|
|
|
|
+import com.nokia.finance.tasks.pojo.vo.house_report.HouseZyztqkVo;
|
|
|
|
+import com.nokia.finance.tasks.service.common.file.FileService;
|
|
|
|
+import com.nokia.finance.tasks.utils.OfficeUtil;
|
|
|
|
+import com.nokia.finance.tasks.utils.ZipUtil;
|
|
|
|
+import freemarker.template.Configuration;
|
|
|
|
+import freemarker.template.Template;
|
|
|
|
+import freemarker.template.TemplateException;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import org.apache.commons.text.StringSubstitutor;
|
|
|
|
+import org.springframework.scheduling.annotation.Scheduled;
|
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
|
+
|
|
|
|
+import java.io.BufferedWriter;
|
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
|
+import java.io.File;
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.nio.file.Files;
|
|
|
|
+import java.nio.file.Path;
|
|
|
|
+import java.nio.file.Paths;
|
|
|
|
+import java.time.LocalDate;
|
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.HashMap;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.Map;
|
|
|
|
+
|
|
|
|
+/**
|
|
|
|
+ * 不动产报告定时任务
|
|
|
|
+ */
|
|
|
|
+@Slf4j
|
|
|
|
+@Service
|
|
|
|
+public class HouseReportJob {
|
|
|
|
+ private final HouseReportConfig houseReportConfig;
|
|
|
|
+ private final HouseReportDao houseReportDao;
|
|
|
|
+ private final FileService fileService;
|
|
|
|
+
|
|
|
|
+ public HouseReportJob(HouseReportConfig houseReportConfig, HouseReportDao houseReportDao, FileService fileService) {
|
|
|
|
+ this.houseReportConfig = houseReportConfig;
|
|
|
|
+ this.houseReportDao = houseReportDao;
|
|
|
|
+ this.fileService = fileService;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 执行任务
|
|
|
|
+ */
|
|
|
|
+ @Scheduled(cron = "0 35 0 13 * ?")
|
|
|
|
+ @Transactional(timeout = 300, rollbackFor = Exception.class)
|
|
|
|
+ public void runJob() {
|
|
|
|
+ try {
|
|
|
|
+ log.info("执行不动产报告定时任务");
|
|
|
|
+ HouseReportVo vo = getReportVo();
|
|
|
|
+ // 生成docx
|
|
|
|
+ generateDocx(vo);
|
|
|
|
+ // 生成pdf
|
|
|
|
+ OfficeUtil.toPdf(houseReportConfig.getOutDir(), houseReportConfig.getDocx(), 1L);
|
|
|
|
+ // 上传文件
|
|
|
|
+ upload(vo);
|
|
|
|
+ // 更新公告
|
|
|
|
+ updateNotices(vo);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
|
+ throw new MyRuntimeException("不动产报告定时任务失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public HouseReportVo getReportVo() {
|
|
|
|
+ LocalDate localDateNow = LocalDate.now();
|
|
|
|
+ LocalDate localDateEnd = localDateNow.minusMonths(1);
|
|
|
|
+ LocalDate localDateStart = localDateEnd.withDayOfYear(1);
|
|
|
|
+ Integer endYearMonth = Integer.valueOf(localDateEnd.format(DateTimeFormatter.ofPattern("yyyyMM")));
|
|
|
|
+ Integer startYearMonth = Integer.valueOf(localDateStart.format(DateTimeFormatter.ofPattern("yyyyMM")));
|
|
|
|
+ Integer endMonth = localDateEnd.getMonthValue();
|
|
|
|
+ HouseReportVo vo = new HouseReportVo();
|
|
|
|
+ vo.setReportYear(String.valueOf(localDateEnd.getYear()));
|
|
|
|
+ vo.setReportMonth(String.valueOf(endMonth));
|
|
|
|
+ vo.setCurrentYear(String.valueOf(localDateNow.getYear()));
|
|
|
|
+ vo.setCurrentMonth(String.valueOf(localDateNow.getMonthValue()));
|
|
|
|
+ vo.setEndYearMonth(endYearMonth);
|
|
|
|
+ // 资源总体情况、房产资源总体使用效率
|
|
|
|
+ List<HouseBuildingStatPo> houseBuildingStatPoList = houseReportDao.getBuildingStat(endYearMonth);
|
|
|
|
+ vo.setZyztqk(new HouseZyztqkVo(houseBuildingStatPoList));
|
|
|
|
+ vo.setFczyztsyxl(new HouseFczyztsyxlVo(houseBuildingStatPoList));
|
|
|
|
+ // todo: 房产出租总体情况
|
|
|
|
+ List<HouseRentOutIncomeStatPo> houseRentOutIncomeStatPoList = houseReportDao.getRentOutIncomeStat(endYearMonth);
|
|
|
|
+ vo.setFcczztqk(new HouseFcczztqkVo(houseRentOutIncomeStatPoList));
|
|
|
|
+ // todo: 房屋维修总体情况
|
|
|
|
+ List<HouseFangWuWeiXiuZongTiQingKuangPo> fangWuWeiXiuZongTiQingKuangPoList = houseReportDao.fwwxztqk(endYearMonth);
|
|
|
|
+ vo.setFwwxztqk(new HouseFwwxztqkVo(fangWuWeiXiuZongTiQingKuangPoList));
|
|
|
|
+ // 房屋闲置建筑面积监控策略
|
|
|
|
+ List<HouseBuildingIdleStrategyPo> houseBuildingIdleStrategyPoList
|
|
|
|
+ = houseReportDao.getBuildingIdleStrategy(endYearMonth);
|
|
|
|
+ vo.setFwxzjzmjjkcl(new HouseFwxzjzmjjkclVo(houseBuildingIdleStrategyPoList));
|
|
|
|
+ // todo: 长期欠费出租合同监控策略
|
|
|
|
+ vo.setCqqfczhtjkcl(new HouseCqqfczhtjkclVo());
|
|
|
|
+ // todo: 大额欠费出租合同监控策略
|
|
|
|
+ vo.setDeqfczhtjkcl(new HouseDeqfczhtjkclVo());
|
|
|
|
+ // 大额零星维修监控策略
|
|
|
|
+ List<HouseBuildingHighSporadicRepairPo> houseBuildingHighSporadicRepairPoList
|
|
|
|
+ = houseReportDao.getBuildingHighSporadicRepair(endYearMonth);
|
|
|
|
+ vo.setDelxwxjkcl(new HouseDelxwxjkclVo(houseBuildingHighSporadicRepairPoList));
|
|
|
|
+ // 高频维修监控策略
|
|
|
|
+ List<HouseBuildingSameRepairFrequencyPo> houseBuildingSameRepairFrequencyPoList
|
|
|
|
+ = houseReportDao.getBuildingSameRepairFrequency(endYearMonth);
|
|
|
|
+ vo.setGpwxjkcl(new HouseGpwxjkclVo(houseBuildingSameRepairFrequencyPoList));
|
|
|
|
+ // todo: 平均出租单价合理性策略
|
|
|
|
+ vo.setPjczhlxcl(new HousePjczdjhlxclVo());
|
|
|
|
+ return vo;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 生成docx
|
|
|
|
+ */
|
|
|
|
+ public void generateDocx(HouseReportVo vo) throws IOException, TemplateException {
|
|
|
|
+ Configuration configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
|
|
|
|
+ configuration.setDefaultEncoding(StandardCharsets.UTF_8.name());
|
|
|
|
+ configuration.setDirectoryForTemplateLoading(new File(houseReportConfig.getFtlDir()));
|
|
|
|
+ // 生成document.xml
|
|
|
|
+ try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(houseReportConfig.getDocumentXml()),
|
|
|
|
+ StandardCharsets.UTF_8)) {
|
|
|
|
+ Template template = configuration.getTemplate(houseReportConfig.getDocumentFtl(),
|
|
|
|
+ StandardCharsets.UTF_8.name());
|
|
|
|
+ template.process(vo, writer);
|
|
|
|
+ }
|
|
|
|
+ Files.createDirectories(Paths.get(houseReportConfig.getOutDir()));
|
|
|
|
+ Path inputDir = Paths.get(houseReportConfig.getDocxDir());
|
|
|
|
+ Path outputFile = Paths.get(houseReportConfig.getDocx());
|
|
|
|
+ ZipUtil.zipDirNonSelf(inputDir, outputFile);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 上传文件
|
|
|
|
+ */
|
|
|
|
+ public void upload(HouseReportVo vo) throws IOException {
|
|
|
|
+ Integer endYearMonth = vo.getEndYearMonth();
|
|
|
|
+ houseReportDao.deleteHouseReports(endYearMonth);
|
|
|
|
+ List<HouseReportsPo> list = new ArrayList<>();
|
|
|
|
+ byte[] bytes = Files.readAllBytes(Paths.get(houseReportConfig.getDocx()));
|
|
|
|
+ long objectSize = bytes.length;
|
|
|
|
+ String object = "oss/reports/house/" + endYearMonth + ".docx";
|
|
|
|
+ fileService.putObject(object, new ByteArrayInputStream(bytes), objectSize, null);
|
|
|
|
+ HouseReportsPo po1 = new HouseReportsPo();
|
|
|
|
+ po1.setYearMonth(endYearMonth);
|
|
|
|
+ po1.setFileType("word");
|
|
|
|
+ po1.setUrl(object);
|
|
|
|
+ list.add(po1);
|
|
|
|
+ bytes = Files.readAllBytes(Paths.get(houseReportConfig.getPdf()));
|
|
|
|
+ objectSize = bytes.length;
|
|
|
|
+ object = "oss/reports/house/" + endYearMonth + ".pdf";
|
|
|
|
+ fileService.putObject(object, new ByteArrayInputStream(bytes), objectSize, null);
|
|
|
|
+ HouseReportsPo po2 = new HouseReportsPo();
|
|
|
|
+ po2.setYearMonth(endYearMonth);
|
|
|
|
+ po2.setFileType("pdf");
|
|
|
|
+ po2.setUrl(object);
|
|
|
|
+ list.add(po2);
|
|
|
|
+ int updateCount = houseReportDao.insertBatchHouseReports(list);
|
|
|
|
+ if (updateCount == 0) {
|
|
|
|
+ throw new MyRuntimeException("插入house.house_reports失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 更新公告
|
|
|
|
+ */
|
|
|
|
+ public void updateNotices(HouseReportVo vo) {
|
|
|
|
+ Integer endYearMonth = vo.getEndYearMonth();
|
|
|
|
+ houseReportDao.deleteHouseNotices(endYearMonth);
|
|
|
|
+ List<HouseNoticesPo> list = new ArrayList<>();
|
|
|
|
+ Map<String, String> map = new HashMap<>();
|
|
|
|
+ StringSubstitutor substitutor = new StringSubstitutor(map);
|
|
|
|
+ String template = "截止报告期,全省共有房产建筑物${fcsl}处,建筑面积${zmj}万平方米,原值${zcyz}亿元。其中核心商圈建筑面积${hxsq}万平方米,一般商圈${ybsq}万平方米。";
|
|
|
|
+ map.put("fcsl", vo.getZyztqk().getFcsl());
|
|
|
|
+ map.put("zmj", vo.getZyztqk().getZmj());
|
|
|
|
+ map.put("zcyz", vo.getZyztqk().getZcyz());
|
|
|
|
+ map.put("hxsq", vo.getZyztqk().getHxsq());
|
|
|
|
+ map.put("ybsq", vo.getZyztqk().getYbsq());
|
|
|
|
+ list.add(new HouseNoticesPo(endYearMonth, substitutor.replace(template)));
|
|
|
|
+ map.clear();
|
|
|
|
+ template = "全省房屋数量及建筑面积排名前5位的为${jzmjTopUnit},房屋建筑面积均超${jzmjTopMin}万平方米,合计占全省房屋建筑面积${jzmjTopPercent}。";
|
|
|
|
+ map.put("jzmjTopUnit", vo.getZyztqk().getJzmjTopUnit());
|
|
|
|
+ map.put("jzmjTopMin", vo.getZyztqk().getJzmjTopMin());
|
|
|
|
+ map.put("jzmjTopPercent", vo.getZyztqk().getJzmjTopPercent());
|
|
|
|
+ list.add(new HouseNoticesPo(endYearMonth, substitutor.replace(template)));
|
|
|
|
+ map.clear();
|
|
|
|
+ template = "全省房屋建筑面积闲置率超过20%的单位有${xzlGtCount}个,其中${xzlMaxUnit}闲置率较高,接近${xzlMaxPercent},对闲置率较高的单位可加大房产盘活力度。";
|
|
|
|
+ map.put("xzlGtCount", vo.getFczyztsyxl().getXzlGtCount());
|
|
|
|
+ map.put("xzlMaxUnit", vo.getFczyztsyxl().getXzlMaxUnit());
|
|
|
|
+ map.put("xzlMaxPercent", vo.getFczyztsyxl().getXzlMaxPercent());
|
|
|
|
+ list.add(new HouseNoticesPo(endYearMonth, substitutor.replace(template)));
|
|
|
|
+ map.clear();
|
|
|
|
+ for (HouseZyztqkTableVo t : vo.getZyztqk().getTable()) {
|
|
|
|
+ if ("合计".equals(t.getAreaName())) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ template = "截止报告期,${areaName}共有房产建筑物${fcsl}处,建筑面积${zmj}万平方米,原值${zcyz}亿元。其中核心商圈建筑面积${hxsq}万平方米,一般商圈${ybsq}万平方米。";
|
|
|
|
+ map.put("areaName", t.getAreaName());
|
|
|
|
+ map.put("fcsl", t.getFcsl());
|
|
|
|
+ map.put("zmj", t.getZmj());
|
|
|
|
+ map.put("zcyz", t.getZcyz());
|
|
|
|
+ map.put("hxsq", t.getHxsq());
|
|
|
|
+ map.put("ybsq", t.getYbsq());
|
|
|
|
+ list.add(new HouseNoticesPo(endYearMonth, t.getAreaName(), substitutor.replace(template)));
|
|
|
|
+ map.clear();
|
|
|
|
+ }
|
|
|
|
+ for (HouseFczyztsyxlTableVo t : vo.getFczyztsyxl().getTable()) {
|
|
|
|
+ if ("合计".equals(t.getAreaName())) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ template = "${areaName}建筑面积闲置率为${xzl}。";
|
|
|
|
+ map.put("areaName", t.getAreaName());
|
|
|
|
+ map.put("xzl", t.getXzl());
|
|
|
|
+ list.add(new HouseNoticesPo(endYearMonth, t.getAreaName(), substitutor.replace(template)));
|
|
|
|
+ map.clear();
|
|
|
|
+ }
|
|
|
|
+ int updateCount = houseReportDao.insertBatchHouseNotices(list);
|
|
|
|
+ if (updateCount == 0) {
|
|
|
|
+ throw new MyRuntimeException("插入house.notices失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|