mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-07-23 15:41:17 +08:00
Compare commits
1 Commits
e4be50b417
...
feature-qc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ec61089fc |
@@ -522,8 +522,8 @@ public class PersonPileController extends BaseController {
|
|||||||
try {
|
try {
|
||||||
String memberId = getMemberIdByAuthorization(request);
|
String memberId = getMemberIdByAuthorization(request);
|
||||||
dto.setMemberId(memberId);
|
dto.setMemberId(memberId);
|
||||||
yuxinReservationChargingService.createReservation(dto);
|
int reservedId = yuxinReservationChargingService.createReservation(dto);
|
||||||
response = new RestApiResponse<>();
|
response = new RestApiResponse<>(ImmutableMap.of("reservedId", reservedId));
|
||||||
} catch (BusinessException e) {
|
} catch (BusinessException e) {
|
||||||
logger.error("羽信添加预约充电error, params:{}", dto, e);
|
logger.error("羽信添加预约充电error, params:{}", dto, e);
|
||||||
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||||
@@ -535,6 +535,102 @@ public class PersonPileController extends BaseController {
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 羽信主板修改预约充电
|
||||||
|
* http://localhost:8080/uniapp/personalPile/yuxin/updateReservation
|
||||||
|
*/
|
||||||
|
@PostMapping("/yuxin/updateReservation")
|
||||||
|
public RestApiResponse<?> updateYuxinReservation(HttpServletRequest request, @RequestBody YuxinReservationChargingDTO dto) {
|
||||||
|
RestApiResponse<?> response = null;
|
||||||
|
try {
|
||||||
|
String memberId = getMemberIdByAuthorization(request);
|
||||||
|
dto.setMemberId(memberId);
|
||||||
|
int i = yuxinReservationChargingService.updateReservation(dto);
|
||||||
|
if (i > 0) {
|
||||||
|
response = new RestApiResponse<>();
|
||||||
|
} else {
|
||||||
|
response = new RestApiResponse<>(ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR.getValue(), ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR.getLabel() + ": 充电桩返回修改失败");
|
||||||
|
}
|
||||||
|
} catch (BusinessException e) {
|
||||||
|
logger.error("羽信修改预约充电error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("羽信修改预约充电error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR);
|
||||||
|
}
|
||||||
|
logger.info("羽信修改预约充电params:{}, result:{}", dto, response);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 羽信主板取消预约充电
|
||||||
|
* http://localhost:8080/uniapp/personalPile/yuxin/cancelReservation
|
||||||
|
*/
|
||||||
|
@PostMapping("/yuxin/cancelReservation")
|
||||||
|
public RestApiResponse<?> cancelYuxinReservation(HttpServletRequest request, @RequestBody YuxinReservationChargingDTO dto) {
|
||||||
|
RestApiResponse<?> response = null;
|
||||||
|
try {
|
||||||
|
String memberId = getMemberIdByAuthorization(request);
|
||||||
|
dto.setMemberId(memberId);
|
||||||
|
yuxinReservationChargingService.cancelReservation(dto);
|
||||||
|
response = new RestApiResponse<>();
|
||||||
|
} catch (BusinessException e) {
|
||||||
|
logger.error("羽信取消预约充电error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("羽信取消预约充电error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR);
|
||||||
|
}
|
||||||
|
logger.info("羽信取消预约充电params:{}, result:{}", dto, response);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 羽信主板删除预约
|
||||||
|
* http://localhost:8080/uniapp/personalPile/yuxin/deleteReservation
|
||||||
|
*/
|
||||||
|
@PostMapping("/yuxin/deleteReservation")
|
||||||
|
public RestApiResponse<?> deleteYuxinReservation(HttpServletRequest request, @RequestBody YuxinReservationChargingDTO dto) {
|
||||||
|
RestApiResponse<?> response = null;
|
||||||
|
try {
|
||||||
|
String memberId = getMemberIdByAuthorization(request);
|
||||||
|
dto.setMemberId(memberId);
|
||||||
|
yuxinReservationChargingService.deleteReservation(dto);
|
||||||
|
response = new RestApiResponse<>();
|
||||||
|
} catch (BusinessException e) {
|
||||||
|
logger.error("羽信删除预约error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("羽信删除预约error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR);
|
||||||
|
}
|
||||||
|
logger.info("羽信删除预约params:{}, result:{}", dto, response);
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 羽信主板查询预约信息
|
||||||
|
* http://localhost:8080/uniapp/personalPile/yuxin/queryReservationInfo
|
||||||
|
*/
|
||||||
|
@PostMapping("/yuxin/queryReservationInfo")
|
||||||
|
public RestApiResponse<?> queryYuxinReservationInfo(HttpServletRequest request, @RequestBody YuxinReservationChargingDTO dto) {
|
||||||
|
RestApiResponse<?> response = null;
|
||||||
|
try {
|
||||||
|
String memberId = getMemberIdByAuthorization(request);
|
||||||
|
dto.setMemberId(memberId);
|
||||||
|
PileReservationInfoVO vo = yuxinReservationChargingService.queryReservationInfo(dto);
|
||||||
|
response = new RestApiResponse<>(vo);
|
||||||
|
} catch (BusinessException e) {
|
||||||
|
logger.error("羽信查询预约状态error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("羽信查询预约状态error, params:{}", dto, e);
|
||||||
|
response = new RestApiResponse<>(ReturnCodeEnum.CODE_QUERY_RESERVATION_STATUS_ERROR);
|
||||||
|
}
|
||||||
|
logger.info("羽信查询预约状态params:{}, result:{}", dto, JSON.toJSONString(response));
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存蓝牙充电记录
|
* 保存蓝牙充电记录
|
||||||
* http://localhost:8080/uniapp/personalPile/saveBluetoothChargingRecord
|
* http://localhost:8080/uniapp/personalPile/saveBluetoothChargingRecord
|
||||||
|
|||||||
@@ -45,15 +45,6 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
|||||||
// log.info("[====远程更新应答====] param:{}, channel:{}", JSON.toJSONString(ykcDataProtocol), channel.toString());
|
// log.info("[====远程更新应答====] param:{}, channel:{}", JSON.toJSONString(ykcDataProtocol), channel.toString());
|
||||||
// 消息体
|
// 消息体
|
||||||
byte[] msgBody = ykcDataProtocol.getMsgBody();
|
byte[] msgBody = ykcDataProtocol.getMsgBody();
|
||||||
String responseFrameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType());
|
|
||||||
boolean yuxinResponse = StringUtils.equals(responseFrameType, yuxinType);
|
|
||||||
String rawMessage = BytesUtil.bin2HexStr(ykcDataProtocol.getBytes());
|
|
||||||
int minMsgBodyLength = yuxinResponse ? 27 : 26;
|
|
||||||
if (msgBody == null || msgBody.length < minMsgBodyLength) {
|
|
||||||
log.warn("预约充电响应长度异常, 帧类型:{}, 报文体长度:{}, 原始报文:{}",
|
|
||||||
responseFrameType, msgBody == null ? null : msgBody.length, rawMessage);
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int startIndex = 0;
|
int startIndex = 0;
|
||||||
int length = 16;
|
int length = 16;
|
||||||
@@ -75,6 +66,8 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
|||||||
startIndex += length;
|
startIndex += length;
|
||||||
length = 1;
|
length = 1;
|
||||||
byte[] connectorCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
byte[] connectorCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
||||||
|
String responseFrameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType());
|
||||||
|
boolean yuxinResponse = StringUtils.equals(responseFrameType, yuxinType);
|
||||||
String connectorCode = yuxinResponse ? parseYuxinConnectorCode(connectorCodeByteArr) : BytesUtil.bcd2Str(connectorCodeByteArr);
|
String connectorCode = yuxinResponse ? parseYuxinConnectorCode(connectorCodeByteArr) : BytesUtil.bcd2Str(connectorCodeByteArr);
|
||||||
|
|
||||||
String reservationType = null;
|
String reservationType = null;
|
||||||
@@ -100,41 +93,27 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
|||||||
String failedReasonMsg = yuxinResponse ? getYuxinFailedReasonMsg(failedReason) : failedReason;
|
String failedReasonMsg = yuxinResponse ? getYuxinFailedReasonMsg(failedReason) : failedReason;
|
||||||
|
|
||||||
if (yuxinResponse) {
|
if (yuxinResponse) {
|
||||||
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 结果:{}({}), 失败原因:{}({}), 原始报文:{}",
|
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 结果:{}, 失败原因:{}",
|
||||||
responseFrameType, transactionCode, pileSn, connectorCode, reservationType, resultCode,
|
responseFrameType, transactionCode, pileSn, connectorCode, reservationType, resultCode, failedReasonMsg);
|
||||||
getYuxinSetupResultMsg(resultCode), failedReason, failedReasonMsg, rawMessage);
|
|
||||||
if (!StringUtils.equals(resultCode, "01")) {
|
|
||||||
log.warn("羽信预约充电设置失败, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 失败原因:{}({}), 原始报文:{}",
|
|
||||||
transactionCode, pileSn, connectorCode, reservationType, failedReason, failedReasonMsg, rawMessage);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 结果:{}, 失败原因:{}, 原始报文:{}",
|
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 结果:{}, 失败原因:{}",
|
||||||
responseFrameType, transactionCode, pileSn, connectorCode, resultCode, failedReason, rawMessage);
|
responseFrameType, transactionCode, pileSn, connectorCode, resultCode, failedReason);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据请求id,在集合中找到与外部线程通信的SyncPromise对象
|
// 根据请求id,在集合中找到与外部线程通信的SyncPromise对象
|
||||||
String requestFrameType = YKCFrameTypeCode.PileAnswersRelation.getRequestFrameType(responseFrameType);
|
String requestFrameType = YKCFrameTypeCode.PileAnswersRelation.getRequestFrameType(responseFrameType);
|
||||||
if (StringUtils.isBlank(requestFrameType)) {
|
if (StringUtils.isBlank(requestFrameType)) {
|
||||||
requestFrameType = yuxinResponse
|
requestFrameType = YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_SETUP_CODE.getBytes());
|
||||||
? YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE.getBytes())
|
|
||||||
: YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_SETUP_CODE.getBytes());
|
|
||||||
}
|
}
|
||||||
String msgId = ctx.channel().id().toString() + "_" + requestFrameType;
|
String msgId = ctx.channel().id().toString() + "_" + requestFrameType;
|
||||||
log.info("同步获取响应数据-收到消息, msgId:{}", msgId);
|
log.info("同步获取响应数据-收到消息, msgId:{}", msgId);
|
||||||
SyncPromise syncPromise = RpcUtil.getSyncPromiseMap().get(msgId);
|
SyncPromise syncPromise = RpcUtil.getSyncPromiseMap().get(msgId);
|
||||||
if (syncPromise != null) {
|
if(syncPromise != null) {
|
||||||
// 设置响应结果
|
// 设置响应结果
|
||||||
syncPromise.setRpcResult(ykcDataProtocol.getBytes());
|
syncPromise.setRpcResult(ykcDataProtocol.getBytes());
|
||||||
// 唤醒外部线程
|
// 唤醒外部线程
|
||||||
log.info("同步获取响应数据-唤醒外部线程, SyncPromise:{}", JSON.toJSONString(syncPromise));
|
log.info("同步获取响应数据-唤醒外部线程, SyncPromise:{}", JSON.toJSONString(syncPromise));
|
||||||
syncPromise.wake();
|
syncPromise.wake();
|
||||||
} else {
|
|
||||||
log.warn("同步获取响应数据-未找到等待线程, msgId:{}, responseFrameType:{}, requestFrameType:{}, 原始报文:{}",
|
|
||||||
msgId, responseFrameType, requestFrameType, rawMessage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yuxinResponse) {
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果收到成功, 从redis取值, 保存到数据库
|
// 如果收到成功, 从redis取值, 保存到数据库
|
||||||
@@ -168,13 +147,4 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
|||||||
}
|
}
|
||||||
return failedReason;
|
return failedReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getYuxinSetupResultMsg(String resultCode) {
|
|
||||||
if (StringUtils.equals(resultCode, "00")) {
|
|
||||||
return "失败";
|
|
||||||
} else if (StringUtils.equals(resultCode, "01")) {
|
|
||||||
return "成功";
|
|
||||||
}
|
|
||||||
return resultCode;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ public class ThirdpartyParkingConfig {
|
|||||||
*/
|
*/
|
||||||
private String parkingName;
|
private String parkingName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停车平台类型(1-路通云停;2-软杰;3-qcyun)
|
||||||
|
*/
|
||||||
|
private String platformType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 停车场库appId
|
* 停车场库appId
|
||||||
*/
|
*/
|
||||||
@@ -46,6 +51,21 @@ public class ThirdpartyParkingConfig {
|
|||||||
*/
|
*/
|
||||||
private String couponId;
|
private String couponId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcyun机构ID
|
||||||
|
*/
|
||||||
|
private String orgId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* qcyun车场ID
|
||||||
|
*/
|
||||||
|
private String parkId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 平台接口地址
|
||||||
|
*/
|
||||||
|
private String apiUrl;
|
||||||
|
|
||||||
private Date createTime;
|
private Date createTime;
|
||||||
|
|
||||||
private String createBy;
|
private String createBy;
|
||||||
|
|||||||
@@ -23,11 +23,6 @@ public class YuxinReservationChargingDTO {
|
|||||||
*/
|
*/
|
||||||
private String reservedId;
|
private String reservedId;
|
||||||
|
|
||||||
/**
|
|
||||||
* 状态 (0-停用;1-启用)
|
|
||||||
*/
|
|
||||||
private String status;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 充电桩编号
|
* 充电桩编号
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -61,4 +61,12 @@ public interface ThirdpartyParkingConfigMapper {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
List<ThirdpartyParkingConfig> selectInfoList();
|
List<ThirdpartyParkingConfig> selectInfoList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据站点查询绑定的停车平台配置
|
||||||
|
*
|
||||||
|
* @param stationId 站点id
|
||||||
|
* @return 停车平台配置
|
||||||
|
*/
|
||||||
|
ThirdpartyParkingConfig selectByStationId(String stationId);
|
||||||
}
|
}
|
||||||
@@ -22,6 +22,7 @@ import com.jsowell.pile.domain.ykcCommond.*;
|
|||||||
import com.jsowell.pile.dto.PublishBillingTemplateDTO;
|
import com.jsowell.pile.dto.PublishBillingTemplateDTO;
|
||||||
import com.jsowell.pile.dto.RemoteAccountBalanceUpdateDTO;
|
import com.jsowell.pile.dto.RemoteAccountBalanceUpdateDTO;
|
||||||
import com.jsowell.pile.dto.UpdateFirmwareDTO;
|
import com.jsowell.pile.dto.UpdateFirmwareDTO;
|
||||||
|
import com.jsowell.pile.vo.base.ConnectorInfoVO;
|
||||||
import com.jsowell.pile.vo.web.BillingTemplateVO;
|
import com.jsowell.pile.vo.web.BillingTemplateVO;
|
||||||
import com.jsowell.pile.vo.web.PileDetailVO;
|
import com.jsowell.pile.vo.web.PileDetailVO;
|
||||||
import com.jsowell.wxpay.service.WxAppletRemoteService;
|
import com.jsowell.wxpay.service.WxAppletRemoteService;
|
||||||
@@ -519,86 +520,11 @@ public class PileRemoteService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 羽信预约充电指令
|
* 羽信预约充电指令
|
||||||
*
|
|
||||||
* @return result: 1-成功; 0-失败
|
* @return result: 1-成功; 0-失败
|
||||||
*/
|
*/
|
||||||
public String yuxinReservationCharging(YuxinReservationChargingCommand command) {
|
public String yuxinReservationCharging(YuxinReservationChargingCommand command) {
|
||||||
byte[] bytes = ykcPushCommandService.pushYuxinReservationChargingCommand(command);
|
byte[] bytes = ykcPushCommandService.pushYuxinReservationChargingCommand(command);
|
||||||
return parseYuxinReservationChargingResponse(bytes);
|
return parseReservationChargingResponse(bytes);
|
||||||
}
|
|
||||||
|
|
||||||
private String parseYuxinReservationChargingResponse(byte[] bytes) {
|
|
||||||
String result = "0";
|
|
||||||
if (Objects.isNull(bytes)) {
|
|
||||||
log.warn("羽信预约启动充电回复为空, 原始报文:null");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
String rawMessage = BytesUtil.bin2HexStr(bytes);
|
|
||||||
try {
|
|
||||||
YKCDataProtocol ykcDataProtocol = new YKCDataProtocol(bytes);
|
|
||||||
String responseFrameType = YKCUtils.frameType2Str(ykcDataProtocol.getFrameType());
|
|
||||||
byte[] msgBody = ykcDataProtocol.getMsgBody();
|
|
||||||
if (!StringUtils.equals(responseFrameType,
|
|
||||||
YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_ANSWER_CODE.getBytes()))) {
|
|
||||||
log.warn("羽信预约启动充电回复帧类型异常, 帧类型:{}, 原始报文:{}", responseFrameType, rawMessage);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if (Objects.isNull(msgBody) || msgBody.length < 27) {
|
|
||||||
log.warn("羽信预约启动充电回复长度异常, 帧类型:{}, 报文体长度:{}, 原始报文:{}",
|
|
||||||
responseFrameType, Objects.isNull(msgBody) ? null : msgBody.length, rawMessage);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int startIndex = 0;
|
|
||||||
int length = 16;
|
|
||||||
byte[] transactionCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
|
||||||
String transactionCode = BytesUtil.bcd2Str(transactionCodeByteArr);
|
|
||||||
|
|
||||||
startIndex += length;
|
|
||||||
length = 7;
|
|
||||||
byte[] pileSnByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
|
||||||
String pileSn = BytesUtil.bcd2Str(pileSnByteArr);
|
|
||||||
|
|
||||||
startIndex += length;
|
|
||||||
length = 1;
|
|
||||||
byte[] connectorCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
|
||||||
String connectorCode = parseYuxinConnectorCode(connectorCodeByteArr);
|
|
||||||
|
|
||||||
startIndex += length;
|
|
||||||
length = 1;
|
|
||||||
byte[] reservationTypeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
|
||||||
String reservationType = BytesUtil.bin2HexStr(reservationTypeByteArr);
|
|
||||||
|
|
||||||
startIndex += length;
|
|
||||||
length = 1;
|
|
||||||
byte[] resultCodeByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
|
||||||
String resultCode = BytesUtil.bin2HexStr(resultCodeByteArr);
|
|
||||||
|
|
||||||
startIndex += length;
|
|
||||||
length = 1;
|
|
||||||
byte[] failedReasonByteArr = BytesUtil.copyBytes(msgBody, startIndex, length);
|
|
||||||
String failedReason = BytesUtil.bin2HexStr(failedReasonByteArr);
|
|
||||||
String failedReasonMsg = getYuxinFailedReasonMsg(failedReason);
|
|
||||||
|
|
||||||
if (StringUtils.equals(resultCode, "01")) {
|
|
||||||
result = "1";
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("{}羽信预约启动充电回复sync, 交易流水号:{}, 桩SN:{}, 枪口号:{}({}), 预约方式:{}({}), 设置结果:{}({}), 失败原因:{}({}), 原始报文:{}",
|
|
||||||
responseFrameType, transactionCode, pileSn, connectorCode, getYuxinConnectorCodeMsg(connectorCode),
|
|
||||||
reservationType, getYuxinReservationTypeMsg(reservationType),
|
|
||||||
resultCode, getYuxinSetupResultMsg(resultCode), failedReason, failedReasonMsg, rawMessage);
|
|
||||||
if (!StringUtils.equals(resultCode, "01")) {
|
|
||||||
log.warn("羽信预约启动充电设置失败, 交易流水号:{}, 桩SN:{}, 枪口号:{}({}), 失败原因:{}({}), 原始报文:{}",
|
|
||||||
transactionCode, pileSn, connectorCode, getYuxinConnectorCodeMsg(connectorCode),
|
|
||||||
failedReason, failedReasonMsg, rawMessage);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.warn("羽信预约启动充电回复解析异常, 原始报文:{}", rawMessage, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String parseReservationChargingResponse(byte[] bytes) {
|
private String parseReservationChargingResponse(byte[] bytes) {
|
||||||
@@ -675,31 +601,6 @@ public class PileRemoteService {
|
|||||||
return String.format("%02d", connectorCodeByteArr[0] & 0xFF);
|
return String.format("%02d", connectorCodeByteArr[0] & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getYuxinConnectorCodeMsg(String connectorCode) {
|
|
||||||
if (StringUtils.equals(connectorCode, "00")) {
|
|
||||||
return "所有枪";
|
|
||||||
}
|
|
||||||
return Integer.parseInt(connectorCode) + "号枪";
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getYuxinReservationTypeMsg(String reservationType) {
|
|
||||||
if (StringUtils.equals(reservationType, "00")) {
|
|
||||||
return "立即预约";
|
|
||||||
} else if (StringUtils.equals(reservationType, "01")) {
|
|
||||||
return "取消预约";
|
|
||||||
}
|
|
||||||
return reservationType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getYuxinSetupResultMsg(String resultCode) {
|
|
||||||
if (StringUtils.equals(resultCode, "00")) {
|
|
||||||
return "失败";
|
|
||||||
} else if (StringUtils.equals(resultCode, "01")) {
|
|
||||||
return "成功";
|
|
||||||
}
|
|
||||||
return resultCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String getYuxinFailedReasonMsg(String failedReason) {
|
private String getYuxinFailedReasonMsg(String failedReason) {
|
||||||
if (StringUtils.equals(failedReason, "00")) {
|
if (StringUtils.equals(failedReason, "00")) {
|
||||||
return "无";
|
return "无";
|
||||||
|
|||||||
@@ -57,4 +57,12 @@ public interface ThirdPartyParkingConfigService {
|
|||||||
* 查询基本信息列表(调用时需分页)
|
* 查询基本信息列表(调用时需分页)
|
||||||
*/
|
*/
|
||||||
List<ThirdpartyParkingConfig> selectInfoList();
|
List<ThirdpartyParkingConfig> selectInfoList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据站点查询绑定的停车平台配置
|
||||||
|
*
|
||||||
|
* @param stationId 站点id
|
||||||
|
* @return 停车平台配置
|
||||||
|
*/
|
||||||
|
ThirdpartyParkingConfig selectByStationId(String stationId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,17 @@
|
|||||||
package com.jsowell.pile.service;
|
package com.jsowell.pile.service;
|
||||||
|
|
||||||
import com.jsowell.pile.dto.YuxinReservationChargingDTO;
|
import com.jsowell.pile.dto.YuxinReservationChargingDTO;
|
||||||
|
import com.jsowell.pile.vo.PileReservationInfoVO;
|
||||||
|
|
||||||
public interface YuxinReservationChargingService {
|
public interface YuxinReservationChargingService {
|
||||||
|
|
||||||
void createReservation(YuxinReservationChargingDTO dto);
|
int createReservation(YuxinReservationChargingDTO dto);
|
||||||
|
|
||||||
|
int updateReservation(YuxinReservationChargingDTO dto);
|
||||||
|
|
||||||
|
void cancelReservation(YuxinReservationChargingDTO dto);
|
||||||
|
|
||||||
|
void deleteReservation(YuxinReservationChargingDTO dto);
|
||||||
|
|
||||||
|
PileReservationInfoVO queryReservationInfo(YuxinReservationChargingDTO dto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,4 +59,9 @@ public class ThirdPartyParkingConfigServiceImpl implements ThirdPartyParkingConf
|
|||||||
return thirdpartyParkingConfigMapper.selectInfoList();
|
return thirdpartyParkingConfigMapper.selectInfoList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThirdpartyParkingConfig selectByStationId(String stationId) {
|
||||||
|
return thirdpartyParkingConfigMapper.selectByStationId(stationId);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,6 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
|
|||||||
private static final BigDecimal DEFAULT_YUXIN_CHARGING_PARAM = BigDecimal.ZERO;
|
private static final BigDecimal DEFAULT_YUXIN_CHARGING_PARAM = BigDecimal.ZERO;
|
||||||
private static final int DEFAULT_YUXIN_CHARGING_STRATEGY = 0;
|
private static final int DEFAULT_YUXIN_CHARGING_STRATEGY = 0;
|
||||||
private static final int DEFAULT_YUXIN_RESERVATION_TIMEOUT = 0;
|
private static final int DEFAULT_YUXIN_RESERVATION_TIMEOUT = 0;
|
||||||
private static final int YUXIN_RESERVATION_RESPONSE_TIMEOUT_SECONDS = 5;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PileBillingTemplateService pileBillingTemplateService;
|
private PileBillingTemplateService pileBillingTemplateService;
|
||||||
@@ -787,17 +786,13 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
|
|||||||
public byte[] pushYuxinReservationChargingCommand(YuxinReservationChargingCommand command) {
|
public byte[] pushYuxinReservationChargingCommand(YuxinReservationChargingCommand command) {
|
||||||
String pileSn = command.getPileSn();
|
String pileSn = command.getPileSn();
|
||||||
byte[] msg = buildYuxinReservationChargingMsg(command);
|
byte[] msg = buildYuxinReservationChargingMsg(command);
|
||||||
log.info("羽信预约充电下发原始报文, pileSn:{}, rawMessage:{}", pileSn, BytesUtil.bin2HexStr(msg));
|
|
||||||
byte[] response;
|
byte[] response;
|
||||||
try {
|
try {
|
||||||
response = this.supplySend(msg, pileSn, YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE,
|
response = this.supplySend(msg, pileSn, YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE);
|
||||||
YUXIN_RESERVATION_RESPONSE_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("发送羽信预约充电消息异常", e);
|
log.error("发送羽信预约充电消息异常", e);
|
||||||
response = null;
|
response = null;
|
||||||
}
|
}
|
||||||
log.info("羽信预约充电回复原始报文, pileSn:{}, rawMessage:{}",
|
|
||||||
pileSn, response == null ? "null" : BytesUtil.bin2HexStr(response));
|
|
||||||
|
|
||||||
log.info("【=====平台下发指令=====】: 羽信预约充电指令, 帧类型:{}, 交易流水号:{}, 桩编号:{}, 枪口号:{}, 账户余额:{}, 预约类型(00-立即预约;01-取消预约):{}, 充电策略:{}, 充电参数:{}, 系统时间:{}, 预约启动时间:{}, 预约超时时间:{}",
|
log.info("【=====平台下发指令=====】: 羽信预约充电指令, 帧类型:{}, 交易流水号:{}, 桩编号:{}, 枪口号:{}, 账户余额:{}, 预约类型(00-立即预约;01-取消预约):{}, 充电策略:{}, 充电参数:{}, 系统时间:{}, 预约启动时间:{}, 预约超时时间:{}",
|
||||||
YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE.getBytes()),
|
YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE.getBytes()),
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.jsowell.pile.service.impl;
|
package com.jsowell.pile.service.impl;
|
||||||
|
|
||||||
import com.jsowell.common.constant.Constants;
|
import com.jsowell.common.constant.Constants;
|
||||||
|
import com.jsowell.common.enums.DelFlagEnum;
|
||||||
import com.jsowell.common.enums.ykc.PileMainboardManufacturerEnum;
|
import com.jsowell.common.enums.ykc.PileMainboardManufacturerEnum;
|
||||||
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
|
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
|
||||||
import com.jsowell.common.exception.BusinessException;
|
import com.jsowell.common.exception.BusinessException;
|
||||||
@@ -9,31 +10,41 @@ import com.jsowell.common.util.PileProgramVersionUtils;
|
|||||||
import com.jsowell.common.util.StringUtils;
|
import com.jsowell.common.util.StringUtils;
|
||||||
import com.jsowell.common.util.YKCUtils;
|
import com.jsowell.common.util.YKCUtils;
|
||||||
import com.jsowell.pile.domain.PileBasicInfo;
|
import com.jsowell.pile.domain.PileBasicInfo;
|
||||||
|
import com.jsowell.pile.domain.PileReservationInfo;
|
||||||
import com.jsowell.pile.domain.ykcCommond.YuxinReservationChargingCommand;
|
import com.jsowell.pile.domain.ykcCommond.YuxinReservationChargingCommand;
|
||||||
import com.jsowell.pile.dto.YuxinReservationChargingDTO;
|
import com.jsowell.pile.dto.YuxinReservationChargingDTO;
|
||||||
|
import com.jsowell.pile.mapper.PileReservationInfoMapper;
|
||||||
import com.jsowell.pile.service.PileBasicInfoService;
|
import com.jsowell.pile.service.PileBasicInfoService;
|
||||||
import com.jsowell.pile.service.PileRemoteService;
|
import com.jsowell.pile.service.PileRemoteService;
|
||||||
import com.jsowell.pile.service.YuxinReservationChargingService;
|
import com.jsowell.pile.service.YuxinReservationChargingService;
|
||||||
|
import com.jsowell.pile.vo.PileReservationInfoVO;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
|
||||||
import java.sql.Time;
|
import java.sql.Time;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.LocalTime;
|
import java.time.LocalTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
public class YuxinReservationChargingServiceImpl implements YuxinReservationChargingService {
|
public class YuxinReservationChargingServiceImpl implements YuxinReservationChargingService {
|
||||||
|
|
||||||
private static final String YUXIN_RESERVATION_TYPE_CREATE = "00";
|
private static final String YUXIN_RESERVATION_TYPE_CREATE = "00";
|
||||||
|
private static final String YUXIN_RESERVATION_TYPE_CANCEL = "01";
|
||||||
private static final BigDecimal YUXIN_ACCOUNT_BALANCE = new BigDecimal("999.99");
|
private static final BigDecimal YUXIN_ACCOUNT_BALANCE = new BigDecimal("999.99");
|
||||||
private static final int TIME_CONTROL_CHARGING_STRATEGY = 1;
|
private static final BigDecimal DEFAULT_CHARGING_PARAM = BigDecimal.ZERO;
|
||||||
private static final int DEFAULT_RESERVATION_TIMEOUT_MINUTES = 0xFF;
|
private static final int DEFAULT_CHARGING_STRATEGY = 0;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PileReservationInfoMapper pileReservationInfoMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PileRemoteService pileRemoteService;
|
private PileRemoteService pileRemoteService;
|
||||||
@@ -42,47 +53,198 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
|||||||
private PileBasicInfoService pileBasicInfoService;
|
private PileBasicInfoService pileBasicInfoService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createReservation(YuxinReservationChargingDTO dto) {
|
public int createReservation(YuxinReservationChargingDTO dto) {
|
||||||
validateCreateOrUpdateParam(dto);
|
validateCreateOrUpdateParam(dto);
|
||||||
normalizePileInfo(dto);
|
normalizePileInfo(dto);
|
||||||
assertYuxinMainboard(dto.getPileSn());
|
assertYuxinMainboard(dto.getPileSn());
|
||||||
|
|
||||||
sendYuxinReservationCommandAndAssertSuccess(dto, YUXIN_RESERVATION_TYPE_CREATE);
|
PileReservationInfo currentReservation = pileReservationInfoMapper.selectByPileConnectorCode(dto.getPileConnectorCode());
|
||||||
|
PileReservationInfo oldReservation = currentReservation == null ? null : copyReservationInfo(currentReservation);
|
||||||
|
boolean oldActive = oldReservation != null && StringUtils.equals(oldReservation.getStatus(), Constants.ONE);
|
||||||
|
|
||||||
|
PileReservationInfo reservationInfo = currentReservation == null ? new PileReservationInfo() : currentReservation;
|
||||||
|
fillReservationInfo(reservationInfo, dto);
|
||||||
|
if (currentReservation == null) {
|
||||||
|
reservationInfo.setCreateBy(dto.getMemberId());
|
||||||
|
} else {
|
||||||
|
reservationInfo.setUpdateBy(dto.getMemberId());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isTimeSlotAvailable(dto.getMemberId(), dto.getPileSn(), reservationInfo.getStartTime(),
|
||||||
|
reservationInfo.getEndTime(), reservationInfo.getId())) {
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_REFUSED);
|
||||||
|
}
|
||||||
|
if (oldActive) {
|
||||||
|
cancelOldReservationBeforeCreate(dto, oldReservation);
|
||||||
|
}
|
||||||
|
sendYuxinReservationCommandAndAssertSuccess(dto, reservationInfo, YUXIN_RESERVATION_TYPE_CREATE);
|
||||||
|
pileReservationInfoMapper.insertOrUpdateSelective(reservationInfo);
|
||||||
|
return reservationInfo.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int updateReservation(YuxinReservationChargingDTO dto) {
|
||||||
|
if (StringUtils.isBlank(dto.getReservedId())) {
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||||
|
}
|
||||||
|
PileReservationInfo reservationInfo = pileReservationInfoMapper.selectByPrimaryKey(Integer.valueOf(dto.getReservedId()));
|
||||||
|
if (reservationInfo == null) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
dto.setPileSn(StringUtils.defaultIfBlank(dto.getPileSn(), reservationInfo.getPileSn()));
|
||||||
|
dto.setPileConnectorCode(StringUtils.defaultIfBlank(dto.getPileConnectorCode(), reservationInfo.getPileConnectorCode()));
|
||||||
|
dto.setStartTime(StringUtils.defaultIfBlank(dto.getStartTime(), reservationInfo.getStartTime().toString()));
|
||||||
|
dto.setEndTime(StringUtils.defaultIfBlank(dto.getEndTime(), reservationInfo.getEndTime().toString()));
|
||||||
|
assertYuxinMainboard(dto.getPileSn());
|
||||||
|
|
||||||
|
PileReservationInfo oldReservation = copyReservationInfo(reservationInfo);
|
||||||
|
fillReservationInfo(reservationInfo, dto);
|
||||||
|
reservationInfo.setUpdateBy(dto.getMemberId());
|
||||||
|
|
||||||
|
if (!isTimeSlotAvailable(dto.getMemberId(), dto.getPileSn(), reservationInfo.getStartTime(),
|
||||||
|
reservationInfo.getEndTime(), reservationInfo.getId())) {
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_REFUSED);
|
||||||
|
}
|
||||||
|
if (StringUtils.equals(oldReservation.getStatus(), Constants.ONE)) {
|
||||||
|
cancelOldReservationBeforeCreate(dto, oldReservation);
|
||||||
|
}
|
||||||
|
sendYuxinReservationCommandAndAssertSuccess(dto, reservationInfo, YUXIN_RESERVATION_TYPE_CREATE);
|
||||||
|
return pileReservationInfoMapper.insertOrUpdateSelective(reservationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void cancelReservation(YuxinReservationChargingDTO dto) {
|
||||||
|
if (StringUtils.isBlank(dto.getReservedId())) {
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||||
|
}
|
||||||
|
PileReservationInfo reservationInfo = pileReservationInfoMapper.selectByPrimaryKey(Integer.valueOf(dto.getReservedId()));
|
||||||
|
if (reservationInfo == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assertYuxinMainboard(reservationInfo.getPileSn());
|
||||||
|
boolean cancelSuccess = true;
|
||||||
|
if (StringUtils.equals(reservationInfo.getStatus(), Constants.ONE)) {
|
||||||
|
cancelSuccess = sendYuxinReservationCommand(dto, reservationInfo, YUXIN_RESERVATION_TYPE_CANCEL);
|
||||||
|
}
|
||||||
|
if (!cancelSuccess && !isReservationTimeEnded(reservationInfo)) {
|
||||||
|
throwReservationCommandFailed();
|
||||||
|
}
|
||||||
|
if (!cancelSuccess) {
|
||||||
|
log.warn("羽信取消预约失败, 但预约时间窗已过期, 本地停用预约, memberId:{}, reservation:{}",
|
||||||
|
dto.getMemberId(), reservationLogText(reservationInfo));
|
||||||
|
}
|
||||||
|
reservationInfo.setStatus(Constants.ZERO);
|
||||||
|
reservationInfo.setUpdateBy(dto.getMemberId());
|
||||||
|
pileReservationInfoMapper.updateByPrimaryKeySelective(reservationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteReservation(YuxinReservationChargingDTO dto) {
|
||||||
|
if (StringUtils.isBlank(dto.getReservedId())) {
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||||
|
}
|
||||||
|
PileReservationInfo reservationInfo = pileReservationInfoMapper.selectByPrimaryKey(Integer.valueOf(dto.getReservedId()));
|
||||||
|
if (Objects.isNull(reservationInfo)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
assertYuxinMainboard(reservationInfo.getPileSn());
|
||||||
|
boolean cancelSuccess = true;
|
||||||
|
if (StringUtils.equals(reservationInfo.getStatus(), Constants.ONE)) {
|
||||||
|
cancelSuccess = sendYuxinReservationCommand(dto, reservationInfo, YUXIN_RESERVATION_TYPE_CANCEL);
|
||||||
|
}
|
||||||
|
if (!cancelSuccess && !isReservationTimeEnded(reservationInfo)) {
|
||||||
|
throwReservationCommandFailed();
|
||||||
|
}
|
||||||
|
reservationInfo.setStatus(Constants.ZERO);
|
||||||
|
reservationInfo.setDelFlag(DelFlagEnum.DELETE.getValue());
|
||||||
|
reservationInfo.setUpdateBy(dto.getMemberId());
|
||||||
|
pileReservationInfoMapper.updateByPrimaryKey(reservationInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PileReservationInfoVO queryReservationInfo(YuxinReservationChargingDTO dto) {
|
||||||
|
if (StringUtils.isBlank(dto.getPileConnectorCode())) {
|
||||||
|
throw new BusinessException(ReturnCodeEnum.CODE_PARAM_NOT_NULL_ERROR);
|
||||||
|
}
|
||||||
|
PileReservationInfo reservationInfo = pileReservationInfoMapper.selectByPileConnectorCode(dto.getPileConnectorCode());
|
||||||
|
if (reservationInfo == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return PileReservationInfoVO.builder()
|
||||||
|
.reservedId(reservationInfo.getId() + "")
|
||||||
|
.pileSn(reservationInfo.getPileSn())
|
||||||
|
.pileConnectorCode(reservationInfo.getPileConnectorCode())
|
||||||
|
.startTime(reservationInfo.getStartTime().toString())
|
||||||
|
.endTime(reservationInfo.getEndTime().toString())
|
||||||
|
.verifyIdentity(reservationInfo.getVerifyIdentity())
|
||||||
|
.status(reservationInfo.getStatus())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fillReservationInfo(PileReservationInfo reservationInfo, YuxinReservationChargingDTO dto) {
|
||||||
|
reservationInfo.setMemberId(dto.getMemberId());
|
||||||
|
reservationInfo.setPileSn(dto.getPileSn());
|
||||||
|
reservationInfo.setPileConnectorCode(dto.getPileConnectorCode());
|
||||||
|
reservationInfo.setStatus(Constants.ONE);
|
||||||
|
reservationInfo.setDelFlag(DelFlagEnum.NORMAL.getValue());
|
||||||
|
reservationInfo.setReservationType("recurring");
|
||||||
|
reservationInfo.setFreq("daily");
|
||||||
|
reservationInfo.setVerifyIdentity(Constants.ZERO);
|
||||||
|
reservationInfo.setStartTime(parseSqlTime(dto.getStartTime()));
|
||||||
|
reservationInfo.setEndTime(parseSqlTime(dto.getEndTime()));
|
||||||
|
if (reservationInfo.getId() == null) {
|
||||||
|
reservationInfo.setCreateTime(DateUtils.getNowDate());
|
||||||
|
} else {
|
||||||
|
reservationInfo.setUpdateTime(DateUtils.getNowDate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelOldReservationBeforeCreate(YuxinReservationChargingDTO dto, PileReservationInfo oldReservation) {
|
||||||
|
boolean cancelSuccess = sendYuxinReservationCommand(dto, oldReservation, YUXIN_RESERVATION_TYPE_CANCEL);
|
||||||
|
if (!cancelSuccess && !isReservationTimeEnded(oldReservation)) {
|
||||||
|
throwReservationCommandFailed();
|
||||||
|
}
|
||||||
|
if (!cancelSuccess) {
|
||||||
|
log.warn("羽信预约新时间前取消旧预约失败, 但旧预约时间窗已过期, 继续预约新时间, memberId:{}, oldReservation:{}",
|
||||||
|
dto.getMemberId(), reservationLogText(oldReservation));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendYuxinReservationCommandAndAssertSuccess(YuxinReservationChargingDTO dto,
|
private void sendYuxinReservationCommandAndAssertSuccess(YuxinReservationChargingDTO dto,
|
||||||
|
PileReservationInfo reservationInfo,
|
||||||
String yuxinReservationType) {
|
String yuxinReservationType) {
|
||||||
if (!sendYuxinReservationCommand(dto, yuxinReservationType)) {
|
if (!sendYuxinReservationCommand(dto, reservationInfo, yuxinReservationType)) {
|
||||||
throwReservationCommandFailed();
|
throwReservationCommandFailed();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean sendYuxinReservationCommand(YuxinReservationChargingDTO dto,
|
private boolean sendYuxinReservationCommand(YuxinReservationChargingDTO dto,
|
||||||
|
PileReservationInfo reservationInfo,
|
||||||
String yuxinReservationType) {
|
String yuxinReservationType) {
|
||||||
YuxinReservationChargingCommand command = buildYuxinReservationChargingCommand(dto, yuxinReservationType);
|
YuxinReservationChargingCommand command = buildYuxinReservationChargingCommand(dto, reservationInfo, yuxinReservationType);
|
||||||
log.info("羽信预约充电指令下发, memberId:{}, reservationType:{}, command:{}",
|
log.info("羽信预约充电指令下发, memberId:{}, reservedId:{}, reservationType:{}, reservation:{}",
|
||||||
dto.getMemberId(), yuxinReservationType, reservationLogText(dto, command));
|
dto.getMemberId(), reservationInfo.getId(), yuxinReservationType, reservationLogText(reservationInfo));
|
||||||
String result = pileRemoteService.yuxinReservationCharging(command);
|
String result = pileRemoteService.yuxinReservationCharging(command);
|
||||||
boolean success = StringUtils.equals(result, Constants.ONE);
|
boolean success = StringUtils.equals(result, Constants.ONE);
|
||||||
log.info("羽信预约充电指令返回, memberId:{}, reservationType:{}, result:{}, success:{}",
|
log.info("羽信预约充电指令返回, memberId:{}, reservedId:{}, reservationType:{}, result:{}, success:{}",
|
||||||
dto.getMemberId(), yuxinReservationType, result, success);
|
dto.getMemberId(), reservationInfo.getId(), yuxinReservationType, result, success);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
private YuxinReservationChargingCommand buildYuxinReservationChargingCommand(YuxinReservationChargingDTO dto,
|
private YuxinReservationChargingCommand buildYuxinReservationChargingCommand(YuxinReservationChargingDTO dto,
|
||||||
|
PileReservationInfo reservationInfo,
|
||||||
String yuxinReservationType) {
|
String yuxinReservationType) {
|
||||||
LocalTime startTime = parseSqlTime(dto.getStartTime()).toLocalTime();
|
|
||||||
return YuxinReservationChargingCommand.builder()
|
return YuxinReservationChargingCommand.builder()
|
||||||
.transactionCode(Constants.ILLEGAL_TRANSACTION_CODE)
|
.transactionCode(Constants.ILLEGAL_TRANSACTION_CODE)
|
||||||
.pileSn(dto.getPileSn())
|
.pileSn(reservationInfo.getPileSn())
|
||||||
.connectorCode(getConnectorCode(dto))
|
.connectorCode(getConnectorCode(reservationInfo))
|
||||||
.accountBalance(YUXIN_ACCOUNT_BALANCE)
|
.accountBalance(YUXIN_ACCOUNT_BALANCE)
|
||||||
.reservationType(yuxinReservationType)
|
.reservationType(yuxinReservationType)
|
||||||
.chargingStrategy(TIME_CONTROL_CHARGING_STRATEGY)
|
.chargingStrategy(dto.getChargingStrategy() == null ? DEFAULT_CHARGING_STRATEGY : dto.getChargingStrategy())
|
||||||
.chargingParam(getChargingHours(dto))
|
.chargingParam(dto.getChargingParam() == null ? DEFAULT_CHARGING_PARAM : dto.getChargingParam())
|
||||||
.systemTime(new Date())
|
.systemTime(new Date())
|
||||||
.reservedStartTime(getReservedStartDate(startTime, yuxinReservationType))
|
.reservedStartTime(getReservedStartDate(reservationInfo.getStartTime().toLocalTime(), yuxinReservationType))
|
||||||
.reservationTimeout(getReservationTimeout(dto))
|
.reservationTimeout(getReservationTimeout(dto, reservationInfo, yuxinReservationType))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,26 +258,26 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
|||||||
return DateUtils.localDateTime2Date(reservedStartDateTime);
|
return DateUtils.localDateTime2Date(reservedStartDateTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getReservationTimeout(YuxinReservationChargingDTO dto) {
|
private int getReservationTimeout(YuxinReservationChargingDTO dto,
|
||||||
|
PileReservationInfo reservationInfo,
|
||||||
|
String yuxinReservationType) {
|
||||||
|
if (StringUtils.equals(yuxinReservationType, YUXIN_RESERVATION_TYPE_CANCEL)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
if (dto.getReservationTimeout() != null) {
|
if (dto.getReservationTimeout() != null) {
|
||||||
return Math.min(Math.max(dto.getReservationTimeout(), 0), 0xFF);
|
return Math.min(Math.max(dto.getReservationTimeout(), 0), 0xFF);
|
||||||
}
|
}
|
||||||
return DEFAULT_RESERVATION_TIMEOUT_MINUTES;
|
LocalTime startTime = reservationInfo.getStartTime().toLocalTime();
|
||||||
}
|
LocalTime endTime = reservationInfo.getEndTime().toLocalTime();
|
||||||
|
|
||||||
private BigDecimal getChargingHours(YuxinReservationChargingDTO dto) {
|
|
||||||
LocalTime startTime = parseSqlTime(dto.getStartTime()).toLocalTime();
|
|
||||||
LocalTime endTime = parseSqlTime(dto.getEndTime()).toLocalTime();
|
|
||||||
long timeout = Duration.between(startTime, endTime).toMinutes();
|
long timeout = Duration.between(startTime, endTime).toMinutes();
|
||||||
if (timeout <= 0) {
|
if (timeout <= 0) {
|
||||||
timeout += Duration.ofDays(1).toMinutes();
|
timeout += TimeUnit.DAYS.toMinutes(1);
|
||||||
}
|
}
|
||||||
return BigDecimal.valueOf(timeout)
|
return (int) Math.min(timeout, 0xFF);
|
||||||
.divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getConnectorCode(YuxinReservationChargingDTO dto) {
|
private String getConnectorCode(PileReservationInfo reservationInfo) {
|
||||||
return dto.getPileConnectorCode().replace(dto.getPileSn(), "");
|
return reservationInfo.getPileConnectorCode().replace(reservationInfo.getPileSn(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void normalizePileInfo(YuxinReservationChargingDTO dto) {
|
private void normalizePileInfo(YuxinReservationChargingDTO dto) {
|
||||||
@@ -143,6 +305,39 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
|||||||
return Time.valueOf(time);
|
return Time.valueOf(time);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isTimeSlotAvailable(String memberId, String pileSn, Time startTime, Time endTime, Integer reservationId) {
|
||||||
|
List<PileReservationInfo> reservations = pileReservationInfoMapper.findByMemberIdAndPileSnAndStatus(memberId, pileSn, Constants.ONE);
|
||||||
|
LocalTime newStartTime = startTime.toLocalTime();
|
||||||
|
LocalTime newEndTime = endTime.toLocalTime();
|
||||||
|
for (PileReservationInfo res : reservations) {
|
||||||
|
if (reservationId != null && res.getId().equals(reservationId)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
LocalTime existingStartTime = res.getStartTime().toLocalTime();
|
||||||
|
LocalTime existingEndTime = res.getEndTime().toLocalTime();
|
||||||
|
if (newStartTime.isBefore(existingEndTime) && newEndTime.isAfter(existingStartTime)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isReservationTimeEnded(PileReservationInfo reservationInfo) {
|
||||||
|
if (reservationInfo == null || reservationInfo.getStartTime() == null || reservationInfo.getEndTime() == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
LocalTime now = LocalTime.now();
|
||||||
|
LocalTime startTime = reservationInfo.getStartTime().toLocalTime();
|
||||||
|
LocalTime endTime = reservationInfo.getEndTime().toLocalTime();
|
||||||
|
boolean crossDay = endTime.isBefore(startTime);
|
||||||
|
boolean ended = crossDay
|
||||||
|
? !now.isBefore(endTime) && now.isBefore(startTime)
|
||||||
|
: !endTime.isAfter(now);
|
||||||
|
log.info("羽信预约过期判断, reservedId:{}, pileConnectorCode:{}, now:{}, startTime:{}, endTime:{}, crossDay:{}, ended:{}",
|
||||||
|
reservationInfo.getId(), reservationInfo.getPileConnectorCode(), now, startTime, endTime, crossDay, ended);
|
||||||
|
return ended;
|
||||||
|
}
|
||||||
|
|
||||||
private void assertYuxinMainboard(String pileSn) {
|
private void assertYuxinMainboard(String pileSn) {
|
||||||
PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn);
|
PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn);
|
||||||
String programVersion = pileBasicInfo == null ? null : pileBasicInfo.getProgramVersion();
|
String programVersion = pileBasicInfo == null ? null : pileBasicInfo.getProgramVersion();
|
||||||
@@ -157,10 +352,33 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
|||||||
ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR.getLabel() + ": 充电桩返回修改失败");
|
ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR.getLabel() + ": 充电桩返回修改失败");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String reservationLogText(YuxinReservationChargingDTO dto, YuxinReservationChargingCommand command) {
|
private String reservationLogText(PileReservationInfo reservationInfo) {
|
||||||
return String.format("pileSn=%s,pileConnectorCode=%s,startTime=%s,endTime=%s,chargingStrategy=%s,chargingParam=%s,reservationTimeout=%s",
|
if (reservationInfo == null) {
|
||||||
dto.getPileSn(), dto.getPileConnectorCode(), dto.getStartTime(), dto.getEndTime(),
|
return "null";
|
||||||
command.getChargingStrategy(), command.getChargingParam(), command.getReservationTimeout());
|
}
|
||||||
|
return String.format("reservedId=%s,pileSn=%s,pileConnectorCode=%s,status=%s,reservationType=%s,verifyIdentity=%s,startTime=%s,endTime=%s",
|
||||||
|
reservationInfo.getId(), reservationInfo.getPileSn(), reservationInfo.getPileConnectorCode(),
|
||||||
|
reservationInfo.getStatus(), reservationInfo.getReservationType(), reservationInfo.getVerifyIdentity(),
|
||||||
|
reservationInfo.getStartTime(), reservationInfo.getEndTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private PileReservationInfo copyReservationInfo(PileReservationInfo source) {
|
||||||
|
PileReservationInfo target = new PileReservationInfo();
|
||||||
|
target.setId(source.getId());
|
||||||
|
target.setMemberId(source.getMemberId());
|
||||||
|
target.setPileSn(source.getPileSn());
|
||||||
|
target.setPileConnectorCode(source.getPileConnectorCode());
|
||||||
|
target.setStatus(source.getStatus());
|
||||||
|
target.setReservationType(source.getReservationType());
|
||||||
|
target.setVerifyIdentity(source.getVerifyIdentity());
|
||||||
|
target.setStartTime(source.getStartTime());
|
||||||
|
target.setEndTime(source.getEndTime());
|
||||||
|
target.setFreq(source.getFreq());
|
||||||
|
target.setCreateBy(source.getCreateBy());
|
||||||
|
target.setCreateTime(source.getCreateTime());
|
||||||
|
target.setUpdateBy(source.getUpdateBy());
|
||||||
|
target.setUpdateTime(source.getUpdateTime());
|
||||||
|
target.setDelFlag(source.getDelFlag());
|
||||||
|
return target;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,10 +6,14 @@
|
|||||||
<!--@Table thirdparty_parking_config-->
|
<!--@Table thirdparty_parking_config-->
|
||||||
<id column="id" jdbcType="INTEGER" property="id"/>
|
<id column="id" jdbcType="INTEGER" property="id"/>
|
||||||
<result column="parking_name" jdbcType="VARCHAR" property="parkingName"/>
|
<result column="parking_name" jdbcType="VARCHAR" property="parkingName"/>
|
||||||
|
<result column="platform_type" jdbcType="VARCHAR" property="platformType"/>
|
||||||
<result column="app_id" jdbcType="VARCHAR" property="appId"/>
|
<result column="app_id" jdbcType="VARCHAR" property="appId"/>
|
||||||
<result column="secret_key" jdbcType="VARCHAR" property="secretKey"/>
|
<result column="secret_key" jdbcType="VARCHAR" property="secretKey"/>
|
||||||
<result column="parking_merchant_id" jdbcType="VARCHAR" property="parkingMerchantId"/>
|
<result column="parking_merchant_id" jdbcType="VARCHAR" property="parkingMerchantId"/>
|
||||||
<result column="coupon_id" jdbcType="VARCHAR" property="couponId"/>
|
<result column="coupon_id" jdbcType="VARCHAR" property="couponId"/>
|
||||||
|
<result column="org_id" jdbcType="VARCHAR" property="orgId"/>
|
||||||
|
<result column="park_id" jdbcType="VARCHAR" property="parkId"/>
|
||||||
|
<result column="api_url" jdbcType="VARCHAR" property="apiUrl"/>
|
||||||
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
<result column="create_time" jdbcType="TIMESTAMP" property="createTime"/>
|
||||||
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
|
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
|
||||||
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
<result column="update_time" jdbcType="TIMESTAMP" property="updateTime"/>
|
||||||
@@ -21,10 +25,14 @@
|
|||||||
<!--@mbg.generated-->
|
<!--@mbg.generated-->
|
||||||
id,
|
id,
|
||||||
parking_name,
|
parking_name,
|
||||||
|
platform_type,
|
||||||
app_id,
|
app_id,
|
||||||
secret_key,
|
secret_key,
|
||||||
parking_merchant_id,
|
parking_merchant_id,
|
||||||
coupon_id,
|
coupon_id,
|
||||||
|
org_id,
|
||||||
|
park_id,
|
||||||
|
api_url,
|
||||||
create_time,
|
create_time,
|
||||||
create_by,
|
create_by,
|
||||||
update_time,
|
update_time,
|
||||||
@@ -49,12 +57,13 @@
|
|||||||
|
|
||||||
<insert id="insert" parameterType="com.jsowell.pile.domain.ThirdpartyParkingConfig">
|
<insert id="insert" parameterType="com.jsowell.pile.domain.ThirdpartyParkingConfig">
|
||||||
<!--@mbg.generated-->
|
<!--@mbg.generated-->
|
||||||
insert into thirdparty_parking_config (id, parking_name, app_id,
|
insert into thirdparty_parking_config (id, parking_name, platform_type, app_id,
|
||||||
secret_key, parking_merchant_id, coupon_id,
|
secret_key, parking_merchant_id, coupon_id, org_id, park_id, api_url,
|
||||||
create_time, create_by, update_time,
|
create_time, create_by, update_time,
|
||||||
update_by, del_flag)
|
update_by, del_flag)
|
||||||
values (#{id,jdbcType=INTEGER}, #{parkingName,jdbcType=VARCHAR}, #{appId,jdbcType=VARCHAR},
|
values (#{id,jdbcType=INTEGER}, #{parkingName,jdbcType=VARCHAR}, #{platformType,jdbcType=VARCHAR}, #{appId,jdbcType=VARCHAR},
|
||||||
#{secretKey,jdbcType=VARCHAR}, #{parkingMerchantId,jdbcType=VARCHAR}, #{couponId,jdbcType=VARCHAR},
|
#{secretKey,jdbcType=VARCHAR}, #{parkingMerchantId,jdbcType=VARCHAR}, #{couponId,jdbcType=VARCHAR},
|
||||||
|
#{orgId,jdbcType=VARCHAR}, #{parkId,jdbcType=VARCHAR}, #{apiUrl,jdbcType=VARCHAR},
|
||||||
#{createTime,jdbcType=TIMESTAMP}, #{createBy,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP},
|
#{createTime,jdbcType=TIMESTAMP}, #{createBy,jdbcType=VARCHAR}, #{updateTime,jdbcType=TIMESTAMP},
|
||||||
#{updateBy,jdbcType=VARCHAR}, #{delFlag,jdbcType=VARCHAR})
|
#{updateBy,jdbcType=VARCHAR}, #{delFlag,jdbcType=VARCHAR})
|
||||||
</insert>
|
</insert>
|
||||||
@@ -69,6 +78,9 @@
|
|||||||
<if test="parkingName != null">
|
<if test="parkingName != null">
|
||||||
parking_name,
|
parking_name,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="platformType != null">
|
||||||
|
platform_type,
|
||||||
|
</if>
|
||||||
<if test="appId != null">
|
<if test="appId != null">
|
||||||
app_id,
|
app_id,
|
||||||
</if>
|
</if>
|
||||||
@@ -81,6 +93,15 @@
|
|||||||
<if test="couponId != null">
|
<if test="couponId != null">
|
||||||
coupon_id,
|
coupon_id,
|
||||||
</if>
|
</if>
|
||||||
|
<if test="orgId != null">
|
||||||
|
org_id,
|
||||||
|
</if>
|
||||||
|
<if test="parkId != null">
|
||||||
|
park_id,
|
||||||
|
</if>
|
||||||
|
<if test="apiUrl != null">
|
||||||
|
api_url,
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
create_time,
|
create_time,
|
||||||
</if>
|
</if>
|
||||||
@@ -104,6 +125,9 @@
|
|||||||
<if test="parkingName != null">
|
<if test="parkingName != null">
|
||||||
#{parkingName,jdbcType=VARCHAR},
|
#{parkingName,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="platformType != null">
|
||||||
|
#{platformType,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="appId != null">
|
<if test="appId != null">
|
||||||
#{appId,jdbcType=VARCHAR},
|
#{appId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
@@ -116,6 +140,15 @@
|
|||||||
<if test="couponId != null">
|
<if test="couponId != null">
|
||||||
#{couponId,jdbcType=VARCHAR},
|
#{couponId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="orgId != null">
|
||||||
|
#{orgId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="parkId != null">
|
||||||
|
#{parkId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="apiUrl != null">
|
||||||
|
#{apiUrl,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
#{createTime,jdbcType=TIMESTAMP},
|
#{createTime,jdbcType=TIMESTAMP},
|
||||||
</if>
|
</if>
|
||||||
@@ -141,6 +174,9 @@
|
|||||||
<if test="parkingName != null">
|
<if test="parkingName != null">
|
||||||
parking_name = #{parkingName,jdbcType=VARCHAR},
|
parking_name = #{parkingName,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="platformType != null">
|
||||||
|
platform_type = #{platformType,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="appId != null">
|
<if test="appId != null">
|
||||||
app_id = #{appId,jdbcType=VARCHAR},
|
app_id = #{appId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
@@ -153,6 +189,15 @@
|
|||||||
<if test="couponId != null">
|
<if test="couponId != null">
|
||||||
coupon_id = #{couponId,jdbcType=VARCHAR},
|
coupon_id = #{couponId,jdbcType=VARCHAR},
|
||||||
</if>
|
</if>
|
||||||
|
<if test="orgId != null">
|
||||||
|
org_id = #{orgId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="parkId != null">
|
||||||
|
park_id = #{parkId,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
|
<if test="apiUrl != null">
|
||||||
|
api_url = #{apiUrl,jdbcType=VARCHAR},
|
||||||
|
</if>
|
||||||
<if test="createTime != null">
|
<if test="createTime != null">
|
||||||
create_time = #{createTime,jdbcType=TIMESTAMP},
|
create_time = #{createTime,jdbcType=TIMESTAMP},
|
||||||
</if>
|
</if>
|
||||||
@@ -176,10 +221,14 @@
|
|||||||
<!--@mbg.generated-->
|
<!--@mbg.generated-->
|
||||||
update thirdparty_parking_config
|
update thirdparty_parking_config
|
||||||
set parking_name = #{parkingName,jdbcType=VARCHAR},
|
set parking_name = #{parkingName,jdbcType=VARCHAR},
|
||||||
|
platform_type = #{platformType,jdbcType=VARCHAR},
|
||||||
app_id = #{appId,jdbcType=VARCHAR},
|
app_id = #{appId,jdbcType=VARCHAR},
|
||||||
secret_key = #{secretKey,jdbcType=VARCHAR},
|
secret_key = #{secretKey,jdbcType=VARCHAR},
|
||||||
parking_merchant_id = #{parkingMerchantId,jdbcType=VARCHAR},
|
parking_merchant_id = #{parkingMerchantId,jdbcType=VARCHAR},
|
||||||
coupon_id = #{couponId,jdbcType=VARCHAR},
|
coupon_id = #{couponId,jdbcType=VARCHAR},
|
||||||
|
org_id = #{orgId,jdbcType=VARCHAR},
|
||||||
|
park_id = #{parkId,jdbcType=VARCHAR},
|
||||||
|
api_url = #{apiUrl,jdbcType=VARCHAR},
|
||||||
create_time = #{createTime,jdbcType=TIMESTAMP},
|
create_time = #{createTime,jdbcType=TIMESTAMP},
|
||||||
create_by = #{createBy,jdbcType=VARCHAR},
|
create_by = #{createBy,jdbcType=VARCHAR},
|
||||||
update_time = #{updateTime,jdbcType=TIMESTAMP},
|
update_time = #{updateTime,jdbcType=TIMESTAMP},
|
||||||
@@ -193,4 +242,28 @@
|
|||||||
<include refid="Base_Column_List"/>
|
<include refid="Base_Column_List"/>
|
||||||
from thirdparty_parking_config
|
from thirdparty_parking_config
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByStationId" parameterType="java.lang.String" resultMap="BaseResultMap">
|
||||||
|
select
|
||||||
|
tpc.id,
|
||||||
|
tpc.parking_name,
|
||||||
|
tpc.platform_type,
|
||||||
|
tpc.app_id,
|
||||||
|
tpc.secret_key,
|
||||||
|
tpc.parking_merchant_id,
|
||||||
|
tpc.coupon_id,
|
||||||
|
tpc.org_id,
|
||||||
|
tpc.park_id,
|
||||||
|
tpc.api_url,
|
||||||
|
tpc.create_time,
|
||||||
|
tpc.create_by,
|
||||||
|
tpc.update_time,
|
||||||
|
tpc.update_by,
|
||||||
|
tpc.del_flag
|
||||||
|
from pile_station_info psi
|
||||||
|
inner join thirdparty_parking_config tpc on psi.parking_id = tpc.id
|
||||||
|
where psi.del_flag = '0'
|
||||||
|
and tpc.del_flag = '0'
|
||||||
|
and psi.id = #{stationId,jdbcType=VARCHAR}
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -83,32 +83,17 @@ public class JsowellTask {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private AdapayUnsplitRecordHandleService adapayUnsplitRecordHandleService;
|
private AdapayUnsplitRecordHandleService adapayUnsplitRecordHandleService;
|
||||||
|
|
||||||
private static final String PRE_PROFILE = "pre";
|
|
||||||
|
|
||||||
private static final long YKC_DAILY_TIMECHECK_INTERVAL_MILLIS = 200L;
|
private static final long YKC_DAILY_TIMECHECK_INTERVAL_MILLIS = 200L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置挡板, PRE环境不执行
|
* 设置挡板, PRE环境不执行
|
||||||
*/
|
*/
|
||||||
public void setBarrier() {
|
public void setBarrier() {
|
||||||
skipInPre("设置挡板");
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
|
// return;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean skipInPre(String taskName) {
|
|
||||||
if (!isPreProfile()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
log.info("PRE环境不执行,{}", taskName);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isPreProfile() {
|
|
||||||
String[] activeProfiles = SpringUtils.getActiveProfiles();
|
|
||||||
if (activeProfiles == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return Arrays.stream(activeProfiles)
|
|
||||||
.anyMatch(profile -> StringUtils.equalsIgnoreCase(profile, PRE_PROFILE));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,7 +101,9 @@ public class JsowellTask {
|
|||||||
* close15MinutesOfUnpaidOrders
|
* close15MinutesOfUnpaidOrders
|
||||||
*/
|
*/
|
||||||
public void close15MinutesOfUnpaidOrders() {
|
public void close15MinutesOfUnpaidOrders() {
|
||||||
if (skipInPre("关闭15分钟未支付的订单")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// log.info("关闭15分钟未支付的订单");
|
// log.info("关闭15分钟未支付的订单");
|
||||||
@@ -128,8 +115,10 @@ public class JsowellTask {
|
|||||||
* 订单支付成功,在15分钟内未启动,
|
* 订单支付成功,在15分钟内未启动,
|
||||||
*/
|
*/
|
||||||
public void closeStartFailedOrder() {
|
public void closeStartFailedOrder() {
|
||||||
if (skipInPre("关闭启动失败的订单")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
return;
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
|
// return;
|
||||||
}
|
}
|
||||||
// 查询出最近2天支付成功,并且订单状态为未启动的订单
|
// 查询出最近2天支付成功,并且订单状态为未启动的订单
|
||||||
String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(new Date(), -2));
|
String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(new Date(), -2));
|
||||||
@@ -141,7 +130,9 @@ public class JsowellTask {
|
|||||||
* 查询预约充电的订单并启动
|
* 查询预约充电的订单并启动
|
||||||
*/
|
*/
|
||||||
public void appointmentOrderStart() {
|
public void appointmentOrderStart() {
|
||||||
if (skipInPre("查询预约充电的订单并启动")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 查询出 已支付 设置预约充电 未启动 的订单
|
// 查询出 已支付 设置预约充电 未启动 的订单
|
||||||
@@ -196,7 +187,9 @@ public class JsowellTask {
|
|||||||
* jsowellTask.dailyProofreadTimeForYkcV160(200)
|
* jsowellTask.dailyProofreadTimeForYkcV160(200)
|
||||||
*/
|
*/
|
||||||
public void dailyProofreadTimeForYkcV160(Long intervalMillis) {
|
public void dailyProofreadTimeForYkcV160(Long intervalMillis) {
|
||||||
if (skipInPre("云快充1.6每日自动对时")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -257,7 +250,9 @@ public class JsowellTask {
|
|||||||
* jsowellTask.calculateTheSiteOrdersReport()
|
* jsowellTask.calculateTheSiteOrdersReport()
|
||||||
*/
|
*/
|
||||||
public void calculateTheSiteOrdersReport() {
|
public void calculateTheSiteOrdersReport() {
|
||||||
if (skipInPre("计算站点订单报表")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 查询出所有站点
|
// 查询出所有站点
|
||||||
@@ -284,7 +279,9 @@ public class JsowellTask {
|
|||||||
* jsowellTask.pushToAMap()
|
* jsowellTask.pushToAMap()
|
||||||
*/
|
*/
|
||||||
public void pushToAMap() {
|
public void pushToAMap() {
|
||||||
if (skipInPre("站点的枪口数据推送到高德")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Set<String> stationIds = redisCache.getCacheSet(CacheConstants.PUSH_STATION_CONNECTOR);
|
Set<String> stationIds = redisCache.getCacheSet(CacheConstants.PUSH_STATION_CONNECTOR);
|
||||||
@@ -307,7 +304,9 @@ public class JsowellTask {
|
|||||||
* 贵州省平台推送充电站实时功率 15分钟执行一次
|
* 贵州省平台推送充电站实时功率 15分钟执行一次
|
||||||
*/
|
*/
|
||||||
public void pushStationRealTimePowerInfo() {
|
public void pushStationRealTimePowerInfo() {
|
||||||
if (skipInPre("贵州省平台推送充电站实时功率")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -345,7 +344,9 @@ public class JsowellTask {
|
|||||||
* 推送统计信息 24小时执行一次
|
* 推送统计信息 24小时执行一次
|
||||||
*/
|
*/
|
||||||
public void pushStatisticsInfo() {
|
public void pushStatisticsInfo() {
|
||||||
if (skipInPre("推送统计信息 24小时执行一次")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +385,9 @@ public class JsowellTask {
|
|||||||
* jsowellTask.processOrderSplitting()
|
* jsowellTask.processOrderSplitting()
|
||||||
*/
|
*/
|
||||||
public void processOrderSplitting() {
|
public void processOrderSplitting() {
|
||||||
if (skipInPre("定时任务, 订单分账")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 查询运营商列表
|
// 查询运营商列表
|
||||||
@@ -421,7 +424,9 @@ public class JsowellTask {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void generateMerchantBill() {
|
public void generateMerchantBill() {
|
||||||
if (skipInPre("生成运营商日报表")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 查询运营商列表
|
// 查询运营商列表
|
||||||
@@ -448,7 +453,9 @@ public class JsowellTask {
|
|||||||
* jsowellTask.automaticPayouts()
|
* jsowellTask.automaticPayouts()
|
||||||
*/
|
*/
|
||||||
public void automaticPayouts() {
|
public void automaticPayouts() {
|
||||||
if (skipInPre("定时任务,自动提现")) {
|
String env = SpringUtils.getActiveProfile();
|
||||||
|
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||||
|
log.debug("PRE环境不执行");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 查询开启自动提现运营商列表
|
// 查询开启自动提现运营商列表
|
||||||
@@ -477,9 +484,6 @@ public class JsowellTask {
|
|||||||
* jsowellTask.processUnSettledOrder()
|
* jsowellTask.processUnSettledOrder()
|
||||||
*/
|
*/
|
||||||
public void processUnSettledOrder() {
|
public void processUnSettledOrder() {
|
||||||
if (skipInPre("处理未分帐订单")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.processUnSettledOrder();
|
adapayUnsplitRecordHandleService.processUnSettledOrder();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,9 +493,6 @@ public class JsowellTask {
|
|||||||
* jsowellTask.processUnsplitRecordToDefaultMember()
|
* jsowellTask.processUnsplitRecordToDefaultMember()
|
||||||
*/
|
*/
|
||||||
public void processUnsplitRecordToDefaultMember() {
|
public void processUnsplitRecordToDefaultMember() {
|
||||||
if (skipInPre("处理adapay_unsplit_record待分账数据")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.processUnsplitRecordToDefaultMember();
|
adapayUnsplitRecordHandleService.processUnsplitRecordToDefaultMember();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,9 +501,6 @@ public class JsowellTask {
|
|||||||
* jsowellTask.processUnsplitRecordToDefaultMember(wechatAppId, pageSize)
|
* jsowellTask.processUnsplitRecordToDefaultMember(wechatAppId, pageSize)
|
||||||
*/
|
*/
|
||||||
public void processUnsplitRecordToDefaultMember(String wechatAppId, Integer pageSize) {
|
public void processUnsplitRecordToDefaultMember(String wechatAppId, Integer pageSize) {
|
||||||
if (skipInPre("处理adapay_unsplit_record待分账数据")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.processUnsplitRecordToDefaultMember(wechatAppId, pageSize);
|
adapayUnsplitRecordHandleService.processUnsplitRecordToDefaultMember(wechatAppId, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,9 +515,6 @@ public class JsowellTask {
|
|||||||
* jsowellTask.importAdapayUnsplitRecordAndCompleteFields()
|
* jsowellTask.importAdapayUnsplitRecordAndCompleteFields()
|
||||||
*/
|
*/
|
||||||
public void importAdapayUnsplitRecordAndCompleteFields() {
|
public void importAdapayUnsplitRecordAndCompleteFields() {
|
||||||
if (skipInPre("从Excel导入adapay_unsplit_record并补齐缺失字段")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields();
|
adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,9 +525,6 @@ public class JsowellTask {
|
|||||||
* 示例:jsowellTask.completeAdapayUnsplitRecordFields('2024-01-01 00:00:00', '2025-12-31 23:59:59')
|
* 示例:jsowellTask.completeAdapayUnsplitRecordFields('2024-01-01 00:00:00', '2025-12-31 23:59:59')
|
||||||
*/
|
*/
|
||||||
public void completeAdapayUnsplitRecordFields(String startTime, String endTime) {
|
public void completeAdapayUnsplitRecordFields(String startTime, String endTime) {
|
||||||
if (skipInPre("补齐adapay_unsplit_record表中缺失字段")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.completeAdapayUnsplitRecordFields(startTime, endTime);
|
adapayUnsplitRecordHandleService.completeAdapayUnsplitRecordFields(startTime, endTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,9 +533,6 @@ public class JsowellTask {
|
|||||||
* jsowellTask.syncAndRefreshFlagsFromAdapay(paymentId, wechatAppId)
|
* jsowellTask.syncAndRefreshFlagsFromAdapay(paymentId, wechatAppId)
|
||||||
*/
|
*/
|
||||||
public void syncAndRefreshFlagsFromAdapay(String paymentId, String wechatAppId) {
|
public void syncAndRefreshFlagsFromAdapay(String paymentId, String wechatAppId) {
|
||||||
if (skipInPre("按paymentId从汇付同步并刷新adapay_unsplit_record标识")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.syncAndRefreshFlagsFromAdapay(paymentId, wechatAppId);
|
adapayUnsplitRecordHandleService.syncAndRefreshFlagsFromAdapay(paymentId, wechatAppId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,9 +542,6 @@ public class JsowellTask {
|
|||||||
* 示例:jsowellTask.syncAndRefreshFlagsFromAdapay('2024-01-01 00:00:00', '2025-12-31 23:59:59', 'app_id', 500)
|
* 示例:jsowellTask.syncAndRefreshFlagsFromAdapay('2024-01-01 00:00:00', '2025-12-31 23:59:59', 'app_id', 500)
|
||||||
*/
|
*/
|
||||||
public void syncAndRefreshFlagsFromAdapay(String startTime, String endTime, String wechatAppId, Integer pageSize) {
|
public void syncAndRefreshFlagsFromAdapay(String startTime, String endTime, String wechatAppId, Integer pageSize) {
|
||||||
if (skipInPre("批量从汇付同步并刷新adapay_unsplit_record标识")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.syncAndRefreshFlagsFromAdapay(startTime, endTime, wechatAppId, pageSize);
|
adapayUnsplitRecordHandleService.syncAndRefreshFlagsFromAdapay(startTime, endTime, wechatAppId, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -569,16 +555,10 @@ public class JsowellTask {
|
|||||||
* jsowellTask.importAdapayUnsplitRecordAndCompleteFields(文件路径)
|
* jsowellTask.importAdapayUnsplitRecordAndCompleteFields(文件路径)
|
||||||
*/
|
*/
|
||||||
public void importAdapayUnsplitRecordAndCompleteFields(String filePath) {
|
public void importAdapayUnsplitRecordAndCompleteFields(String filePath) {
|
||||||
if (skipInPre("从Excel导入adapay_unsplit_record并补齐缺失字段")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields(filePath);
|
adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields(filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateOrderReview() {
|
public void updateOrderReview() {
|
||||||
if (skipInPre("更新订单评价标识")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LocalDate yesterday = DateUtils.getYesterday();
|
LocalDate yesterday = DateUtils.getYesterday();
|
||||||
LocalDateTime start = yesterday.atStartOfDay();
|
LocalDateTime start = yesterday.atStartOfDay();
|
||||||
LocalDateTime end = yesterday.atTime(23, 59, 59);
|
LocalDateTime end = yesterday.atTime(23, 59, 59);
|
||||||
|
|||||||
@@ -822,7 +822,9 @@ public class CommonService {
|
|||||||
QcyunParkCouponDTO dto = QcyunParkCouponDTO.builder()
|
QcyunParkCouponDTO dto = QcyunParkCouponDTO.builder()
|
||||||
.plateNumber(orderBasicInfo.getPlateNumber())
|
.plateNumber(orderBasicInfo.getPlateNumber())
|
||||||
.stationId(orderBasicInfo.getStationId())
|
.stationId(orderBasicInfo.getStationId())
|
||||||
.stationName("深圳停车场")
|
.grantSerial(orderBasicInfo.getOrderCode())
|
||||||
|
.discountType(chargeParkingDiscount.getDiscountType())
|
||||||
|
.discountValue(chargeParkingDiscount.getDiscountValue())
|
||||||
.build();
|
.build();
|
||||||
discountFlag = qcyunsService.issuanceOfParkingTickets(dto);
|
discountFlag = qcyunsService.issuanceOfParkingTickets(dto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,4 +33,14 @@ public class QcyunParkCouponDTO {
|
|||||||
|
|
||||||
// 停车流水, 标识具体某次停车事件, 需保证该停车场下唯一
|
// 停车流水, 标识具体某次停车事件, 需保证该停车场下唯一
|
||||||
private String parkingSerial;
|
private String parkingSerial;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠类型(1-减时间单位分钟; 2-减金额单位元)
|
||||||
|
*/
|
||||||
|
private Integer discountType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优惠值
|
||||||
|
*/
|
||||||
|
private String discountValue;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,7 @@ public interface QcyunsService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 发放停车券
|
* 发放停车券
|
||||||
* dto中只需要传入车牌号, 其他参数取配置文件中的参数
|
* dto中需要传入车牌号、站点id和优惠配置,停车场鉴权参数根据站点绑定配置查询
|
||||||
* 现在只有一家车场, parkId在配置文件中, 以后多家车场改为数据库配置
|
|
||||||
* @return true: 发放成功, false: 失败
|
* @return true: 发放成功, false: 失败
|
||||||
*/
|
*/
|
||||||
boolean issuanceOfParkingTickets(QcyunParkCouponDTO dto);
|
boolean issuanceOfParkingTickets(QcyunParkCouponDTO dto);
|
||||||
|
|||||||
@@ -6,18 +6,24 @@ import com.alibaba.fastjson2.JSON;
|
|||||||
import com.alibaba.fastjson2.JSONObject;
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.jsowell.common.core.domain.parking.ParkingCommonParam;
|
import com.jsowell.common.core.domain.parking.ParkingCommonParam;
|
||||||
|
import com.jsowell.common.enums.parkplatform.ParkingPlatformEnum;
|
||||||
import com.jsowell.common.util.ParkingUtil;
|
import com.jsowell.common.util.ParkingUtil;
|
||||||
import com.jsowell.common.util.StringUtils;
|
import com.jsowell.common.util.StringUtils;
|
||||||
import com.jsowell.common.util.id.UUID;
|
import com.jsowell.common.util.id.UUID;
|
||||||
|
import com.jsowell.pile.domain.ThirdpartyParkingConfig;
|
||||||
|
import com.jsowell.pile.service.ThirdPartyParkingConfigService;
|
||||||
import com.jsowell.thirdparty.parking.common.ServiceApiCmd;
|
import com.jsowell.thirdparty.parking.common.ServiceApiCmd;
|
||||||
import com.jsowell.thirdparty.parking.common.bean.QcyunParkCouponDTO;
|
import com.jsowell.thirdparty.parking.common.bean.QcyunParkCouponDTO;
|
||||||
import com.jsowell.thirdparty.parking.common.bean.TempCarInfo;
|
import com.jsowell.thirdparty.parking.common.bean.TempCarInfo;
|
||||||
import com.jsowell.thirdparty.parking.common.response.DataResponse;
|
import com.jsowell.thirdparty.parking.common.response.DataResponse;
|
||||||
import com.jsowell.thirdparty.parking.service.QcyunsService;
|
import com.jsowell.thirdparty.parking.service.QcyunsService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.math.RoundingMode;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -27,28 +33,36 @@ import java.util.Map;
|
|||||||
@Service
|
@Service
|
||||||
public class QcyunsServiceImpl implements QcyunsService {
|
public class QcyunsServiceImpl implements QcyunsService {
|
||||||
|
|
||||||
@Value("${parking.qcyuns.url}")
|
private static final String QCYUN_DISCOUNT_TYPE_AMOUNT = "1";
|
||||||
private String URL;
|
|
||||||
|
|
||||||
@Value("${parking.qcyuns.secretKey}")
|
private static final String QCYUN_DISCOUNT_TYPE_TIME = "2";
|
||||||
private String secretKey;
|
|
||||||
|
|
||||||
@Value("${parking.qcyuns.parkId}")
|
private static final Integer DISCOUNT_TYPE_TIME = 1;
|
||||||
private String parkId;
|
|
||||||
|
|
||||||
@Value("${parking.qcyuns.orgId}")
|
private static final Integer DISCOUNT_TYPE_AMOUNT = 2;
|
||||||
private String orgId;
|
|
||||||
|
@Value("${parking.qcyuns.url:}")
|
||||||
|
private String defaultUrl;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ThirdPartyParkingConfigService thirdPartyParkingConfigService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发放停车券
|
* 发放停车券
|
||||||
* dto中只需要传入车牌号, 其他参数取配置文件中的参数
|
* 根据站点绑定的停车场配置动态获取parkId/orgId/secretKey
|
||||||
* 现在只有一家车场, parkId在配置文件中, 以后多家车场改为数据库配置
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean issuanceOfParkingTickets(QcyunParkCouponDTO dto) {
|
public boolean issuanceOfParkingTickets(QcyunParkCouponDTO dto) {
|
||||||
dto.setParkId(parkId);
|
ThirdpartyParkingConfig parkingConfig = resolveParkingConfig(dto);
|
||||||
|
if (parkingConfig == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dto.setParkId(parkingConfig.getParkId());
|
||||||
|
if (StringUtils.isBlank(dto.getGrantSerial())) {
|
||||||
|
dto.setGrantSerial(UUID.randomUUID().toString());
|
||||||
|
}
|
||||||
// 1. 查询车辆信息
|
// 1. 查询车辆信息
|
||||||
String carInfo = getCarInfo(dto);
|
String carInfo = getCarInfo(dto, parkingConfig);
|
||||||
if (StringUtils.isBlank(carInfo)) {
|
if (StringUtils.isBlank(carInfo)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -60,18 +74,48 @@ public class QcyunsServiceImpl implements QcyunsService {
|
|||||||
}
|
}
|
||||||
dto.setParkingSerial(String.valueOf(tempCarInfo.getRecordId()));
|
dto.setParkingSerial(String.valueOf(tempCarInfo.getRecordId()));
|
||||||
// 2. 创建停车券
|
// 2. 创建停车券
|
||||||
boolean discountCoupon = createDiscountCoupon(dto);
|
boolean discountCoupon = createDiscountCoupon(dto, parkingConfig);
|
||||||
// 3. 查询优惠抵扣金额
|
// 3. 查询优惠抵扣金额
|
||||||
// queryCarInfoDiscountDestory(dto);
|
// queryCarInfoDiscountDestory(dto);
|
||||||
return discountCoupon;
|
return discountCoupon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ThirdpartyParkingConfig resolveParkingConfig(QcyunParkCouponDTO dto) {
|
||||||
|
if (dto == null || StringUtils.isBlank(dto.getStationId())) {
|
||||||
|
log.warn("qcyun发券失败, stationId为空, dto:{}", JSON.toJSONString(dto));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
ThirdpartyParkingConfig parkingConfig = thirdPartyParkingConfigService.selectByStationId(dto.getStationId());
|
||||||
|
if (parkingConfig == null) {
|
||||||
|
log.warn("qcyun发券失败, 站点未绑定停车场配置, stationId:{}", dto.getStationId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!StringUtils.equals(ParkingPlatformEnum.SHEN_ZHEN_PLATFORM.getCode(), parkingConfig.getPlatformType())) {
|
||||||
|
log.warn("qcyun发券失败, 站点绑定的停车平台类型不是qcyun, stationId:{}, parkingConfigId:{}, platformType:{}",
|
||||||
|
dto.getStationId(), parkingConfig.getId(), parkingConfig.getPlatformType());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(parkingConfig.getParkId())
|
||||||
|
|| StringUtils.isBlank(parkingConfig.getOrgId())
|
||||||
|
|| StringUtils.isBlank(parkingConfig.getSecretKey())) {
|
||||||
|
log.warn("qcyun发券失败, 停车场配置缺少parkId/orgId/secretKey, stationId:{}, parkingConfigId:{}",
|
||||||
|
dto.getStationId(), parkingConfig.getId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(getRequestUrl(parkingConfig))) {
|
||||||
|
log.warn("qcyun发券失败, 停车场配置缺少接口地址, stationId:{}, parkingConfigId:{}",
|
||||||
|
dto.getStationId(), parkingConfig.getId());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return parkingConfig;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取车辆信息接口
|
* 获取车辆信息接口
|
||||||
* 根据车牌号获取车辆信息(临时车,月租车,储值车)
|
* 根据车牌号获取车辆信息(临时车,月租车,储值车)
|
||||||
*/
|
*/
|
||||||
private String getCarInfo(QcyunParkCouponDTO dto) {
|
private String getCarInfo(QcyunParkCouponDTO dto, ThirdpartyParkingConfig parkingConfig) {
|
||||||
String parkId = dto.getParkId(); // 使用dto中传入的parkId(写在配置文件中), 也许以后有多家车场改为数据库配置
|
String parkId = dto.getParkId();
|
||||||
// 业务参数
|
// 业务参数
|
||||||
Map<String, String> data = Maps.newHashMap();
|
Map<String, String> data = Maps.newHashMap();
|
||||||
data.put("parkId", parkId);
|
data.put("parkId", parkId);
|
||||||
@@ -81,13 +125,16 @@ public class QcyunsServiceImpl implements QcyunsService {
|
|||||||
param.setService(ServiceApiCmd.CarInfo);
|
param.setService(ServiceApiCmd.CarInfo);
|
||||||
param.setVersion("01");
|
param.setVersion("01");
|
||||||
param.setMsgId(UUID.randomUUID().toString());
|
param.setMsgId(UUID.randomUUID().toString());
|
||||||
// param.setOrgId(dto.getOrgId());
|
param.setOrgId(parkingConfig.getOrgId());
|
||||||
param.setOrgId(orgId);
|
|
||||||
param.setData(data);
|
param.setData(data);
|
||||||
// 生成sign
|
// 生成sign
|
||||||
ParkingUtil.generateAndSetSign(param, secretKey);
|
ParkingUtil.generateAndSetSign(param, parkingConfig.getSecretKey());
|
||||||
// 发送请求
|
// 发送请求
|
||||||
String result = HttpUtil.post(URL, JSON.toJSONString(param));
|
String result = HttpUtil.post(getRequestUrl(parkingConfig), JSON.toJSONString(param));
|
||||||
|
if (StringUtils.isBlank(result)) {
|
||||||
|
log.warn("获取车辆信息接口返回为空, param:{}", JSON.toJSONString(param));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
DataResponse dataResponse = JSONUtil.toBean(result, DataResponse.class);
|
DataResponse dataResponse = JSONUtil.toBean(result, DataResponse.class);
|
||||||
log.info("获取车辆信息接口成功, param:{}, response:{}", JSON.toJSONString(param), JSON.toJSONString(dataResponse));
|
log.info("获取车辆信息接口成功, param:{}, response:{}", JSON.toJSONString(param), JSON.toJSONString(dataResponse));
|
||||||
if (dataResponse.getRetCode() == 0) {
|
if (dataResponse.getRetCode() == 0) {
|
||||||
@@ -99,28 +146,39 @@ public class QcyunsServiceImpl implements QcyunsService {
|
|||||||
/**
|
/**
|
||||||
* 商家减免
|
* 商家减免
|
||||||
*/
|
*/
|
||||||
private boolean createDiscountCoupon(QcyunParkCouponDTO dto) {
|
private boolean createDiscountCoupon(QcyunParkCouponDTO dto, ThirdpartyParkingConfig parkingConfig) {
|
||||||
|
String qcyunDiscountType = getQcyunDiscountType(dto);
|
||||||
|
String qcyunDiscountValue = getQcyunDiscountValue(dto);
|
||||||
|
if (StringUtils.isBlank(qcyunDiscountType) || StringUtils.isBlank(qcyunDiscountValue)) {
|
||||||
|
log.warn("qcyun创建优惠券失败, 优惠配置错误, stationId:{}, discountType:{}, discountValue:{}",
|
||||||
|
dto.getStationId(), dto.getDiscountType(), dto.getDiscountValue());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// 业务参数
|
// 业务参数
|
||||||
Map<String, String> data = Maps.newHashMap();
|
Map<String, String> data = Maps.newHashMap();
|
||||||
data.put("parkingSerial", dto.getParkingSerial());
|
data.put("parkingSerial", dto.getParkingSerial());
|
||||||
data.put("grantSerial", dto.getGrantSerial()); // 对接方唯一id
|
data.put("grantSerial", dto.getGrantSerial()); // 对接方唯一id
|
||||||
data.put("plate", dto.getPlateNumber()); // 车牌号
|
data.put("plate", dto.getPlateNumber()); // 车牌号
|
||||||
data.put("storeName", dto.getStationName()); // 商家名称
|
data.put("storeName", StringUtils.defaultIfBlank(dto.getStationName(),
|
||||||
data.put("type", "1"); // 优惠类型: 1.金额, 2.时长, 3.全免
|
StringUtils.defaultIfBlank(parkingConfig.getParkingName(), "充电停车优惠"))); // 商家名称
|
||||||
data.put("value", String.valueOf(10 * 100)); // 当type=1时单位为分;当type=2时单位为分钟
|
data.put("type", qcyunDiscountType); // 优惠类型: 1.金额, 2.时长, 3.全免
|
||||||
|
data.put("value", qcyunDiscountValue); // 当type=1时单位为分;当type=2时单位为分钟
|
||||||
data.put("parkId", dto.getParkId()); // 车场id
|
data.put("parkId", dto.getParkId()); // 车场id
|
||||||
// 组装请求体
|
// 组装请求体
|
||||||
ParkingCommonParam param = new ParkingCommonParam();
|
ParkingCommonParam param = new ParkingCommonParam();
|
||||||
param.setService(ServiceApiCmd.DiscountCreate);
|
param.setService(ServiceApiCmd.DiscountCreate);
|
||||||
param.setVersion("01");
|
param.setVersion("01");
|
||||||
param.setMsgId(UUID.randomUUID().toString());
|
param.setMsgId(UUID.randomUUID().toString());
|
||||||
// param.setOrgId(dto.getOrgId());
|
param.setOrgId(parkingConfig.getOrgId());
|
||||||
param.setOrgId(orgId);
|
|
||||||
param.setData(data);
|
param.setData(data);
|
||||||
// 生成sign
|
// 生成sign
|
||||||
ParkingUtil.generateAndSetSign(param, secretKey);
|
ParkingUtil.generateAndSetSign(param, parkingConfig.getSecretKey());
|
||||||
// 发送请求
|
// 发送请求
|
||||||
String result = HttpUtil.post(URL, JSON.toJSONString(param));
|
String result = HttpUtil.post(getRequestUrl(parkingConfig), JSON.toJSONString(param));
|
||||||
|
if (StringUtils.isBlank(result)) {
|
||||||
|
log.warn("创建优惠券返回为空, param:{}", JSON.toJSONString(param));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
DataResponse dataResponse = JSONUtil.toBean(result, DataResponse.class);
|
DataResponse dataResponse = JSONUtil.toBean(result, DataResponse.class);
|
||||||
log.info("创建优惠券成功, param:{}, response:{}", JSON.toJSONString(param), JSON.toJSONString(dataResponse));
|
log.info("创建优惠券成功, param:{}, response:{}", JSON.toJSONString(param), JSON.toJSONString(dataResponse));
|
||||||
|
|
||||||
@@ -130,30 +188,65 @@ public class QcyunsServiceImpl implements QcyunsService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getQcyunDiscountType(QcyunParkCouponDTO dto) {
|
||||||
|
if (DISCOUNT_TYPE_AMOUNT.equals(dto.getDiscountType())) {
|
||||||
|
return QCYUN_DISCOUNT_TYPE_AMOUNT;
|
||||||
|
}
|
||||||
|
if (DISCOUNT_TYPE_TIME.equals(dto.getDiscountType())) {
|
||||||
|
return QCYUN_DISCOUNT_TYPE_TIME;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getQcyunDiscountValue(QcyunParkCouponDTO dto) {
|
||||||
|
if (StringUtils.isBlank(dto.getDiscountValue())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
BigDecimal discountValue = new BigDecimal(dto.getDiscountValue());
|
||||||
|
if (discountValue.compareTo(BigDecimal.ZERO) <= 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (DISCOUNT_TYPE_AMOUNT.equals(dto.getDiscountType())) {
|
||||||
|
return discountValue.multiply(new BigDecimal("100")).setScale(0, RoundingMode.HALF_UP).toPlainString();
|
||||||
|
}
|
||||||
|
if (DISCOUNT_TYPE_TIME.equals(dto.getDiscountType())) {
|
||||||
|
return discountValue.setScale(0, RoundingMode.HALF_UP).toPlainString();
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
log.warn("qcyun优惠值转换失败, discountValue:{}", dto.getDiscountValue(), e);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getRequestUrl(ThirdpartyParkingConfig parkingConfig) {
|
||||||
|
return StringUtils.defaultIfBlank(parkingConfig.getApiUrl(), defaultUrl);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询优惠抵扣金额
|
* 查询优惠抵扣金额
|
||||||
*/
|
*/
|
||||||
private void queryCarInfoDiscountDestory(QcyunParkCouponDTO dto) {
|
private void queryCarInfoDiscountDestory(QcyunParkCouponDTO dto, ThirdpartyParkingConfig parkingConfig) {
|
||||||
// 业务参数
|
// 业务参数
|
||||||
Map<String, String> data = Maps.newHashMap();
|
Map<String, String> data = Maps.newHashMap();
|
||||||
data.put("parkingSerial", dto.getParkingSerial());
|
data.put("parkingSerial", dto.getParkingSerial());
|
||||||
data.put("grantSerial", dto.getGrantSerial()); // 对接方唯一id
|
data.put("grantSerial", dto.getGrantSerial()); // 对接方唯一id
|
||||||
data.put("plate", dto.getPlateNumber()); // 车牌号
|
data.put("plate", dto.getPlateNumber()); // 车牌号
|
||||||
data.put("storeName", dto.getStationName()); // 商家名称
|
data.put("storeName", dto.getStationName()); // 商家名称
|
||||||
data.put("type", "1"); // 优惠类型: 1.金额, 2.时长, 3.全免
|
data.put("type", getQcyunDiscountType(dto)); // 优惠类型: 1.金额, 2.时长, 3.全免
|
||||||
data.put("value", String.valueOf(10 * 100)); // 当type=1时单位为分;当type=2时单位为分钟
|
data.put("value", getQcyunDiscountValue(dto)); // 当type=1时单位为分;当type=2时单位为分钟
|
||||||
data.put("parkId", dto.getParkId()); //
|
data.put("parkId", dto.getParkId()); //
|
||||||
// 组装请求体
|
// 组装请求体
|
||||||
ParkingCommonParam param = new ParkingCommonParam();
|
ParkingCommonParam param = new ParkingCommonParam();
|
||||||
param.setService(ServiceApiCmd.CarInfoDiscountDestory);
|
param.setService(ServiceApiCmd.CarInfoDiscountDestory);
|
||||||
param.setVersion("01");
|
param.setVersion("01");
|
||||||
param.setMsgId(UUID.randomUUID().toString());
|
param.setMsgId(UUID.randomUUID().toString());
|
||||||
param.setOrgId(orgId);
|
param.setOrgId(parkingConfig.getOrgId());
|
||||||
param.setData(data);
|
param.setData(data);
|
||||||
// 生成sign
|
// 生成sign
|
||||||
ParkingUtil.generateAndSetSign(param, secretKey);
|
ParkingUtil.generateAndSetSign(param, parkingConfig.getSecretKey());
|
||||||
// 发送请求
|
// 发送请求
|
||||||
String result = HttpUtil.post(URL, JSON.toJSONString(param));
|
String result = HttpUtil.post(getRequestUrl(parkingConfig), JSON.toJSONString(param));
|
||||||
DataResponse dataResponse = JSONUtil.toBean(result, DataResponse.class);
|
DataResponse dataResponse = JSONUtil.toBean(result, DataResponse.class);
|
||||||
log.info("查询优惠抵扣金额, param:{}, response:{}", JSON.toJSONString(param), JSON.toJSONString(dataResponse));
|
log.info("查询优惠抵扣金额, param:{}, response:{}", JSON.toJSONString(param), JSON.toJSONString(dataResponse));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user