parent
c82c470088
commit
36f6e25c07
@ -0,0 +1,282 @@ |
||||
package com.hfkj.channel.gas.shell; |
||||
|
||||
import com.alibaba.excel.util.CollectionUtils; |
||||
import com.alibaba.fastjson.JSONArray; |
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.hfkj.channel.gas.newlink.NewLinkRequestService; |
||||
import com.hfkj.entity.BsGasOilGunNo; |
||||
import com.hfkj.entity.BsGasOilPrice; |
||||
import com.hfkj.entity.BsMerchant; |
||||
import com.hfkj.service.gas.BsGasOilGunNoService; |
||||
import com.hfkj.service.gas.BsGasOilPriceService; |
||||
import com.hfkj.service.gas.BsGasService; |
||||
import com.hfkj.service.merchant.BsMerchantService; |
||||
import com.hfkj.sysenum.MerchantSourceTypeEnum; |
||||
import com.hfkj.sysenum.MerchantStatusEnum; |
||||
import com.hfkj.sysenum.gas.GasOilPriceStatusEnum; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import javax.annotation.Resource; |
||||
import java.math.BigDecimal; |
||||
import java.util.ArrayList; |
||||
import java.util.Date; |
||||
import java.util.List; |
||||
import java.util.concurrent.ArrayBlockingQueue; |
||||
import java.util.concurrent.CountDownLatch; |
||||
import java.util.concurrent.ThreadPoolExecutor; |
||||
import java.util.concurrent.TimeUnit; |
||||
import java.util.stream.Collectors; |
||||
|
||||
/** |
||||
* 重庆壳牌油站服务 |
||||
* @className: CqShellPetroleumService |
||||
* @author: HuRui |
||||
* @date: 2024/7/22 |
||||
**/ |
||||
@Component |
||||
public class CqShellPetroleumGasService { |
||||
|
||||
@Resource |
||||
private BsMerchantService merchantService; |
||||
@Resource |
||||
private BsGasService gasService; |
||||
@Resource |
||||
private BsGasOilPriceService gasOilPriceService; |
||||
@Resource |
||||
private BsGasOilGunNoService gasOilGunNoService; |
||||
|
||||
/** |
||||
* 刷取全量油站 |
||||
* @throws Exception |
||||
*/ |
||||
public void refresh() throws Exception { |
||||
// 最新全量加油站数据
|
||||
List<Object> gasDataList = new ArrayList<>(); |
||||
// 初始化页数
|
||||
Integer totalPageNum = 3; |
||||
// 每页数量
|
||||
Integer pageSize = 50; |
||||
for (int pageIndex = 1; pageIndex <= totalPageNum;pageIndex++) { |
||||
// 查询油站
|
||||
JSONObject object = CqShellPetroleumRequestService.gasPageQueryAllStation(pageIndex, pageSize); |
||||
// 总页数
|
||||
JSONObject pageInfo = JSONObject.parseObject(object.getString("pageInfo")); |
||||
totalPageNum = (pageInfo.getInteger("totalCount") + pageSize - 1) / pageSize; |
||||
// 加入全量数据集合
|
||||
gasDataList.addAll(JSONArray.parseArray(object.getString("infoList"))); |
||||
} |
||||
// 设备核心数目
|
||||
int processorsNum = Runtime.getRuntime().availableProcessors(); |
||||
|
||||
Long startTime = System.currentTimeMillis(); |
||||
System.out.println("本次更新任务开始"); |
||||
System.out.println("重庆壳牌"); |
||||
// 初始化线程池
|
||||
ThreadPoolExecutor threadPool = new ThreadPoolExecutor( |
||||
processorsNum * 2, |
||||
processorsNum * 2, |
||||
4, |
||||
TimeUnit.SECONDS, |
||||
new ArrayBlockingQueue(processorsNum * 2 * 10), |
||||
new ThreadPoolExecutor.DiscardPolicy()); |
||||
|
||||
// 大集合拆分成N个小集合,然后用多线程去处理数据,确保不会因为数据量过大导致执行过慢
|
||||
List<List<Object>> splitNList = splitList(gasDataList, 10); |
||||
// 记录单个任务的执行次数
|
||||
CountDownLatch countDownLatch = new CountDownLatch(splitNList.size()); |
||||
// 对拆分的集合进行批量处理, 先拆分的集合, 再多线程执行
|
||||
for (List<Object> singleList : splitNList) { |
||||
// 线程池执行
|
||||
threadPool.execute(new Thread(new Runnable(){ |
||||
@Override |
||||
public void run() { |
||||
//模拟执行时间
|
||||
System.out.println("当前线程:"+Thread.currentThread().getName()); |
||||
try { |
||||
for (Object obj : singleList) { |
||||
try { |
||||
//组装要执行的批量更新数据
|
||||
JSONObject gasData = (JSONObject) obj; |
||||
// 查询商户
|
||||
BsMerchant merchant = merchantService.getMerchant(gasData.getString("stationCode")); |
||||
if (merchant == null) { |
||||
merchant = new BsMerchant(); |
||||
merchant.setStatus(MerchantStatusEnum.status1.getNumber()); |
||||
} |
||||
merchant.setSourceType(MerchantSourceTypeEnum.type3.getNumber()); |
||||
merchant.setProvinceCode(gasData.getLong("provinceId")); |
||||
merchant.setProvinceName(gasData.getString("provinceName")); |
||||
merchant.setCityCode(gasData.getLong("cityId")); |
||||
merchant.setCityName(gasData.getString("cityName")); |
||||
merchant.setAreaCode(gasData.getLong("districtId")); |
||||
merchant.setAreaName(gasData.getString("districtName")); |
||||
merchant.setMerNo(gasData.getString("stationCode")); |
||||
merchant.setMerName(gasData.getString("stationName")); |
||||
merchant.setMerLogo("https://oil.dctpay.com/filesystem/gas_logo_default.jpg"); |
||||
merchant.setAddress(gasData.getString("stationAddress")); |
||||
merchant.setLongitude(gasData.getString("longitude")); |
||||
merchant.setLatitude(gasData.getString("latitude")); |
||||
merchant.setContactsName(merchant.getMerName()); |
||||
merchant.setContactsTel(merchant.getMerNo()); |
||||
merchant.setCustomerServiceTel("400-0236806"); |
||||
merchant.setMerLabel(null); |
||||
if (merchant.getId() == null) { |
||||
merchantService.createMerchant(merchant); |
||||
} else { |
||||
merchantService.updateMerchant(merchant); |
||||
} |
||||
|
||||
// 查询油站油价
|
||||
List<BsGasOilPrice> gasOilPriceList = gasOilPriceService.getGasOilPriceList(merchant.getId()); |
||||
if (!gasOilPriceList.isEmpty()) { |
||||
BsGasOilPrice oilPriceExample = new BsGasOilPrice(); |
||||
oilPriceExample.setStatus(GasOilPriceStatusEnum.status2.getNumber()); |
||||
gasOilPriceService.batchUpdate(merchant.getMerNo(), oilPriceExample); |
||||
} |
||||
// 查询油站抢号
|
||||
List<BsGasOilGunNo> oilGunNoList = gasOilGunNoService.getOilGunNoList(merchant.getMerNo()); |
||||
for (BsGasOilGunNo gunNo : oilGunNoList) { |
||||
gunNo.setStatus(0); |
||||
} |
||||
|
||||
JSONArray oilPriceList = gasData.getJSONArray("oilPriceList"); |
||||
for (Object oilPrice : oilPriceList) { |
||||
JSONObject oilPriceObject = JSONObject.parseObject(JSONObject.toJSONString(oilPrice)); |
||||
// 查询油站油价
|
||||
List<BsGasOilPrice> oilPriceCollect = gasOilPriceList.stream().filter(o -> o.getOilNo().equals(oilPriceObject.getString("goodsCode"))).collect(Collectors.toList()); |
||||
BsGasOilPrice gasOilPrice = null; |
||||
if (oilPriceCollect.isEmpty()) { |
||||
gasOilPrice = new BsGasOilPrice(); |
||||
gasOilPrice.setMerId(merchant.getId()); |
||||
gasOilPrice.setMerNo(merchant.getMerNo()); |
||||
gasOilPrice.setOilNo(oilPriceObject.getString("goodsCode")); |
||||
gasOilPrice.setOilNoName(oilPriceObject.getString("goodsCode")+"#"); |
||||
gasOilPrice.setStatus(GasOilPriceStatusEnum.status1.getNumber()); |
||||
// 油品类型 1:汽油:2:柴油;3:天然气
|
||||
if (oilPriceObject.getString("goodsGroupType").equals("GASOLINE")) { |
||||
gasOilPrice.setOilType(1); |
||||
gasOilPrice.setOilTypeName("汽油"); |
||||
} else if (oilPriceObject.getString("goodsGroupType").equals("DIESEL_OIL")) { |
||||
gasOilPrice.setOilType(2); |
||||
gasOilPrice.setOilTypeName("柴油"); |
||||
} else if (oilPriceObject.getString("goodsGroupType").equals("NATURAL_GAS")) { |
||||
gasOilPrice.setOilType(3); |
||||
gasOilPrice.setOilTypeName("天然气"); |
||||
} |
||||
} else { |
||||
gasOilPrice = oilPriceCollect.get(0); |
||||
gasOilPrice.setStatus(GasOilPriceStatusEnum.status1.getNumber()); |
||||
} |
||||
// 平台优惠
|
||||
gasOilPrice.setPreferentialMargin(new BigDecimal("0")); |
||||
gasOilPrice.setPriceCost(oilPriceObject.getJSONObject("goodsPrice").getBigDecimal("amount")); |
||||
gasOilPrice.setPriceVip(gasOilPrice.getPriceCost()); |
||||
gasOilPrice.setPriceGun(gasOilPrice.getPriceCost()); |
||||
gasOilPrice.setPriceOfficial(oilPriceObject.getJSONObject("listedPrice").getBigDecimal("amount")); |
||||
// 国标价 - 油站价 = 油站直降
|
||||
gasOilPrice.setGasStationDrop(gasOilPrice.getPriceOfficial().subtract(gasOilPrice.getPriceCost())); |
||||
gasOilPriceService.editOilPrice(gasOilPrice); |
||||
|
||||
for (Object gunNo : oilPriceObject.getJSONArray("oilGunNoList")) { |
||||
// 查询抢号
|
||||
List<BsGasOilGunNo> gunNoCollect = oilGunNoList.stream() |
||||
.filter(o -> o.getOilNo().equals(oilPriceObject.getString("goodsCode")) && o.getGunNo().equals(gunNo.toString())) |
||||
.collect(Collectors.toList()); |
||||
// 如果没有找到抢号就新增一个
|
||||
BsGasOilGunNo gasOilGunNo = null; |
||||
if (gunNoCollect.isEmpty()) { |
||||
gasOilGunNo = new BsGasOilGunNo(); |
||||
gasOilGunNo.setGasOilPriceId(gasOilPrice.getId()); |
||||
gasOilGunNo.setMerId(gasOilPrice.getMerId()); |
||||
gasOilGunNo.setMerNo(gasOilPrice.getMerNo()); |
||||
gasOilGunNo.setOilNo(gasOilPrice.getOilNo()); |
||||
gasOilGunNo.setOilNoName(gasOilPrice.getOilNoName()); |
||||
gasOilGunNo.setOilType(gasOilPrice.getOilType()); |
||||
gasOilGunNo.setOilTypeName(gasOilPrice.getOilTypeName()); |
||||
gasOilGunNo.setGunNo(gunNo.toString()); |
||||
gasOilGunNo.setStatus(1); |
||||
gasOilGunNo.setCreateTime(new Date()); |
||||
oilGunNoList.add(gasOilGunNo); |
||||
} else { |
||||
gasOilGunNo = gunNoCollect.get(0); |
||||
gasOilGunNo.setStatus(1); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// 添加
|
||||
gasOilGunNoService.batchInsert(oilGunNoList.stream().filter(o-> o.getId() == null).collect(Collectors.toList())); |
||||
// 更新
|
||||
gasOilGunNoService.batchUpdate(oilGunNoList.stream().filter(o-> o.getId() != null && o.getStatus().equals(0)).collect(Collectors.toList())); |
||||
// 删除缓存
|
||||
gasOilGunNoService.cleanCache(merchant.getMerNo()); |
||||
// 清除油站缓存
|
||||
gasService.clean(merchant.getMerNo()); |
||||
} catch (Exception e) { |
||||
System.out.println("更新油站失败"); |
||||
} |
||||
} |
||||
|
||||
} catch (Exception e) { |
||||
System.out.println("更新油站出现异常"); |
||||
System.out.println(e.getMessage()); |
||||
} finally { |
||||
// 任务个数 - 1, 直至为0时唤醒await()
|
||||
countDownLatch.countDown(); |
||||
} |
||||
} |
||||
})); |
||||
} |
||||
try { |
||||
// 让当前线程处于阻塞状态,直到锁存器计数为零
|
||||
countDownLatch.await(); |
||||
} catch (Exception e) { |
||||
System.out.println("系统出现异常"); |
||||
} |
||||
Long endTime = System.currentTimeMillis(); |
||||
Long useTime = endTime - startTime; |
||||
System.out.println("本次更新任务结束,共计用时"+useTime+"毫秒"); |
||||
} |
||||
|
||||
/** |
||||
* 拆分集合 |
||||
* |
||||
* @param <T> 泛型对象 |
||||
* @param resList 需要拆分的集合 |
||||
* @param subListLength 每个子集合的元素个数 |
||||
* @return 返回拆分后的各个集合组成的列表 |
||||
**/ |
||||
public static <T> List<List<T>> splitList(List<T> resList, int subListLength) { |
||||
if (CollectionUtils.isEmpty(resList) || subListLength <= 0) { |
||||
return new ArrayList<>(); |
||||
} |
||||
List<List<T>> ret = new ArrayList<>(); |
||||
int size = resList.size(); |
||||
if (size <= subListLength) { |
||||
// 数据量不足 subListLength 指定的大小
|
||||
ret.add(resList); |
||||
} else { |
||||
int pre = size / subListLength; |
||||
int last = size % subListLength; |
||||
// 前面pre个集合,每个大小都是 subListLength 个元素
|
||||
for (int i = 0; i < pre; i++) { |
||||
List<T> itemList = new ArrayList<>(subListLength); |
||||
for (int j = 0; j < subListLength; j++) { |
||||
itemList.add(resList.get(i * subListLength + j)); |
||||
} |
||||
ret.add(itemList); |
||||
} |
||||
|
||||
// last的进行处理
|
||||
if (last > 0) { |
||||
List<T> itemList = new ArrayList<>(last); |
||||
for (int i = 0; i < last; i++) { |
||||
itemList.add(resList.get(pre * subListLength + i)); |
||||
} |
||||
ret.add(itemList); |
||||
} |
||||
} |
||||
return ret; |
||||
} |
||||
} |
@ -0,0 +1,194 @@ |
||||
package com.hfkj.channel.gas.shell; |
||||
|
||||
import com.alibaba.fastjson.JSONObject; |
||||
import com.hfkj.common.exception.ErrorCode; |
||||
import com.hfkj.common.exception.ErrorHelp; |
||||
import com.hfkj.common.exception.SysCode; |
||||
import com.hfkj.common.utils.DateUtil; |
||||
import com.hfkj.common.utils.HttpsUtils; |
||||
import com.hfkj.common.utils.MD5Util; |
||||
import com.hfkj.config.CommonSysConst; |
||||
import org.apache.commons.lang3.StringUtils; |
||||
|
||||
import java.math.BigDecimal; |
||||
import java.util.*; |
||||
|
||||
/** |
||||
* 重庆壳牌请求 |
||||
* @className: CqShellPetroleumConfig |
||||
* @author: HuRui |
||||
* @date: 2024/7/22 |
||||
**/ |
||||
public class CqShellPetroleumRequestService { |
||||
|
||||
/** |
||||
* 请求地址 |
||||
*/ |
||||
private final static String REQ_URL = CommonSysConst.getSysConfig().getCqShellReqUrl(); |
||||
/** |
||||
* 壳牌合作伙伴id |
||||
*/ |
||||
private final static String PARTNER_ID = CommonSysConst.getSysConfig().getCqShellPartnerId(); |
||||
/** |
||||
* 平台商id |
||||
*/ |
||||
private final static String PLAT_MERCHANT_ID = CommonSysConst.getSysConfig().getCqShellPlatMerchantId(); |
||||
/** |
||||
* 平台商key |
||||
*/ |
||||
private final static String PLAT_MERCHANT_KEY = CommonSysConst.getSysConfig().getCqShellPlatMerchantKey(); |
||||
|
||||
/** |
||||
* 查询全量加油站 |
||||
* @param pageNum 当前页码 |
||||
* @param pageSize 每页数据量。最大值50 |
||||
* @return |
||||
*/ |
||||
public static JSONObject gasPageQueryAllStation(Integer pageNum, Integer pageSize) throws Exception { |
||||
Map<String, Object> param = new HashMap<>(); |
||||
param.put("platMerchantId", PLAT_MERCHANT_ID); |
||||
param.put("pageNo", pageNum); |
||||
param.put("pageSize", pageSize); |
||||
return request(System.currentTimeMillis()+"","gasPageQueryAllStation", param); |
||||
} |
||||
|
||||
/** |
||||
* 查询单个油站全量信息 |
||||
* @param stationCode 油站编码 |
||||
* @return |
||||
*/ |
||||
public static JSONObject gasStationQueryDetail(String stationCode) { |
||||
try { |
||||
Map<String, Object> param = new HashMap<>(); |
||||
param.put("platMerchantId", PLAT_MERCHANT_ID); |
||||
param.put("stationCode", stationCode); |
||||
return request(System.currentTimeMillis()+"","gasPageQueryAllStation", param); |
||||
} catch (Exception e) { |
||||
e.printStackTrace(); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* 【同步】油站付款 |
||||
* @param orderNo 订单号 |
||||
* @param stationCode 油站编码 |
||||
* @param finishTime 完成时间 |
||||
* @param oilPrice 加油金额 |
||||
* @param oilCode 油品编码 |
||||
* @param oilGun 油枪 |
||||
* @param settlementAmount 支付金额 |
||||
* @param channelFavourAmount 优惠金额 |
||||
* @return |
||||
*/ |
||||
public static JSONObject gasSyncPayment(String orderNo, |
||||
String stationCode, |
||||
Date finishTime, |
||||
BigDecimal oilPrice, |
||||
String oilCode, |
||||
String oilGun, |
||||
BigDecimal settlementAmount, |
||||
BigDecimal channelFavourAmount) throws Exception { |
||||
Map<String, Object> param = new HashMap<>(); |
||||
param.put("platMerchantId", PLAT_MERCHANT_ID); |
||||
param.put("stationCode", stationCode); |
||||
param.put("orderType", "OIL"); |
||||
param.put("finishTime", DateUtil.date2String(finishTime, "yyyy-MM-dd HH:mm:ss")); |
||||
param.put("channelFavourAmount", channelFavourAmount); |
||||
|
||||
Map<String, Object> tradeOilOrder = new HashMap<>(); |
||||
tradeOilOrder.put("amount", oilPrice); |
||||
tradeOilOrder.put("code", oilCode); |
||||
tradeOilOrder.put("oilGun", oilGun); |
||||
tradeOilOrder.put("channelSettlementAmount", settlementAmount); |
||||
param.put("tradeOilOrder", JSONObject.toJSONString(tradeOilOrder)); |
||||
return request(orderNo, "gas_sync_payment_notify", param); |
||||
} |
||||
|
||||
/** |
||||
* 【同步】油站退款 |
||||
* @param finishTime 业务完成时间 |
||||
* @param tradeNo 交易流水号 |
||||
* @return |
||||
*/ |
||||
public static JSONObject gasSyncRefund(Date finishTime,String tradeNo) throws Exception { |
||||
Map<String, Object> param = new HashMap<>(); |
||||
param.put("platMerchantId", PLAT_MERCHANT_ID); |
||||
param.put("finishTime", DateUtil.date2String(finishTime, "yyyy-MM-dd HH:mm:ss")); |
||||
param.put("tradeNo", tradeNo.replace("HF","")); |
||||
// 请求接口
|
||||
return request(System.currentTimeMillis()+"" ,"gas_sync_refund_notify", param); |
||||
} |
||||
|
||||
/** |
||||
* 接口请求 |
||||
* @param map |
||||
* @return |
||||
* @throws Exception |
||||
*/ |
||||
private static JSONObject request(String logSerialNo, String service, Map<String,Object> map) throws Exception { |
||||
Map<String, Object> param = new HashMap<>(); |
||||
param.put("merchantOrderNo", logSerialNo); |
||||
param.put("partnerId", PARTNER_ID); |
||||
param.put("service", service); |
||||
param.put("version", "1.0.0"); |
||||
param.put("signType", "MD5"); |
||||
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) { |
||||
param.put(entry.getKey(), entry.getValue()); |
||||
} |
||||
param.put("sign", MD5Util.encode(generateSignature(param, PLAT_MERCHANT_KEY).getBytes()).toLowerCase()); |
||||
// 请求接口
|
||||
JSONObject response = HttpsUtils.doPost(REQ_URL, param); |
||||
if (response == null || !response.getString("status").equals("SUCCESS")) { |
||||
throw ErrorHelp.genException(SysCode.System, ErrorCode.COMMON_ERROR, response == null?"请求失败":response.getString("message")); |
||||
} |
||||
return response; |
||||
} |
||||
|
||||
/** |
||||
* 生成签名 |
||||
* @param data 数据 |
||||
* @param key 秘钥app_secret |
||||
* @return 加密结果 |
||||
*/ |
||||
public static String generateSignature(final Map<String, Object> data, String key) { |
||||
Set<String> keySet = data.keySet(); |
||||
String[] keyArray = keySet.toArray(new String[keySet.size()]); |
||||
Arrays.sort(keyArray); |
||||
StringBuilder sb = new StringBuilder(); |
||||
for (String k : keyArray) { |
||||
if (data.get(k) != null) { |
||||
if (StringUtils.isBlank(sb.toString())) { |
||||
sb.append(k).append("=").append(data.get(k)); |
||||
} else { |
||||
sb.append("&").append(k).append("=").append(data.get(k)); |
||||
} |
||||
} |
||||
} |
||||
sb.append(key); |
||||
return sb.toString(); |
||||
} |
||||
|
||||
/** |
||||
* 生成参数 |
||||
* @param data 数据 |
||||
* @return 加密结果 |
||||
*/ |
||||
public static String generateParam(final Map<String, Object> data) { |
||||
Set<String> keySet = data.keySet(); |
||||
String[] keyArray = keySet.toArray(new String[keySet.size()]); |
||||
StringBuilder sb = new StringBuilder(); |
||||
for (String k : keyArray) { |
||||
if (data.get(k) != null) { |
||||
if (StringUtils.isBlank(sb.toString())) { |
||||
sb.append(k).append("=").append(data.get(k)); |
||||
} else { |
||||
sb.append("&").append(k).append("=").append(data.get(k)); |
||||
} |
||||
} |
||||
} |
||||
return sb.toString(); |
||||
} |
||||
} |
Loading…
Reference in new issue