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

add lifang park

release_toaliyun_real
lin 2 лет назад
Родитель
Сommit
bc96c2d4a0
9 измененных файлов: 1004 добавлений и 7 удалений
  1. +134
    -0
      mallinkCallback/src/main/java/com/iformall/controller/callback/car/lifang/WxCarLiFangCallBackController.java
  2. +9
    -4
      mallinkService/src/main/java/com/iformall/enums/EnumCarCmd.java
  3. +3
    -2
      mallinkService/src/main/java/com/iformall/enums/EnumCarVendor.java
  4. +9
    -0
      mallinkService/src/main/java/com/iformall/service/park/ParkFactory.java
  5. +1
    -1
      mallinkService/src/main/java/com/iformall/service/park/impl/jieshunV2/JieShunV2ParkService.java
  6. +295
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/lifang/LiFangAESUtils.java
  7. +167
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/lifang/LiFangParkCallbackService.java
  8. +216
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/lifang/LiFangParkService.java
  9. +170
    -0
      mallinkService/src/main/java/com/iformall/service/park/impl/lifang/LiFangUtil.java

+ 134
- 0
mallinkCallback/src/main/java/com/iformall/controller/callback/car/lifang/WxCarLiFangCallBackController.java Просмотреть файл

@@ -0,0 +1,134 @@
package com.iformall.controller.callback.car.lifang;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.iformall.common.Result;
import com.iformall.controller.base.BaseController;
import com.iformall.controller.callback.car.WxParkCallBackBaseController;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.WxCarCYFVo;
import com.iformall.enums.EnumCarCmd;
import com.iformall.enums.EnumCarVendor;
import com.iformall.enums.EnumCouponSendSendType;
import com.iformall.enums.EnumPayWay;
import com.iformall.service.*;
import com.iformall.service.park.impl.cyf.CYFUtil;
import com.iformall.service.park.impl.tjd.TJDUtil;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

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

/**
* @author: furunxin
* @Date: 2020/7/6 15:29
* @Description: 车易付回调接口
*/

@Slf4j
@RestController
@RequestMapping("/liFangCarCallback")
public class WxCarLiFangCallBackController extends WxParkCallBackBaseController {

@Autowired
WxParkService wxParkService;

@Autowired
WxCarCmdLogService wxCarCmdLogService;

@Autowired
WxCUserService wxCUserService;

@Autowired
WxCUserCarService wxCUserCarService;

@Autowired
WxCouponSendService wxCouponSendService;

@Autowired
WxCarPayRecordService wxCarPayRecordService;

@Autowired
WxCUserBasicInfoService wxCUserBasicInfoService;

/**
* @description 捷顺 车辆入场通知
* {
"carCode": "浙A5C393",
"inTime": "2016-10-18 16:44:44",
"passTime": "2016-10-28 16:44:44",
"parkID": "12222",
"inOrOut": "1", 0:进场,1:出场
"GUID": "134589c1d68d44d38dcb7f084b9cf8a1",
"channelID": "1",
"channelName": "北大门出口",
"imagePath": "http://xxx.xxx.xx.xx:xx\\xxx\\xxx.jpg"
}
* @Params [paramMap]
* @return com.iformall.common.Result
* @Author furunxin
* @Date 2020/7/8 上午8:27
**/
@PostMapping(value = "/parkIn")
public Result parkInCallback(@RequestBody Map<String, Object> paramMap) {
log.info("["+getIpAddr()+"] liFangCarCallback parkIn: " + paramMap.toString());
String inOrOut = (String) paramMap.get("inOrOut");
if ("0".endsWith(inOrOut)) {
Result r = super.parkInCallBack(EnumCarVendor.CAR_LIFANG, EnumCarCmd.CAR_LIFANG_CALLBACK_PARK_IN, paramMap);
if (r.code == Result.SUCCESS) {
return new Result(0,"成功");
}else {
return r;
}
}
return new Result(0,"成功");
}


/**
* @description 车易付 车辆离场通知
* @Params [param]
* @return java.util.Map
* @Author furunxin
* @Date 2020/7/12 上午9:00
**/
@PostMapping(value = "/parkOut")
public Result parkOutCallback(@RequestBody Map<String, Object> paramMap) {
log.info("["+getIpAddr()+"] lifangCarCallback parkOut: " + paramMap.toString());
String inOrOut = (String) paramMap.get("inOrOut");
if ("1".endsWith(inOrOut)) {
Result r = super.parkOutCallBack(EnumCarVendor.CAR_LIFANG, EnumCarCmd.CAR_LIFANG_CALLBACK_PARK_OUT, paramMap);
if (r.code == Result.SUCCESS) {
return new Result(0,"成功");
}else {
return r;
}
}
return new Result(0,"成功");
}
@PostMapping(value = "/unbind")
public Result unbindCallback(@RequestBody Map<String, Object> paramMap) {
log.info("["+getIpAddr()+"] futeCarCallback unbind: " + paramMap.toString());
//解析车易付参数
return super.unbindCarCallBack(EnumCarVendor.CAR_FUTE, EnumCarCmd.CAR_FUTE_CALLBACK_UNBIND, paramMap);
}
@PostMapping(value = "/paid")
public Result paidCallback(@RequestBody Map<String, Object> paramMap) {
log.info("["+getIpAddr()+"] futeCarCallback paid: " + paramMap.toString());
//解析车易付参数
return super.paidCallback(EnumCarVendor.CAR_FUTE, EnumCarCmd.CAR_FUTE_CALLBACK_PAID, paramMap);
}
}

+ 9
- 4
mallinkService/src/main/java/com/iformall/enums/EnumCarCmd.java Просмотреть файл

@@ -36,10 +36,15 @@ public enum EnumCarCmd {
CAR_HAIKANGWEISHI_CALLBACK_UNBIND(630,"海康解绑车牌通知"), CAR_HAIKANGWEISHI_CALLBACK_UNBIND(630,"海康解绑车牌通知"),
CAR_HAIKANGWEISHI_CALLBACK_PAID(631,"海康支付通知"), CAR_HAIKANGWEISHI_CALLBACK_PAID(631,"海康支付通知"),
CAR_FUTE_CALLBACK_PARK_IN(628,"福特进场通知"),
CAR_FUTE_CALLBACK_PARK_OUT(629,"福特出场通知"),
CAR_FUTE_CALLBACK_UNBIND(630,"福特解绑车牌通知"),
CAR_FUTE_CALLBACK_PAID(631,"福特支付通知")
CAR_FUTE_CALLBACK_PARK_IN(632,"福特进场通知"),
CAR_FUTE_CALLBACK_PARK_OUT(633,"福特出场通知"),
CAR_FUTE_CALLBACK_UNBIND(634,"福特解绑车牌通知"),
CAR_FUTE_CALLBACK_PAID(635,"福特支付通知"),
CAR_LIFANG_CALLBACK_PARK_IN(636,"立方进场通知"),
CAR_LIFANG_CALLBACK_PARK_OUT(637,"立方出场通知"),
CAR_LIFANG_CALLBACK_UNBIND(638,"立方解绑车牌通知"),
CAR_LIFANG_CALLBACK_PAID(639,"立方支付通知")
; ;


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


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

@@ -14,9 +14,10 @@ public enum EnumCarVendor {
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_JIESHUN_V2(10,"JIESHUNV2",true),
CAR_JIESHUN_V2(10,"JIESHUNV2",true),//捷顺通用版本
CAR_HAIKANGWEISHI(8,"HAIKANGWEISHI",true), CAR_HAIKANGWEISHI(8,"HAIKANGWEISHI",true),
CAR_FUTE(9,"FUTE",false)//深圳市福特智能科技有限公司
CAR_FUTE(9,"FUTE",false),//深圳市福特智能科技有限公司
CAR_LIFANG(10,"LIFANG",false)//立方停车
; ;


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


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

@@ -21,6 +21,8 @@ import com.iformall.service.park.impl.jieshun.JieShunParkCallbackService;
import com.iformall.service.park.impl.jieshun.JieShunParkService; import com.iformall.service.park.impl.jieshun.JieShunParkService;
import com.iformall.service.park.impl.jieshunV2.JieShunV2ParkCallbackService; import com.iformall.service.park.impl.jieshunV2.JieShunV2ParkCallbackService;
import com.iformall.service.park.impl.jieshunV2.JieShunV2ParkService; import com.iformall.service.park.impl.jieshunV2.JieShunV2ParkService;
import com.iformall.service.park.impl.lifang.LiFangParkCallbackService;
import com.iformall.service.park.impl.lifang.LiFangParkService;
import com.iformall.service.park.impl.shangan.ShangAnParkService; import com.iformall.service.park.impl.shangan.ShangAnParkService;
import com.iformall.service.park.impl.tjd.TJDParkService; import com.iformall.service.park.impl.tjd.TJDParkService;


@@ -45,6 +47,8 @@ public class ParkFactory {
HaiKangWeiShiParkService haikangWeishiService; HaiKangWeiShiParkService haikangWeishiService;
@Autowired @Autowired
FuteParkService futeParkService; FuteParkService futeParkService;
@Autowired
LiFangParkService lifangParkService;
@Autowired @Autowired
CYFParkCallbackService cyfCallbackService; CYFParkCallbackService cyfCallbackService;
@@ -56,6 +60,9 @@ public class ParkFactory {
HaiKangWeiShiParkCallbackService haikangWeishiCallBackService; HaiKangWeiShiParkCallbackService haikangWeishiCallBackService;
@Autowired @Autowired
FuteParkCallbackService futeParkCallbackService; FuteParkCallbackService futeParkCallbackService;
@Autowired
LiFangParkCallbackService lifangParkCallbackService;
private Map<Integer,ParkAdapterService> parkServiceMap ; private Map<Integer,ParkAdapterService> parkServiceMap ;
private Map<Integer,EnumCarVendor> enumMap ; private Map<Integer,EnumCarVendor> enumMap ;
@@ -77,6 +84,7 @@ public class ParkFactory {
parkServiceMap.put(EnumCarVendor.CAR_JIESHUN_V2.getCode(), jieshunV2Service); parkServiceMap.put(EnumCarVendor.CAR_JIESHUN_V2.getCode(), jieshunV2Service);
parkServiceMap.put(EnumCarVendor.CAR_HAIKANGWEISHI.getCode(), haikangWeishiService); parkServiceMap.put(EnumCarVendor.CAR_HAIKANGWEISHI.getCode(), haikangWeishiService);
parkServiceMap.put(EnumCarVendor.CAR_FUTE.getCode(), futeParkService); parkServiceMap.put(EnumCarVendor.CAR_FUTE.getCode(), futeParkService);
parkServiceMap.put(EnumCarVendor.CAR_LIFANG.getCode(), lifangParkService);
return parkServiceMap; return parkServiceMap;
} }
@@ -99,6 +107,7 @@ public class ParkFactory {
callBackServiceMap = new ConcurrentHashMap<Integer, ParkCallBackAdapterService>(); callBackServiceMap = new ConcurrentHashMap<Integer, ParkCallBackAdapterService>();
callBackServiceMap.put(EnumCarVendor.CAE_CYF.getCode(), cyfCallbackService); callBackServiceMap.put(EnumCarVendor.CAE_CYF.getCode(), cyfCallbackService);
callBackServiceMap.put(EnumCarVendor.CAR_FUTE.getCode(), futeParkCallbackService); callBackServiceMap.put(EnumCarVendor.CAR_FUTE.getCode(), futeParkCallbackService);
callBackServiceMap.put(EnumCarVendor.CAR_LIFANG.getCode(), lifangParkCallbackService);
return callBackServiceMap; return callBackServiceMap;
} }


+ 1
- 1
mallinkService/src/main/java/com/iformall/service/park/impl/jieshunV2/JieShunV2ParkService.java Просмотреть файл

@@ -203,7 +203,7 @@ public class JieShunV2ParkService extends BaseParkService implements ParkAdapter
"0.00",appId,"payPath",null,msg,null); "0.00",appId,"payPath",null,msg,null);
}else { }else {
//0元订单结清,查询是否用过打折方案,如果用过,则需要调用接口结清订单 //0元订单结清,查询是否用过打折方案,如果用过,则需要调用接口结清订单
Integer used = ParkCacheUtils.getCarCouponUseCacheLock(redisTemplate, EnumCarVendor.CAR_JIESHUN.getMessage(), carNumber);
Integer used = ParkCacheUtils.getCarCouponUseCacheLock(redisTemplate, EnumCarVendor.CAR_JIESHUN_V2.getMessage(), carNumber);
if (null == used || (null != used && used.intValue() < 1)) { if (null == used || (null != used && used.intValue() < 1)) {
//未使用停车券 //未使用停车券
return new ParkStopFee("-999",jieshun.utcToLocal(_createTime),jieshun.utcToLocal(_endTime), return new ParkStopFee("-999",jieshun.utcToLocal(_createTime),jieshun.utcToLocal(_endTime),


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

@@ -0,0 +1,295 @@
package com.iformall.service.park.impl.lifang;

import java.security.Key;
import java.security.NoSuchAlgorithmException;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import com.iformall.utils.Base64Util;
import org.apache.commons.codec.binary.Base64;


public class LiFangAESUtils {
/**
* 密钥算法
*/
private static final String KEY_ALGORITHM = "AES";
private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
/**
* 初始化密钥
*
* @return byte[] 密钥
* @throws Exception
*/
public static byte[] initSecretKey() {
// 返回生成指定算法的秘密密钥的 KeyGenerator 对象
KeyGenerator kg = null;
try {
kg = KeyGenerator.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return new byte[0];
}
// 初始化此密钥生成器,使其具有确定的密钥大小
// AES 要求密钥长度为 128
kg.init(128);
// 生成一个密钥
SecretKey secretKey = kg.generateKey();
return secretKey.getEncoded();
}
/**
* 转换密钥
*
* @param key
* 二进制密钥
* @return 密钥
*/
public static Key toKey(byte[] key) {
// 生成密钥
return new SecretKeySpec(key, KEY_ALGORITHM);
}
/**
* 加密
*
* @param data
* 待加密数据
* @param key
* 密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, Key key) throws Exception {
return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
}
/**
* 加密
*
* @param data
* 待加密数据
* @param key
* 二进制密钥
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key) throws Exception {
return encrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
}
/**
* 加密
*
* @param data
* 待加密数据
* @param key
* 二进制密钥
* @param cipherAlgorithm
* 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {
// 还原密钥
Key k = toKey(key);
return encrypt(data, k, cipherAlgorithm);
}
/**
* 加密
*
* @param data
* 待加密数据
* @param key
* 密钥
* @param cipherAlgorithm
* 加密算法/工作模式/填充方式
* @return byte[] 加密数据
* @throws Exception
*/
public static byte[] encrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
// 实例化
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
// 使用密钥初始化,设置为加密模式
cipher.init(Cipher.ENCRYPT_MODE, key);
// 执行操作
return cipher.doFinal(data);
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 二进制密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 密钥
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, Key key) throws Exception {
return decrypt(data, key, DEFAULT_CIPHER_ALGORITHM);
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 二进制密钥
* @param cipherAlgorithm
* 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, byte[] key, String cipherAlgorithm) throws Exception {
// 还原密钥
Key k = toKey(key);
return decrypt(data, k, cipherAlgorithm);
}
/**
* 解密
*
* @param data
* 待解密数据
* @param key
* 密钥
* @param cipherAlgorithm
* 加密算法/工作模式/填充方式
* @return byte[] 解密数据
* @throws Exception
*/
public static byte[] decrypt(byte[] data, Key key, String cipherAlgorithm) throws Exception {
// 实例化
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
// 使用密钥初始化,设置为解密模式
cipher.init(Cipher.DECRYPT_MODE, key);
// 执行操作
return cipher.doFinal(data);
}
public static String showByteArray(byte[] data) {
if (null == data) {
return null;
}
StringBuilder sb = new StringBuilder("{");
for (byte b : data) {
sb.append(b).append(",");
}
sb.deleteCharAt(sb.length() - 1);
sb.append("}");
return sb.toString();
}
/**
* 将16进制转换为二进制
*
* @param hexStr
* @return
*/
public static byte[] parseHexStr2Byte(String hexStr) {
if (hexStr.length() < 1)
return null;
byte[] result = new byte[hexStr.length() / 2];
for (int i = 0; i < hexStr.length() / 2; i++) {
int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);
int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);
result[i] = (byte) (high * 16 + low);
}
return result;
}
/**
* 将二进制转换成16进制
*
* @param buf
* @return
*/
public static String parseByte2HexStr(byte buf[]) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < buf.length; i++) {
String hex = Integer.toHexString(buf[i] & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* @param str
* @param key
* @return
* @throws Exception
*/
public static String aesEncrypt(String str, String key) throws Exception {
if (str == null || key == null)
return null;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
byte[] bytes = cipher.doFinal(str.getBytes("utf-8"));
//return new BASE64Encoder().encode(bytes);
return Base64Util.encode(bytes);
}
public static String aesDecrypt(String str, String key) throws Exception {
if (str == null || key == null)
return null;
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key.getBytes("utf-8"), "AES"));
//byte[] bytes = new BASE64Decoder().decodeBuffer(str);
byte[] bytes = Base64Util.decode(str);
bytes = cipher.doFinal(bytes);
return new String(bytes, "utf-8");
}
public static void main(String[] args) throws Exception {
byte[] key = initSecretKey();
System.out.println("key:" + Base64.encodeBase64String(key));
System.out.println("key:" + showByteArray(key));
// 指定key
String kekkk = "9iEepr1twrizIEKrs1hs2A==";
System.out.println("kekkk:" + showByteArray(Base64.decodeBase64(kekkk)));
Key k = toKey(Base64.decodeBase64(kekkk));
String data = "{\"requestName\":\"BeforeIn\",\"requestValue\":{\"carCode\":\"浙AD0V07\",\"inTime\":\"2016-09-29 10:06:03\",\"inChannelId\":\"4\",\"GUID\":\"1403970b-4eb2-46bc-8f2b-eeec91ddcd5f\",\"inOrOut\":\"0\"},\"Type\":\"0\"}";
System.out.println("加密前数据: string:" + data);
System.out.println("加密前数据: byte[]:" + showByteArray(data.getBytes("utf-8")));
System.out.println();
byte[] encryptData = encrypt(data.getBytes("utf-8"), k);
String encryptStr=parseByte2HexStr(encryptData);
System.out.println("加密后数据: byte[]:" + showByteArray(encryptData));
System.out.println("加密后数据: Byte2HexStr:" + encryptStr);
System.out.println();
byte[] decryptData = decrypt(parseHexStr2Byte(encryptStr), k);
System.out.println("解密后数据: byte[]:" + showByteArray(decryptData));
System.out.println("解密后数据: string:" + new String(decryptData,"utf-8"));
}
}

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

@@ -0,0 +1,167 @@
package com.iformall.service.park.impl.lifang;

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;

@Slf4j
@Service
public class LiFangParkCallbackService extends BaseParkService implements ParkCallBackAdapterService {
@Autowired
LiFangParkService liFangParkService;
@Autowired
WxParkService wxParkService;
@Autowired
WxCarJSOrderMapper wxCarJSOrderMapper;
LiFangUtil lifang = new LiFangUtil();
/**
* {
"carCode": "浙A5C393",
"inTime": "2016-10-18 16:44:44",
"passTime": "2016-10-28 16:44:44",
"parkID": "12222",
"inOrOut": "1",
"GUID": "134589c1d68d44d38dcb7f084b9cf8a1",
"channelID": "1",
"channelName": "北大门出口",
"imagePath": "http://xxx.xxx.xx.xx:xx\\xxx\\xxx.jpg"
}
*/
@Override
public ParkNotifyParam parseInNoticyParam(Object param) {
Map<String,Object> paramMap = (Map<String, Object>) param;
String carNumber = paramMap.get("carCode").toString();
String parkCode = paramMap.get("parkID").toString();
String parkName = "";
String synId = paramMap.get("GUID").toString();
Integer inTime = (Integer)paramMap.get("inTime");
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber(carNumber);
p.setParkId(parkCode);
p.setParkName(parkName);
p.setSynId(synId);
try {
p.setEntranceTime(new Date(inTime.longValue()*1000));
} catch (Exception e) {
log.error("fute entranceTime format error",e);
return null;
}
return p;
}
/**
* {
"carCode": "浙A5C393",
"inTime": "2016-10-18 16:44:44",
"passTime": "2016-10-28 16:44:44",
"parkID": "12222",
"inOrOut": "1",
"GUID": "134589c1d68d44d38dcb7f084b9cf8a1",
"channelID": "1",
"channelName": "北大门出口",
"imagePath": "http://xxx.xxx.xx.xx:xx\\xxx\\xxx.jpg"
}
*/
@Override
public ParkNotifyParam parseOutNoticyParam(Object param) {
Map<String,Object> paramMap = (Map<String, Object>) param;
String carNumber = paramMap.get("carCode").toString();
String parkCode = paramMap.get("parkID").toString();
String parkName = "";
String synId = paramMap.get("GUID").toString();
Integer inTime = (Integer)paramMap.get("inTime");
Integer outTime = (Integer)paramMap.get("passTime");
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber(carNumber);
p.setParkId(parkCode);
p.setParkName(parkName);
p.setSynId(synId);
try {
p.setEntranceTime(new Date(inTime.longValue()*1000));
} catch (Exception e) {
log.error("lifang entranceTime format error",e);
return null;
}
try {
p.setOutTime(new Date(outTime.longValue()*1000));
} catch (Exception e) {
log.error("lifang outTime format error",e);
return null;
}
p.setFee("0");
return p;
}
@Override
public ParkNotifyParam parseUnbindNoticyParam(Object param) {
return null;
}

/**
* {
"recordID": "1",
"carCode": "浙A5C393",
"inTime": "2016-10-18 16:44:44",
"payTime": "2016-10-28 16:44:44",
"parkID": "12222",
"GUID": "134589c1d68d44d38dcb7f084b9cf8a1",
"chargeMoney": 1,
"paidMoney": 1,
"JMMoney": 0,
"chargeType": 0,
"chargeSource": 0,
"amountType": 0
}
*/
@Override
public ParkNotifyParam parsePaidNoticyParam(Object param) {
Map<String,Object> paramm = (Map<String, Object>) param;
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber((String) paramm.get("carCode"));
p.setParkId((String) paramm.get("parkID"));
p.setParkOrderId((String) paramm.get("recordID"));
p.setSynId((String) paramm.get("GUID"));
p.setFee(paramm.get("paidMoney").toString());
try {
p.setPayTime(lifang.utcToLocal((String)paramm.get("payTime")));
} catch (ParseException e) {
e.printStackTrace();
}
return p;
}
}

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

@@ -0,0 +1,216 @@
package com.iformall.service.park.impl.lifang;

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.ParkCreatePayOrder;
import com.iformall.service.park.entity.ParkNotifyPaid;
import com.iformall.service.park.entity.ParkPaidNotifyResult;
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;

/**
*
* token是和ip是一对一绑定,新的ip服务器调捷顺的接口会出现ip不合法,需把ip提供捷顺方,添加白名单。多个服务调捷顺接口共用一个ip情况下,只能共用一套登录获取token机制,各自登录会冲突
* 捷顺参数:
* loginurl=http://syx.jslife.com.cn/jsaims/login
* funcurl=http://syx.jslife.com.cn/jsaims/as
* cid=880075500000002
* usr=880075500000002
* psw=888888
* v=2
* signKey=2f4ce8242b796e4adbb9bdad0794c898
* parkcode=0020200529
*
* https://syx.jslife.com.cn/store/index.html#/auth/login
* 您的登录帐号是880075500000002000019,登录密码为a9A3MYJK
*
* 跳转捷停车小程序参数:(生产环境)
appid:wx24b70f0ad2a9a89a
1>小程序首页
path:pages/index/index
2>小程序页面 pages/thirdPayOrderByNo/payOrder?orderNo=订单编号&freeMinute=免费离场时间(分钟数)
找捷顺。顺易通开通下第三方小程序的捷停车支付方式
*/
@Service
public class LiFangParkService 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;
@Autowired
WxCarJSOrderMapper wxCarJSOrderMapper;
LiFangUtil lifang = new LiFangUtil();
@Override
public ResultData parkInitConfig(WxPark park) throws Exception {
// TODO Auto-generated method stub
return null;
}
@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 "lifang";
}

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


/**
* 每一次查询都会产生订单,然后根据订单号查询
*/
@Override
public ParkStopFee carStopFee(Map<String, String> paramMap, WxPark park,String carNumber) throws Exception{
return lifangCarStopFee(paramMap, park,carNumber);
}
private ParkStopFee lifangCarStopFee(Map<String, String> paramMap, WxPark park,String carNumber) throws Exception{
//下订单;
String retCode = lifang.getCarStopFee(park, carNumber);
if (StringUtils.isBlank(retCode)) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(), "lifang getCarStopFee error. has no result");
}
JSONObject result = JSON.parseObject(retCode);
if (result.getInteger("resCode") != 0 ) {
String message = result.getString("resMsg");
throw new MallinkException(result.getInteger("resCode"), "lifang getCarStopFee error."+message);
}
Integer totalFee = result.getInteger("paidMoney");
String appId = "wx24b70f0ad2a9a89a";
Integer freeMinute = result.getInteger("remainLeaveTime");
String _createTime = result.getString("inTime");//计费时间,格式为“yyyy-MM-dd HH:mi:ss”
if (totalFee <= 0 ) {
String msg = result.getString("note");
if (!StringUtils.isBlank(msg)) {
if (msg.contains("未入场")) {
return new ParkStopFee(null,lifang.utcToLocal(_createTime),new Date(),
"0.00",appId,"payPath",null,msg,null);
}else {
//0元订单结清,查询是否用过打折方案,如果用过,则需要调用接口结清订单
Integer used = ParkCacheUtils.getCarCouponUseCacheLock(redisTemplate, EnumCarVendor.CAR_LIFANG.getMessage(), carNumber);
if (null == used || (null != used && used.intValue() < 1)) {
//未使用停车券
return new ParkStopFee("-999",lifang.utcToLocal(_createTime),new Date(),
"0.00",appId,"payPath",null,msg,null);
}else {
return new ParkStopFee("-999",lifang.utcToLocal(_createTime),new Date(),
"0.00",appId,"payPath",null,msg,"用券抵扣后账单为0,获得"+freeMinute+"分钟免费出场时间");
}
}
}
}
String payPath = null;//"pages/thirdPayOrderByNo/payOrder?orderNo="+parkOrderId+"&freeMinute="+freeMinute;
//String payPath = "pages/thirdPayOrder/payOrder?carNo="+jieshun.handleCarNumber(carNumber)+"&parkCode="+park.getParkingId();
return new ParkStopFee(null,lifang.utcToLocal(_createTime),new Date(),
String.valueOf(totalFee),appId,payPath,null,null,"请支付后"+freeMinute+"分钟内离场");
}

/**
* 使用3.8打折方案,3.9有限制如果领券了之后未使用,不能再次领券。导致出现异常之后,用户永远无法使用优惠券。
* @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());
}
try {
ParkStopFee stopFee = lifangCarStopFee(paramMap, park, carNumber);
if (Integer.parseInt(stopFee.getRemainingFee()) <= 0 ) {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(),"0元无需使用优惠券");
}
//coupon判断是小时券还是现金券
String ret = lifang.addChargeInfo(park, carNumber, false, null, null);
logger.info("lifang addChargeInfo result:"+ret);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("resCode") == 0){
return new ResultData();
}else {
return new ResultData(retObj.getIntValue("resCode"),"当前用户使用立方停打折方案失败。"+retObj.getString("resMsg"));
}
}catch(Exception e) {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(),e.getMessage());
}
}
@Override
public ParkCreatePayOrder createPayOrder(Map<String, String> paramMap, WxPark park, String carNumber) throws Exception {
return null;
}

@Override
public ParkPaidNotifyResult notifyPaid(WxPark park,ParkNotifyPaid notifyPaid) throws Exception {
return null;
}

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

@Override
public boolean ignoreUseCouponCache() {
return false;
}

}

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

@@ -0,0 +1,170 @@
package com.iformall.service.park.impl.lifang;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.domain.po.WxPark;
import com.iformall.exception.MallinkException;
import com.iformall.utils.DateUtils;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.Consts;
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.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
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.net.URLEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
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;
import java.util.TimeZone;


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

@Slf4j
public class LiFangUtil {

public static final String QUERY_CAR = "/GetCarInfo";
public static final String ADD_CHARGE_INFO = "/AddChargeInfo";

/**
* @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 getCarStopFee(WxPark wxPark,String carNumber){
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
Map<String,Object> params = new HashMap<String,Object>();
params.put("carCode", carNumber);
log.info("lifang getCarStopFee :" + JSON.toJSONString(params));
return ProcBussiness(vp,QUERY_CAR,params);
}
/**
* 保存缴费信息
*/
public String addChargeInfo(WxPark wxPark,String carNumber,boolean isReduceFee,Integer total,Integer reduce) {
try {
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
Map<String,Object> params = new HashMap<String,Object>();
params.put("carCode", carNumber);
if (isReduceFee) {
params.put("chargeMoney", total);
params.put("paidMoney", total-reduce);
params.put("JMMoney", reduce);
}
params.put("payTime", DateUtils.date2String(new Date()));
params.put("chargeType", 11);
params.put("chargeSource", "3");
log.info("lifang addChargeInfo :" + JSON.toJSONString(params));
return ProcBussiness(vp,ADD_CHARGE_INFO,params);
} catch (Exception e) {
log.error("lifang verifyuser error.park:"+wxPark.getId(),e);
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"lifang addChargeInfo error.park:"+wxPark.getId()+".error"+e.getMessage());
}
}
private static String ProcBussiness(JSONObject vp,String api,Map<String,Object> params) {
String url = vp.getString("reqUrl")+api;
return Proc(url,params);
}
private static String Proc(String url, Map<String,Object> params) {
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 (null != params) {
try {
httpPost.setEntity(new StringEntity(JSONObject.toJSONString(params),ContentType.create("application/json","utf-8")));
} catch (Exception e) {
log.error(e.getLocalizedMessage(),e);
return null;
}
}

if (null != params) {
log.info("lifang httpRequest:[url]"+url+"[params]"+JSON.toJSONString(params));
}else {
log.info("lifang 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;
}
}

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