| | |
| | | if (sys == null) return null; // 缺失由 EXISTENCE_SYS 规则提示 |
| | | String field = rule.getCheckField(); |
| | | double actual; |
| | | double reference; |
| | | Double referenceObj; |
| | | String fieldName; |
| | | if ("startCum".equals(field)) { |
| | | actual = nvl(monthly.getStartCum()); |
| | | reference = nvl(sys.getStartCum()); |
| | | referenceObj = sys.getStartCum(); |
| | | fieldName = "自开始建设累计"; |
| | | } else if ("yearCum".equals(field)) { |
| | | actual = nvl(monthly.getYearCum()); |
| | | reference = nvl(sys.getYearCum()); |
| | | referenceObj = sys.getYearCum(); |
| | | fieldName = "自年初累计"; |
| | | } else if ("monthDone".equals(field)) { |
| | | actual = nvl(monthly.getMonthDone()); |
| | | reference = nvl(sys.getMonthDone()); |
| | | referenceObj = sys.getMonthDone(); |
| | | fieldName = "本月完成"; |
| | | } else { |
| | | return null; |
| | | } |
| | | // 基准缺失(如新模板《2026年X月投资系统项目明细》没有「自年初累计」列)→ 不具备可比性,跳过并记日志; |
| | | // 不能把 null 当成 0 去比对,否则会成片误报。 |
| | | if (referenceObj == null) { |
| | | log.warn("投资比对跳过(投资系统基准缺失):rule={} project={} field={}", rule.getRuleCode(), projectName, fieldName); |
| | | return null; |
| | | } |
| | | double reference = referenceObj; |
| | | String[] parts = rule.getThreshold().split("\\|"); |
| | | double absThreshold = parts.length > 0 ? parseDoubleSafe(parts[0], 50) : 50; |
| | | double pctThreshold = parts.length > 1 ? parseDoubleSafe(parts[1], 5) : 5; |
| | |
| | | |
| | | public List<AuditResult> queryResults(String reportPeriod, String reportType) { |
| | | String type = reportType == null || reportType.trim().isEmpty() ? "H2032" : reportType.trim(); |
| | | List<AuditRule> rules = ruleMapper.selectList(new LambdaQueryWrapper<AuditRule>() |
| | | .eq(AuditRule::getReportType, type)); |
| | | if (rules.isEmpty()) return new java.util.ArrayList<>(); |
| | | List<Long> ruleIds = new ArrayList<>(); |
| | | for (AuditRule rule : rules) ruleIds.add(rule.getId()); |
| | | List<AuditResult> results = resultMapper.selectList(new LambdaQueryWrapper<AuditResult>() |
| | | .eq(AuditResult::getReportPeriod, reportPeriod) |
| | | .in(AuditResult::getRuleId, ruleIds) |
| | | .orderByAsc(AuditResult::getId)); |
| | | List<Long> ruleIds = new ArrayList<>(); |
| | | for (AuditRule rule : ruleMapper.selectList(null)) { |
| | | if (type.equals(rule.getReportType())) ruleIds.add(rule.getId()); |
| | | } |
| | | List<AuditResult> filtered = new ArrayList<>(); |
| | | for (AuditResult result : results) { |
| | | if (ruleIds.contains(result.getRuleId())) filtered.add(result); |
| | | } |
| | | attachInfo(filtered); |
| | | return filtered; |
| | | attachInfo(results, type, reportPeriod); |
| | | return results; |
| | | } |
| | | |
| | | public void reviewResult(Long id, String status, String comment) { |
| | |
| | | resultMapper.updateById(result); |
| | | } |
| | | |
| | | private void attachInfo(List<AuditResult> results) { |
| | | private void attachInfo(List<AuditResult> results, String type, String period) { |
| | | if (results.isEmpty()) return; |
| | | Map<Long, AuditRule> ruleMap = new HashMap<>(); |
| | | for (AuditRule rule : ruleMapper.selectList(null)) ruleMap.put(rule.getId(), rule); |
| | | Map<Long, String> h2032Name = new HashMap<>(); |
| | | Map<Long, String> h2032Explain = new HashMap<>(); |
| | | Map<Long, String> passengerName = new HashMap<>(); |
| | | Map<Long, String> passengerExplain = new HashMap<>(); |
| | | Map<Long, String> energyName = new HashMap<>(); |
| | | Map<Long, String> investName = new HashMap<>(); |
| | | Map<Long, String> busName = new HashMap<>(); |
| | | Map<Long, String> busExplain = new HashMap<>(); |
| | | Map<Long, String> taxiName = new HashMap<>(); |
| | | Map<Long, String> taxiExplain = new HashMap<>(); |
| | | for (H2032EnterpriseMonthly r : h2032Mapper.selectList(null)) { |
| | | h2032Name.putIfAbsent(r.getId(), r.getEnterpriseName()); |
| | | h2032Explain.putIfAbsent(r.getId(), r.getVerifyExplanation()); |
| | | for (AuditRule rule : ruleMapper.selectList(new LambdaQueryWrapper<AuditRule>() |
| | | .eq(AuditRule::getReportType, type))) { |
| | | ruleMap.put(rule.getId(), rule); |
| | | } |
| | | for (PassengerEnterpriseMonthly r : passengerMapper.selectList(null)) { |
| | | passengerName.putIfAbsent(r.getId(), r.getEnterpriseName()); |
| | | passengerExplain.putIfAbsent(r.getId(), r.getVerifyExplanation()); |
| | | } |
| | | for (EnergyVehicleQuarterly r : energyMapper.selectList(null)) { |
| | | energyName.putIfAbsent(r.getId(), r.getEnterpriseName()); |
| | | } |
| | | for (CityBusMonthly r : cityBusMapper.selectList(null)) { |
| | | busName.putIfAbsent(r.getId(), r.getEnterpriseName()); |
| | | busExplain.putIfAbsent(r.getId(), r.getVerifyExplanation()); |
| | | } |
| | | for (CityTaxiMonthly r : cityTaxiMapper.selectList(null)) { |
| | | taxiName.putIfAbsent(r.getId(), r.getCity()); |
| | | taxiExplain.putIfAbsent(r.getId(), r.getVerifyExplanation()); |
| | | } |
| | | Map<Long, Long> investProjectId = new HashMap<>(); |
| | | for (InvestmentMonthly r : investMonthlyMapper.selectList(null)) { |
| | | investProjectId.putIfAbsent(r.getId(), r.getProjectId()); |
| | | } |
| | | for (InvestmentProject p : investProjectMapper.selectList(null)) { |
| | | for (Map.Entry<Long, Long> e : investProjectId.entrySet()) { |
| | | if (e.getValue().equals(p.getId())) investName.putIfAbsent(e.getKey(), p.getProjectName()); |
| | | Map<Long, String> nameMap = new HashMap<>(); |
| | | Map<Long, String> explainMap = new HashMap<>(); |
| | | if ("INVEST".equals(type)) { |
| | | Map<Long, Long> monthlyProject = new HashMap<>(); |
| | | for (InvestmentMonthly m : investMonthlyMapper.selectList(new LambdaQueryWrapper<InvestmentMonthly>() |
| | | .eq(InvestmentMonthly::getReportPeriod, period))) { |
| | | monthlyProject.put(m.getId(), m.getProjectId()); |
| | | } |
| | | for (InvestmentProject p : investProjectMapper.selectList(null)) { |
| | | for (Map.Entry<Long, Long> e : monthlyProject.entrySet()) { |
| | | if (e.getValue() != null && e.getValue().equals(p.getId())) { |
| | | nameMap.putIfAbsent(e.getKey(), p.getProjectName()); |
| | | } |
| | | } |
| | | } |
| | | } else if ("H204".equals(type)) { |
| | | for (EnergyVehicleQuarterly m : energyMapper.selectList(new LambdaQueryWrapper<EnergyVehicleQuarterly>() |
| | | .eq(EnergyVehicleQuarterly::getReportPeriod, period))) { |
| | | nameMap.putIfAbsent(m.getId(), m.getEnterpriseName()); |
| | | } |
| | | } else if ("H2031".equals(type)) { |
| | | for (PassengerEnterpriseMonthly m : passengerMapper.selectList(new LambdaQueryWrapper<PassengerEnterpriseMonthly>() |
| | | .eq(PassengerEnterpriseMonthly::getReportPeriod, period))) { |
| | | nameMap.putIfAbsent(m.getId(), m.getEnterpriseName()); |
| | | explainMap.putIfAbsent(m.getId(), m.getVerifyExplanation()); |
| | | } |
| | | } else if ("CITY_BUS".equals(type)) { |
| | | for (CityBusMonthly m : cityBusMapper.selectList(new LambdaQueryWrapper<CityBusMonthly>() |
| | | .eq(CityBusMonthly::getReportPeriod, period))) { |
| | | nameMap.putIfAbsent(m.getId(), m.getEnterpriseName()); |
| | | explainMap.putIfAbsent(m.getId(), m.getVerifyExplanation()); |
| | | } |
| | | } else if ("CITY_TAXI".equals(type)) { |
| | | for (CityTaxiMonthly m : cityTaxiMapper.selectList(new LambdaQueryWrapper<CityTaxiMonthly>() |
| | | .eq(CityTaxiMonthly::getReportPeriod, period))) { |
| | | nameMap.putIfAbsent(m.getId(), m.getCity()); |
| | | explainMap.putIfAbsent(m.getId(), m.getVerifyExplanation()); |
| | | } |
| | | } else { |
| | | for (H2032EnterpriseMonthly m : h2032Mapper.selectList(new LambdaQueryWrapper<H2032EnterpriseMonthly>() |
| | | .eq(H2032EnterpriseMonthly::getReportPeriod, period))) { |
| | | nameMap.putIfAbsent(m.getId(), m.getEnterpriseName()); |
| | | explainMap.putIfAbsent(m.getId(), m.getVerifyExplanation()); |
| | | } |
| | | } |
| | | for (AuditResult result : results) { |
| | |
| | | result.setRuleCode(rule.getRuleCode()); |
| | | result.setAlertLevel(rule.getAlertLevel()); |
| | | } |
| | | // 各报表表 id 各自独立自增,需按规则所属报表类型分表回填企业名称 |
| | | String type = rule == null ? null : rule.getReportType(); |
| | | Map<Long, String> nameMap = "INVEST".equals(type) ? investName |
| | | : "H204".equals(type) ? energyName |
| | | : "H2031".equals(type) ? passengerName |
| | | : "CITY_BUS".equals(type) ? busName |
| | | : "CITY_TAXI".equals(type) ? taxiName : h2032Name; |
| | | Map<Long, String> explainMap = "H2031".equals(type) ? passengerExplain |
| | | : "CITY_BUS".equals(type) ? busExplain |
| | | : "CITY_TAXI".equals(type) ? taxiExplain : h2032Explain; |
| | | String enterpriseName = nameMap.get(result.getReportId()); |
| | | if (enterpriseName == null) { |
| | | // 上报数据被重新导入后旧审核结果已失效,给出提示而非空白 |
| | | enterpriseName = "\uFF08\u539F\u6570\u636E\u5DF2\u91CD\u65B0\u5BFC\u5165\uFF0C\u8BF7\u91CD\u65B0\u6267\u884C\u5BA1\u6838\uFF09"; |
| | | enterpriseName = "(原数据已重新导入,请重新执行审核)"; |
| | | } |
| | | result.setEnterpriseName(enterpriseName); |
| | | result.setVerifyExplanation(explainMap.get(result.getReportId())); |
| | | } |
| | | } |
| | | |
| | | /** 最近有数据的报表期(用于前端默认选中) */ |
| | | public String latestPeriod(String reportType) { |
| | | String type = reportType == null || reportType.trim().isEmpty() ? "H2032" : reportType.trim(); |
| | | String max = null; |
| | | switch (type) { |
| | | case "H2031": |
| | | for (PassengerEnterpriseMonthly m : passengerMapper.selectList( |
| | | new LambdaQueryWrapper<PassengerEnterpriseMonthly>().select(PassengerEnterpriseMonthly::getReportPeriod))) { |
| | | max = maxPeriod(max, m.getReportPeriod()); |
| | | } |
| | | break; |
| | | return firstOf(passengerMapper.selectObjs(new LambdaQueryWrapper<PassengerEnterpriseMonthly>() |
| | | .select(PassengerEnterpriseMonthly::getReportPeriod) |
| | | .orderByDesc(PassengerEnterpriseMonthly::getReportPeriod).last("LIMIT 1"))); |
| | | case "H204": |
| | | for (EnergyVehicleQuarterly m : energyMapper.selectList( |
| | | new LambdaQueryWrapper<EnergyVehicleQuarterly>().select(EnergyVehicleQuarterly::getReportPeriod))) { |
| | | max = maxPeriod(max, m.getReportPeriod()); |
| | | } |
| | | break; |
| | | return firstOf(energyMapper.selectObjs(new LambdaQueryWrapper<EnergyVehicleQuarterly>() |
| | | .select(EnergyVehicleQuarterly::getReportPeriod) |
| | | .orderByDesc(EnergyVehicleQuarterly::getReportPeriod).last("LIMIT 1"))); |
| | | case "INVEST": |
| | | for (InvestmentMonthly m : investMonthlyMapper.selectList( |
| | | new LambdaQueryWrapper<InvestmentMonthly>().select(InvestmentMonthly::getReportPeriod))) { |
| | | max = maxPeriod(max, m.getReportPeriod()); |
| | | } |
| | | break; |
| | | return firstOf(investMonthlyMapper.selectObjs(new LambdaQueryWrapper<InvestmentMonthly>() |
| | | .select(InvestmentMonthly::getReportPeriod) |
| | | .orderByDesc(InvestmentMonthly::getReportPeriod).last("LIMIT 1"))); |
| | | case "CITY_BUS": |
| | | for (CityBusMonthly m : cityBusMapper.selectList( |
| | | new LambdaQueryWrapper<CityBusMonthly>().select(CityBusMonthly::getReportPeriod))) { |
| | | max = maxPeriod(max, m.getReportPeriod()); |
| | | } |
| | | break; |
| | | return firstOf(cityBusMapper.selectObjs(new LambdaQueryWrapper<CityBusMonthly>() |
| | | .select(CityBusMonthly::getReportPeriod) |
| | | .orderByDesc(CityBusMonthly::getReportPeriod).last("LIMIT 1"))); |
| | | case "CITY_TAXI": |
| | | for (CityTaxiMonthly m : cityTaxiMapper.selectList( |
| | | new LambdaQueryWrapper<CityTaxiMonthly>().select(CityTaxiMonthly::getReportPeriod))) { |
| | | max = maxPeriod(max, m.getReportPeriod()); |
| | | } |
| | | break; |
| | | return firstOf(cityTaxiMapper.selectObjs(new LambdaQueryWrapper<CityTaxiMonthly>() |
| | | .select(CityTaxiMonthly::getReportPeriod) |
| | | .orderByDesc(CityTaxiMonthly::getReportPeriod).last("LIMIT 1"))); |
| | | default: |
| | | for (H2032EnterpriseMonthly m : h2032Mapper.selectList( |
| | | new LambdaQueryWrapper<H2032EnterpriseMonthly>().select(H2032EnterpriseMonthly::getReportPeriod))) { |
| | | max = maxPeriod(max, m.getReportPeriod()); |
| | | } |
| | | break; |
| | | return firstOf(h2032Mapper.selectObjs(new LambdaQueryWrapper<H2032EnterpriseMonthly>() |
| | | .select(H2032EnterpriseMonthly::getReportPeriod) |
| | | .orderByDesc(H2032EnterpriseMonthly::getReportPeriod).last("LIMIT 1"))); |
| | | } |
| | | return max; |
| | | } |
| | | |
| | | private String firstOf(List<Object> objs) { |
| | | if (objs == null || objs.isEmpty() || objs.get(0) == null) return null; |
| | | String v = String.valueOf(objs.get(0)); |
| | | return v.trim().isEmpty() ? null : v.trim(); |
| | | } |
| | | |
| | | private String maxPeriod(String a, String b) { |
| | |
| | | return a; |
| | | } |
| | | |
| | | /** 审核结果导出 Excel(含企业名/规则名/状态/审核意见) */ |
| | | /** 审核结果导出 Excel(两 Sheet,按业务模板):Sheet1 审核结果(逐条明细);Sheet2 企业合并(按企业汇总 + 问题列) */ |
| | | public byte[] exportResults(String reportPeriod, String reportType) throws Exception { |
| | | return exportResults(reportPeriod, reportType, true, "all"); |
| | | } |
| | | |
| | | /** onlyVerify=true 时剔除“提醒型”规则(如 RULE_004 环比提醒),只保留核实型问题;status=all/pending/handled 与界面“状态”筛选一致 */ |
| | | public byte[] exportResults(String reportPeriod, String reportType, boolean onlyVerify, String status) throws Exception { |
| | | List<AuditResult> results = queryResults(reportPeriod, reportType); |
| | | java.util.List<AuditResult> filtered = new java.util.ArrayList<>(); |
| | | String st = status == null ? "all" : status.trim(); |
| | | for (AuditResult res : results) { |
| | | if (onlyVerify && isReminderRule(res.getRuleCode())) continue; |
| | | if ("pending".equals(st) && !"PENDING".equals(res.getStatus())) continue; |
| | | if ("handled".equals(st) && (res.getStatus() == null || "PENDING".equals(res.getStatus()))) continue; |
| | | filtered.add(res); |
| | | } |
| | | try (XSSFWorkbook wb = new XSSFWorkbook()) { |
| | | // ---------- Sheet1 审核结果(逐条,列与业务模板一致) ---------- |
| | | Sheet sheet = wb.createSheet("审核结果"); |
| | | String[] headers = {"报表期", "企业/市州", "规则编码", "审核规则", "等级", "实际值", "阈值/基准", "偏差说明", "状态", "审核意见"}; |
| | | Row head = sheet.createRow(0); |
| | | for (int i = 0; i < headers.length; i++) { |
| | | Cell cell = head.createCell(i); |
| | | cell.setCellValue(headers[i]); |
| | | org.apache.poi.ss.usermodel.CellStyle style = wb.createCellStyle(); |
| | | org.apache.poi.ss.usermodel.Font font = wb.createFont(); |
| | | font.setBold(true); |
| | | style.setFont(font); |
| | | cell.setCellStyle(style); |
| | | } |
| | | writeAuditHeader(sheet, headers); |
| | | int r = 1; |
| | | for (AuditResult res : results) { |
| | | for (AuditResult res : filtered) { |
| | | Row row = sheet.createRow(r++); |
| | | row.createCell(0).setCellValue(valueOf(res.getReportPeriod())); |
| | | row.createCell(1).setCellValue(valueOf(res.getEnterpriseName())); |
| | |
| | | for (int i = 0; i < widths.length; i++) { |
| | | sheet.setColumnWidth(i, widths[i] * 256); |
| | | } |
| | | |
| | | // ---------- Sheet2 企业合并(同一企业多条规则并排列出 + 问题汇总列) ---------- |
| | | Sheet ms = wb.createSheet("企业合并"); |
| | | String[] h2 = {"报表期", "企业/市州", "审核规则", "实际值", "阈值/基准", "偏差说明", "问题"}; |
| | | writeAuditHeader(ms, h2); |
| | | java.util.LinkedHashMap<String, java.util.List<AuditResult>> groups = new java.util.LinkedHashMap<>(); |
| | | for (AuditResult res : filtered) { |
| | | String key = valueOf(res.getEnterpriseName()); |
| | | if (key.isEmpty()) key = valueOf(res.getReportPeriod()) + "#" + valueOf(res.getActualValue()); |
| | | groups.computeIfAbsent(key, k -> new java.util.ArrayList<>()).add(res); |
| | | } |
| | | int rowCursor = 1; |
| | | for (java.util.Map.Entry<String, java.util.List<AuditResult>> e : groups.entrySet()) { |
| | | java.util.List<AuditResult> items = e.getValue(); |
| | | int groupStart = rowCursor; |
| | | StringBuilder problems = new StringBuilder(); |
| | | int seq = 0; |
| | | for (AuditResult it : items) { |
| | | Row row = ms.createRow(rowCursor++); |
| | | if (seq == 0) { |
| | | row.createCell(0).setCellValue(valueOf(it.getReportPeriod())); |
| | | row.createCell(1).setCellValue(valueOf(it.getEnterpriseName()).isEmpty() ? e.getKey() : valueOf(it.getEnterpriseName())); |
| | | } |
| | | row.createCell(2).setCellValue(valueOf(it.getRuleName())); |
| | | row.createCell(3).setCellValue(valueOf(it.getActualValue())); |
| | | row.createCell(4).setCellValue(valueOf(it.getThresholdValue())); |
| | | row.createCell(5).setCellValue(valueOf(it.getDeviation())); |
| | | seq++; |
| | | if (problems.length() > 0) problems.append("\n"); |
| | | problems.append(seq).append("、").append(issueSentence(it)); |
| | | } |
| | | if (rowCursor - groupStart > 1) { |
| | | ms.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(groupStart, rowCursor - 1, 1, 1)); |
| | | ms.addMergedRegion(new org.apache.poi.ss.util.CellRangeAddress(groupStart, rowCursor - 1, 6, 6)); |
| | | } |
| | | Row first = ms.getRow(groupStart); |
| | | if (first.getCell(6) == null) first.createCell(6); |
| | | first.getCell(6).setCellValue(problems.toString()); |
| | | } |
| | | int[] widths2 = {12, 30, 22, 34, 22, 34, 60}; |
| | | for (int i = 0; i < widths2.length; i++) { |
| | | ms.setColumnWidth(i, widths2[i] * 256); |
| | | } |
| | | ByteArrayOutputStream out = new ByteArrayOutputStream(); |
| | | wb.write(out); |
| | | return out.toByteArray(); |
| | | } |
| | | } |
| | | |
| | | private void writeAuditHeader(Sheet sheet, String[] headers) { |
| | | Row head = sheet.createRow(0); |
| | | for (int i = 0; i < headers.length; i++) { |
| | | Cell cell = head.createCell(i); |
| | | cell.setCellValue(headers[i]); |
| | | org.apache.poi.ss.usermodel.CellStyle style = sheet.getWorkbook().createCellStyle(); |
| | | org.apache.poi.ss.usermodel.Font font = sheet.getWorkbook().createFont(); |
| | | font.setBold(true); |
| | | style.setFont(font); |
| | | cell.setCellStyle(style); |
| | | } |
| | | } |
| | | |
| | | /** 提醒型规则:仅提示变化、不需人工核实(如 RULE_004 货运类型环比提醒) */ |
| | | private boolean isReminderRule(String ruleCode) { |
| | | return "RULE_004".equals(ruleCode); |
| | | } |
| | | |
| | | /** 企业合并“问题”列话术:按规则类型生成可读的核实意见 */ |
| | | private String issueSentence(AuditResult res) { |
| | | String code = res.getRuleCode(); |
| | | String name = valueOf(res.getRuleName()); |
| | | String act = valueOf(res.getActualValue()); |
| | | if ("RULE_001".equals(code) || "RULE_002".equals(code)) { |
| | | return "企业上报车辆/吨位与运政数据对比存在差异(" + act + "),请核实"; |
| | | } |
| | | if ("RULE_003".equals(code)) { |
| | | return "上报周转量与轨迹测算周转量差异明显(" + act + "),请参考轨迹核实企业周转量"; |
| | | } |
| | | if ("RULE_004".equals(code)) { |
| | | return "货运类型环比发生变化" + (act.isEmpty() ? "" : "(" + act + ")") + ",请关注是否填报正常"; |
| | | } |
| | | if ("RULE_005".equals(code)) { |
| | | return "无集装箱车但存在集装箱货运量(" + act + "),请核实车辆类型与货运量填报"; |
| | | } |
| | | if ("RULE_006".equals(code)) { |
| | | return "整车平均吨位超出合理范围(" + act + "),请核实平均吨位填报"; |
| | | } |
| | | if (code != null && code.startsWith("RULE_P")) { |
| | | String special = passengerIssueSentence(res); |
| | | if (special != null) return special; |
| | | } |
| | | return name + "异常(" + act + "),请核实"; |
| | | } |
| | | |
| | | /** 客运(H2031)规则问题话术:贴合模板示例“核实异常(上期指标=,本期指标=)请核实” */ |
| | | private String passengerIssueSentence(AuditResult res) { |
| | | String code = res.getRuleCode(); |
| | | String act = valueOf(res.getActualValue()); |
| | | if ("RULE_P003".equals(code) || "RULE_P004".equals(code)) { |
| | | boolean turnover = "RULE_P004".equals(code); |
| | | String inner = act; |
| | | if (inner.startsWith("本月与上月相同: ")) { |
| | | inner = inner.substring("本月与上月相同: ".length()); |
| | | } |
| | | java.util.List<String> clauses = new java.util.ArrayList<>(); |
| | | for (String item : inner.split("、")) { |
| | | int eq = item.indexOf('='); |
| | | if (eq <= 0) { clauses.add(item); continue; } |
| | | String label = item.substring(0, eq).trim(); |
| | | String v = item.substring(eq + 1).trim(); |
| | | clauses.add("上月" + (turnover ? "周转量" : "客运量") + "=" + v + ",本月" + label + "=" + v); |
| | | } |
| | | return valueOf(res.getRuleName()) + "异常(" + String.join(";", clauses) + ")请核实"; |
| | | } |
| | | if ("RULE_P005".equals(code)) { |
| | | String pct = extractPct(valueOf(res.getThresholdValue())); |
| | | String prefix = pct.isEmpty() ? "班线平均运距环比超限" : "班线平均运距环比超±" + pct + "%"; |
| | | return prefix + ",正常班线运距在线路未发生重大变化前较为稳定(" + act + "),请核实"; |
| | | } |
| | | if ("RULE_P006".equals(code)) { |
| | | String inner = act; |
| | | if (inner.startsWith("等于上月: ")) { |
| | | inner = inner.substring("等于上月: ".length()); |
| | | } |
| | | java.util.List<String> clauses = new java.util.ArrayList<>(); |
| | | for (String item : inner.split("、")) { |
| | | int eq = item.indexOf('='); |
| | | if (eq <= 0) { clauses.add(item); continue; } |
| | | String v = item.substring(eq + 1).trim(); |
| | | clauses.add("上月运距=" + v + ",本月运距=" + v); |
| | | } |
| | | return "包车平均运距等于上月(" + String.join(";", clauses) |
| | | + ")请核实企业是否是固定线路旅游或者通勤业务"; |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | private String extractPct(String thresholdText) { |
| | | if (thresholdText == null || thresholdText.isEmpty()) return ""; |
| | | int idx = thresholdText.indexOf('\u00b1'); |
| | | if (idx < 0) return ""; |
| | | StringBuilder num = new StringBuilder(); |
| | | for (int i = idx + 1; i < thresholdText.length(); i++) { |
| | | char c = thresholdText.charAt(i); |
| | | if (Character.isDigit(c) || c == '.') num.append(c); |
| | | else if (!Character.isWhitespace(c)) break; |
| | | } |
| | | return num.toString(); |
| | | } |
| | | |
| | | private String auditStatusCn(String status) { |
| | | if ("CONFIRMED".equals(status)) return "已确认"; |
| | | if ("IGNORED".equals(status)) return "已忽略"; |