mirror of
https://codeup.aliyun.com/67c68d4e484ca2f0a13ac3c1/ydc/jsowell-charger-web.git
synced 2026-07-20 22:18:07 +08:00
Compare commits
15 Commits
feature-qc
...
17b19ab0da
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
17b19ab0da | ||
|
|
aa7a9a10d9 | ||
|
|
06aab00627 | ||
|
|
7685f3df55 | ||
|
|
fecc17bf08 | ||
|
|
d266156953 | ||
|
|
681691c183 | ||
|
|
e4be50b417 | ||
|
|
e2c0d7fd34 | ||
|
|
ddcf6abb3e | ||
|
|
84fc754c39 | ||
|
|
944f4100ad | ||
|
|
db544375bd | ||
|
|
b77ad0d686 | ||
|
|
838e37ed03 |
3
docs/sql/pile_msg_record_retention_index.sql
Normal file
3
docs/sql/pile_msg_record_retention_index.sql
Normal file
@@ -0,0 +1,3 @@
|
||||
ALTER TABLE `pile_msg_record`
|
||||
ADD KEY `idx_pile_frame_id` (`pile_sn`, `frame_type`, `id`),
|
||||
ADD KEY `idx_pile_frame_transaction` (`pile_sn`, `frame_type`, `transaction_code`);
|
||||
@@ -522,8 +522,8 @@ public class PersonPileController extends BaseController {
|
||||
try {
|
||||
String memberId = getMemberIdByAuthorization(request);
|
||||
dto.setMemberId(memberId);
|
||||
int reservedId = yuxinReservationChargingService.createReservation(dto);
|
||||
response = new RestApiResponse<>(ImmutableMap.of("reservedId", reservedId));
|
||||
yuxinReservationChargingService.createReservation(dto);
|
||||
response = new RestApiResponse<>();
|
||||
} catch (BusinessException e) {
|
||||
logger.error("羽信添加预约充电error, params:{}", dto, e);
|
||||
response = new RestApiResponse<>(e.getCode(), e.getMessage());
|
||||
@@ -535,102 +535,6 @@ public class PersonPileController extends BaseController {
|
||||
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
|
||||
|
||||
@@ -9,7 +9,7 @@ spring:
|
||||
# redis 配置
|
||||
redis:
|
||||
# 地址
|
||||
host: 192.168.0.8
|
||||
host: 192.168.0.118
|
||||
# 端口,默认为6379
|
||||
port: 6379
|
||||
# 数据库索引
|
||||
@@ -36,9 +36,9 @@ spring:
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
# url: jdbc:mysql://192.168.0.8:3306/jsowell_pre?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
# url: jdbc:mysql://192.168.0.118:3306/jsowell_pre?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
# username: jsowell_pre
|
||||
url: jdbc:mysql://192.168.0.8:3306/jsowell_prd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://192.168.0.118:3306/jsowell_prd?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: jsowell_prd
|
||||
password: dev@js160829
|
||||
# 从库数据源
|
||||
@@ -90,7 +90,7 @@ spring:
|
||||
|
||||
# rabbitmq配置 dev
|
||||
rabbitmq:
|
||||
host: 192.168.0.8
|
||||
host: 192.168.0.118
|
||||
port: 5672
|
||||
username: admin
|
||||
password: admin
|
||||
@@ -121,7 +121,7 @@ logging:
|
||||
|
||||
# 基础URL前缀
|
||||
baseurl:
|
||||
prefix: http://192.168.0.8:8080
|
||||
prefix: http://192.168.0.118:8080
|
||||
|
||||
# Minio配置
|
||||
minio:
|
||||
@@ -271,7 +271,7 @@ dubbo:
|
||||
name: wcc-server
|
||||
qosEnable: false
|
||||
registry:
|
||||
address: nacos://192.168.0.8:8848
|
||||
address: nacos://192.168.0.118:8848
|
||||
parameters:
|
||||
namespace: e328faaf-8516-42d0-817a-7406232b3581
|
||||
username: nacos
|
||||
|
||||
@@ -45,6 +45,15 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
||||
// log.info("[====远程更新应答====] param:{}, channel:{}", JSON.toJSONString(ykcDataProtocol), channel.toString());
|
||||
// 消息体
|
||||
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 length = 16;
|
||||
@@ -66,8 +75,6 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
||||
startIndex += length;
|
||||
length = 1;
|
||||
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 reservationType = null;
|
||||
@@ -93,27 +100,41 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
||||
String failedReasonMsg = yuxinResponse ? getYuxinFailedReasonMsg(failedReason) : failedReason;
|
||||
|
||||
if (yuxinResponse) {
|
||||
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 结果:{}, 失败原因:{}",
|
||||
responseFrameType, transactionCode, pileSn, connectorCode, reservationType, resultCode, failedReasonMsg);
|
||||
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 结果:{}({}), 失败原因:{}({}), 原始报文:{}",
|
||||
responseFrameType, transactionCode, pileSn, connectorCode, reservationType, resultCode,
|
||||
getYuxinSetupResultMsg(resultCode), failedReason, failedReasonMsg, rawMessage);
|
||||
if (!StringUtils.equals(resultCode, "01")) {
|
||||
log.warn("羽信预约充电设置失败, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 预约方式:{}, 失败原因:{}({}), 原始报文:{}",
|
||||
transactionCode, pileSn, connectorCode, reservationType, failedReason, failedReasonMsg, rawMessage);
|
||||
}
|
||||
} else {
|
||||
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 结果:{}, 失败原因:{}",
|
||||
responseFrameType, transactionCode, pileSn, connectorCode, resultCode, failedReason);
|
||||
log.info("{}预约充电响应, 交易流水号:{}, 桩SN:{}, 枪口号:{}, 结果:{}, 失败原因:{}, 原始报文:{}",
|
||||
responseFrameType, transactionCode, pileSn, connectorCode, resultCode, failedReason, rawMessage);
|
||||
}
|
||||
|
||||
// 根据请求id,在集合中找到与外部线程通信的SyncPromise对象
|
||||
String requestFrameType = YKCFrameTypeCode.PileAnswersRelation.getRequestFrameType(responseFrameType);
|
||||
if (StringUtils.isBlank(requestFrameType)) {
|
||||
requestFrameType = YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_SETUP_CODE.getBytes());
|
||||
requestFrameType = yuxinResponse
|
||||
? YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE.getBytes())
|
||||
: YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_SETUP_CODE.getBytes());
|
||||
}
|
||||
String msgId = ctx.channel().id().toString() + "_" + requestFrameType;
|
||||
log.info("同步获取响应数据-收到消息, msgId:{}", msgId);
|
||||
SyncPromise syncPromise = RpcUtil.getSyncPromiseMap().get(msgId);
|
||||
if(syncPromise != null) {
|
||||
if (syncPromise != null) {
|
||||
// 设置响应结果
|
||||
syncPromise.setRpcResult(ykcDataProtocol.getBytes());
|
||||
// 唤醒外部线程
|
||||
log.info("同步获取响应数据-唤醒外部线程, SyncPromise:{}", JSON.toJSONString(syncPromise));
|
||||
syncPromise.wake();
|
||||
} else {
|
||||
log.warn("同步获取响应数据-未找到等待线程, msgId:{}, responseFrameType:{}, requestFrameType:{}, 原始报文:{}",
|
||||
msgId, responseFrameType, requestFrameType, rawMessage);
|
||||
}
|
||||
|
||||
if (yuxinResponse) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 如果收到成功, 从redis取值, 保存到数据库
|
||||
@@ -147,4 +168,13 @@ public class ReservationChargingResponseHandler extends AbstractYkcHandler {
|
||||
}
|
||||
return failedReason;
|
||||
}
|
||||
|
||||
private String getYuxinSetupResultMsg(String resultCode) {
|
||||
if (StringUtils.equals(resultCode, "00")) {
|
||||
return "失败";
|
||||
} else if (StringUtils.equals(resultCode, "01")) {
|
||||
return "成功";
|
||||
}
|
||||
return resultCode;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,11 @@ public class YuxinReservationChargingDTO {
|
||||
*/
|
||||
private String reservedId;
|
||||
|
||||
/**
|
||||
* 状态 (0-停用;1-启用)
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/**
|
||||
* 充电桩编号
|
||||
*/
|
||||
|
||||
@@ -23,4 +23,13 @@ public interface PileMsgRecordMapper {
|
||||
|
||||
List<PileMsgRecord> queryPileFeedList(@Param("pileSn") String pileSn, @Param("frameType") String frameType,
|
||||
@Param("transactionCode") String transactionCode);
|
||||
|
||||
List<PileMsgRecord> queryPileFeedListByJsonTransactionCode(@Param("pileSn") String pileSn, @Param("frameType") String frameType,
|
||||
@Param("transactionCode") String transactionCode);
|
||||
|
||||
Long selectRetentionCutoffId(@Param("pileSn") String pileSn, @Param("frameType") String frameType,
|
||||
@Param("offset") int offset);
|
||||
|
||||
int deleteOldRecordsBeforeId(@Param("pileSn") String pileSn, @Param("frameType") String frameType,
|
||||
@Param("cutoffId") Long cutoffId, @Param("limit") int limit);
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.jsowell.pile.domain.ykcCommond.*;
|
||||
import com.jsowell.pile.dto.PublishBillingTemplateDTO;
|
||||
import com.jsowell.pile.dto.RemoteAccountBalanceUpdateDTO;
|
||||
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.PileDetailVO;
|
||||
import com.jsowell.wxpay.service.WxAppletRemoteService;
|
||||
@@ -520,11 +519,86 @@ public class PileRemoteService {
|
||||
|
||||
/**
|
||||
* 羽信预约充电指令
|
||||
*
|
||||
* @return result: 1-成功; 0-失败
|
||||
*/
|
||||
public String yuxinReservationCharging(YuxinReservationChargingCommand command) {
|
||||
byte[] bytes = ykcPushCommandService.pushYuxinReservationChargingCommand(command);
|
||||
return parseReservationChargingResponse(bytes);
|
||||
return parseYuxinReservationChargingResponse(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) {
|
||||
@@ -601,6 +675,31 @@ public class PileRemoteService {
|
||||
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) {
|
||||
if (StringUtils.equals(failedReason, "00")) {
|
||||
return "无";
|
||||
|
||||
@@ -1,17 +1,8 @@
|
||||
package com.jsowell.pile.service;
|
||||
|
||||
import com.jsowell.pile.dto.YuxinReservationChargingDTO;
|
||||
import com.jsowell.pile.vo.PileReservationInfoVO;
|
||||
|
||||
public interface YuxinReservationChargingService {
|
||||
|
||||
int createReservation(YuxinReservationChargingDTO dto);
|
||||
|
||||
int updateReservation(YuxinReservationChargingDTO dto);
|
||||
|
||||
void cancelReservation(YuxinReservationChargingDTO dto);
|
||||
|
||||
void deleteReservation(YuxinReservationChargingDTO dto);
|
||||
|
||||
PileReservationInfoVO queryReservationInfo(YuxinReservationChargingDTO dto);
|
||||
void createReservation(YuxinReservationChargingDTO dto);
|
||||
}
|
||||
|
||||
@@ -828,7 +828,7 @@ public class PileBillingTemplateServiceImpl implements PileBillingTemplateServic
|
||||
EchoBillingTemplateVO echoBillingTemplateVO = queryPileBillingTemplateById(Long.parseLong(billingTemplateVO.getTemplateId()));
|
||||
// 时段清单
|
||||
List<BillingTimeDTO> timeArray = echoBillingTemplateVO.getTimeArray();
|
||||
log.info("计费模板时段:{}", JSON.toJSONString(timeArray));
|
||||
// log.info("计费模板时段:{}", JSON.toJSONString(timeArray));
|
||||
|
||||
List<BillingPriceVO> resultList = Lists.newArrayList();
|
||||
for (BillingTimeDTO billingTimeDTO : timeArray) {
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
package com.jsowell.pile.service.impl;
|
||||
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.pile.mapper.PileMsgRecordMapper;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 非交易记录报文保留策略:
|
||||
* 每个桩的每个帧类型仅保留最近200条,删除动作放到后台异步分批执行,
|
||||
* 避免在报文写入主链路上同步删除带来额外延迟。
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PileMsgRecordRetentionService {
|
||||
|
||||
private static final String KEEP_FOREVER_FRAME_TYPE = "0x3B";
|
||||
private static final int RETAIN_COUNT = 200;
|
||||
private static final int RETENTION_OFFSET = RETAIN_COUNT - 1;
|
||||
private static final int DELETE_BATCH_SIZE = 500;
|
||||
private static final int MAX_DELETE_BATCHES_PER_RUN = 20;
|
||||
private static final long CLEANUP_DELAY_SECONDS = 30L;
|
||||
private static final long FOLLOW_UP_DELAY_SECONDS = 5L;
|
||||
|
||||
@Autowired
|
||||
private PileMsgRecordMapper pileMsgRecordMapper;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("scheduledExecutorService")
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
private final Set<String> pendingCleanupKeys = ConcurrentHashMap.newKeySet();
|
||||
|
||||
public void scheduleRetention(String pileSn, String frameType) {
|
||||
if (StringUtils.isBlank(pileSn) || StringUtils.isBlank(frameType) || KEEP_FOREVER_FRAME_TYPE.equals(frameType)) {
|
||||
return;
|
||||
}
|
||||
this.scheduleRetention(pileSn, frameType, CLEANUP_DELAY_SECONDS);
|
||||
}
|
||||
|
||||
private void scheduleRetention(String pileSn, String frameType, long delaySeconds) {
|
||||
String key = buildKey(pileSn, frameType);
|
||||
if (!pendingCleanupKeys.add(key)) {
|
||||
return;
|
||||
}
|
||||
scheduledExecutorService.schedule(() -> runCleanup(key, pileSn, frameType), delaySeconds, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
private void runCleanup(String key, String pileSn, String frameType) {
|
||||
boolean hasMore = false;
|
||||
try {
|
||||
hasMore = cleanupGroup(pileSn, frameType);
|
||||
} catch (Exception e) {
|
||||
log.error("pile_msg_record清理失败, pileSn:{}, frameType:{}", pileSn, frameType, e);
|
||||
} finally {
|
||||
pendingCleanupKeys.remove(key);
|
||||
}
|
||||
|
||||
if (hasMore) {
|
||||
this.scheduleRetention(pileSn, frameType, FOLLOW_UP_DELAY_SECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean cleanupGroup(String pileSn, String frameType) {
|
||||
Long cutoffId = pileMsgRecordMapper.selectRetentionCutoffId(pileSn, frameType, RETENTION_OFFSET);
|
||||
if (cutoffId == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int totalDeleted = 0;
|
||||
for (int i = 0; i < MAX_DELETE_BATCHES_PER_RUN; i++) {
|
||||
int deleted = pileMsgRecordMapper.deleteOldRecordsBeforeId(pileSn, frameType, cutoffId, DELETE_BATCH_SIZE);
|
||||
totalDeleted += deleted;
|
||||
if (deleted < DELETE_BATCH_SIZE) {
|
||||
if (totalDeleted > 0) {
|
||||
log.info("pile_msg_record清理完成, pileSn:{}, frameType:{}, deleted:{}", pileSn, frameType, totalDeleted);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (totalDeleted > 0) {
|
||||
log.info("pile_msg_record本轮清理完成, pileSn:{}, frameType:{}, deleted:{}, 将继续异步清理",
|
||||
pileSn, frameType, totalDeleted);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String buildKey(String pileSn, String frameType) {
|
||||
return pileSn + "#" + frameType;
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ import com.jsowell.pile.service.OrderBasicInfoService;
|
||||
import com.jsowell.pile.service.PileMsgRecordService;
|
||||
import com.jsowell.pile.vo.web.PileCommunicationLogVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@@ -36,6 +37,9 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
|
||||
@Autowired
|
||||
private OrderBasicInfoService orderBasicInfoService;
|
||||
|
||||
@Autowired
|
||||
private PileMsgRecordRetentionService pileMsgRecordRetentionService;
|
||||
|
||||
@Override
|
||||
public void save(String pileSn, String connectorCode, String frameType, String jsonMsg, String originalMsg) {
|
||||
PileMsgRecord pileMsgRecord = PileMsgRecord.builder()
|
||||
@@ -46,6 +50,7 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
|
||||
.originalMsg(originalMsg)
|
||||
.build();
|
||||
pileMsgRecordMapper.insertSelective(pileMsgRecord);
|
||||
pileMsgRecordRetentionService.scheduleRetention(pileSn, frameType);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -85,6 +90,7 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
|
||||
pileMsgRecord.setOriginalMsg(originalMsg);
|
||||
pileMsgRecord.setCreateTime(DateUtils.getDateTime());
|
||||
pileMsgRecordMapper.insertSelective(pileMsgRecord);
|
||||
pileMsgRecordRetentionService.scheduleRetention(pileSn, frameType);
|
||||
}
|
||||
|
||||
// @Override
|
||||
@@ -178,6 +184,9 @@ public class PileMsgRecordServiceImpl implements PileMsgRecordService {
|
||||
@Override
|
||||
public List<PileMsgRecord> queryPileFeedList(String pileSn, String frameType, String transactionCode) {
|
||||
List<PileMsgRecord> list = pileMsgRecordMapper.queryPileFeedList(pileSn, frameType, transactionCode);
|
||||
if (CollectionUtils.isEmpty(list) && StringUtils.isNotBlank(transactionCode)) {
|
||||
list = pileMsgRecordMapper.queryPileFeedListByJsonTransactionCode(pileSn, frameType, transactionCode);
|
||||
}
|
||||
log.info("queryPileFeedList - pileSn:{}, frameType:{}, transactionCode:{}, list: {}", pileSn, frameType, transactionCode, list);
|
||||
return list;
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
|
||||
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_RESERVATION_TIMEOUT = 0;
|
||||
private static final int YUXIN_RESERVATION_RESPONSE_TIMEOUT_SECONDS = 5;
|
||||
|
||||
@Autowired
|
||||
private PileBillingTemplateService pileBillingTemplateService;
|
||||
@@ -193,6 +194,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
|
||||
log.error("push命令[{}]失败, 桩号:{}无法获取到长连接, 请检查充电桩连接状态!", frameTypeName, pileSn);
|
||||
throw new NullPointerException("channel");
|
||||
}
|
||||
log.info("同步获取响应数据-发送消息, pileSn:{}, channelId:{}, 帧类型:{}", pileSn, ctx.channel().id(), frameTypeName);
|
||||
if(msg == null) {
|
||||
throw new NullPointerException("发送消息msg为空");
|
||||
}
|
||||
@@ -786,13 +788,17 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
|
||||
public byte[] pushYuxinReservationChargingCommand(YuxinReservationChargingCommand command) {
|
||||
String pileSn = command.getPileSn();
|
||||
byte[] msg = buildYuxinReservationChargingMsg(command);
|
||||
log.info("羽信预约充电下发原始报文, pileSn:{}, rawMessage:{}", pileSn, BytesUtil.bin2HexStr(msg));
|
||||
byte[] response;
|
||||
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) {
|
||||
log.error("发送羽信预约充电消息异常", e);
|
||||
response = null;
|
||||
}
|
||||
log.info("羽信预约充电回复原始报文, pileSn:{}, rawMessage:{}",
|
||||
pileSn, response == null ? "null" : BytesUtil.bin2HexStr(response));
|
||||
|
||||
log.info("【=====平台下发指令=====】: 羽信预约充电指令, 帧类型:{}, 交易流水号:{}, 桩编号:{}, 枪口号:{}, 账户余额:{}, 预约类型(00-立即预约;01-取消预约):{}, 充电策略:{}, 充电参数:{}, 系统时间:{}, 预约启动时间:{}, 预约超时时间:{}",
|
||||
YKCUtils.frameType2Str(YKCFrameTypeCode.YUXIN_RESERVATION_CHARGING_SETUP_CODE.getBytes()),
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.jsowell.pile.service.impl;
|
||||
|
||||
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.ReturnCodeEnum;
|
||||
import com.jsowell.common.exception.BusinessException;
|
||||
@@ -10,41 +9,31 @@ import com.jsowell.common.util.PileProgramVersionUtils;
|
||||
import com.jsowell.common.util.StringUtils;
|
||||
import com.jsowell.common.util.YKCUtils;
|
||||
import com.jsowell.pile.domain.PileBasicInfo;
|
||||
import com.jsowell.pile.domain.PileReservationInfo;
|
||||
import com.jsowell.pile.domain.ykcCommond.YuxinReservationChargingCommand;
|
||||
import com.jsowell.pile.dto.YuxinReservationChargingDTO;
|
||||
import com.jsowell.pile.mapper.PileReservationInfoMapper;
|
||||
import com.jsowell.pile.service.PileBasicInfoService;
|
||||
import com.jsowell.pile.service.PileRemoteService;
|
||||
import com.jsowell.pile.service.YuxinReservationChargingService;
|
||||
import com.jsowell.pile.vo.PileReservationInfoVO;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.sql.Time;
|
||||
import java.time.Duration;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class YuxinReservationChargingServiceImpl implements YuxinReservationChargingService {
|
||||
|
||||
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 DEFAULT_CHARGING_PARAM = BigDecimal.ZERO;
|
||||
private static final int DEFAULT_CHARGING_STRATEGY = 0;
|
||||
|
||||
@Resource
|
||||
private PileReservationInfoMapper pileReservationInfoMapper;
|
||||
private static final int TIME_CONTROL_CHARGING_STRATEGY = 1;
|
||||
private static final int DEFAULT_RESERVATION_TIMEOUT_MINUTES = 0xFF;
|
||||
|
||||
@Autowired
|
||||
private PileRemoteService pileRemoteService;
|
||||
@@ -53,198 +42,47 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
||||
private PileBasicInfoService pileBasicInfoService;
|
||||
|
||||
@Override
|
||||
public int createReservation(YuxinReservationChargingDTO dto) {
|
||||
public void createReservation(YuxinReservationChargingDTO dto) {
|
||||
validateCreateOrUpdateParam(dto);
|
||||
normalizePileInfo(dto);
|
||||
assertYuxinMainboard(dto.getPileSn());
|
||||
|
||||
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));
|
||||
}
|
||||
sendYuxinReservationCommandAndAssertSuccess(dto, YUXIN_RESERVATION_TYPE_CREATE);
|
||||
}
|
||||
|
||||
private void sendYuxinReservationCommandAndAssertSuccess(YuxinReservationChargingDTO dto,
|
||||
PileReservationInfo reservationInfo,
|
||||
String yuxinReservationType) {
|
||||
if (!sendYuxinReservationCommand(dto, reservationInfo, yuxinReservationType)) {
|
||||
if (!sendYuxinReservationCommand(dto, yuxinReservationType)) {
|
||||
throwReservationCommandFailed();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean sendYuxinReservationCommand(YuxinReservationChargingDTO dto,
|
||||
PileReservationInfo reservationInfo,
|
||||
String yuxinReservationType) {
|
||||
YuxinReservationChargingCommand command = buildYuxinReservationChargingCommand(dto, reservationInfo, yuxinReservationType);
|
||||
log.info("羽信预约充电指令下发, memberId:{}, reservedId:{}, reservationType:{}, reservation:{}",
|
||||
dto.getMemberId(), reservationInfo.getId(), yuxinReservationType, reservationLogText(reservationInfo));
|
||||
YuxinReservationChargingCommand command = buildYuxinReservationChargingCommand(dto, yuxinReservationType);
|
||||
log.info("羽信预约充电指令下发, memberId:{}, reservationType:{}, command:{}",
|
||||
dto.getMemberId(), yuxinReservationType, reservationLogText(dto, command));
|
||||
String result = pileRemoteService.yuxinReservationCharging(command);
|
||||
boolean success = StringUtils.equals(result, Constants.ONE);
|
||||
log.info("羽信预约充电指令返回, memberId:{}, reservedId:{}, reservationType:{}, result:{}, success:{}",
|
||||
dto.getMemberId(), reservationInfo.getId(), yuxinReservationType, result, success);
|
||||
log.info("羽信预约充电指令返回, memberId:{}, reservationType:{}, result:{}, success:{}",
|
||||
dto.getMemberId(), yuxinReservationType, result, success);
|
||||
return success;
|
||||
}
|
||||
|
||||
private YuxinReservationChargingCommand buildYuxinReservationChargingCommand(YuxinReservationChargingDTO dto,
|
||||
PileReservationInfo reservationInfo,
|
||||
String yuxinReservationType) {
|
||||
LocalTime startTime = parseSqlTime(dto.getStartTime()).toLocalTime();
|
||||
return YuxinReservationChargingCommand.builder()
|
||||
.transactionCode(Constants.ILLEGAL_TRANSACTION_CODE)
|
||||
.pileSn(reservationInfo.getPileSn())
|
||||
.connectorCode(getConnectorCode(reservationInfo))
|
||||
.pileSn(dto.getPileSn())
|
||||
.connectorCode(getConnectorCode(dto))
|
||||
.accountBalance(YUXIN_ACCOUNT_BALANCE)
|
||||
.reservationType(yuxinReservationType)
|
||||
.chargingStrategy(dto.getChargingStrategy() == null ? DEFAULT_CHARGING_STRATEGY : dto.getChargingStrategy())
|
||||
.chargingParam(dto.getChargingParam() == null ? DEFAULT_CHARGING_PARAM : dto.getChargingParam())
|
||||
.chargingStrategy(TIME_CONTROL_CHARGING_STRATEGY)
|
||||
.chargingParam(getChargingHours(dto))
|
||||
.systemTime(new Date())
|
||||
.reservedStartTime(getReservedStartDate(reservationInfo.getStartTime().toLocalTime(), yuxinReservationType))
|
||||
.reservationTimeout(getReservationTimeout(dto, reservationInfo, yuxinReservationType))
|
||||
.reservedStartTime(getReservedStartDate(startTime, yuxinReservationType))
|
||||
.reservationTimeout(getReservationTimeout(dto))
|
||||
.build();
|
||||
}
|
||||
|
||||
@@ -258,26 +96,26 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
||||
return DateUtils.localDateTime2Date(reservedStartDateTime);
|
||||
}
|
||||
|
||||
private int getReservationTimeout(YuxinReservationChargingDTO dto,
|
||||
PileReservationInfo reservationInfo,
|
||||
String yuxinReservationType) {
|
||||
if (StringUtils.equals(yuxinReservationType, YUXIN_RESERVATION_TYPE_CANCEL)) {
|
||||
return 0;
|
||||
}
|
||||
private int getReservationTimeout(YuxinReservationChargingDTO dto) {
|
||||
if (dto.getReservationTimeout() != null) {
|
||||
return Math.min(Math.max(dto.getReservationTimeout(), 0), 0xFF);
|
||||
}
|
||||
LocalTime startTime = reservationInfo.getStartTime().toLocalTime();
|
||||
LocalTime endTime = reservationInfo.getEndTime().toLocalTime();
|
||||
long timeout = Duration.between(startTime, endTime).toMinutes();
|
||||
if (timeout <= 0) {
|
||||
timeout += TimeUnit.DAYS.toMinutes(1);
|
||||
}
|
||||
return (int) Math.min(timeout, 0xFF);
|
||||
return DEFAULT_RESERVATION_TIMEOUT_MINUTES;
|
||||
}
|
||||
|
||||
private String getConnectorCode(PileReservationInfo reservationInfo) {
|
||||
return reservationInfo.getPileConnectorCode().replace(reservationInfo.getPileSn(), "");
|
||||
private BigDecimal getChargingHours(YuxinReservationChargingDTO dto) {
|
||||
LocalTime startTime = parseSqlTime(dto.getStartTime()).toLocalTime();
|
||||
LocalTime endTime = parseSqlTime(dto.getEndTime()).toLocalTime();
|
||||
long timeout = Duration.between(startTime, endTime).toMinutes();
|
||||
if (timeout <= 0) {
|
||||
timeout += Duration.ofDays(1).toMinutes();
|
||||
}
|
||||
return BigDecimal.valueOf(timeout)
|
||||
.divide(BigDecimal.valueOf(60), 2, RoundingMode.HALF_UP);
|
||||
}
|
||||
|
||||
private String getConnectorCode(YuxinReservationChargingDTO dto) {
|
||||
return dto.getPileConnectorCode().replace(dto.getPileSn(), "");
|
||||
}
|
||||
|
||||
private void normalizePileInfo(YuxinReservationChargingDTO dto) {
|
||||
@@ -305,39 +143,6 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
||||
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) {
|
||||
PileBasicInfo pileBasicInfo = pileBasicInfoService.selectPileBasicInfoBySN(pileSn);
|
||||
String programVersion = pileBasicInfo == null ? null : pileBasicInfo.getProgramVersion();
|
||||
@@ -352,33 +157,10 @@ public class YuxinReservationChargingServiceImpl implements YuxinReservationChar
|
||||
ReturnCodeEnum.CODE_UPDATE_RESERVED_STATUS_ERROR.getLabel() + ": 充电桩返回修改失败");
|
||||
}
|
||||
|
||||
private String reservationLogText(PileReservationInfo reservationInfo) {
|
||||
if (reservationInfo == null) {
|
||||
return "null";
|
||||
}
|
||||
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 String reservationLogText(YuxinReservationChargingDTO dto, YuxinReservationChargingCommand command) {
|
||||
return String.format("pileSn=%s,pileConnectorCode=%s,startTime=%s,endTime=%s,chargingStrategy=%s,chargingParam=%s,reservationTimeout=%s",
|
||||
dto.getPileSn(), dto.getPileConnectorCode(), dto.getStartTime(), dto.getEndTime(),
|
||||
command.getChargingStrategy(), command.getChargingParam(), command.getReservationTimeout());
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</resultMap>
|
||||
<sql id="Base_Column_List">
|
||||
<!--@mbg.generated-->
|
||||
id, pile_sn, frame_type, connector_code, pile_connector_code, original_msg, json_msg, create_time
|
||||
id, pile_sn, transaction_code, frame_type, connector_code, pile_connector_code, original_msg, json_msg, create_time
|
||||
</sql>
|
||||
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
|
||||
<!--@mbg.generated-->
|
||||
@@ -154,6 +154,19 @@
|
||||
</select>
|
||||
|
||||
<select id="queryPileFeedList" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from pile_msg_record
|
||||
where pile_sn = #{pileSn,jdbcType=VARCHAR}
|
||||
<if test="frameType != null and frameType != ''">
|
||||
and frame_type = #{frameType,jdbcType=VARCHAR}
|
||||
</if>
|
||||
<if test="transactionCode != null and transactionCode != ''" >
|
||||
and transaction_code = #{transactionCode,jdbcType=VARCHAR}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="queryPileFeedListByJsonTransactionCode" resultMap="BaseResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List" />
|
||||
from pile_msg_record
|
||||
@@ -165,4 +178,23 @@
|
||||
and json_msg->>'$.transactionCode' LIKE CONCAT('%', #{transactionCode}, '%')
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="selectRetentionCutoffId" resultType="java.lang.Long">
|
||||
select id
|
||||
from pile_msg_record
|
||||
where pile_sn = #{pileSn,jdbcType=VARCHAR}
|
||||
and frame_type = #{frameType,jdbcType=VARCHAR}
|
||||
and frame_type != '0x3B'
|
||||
order by id desc
|
||||
limit #{offset}, 1
|
||||
</select>
|
||||
|
||||
<delete id="deleteOldRecordsBeforeId">
|
||||
delete from pile_msg_record
|
||||
where pile_sn = #{pileSn,jdbcType=VARCHAR}
|
||||
and frame_type = #{frameType,jdbcType=VARCHAR}
|
||||
and frame_type != '0x3B'
|
||||
and id < #{cutoffId,jdbcType=BIGINT}
|
||||
limit #{limit}
|
||||
</delete>
|
||||
</mapper>
|
||||
|
||||
@@ -83,17 +83,32 @@ public class JsowellTask {
|
||||
@Autowired
|
||||
private AdapayUnsplitRecordHandleService adapayUnsplitRecordHandleService;
|
||||
|
||||
private static final String PRE_PROFILE = "pre";
|
||||
|
||||
private static final long YKC_DAILY_TIMECHECK_INTERVAL_MILLIS = 200L;
|
||||
|
||||
/**
|
||||
* 设置挡板, PRE环境不执行
|
||||
*/
|
||||
public void setBarrier() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
// return;
|
||||
skipInPre("设置挡板");
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,9 +116,7 @@ public class JsowellTask {
|
||||
* close15MinutesOfUnpaidOrders
|
||||
*/
|
||||
public void close15MinutesOfUnpaidOrders() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("关闭15分钟未支付的订单")) {
|
||||
return;
|
||||
}
|
||||
// log.info("关闭15分钟未支付的订单");
|
||||
@@ -115,10 +128,8 @@ public class JsowellTask {
|
||||
* 订单支付成功,在15分钟内未启动,
|
||||
*/
|
||||
public void closeStartFailedOrder() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
// return;
|
||||
if (skipInPre("关闭启动失败的订单")) {
|
||||
return;
|
||||
}
|
||||
// 查询出最近2天支付成功,并且订单状态为未启动的订单
|
||||
String startTime = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.addDays(new Date(), -2));
|
||||
@@ -130,9 +141,7 @@ public class JsowellTask {
|
||||
* 查询预约充电的订单并启动
|
||||
*/
|
||||
public void appointmentOrderStart() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("查询预约充电的订单并启动")) {
|
||||
return;
|
||||
}
|
||||
// 查询出 已支付 设置预约充电 未启动 的订单
|
||||
@@ -187,9 +196,7 @@ public class JsowellTask {
|
||||
* jsowellTask.dailyProofreadTimeForYkcV160(200)
|
||||
*/
|
||||
public void dailyProofreadTimeForYkcV160(Long intervalMillis) {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("云快充1.6每日自动对时")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -250,9 +257,7 @@ public class JsowellTask {
|
||||
* jsowellTask.calculateTheSiteOrdersReport()
|
||||
*/
|
||||
public void calculateTheSiteOrdersReport() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("计算站点订单报表")) {
|
||||
return;
|
||||
}
|
||||
// 查询出所有站点
|
||||
@@ -279,9 +284,7 @@ public class JsowellTask {
|
||||
* jsowellTask.pushToAMap()
|
||||
*/
|
||||
public void pushToAMap() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("站点的枪口数据推送到高德")) {
|
||||
return;
|
||||
}
|
||||
Set<String> stationIds = redisCache.getCacheSet(CacheConstants.PUSH_STATION_CONNECTOR);
|
||||
@@ -304,9 +307,7 @@ public class JsowellTask {
|
||||
* 贵州省平台推送充电站实时功率 15分钟执行一次
|
||||
*/
|
||||
public void pushStationRealTimePowerInfo() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("贵州省平台推送充电站实时功率")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -344,9 +345,7 @@ public class JsowellTask {
|
||||
* 推送统计信息 24小时执行一次
|
||||
*/
|
||||
public void pushStatisticsInfo() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("推送统计信息 24小时执行一次")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -385,9 +384,7 @@ public class JsowellTask {
|
||||
* jsowellTask.processOrderSplitting()
|
||||
*/
|
||||
public void processOrderSplitting() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("定时任务, 订单分账")) {
|
||||
return;
|
||||
}
|
||||
// 查询运营商列表
|
||||
@@ -424,9 +421,7 @@ public class JsowellTask {
|
||||
*
|
||||
*/
|
||||
public void generateMerchantBill() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("生成运营商日报表")) {
|
||||
return;
|
||||
}
|
||||
// 查询运营商列表
|
||||
@@ -453,9 +448,7 @@ public class JsowellTask {
|
||||
* jsowellTask.automaticPayouts()
|
||||
*/
|
||||
public void automaticPayouts() {
|
||||
String env = SpringUtils.getActiveProfile();
|
||||
if (StringUtils.equalsIgnoreCase(env, "pre")) {
|
||||
log.debug("PRE环境不执行");
|
||||
if (skipInPre("定时任务,自动提现")) {
|
||||
return;
|
||||
}
|
||||
// 查询开启自动提现运营商列表
|
||||
@@ -484,6 +477,9 @@ public class JsowellTask {
|
||||
* jsowellTask.processUnSettledOrder()
|
||||
*/
|
||||
public void processUnSettledOrder() {
|
||||
if (skipInPre("处理未分帐订单")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.processUnSettledOrder();
|
||||
}
|
||||
|
||||
@@ -493,6 +489,9 @@ public class JsowellTask {
|
||||
* jsowellTask.processUnsplitRecordToDefaultMember()
|
||||
*/
|
||||
public void processUnsplitRecordToDefaultMember() {
|
||||
if (skipInPre("处理adapay_unsplit_record待分账数据")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.processUnsplitRecordToDefaultMember();
|
||||
}
|
||||
|
||||
@@ -501,6 +500,9 @@ public class JsowellTask {
|
||||
* jsowellTask.processUnsplitRecordToDefaultMember(wechatAppId, pageSize)
|
||||
*/
|
||||
public void processUnsplitRecordToDefaultMember(String wechatAppId, Integer pageSize) {
|
||||
if (skipInPre("处理adapay_unsplit_record待分账数据")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.processUnsplitRecordToDefaultMember(wechatAppId, pageSize);
|
||||
}
|
||||
|
||||
@@ -515,6 +517,9 @@ public class JsowellTask {
|
||||
* jsowellTask.importAdapayUnsplitRecordAndCompleteFields()
|
||||
*/
|
||||
public void importAdapayUnsplitRecordAndCompleteFields() {
|
||||
if (skipInPre("从Excel导入adapay_unsplit_record并补齐缺失字段")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields();
|
||||
}
|
||||
|
||||
@@ -525,6 +530,9 @@ public class JsowellTask {
|
||||
* 示例:jsowellTask.completeAdapayUnsplitRecordFields('2024-01-01 00:00:00', '2025-12-31 23:59:59')
|
||||
*/
|
||||
public void completeAdapayUnsplitRecordFields(String startTime, String endTime) {
|
||||
if (skipInPre("补齐adapay_unsplit_record表中缺失字段")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.completeAdapayUnsplitRecordFields(startTime, endTime);
|
||||
}
|
||||
|
||||
@@ -533,6 +541,9 @@ public class JsowellTask {
|
||||
* jsowellTask.syncAndRefreshFlagsFromAdapay(paymentId, wechatAppId)
|
||||
*/
|
||||
public void syncAndRefreshFlagsFromAdapay(String paymentId, String wechatAppId) {
|
||||
if (skipInPre("按paymentId从汇付同步并刷新adapay_unsplit_record标识")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.syncAndRefreshFlagsFromAdapay(paymentId, wechatAppId);
|
||||
}
|
||||
|
||||
@@ -542,6 +553,9 @@ public class JsowellTask {
|
||||
* 示例: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) {
|
||||
if (skipInPre("批量从汇付同步并刷新adapay_unsplit_record标识")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.syncAndRefreshFlagsFromAdapay(startTime, endTime, wechatAppId, pageSize);
|
||||
}
|
||||
|
||||
@@ -555,10 +569,16 @@ public class JsowellTask {
|
||||
* jsowellTask.importAdapayUnsplitRecordAndCompleteFields(文件路径)
|
||||
*/
|
||||
public void importAdapayUnsplitRecordAndCompleteFields(String filePath) {
|
||||
if (skipInPre("从Excel导入adapay_unsplit_record并补齐缺失字段")) {
|
||||
return;
|
||||
}
|
||||
adapayUnsplitRecordHandleService.importAdapayUnsplitRecordAndCompleteFields(filePath);
|
||||
}
|
||||
|
||||
public void updateOrderReview() {
|
||||
if (skipInPre("更新订单评价标识")) {
|
||||
return;
|
||||
}
|
||||
LocalDate yesterday = DateUtils.getYesterday();
|
||||
LocalDateTime start = yesterday.atStartOfDay();
|
||||
LocalDateTime end = yesterday.atTime(23, 59, 59);
|
||||
|
||||
BIN
tmp/pdfs/lele_pages/page-1.png
Normal file
BIN
tmp/pdfs/lele_pages/page-1.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 107 KiB |
BIN
tmp/pdfs/lele_pages/page-2.png
Normal file
BIN
tmp/pdfs/lele_pages/page-2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 90 KiB |
BIN
tmp/pdfs/lele_pages/page-3.png
Normal file
BIN
tmp/pdfs/lele_pages/page-3.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 98 KiB |
BIN
tmp/pdfs/lele_pages/page-4.png
Normal file
BIN
tmp/pdfs/lele_pages/page-4.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 19 KiB |
217
tmp/pdfs/lele_reservation_protocol.txt
Normal file
217
tmp/pdfs/lele_reservation_protocol.txt
Normal file
@@ -0,0 +1,217 @@
|
||||
限
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云 乐
|
||||
) ( 享
|
||||
科 广 智
|
||||
技 州 云
|
||||
有 ) (
|
||||
限 科 广
|
||||
公 技 州
|
||||
司 有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
限
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云 乐
|
||||
) ( 享
|
||||
科 广 智
|
||||
技 州 云
|
||||
有 ) (
|
||||
限 科 广
|
||||
公 技 州
|
||||
司 有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
限
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云 乐
|
||||
) ( 享
|
||||
科 广 智
|
||||
技 州 云
|
||||
有 ) (
|
||||
限 科 广
|
||||
公 技 州
|
||||
司 有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
限
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云 乐
|
||||
) ( 享
|
||||
科 广 智
|
||||
技 州 云
|
||||
有 ) (
|
||||
限 科 广
|
||||
公 技 州
|
||||
司 有 )
|
||||
限 科
|
||||
公 技
|
||||
乐 司 有
|
||||
享 限
|
||||
智 公
|
||||
云 乐 司
|
||||
( 享
|
||||
广 智
|
||||
州 云
|
||||
) (
|
||||
科 广
|
||||
技 州
|
||||
有 )
|
||||
限 科
|
||||
公 技
|
||||
司 有
|
||||
限
|
||||
公
|
||||
乐 司
|
||||
享
|
||||
智
|
||||
云 乐
|
||||
|
||||
Reference in New Issue
Block a user