From e9f1ee7341bcf55904f6c0d31aa91ff52aa441dc Mon Sep 17 00:00:00 2001
From: zhizhijie <zhizhijie@users.noreply.gitee.com>
Date: 星期二, 22 九月 2026 11:28:40 +0800
Subject: [PATCH] feat(数据查看): 按市州汇总(任意起止月/自动上年同期/时点列不参与/排名可选) + 导出 Excel,新增 CityRollupService 与 3 个接口

---
 traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataViewController.java |  651 +++++++++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 606 insertions(+), 45 deletions(-)

diff --git a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataViewController.java b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataViewController.java
index c01014e..6ce7914 100644
--- a/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataViewController.java
+++ b/traffic-audit-server/src/main/java/com/trafficaudit/dataimport/controller/DataViewController.java
@@ -6,14 +6,44 @@
 import com.trafficaudit.common.Result;
 import com.trafficaudit.dataimport.entity.FreightTurnoverImport;
 import com.trafficaudit.dataimport.entity.H2032EnterpriseMonthly;
+import com.trafficaudit.dataimport.entity.PassengerAuthVehicle;
+import com.trafficaudit.dataimport.entity.CityBusMonthly;
+import com.trafficaudit.dataimport.entity.CityTaxiAuth;
+import com.trafficaudit.dataimport.entity.CityTaxiMonthly;
+import com.trafficaudit.dataimport.entity.PassengerEnterpriseMonthly;
 import com.trafficaudit.dataimport.entity.ScaleSplitTransport;
 import com.trafficaudit.dataimport.entity.TransportAuthVehicle;
 import com.trafficaudit.dataimport.entity.VehicleTrackMileage;
+import com.trafficaudit.dataimport.entity.InvestmentMonthly;
+import com.trafficaudit.dataimport.entity.InvestmentProject;
+import com.trafficaudit.dataimport.entity.InvestmentSystem;
+import com.trafficaudit.dataimport.entity.EnergyVehicleQuarterly;
+import com.trafficaudit.dataimport.entity.EnergyAuthVehicle;
+import com.trafficaudit.dataimport.entity.PassengerIndividualMonthly;
+import com.trafficaudit.dataimport.entity.WycOrderMonthly;
+import com.trafficaudit.dataimport.entity.WycTotalMonthly;
+import com.trafficaudit.common.util.RegionUtil;
+import com.trafficaudit.reportexport.calc.WycSplitCalc;
+import com.trafficaudit.dataimport.service.CityRollupService;
+import javax.servlet.http.HttpServletResponse;
 import com.trafficaudit.dataimport.mapper.FreightTurnoverImportMapper;
 import com.trafficaudit.dataimport.mapper.H2032EnterpriseMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.PassengerAuthVehicleMapper;
+import com.trafficaudit.dataimport.mapper.CityBusMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.CityTaxiAuthMapper;
+import com.trafficaudit.dataimport.mapper.CityTaxiMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.PassengerEnterpriseMonthlyMapper;
 import com.trafficaudit.dataimport.mapper.ScaleSplitTransportMapper;
 import com.trafficaudit.dataimport.mapper.TransportAuthVehicleMapper;
 import com.trafficaudit.dataimport.mapper.VehicleTrackMileageMapper;
+import com.trafficaudit.dataimport.mapper.InvestmentMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.InvestmentProjectMapper;
+import com.trafficaudit.dataimport.mapper.InvestmentSystemMapper;
+import com.trafficaudit.dataimport.mapper.EnergyVehicleQuarterlyMapper;
+import com.trafficaudit.dataimport.mapper.EnergyAuthVehicleMapper;
+import com.trafficaudit.dataimport.mapper.PassengerIndividualMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.WycOrderMonthlyMapper;
+import com.trafficaudit.dataimport.mapper.WycTotalMonthlyMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
@@ -44,11 +74,42 @@
     private ScaleSplitTransportMapper scaleSplitMapper;
     @Resource
     private FreightTurnoverImportMapper freightTurnoverMapper;
+    @Resource
+    private PassengerEnterpriseMonthlyMapper passengerMapper;
+    @Resource
+    private PassengerAuthVehicleMapper passengerAuthMapper;
+    @Resource
+    private CityBusMonthlyMapper cityBusMapper;
+    @Resource
+    private CityTaxiMonthlyMapper cityTaxiMapper;
+    @Resource
+    private CityTaxiAuthMapper cityTaxiAuthMapper;
+    @Resource
+    private InvestmentMonthlyMapper investmentMonthlyMapper;
+    @Resource
+    private InvestmentProjectMapper investmentProjectMapper;
+    @Resource
+    private InvestmentSystemMapper investmentSystemMapper;
+    @Resource
+    private EnergyVehicleQuarterlyMapper energyVehicleMapper;
+    @Resource
+    private EnergyAuthVehicleMapper energyAuthMapper;
+    @Resource
+    private PassengerIndividualMonthlyMapper passengerIndividualMapper;
+    @Resource
+    private WycOrderMonthlyMapper wycOrderMapper;
+    @Resource
+    private WycTotalMonthlyMapper wycTotalMapper;
+    @Resource
+    private WycSplitCalc wycSplitCalc;
+    @Resource
+    private CityRollupService cityRollupService;
 
     @GetMapping("/list")
     public Result<Map<String, Object>> list(@RequestParam("type") String type,
                                             @RequestParam(value = "period", required = false) String period,
                                             @RequestParam(value = "keyword", required = false) String keyword,
+                                            @RequestParam(value = "periodType", required = false) String periodType,
                                             @RequestParam(value = "page", defaultValue = "1") long page,
                                             @RequestParam(value = "size", defaultValue = "20") long size) {
         String kw = keyword == null ? "" : keyword.trim();
@@ -67,7 +128,9 @@
                         .orderByDesc(H2032EnterpriseMonthly::getId);
                 Page<H2032EnterpriseMonthly> p = new Page<>(safePage, safeSize);
                 Page<H2032EnterpriseMonthly> r = h2032Mapper.selectPage(p, w);
-                result.put("records", toMaps(r.getRecords(), propsOf(H2032_COLUMNS)));
+                List<Map<String, Object>> rows = toMaps(r.getRecords(), propsOf(H2032_COLUMNS));
+                fillCity(rows);
+                result.put("records", rows);
                 fillPage(result, r);
                 break;
             }
@@ -96,6 +159,7 @@
             case "scaleSplit": {
                 LambdaQueryWrapper<ScaleSplitTransport> w = new LambdaQueryWrapper<ScaleSplitTransport>()
                         .eq(notEmpty(period), ScaleSplitTransport::getReportPeriod, period)
+                        .eq(notEmpty(periodType), ScaleSplitTransport::getPeriodType, periodType)
                         .like(!kw.isEmpty(), ScaleSplitTransport::getRegionName, kw)
                         .orderByDesc(ScaleSplitTransport::getId);
                 Page<ScaleSplitTransport> p = new Page<>(safePage, safeSize);
@@ -113,6 +177,63 @@
                 fillPage(result, r);
                 break;
             }
+            case "h2031": {
+                LambdaQueryWrapper<PassengerEnterpriseMonthly> w = new LambdaQueryWrapper<PassengerEnterpriseMonthly>()
+                        .eq(notEmpty(period), PassengerEnterpriseMonthly::getReportPeriod, period)
+                        .like(!kw.isEmpty(), PassengerEnterpriseMonthly::getEnterpriseName, kw)
+                        .orderByDesc(PassengerEnterpriseMonthly::getId);
+                Page<PassengerEnterpriseMonthly> p = new Page<>(safePage, safeSize);
+                Page<PassengerEnterpriseMonthly> r = passengerMapper.selectPage(p, w);
+                List<Map<String, Object>> rows = toMaps(r.getRecords(), propsOf(H2031_COLUMNS));
+                fillCity(rows);
+                result.put("records", rows);
+                fillPage(result, r);
+                break;
+            }
+            case "cityBus": {
+                LambdaQueryWrapper<CityBusMonthly> w = new LambdaQueryWrapper<CityBusMonthly>()
+                        .eq(notEmpty(period), CityBusMonthly::getReportPeriod, period)
+                        .like(!kw.isEmpty(), CityBusMonthly::getEnterpriseName, kw)
+                        .orderByDesc(CityBusMonthly::getId);
+                Page<CityBusMonthly> p = new Page<>(safePage, safeSize);
+                Page<CityBusMonthly> r = cityBusMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(BUS_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "cityTaxi": {
+                LambdaQueryWrapper<CityTaxiMonthly> w = new LambdaQueryWrapper<CityTaxiMonthly>()
+                        .eq(notEmpty(period), CityTaxiMonthly::getReportPeriod, period)
+                        .like(!kw.isEmpty(), CityTaxiMonthly::getCity, kw)
+                        .orderByAsc(CityTaxiMonthly::getId);
+                Page<CityTaxiMonthly> p = new Page<>(safePage, safeSize);
+                Page<CityTaxiMonthly> r = cityTaxiMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(TAXI_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "cityTaxiAuth": {
+                LambdaQueryWrapper<CityTaxiAuth> w = new LambdaQueryWrapper<CityTaxiAuth>()
+                        .eq(notEmpty(period), CityTaxiAuth::getReportPeriod, period)
+                        .like(!kw.isEmpty(), CityTaxiAuth::getCity, kw)
+                        .orderByDesc(CityTaxiAuth::getId);
+                Page<CityTaxiAuth> p = new Page<>(safePage, safeSize);
+                Page<CityTaxiAuth> r = cityTaxiAuthMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(TAXI_AUTH_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "passengerAuth": {
+                LambdaQueryWrapper<PassengerAuthVehicle> w = new LambdaQueryWrapper<PassengerAuthVehicle>()
+                        .eq(notEmpty(period), PassengerAuthVehicle::getReportPeriod, period)
+                        .like(!kw.isEmpty(), PassengerAuthVehicle::getEnterpriseName, kw)
+                        .orderByDesc(PassengerAuthVehicle::getId);
+                Page<PassengerAuthVehicle> p = new Page<>(safePage, safeSize);
+                Page<PassengerAuthVehicle> r = passengerAuthMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(PAUTH_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
             case "freightTurnover": {
                 LambdaQueryWrapper<FreightTurnoverImport> w = new LambdaQueryWrapper<FreightTurnoverImport>()
                         .eq(notEmpty(period), FreightTurnoverImport::getReportPeriod, period)
@@ -124,6 +245,118 @@
                 fillPage(result, r);
                 break;
             }
+            case "investmentMonthly": {
+                java.util.List<Long> pids = new ArrayList<>();
+                if (!kw.isEmpty()) {
+                    for (InvestmentProject ip : investmentProjectMapper.selectList(
+                            new LambdaQueryWrapper<InvestmentProject>().like(InvestmentProject::getProjectName, kw))) {
+                        pids.add(ip.getId());
+                    }
+                    if (pids.isEmpty()) {
+                        result.put("records", new ArrayList<>());
+                        result.put("total", 0L);
+                        result.put("current", safePage);
+                        result.put("size", safeSize);
+                        break;
+                    }
+                }
+                LambdaQueryWrapper<InvestmentMonthly> w = new LambdaQueryWrapper<InvestmentMonthly>()
+                        .eq(notEmpty(period), InvestmentMonthly::getReportPeriod, period)
+                        .in(!pids.isEmpty(), InvestmentMonthly::getProjectId, pids)
+                        .orderByAsc(InvestmentMonthly::getProjectId)
+                        .orderByAsc(InvestmentMonthly::getId);
+                Page<InvestmentMonthly> p = new Page<>(safePage, safeSize);
+                Page<InvestmentMonthly> r = investmentMonthlyMapper.selectPage(p, w);
+                List<Map<String, Object>> rows = toMaps(r.getRecords(), propsOf(INVEST_MONTHLY_COLUMNS));
+                fillProjectInfo(rows);
+                result.put("records", rows);
+                fillPage(result, r);
+                break;
+            }
+            case "investmentProject": {
+                LambdaQueryWrapper<InvestmentProject> w = new LambdaQueryWrapper<InvestmentProject>()
+                        .like(!kw.isEmpty(), InvestmentProject::getProjectName, kw)
+                        .orderByAsc(InvestmentProject::getCity)
+                        .orderByAsc(InvestmentProject::getId);
+                Page<InvestmentProject> p = new Page<>(safePage, safeSize);
+                Page<InvestmentProject> r = investmentProjectMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(INVEST_PROJECT_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "investmentSystem": {
+                LambdaQueryWrapper<InvestmentSystem> w = new LambdaQueryWrapper<InvestmentSystem>()
+                        .eq(notEmpty(period), InvestmentSystem::getReportPeriod, period)
+                        .like(!kw.isEmpty(), InvestmentSystem::getProjectName, kw)
+                        .orderByDesc(InvestmentSystem::getId);
+                Page<InvestmentSystem> p = new Page<>(safePage, safeSize);
+                Page<InvestmentSystem> r = investmentSystemMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(INVEST_SYSTEM_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "energyVehicle": {
+                LambdaQueryWrapper<EnergyVehicleQuarterly> w = new LambdaQueryWrapper<EnergyVehicleQuarterly>()
+                        .eq(notEmpty(period), EnergyVehicleQuarterly::getReportPeriod, period)
+                        .like(!kw.isEmpty(), EnergyVehicleQuarterly::getEnterpriseName, kw)
+                        .orderByDesc(EnergyVehicleQuarterly::getId);
+                Page<EnergyVehicleQuarterly> p = new Page<>(safePage, safeSize);
+                Page<EnergyVehicleQuarterly> r = energyVehicleMapper.selectPage(p, w);
+                List<Map<String, Object>> rows = toMaps(r.getRecords(), propsOf(ENERGY_VEHICLE_COLUMNS));
+                fillCity(rows);
+                result.put("records", rows);
+                fillPage(result, r);
+                break;
+            }
+            case "energyAuth": {
+                LambdaQueryWrapper<EnergyAuthVehicle> w = new LambdaQueryWrapper<EnergyAuthVehicle>()
+                        .eq(notEmpty(period), EnergyAuthVehicle::getReportPeriod, period)
+                        .like(!kw.isEmpty(), EnergyAuthVehicle::getPlateNo, kw)
+                        .orderByDesc(EnergyAuthVehicle::getId);
+                Page<EnergyAuthVehicle> p = new Page<>(safePage, safeSize);
+                Page<EnergyAuthVehicle> r = energyAuthMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(ENERGY_AUTH_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "passengerIndividual": {
+                LambdaQueryWrapper<PassengerIndividualMonthly> w = new LambdaQueryWrapper<PassengerIndividualMonthly>()
+                        .eq(notEmpty(period), PassengerIndividualMonthly::getReportPeriod, period)
+                        .like(!kw.isEmpty(), PassengerIndividualMonthly::getEnterpriseName, kw)
+                        .orderByDesc(PassengerIndividualMonthly::getId);
+                Page<PassengerIndividualMonthly> p = new Page<>(safePage, safeSize);
+                Page<PassengerIndividualMonthly> r = passengerIndividualMapper.selectPage(p, w);
+                List<Map<String, Object>> rows = toMaps(r.getRecords(), propsOf(PAX_INDIVIDUAL_COLUMNS));
+                fillCity(rows);
+                result.put("records", rows);
+                fillPage(result, r);
+                break;
+            }
+            case "wycTotal": {
+                LambdaQueryWrapper<WycTotalMonthly> w = new LambdaQueryWrapper<WycTotalMonthly>()
+                        .eq(notEmpty(period), WycTotalMonthly::getReportPeriod, period)
+                        .orderByDesc(WycTotalMonthly::getId);
+                Page<WycTotalMonthly> p = new Page<>(safePage, safeSize);
+                Page<WycTotalMonthly> r = wycTotalMapper.selectPage(p, w);
+                result.put("records", toMaps(r.getRecords(), propsOf(WYC_TOTAL_COLUMNS)));
+                fillPage(result, r);
+                break;
+            }
+            case "wycOrder": {
+                LambdaQueryWrapper<WycOrderMonthly> w = new LambdaQueryWrapper<WycOrderMonthly>()
+                        .eq(notEmpty(period), WycOrderMonthly::getReportPeriod, period)
+                        .orderByDesc(WycOrderMonthly::getReportPeriod);
+                List<WycOrderMonthly> list = wycOrderMapper.selectList(w);
+                List<Map<String, Object>> rows = new ArrayList<>();
+                for (WycOrderMonthly o : list) {
+                    rows.addAll(wycOrderCityRows(o));
+                }
+                result.put("records", rows);
+                result.put("total", (long) rows.size());
+                result.put("current", 1L);
+                result.put("size", (long) rows.size());
+                break;
+            }
             default:
                 result.put("records", new ArrayList<>());
                 result.put("total", 0L);
@@ -131,6 +364,128 @@
                 result.put("size", safeSize);
         }
         return Result.ok(result);
+    }
+
+    /** 鍖哄垝浠g爜 -> 甯傚窞鍚嶏紙鏃犳硶璇嗗埆杩斿洖绌轰覆锛� */
+    private String cityOf(String regionCode) {
+        if (regionCode == null || regionCode.trim().isEmpty()) return "";
+        String city = RegionUtil.cityByCode(regionCode.trim());
+        return city == null ? "" : city;
+    }
+
+    /** 鎸� regionCode 娲剧敓"甯傚窞"鍒楋紙浼佷笟绫昏〃閫氱敤锛� */
+    private void fillCity(List<Map<String, Object>> rows) {
+        for (Map<String, Object> row : rows) {
+            Object rc = row.get("regionCode");
+            row.put("city", cityOf(rc == null ? null : String.valueOf(rc)));
+        }
+    }
+
+    /** 鎶曡祫鏈堟姤锛氳ˉ椤圭洰鍚嶇О涓庡競宸烇紙鍘熻〃鍙湁 projectId锛岄〉闈㈡棤娉曡鲸璇嗛」鐩級 */
+    private void fillProjectInfo(List<Map<String, Object>> rows) {
+        java.util.Set<Long> ids = new java.util.LinkedHashSet<>();
+        for (Map<String, Object> row : rows) {
+            Object pid = row.get("projectId");
+            if (pid instanceof Number) ids.add(((Number) pid).longValue());
+        }
+        if (ids.isEmpty()) return;
+        Map<Long, InvestmentProject> byId = new LinkedHashMap<>();
+        for (InvestmentProject ip : investmentProjectMapper.selectBatchIds(ids)) {
+            byId.put(ip.getId(), ip);
+        }
+        for (Map<String, Object> row : rows) {
+            Object pid = row.get("projectId");
+            InvestmentProject ip = pid instanceof Number ? byId.get(((Number) pid).longValue()) : null;
+            row.put("projectName", ip == null ? null : ip.getProjectName());
+            row.put("city", ip == null ? null : ip.getCity());
+        }
+    }
+
+    private static double nz(Double v) {
+        return v == null ? 0.0 : v;
+    }
+
+    /** 缃戠害杞﹁鍗曞彴璐� -> 鎸夊競宸炵珫鎺掞細鍏ㄧ渷 + 17 甯傚窞 脳 鎸囨爣锛堝杩愰噺/鍛ㄨ浆閲忕敱 WycSplitCalc 鎷嗗垎鍙e緞璁$畻锛� */
+    private List<Map<String, Object>> wycOrderCityRows(WycOrderMonthly o) {
+        List<Map<String, Object>> rows = new ArrayList<>();
+        List<String> cities = RegionUtil.cityList();
+        double orderSum = nz(o.getOrderSum());
+        double[] orders = { nz(o.getOrderWuhan()), nz(o.getOrderHuangshi()), nz(o.getOrderShiyan()),
+                nz(o.getOrderYichang()), nz(o.getOrderXiangyang()), nz(o.getOrderEzhou()), nz(o.getOrderJingmen()),
+                nz(o.getOrderXiaogan()), nz(o.getOrderJingzhou()), nz(o.getOrderHuanggang()), nz(o.getOrderXianning()),
+                nz(o.getOrderSuizhou()), nz(o.getOrderEnshi()), nz(o.getOrderXiantao()), nz(o.getOrderQianjiang()),
+                nz(o.getOrderTianmen()), nz(o.getOrderShennong()) };
+
+        Map<String, Object> province = new LinkedHashMap<>();
+        province.put("reportPeriod", o.getReportPeriod());
+        province.put("period", o.getReportPeriod());
+        province.put("region", "鍏ㄧ渷");
+        province.put("orderCount", orderSum);
+        province.put("orderShare", orderSum > 0 ? 1.0 : null);
+        province.put("pax", o.getPinK());
+        province.put("turnover", o.getPinZ());
+        province.put("cityPax", o.getPinCK());
+        province.put("cityTurnover", o.getPinCZ());
+        province.put("note", "鍏ㄧ渷鍙e緞鐩存帴鍙栧彴璐� pin 鍊�");
+        rows.add(province);
+
+        Map<String, WycSplitCalc.WycMetrics> byCity = null;
+        String calcError = null;
+        try {
+            byCity = wycSplitCalc.calc(o.getReportPeriod()).getByCity();
+        } catch (Exception e) {
+            calcError = e.getMessage() == null ? "鎷嗗垎璁$畻澶辫触" : e.getMessage();
+        }
+        for (int i = 0; i < cities.size() && i < orders.length; i++) {
+            String city = cities.get(i);
+            Map<String, Object> row = new LinkedHashMap<>();
+            row.put("reportPeriod", o.getReportPeriod());
+            row.put("period", o.getReportPeriod());
+            row.put("region", city);
+            row.put("orderCount", orders[i]);
+            row.put("orderShare", orderSum > 0 ? orders[i] / orderSum : null);
+            WycSplitCalc.WycMetrics m = byCity == null ? null : byCity.get(city);
+            row.put("pax", m == null ? null : m.getTotalPax());
+            row.put("turnover", m == null ? null : m.getTotalTurnover());
+            row.put("cityPax", m == null ? null : m.getCityPax());
+            row.put("cityTurnover", m == null ? null : m.getCityTurnover());
+            row.put("note", m == null ? (calcError == null ? "鎷嗗垎鏈绠�" : calcError) : "");
+            rows.add(row);
+        }
+        return rows;
+    }
+
+    /** 鏀寔鎸夊競宸炴眹鎬荤殑鏁版嵁绫诲瀷 */
+    @GetMapping("/rollupTypes")
+    public Result<List<Map<String, Object>>> rollupTypes() {
+        return Result.ok(cityRollupService.supportedTypes());
+    }
+
+    /** 鎸夊競宸炴眹鎬伙紙浠绘剰璧锋鏈堬級 */
+    @GetMapping("/summary")
+    public Result<Map<String, Object>> summary(@RequestParam("type") String type,
+                                               @RequestParam("from") String from,
+                                               @RequestParam("to") String to,
+                                               @RequestParam(value = "rankMode", defaultValue = "blank") String rankMode) {
+        return Result.ok(cityRollupService.summary(type, from, to, "recompute".equalsIgnoreCase(rankMode)));
+    }
+
+    /** 鎸夊競宸炴眹鎬诲鍑� Excel锛堟暟鍊煎叏绮惧害锛屾樉绀� 2 浣嶅皬鏁� / 鐧惧垎姣旓級 */
+    @GetMapping("/export")
+    public void export(@RequestParam("type") String type,
+                       @RequestParam("from") String from,
+                       @RequestParam("to") String to,
+                       @RequestParam(value = "rankMode", defaultValue = "blank") String rankMode,
+                       HttpServletResponse response) throws Exception {
+        byte[] bytes = cityRollupService.exportExcel(type, from, to, "recompute".equalsIgnoreCase(rankMode));
+        String fileName = "鎸夊競宸炴眹鎬籣" + type + "_" + from + "_" + to + ".xlsx";
+        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        response.setCharacterEncoding("UTF-8");
+        response.setHeader("Content-Disposition",
+                "attachment; filename=\"" + java.net.URLEncoder.encode(fileName, "UTF-8") + "\"");
+        response.setContentLength(bytes.length);
+        response.getOutputStream().write(bytes);
+        response.getOutputStream().flush();
     }
 
     private boolean notEmpty(String s) {
@@ -171,6 +526,19 @@
             case "trackMileage": return TRACK_COLUMNS;
             case "scaleSplit": return SPLIT_COLUMNS;
             case "freightTurnover": return FREIGHT_COLUMNS;
+            case "h2031": return H2031_COLUMNS;
+            case "cityBus": return BUS_COLUMNS;
+            case "cityTaxi": return TAXI_COLUMNS;
+            case "cityTaxiAuth": return TAXI_AUTH_COLUMNS;
+            case "passengerAuth": return PAUTH_COLUMNS;
+            case "investmentMonthly": return INVEST_MONTHLY_COLUMNS;
+            case "investmentProject": return INVEST_PROJECT_COLUMNS;
+            case "investmentSystem": return INVEST_SYSTEM_COLUMNS;
+            case "energyVehicle": return ENERGY_VEHICLE_COLUMNS;
+            case "energyAuth": return ENERGY_AUTH_COLUMNS;
+            case "passengerIndividual": return PAX_INDIVIDUAL_COLUMNS;
+            case "wycTotal": return WYC_TOTAL_COLUMNS;
+            case "wycOrder": return WYC_ORDER_COLUMNS;
             default: return new ArrayList<>();
         }
     }
@@ -181,6 +549,7 @@
         m.put("label", label);
         m.put("width", width);
         return m;
+
     }
 
     private static final List<Map<String, Object>> H2032_COLUMNS = new ArrayList<>();
@@ -188,35 +557,49 @@
     private static final List<Map<String, Object>> TRACK_COLUMNS = new ArrayList<>();
     private static final List<Map<String, Object>> SPLIT_COLUMNS = new ArrayList<>();
     private static final List<Map<String, Object>> FREIGHT_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> H2031_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> PAUTH_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> BUS_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> TAXI_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> TAXI_AUTH_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> INVEST_MONTHLY_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> INVEST_PROJECT_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> INVEST_SYSTEM_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> ENERGY_VEHICLE_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> ENERGY_AUTH_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> PAX_INDIVIDUAL_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> WYC_TOTAL_COLUMNS = new ArrayList<>();
+    private static final List<Map<String, Object>> WYC_ORDER_COLUMNS = new ArrayList<>();
 
     static {
         H2032_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
         H2032_COLUMNS.add(col("regionCode", "鎵�灞炲湴鍖�", 100));
+        H2032_COLUMNS.add(col("city", "甯傚窞", 110));
         H2032_COLUMNS.add(col("enterpriseCode", "浼佷笟浠g爜", 130));
         H2032_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 220));
         H2032_COLUMNS.add(col("unifiedCreditCode", "缁熶竴绀句細淇$敤浠g爜", 180));
         H2032_COLUMNS.add(col("reportUnit", "濉姤鍗曚綅", 160));
-        H2032_COLUMNS.add(col("vehicleTotal", "杞﹁締鏁板悎璁�", 110));
-        H2032_COLUMNS.add(col("tonsTotal", "鏍囪鍚ㄤ綅鏁板悎璁�", 130));
-        H2032_COLUMNS.add(col("vehicleTractor", "鐗靛紩杞�", 90));
-        H2032_COLUMNS.add(col("vehicleTrailer", "鎸傝溅", 90));
-        H2032_COLUMNS.add(col("tonsTrailer", "鍚ㄤ綅-鎸傝溅", 110));
-        H2032_COLUMNS.add(col("vehicleContainer", "闆嗚绠辫溅", 110));
-        H2032_COLUMNS.add(col("tonsContainer", "鍚ㄤ綅-闆嗚绠�", 120));
-        H2032_COLUMNS.add(col("vehicleWhole", "鏁磋溅", 90));
-        H2032_COLUMNS.add(col("tonsWhole", "鍚ㄤ綅-鏁磋溅", 110));
-        H2032_COLUMNS.add(col("freightTotal", "璐ц繍閲忓悎璁�", 110));
-        H2032_COLUMNS.add(col("turnoverTotal", "鍛ㄨ浆閲忓悎璁�", 110));
-        H2032_COLUMNS.add(col("freightContainer", "璐ц繍閲�-闆嗚绠�", 130));
-        H2032_COLUMNS.add(col("freightCoal", "璐ц繍閲�-鐓ょ偔", 120));
-        H2032_COLUMNS.add(col("freightOilGas", "璐ц繍閲�-娌规皵", 120));
-        H2032_COLUMNS.add(col("freightCrudeOil", "璐ц繍閲�-鍘熸补", 120));
-        H2032_COLUMNS.add(col("freightMetalOre", "璐ц繍閲�-閲戝睘鐭跨煶", 140));
-        H2032_COLUMNS.add(col("freightIronOre", "璐ц繍閲�-閾佺熆鐭�", 130));
-        H2032_COLUMNS.add(col("freightBuilding", "璐ц繍閲�-寤烘潗", 120));
-        H2032_COLUMNS.add(col("freightGrain", "璐ц繍閲�-绮", 120));
-        H2032_COLUMNS.add(col("avgTonnage", "骞冲潎鍚ㄤ綅", 100));
-        H2032_COLUMNS.add(col("avgDistance", "骞冲潎杩愯窛", 100));
+        H2032_COLUMNS.add(col("vehicleTotal", "杞﹁締鏁板悎璁�(杈�)", 130));
+        H2032_COLUMNS.add(col("tonsTotal", "鏍囪鍚ㄤ綅鏁板悎璁�(鍚�)", 150));
+        H2032_COLUMNS.add(col("vehicleTractor", "鐗靛紩杞�(杈�)", 110));
+        H2032_COLUMNS.add(col("vehicleTrailer", "鎸傝溅(杈�)", 110));
+        H2032_COLUMNS.add(col("tonsTrailer", "鍚ㄤ綅-鎸傝溅(鍚�)", 130));
+        H2032_COLUMNS.add(col("vehicleContainer", "闆嗚绠辫溅(杈�)", 120));
+        H2032_COLUMNS.add(col("tonsContainer", "鍚ㄤ綅-闆嗚绠�(鍚�)", 140));
+        H2032_COLUMNS.add(col("vehicleWhole", "鏁磋溅(杈�)", 110));
+        H2032_COLUMNS.add(col("tonsWhole", "鍚ㄤ綅-鏁磋溅(鍚�)", 130));
+        H2032_COLUMNS.add(col("freightTotal", "璐ц繍閲忓悎璁�(鍚�)", 130));
+        H2032_COLUMNS.add(col("turnoverTotal", "鍛ㄨ浆閲忓悎璁�(鍚ㄥ叕閲�)", 150));
+        H2032_COLUMNS.add(col("freightContainer", "璐ц繍閲�-闆嗚绠�(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightCoal", "璐ц繍閲�-鐓ょ偔(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightOilGas", "璐ц繍閲�-娌规皵(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightCrudeOil", "璐ц繍閲�-鍘熸补(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightMetalOre", "璐ц繍閲�-閲戝睘鐭跨煶(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightIronOre", "璐ц繍閲�-閾佺熆鐭�(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightBuilding", "璐ц繍閲�-寤烘潗(鍚�)", 140));
+        H2032_COLUMNS.add(col("freightGrain", "璐ц繍閲�-绮(鍚�)", 140));
+        H2032_COLUMNS.add(col("avgTonnage", "骞冲潎鍚ㄤ綅(鍚�)", 120));
+        H2032_COLUMNS.add(col("avgDistance", "骞冲潎杩愯窛(鍏噷)", 120));
         H2032_COLUMNS.add(col("unitLeader", "鍗曚綅璐熻矗浜�", 110));
         H2032_COLUMNS.add(col("statsLeader", "缁熻璐熻矗浜�", 110));
         H2032_COLUMNS.add(col("contactPerson", "濉〃浜�", 100));
@@ -227,46 +610,224 @@
 
         AUTH_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
         AUTH_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 240));
-        AUTH_COLUMNS.add(col("tractorCount", "鐗靛紩杞︽暟", 100));
-        AUTH_COLUMNS.add(col("trailerCount", "鎸傝溅鏁�", 100));
-        AUTH_COLUMNS.add(col("otherCount", "鍏朵粬杞︽暟", 100));
-        AUTH_COLUMNS.add(col("trailerTons", "鎸傝溅鍚ㄤ綅", 110));
-        AUTH_COLUMNS.add(col("otherTons", "鍏朵粬鍚ㄤ綅", 110));
+        AUTH_COLUMNS.add(col("tractorCount", "鐗靛紩杞︽暟(杈�)", 110));
+        AUTH_COLUMNS.add(col("trailerCount", "鎸傝溅鏁�(杈�)", 110));
+        AUTH_COLUMNS.add(col("otherCount", "鍏朵粬杞︽暟(杈�)", 110));
+        AUTH_COLUMNS.add(col("trailerTons", "鎸傝溅鍚ㄤ綅(鍚�)", 120));
+        AUTH_COLUMNS.add(col("otherTons", "鍏朵粬鍚ㄤ綅(鍚�)", 120));
 
         TRACK_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
         TRACK_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 240));
-        TRACK_COLUMNS.add(col("monthlyMileage", "鏈堝害閲岀▼", 120));
-        TRACK_COLUMNS.add(col("trackedVehicles", "杞ㄨ抗杞﹁締鏁�", 120));
+        TRACK_COLUMNS.add(col("monthlyMileage", "鏈堝害閲岀▼(鍏噷)", 130));
+        TRACK_COLUMNS.add(col("trackedVehicles", "杞ㄨ抗杞﹁締鏁�(杈�)", 130));
 
         SPLIT_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
         SPLIT_COLUMNS.add(col("periodType", "鍙e緞", 90));
         SPLIT_COLUMNS.add(col("regionName", "甯傚窞", 130));
-        SPLIT_COLUMNS.add(col("aboveScaleFreight", "瑙勪笂璐ц繍閲�", 120));
-        SPLIT_COLUMNS.add(col("aboveScaleTurnover", "瑙勪笂鍛ㄨ浆閲�", 120));
-        SPLIT_COLUMNS.add(col("aboveScaleRank", "瑙勪笂鎺掑悕", 100));
-        SPLIT_COLUMNS.add(col("aboveScaleYoy", "瑙勪笂鍚屾瘮", 100));
-        SPLIT_COLUMNS.add(col("belowScaleFreight", "瑙勪笅璐ц繍閲�", 120));
-        SPLIT_COLUMNS.add(col("belowScaleTurnover", "瑙勪笅鍛ㄨ浆閲�", 120));
-        SPLIT_COLUMNS.add(col("belowScaleRank", "瑙勪笅鎺掑悕", 100));
-        SPLIT_COLUMNS.add(col("belowScaleYoy", "瑙勪笅鍚屾瘮", 100));
-        SPLIT_COLUMNS.add(col("totalFreight", "鍚堣璐ц繍閲�", 120));
-        SPLIT_COLUMNS.add(col("totalTurnover", "鍚堣鍛ㄨ浆閲�", 120));
-        SPLIT_COLUMNS.add(col("totalRank", "鍚堣鎺掑悕", 100));
-        SPLIT_COLUMNS.add(col("totalYoy", "鍚堣鍚屾瘮", 100));
+        SPLIT_COLUMNS.add(col("aboveScaleFreight", "瑙勪笂璐ц繍閲�(涓囧惃)", 140));
+        SPLIT_COLUMNS.add(col("aboveScaleTurnover", "瑙勪笂鍛ㄨ浆閲�(涓囧惃鍏噷)", 170));
+        SPLIT_COLUMNS.add(col("aboveScaleRank", "瑙勪笂鎺掑悕(鍚�)", 110));
+        SPLIT_COLUMNS.add(col("aboveScaleYoy", "瑙勪笂鍚屾瘮(%)", 110));
+        SPLIT_COLUMNS.add(col("belowScaleFreight", "瑙勪笅璐ц繍閲�(涓囧惃)", 140));
+        SPLIT_COLUMNS.add(col("belowScaleTurnover", "瑙勪笅鍛ㄨ浆閲�(涓囧惃鍏噷)", 170));
+        SPLIT_COLUMNS.add(col("belowScaleRank", "瑙勪笅鎺掑悕(鍚�)", 110));
+        SPLIT_COLUMNS.add(col("belowScaleYoy", "瑙勪笅鍚屾瘮(%)", 110));
+        SPLIT_COLUMNS.add(col("totalFreight", "鍚堣璐ц繍閲�(涓囧惃)", 140));
+        SPLIT_COLUMNS.add(col("totalTurnover", "鍚堣鍛ㄨ浆閲�(涓囧惃鍏噷)", 170));
+        SPLIT_COLUMNS.add(col("totalRank", "鍚堣鎺掑悕(鍚�)", 110));
+        SPLIT_COLUMNS.add(col("totalYoy", "鍚堣鍚屾瘮(%)", 110));
 
         FREIGHT_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
         FREIGHT_COLUMNS.add(col("regionName", "甯傚窞", 130));
         for (int m = 1; m <= 12; m++) {
-            FREIGHT_COLUMNS.add(col(String.format("freightM%02d", m), "璐ц繍閲�" + m + "鏈�", 110));
+            FREIGHT_COLUMNS.add(col(String.format("freightM%02d", m), "璐ц繍閲�" + m + "鏈�(涓囧惃)", 140));
         }
         for (int m = 1; m <= 12; m++) {
-            FREIGHT_COLUMNS.add(col(String.format("lastFreightM%02d", m), "鍘诲勾璐ц繍閲�" + m + "鏈�", 130));
+            FREIGHT_COLUMNS.add(col(String.format("lastFreightM%02d", m), "鍘诲勾璐ц繍閲�" + m + "鏈�(涓囧惃)", 160));
         }
         for (int m = 1; m <= 12; m++) {
-            FREIGHT_COLUMNS.add(col(String.format("turnoverM%02d", m), "鍛ㄨ浆閲�" + m + "鏈�", 120));
+            FREIGHT_COLUMNS.add(col(String.format("turnoverM%02d", m), "鍛ㄨ浆閲�" + m + "鏈�(涓囧惃鍏噷)", 160));
         }
         for (int m = 1; m <= 12; m++) {
-            FREIGHT_COLUMNS.add(col(String.format("lastTurnoverM%02d", m), "鍘诲勾鍛ㄨ浆閲�" + m + "鏈�", 140));
+            FREIGHT_COLUMNS.add(col(String.format("lastTurnoverM%02d", m), "鍘诲勾鍛ㄨ浆閲�" + m + "鏈�(涓囧惃鍏噷)", 180));
         }
+
+        H2031_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        H2031_COLUMNS.add(col("regionCode", "鎵�灞炲湴鍖�", 100));
+        H2031_COLUMNS.add(col("city", "甯傚窞", 110));
+        H2031_COLUMNS.add(col("enterpriseCode", "浼佷笟浠g爜", 130));
+        H2031_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 220));
+        H2031_COLUMNS.add(col("unifiedCreditCode", "缁熶竴绀句細淇$敤浠g爜", 180));
+        H2031_COLUMNS.add(col("reportUnit", "濉姤鍗曚綅", 160));
+        H2031_COLUMNS.add(col("vehicleTotal", "瀹㈣繍杞﹁締鍚堣(杈�)", 130));
+        H2031_COLUMNS.add(col("seatTotal", "鏍稿畾杞藉浣嶅悎璁�(搴�)", 150));
+        H2031_COLUMNS.add(col("vehicleSchedule", "鐝嚎杞﹁締鏁�(杈�)", 130));
+        H2031_COLUMNS.add(col("seatSchedule", "鐝嚎杞藉浣�(搴�)", 130));
+        H2031_COLUMNS.add(col("vehicleCharter", "鍖呰溅杞﹁締鏁�(杈�)", 130));
+        H2031_COLUMNS.add(col("seatCharter", "鍖呰溅杞藉浣�(搴�)", 130));
+        H2031_COLUMNS.add(col("passengerTotal", "瀹㈣繍閲忓悎璁�(浜�)", 130));
+        H2031_COLUMNS.add(col("turnoverTotal", "鍛ㄨ浆閲忓悎璁�(浜哄叕閲�)", 140));
+        H2031_COLUMNS.add(col("passengerClass1", "瀹㈣繍閲忎竴绫�(浜�)", 120));
+        H2031_COLUMNS.add(col("passengerClass2", "瀹㈣繍閲忎簩绫�(浜�)", 120));
+        H2031_COLUMNS.add(col("passengerClass3", "瀹㈣繍閲忎笁绫�(浜�)", 120));
+        H2031_COLUMNS.add(col("passengerClass4", "瀹㈣繍閲忓洓绫�(浜�)", 120));
+        H2031_COLUMNS.add(col("passengerCharter", "瀹㈣繍閲忓寘杞�(浜�)", 130));
+        H2031_COLUMNS.add(col("turnoverClass1", "鍛ㄨ浆閲忎竴绫�(浜哄叕閲�)", 140));
+        H2031_COLUMNS.add(col("turnoverClass2", "鍛ㄨ浆閲忎簩绫�(浜哄叕閲�)", 140));
+        H2031_COLUMNS.add(col("turnoverClass3", "鍛ㄨ浆閲忎笁绫�(浜哄叕閲�)", 140));
+        H2031_COLUMNS.add(col("turnoverClass4", "鍛ㄨ浆閲忓洓绫�(浜哄叕閲�)", 140));
+        H2031_COLUMNS.add(col("turnoverCharter", "鍛ㄨ浆閲忓寘杞�(浜哄叕閲�)", 150));
+        H2031_COLUMNS.add(col("avgDistanceTotal", "骞冲潎杩愯窛鍚堣(鍏噷)", 140));
+        H2031_COLUMNS.add(col("avgDistanceClass1", "涓�绫诲钩鍧囪繍璺�(鍏噷)", 140));
+        H2031_COLUMNS.add(col("avgDistanceClass2", "浜岀被骞冲潎杩愯窛(鍏噷)", 140));
+        H2031_COLUMNS.add(col("avgDistanceClass3", "涓夌被骞冲潎杩愯窛(鍏噷)", 140));
+        H2031_COLUMNS.add(col("avgDistanceClass4", "鍥涚被骞冲潎杩愯窛(鍏噷)", 140));
+        H2031_COLUMNS.add(col("avgDistanceCharter", "鍖呰溅骞冲潎杩愯窛(鍏噷)", 140));
+        BUS_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        BUS_COLUMNS.add(col("regionCode", "鎵�灞炲湴鍖�", 100));
+        BUS_COLUMNS.add(col("city", "甯傚窞", 110));
+        BUS_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 220));
+        BUS_COLUMNS.add(col("opVehicles", "杩愯惀杞︽暟(杈�)", 120));
+        BUS_COLUMNS.add(col("stopTotal", "绔欑偣鎬讳釜鏁�(涓�)", 130));
+        BUS_COLUMNS.add(col("stopCity", "鍩庡競鍐呯珯鐐�(涓�)", 130));
+        BUS_COLUMNS.add(col("passengerVolume", "瀹㈣繍閲�(涓囦汉娆�)", 120));
+        BUS_COLUMNS.add(col("passengerCity", "鍩庡競鍐呭杩愰噺(涓囦汉娆�)", 150));
+        BUS_COLUMNS.add(col("turnover", "鏃呭鍛ㄨ浆閲�(涓囦汉鍏噷)", 170));
+        BUS_COLUMNS.add(col("turnoverCity", "鍩庡競鍐呭懆杞噺(涓囦汉鍏噷)", 180));
+        BUS_COLUMNS.add(col("avgDistance", "骞冲潎杩愯窛(鍏噷)", 120));
+        BUS_COLUMNS.add(col("avgDistanceCity", "鍩庡競鍐呭钩鍧囪繍璺�(鍏噷)", 150));
+        BUS_COLUMNS.add(col("passengerChengxiang", "鍩庨檯鍩庝埂瀹㈣繍閲�(涓囦汉娆�)", 160));
+        BUS_COLUMNS.add(col("turnoverChengxiang", "鍩庨檯鍩庝埂鍛ㄨ浆閲�(涓囦汉鍏噷)", 190));
+        BUS_COLUMNS.add(col("avgDistanceChengxiang", "鍩庨檯鍩庝埂骞冲潎杩愯窛(鍏噷)", 160));
+        BUS_COLUMNS.add(col("ratePassengerMom", "瀹㈣繍閲忕幆姣�", 100));
+        BUS_COLUMNS.add(col("ratePassengerCityMom", "鍩庡競鍐呯幆姣�", 100));
+        BUS_COLUMNS.add(col("rateChengxiangMom", "鍩庨檯鍩庝埂鐜瘮", 110));
+        BUS_COLUMNS.add(col("ratePassengerYoy", "瀹㈣繍閲忓悓姣�", 100));
+        BUS_COLUMNS.add(col("passengerCityRatio", "鍩庡競鍐呭崰姣�", 100));
+        BUS_COLUMNS.add(col("chengxiangRatio", "鍩庨檯鍩庝埂鍗犳瘮", 110));
+        BUS_COLUMNS.add(col("contactPerson", "濉〃浜�", 100));
+        BUS_COLUMNS.add(col("reportDate", "鎶ュ嚭鏃ユ湡", 110));
+        BUS_COLUMNS.add(col("verifyExplanation", "鏍稿疄瑙i噴", 220));
+        TAXI_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        TAXI_COLUMNS.add(col("regionCode", "鎵�灞炲湴鍖�", 100));
+        TAXI_COLUMNS.add(col("city", "甯傚窞", 110));
+        TAXI_COLUMNS.add(col("tripTotal", "杞藉杞︽鎬绘暟(杞︽)", 150));
+        TAXI_COLUMNS.add(col("tripCity", "杞藉杞︽_鍩庡競鍐�(杞︽)", 160));
+        TAXI_COLUMNS.add(col("passengerVolume", "瀹㈣繍閲�(涓囦汉娆�)", 120));
+        TAXI_COLUMNS.add(col("passengerCity", "鍩庡競鍐呭杩愰噺(涓囦汉娆�)", 150));
+        TAXI_COLUMNS.add(col("turnover", "鏃呭鍛ㄨ浆閲�(涓囦汉鍏噷)", 170));
+        TAXI_COLUMNS.add(col("turnoverCity", "鍩庡競鍐呭懆杞噺(涓囦汉鍏噷)", 180));
+        TAXI_COLUMNS.add(col("opVehicles", "杩愯惀杞﹁締鏁�(杈�)", 130));
+        TAXI_COLUMNS.add(col("avgDistance", "骞冲潎杩愯窛(鍏噷)", 120));
+        TAXI_COLUMNS.add(col("avgDistanceCity", "鍩庡競鍐呭钩鍧囪繍璺�(鍏噷)", 150));
+        TAXI_COLUMNS.add(col("passengersPerTrip", "鍗曡溅娆¤浇瀹汉鏁�(浜�/杞︽)", 170));
+        TAXI_COLUMNS.add(col("rateTripMom", "杞藉杞︽鐜瘮", 110));
+        TAXI_COLUMNS.add(col("rateTripYoy", "杞藉杞︽鍚屾瘮", 110));
+        TAXI_COLUMNS.add(col("ratePassengerMom", "瀹㈣繍閲忕幆姣�", 100));
+        TAXI_COLUMNS.add(col("ratePassengerYoy", "瀹㈣繍閲忓悓姣�", 100));
+        TAXI_COLUMNS.add(col("passengerCityRatio", "鍩庡競鍐呭杩愰噺鍗犳瘮", 140));
+        TAXI_COLUMNS.add(col("avgDistanceChengxiang", "鍩庨檯鍩庝埂骞冲潎杩愯窛(鍏噷)", 160));
+        TAXI_COLUMNS.add(col("verifyExplanation", "鏍稿疄瑙i噴", 220));
+        TAXI_AUTH_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        TAXI_AUTH_COLUMNS.add(col("city", "甯傚窞", 110));
+        TAXI_AUTH_COLUMNS.add(col("plateNo", "杞︾墝鍙风爜", 120));
+        TAXI_AUTH_COLUMNS.add(col("vehicleType", "杞﹁締绫诲瀷", 110));
+        TAXI_AUTH_COLUMNS.add(col("fuelType", "鐕冩枡绫诲瀷", 100));
+        TAXI_AUTH_COLUMNS.add(col("opStatus", "钀ヨ繍鐘舵��", 100));
+        TAXI_AUTH_COLUMNS.add(col("certStatus", "璇佷欢鐘舵��", 100));
+        TAXI_AUTH_COLUMNS.add(col("licenseNo", "缁忚惀鏉冨彿", 130));
+        TAXI_AUTH_COLUMNS.add(col("archiveNo", "妗f鍙�", 130));
+        TAXI_AUTH_COLUMNS.add(col("roadCertNo", "閬撹矾杩愯緭璇佸瓧鍙�", 150));
+        TAXI_AUTH_COLUMNS.add(col("operatorName", "涓氭埛鍚嶇О", 240));
+        TAXI_AUTH_COLUMNS.add(col("operatorAddr", "涓氭埛鍦板潃", 280));
+        PAUTH_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        PAUTH_COLUMNS.add(col("enterpriseCode", "浼佷笟浠g爜", 130));
+        PAUTH_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 240));
+        PAUTH_COLUMNS.add(col("vehicleCount", "杞﹁締鏁�(杈�)", 110));
+        PAUTH_COLUMNS.add(col("seatCount", "杞藉浣嶆暟(搴�)", 120));
+        INVEST_MONTHLY_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        INVEST_MONTHLY_COLUMNS.add(col("projectId", "椤圭洰ID", 80));
+        INVEST_MONTHLY_COLUMNS.add(col("projectName", "椤圭洰鍚嶇О", 280));
+        INVEST_MONTHLY_COLUMNS.add(col("city", "甯傚窞", 90));
+        INVEST_MONTHLY_COLUMNS.add(col("yearPlan", "鏈勾璁″垝鎶曡祫(涓囧厓)", 140));
+        INVEST_MONTHLY_COLUMNS.add(col("yearCum", "鑷勾鍒濈疮璁″畬鎴�(涓囧厓)", 160));
+        INVEST_MONTHLY_COLUMNS.add(col("monthDone", "鏈湀瀹屾垚鎶曡祫(涓囧厓)", 150));
+        INVEST_MONTHLY_COLUMNS.add(col("startCum", "鑷紑濮嬪缓璁剧疮璁″畬鎴�(涓囧厓)", 180));
+        INVEST_MONTHLY_COLUMNS.add(col("progressStage", "寤鸿闃舵", 120));
+        INVEST_MONTHLY_COLUMNS.add(col("progressDesc", "褰㈣薄杩涘害", 320));
+        INVEST_MONTHLY_COLUMNS.add(col("buildingArea", "寤虹瓚闈㈢Н(骞虫柟绫�)", 140));
+        INVEST_PROJECT_COLUMNS.add(col("projectName", "椤圭洰鍚嶇О", 260));
+        INVEST_PROJECT_COLUMNS.add(col("category", "绫诲埆", 100));
+        INVEST_PROJECT_COLUMNS.add(col("city", "甯傚窞", 90));
+        INVEST_PROJECT_COLUMNS.add(col("county", "鍘匡紙甯傘�佸尯锛�", 120));
+        INVEST_PROJECT_COLUMNS.add(col("builderName", "寤鸿鍗曚綅", 200));
+        INVEST_PROJECT_COLUMNS.add(col("constructNature", "寤鸿鎬ц川", 100));
+        INVEST_PROJECT_COLUMNS.add(col("startTime", "寮�宸ュ勾", 90));
+        INVEST_PROJECT_COLUMNS.add(col("endTime", "瀹屽伐骞�", 90));
+        INVEST_PROJECT_COLUMNS.add(col("totalInvestment", "鎬绘姇璧�(涓囧厓)", 130));
+        INVEST_PROJECT_COLUMNS.add(col("buildingArea", "寤虹瓚闈㈢Н(骞虫柟绫�)", 140));
+        INVEST_PROJECT_COLUMNS.add(col("approvalGk", "宸ュ彲鎴栨牳鍑嗘壒澶嶆枃鍙�", 200));
+        INVEST_PROJECT_COLUMNS.add(col("approvalCs", "鍒濊鎴栨柦宸ュ浘鎵瑰鏂囧彿", 200));
+        INVEST_PROJECT_COLUMNS.add(col("source", "鏉ユ簮", 100));
+        INVEST_SYSTEM_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        INVEST_SYSTEM_COLUMNS.add(col("projectName", "椤圭洰鍚嶇О", 260));
+        INVEST_SYSTEM_COLUMNS.add(col("totalInvestment", "鎬绘姇璧�(涓囧厓)", 130));
+        INVEST_SYSTEM_COLUMNS.add(col("startCum", "鑷紑濮嬪缓璁剧疮璁″畬鎴�(涓囧厓)", 180));
+        INVEST_SYSTEM_COLUMNS.add(col("yearPlan", "鏈勾璁″垝鎶曡祫(涓囧厓)", 140));
+        INVEST_SYSTEM_COLUMNS.add(col("yearCum", "鑷勾鍒濈疮璁″畬鎴�(涓囧厓)", 160));
+        INVEST_SYSTEM_COLUMNS.add(col("monthDone", "鏈湀瀹屾垚鎶曡祫(涓囧厓)", 150));
+        ENERGY_VEHICLE_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        ENERGY_VEHICLE_COLUMNS.add(col("regionCode", "鎵�灞炲湴鍖�", 100));
+        ENERGY_VEHICLE_COLUMNS.add(col("city", "甯傚窞", 110));
+        ENERGY_VEHICLE_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 220));
+        ENERGY_VEHICLE_COLUMNS.add(col("plateNo", "杞︾墝鍙�", 110));
+        ENERGY_VEHICLE_COLUMNS.add(col("vehicleType", "杞﹁締绫诲瀷", 130));
+        ENERGY_VEHICLE_COLUMNS.add(col("fuelType", "鐕冩枡绫诲瀷", 110));
+        ENERGY_VEHICLE_COLUMNS.add(col("manufactureYear", "鍑哄巶骞翠唤", 100));
+        ENERGY_VEHICLE_COLUMNS.add(col("markedTonnage", "鏍囪鍚ㄤ綅(鍚�)", 120));
+        ENERGY_VEHICLE_COLUMNS.add(col("totalMileage", "鎬昏椹堕噷绋�(鍏噷)", 150));
+        ENERGY_VEHICLE_COLUMNS.add(col("loadedMileage", "閲嶈浇閲岀▼(鍏噷)", 140));
+        ENERGY_VEHICLE_COLUMNS.add(col("emptyMileage", "绌鸿浇閲岀▼(鍏噷)", 140));
+        ENERGY_VEHICLE_COLUMNS.add(col("freight", "璐ц繍閲�(鍚�)", 120));
+        ENERGY_VEHICLE_COLUMNS.add(col("turnover", "鍛ㄨ浆閲�(鍚ㄥ叕閲�)", 140));
+        ENERGY_VEHICLE_COLUMNS.add(col("tripCount", "杞︽(娆�)", 100));
+        ENERGY_VEHICLE_COLUMNS.add(col("fuelUnit", "鐕冩枡鍗曚綅", 100));
+        ENERGY_VEHICLE_COLUMNS.add(col("fuelConsumption", "鐕冩枡娑堣�楅噺(鎸夌噧鏂欏崟浣�)", 170));
+        ENERGY_VEHICLE_COLUMNS.add(col("avgDistance", "骞冲潎杩愯窛(鍏噷)", 130));
+        ENERGY_VEHICLE_COLUMNS.add(col("avgLoadedTonnage", "骞冲潎杞介噸鍚ㄤ綅(鍚�)", 150));
+        ENERGY_VEHICLE_COLUMNS.add(col("avgTripMileage", "骞冲潎杞︽閲岀▼(鍏噷)", 150));
+        ENERGY_VEHICLE_COLUMNS.add(col("fuelPer100km", "鐧惧叕閲屾补鑰�(鎸夌噧鏂欏崟浣�)", 170));
+        ENERGY_VEHICLE_COLUMNS.add(col("turnoverFuel", "鍛ㄨ浆閲忔补鑰�(鎸夌噧鏂欏崟浣�)", 170));
+        ENERGY_AUTH_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        ENERGY_AUTH_COLUMNS.add(col("plateNo", "杞︾墝鍙�", 110));
+        ENERGY_AUTH_COLUMNS.add(col("vehicleType", "杞﹁締绫诲瀷", 130));
+        ENERGY_AUTH_COLUMNS.add(col("fuelType", "鐕冩枡绫诲瀷", 110));
+        ENERGY_AUTH_COLUMNS.add(col("markedTonnage", "鏍囪鍚ㄤ綅(鍚�)", 120));
+        ENERGY_AUTH_COLUMNS.add(col("tractionQuality", "鐗靛紩璐ㄩ噺(鍚�)", 130));
+
+        PAX_INDIVIDUAL_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        PAX_INDIVIDUAL_COLUMNS.add(col("regionCode", "鎵�灞炲湴鍖�", 110));
+        PAX_INDIVIDUAL_COLUMNS.add(col("city", "甯傚窞", 110));
+        PAX_INDIVIDUAL_COLUMNS.add(col("enterpriseCode", "浼佷笟浠g爜", 130));
+        PAX_INDIVIDUAL_COLUMNS.add(col("enterpriseName", "浼佷笟鍚嶇О", 220));
+        PAX_INDIVIDUAL_COLUMNS.add(col("passengerCount", "涓綋瀹㈣繍閲�(浜�)", 140));
+        PAX_INDIVIDUAL_COLUMNS.add(col("turnover", "涓綋鏃呭鍛ㄨ浆閲�(浜哄叕閲�)", 180));
+
+        WYC_TOTAL_COLUMNS.add(col("reportPeriod", "鎶ヨ〃鏈�", 100));
+        WYC_TOTAL_COLUMNS.add(col("pinK", "鍏ㄧ渷缃戠害杞﹀杩愰噺(涓囦汉娆�)", 210));
+        WYC_TOTAL_COLUMNS.add(col("pinCK", "鍏朵腑鍩庡競鍐呭杩愰噺(涓囦汉娆�)", 210));
+        WYC_TOTAL_COLUMNS.add(col("pinZ", "鍏ㄧ渷缃戠害杞﹀懆杞噺(涓囦汉鍏噷)", 220));
+        WYC_TOTAL_COLUMNS.add(col("pinCZ", "鍏朵腑鍩庡競鍐呭懆杞噺(涓囦汉鍏噷)", 220));
+
+        WYC_ORDER_COLUMNS.add(col("region", "鍦板尯", 110));
+        WYC_ORDER_COLUMNS.add(col("period", "鏈熼棿", 100));
+        WYC_ORDER_COLUMNS.add(col("orderCount", "璁㈠崟鏁�(鍗�)", 130));
+        WYC_ORDER_COLUMNS.add(col("orderShare", "璁㈠崟鍗犳瘮", 100));
+        WYC_ORDER_COLUMNS.add(col("pax", "瀹㈣繍閲�(涓囦汉娆�)", 140));
+        WYC_ORDER_COLUMNS.add(col("turnover", "鏃呭鍛ㄨ浆閲�(涓囦汉鍏噷)", 180));
+        WYC_ORDER_COLUMNS.add(col("cityPax", "鍏朵腑鍩庡競鍐呭杩愰噺(涓囦汉娆�)", 190));
+        WYC_ORDER_COLUMNS.add(col("cityTurnover", "鍏朵腑鍩庡競鍐呮梾瀹㈠懆杞噺(涓囦汉鍏噷)", 230));
+        WYC_ORDER_COLUMNS.add(col("note", "璇存槑", 200));
+
     }
 }
\ No newline at end of file

--
Gitblit v1.9.1