| | |
| | | |
| | | import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
| | | import com.trafficaudit.auditengine.entity.AuditResult; |
| | | import com.trafficaudit.auditengine.entity.AuditRun; |
| | | import com.trafficaudit.auditengine.mapper.AuditResultMapper; |
| | | import com.trafficaudit.auditengine.mapper.AuditRunMapper; |
| | | import com.trafficaudit.common.util.RegionUtil; |
| | | import com.trafficaudit.dataimport.entity.EnergyAuthVehicle; |
| | | import com.trafficaudit.dataimport.entity.EnergyVehicleQuarterly; |
| | |
| | | import org.apache.poi.ss.usermodel.WorkbookFactory; |
| | | import cn.hutool.core.io.IoUtil; |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | import org.springframework.web.multipart.MultipartFile; |
| | | |
| | | import javax.annotation.Resource; |
| | |
| | | private FreightTurnoverImportMapper freightTurnoverMapper; |
| | | @Resource |
| | | private AuditResultMapper auditResultMapper; |
| | | @Resource |
| | | private AuditRunMapper auditRunMapper; |
| | | @Resource |
| | | private PassengerEnterpriseMonthlyMapper passengerMapper; |
| | | @Resource |
| | |
| | | } |
| | | } |
| | | |
| | | /** 支持“按类型清空”的数据类型 -> 数据表操作键(同表同类别归并,避免重复删除) */ |
| | | private static final Map<String, String> CLEAR_TYPE_TO_OP = new LinkedHashMap<>(); |
| | | /** 数据类型 -> 关联审核规则类型(同步清除审核结果与已审核标记) */ |
| | | private static final Map<String, String[]> CLEAR_TYPE_TO_AUDIT = new HashMap<>(); |
| | | /** 数据类型 -> 关联导入批次 importType(同步清除导入批次记录) */ |
| | | private static final Map<String, String[]> CLEAR_TYPE_TO_BATCH = new HashMap<>(); |
| | | |
| | | static { |
| | | CLEAR_TYPE_TO_OP.put("h2032", "H2032"); |
| | | CLEAR_TYPE_TO_OP.put("transportAuth", "TRANSPORT_AUTH"); |
| | | CLEAR_TYPE_TO_OP.put("trackMileage", "TRACK_MILEAGE"); |
| | | CLEAR_TYPE_TO_OP.put("scaleSplit", "SCALE_SPLIT"); |
| | | CLEAR_TYPE_TO_OP.put("freightTurnover", "FREIGHT_TURNOVER"); |
| | | CLEAR_TYPE_TO_OP.put("passengerMonthly", "H2031"); |
| | | CLEAR_TYPE_TO_OP.put("passengerAuth", "PASSENGER_AUTH"); |
| | | CLEAR_TYPE_TO_OP.put("passengerIndividual", "PASSENGER_INDIVIDUAL"); |
| | | CLEAR_TYPE_TO_OP.put("energyMonthly", "H204"); |
| | | CLEAR_TYPE_TO_OP.put("energyAuth", "ENERGY_AUTH"); |
| | | CLEAR_TYPE_TO_OP.put("investment", "INVEST_MONTHLY_PASSENGER"); |
| | | CLEAR_TYPE_TO_OP.put("investCityPassenger", "INVEST_MONTHLY_PASSENGER"); |
| | | CLEAR_TYPE_TO_OP.put("investmentLogistics", "INVEST_MONTHLY_LOGISTICS"); |
| | | CLEAR_TYPE_TO_OP.put("investCityLogistics", "INVEST_MONTHLY_LOGISTICS"); |
| | | CLEAR_TYPE_TO_OP.put("investmentSystem", "INVEST_SYSTEM"); |
| | | CLEAR_TYPE_TO_OP.put("cityBus", "CITY_BUS"); |
| | | CLEAR_TYPE_TO_OP.put("cityTaxi", "CITY_TAXI"); |
| | | CLEAR_TYPE_TO_OP.put("cityTaxiAuth", "CITY_TAXI_AUTH"); |
| | | CLEAR_TYPE_TO_OP.put("wycTotal", "WYC_TOTAL"); |
| | | CLEAR_TYPE_TO_OP.put("wycOrder", "WYC_ORDER"); |
| | | |
| | | CLEAR_TYPE_TO_AUDIT.put("h2032", new String[]{"H2032"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("transportAuth", new String[]{"H2032"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("trackMileage", new String[]{"H2032"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("scaleSplit", new String[]{"H2032"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("freightTurnover", new String[]{"H2032"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("passengerMonthly", new String[]{"H2031"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("passengerAuth", new String[]{"H2031"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("passengerIndividual", new String[]{"H2031"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("energyMonthly", new String[]{"H204"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("energyAuth", new String[]{"H204"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("investment", new String[]{"INVEST"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("investmentLogistics", new String[]{"INVEST"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("investCityPassenger", new String[]{"INVEST"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("investCityLogistics", new String[]{"INVEST"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("investmentSystem", new String[]{"INVEST"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("cityBus", new String[]{"CITY_BUS"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("cityTaxi", new String[]{"CITY_TAXI"}); |
| | | CLEAR_TYPE_TO_AUDIT.put("cityTaxiAuth", new String[]{"CITY_TAXI"}); |
| | | |
| | | String[] investPassengerBatch = {"INVEST_客运站场", "INVEST_客运站场_CITY"}; |
| | | String[] investLogisticsBatch = {"INVEST_物流园区", "INVEST_物流园区_CITY"}; |
| | | CLEAR_TYPE_TO_BATCH.put("h2032", new String[]{"H2032"}); |
| | | CLEAR_TYPE_TO_BATCH.put("transportAuth", new String[]{"TRANSPORT_AUTH"}); |
| | | CLEAR_TYPE_TO_BATCH.put("trackMileage", new String[]{"TRACK_MILEAGE"}); |
| | | CLEAR_TYPE_TO_BATCH.put("scaleSplit", new String[]{"SCALE_SPLIT"}); |
| | | CLEAR_TYPE_TO_BATCH.put("freightTurnover", new String[]{"FREIGHT_TURNOVER"}); |
| | | CLEAR_TYPE_TO_BATCH.put("passengerMonthly", new String[]{"H2031"}); |
| | | CLEAR_TYPE_TO_BATCH.put("passengerAuth", new String[]{"PASSENGER_AUTH"}); |
| | | CLEAR_TYPE_TO_BATCH.put("passengerIndividual", new String[]{"PASSENGER_INDIVIDUAL"}); |
| | | CLEAR_TYPE_TO_BATCH.put("energyMonthly", new String[]{"H204"}); |
| | | CLEAR_TYPE_TO_BATCH.put("energyAuth", new String[]{"ENERGY_AUTH"}); |
| | | CLEAR_TYPE_TO_BATCH.put("investment", investPassengerBatch); |
| | | CLEAR_TYPE_TO_BATCH.put("investCityPassenger", investPassengerBatch); |
| | | CLEAR_TYPE_TO_BATCH.put("investmentLogistics", investLogisticsBatch); |
| | | CLEAR_TYPE_TO_BATCH.put("investCityLogistics", investLogisticsBatch); |
| | | CLEAR_TYPE_TO_BATCH.put("investmentSystem", new String[]{"INVEST_SYSTEM"}); |
| | | CLEAR_TYPE_TO_BATCH.put("cityBus", new String[]{"CITY_BUS"}); |
| | | CLEAR_TYPE_TO_BATCH.put("cityTaxi", new String[]{"CITY_TAXI"}); |
| | | CLEAR_TYPE_TO_BATCH.put("cityTaxiAuth", new String[]{"CITY_TAXI_AUTH"}); |
| | | CLEAR_TYPE_TO_BATCH.put("wycTotal", new String[]{"WYC_TOTAL"}); |
| | | CLEAR_TYPE_TO_BATCH.put("wycOrder", new String[]{"WYC_ORDER"}); |
| | | } |
| | | |
| | | /** |
| | | * 清空指定报表期已导入数据与审核结果,用于整月重导;投资项目主档保留。 |
| | | * |
| | | * @param types 需清空的数据类型(前端类型键,如 h2032/cityBus);为空则清空该报表期全部类型 |
| | | */ |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public Map<String, Object> clearPeriod(String period, List<String> types) { |
| | | if (period == null || !period.matches("\\d{4}-\\d{2}")) { |
| | | throw new IllegalArgumentException("报表期格式不正确,应为 yyyy-MM"); |
| | | } |
| | | Set<String> selected = new LinkedHashSet<>(); |
| | | if (types != null) { |
| | | for (String t : types) { |
| | | if (t != null && !t.trim().isEmpty()) selected.add(t.trim()); |
| | | } |
| | | } |
| | | boolean clearAll = selected.isEmpty(); |
| | | int dataRows = 0; |
| | | int auditRows = 0; |
| | | int auditRunRows = 0; |
| | | int batchRows = 0; |
| | | if (clearAll) { |
| | | dataRows += h2032Mapper.delete(new LambdaQueryWrapper<H2032EnterpriseMonthly>() |
| | | .eq(H2032EnterpriseMonthly::getReportPeriod, period)); |
| | | dataRows += transportAuthMapper.delete(new LambdaQueryWrapper<TransportAuthVehicle>() |
| | | .eq(TransportAuthVehicle::getReportPeriod, period)); |
| | | dataRows += trackMileageMapper.delete(new LambdaQueryWrapper<VehicleTrackMileage>() |
| | | .eq(VehicleTrackMileage::getReportPeriod, period)); |
| | | dataRows += scaleSplitMapper.delete(new LambdaQueryWrapper<ScaleSplitTransport>() |
| | | .eq(ScaleSplitTransport::getReportPeriod, period)); |
| | | dataRows += freightTurnoverMapper.delete(new LambdaQueryWrapper<FreightTurnoverImport>() |
| | | .eq(FreightTurnoverImport::getReportPeriod, period)); |
| | | dataRows += passengerMapper.delete(new LambdaQueryWrapper<PassengerEnterpriseMonthly>() |
| | | .eq(PassengerEnterpriseMonthly::getReportPeriod, period)); |
| | | dataRows += passengerIndividualMapper.delete(new LambdaQueryWrapper<PassengerIndividualMonthly>() |
| | | .eq(PassengerIndividualMonthly::getReportPeriod, period)); |
| | | dataRows += passengerAuthMapper.delete(new LambdaQueryWrapper<PassengerAuthVehicle>() |
| | | .eq(PassengerAuthVehicle::getReportPeriod, period)); |
| | | dataRows += energyMapper.delete(new LambdaQueryWrapper<EnergyVehicleQuarterly>() |
| | | .eq(EnergyVehicleQuarterly::getReportPeriod, period)); |
| | | dataRows += energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>() |
| | | .eq(EnergyAuthVehicle::getReportPeriod, period)); |
| | | dataRows += investMonthlyMapper.delete(new LambdaQueryWrapper<InvestmentMonthly>() |
| | | .eq(InvestmentMonthly::getReportPeriod, period)); |
| | | dataRows += investSystemMapper.delete(new LambdaQueryWrapper<InvestmentSystem>() |
| | | .eq(InvestmentSystem::getReportPeriod, period)); |
| | | dataRows += cityBusMapper.delete(new LambdaQueryWrapper<CityBusMonthly>() |
| | | .eq(CityBusMonthly::getReportPeriod, period)); |
| | | dataRows += cityTaxiMapper.delete(new LambdaQueryWrapper<CityTaxiMonthly>() |
| | | .eq(CityTaxiMonthly::getReportPeriod, period)); |
| | | dataRows += cityTaxiAuthMapper.delete(new LambdaQueryWrapper<CityTaxiAuth>() |
| | | .eq(CityTaxiAuth::getReportPeriod, period)); |
| | | dataRows += wycTotalMapper.delete(new LambdaQueryWrapper<WycTotalMonthly>() |
| | | .eq(WycTotalMonthly::getReportPeriod, period)); |
| | | dataRows += wycOrderMapper.delete(new LambdaQueryWrapper<WycOrderMonthly>() |
| | | .eq(WycOrderMonthly::getReportPeriod, period)); |
| | | auditRows = auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>() |
| | | .eq(AuditResult::getReportPeriod, period)); |
| | | auditRunRows = auditRunMapper.delete(new LambdaQueryWrapper<AuditRun>() |
| | | .eq(AuditRun::getReportPeriod, period)); |
| | | batchRows = importBatchMapper.delete(new LambdaQueryWrapper<ImportBatch>() |
| | | .eq(ImportBatch::getReportPeriod, period)); |
| | | } else { |
| | | Set<String> ops = new LinkedHashSet<>(); |
| | | Set<String> auditTypes = new LinkedHashSet<>(); |
| | | Set<String> batchTypes = new LinkedHashSet<>(); |
| | | for (String t : selected) { |
| | | String op = CLEAR_TYPE_TO_OP.get(t); |
| | | if (op == null) { |
| | | log.warn("清空数据:未知数据类型 {},已忽略", t); |
| | | continue; |
| | | } |
| | | ops.add(op); |
| | | String[] at = CLEAR_TYPE_TO_AUDIT.get(t); |
| | | if (at != null) java.util.Collections.addAll(auditTypes, at); |
| | | String[] bt = CLEAR_TYPE_TO_BATCH.get(t); |
| | | if (bt != null) java.util.Collections.addAll(batchTypes, bt); |
| | | } |
| | | if (ops.isEmpty()) { |
| | | throw new IllegalArgumentException("未指定有效的数据类型"); |
| | | } |
| | | for (String op : ops) { |
| | | dataRows += clearTypeData(op, period); |
| | | } |
| | | if (!auditTypes.isEmpty()) { |
| | | List<Long> ruleIds = new ArrayList<>(); |
| | | for (com.trafficaudit.rulemanage.entity.AuditRule rule : ruleMapper.selectList(null)) { |
| | | if (rule.getReportType() != null && auditTypes.contains(rule.getReportType())) { |
| | | ruleIds.add(rule.getId()); |
| | | } |
| | | } |
| | | if (!ruleIds.isEmpty()) { |
| | | auditRows = auditResultMapper.delete(new LambdaQueryWrapper<AuditResult>() |
| | | .eq(AuditResult::getReportPeriod, period) |
| | | .in(AuditResult::getRuleId, ruleIds)); |
| | | } |
| | | for (String rt : auditTypes) { |
| | | auditRunRows += auditRunMapper.delete(new LambdaQueryWrapper<AuditRun>() |
| | | .eq(AuditRun::getReportPeriod, period) |
| | | .eq(AuditRun::getReportType, rt)); |
| | | } |
| | | } |
| | | if (!batchTypes.isEmpty()) { |
| | | batchRows = importBatchMapper.delete(new LambdaQueryWrapper<ImportBatch>() |
| | | .eq(ImportBatch::getReportPeriod, period) |
| | | .in(ImportBatch::getImportType, batchTypes)); |
| | | } |
| | | } |
| | | Map<String, Object> stats = new LinkedHashMap<>(); |
| | | stats.put("period", period); |
| | | stats.put("scope", clearAll ? "all" : "types"); |
| | | if (!clearAll) stats.put("types", new ArrayList<>(selected)); |
| | | stats.put("dataRows", dataRows); |
| | | stats.put("auditRows", auditRows); |
| | | stats.put("auditRunRows", auditRunRows); |
| | | stats.put("batchRows", batchRows); |
| | | log.info("清空报表期 {}({})完成:业务数据 {} 行、审核结果 {} 行、审核标记 {} 行、导入批次 {} 行", |
| | | period, clearAll ? "全部类型" : String.join(",", selected), dataRows, auditRows, auditRunRows, batchRows); |
| | | return stats; |
| | | } |
| | | |
| | | /** 按“数据表操作键”清空对应业务表(投资月度按项目类别过滤),返回删除行数 */ |
| | | private int clearTypeData(String op, String period) { |
| | | switch (op) { |
| | | case "H2032": |
| | | return h2032Mapper.delete(new LambdaQueryWrapper<H2032EnterpriseMonthly>() |
| | | .eq(H2032EnterpriseMonthly::getReportPeriod, period)); |
| | | case "TRANSPORT_AUTH": |
| | | return transportAuthMapper.delete(new LambdaQueryWrapper<TransportAuthVehicle>() |
| | | .eq(TransportAuthVehicle::getReportPeriod, period)); |
| | | case "TRACK_MILEAGE": |
| | | return trackMileageMapper.delete(new LambdaQueryWrapper<VehicleTrackMileage>() |
| | | .eq(VehicleTrackMileage::getReportPeriod, period)); |
| | | case "SCALE_SPLIT": |
| | | return scaleSplitMapper.delete(new LambdaQueryWrapper<ScaleSplitTransport>() |
| | | .eq(ScaleSplitTransport::getReportPeriod, period)); |
| | | case "FREIGHT_TURNOVER": |
| | | return freightTurnoverMapper.delete(new LambdaQueryWrapper<FreightTurnoverImport>() |
| | | .eq(FreightTurnoverImport::getReportPeriod, period)); |
| | | case "H2031": |
| | | return passengerMapper.delete(new LambdaQueryWrapper<PassengerEnterpriseMonthly>() |
| | | .eq(PassengerEnterpriseMonthly::getReportPeriod, period)); |
| | | case "PASSENGER_AUTH": |
| | | return passengerAuthMapper.delete(new LambdaQueryWrapper<PassengerAuthVehicle>() |
| | | .eq(PassengerAuthVehicle::getReportPeriod, period)); |
| | | case "PASSENGER_INDIVIDUAL": |
| | | return passengerIndividualMapper.delete(new LambdaQueryWrapper<PassengerIndividualMonthly>() |
| | | .eq(PassengerIndividualMonthly::getReportPeriod, period)); |
| | | case "H204": |
| | | return energyMapper.delete(new LambdaQueryWrapper<EnergyVehicleQuarterly>() |
| | | .eq(EnergyVehicleQuarterly::getReportPeriod, period)); |
| | | case "ENERGY_AUTH": |
| | | return energyAuthMapper.delete(new LambdaQueryWrapper<EnergyAuthVehicle>() |
| | | .eq(EnergyAuthVehicle::getReportPeriod, period)); |
| | | case "INVEST_MONTHLY_PASSENGER": |
| | | return deleteInvestmentMonthly(period, "客运站场"); |
| | | case "INVEST_MONTHLY_LOGISTICS": |
| | | return deleteInvestmentMonthly(period, "物流园区"); |
| | | case "INVEST_SYSTEM": |
| | | return investSystemMapper.delete(new LambdaQueryWrapper<InvestmentSystem>() |
| | | .eq(InvestmentSystem::getReportPeriod, period)); |
| | | case "CITY_BUS": |
| | | return cityBusMapper.delete(new LambdaQueryWrapper<CityBusMonthly>() |
| | | .eq(CityBusMonthly::getReportPeriod, period)); |
| | | case "CITY_TAXI": |
| | | return cityTaxiMapper.delete(new LambdaQueryWrapper<CityTaxiMonthly>() |
| | | .eq(CityTaxiMonthly::getReportPeriod, period)); |
| | | case "CITY_TAXI_AUTH": |
| | | return cityTaxiAuthMapper.delete(new LambdaQueryWrapper<CityTaxiAuth>() |
| | | .eq(CityTaxiAuth::getReportPeriod, period)); |
| | | case "WYC_TOTAL": |
| | | return wycTotalMapper.delete(new LambdaQueryWrapper<WycTotalMonthly>() |
| | | .eq(WycTotalMonthly::getReportPeriod, period)); |
| | | case "WYC_ORDER": |
| | | return wycOrderMapper.delete(new LambdaQueryWrapper<WycOrderMonthly>() |
| | | .eq(WycOrderMonthly::getReportPeriod, period)); |
| | | default: |
| | | log.warn("清空数据:未知数据表操作 {}", op); |
| | | return 0; |
| | | } |
| | | } |
| | | |
| | | /** 投资月度按项目类别清除(投资项目主档保留) */ |
| | | private int deleteInvestmentMonthly(String period, String category) { |
| | | List<Long> projectIds = new ArrayList<>(); |
| | | for (InvestmentProject p : investProjectMapper.selectList(new LambdaQueryWrapper<InvestmentProject>() |
| | | .eq(InvestmentProject::getCategory, category))) { |
| | | projectIds.add(p.getId()); |
| | | } |
| | | if (projectIds.isEmpty()) return 0; |
| | | return investMonthlyMapper.delete(new LambdaQueryWrapper<InvestmentMonthly>() |
| | | .eq(InvestmentMonthly::getReportPeriod, period) |
| | | .in(InvestmentMonthly::getProjectId, projectIds)); |
| | | } |
| | | |
| | | /** 数据变化后删除指定报表类型指定报表期的审核结果(需重新执行审核) */ |
| | | private void deleteRuleResults(String reportType, String period) { |
| | | List<Long> ruleIds = new ArrayList<>(); |