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

添加捷顺停车

release_toaliyun_real
xiaohanzi 5 лет назад
Родитель
Сommit
d07d6a0ce4
10 измененных файлов: 515 добавлений и 154 удалений
  1. +11
    -1
      mallinkCApi/src/main/java/com/iformall/controller/WxCarController.java
  2. +20
    -0
      mallinkMQConsumer/src/main/java/com/iformall/controller/HomeController.java
  3. +7
    -0
      mallinkService/src/main/java/com/iformall/config/BaseMyBatisConfiguration.java
  4. +24
    -0
      mallinkService/src/main/java/com/iformall/domain/po/WxCarJSOrder.java
  5. +4
    -0
      mallinkService/src/main/java/com/iformall/domain/vo/WxCouponOrderCarCVo.java
  6. +16
    -0
      mallinkService/src/main/java/com/iformall/mapper/WxCarJSOrderMapper.java
  7. +88
    -23
      mallinkService/src/main/java/com/iformall/service/park/impl/jieshun/JieShunParkCallbackService.java
  8. +119
    -68
      mallinkService/src/main/java/com/iformall/service/park/impl/jieshun/JieShunParkService.java
  9. +171
    -62
      mallinkService/src/main/java/com/iformall/service/park/impl/jieshun/JieShunUtil.java
  10. +55
    -0
      mallinkService/src/main/resources/mapper/WxCarJSOrderMapper.xml

+ 11
- 1
mallinkCApi/src/main/java/com/iformall/controller/WxCarController.java Просмотреть файл

@@ -276,7 +276,8 @@ public class WxCarController extends BaseController {
notes = "ETCP:={\"etcpToken\":\"string(ETCP专用)\",\"carNumber\":\"string\",\"couponOrderId\"=\"String\"}\n" +
"TJD:{\"carNumber\":\"string\",\"tradeId\":\"string\",\"accountId\":\"string\",\"couponOrderId\":\"string\"}\n" +
"ShangAn:{\"carNumber\":\"string\",\"couponOrderId\":\"string\"}\n" +
"BoLink:{\"carNumber\":\"string\",\"orderId\":\"string\",\"couponOrderId\":\"string\"}\n"
"BoLink:{\"carNumber\":\"string\",\"orderId\":\"string\",\"couponOrderId\":\"string\"}\n" +
"jieshun:{\"carNumber\":\"string\",\"orderId\":\"string\",\"couponOrderId\":\"string\",\"jsOrderId\":\"string\"}\n}"
)
@PostMapping("/getCoupon")
public ResultData getCoupon(@RequestBody Map<String, String> paramMap) {
@@ -315,6 +316,15 @@ public class WxCarController extends BaseController {
List<WxCouponOrderCarCVo> list = wxCouponOrderService.carListCUserVo(userCarQ);
if (null != list && list.size() > 0) {
userCar = list.get(0);
WxCUserBasicInfo user;
try {
user = getCacheMember();
if (null != user) {
userCar.setCUserPhone(user.getPhone());
}
} catch (Exception e) {
return new ResultData(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "当前用户缓存查询失败");
}
}

EnumCarVendor vendor = EnumCarVendor.getEnum(park.getVendorType());


+ 20
- 0
mallinkMQConsumer/src/main/java/com/iformall/controller/HomeController.java Просмотреть файл

@@ -1,10 +1,19 @@
package com.iformall.controller;

import com.alibaba.fastjson.JSON;
import com.iformall.common.ResultData;
import com.iformall.enums.EnumPayWay;
import com.iformall.pay.WxPayment;
import com.iformall.service.WxRefundOrderService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@@ -21,12 +30,23 @@ public class HomeController {

@Value("${spring.mail.username}")
private String from;
@Autowired
private WxRefundOrderService wxRefundOrderService;

@ApiOperation("获取后端版本号")
@GetMapping("/version")
public ResultData version() {
return new ResultData(version);
}
// @ApiOperation("获取后端版本号")
// @GetMapping("/ttt")
// public ResultData ttttttt() {
// String json = "<xml><return_code>SUCCESS</return_code><appid><![CDATA[wxed2f44705544b892]]></appid><mch_id><![CDATA[1511925291]]></mch_id><sub_appid><![CDATA[wx649b3be73c1afe47]]></sub_appid><sub_mch_id><![CDATA[1513691501]]></sub_mch_id><nonce_str><![CDATA[e247be6b46746354de7b5bd84f56e83d]]></nonce_str><req_info><![CDATA[Ndaz8Fj4VUkxnD9iQ2ghD0YcMhVA1AojXftGoSJ5pE03/BhSaOuypQF8/XIZc3NWcIm0xOhTxw4AhqoFmyDi+ZsDGbPKSYlaBI1prdbXr8ZGvGxVReTHS93ePZNtqpWofvtNt2h/1EOPt+a9E03Og02rvAtLlnq6RKjwTLOlIUxWXJMvtsCtpXKvcWMxRx+8pn42Barx6B2D0lM+39Vmi/qjZpQMsMdpKvl5DHkRl0QNFyaD1lQF6Ehe3B0gJhvWRI/EUkWw9lt+XPN0O3li9XPqBXTvD8DI/syYB/PtWcuKAYVdcVHzVm0uf2yM4YwDdFHWRezdozoOgeeU85NDpH7Q6kNYRqYoIg8z/WzdNRTysmHV+hUjzDZlYG7I6FmRfMoefg5kti7QkOAfDSCUJ8YAj/EzK6sYQeJqabcX6HwZzWyNVAJ9DYJquPa3T+ZFpUM5lW657Xj3DxZDwlX7TyWqSammhqWU34MRlEZ4d832pMgiQeGU2HxyKeBvzo6wwIPz0uEeqHyFSmy7x2EWeAb3SzNBkDT8u7XF6gC7zQzwM8+eoSdkjq7XZV/hPd4ZfsD7a8Y19U14KiizsfA6s33sNcKpBefSVLMfX7shFEGubnpY7bGQyPSl/xCmtgtoZlea2G9luLOlLRtppHRPmDhLvBMr8fmZbHKkRvWIO2Ec8WkhQSXKt2b85hrcP+fYx1/3u614GF+k5OSs7bmbSIydoh2L0Eh7SwgtFw8cYiR7BggAWhrHz739vYpHccKaLx+Rh39+GAtWYmzdOMEjBgScEY00lzfbpc1uruaoKDTwqxWCDfm1WFIs6XnWQh3qZCDHG6Qh+38TOtoi/2FJo509BsRcLEliVOzaSLat/gqVXQ+xYm76bSaxjA8ITdltiNTInZFTg5OJ3nCj63bvULc0Jf1KeXocHQxJQfNHleOl6GwlOIu91BEjy6Tjt5SJ2GYrTTtfb4FiE6yvvwoX08THBrheu958CcQcfD7HY8wJ76BrWIVHqnzaUvnG5aoP8VWLChx7TD+RihjX9nS18K1o8lc/5ySR57MDmPcgwLQ=]]></req_info></xml>";
// wxRefundOrderService.notify(WxPayment.xmlToMap(json), EnumPayWay.getEnum(EnumPayWay.PAY_WAY_WECHAT.getCode()));
// return new ResultData(version);
// }


}

+ 7
- 0
mallinkService/src/main/java/com/iformall/config/BaseMyBatisConfiguration.java Просмотреть файл

@@ -185,6 +185,13 @@ public class BaseMyBatisConfiguration {
wxCouponActionLogSharding.setRule(EnumShardingRule.HASH.getCode());
shardingList.add(wxCouponActionLogSharding);
ShardingSphere wxCarJSOrderSharding = new ShardingSphere();
wxCarJSOrderSharding.setColumn("car_number");
wxCarJSOrderSharding.setTableName("wx_car_js_order");
wxCarJSOrderSharding.setCount(100);
wxCarJSOrderSharding.setRule(EnumShardingRule.HASH.getCode());
shardingList.add(wxCarJSOrderSharding);
//初始化


+ 24
- 0
mallinkService/src/main/java/com/iformall/domain/po/WxCarJSOrder.java Просмотреть файл

@@ -0,0 +1,24 @@
package com.iformall.domain.po;

import com.baomidou.mybatisplus.annotation.TableName;
import com.iformall.domain.po.base.TenantEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import java.util.Date;

@TableName(value = "wx_car_js_order")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class WxCarJSOrder extends TenantEntity {

private static final long serialVersionUID = 4859824437127457878L;
private Long id;
private String carNumber;
private String orderId;
private Integer status;
private Date createTime;
private Date updateTime;

}

+ 4
- 0
mallinkService/src/main/java/com/iformall/domain/vo/WxCouponOrderCarCVo.java Просмотреть файл

@@ -1,5 +1,6 @@
package com.iformall.domain.vo;

import com.baomidou.mybatisplus.annotation.TableField;
import com.iformall.domain.po.WxCouponOrder;
import lombok.Data;
import lombok.EqualsAndHashCode;
@@ -14,5 +15,8 @@ public class WxCouponOrderCarCVo extends WxCouponOrderCVo {

@io.swagger.annotations.ApiModelProperty(value="couponFreeId",name="couponFreeId")
private Integer couponFreeId;
@TableField(exist = false)
private String cUserPhone;

}

+ 16
- 0
mallinkService/src/main/java/com/iformall/mapper/WxCarJSOrderMapper.java Просмотреть файл

@@ -0,0 +1,16 @@
package com.iformall.mapper;

import com.iformall.common.CommonMapper;
import com.iformall.domain.po.WxCarJSOrder;

/**
* @author gongbiao
*/
public interface WxCarJSOrderMapper extends CommonMapper<WxCarJSOrder, String> {
WxCarJSOrder getOneOrder(WxCarJSOrder order);
void updateStatus(WxCarJSOrder order);

}

+ 88
- 23
mallinkService/src/main/java/com/iformall/service/park/impl/jieshun/JieShunParkCallbackService.java Просмотреть файл

@@ -4,20 +4,47 @@ import java.text.ParseException;
import java.util.Date;
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.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.ParkCallBackAdapterService;
import com.iformall.service.park.entity.ParkNotifyParam;
import com.iformall.service.park.impl.BaseParkService;
import com.iformall.service.park.impl.cyf.CYFUtil;
import com.iformall.service.park.impl.tjd.TJDUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class JieShunParkCallbackService extends BaseParkService implements ParkCallBackAdapterService {
@Autowired
JieShunParkService jieshunParkService;
@Autowired
WxParkService wxParkService;
@Autowired
WxCarJSOrderMapper wxCarJSOrderMapper;
private String handleCarNumber(String carNumber) {
if (carNumber.contains("-")) {
carNumber = carNumber.replaceAll("-", "");
}
return carNumber;
}

/**
* {
@@ -45,47 +72,85 @@ public class JieShunParkCallbackService extends BaseParkService implements ParkC
@Override
public ParkNotifyParam parseInNoticyParam(Object param) {
Map<String, Object> paramMap = (Map<String, Object>) param;
String carNumber = paramMap.get(JieShunUtil.CYF_CAR_NUMBER).toString();
String cyfParkId = paramMap.get(CYFUtil.CYF_PARK_ID).toString();
String parkName = paramMap.get(CYFUtil.CYF_PARK_NAME).toString();
String synId = paramMap.get(CYFUtil.CYF_SYN_ID).toString();
String entranceTime = paramMap.get(CYFUtil.CYF_ENTRANCE_TIME).toString();
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();
p.setCarNumber(carNumber);
p.setParkId(cyfParkId);
String realCarNumber = handleCarNumber(carNumber);
p.setCarNumber(realCarNumber);
p.setParkId(parkCode);
p.setParkName(parkName);
p.setSynId(synId);
try {
p.setEntranceTime(CYFUtil.utcToLocal(entranceTime));
p.setEntranceTime(JieShunUtil.utcToLocal(entranceTime));
} catch (ParseException e) {
log.error("cyf entranceTime format error",e);
return null;
}
//下订单;
WxPark pq = new WxPark();
pq.setVendorType(EnumCarVendor.CAR_JIESHUN.getCode());
pq.setParkId(parkCode);
WxPark park = wxParkService.getByObj(pq);
String retCode = jieshunParkService.createOrder(park, carNumber);
if (StringUtils.isBlank(retCode)) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(), "jieshun createOrder error. has no result");
}
JSONObject result = JSON.parseObject(retCode);
if (result.getInteger("resultCode") != 0 ) {
String message = result.getString("message");
throw new MallinkException(result.getInteger("resultCode"), "jieshun createOrder error."+message);
}
String parkOrderId = result.getString("orderNo");
//记录当前车牌的订单号
WxCarJSOrder order = new WxCarJSOrder();
order.setId(IdWorker.get().nextId());
order.setCarNumber(realCarNumber);
order.updateTenantInfo(park);
order.setCreateTime(new Date());
order.setUpdateTime(new Date());
order.setStatus(1);
order.setOrderId(parkOrderId);
wxCarJSOrderMapper.insert(order);
return p;
}

@Override
public ParkNotifyParam parseOutNoticyParam(Object param) {
WxCarCYFVo vo = (WxCarCYFVo) param;
Map<String, Object> paramMap = (Map<String, Object>) param;
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 = handleCarNumber(carNumber);
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber(vo.getPlate());
p.setParkId(String.valueOf(vo.getParkingId()));
p.setParkName(vo.getRecordOrderId());
p.setSynId(vo.getRecordOrderId());
p.setCarNumber(realCarNumber);
p.setParkId(parkCode);
p.setParkName(parkName);
p.setSynId(synId);
try {
p.setEntranceTime(TJDUtil.dateOutFormat.parse(vo.getInInfo().getTime()));
p.setEntranceTime(JieShunUtil.utcToLocal(entranceTime));
} catch (ParseException e) {
log.error("cyf entranceTime format error",e);
return null;
}
try {
p.setOutTime(TJDUtil.dateOutFormat.parse(vo.getOutInfo().getTime()));
p.setOutTime(JieShunUtil.utcToLocal(entranceTime));
} catch (ParseException e) {
log.error("cyf outTime format error",e);
return null;
}
p.setFee(String.valueOf(vo.getPayInfoList().getActualFee()));
p.setFee(String.valueOf(paramMap.get("ssMoney")));
WxCarJSOrder order = new WxCarJSOrder();
order.setCarNumber(realCarNumber);
wxCarJSOrderMapper.updateStatus(order);
return p;
}

@@ -98,12 +163,12 @@ public class JieShunParkCallbackService extends BaseParkService implements ParkC
public ParkNotifyParam parsePaidNoticyParam(Object param) {
Map vo = (Map) param;
ParkNotifyParam p = new ParkNotifyParam();
p.setCarNumber((String) vo.get("plate"));
p.setParkId(String.valueOf(vo.get("parkId")));
p.setCarNumber((String) vo.get("carNumber"));
p.setParkId(String.valueOf(vo.get("parkCode")));
p.setParkOrderId((String) vo.get("orderNo"));
p.setSynId((String) vo.get("orderNo"));
p.setFee(vo.get("fee").toString());
p.setPayTime((Date) vo.get("payTime"));
p.setSynId((String) vo.get("itemId"));
p.setFee(vo.get("totalFee").toString());
p.setPayTime((Date) vo.get("tradeTime"));
return p;
}



+ 119
- 68
mallinkService/src/main/java/com/iformall/service/park/impl/jieshun/JieShunParkService.java Просмотреть файл

@@ -7,21 +7,30 @@ 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.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.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.impl.BaseParkService;
import com.iformall.service.park.impl.util.ParkHelper;
import com.iformall.utils.RedisCacheUtils;
import com.iformall.utils.RedisLock;

@Service
public class JieShunParkService extends BaseParkService implements ParkAdapterService {
@@ -31,48 +40,80 @@ public class JieShunParkService extends BaseParkService implements ParkAdapterSe
@Autowired
ParkHelper parkHelper;
JieShunUtil cyf = new JieShunUtil();
@Autowired
@Qualifier("objectCommonRedisTemplate")
RedisTemplate<String, Object> baseCUserTokenRedisTemplate;
@Autowired
RedisLock redisLock;
@Autowired
WxCarJSOrderMapper wxCarJSOrderMapper;
JieShunUtil jieshun = new JieShunUtil();
private String getCacheToken(WxPark park) {
// String token = RedisCacheUtils.getCacheString(baseCUserTokenRedisTemplate, "carStop:jieshuntoken:"+park.getId());
// if (StringUtils.isBlank(token)) {
// String lockKey = "carStop:jieshuntokenlock:"+park.getTenantId();
// long time = System.currentTimeMillis() + 2000;
// String timeStr = String.valueOf(time);
// if (redisLock.lock2(lockKey, timeStr)) {
// token = jieshun.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(baseCUserTokenRedisTemplate, "carStop:jieshuntoken:"+park.getId());
return null;
}
private void setCacheToken(WxPark park,String token) {
RedisCacheUtils.cache(baseCUserTokenRedisTemplate, "carStop:jieshuntoken:"+park.getId(), token, 3600);
}
/**
* 先去捷顺注册,调用登陆获取令牌,然后根据令牌调用别的接口
* api.jieshun.cn:9088/apply/ 注册信息地址 fumao/iformall2020
*
* API对接注意事项:
1、token有效期两个小时,每两小时内登录一次获取token,调业务接口不需要频繁登录用,建议获取一次token存本地缓存,之后从本地获取,两小时内刷新一次,
为避免调业务接口时刚好token被刷新,导致token失效(无效的令牌或令牌已过期),可以做下容错,重新登录获取token或用最新token重新调业务接口。
2、token是和ip是一对一绑定,新的ip服务器调捷顺的接口会出现ip不合法,需把ip提供捷顺方,添加白名单。多个服务调捷顺接口共用一个ip情况下,只能共用一套登录获取token机制,各自登录会冲突。
3、所有接口要带车牌的一律带横杠。格式如:粤-B12345。
4、无效的数据签名是指sn加密方式不对。sn加密方式是对p+signkey进行Md5加密,加密后的字符串大写。
*/
@Override
public String initLogin(Map<String, String> paramMap, WxPark park, WxCUserBasicInfo member) throws Exception{
return null;
}
/**
* 下订单
*/
public String createOrder(WxPark park,String carNumber) {
return jieshun.createOrder(park, carNumber, getCacheToken(park));
}
@Override
public String bindCar(Map<String, String> paramMap, WxPark park, WxCUserBasicInfo member) throws Exception{
return jieshunBindCar(paramMap,park,member);
return "jieshun";
}
/**
* @description 车易付会员车辆信息注册
* @Params [paramMap, park, wxCUser]
* @return com.iformall.common.ResultData
* @Author furunxin
* @Date 2020/7/8 下午10:23
**/
private String jieshunBindCar(Map<String, String> paramMap, WxPark park,WxCUserBasicInfo member) throws Exception {
String carNumber = paramMap.get("carNumber");
if (StringUtils.isBlank(carNumber)) {
logger.error("carNumber为空");
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), "carNumber为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String token = objParams.getString("token");
int feeGroupId = objParams.getIntValue("feeGroupId");
String ret = cyf.registerCar(token,park.getNumber(),feeGroupId,park.getParkingId(),carNumber,null,member.getNickName());
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("result") == 1){
return retObj.get("localPersonId").toString();
}else {
logger.error("cyfBindCar error. paramMap: {} . cyfResult: {}",JSON.toJSONString(paramMap),ret);
String msg = retObj.getString("strError");
throw new MallinkException(ErrorCode.CAR_BIND_FAIL.getCode(), "绑车牌失败:"+msg);
//return new ResultData(, "绑车牌失败", retObj);
}
}


@Override
public void unbindCar(Map<String, String> paramMap, WxPark park, WxCUserBasicInfo member) throws Exception{
@@ -81,66 +122,76 @@ public class JieShunParkService extends BaseParkService implements ParkAdapterSe

@Override
public ResultData carStopFee(Map<String, String> paramMap, WxPark park) throws Exception{
return cyfCarStopFee(paramMap, park);
return jieshunCarStopFee(paramMap, park);
}
private ResultData cyfCarStopFee(Map<String, String> paramMap, WxPark park) throws Exception{
private ResultData jieshunCarStopFee(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为空");
}
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String token = objParams.getString("token");
String ret = cyf.getCarStopFee(token,park.getParkingId(),carNumber);
WxCarJSOrder order = new WxCarJSOrder();
order.setCarNumber(carNumber);
order.setStatus(1);
WxCarJSOrder jsorder = wxCarJSOrderMapper.getOneOrder(order);
if (null == jsorder) {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(), "停车费获取失败:该车牌订单未查询到!");
}
String ret = jieshun.getCarStopFee(park, jsorder.getOrderId(), getCacheToken(park));
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("result") == 1){
if (retObj.getIntValue("resultCode") == 0){
return new ResultData(retObj);
}else {
logger.error("cyfCarStopFee error. paramMap: {} . cyfResult: {}",JSON.toJSONString(paramMap),ret);
String msg = retObj.getString("strError");
logger.error("jieshunCarStopFee error. paramMap: {} . jieshunResult: {}",JSON.toJSONString(paramMap),ret);
String msg = retObj.getString("message");
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(), "停车费获取失败:"+msg);
}
}

/**
* 优惠券支付流程:(1):调取openapi/getFee路径获取当前停车费,入参:plate,parkingId,token
(2):调用地址:http://wechat.cheyifu2016.com/fm-pay/#/transit?encodeURIComponent('orderNo=123&couponFee=2&actualFee=20')
注: 详细参考接口文档参数
* @param token
* @param orderNo
* @param couponFee
* @param actualFee
* 使用停车券。 先获取停车券,再使用。
* @return
*/
@Override
public ResultData useCoupon(Map<String, String> paramMap, WxPark park, WxCouponOrderCarCVo userCar,WxCoupon coupon,String carNumber) throws Exception{
String params = park.getVendorParams();
JSONObject objParams = JSON.parseObject(params);
String token = objParams.getString("token");
//先获取停车费,然后再提交停车费
String ret = cyf.getCarStopFee(token,park.getParkingId(),carNumber);
String orderNo = objParams.getString("jsOrderId");
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());
}
String ret = jieshun.getCoupon(park, userCar.getCUserPhone(), getCacheToken(park));
logger.info("jieshun getCoupon result:"+ret);
JSONObject retObj = JSON.parseObject(ret);
if (retObj.getIntValue("result") == 1){
String orderId = retObj.getString("orderId");
if (StringUtils.isBlank(orderId)) {
logger.error("cyfCarStopFee error. paramMap: {} . cyfResult: {}",JSON.toJSONString(paramMap),ret);
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(), "车易付停车费查询未返回订单编号:"+orderId);
if (retObj.getIntValue("resultCode") == 0){
JSONArray couponArrays = retObj.getJSONArray("dataItems");
if (null != couponArrays && couponArrays.size() > 0 ) {
JSONObject coupoo = couponArrays.getJSONObject(0);
String couponNo = coupoo.getString("couponsNo");
String rret = jieshun.useCoupon(park, couponNo, orderNo, getCacheToken(park));
logger.info("jieshun useCoupon["+orderNo+"] result:"+rret);
JSONObject rretObj = JSON.parseObject(rret);
if (rretObj.getIntValue("resultCode") == 0){
return new ResultData();
}else {
return new ResultData(rretObj.getIntValue("resultCode"),"当前用户使用捷顺停车券失败。"+rretObj.getString("message"));
}
}else {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(),"当前用户未领用到捷顺停车券。"+userCar.getcUserId());
}
if (!coupon.getUnit().equals(EnumCouponUnit.MONEY.getCode())) {
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(), "车易付只能支持金额券,不能使用小时券:"+orderId);
}
int fee = retObj.getInteger("fee");
int amount = Integer.parseInt(coupon.getPriceStr());
Map retmap = new HashMap();
retmap.put("orderNo", orderId);
retmap.put("couponFee", amount);
retmap.put("actualFee", fee-amount);
return new ResultData();
}else {
logger.error("cyfCarStopFee error. paramMap: {} . cyfResult: {}",JSON.toJSONString(paramMap),ret);
String msg = retObj.getString("strError");
return new ResultData(ErrorCode.CYF_STOP_FEE_FAIL.getCode(), "停车费获取失败:"+msg);
logger.error("jieshun getCoupon error. paramMap: {} . cyfResult: {}",JSON.toJSONString(paramMap),ret);
String msg = retObj.getString("message");
return new ResultData(retObj.getIntValue("resultCode"), "当前用户领用到捷顺停车券失败:"+msg);
}
}



+ 171
- 62
mallinkService/src/main/java/com/iformall/service/park/impl/jieshun/JieShunUtil.java Просмотреть файл

@@ -1,25 +1,38 @@
package com.iformall.service.park.impl.jieshun;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.iformall.domain.po.WxPark;

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.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.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;

@@ -44,6 +57,15 @@ public class JieShunUtil {
public static final int CYF_SUC = 1;
public static final int CYF_ERR = 0;

public static final String TOKEN_URL = "http://www.jslife.com.cn/jsaims/login";
public static final String CREATE_ORDER = "";
public static final String QUERY_ORDER = "";
public static final String GET_COUPON = "";
public static final String COUPON_USE = "";

//会员车辆信息注册接口地址
public static final String REGISTER_CAR_URL = "http://open.cheyifu2016.com:8892/openapi/personCar";
@@ -81,66 +103,153 @@ public class JieShunUtil {
return nowDate;
}



public String getToken(WxPark wxPark) {
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
String cid = wxPark.getParkingId();
String userName = vp.getString("userName");
String password = vp.getString("password");
return getToken(cid,userName,password);
}
private String getToken(String cid,String userName,String password) {
String result = ProcLogin(cid, userName,password);
log.info("jieshun token cid:"+cid+" userName:"+userName+" password:"+password+" result: "+result);
if (StringUtils.isBlank(result)) {
return null;
}
JSONObject res = JSON.parseObject(result);
Integer code = res.getInteger("resultCode");
if (null == code || code.intValue() != 0) {
return null;
}
return res.getString("token");
}
private Map generateMap(String serviceId,Map param) {
Map map = new HashMap();
map.put("serviceId", serviceId);
map.put("requestType", "DATA");
map.put("attributes", param);
return map;
}
private String handleCarNumber(String carNumber) {
if (carNumber.contains("-")) {
return carNumber;
}else {
carNumber = carNumber.substring(0,1)+carNumber.substring(1, carNumber.length()-1);
return carNumber;
}
}
/**
* @description 会员车辆信息注册
* @Params [token, carport, feeGroupId, parkingId, plates, personId, personName]
* @return java.lang.String
* @Author furunxin
* @Date 2020/7/8 下午10:12
* 创建订单
* @return
*/
public String createOrder(WxPark wxPark,String cardNumber,String token) {
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
Map param = new HashMap();
param.put("businesserCode", vp.get("businesserCode"));//商户编号
param.put("parkCode", wxPark.getParkId());
param.put("orderType", "VNP");
param.put("carNo", handleCarNumber(cardNumber));
Map map = generateMap("3c.pay.createorderbycarno",param);
log.info("jieshun create order :" + JSON.toJSONString(map));
return ProcBussiness(CREATE_ORDER, wxPark.getParkingId(), map, token);
}
/**
* 查询停车费
**/
public String registerCar(String token,int carport,int feeGroupId,String parkingId,String plates,Long personId,String personName){
String[] plate = new String[1];
plate[0] = plates;
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("token",token);
paramMap.put("parkingId",Integer.valueOf(parkingId));
paramMap.put("beginTime",getLocalDate());
paramMap.put("endTime",getLocalDate());
paramMap.put("feeGroupId",feeGroupId);
paramMap.put("lotNumber",carport);
//paramMap.put("personId",personId);
paramMap.put("personName",personName);
paramMap.put("plates",plate);
String result = Proc(REGISTER_CAR_URL, paramMap);
return result;
public String getCarStopFee(WxPark wxPark,String orderNo,String token){
Map param = new HashMap();
param.put("orderNo", orderNo);//商户编号
Map map = generateMap("3c.pay.queryorder",param);
log.info("jieshun getCarStopFee :" + JSON.toJSONString(map));
return ProcBussiness(QUERY_ORDER, wxPark.getParkingId(), map, token);
}

/**
* @description 根据车牌号获取停车费
* @Params [token, parkingId, plates]
* @return java.lang.String
* @Author furunxin
* @Date 2020/7/12 下午3:51
* 获取优惠券
**/
public String getCarStopFee(String token,String parkingId,String plates){
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("token ",token);
paramMap.put("parkingId",Integer.valueOf(parkingId));
paramMap.put("plates",plates);
paramMap.put("carOutTime",0);
String result = Proc(GET_CAR_STOPFEE, paramMap);
return result;
public String getCoupon(WxPark wxPark,String phone,String token){
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
String couponNo = vp.getString("couponNo");
Map param = new HashMap();
param.put("businesserCode", vp.get("businesserCode"));//商户编号
param.put("planNo", couponNo);//优惠券编号
param.put("tel", phone);//商户编号
Map map = generateMap("3c.coupons.receive.coupons",param);
log.info("jieshun getCoupon :" + JSON.toJSONString(map));
return ProcBussiness(GET_COUPON, wxPark.getParkingId(), map, token);
}
/**
* @description 解绑车辆
* @param token
* @param parkingId
* @param personId
* @return
*/
public String unbindCar(String token,String parkingId,String vendorPersonId) {
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("token ",token);
paramMap.put("parkingId",Integer.valueOf(parkingId));
paramMap.put("personId",Integer.valueOf(vendorPersonId));
String result = Proc(UNBIND_CAR, paramMap);
return result;
* 使用优惠券
**/
public String useCoupon(WxPark wxPark,String couponNo,String orderNo,String token){
String vendroParams = wxPark.getVendorParams();
JSONObject vp = JSON.parseObject(vendroParams);
Map param = new HashMap();
param.put("businesserCode", vp.get("businesserCode"));//商户编号
param.put("couponsNo", couponNo);//优惠券编号
param.put("orderNo", orderNo);//商户编号
param.put("parkCode", wxPark.getParkId());
Map map = generateMap("3c.coupons.use.coupons",param);
log.info("jieshun useCoupon :" + JSON.toJSONString(map));
return ProcBussiness(COUPON_USE, wxPark.getParkingId(), map, token);
}

private static String Proc(String url, Map<String, Object> paramMap) {
private static String ProcLogin(String cid,String user,String password) {
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("cid", cid));
list.add(new BasicNameValuePair("usr", user));
list.add(new BasicNameValuePair("psw",password));
return Proc(TOKEN_URL,list);
}
private static String ProcBussiness(String url,String cid,Map<String,Object> param,String token) {
try {
MessageDigest md5Tool = MessageDigest.getInstance("MD5");
String p = JSON.toJSONString(param);
byte[] md5Data = md5Tool.digest(p.getBytes("UTF-8"));
String sn = toHexString(md5Data);
ArrayList<NameValuePair> list = new ArrayList<NameValuePair>();
list.add(new BasicNameValuePair("cid", cid));
list.add(new BasicNameValuePair("v", "1.0"));//版本号
list.add(new BasicNameValuePair("p",p));
list.add(new BasicNameValuePair("sn",sn));
if (!StringUtils.isBlank(token)) {
list.add(new BasicNameValuePair("tn",token));
}
return Proc(url,list);
} catch (NoSuchAlgorithmException e) {
log.error("jieshun request error.",e);
} catch (UnsupportedEncodingException e) {
log.error("jieshun request error.",e);
}
return null;
}
private static String toHexString(byte[] bytes) {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < bytes.length; i++) {
buffer.append(String.format("%02X", bytes[i]));
}
return buffer.toString();
}
private static String Proc(String url, List<NameValuePair> pairs) {
CloseableHttpClient httpClient = HttpClients.createDefault();

HttpPost httpPost = new HttpPost(url);
@@ -148,16 +257,16 @@ public class JieShunUtil {
httpPost.addHeader("Accept", "application/json");
httpPost.addHeader("Accept-Encoding", "UTF-8");

String jsonstr = JSON.toJSONString(paramMap);
log.info("请求报文:"+jsonstr);
try {
StringEntity se = new StringEntity(jsonstr, Consts.UTF_8);
se.setContentType("application/json");
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"UTF-8"));
httpPost.setEntity(se);
} catch (Exception e) {
log.error(e.getMessage());
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;
}
}

HttpResponse response = null;
@@ -177,7 +286,7 @@ public class JieShunUtil {
result = EntityUtils.toString(httpEntity, "UTF-8");
log.debug(result);
} catch (Exception e) {
log.error(e.getLocalizedMessage());
log.error(e.getLocalizedMessage(),e);
}

try { //关闭流并释放资源


+ 55
- 0
mallinkService/src/main/resources/mapper/WxCarJSOrderMapper.xml Просмотреть файл

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iformall.mapper.WxCarJSOrderMapper">
<resultMap id="BaseResultMap" type="com.iformall.domain.po.WxCarJSOrder">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/>
<result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId"/>
<result column="car_number" jdbcType="VARCHAR" property="carNumber"/>
<result column="order_id" jdbcType="VARCHAR" property="orderId"/>
<result column="status" jdbcType="INTEGER" property="status"/>
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
</resultMap>

<sql id="allColumns">
`id`,`car_number`,`tenant_id`,`parent_tenant_id`,`order_id`,`status`,`create_time`,`update_time`
</sql>

<sql id="dynamicWhereConditions">
where 1 = 1

<if test=" null != id ">
and `id` = #{id}
</if>

<if test=" null != tenantId and '' != tenantId">
and `tenant_id` = #{tenantId}
</if>
<if test=" null != parentTenantId and '' != parentTenantId">
and `parent_tenant_id` = #{parentTenantId}
</if>

<if test=" null != carNumber and '' != carNumber">
and `car_number` = #{carNumber}
</if>
<if test=" null != status and '' != status">
and `status` = #{status}
</if>
</sql>

<select id="getOneOrder" parameterType="com.iformall.domain.po.WxCarJSOrder" resultMap="BaseResultMap">
select
<include refid="allColumns"/>
from wx_car_js_order
<include refid="dynamicWhereConditions"/>
order by create_time desc
limit 0, 1
</select>
<update id="updateStatus" parameterType="com.iformall.domain.po.WxCarJSOrder">
update wx_car_js_order set status = 2, update_time=now() where car_number = #{carNumber} and status = 1
</update>
</mapper>

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