|  |  | package com.sunyo.wlpt.cgonms.provide.controller; | 
|  |  |  | 
|  |  | import com.google.common.collect.Lists; | 
|  |  |  | 
|  |  | import com.sunyo.wlpt.cgonms.provide.domain.*; | 
|  |  | import com.sunyo.wlpt.cgonms.provide.feign.GetCgoAsmFeign; | 
|  |  | import com.sunyo.wlpt.cgonms.provide.feign.GetDataWareHouseFeign; | 
|  |  | import com.sunyo.wlpt.cgonms.provide.feign.GetTransportFeign; | 
|  |  | import com.sunyo.wlpt.cgonms.provide.service.*; | 
|  |  | import com.sunyo.wlpt.cgonms.provide.thread.ExitThreadPoolFactory; | 
|  |  | import lombok.extern.slf4j.Slf4j; | 
|  |  | import org.springframework.web.bind.annotation.*; | 
|  |  |  | 
|  |  | import javax.annotation.Resource; | 
|  |  | import java.text.SimpleDateFormat; | 
|  |  | import java.util.Date; | 
|  |  | import java.util.List; | 
|  |  | import java.util.concurrent.CountDownLatch; | 
|  |  | import java.util.concurrent.ThreadPoolExecutor; | 
|  |  |  | 
|  |  | /** | 
|  |  | * @author 子诚 | 
|  |  | * Description:多线程获取出港数据统计 | 
|  |  | * 时间:2020/5/26 21:18 | 
|  |  | */ | 
|  |  | @CrossOrigin | 
|  |  | @Slf4j | 
|  |  | @RequestMapping("cgoNms") | 
|  |  | @RestController | 
|  |  | public class NmsController { | 
|  |  | @Resource | 
|  |  | private ResultExitDataService resultExitDataService; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | private PrepareMasterService prepareMasterService; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | private BasAirportService basAirportService; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | private TbAirportCodeService tbAirportCodeService; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | private BasAreaService basAreaService; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | private GetCgoAsmFeign getCgoAsmFeign; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | private GetTransportFeign getTransportFeign; | 
|  |  |  | 
|  |  | @Resource | 
|  |  | GetDataWareHouseFeign getDataWareHouseFeign; | 
|  |  |  | 
|  |  | /** | 
|  |  | * 线程数量 | 
|  |  | */ | 
|  |  | private final static int THREAD_ACCOUNT = 50; | 
|  |  |  | 
|  |  | /** | 
|  |  | * 开启多线程 | 
|  |  | */ | 
|  |  | ThreadPoolExecutor threadPool = ExitThreadPoolFactory.instance(); | 
|  |  |  | 
|  |  | /** | 
|  |  | * 获取开始时间,结束时间 | 
|  |  | */ | 
|  |  | final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); | 
|  |  |  | 
|  |  |  | 
|  |  | /** | 
|  |  | * 根据航班日期、航班号,获取出出港业务统计数据 | 
|  |  | * | 
|  |  | * @param flightDate 航班日期 | 
|  |  | * @param flightNo   航班号 | 
|  |  | * @return {@link ResultExitData} | 
|  |  | */ | 
|  |  | @GetMapping("/getInfo") | 
|  |  | public List<ResultExitData> getData( | 
|  |  | @RequestParam(value = "flightDate", required = false) Date flightDate, | 
|  |  | @RequestParam(value = "flightNo", required = false) String flightNo) { | 
|  |  |  | 
|  |  | final String startTime = sdf.format(new Date()); | 
|  |  | System.out.println("开始时间:" + startTime); | 
|  |  | System.out.println("出港数据,开始获取"); | 
|  |  | /** | 
|  |  | * 查询出新舱单里面回执表里面的数据条件 | 
|  |  | */ | 
|  |  | ResultExitData resultExitData = new ResultExitData(); | 
|  |  | resultExitData.setFlightDate(flightDate); | 
|  |  | resultExitData.setFlightNo(flightNo); | 
|  |  | List<ResultExitData> resultList = resultExitDataService.getResultExitDataInfo(resultExitData); | 
|  |  | System.out.println("长度为:" + resultList.size()); | 
|  |  | //控制index,查询数据的时候,保证索引的位置不出错 | 
|  |  | int index = 0; | 
|  |  | try { | 
|  |  | // 如果数据大于50个,则每次获取前50条。逐次获取 | 
|  |  | if (resultList != null && !resultList.isEmpty() && resultList.size() > THREAD_ACCOUNT) { | 
|  |  | while (index < resultList.size()) { | 
|  |  | //如果剩余未处理的数量 大于 等于线程数量,则遍历次数为线程数量 | 
|  |  | if (resultList.size() - index >= THREAD_ACCOUNT) { | 
|  |  | CountDownLatch latch = new CountDownLatch(THREAD_ACCOUNT); | 
|  |  | log.trace("获取开始{},剩余数量:{}", startTime, resultList.size()); | 
|  |  | int i; | 
|  |  | for (i = 0; i < THREAD_ACCOUNT; i++) { | 
|  |  | ResultExitData result = threadJob(resultList.get(i + index), latch, threadPool); | 
|  |  | resultList.set(i, result); | 
|  |  | } | 
|  |  | index = index + i; | 
|  |  | //完成一次,就等待。每次减1,为0的时候往下执行 | 
|  |  | latch.await(); | 
|  |  | } | 
|  |  | //如果剩余未处理的数量小于线程数量,则遍历次数为 | 
|  |  | else if (resultList.size() - index < THREAD_ACCOUNT) { | 
|  |  | CountDownLatch latch = new CountDownLatch(resultList.size() - index); | 
|  |  | log.trace("获取开始{},剩余数量:{}", startTime, resultList.size()); | 
|  |  | int i; | 
|  |  | for (i = 0; i < resultList.size() - index; i++) { | 
|  |  | ResultExitData result = threadJob(resultList.get(i + index), latch, threadPool); | 
|  |  | resultList.set(i, result); | 
|  |  | } | 
|  |  | index = index + i; | 
|  |  | //完成一次,就等待。每次减1,为0的时候往下执行 | 
|  |  | latch.await(); | 
|  |  | } | 
|  |  | } | 
|  |  | } | 
|  |  | // 如果数据小于等于50个,则每次获取前50条。逐次获取 | 
|  |  | else if (resultList != null && !resultList.isEmpty() && resultList.size() <= THREAD_ACCOUNT) { | 
|  |  | CountDownLatch latch = new CountDownLatch(resultList.size()); | 
|  |  | log.trace("获取开始{},剩余数量:{}", startTime, resultList.size()); | 
|  |  | for (int i = 0; i < resultList.size(); i++) { | 
|  |  | ResultExitData result = threadJob(resultList.get(i), latch, threadPool); | 
|  |  | resultList.set(i, result); | 
|  |  | } | 
|  |  | //完成一次,就等待。等所有的全部完成,再一起返回 | 
|  |  | latch.await(); | 
|  |  | } | 
|  |  | } catch (Exception e) { | 
|  |  | e.printStackTrace(); | 
|  |  | log.error("获取目录文件出错", e); | 
|  |  | } | 
|  |  |  | 
|  |  | final String endTime = sdf.format(new Date()); | 
|  |  | System.out.println("结束时间:" + endTime); | 
|  |  | System.out.println("出港信息,获取完毕"); | 
|  |  | System.out.println("index的值为:" + index); | 
|  |  | return resultList; | 
|  |  | } | 
|  |  |  | 
|  |  | /** | 
|  |  | * 使用线程获取数据. | 
|  |  | * | 
|  |  | * @param result     返回数据 | 
|  |  | * @param latch      计数器 | 
|  |  | * @param threadPool 线程池 | 
|  |  | * @return | 
|  |  | */ | 
|  |  | private ResultExitData threadJob(ResultExitData result, CountDownLatch latch, ThreadPoolExecutor threadPool) { | 
|  |  | Runnable run = new Runnable() { | 
|  |  | @Override | 
|  |  | public void run() { | 
|  |  |  | 
|  |  | //设置航班 | 
|  |  | result.setSegment(result.getOriginatingStation() + " — " + result.getDestinationStation()); | 
|  |  |  | 
|  |  | //设置承运人二字码 | 
|  |  | result.setCarrier(result.getFlightNo().substring(0, 2)); | 
|  |  |  | 
|  |  | /** | 
|  |  | * 3.根据 理货信息 中的目的站代码,获取 新舱单机场代码表 中的相应数据 | 
|  |  | * | 
|  |  | *  机场所属城市代码 | 
|  |  | */ | 
|  |  | BasAirport ba = basAirportService.getBasAirportInfo(result.getDestinationStation()); | 
|  |  |  | 
|  |  | /** | 
|  |  | * 4.根据 新舱单机场代码表 中的 机场所属城市代码 ,获取 天博——机场代码表 的相应数据 | 
|  |  | * | 
|  |  | * 城市代码 | 
|  |  | * 区域id | 
|  |  | * 国家代码 | 
|  |  | */ | 
|  |  | TbAirportCode ta = tbAirportCodeService.getTbAirportCodeInfo(ba.getCityId()); | 
|  |  | // 所属国家代码 | 
|  |  | result.setCountry(ta.getCountry()); | 
|  |  |  | 
|  |  | /** | 
|  |  | * 5.根据 天博——机场代码表 中的 区域id,获取 新舱单——区域代码表 的相应数据 | 
|  |  | * | 
|  |  | * 区域id | 
|  |  | * 国际国内标识;1,国外;2,国内 | 
|  |  | * 区域描述,中文 | 
|  |  | */ | 
|  |  | BasArea basArea = basAreaService.getBasAreaInfo(ta.getArea()); | 
|  |  | //航班目的区域,中文描述,所属洲 | 
|  |  | result.setAreaDescChn(basArea.getAreaDescChn()); | 
|  |  |  | 
|  |  | /** | 
|  |  | * 6.根据  理货信息 中的运单号,获取预配表中的相应数据 | 
|  |  | * | 
|  |  | * 发货人名称 | 
|  |  | * 收货人名称 | 
|  |  | * 航班目的站 | 
|  |  | */ | 
|  |  | List<PrepareMaster> pm = prepareMasterService.getPrepareMasterInfo(result.getWaybillNoMaster()); | 
|  |  | if (pm != null && pm.size() > 0) { | 
|  |  | //发货人名称 | 
|  |  | result.setShipperName(pm.get(0).getShipperName()); | 
|  |  | //收货人名称 | 
|  |  | result.setConsigneeName(pm.get(0).getConsigneeName()); | 
|  |  | //获取目的货物目的站 | 
|  |  | result.setAimStation(pm.get(0).getDestinationStation()); | 
|  |  | } | 
|  |  | /** | 
|  |  | * 获取数据仓库的对应数据 | 
|  |  |  | 
|  |  | //            if (result.getWaybillNoMaster() != null && result.getWaybillNoMaster() != "") {} | 
|  |  | ResultExitData dataWareHouseInfo=new ResultExitData(); | 
|  |  | dataWareHouseInfo = getDataWareHouseFeign.getInfo(result.getWaybillNoMaster()); | 
|  |  | //设置体积 | 
|  |  | result.setVolumeMeasure(dataWareHouseInfo.getVolumeMeasure()); | 
|  |  | //设置计费重量 | 
|  |  | result.setTotalGrossWeightMeasure(dataWareHouseInfo.getTotalGrossWeightMeasure()); | 
|  |  | */ | 
|  |  |  | 
|  |  | /** | 
|  |  | * 获取运输工具的对应数据 | 
|  |  | */ | 
|  |  | ResultExitData transportInfo = new ResultExitData(); | 
|  |  | transportInfo = getTransportFeign.getInfo(result.getFlightNo(), result.getFlightDate()); | 
|  |  | //设置航班公司 | 
|  |  | result.setAirCompany(transportInfo.getAirCompany()); | 
|  |  | //设置机型 | 
|  |  | result.setCfTp(transportInfo.getCfTp()); | 
|  |  | //设置机号 | 
|  |  | result.setCfNo(transportInfo.getCfNo()); | 
|  |  | //设置航班计划日期 | 
|  |  | result.setFlightPlanDate(transportInfo.getFlightPlanDate()); | 
|  |  | //设置航班(起飞)时间 | 
|  |  | result.setFlightTime(transportInfo.getFlightTime()); | 
|  |  | //设置航班计划时间 | 
|  |  | result.setFlightPlanTime(transportInfo.getFlightPlanTime()); | 
|  |  |  | 
|  |  | /** | 
|  |  | *  获取代理人的相关数据 | 
|  |  | */ | 
|  |  | //            if (result.getWaybillNoMaster() != null && result.getWaybillNoMaster() != "") { } | 
|  |  | ResultExitData asmInfo = new ResultExitData(); | 
|  |  | asmInfo = getCgoAsmFeign.getInfo(result.getWaybillNoMaster()); | 
|  |  | //设置代理人全称 | 
|  |  | result.setFullName(asmInfo.getFullName()); | 
|  |  | //设置货主类型 | 
|  |  | result.setTheShipperType(asmInfo.getTheShipperType()); | 
|  |  | //设置品名 | 
|  |  | result.setSdCargoName(asmInfo.getSdCargoName()); | 
|  |  | //设置二级类名称 | 
|  |  | result.setTwoTypeName(asmInfo.getTwoTypeName()); | 
|  |  | //设置一级类名称 | 
|  |  | result.setTypeName(asmInfo.getTypeName()); | 
|  |  | latch.countDown(); | 
|  |  | } | 
|  |  | }; | 
|  |  | threadPool.execute(run); | 
|  |  | return result; | 
|  |  | } | 
|  |  |  | 
|  |  |  | 
|  |  | } | 
... | ... |  |