Просмотр исходного кода

add haikangweishi car

release_toaliyun_real
xiaohanzi 4 лет назад
Родитель
Сommit
8a7cd8cd1e
5 измененных файлов: 579 добавлений и 2 удалений
  1. +1
    -1
      mallinkService/src/main/java/com/iformall/common/ErrorCode.java
  2. +2
    -1
      mallinkService/src/main/java/com/iformall/enums/EnumCarVendor.java
  3. +183
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/haikangweishi/HaiKangWeiShiParkCallbackService.java
  4. +197
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/haikangweishi/HaiKangWeiShiParkService.java
  5. +196
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/haikangweishi/HaiKangWeiShiUtil.java

+ 1
- 1
mallinkService/src/main/java/com/iformall/common/ErrorCode.java Просмотреть файл

@@ -170,7 +170,7 @@ public enum ErrorCode{
BOLINK_SIGN_ERR(2066, "泊链签名错误"), BOLINK_SIGN_ERR(2066, "泊链签名错误"),
BOLINK_STOP_FEE_FAIL(2067, "泊链停车费获取失败"), BOLINK_STOP_FEE_FAIL(2067, "泊链停车费获取失败"),


CYF_STOP_FEE_FAIL(2068, "CYF获取停车费失败"),
CYF_STOP_FEE_FAIL(2068, "获取停车费失败"),


/** /**
* 游戏 * 游戏


+ 2
- 1
mallinkService/src/main/java/com/iformall/enums/EnumCarVendor.java Просмотреть файл

@@ -13,7 +13,8 @@ public enum EnumCarVendor {
CAR_SHANGAN(4, "ShangAn",false), CAR_SHANGAN(4, "ShangAn",false),
CAR_BOLINK(5, "BoLink",false), CAR_BOLINK(5, "BoLink",false),
CAE_CYF(6,"CYF",false), CAE_CYF(6,"CYF",false),
CAR_JIESHUN(7,"JIESHUN",true)
CAR_JIESHUN(7,"JIESHUN",true),
CAR_HAIKANGWEISHI(8,"HAIKANGWEISHI",false)
; ;


public static EnumCarVendor getEnum(Integer code) { public static EnumCarVendor getEnum(Integer code) {


+ 183
- 0
mallinkService/src/main/java/com/iformall/service/park/impl/haikangweishi/HaiKangWeiShiParkCallbackService.java Просмотреть файл

@@ -0,0 +1,183 @@
package com.iformall.service.park.impl.haikangweishi;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.domain.po.WxCarJSOrder;
import com.iformall.domain.po.WxPark;
import com.iformall.domain.vo.WxCarCYFVo;
import com.iformall.enums.EnumCarVendor;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxCarJSOrderMapper;
import com.iformall.service.WxParkService;
import com.iformall.service.park.ParkBatchCallBackAdapterService;
import com.iformall.service.park.ParkCallBackAdapterService;
import com.iformall.service.park.entity.ParkNotifyParam;
import com.iformall.service.park.impl.BaseParkService;

import lombok.extern.slf4j.Slf4j;


/**
* 海康文档 3.1.8
* @author alascor
*
*/
@Slf4j
@Service
public class HaiKangWeiShiParkCallbackService extends BaseParkService implements ParkBatchCallBackAdapterService {
@Autowired
HaiKangWeiShiParkService haiKangWeiShiParkService;
@Autowired
WxParkService wxParkService;

/**
* {dataItems=[{"inTime":"2020-12-09 11:21:15","carNumber":"浙-AF81797","inCarPhoto":"p201127315/NISSP_IMG_PARK_IN/20201209/a9f1130651b9493f8eab64f14afbdd47","isReal":0,"itemId":"a9f1130651b9493f8eab64f14afbdd47","inOperator":"超级管理员","equipName":"东门入口","parkName":"杭州东站西子国际","vehicleInfo":"{\"plateNo\":\"浙-AF81797\",\"plateColor\":\"GREEN\",\"plateBackColor\":0,\"plateWordColor\":0,\"vehicleColor\":null,\"vehicleLogo\":null,\"vehicleModel\":null,\"mainModel\":0,\"subModel\":0,\"vehicleModelTrust\":0,\"mainModelTrust\":0,\"subModelTrust\":0,\"plateNoTrust\":1,\"vehicleLogoTrust\":0,\"vehicleColorTrust\":0}","equipCode":"208202496","parkCode":"p201127315"}], pno=dzxzgj, sn=6C958D99D2769AA16F3A3F06E962263F, tn=-2, ts=20201209112118886, ve=1.0}
*/
@Override
public List<ParkNotifyParam> parseInNoticyParam(Object param) {
Map<String,Object> paramm = (Map<String, Object>) param;
String liststr = (String) paramm.get("dataItems");
JSONArray list = JSONArray.parseArray(liststr);
if (null != list && list.size() > 0 ) {
List<ParkNotifyParam> retList = new ArrayList<ParkNotifyParam>();
for (int i = 0 ; i < list.size() ; i ++) {
Map<String,Object> map = (Map<String, Object>) list.get(i);
ParkNotifyParam ret = parseInNoticyParamSingle(map);
if (null != ret ) {
retList.add(ret);
}
}
return retList;
}
return null;
}
private ParkNotifyParam parseInNoticyParamSingle(Map<String,Object> paramMap) {
String carNumber = paramMap.get("carNumber").toString();
String parkCode = paramMap.get("parkCode").toString();
String parkName = paramMap.get("parkName").toString();
String synId = paramMap.get("itemId").toString();
String entranceTime = paramMap.get("inTime").toString();
ParkNotifyParam p = new ParkNotifyParam();
String realCarNumber = carNumber;
p.setCarNumber(realCarNumber);
p.setParkId(parkCode);
p.setParkName(parkName);
p.setSynId(synId);
// try {
// p.setEntranceTime(JieShunUtil.utcToLocal(entranceTime));
// } catch (ParseException e) {
// log.error("jieshun entranceTime format error",e);
// return null;
// }
return p;
}

@Override
public List<ParkNotifyParam> parseOutNoticyParam(Object param) {
Map<String,Object> paramm = (Map<String, Object>) param;
String liststr = (String) paramm.get("dataItems");
JSONArray list = JSONArray.parseArray(liststr);
if (null != list && list.size() > 0 ) {
List<ParkNotifyParam> retList = new ArrayList<ParkNotifyParam>();
for (int i = 0 ; i < list.size() ; i ++) {
Map<String,Object> map = (Map<String, Object>) list.get(i);
ParkNotifyParam ret = parseOutNoticyParamSingle(map);
if (null != ret ) {
retList.add(ret);
}
}
return retList;
}
return null;
}
private ParkNotifyParam parseOutNoticyParamSingle(Map<String, Object> paramMap) {
String carNumber = paramMap.get("carNumber").toString();
String parkCode = paramMap.get("parkCode").toString();
String parkName = paramMap.get("parkName").toString();
String synId = paramMap.get("itemId").toString();
String entranceTime = paramMap.get("outTime").toString();
String realCarNumber = carNumber;
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber(realCarNumber);
p.setParkId(parkCode);
p.setParkName(parkName);
p.setSynId(synId);
// try {
// p.setEntranceTime(JieShunUtil.utcToLocal(entranceTime));
// } catch (ParseException e) {
// log.error("cyf entranceTime format error",e);
// return null;
// }
// try {
// p.setOutTime(JieShunUtil.utcToLocal(entranceTime));
// } catch (ParseException e) {
// log.error("cyf outTime format error",e);
// return null;
// }
p.setFee(String.valueOf(paramMap.get("ssMoney")));
return p;
}

@Override
public List<ParkNotifyParam> parseUnbindNoticyParam(Object param) {
return null;
}

@Override
public List<ParkNotifyParam> parsePaidNoticyParam(Object param) {
Map<String,Object> paramm = (Map<String, Object>) param;
String liststr = (String) paramm.get("dataItems");
JSONArray list = JSONArray.parseArray(liststr);
if (null != list && list.size() > 0 ) {
List<ParkNotifyParam> retList = new ArrayList<ParkNotifyParam>();
for (int i = 0 ; i < list.size() ; i ++) {
Map<String,Object> map = (Map<String, Object>) list.get(i);
ParkNotifyParam ret = parsePaidNoticyParamSingle(map);
if (null != ret ) {
retList.add(ret);
}
}
return retList;
}
return null;
}
private ParkNotifyParam parsePaidNoticyParamSingle(Map<String,Object> vo) {
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber((String) vo.get("carNumber"));
p.setParkId(String.valueOf(vo.get("parkCode")));
p.setParkOrderId((String) vo.get("itemId"));
p.setSynId((String) vo.get("itemId"));
p.setFee(vo.get("ssMoney").toString());
// try {
// p.setPayTime(jieshun.utcToLocal((String)vo.get("feesTime")));
// } catch (ParseException e) {
// e.printStackTrace();
// }
return p;
}
}

+ 197
- 0
mallinkService/src/main/java/com/iformall/service/park/impl/haikangweishi/HaiKangWeiShiParkService.java Просмотреть файл

@@ -0,0 +1,197 @@
package com.iformall.service.park.impl.haikangweishi;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxCUserBasicInfo;
import com.iformall.domain.po.WxCarJSOrder;
import com.iformall.domain.po.WxCoupon;
import com.iformall.domain.po.WxPark;
import com.iformall.domain.vo.WxCouponOrderCarCVo;
import com.iformall.domain.vo.WxParkCouponConfig;
import com.iformall.enums.EnumCarVendor;
import com.iformall.enums.EnumCouponUnit;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxCarJSOrderMapper;
import com.iformall.service.WxParkService;
import com.iformall.service.park.ParkAdapterService;
import com.iformall.service.park.entity.ParkStopFee;
import com.iformall.service.park.impl.BaseParkService;
import com.iformall.service.park.impl.util.ParkHelper;
import com.iformall.service.park.utils.ParkCacheUtils;
import com.iformall.utils.RedisCacheUtils;
import com.iformall.utils.RedisLock;

/**
* 认证平台 https://www.hikyun.com 武汉富茂链客/zfy151431113
* @author alascor
*
*/
@Service
public class HaiKangWeiShiParkService extends BaseParkService implements ParkAdapterService {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
ParkHelper parkHelper;
@Autowired
@Qualifier("objectCommonRedisTemplate")
RedisTemplate<String, Object> redisTemplate;
@Autowired
RedisLock redisLock;
HaiKangWeiShiUtil haikang = new HaiKangWeiShiUtil();
private String getCacheToken(WxPark park) {
String token = RedisCacheUtils.getCacheString(redisTemplate, "carStop:haikangtoken:"+park.getId());
if (StringUtils.isBlank(token)) {
String lockKey = "carStop:haikangtokenlock:"+park.getTenantId();
long time = System.currentTimeMillis() + 2000;
String timeStr = String.valueOf(time);
if (redisLock.lock2(lockKey, timeStr)) {
token = haikang.getToken(park);
if (!StringUtils.isBlank(token)) {
setCacheToken(park, token);
}
redisLock.unlock(lockKey, timeStr);
} else {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
redisLock.unlock(lockKey, timeStr);
}
}
}
return RedisCacheUtils.getCacheString(redisTemplate, "carStop:haikangtoken:"+park.getId());
}
private void setCacheToken(WxPark park,String token) {
RedisCacheUtils.cache(redisTemplate, "carStop:haikangtoken:"+park.getId(), token, 36000);
}
@Override
public String initLogin(Map<String, String> paramMap, WxPark park, WxCUserBasicInfo member) throws Exception{
return null;
}
@Override
public String bindCar(Map<String, String> paramMap, WxPark park, WxCUserBasicInfo member) throws Exception{
return "haikaiweishi";
}

@Override
public void unbindCar(Map<String, String> paramMap, WxPark park, WxCUserBasicInfo member) throws Exception{
}


/**
* 每一次查询都会产生订单,然后根据订单号查询
*/
@Override
public ResultData carStopFee(Map<String, String> paramMap, WxPark park) throws Exception{
return haiKangWeiShiCarStopFee(paramMap, park);
}
private ResultData haiKangWeiShiCarStopFee(Map<String, String> paramMap, WxPark park) throws Exception{
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
//如果车牌号是鄂AAAAAA, 为测试车牌
if (carNumber.equals("鄂AAAAAA")) {
return new ResultData(new ParkStopFee("-111",haikang.utcToLocal("2020-12-16 00:00:00"),haikang.utcToLocal("2020-12-17 00:00:00"),
"0.01","","payPath",null,"测试车牌,仅测试用",null));
}else if(carNumber.equals("鄂AAAAAB")) {
return new ResultData(21000,"车辆未入场");
}
String retCode = haikang.getFee(park, carNumber, getCacheToken(park));
if (StringUtils.isBlank(retCode)) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(), "haikang getFee error. has no result");
}
JSONObject result = JSON.parseObject(retCode);
if (result.getInteger("code") != 0 ) {
String message = result.getString("msg");
throw new MallinkException(result.getInteger("code"), "haikang getFee error."+message);
}
JSONObject attribute = result.getJSONObject("data");
if (null == attribute) {
throw new MallinkException(result.getInteger("code"), "haikang getFee error. no order result"+carNumber);
}
String appId = "";
String parkOrderId = attribute.getString("id");
String _createTime = attribute.getString("entranceTime");//计费时间,格式为“yyyy-MM-dd HH:mi:ss”
String _endTime = attribute.getString("costTime");//离场时间,格式为“yyyy-MM-dd HH:mi:ss”
String payPath = "";
return new ResultData(new ParkStopFee(parkOrderId,haikang.utcToLocal(_createTime),haikang.utcToLocal(_endTime),
String.valueOf(attribute.getDouble("shouldCost")),appId,payPath,null,null,"请支付后15分钟内离场"));
}

/**
* 使用3.5.9.1接口进行车牌和优惠信息绑定优惠券后,车辆出场时我们会自动抵扣。
* @return
*/
@Override
public ResultData useCoupon(Map<String, String> paramMap, WxPark park, WxCouponOrderCarCVo userCar,WxCoupon coupon,String carNumber) throws Exception{
if (null == userCar) {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(),"当前用户未查询到优惠券!");
}
if (StringUtils.isBlank(userCar.getCUserPhone())) {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(),"当前用户未查询到手机号!"+userCar.getcUserId());
}
Map<String,String> valueMap = WxParkCouponConfig.parseValue(userCar.getVendorParams());
if (null == valueMap) {
return new ResultData(ErrorCode.COUPON_IS_EMPTY.getCode(),"当前停车券没有关联停车场优惠券配置。"+coupon.getTitle());
}
String orderNo = paramMap.get("parkOrderId");
String planNo = valueMap.get("couponNo");
if (StringUtils.isBlank(planNo)) {
return new ResultData(ErrorCode.COUPON_IS_EMPTY.getCode(),"当前停车券没有关联停车场优惠券配置[planNo]。"+coupon.getTitle());
}
//String ret = jieshun.getCoupon(park, planNo,userCar.getCUserPhone(), getCacheToken(park));
//打折登陆验证
String ret = haikang.useCoupon(park,planNo,carNumber,orderNo, getCacheToken(park));
logger.info("haikangweishi useCoupon result:"+ret);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("code") == 0){
return new ResultData();
}else {
logger.error("haikangweishi useCoupon error. paramMap: {} . haikangResult: {}",JSON.toJSONString(paramMap),ret);
String msg = retObj.getString("msg");
return new ResultData(retObj.getIntValue("code"), "当前用户领用到海康威视停车券失败:"+msg);
}
}

@Override
public ResultData getParkStatus(WxPark park) throws Exception{
return new ResultData();
}

}

+ 196
- 0
mallinkService/src/main/java/com/iformall/service/park/impl/haikangweishi/HaiKangWeiShiUtil.java Просмотреть файл

@@ -0,0 +1,196 @@
package com.iformall.service.park.impl.haikangweishi;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iformall.domain.po.WxPark;
import com.iformall.exception.MallinkException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
* @author: furunxin
* @Date: 2020/7/1 17:16
* @Description: 车易付接口对接参数类
*/

@Slf4j
public class HaiKangWeiShiUtil {

public static final String TOKEN_URL = "https://open.hikyun.com/artemis/oauth/token";
public static final String GET_FEE = "https://open.hikyun.com/api/pmsc/v1/pay/quickGetVehicleBill";
public static final String COUPON_USE = "https://open.hikyun.com/api/pmsc/v1/coupon/addition";

/**
* @description UTC时间转化为本地时间
* @Params [utcTime]
* @return java.util.Date
* @Author furunxin
* @Date 2020/7/8 下午12:45
**/
public static Date utcToLocal(String seconds) throws ParseException {
String format = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat sdf = new SimpleDateFormat(format);
Date date=sdf.parse(seconds);
return date;
}

public static String getLocalDate(){
LocalDateTime ldt = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String nowDate = ldt.format(dtf);
return nowDate;
}

public String getToken(WxPark wxPark) {
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
String clientId = vp.getString("AppKey");
String clientSecret = vp.getString("SecretKey");
return getToken(clientId,clientSecret);
}
private String getToken(String clientId,String clientSecret) {
String result = ProcLogin(clientId, clientSecret);
log.info("haikang token clientId:"+clientId+" clientSecret:"+clientSecret+" result: "+result);
if (StringUtils.isBlank(result)) {
return null;
}
JSONObject res = JSON.parseObject(result);
Integer code = res.getInteger("code");
if (null == code || code.intValue() != 0) {
String msg = res.getString("msg");
throw new MallinkException(code,msg);
}
return res.getString("access_token");
}
/**
* 查询停车费 3.5.5 快速获取账单接口
* @return
*/
public String getFee(WxPark wxPark,String cardNumber,String token) {
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("chargeSource", "THIRD"));//商户编号
list.add(new BasicNameValuePair("parkId", wxPark.getParkId()));//优惠券编号
list.add(new BasicNameValuePair("plateNo", cardNumber));//优惠券编号
return ProcBussiness(GET_FEE, list, token);
}
/**
* 使用优惠券 3.5.9.1接口进行车牌和优惠信息绑定优惠券后,车辆出场时会自动抵扣
**/
public String useCoupon(WxPark wxPark,String couponNo,String carNumber,String orderNo,String token){
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
Map couponmap = new HashMap();
couponmap.put("plateNo", carNumber);
couponmap.put("ruleId", couponNo);
couponmap.put("parkId", wxPark.getParkId());
list.add(new BasicNameValuePair("coupons", "["+JSON.toJSONString(couponmap)+"]") );//商户编号
return ProcBussiness(COUPON_USE, list,token);
}
/*token认证登陆**/
private static String ProcLogin(String clientId,String clientSecret) {
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("client_id", clientId));
list.add(new BasicNameValuePair("client_secret", clientSecret));
return Proc(TOKEN_URL,list,null,null);
}
private static String ProcBussiness(String url,ArrayList<NameValuePair> list,String token) {
try {
//TODO 11111111
String authorization = "";
return Proc(url,list,token,authorization);
} catch (Exception e) {
log.error("haikang request error.",e);
}
return null;
}
private static String Proc(String url, List<NameValuePair> pairs,String token,String authorization) {
CloseableHttpClient httpClient = HttpClients.createDefault();

HttpPost httpPost = new HttpPost(url);
httpPost.addHeader(HTTP.CONTENT_TYPE,"application/json");
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Accept-Encoding", "UTF-8");
if (!StringUtils.isBlank(token)) {
httpPost.addHeader("access_token",token);
}
if (!StringUtils.isBlank(authorization)) {
httpPost.addHeader("Authorization",authorization);
}

if (null != pairs) {
HttpEntity en;
try {
en = new UrlEncodedFormEntity(pairs, HTTP.UTF_8);
httpPost.setEntity(en);
} catch (UnsupportedEncodingException e) {
log.error(e.getLocalizedMessage(),e);
return null;
}
}

if (null != pairs) {
log.info("haikangweishi httpRequest:[url]"+url+"[params]"+JSON.toJSONString(pairs));
}else {
log.info("haikangweishi httpRequest:[url]"+url);
}
HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (Exception e) {
log.error(e.getLocalizedMessage(),e);
}

String result = null;

//打印StatusLine
log.debug("StatusLine: " + response.getStatusLine());
try{
//获取实体
HttpEntity httpEntity= response.getEntity();
result = EntityUtils.toString(httpEntity, "UTF-8");
log.debug(result);
} catch (Exception e) {
log.error(e.getLocalizedMessage(),e);
}

try { //关闭流并释放资源
httpClient.close();
} catch (IOException e) {
log.error(e.getLocalizedMessage());
}
return result;
}
}

Загрузка…
Отмена
Сохранить