This commit is contained in:
Lemon
2024-07-30 14:19:40 +08:00
44 changed files with 1065 additions and 271 deletions

View File

@@ -3,6 +3,7 @@ package com.jsowell.pile.domain;
import java.sql.Time;
import java.util.Date;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
@@ -14,6 +15,7 @@ import lombok.experimental.SuperBuilder;
@Data
@Accessors(chain = true)
@SuperBuilder
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PileReservationInfo {
@@ -47,6 +49,11 @@ public class PileReservationInfo {
*/
private String reservationType;
/**
* 验证身份(1-是; 0-否)
*/
private String verifyIdentity;
/**
* 预约开始时间
*/

View File

@@ -46,6 +46,11 @@ public class ReservationChargingCommand {
*/
private String reservationType;
/**
* 身份验证
*/
private String verifyIdentity;
/**
* vin1
*/

View File

@@ -40,6 +40,11 @@ public class CreateReservedDTO {
*/
private String freq;
/**
* 验证身份(1-是; 0-否)
*/
private String verifyIdentity;
@Override
public String toString() {
return new ToStringBuilder(this, ToStringStyle.JSON_STYLE)

View File

@@ -0,0 +1,24 @@
package com.jsowell.pile.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class PersonPileStopChargingDTO {
private String memberId;
private String firstLevelMerchantId;
private String pileSn;
private String ConnectorCode;
/**
* 桩枪口号
*/
private String pileConnectorCode;
}

View File

@@ -38,5 +38,5 @@ public class PileMemberBindingDTO {
/**
* 一级运营商id
*/
private String merchantId;
private String firstLevelMerchantId;
}

View File

@@ -23,11 +23,31 @@ public class PileReservationDTO {
*/
private String status;
/**
* 验证身份(1-是; 0-否)
*/
private String verifyIdentity;
/**
* 桩编号
*/
private String pileSn;
/**
* 充电桩枪口编号
*/
private String pileConnectorCode;
/**
* 开始时间 hh:mm:ss
*/
private String startTime;
/**
* 结束时间 hh:mm:ss
*/
private String endTime;
private Integer pageNo;
private Integer pageSize;
@@ -38,6 +58,11 @@ public class PileReservationDTO {
.append("memberId", memberId)
.append("reservedId", reservedId)
.append("status", status)
.append("pileSn", pileSn)
.append("startTime", startTime)
.append("endTime", endTime)
.append("pageNo", pageNo)
.append("pageSize", pageSize)
.toString();
}
}

View File

@@ -0,0 +1,42 @@
package com.jsowell.pile.dto;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class ReservationChargingStartupResult {
/**
* 交易流水号
*/
private String transactionCode;
/**
* 桩编号
*/
private String pileSn;
/**
* 枪口号
*/
private String connectorCode;
/**
* vin
*/
private String vinCode;
/**
* 启动结果
*/
private String startupResult;
/**
* 失败原因
*/
private String failReason;
}

View File

@@ -34,4 +34,6 @@ public interface PileReservationInfoMapper {
List<PileReservationInfo> findByMemberIdAndPileSn(@Param("memberId") String memberId, @Param("pileSn") String pileSn);
PileReservationInfo selectActiveReservationByPileConnectorCode(String pileConnectorCode);
PileReservationInfo selectByPileConnectorCode(String pileConnectorCode);
}

View File

@@ -66,6 +66,8 @@ public interface OrderPileOccupyService{
void stopOccupyPileOrder(OrderPileOccupy orderPileOccupy);
int retryCalculateOccupyPileOrderAmount(String occupyCode);
/**
* 通过memberid查询挂起状态订单
* @param memberId

View File

@@ -3,6 +3,7 @@ package com.jsowell.pile.service;
import java.util.List;
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
import com.jsowell.pile.domain.OrderBasicInfo;
import com.jsowell.pile.domain.PersonalChargingRecord;
public interface PersonalChargingRecordService{
@@ -35,4 +36,6 @@ public interface PersonalChargingRecordService{
* @param data
*/
void processPersonalChargingRecord(TransactionRecordsData data);
void processPersonalChargingRecord(OrderBasicInfo orderBasicInfo);
}

View File

@@ -2,10 +2,7 @@ package com.jsowell.pile.service;
import com.jsowell.common.core.domain.ykc.RealTimeMonitorData;
import com.jsowell.pile.domain.PileBasicInfo;
import com.jsowell.pile.dto.IndexQueryDTO;
import com.jsowell.pile.dto.QueryPileDTO;
import com.jsowell.pile.dto.ReplaceMerchantStationDTO;
import com.jsowell.pile.dto.StartPersonPileDTO;
import com.jsowell.pile.dto.*;
import com.jsowell.pile.thirdparty.ConnectorInfo;
import com.jsowell.pile.thirdparty.EquipmentInfo;
import com.jsowell.pile.thirdparty.ZDLConnectorInfo;
@@ -222,4 +219,6 @@ public interface PileBasicInfoService {
List<ZDLConnectorInfo> getConnectorListForZDL(String pileSn);
String startPersonalPileCharging(StartPersonPileDTO dto);
void startupResult(ReservationChargingStartupResult chargingStartupResult);
}

View File

@@ -72,7 +72,6 @@ public class PileRemoteService {
.build();
ykcPushCommandService.pushGetRealTimeMonitorDataCommand(command);
}
}
/**
@@ -95,7 +94,7 @@ public class PileRemoteService {
log.warn("远程启动充电, 充电桩编号和枪口号不能为空");
return;
}
log.info("=====平台下发指令=====: 远程启动充电, 桩号:{}, 枪口号:{}", pileSn, connectorCode);
log.info("=====平台下发指令=====: 远程启动充电, 桩号:{}, 枪口号:{}", pileSn, connectorCode);
StartChargingCommand startChargingCommand = StartChargingCommand.builder()
.pileSn(pileSn)
.connectorCode(connectorCode)

View File

@@ -2,8 +2,12 @@ package com.jsowell.pile.service;
import java.util.List;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.pile.dto.CreateReservedDTO;
import com.jsowell.pile.dto.PersonPileStopChargingDTO;
import com.jsowell.pile.dto.PileReservationDTO;
import com.jsowell.pile.domain.PileReservationInfo;
import com.jsowell.pile.vo.PileReservationInfoVO;
public interface PileReservationInfoService {
int deleteByPrimaryKey(Integer id);
@@ -55,5 +59,17 @@ public interface PileReservationInfoService {
void cancelOneTimeReservation(String pileConnectorCode);
void deleteReservation(PileReservationDTO dto);
int createReservation(CreateReservedDTO dto);
PageResponse queryReservationList(PileReservationDTO dto);
void updateReservationStatus(PileReservationDTO dto);
void updateReservation(PileReservationDTO dto);
void personPileStopCharging(PersonPileStopChargingDTO dto);
PileReservationInfoVO queryReservationInfo(PileReservationDTO dto);
}

View File

@@ -282,6 +282,26 @@ public class OrderPileOccupyServiceImpl implements OrderPileOccupyService {
orderPileOccupyMapper.updateByPrimaryKeySelective(orderPileOccupy);
}
@Override
public int retryCalculateOccupyPileOrderAmount(String occupyCode) {
OrderPileOccupy orderPileOccupy = queryByOccupyCode(occupyCode);
// 计算金额
BigDecimal orderAmount = calculateOccupyPileOrderAmount(orderPileOccupy);
if (orderAmount.compareTo(BigDecimal.ZERO) > 0) {
// 需要支付金额,订单挂起
orderPileOccupy.setStatus(Constants.TWO); // 2-订单挂起
} else {
// 订单金额为0
orderPileOccupy.setPayStatus(Constants.TWO); // 2-无需支付
orderPileOccupy.setStatus(Constants.ONE); // 1-订单完成
}
orderPileOccupy.setOrderAmount(orderAmount);
// 更新数据库
int i = orderPileOccupyMapper.updateByPrimaryKeySelective(orderPileOccupy);
return i;
}
/**
* 计算占桩订单金额
* calculateTheAmountOfTheOccupancyOrder
@@ -325,8 +345,8 @@ public class OrderPileOccupyServiceImpl implements OrderPileOccupyService {
dto.setStartTime(DateUtils.formatDateTime(startTime));
dto.setEndTime(DateUtils.formatDateTime(endTime));
List<OrderListVO> orderListVOS = orderBasicInfoService.queryOrderByOccupyTime(dto);
log.info("查询会员在占用时段内有没有充电订单, 占桩订单编号:{}, 占桩开始时间:{}, 占桩结束时间:{}, result:{}",
occupyCode, DateUtils.formatDateTime(startTime), DateUtils.formatDateTime(endTime), JSON.toJSONString(orderListVOS));
log.info("查询会员在占用时段内有没有充电订单, 占桩订单编号:{}, memberId:{}, stationId:{}, 占桩开始时间:{}, 占桩结束时间:{}, result:{}",
occupyCode, orderPileOccupy.getMemberId(), orderPileOccupy.getStationId(), DateUtils.formatDateTime(startTime), DateUtils.formatDateTime(endTime), JSON.toJSONString(orderListVOS));
/*
计算充电时长
*/

View File

@@ -1,8 +1,9 @@
package com.jsowell.pile.service.impl;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.domain.ykc.TransactionRecordsData;
import com.jsowell.common.util.Cp56Time2a.Cp56Time2aUtil;
import com.jsowell.common.util.DateUtils;
import com.jsowell.pile.domain.OrderBasicInfo;
import com.jsowell.pile.domain.PileBasicInfo;
import com.jsowell.pile.service.PileBasicInfoService;
import org.springframework.beans.factory.annotation.Autowired;
@@ -82,8 +83,7 @@ public class PersonalChargingRecordServiceImpl implements PersonalChargingRecord
}
/**
* 处理个人桩充电记录
*
* 收到交易记录时, 处理个人桩充电记录
* @param data
*/
@Override
@@ -133,4 +133,48 @@ public class PersonalChargingRecordServiceImpl implements PersonalChargingRecord
personalChargingRecordMapper.insertOrUpdateSelective(chargingRecord);
}
/**
* 一键启动时, 处理个人桩充电记录
* @param orderBasicInfo
*/
@Override
public void processPersonalChargingRecord(OrderBasicInfo orderBasicInfo) {
// 根据交易流水号查询,如果数据库没有就入库
PersonalChargingRecord chargingRecord = new PersonalChargingRecord();
// 处理数据
chargingRecord.setTransactionCode(orderBasicInfo.getTransactionCode());
chargingRecord.setStatus(Constants.ONE);
chargingRecord.setMemberId(orderBasicInfo.getMemberId());
chargingRecord.setStationId(orderBasicInfo.getStationId());
chargingRecord.setMerchantId(orderBasicInfo.getMerchantId());
chargingRecord.setPileSn(orderBasicInfo.getPileSn());
chargingRecord.setConnectorCode(orderBasicInfo.getConnectorCode());
chargingRecord.setPileConnectorCode(orderBasicInfo.getPileConnectorCode());
chargingRecord.setLogicCard(orderBasicInfo.getLogicCard());
chargingRecord.setVinCode(orderBasicInfo.getVinCode());
chargingRecord.setStartMode(orderBasicInfo.getStartMode());
chargingRecord.setPlateNumber(orderBasicInfo.getPlateNumber());
chargingRecord.setChargeStartTime(orderBasicInfo.getChargeStartTime());
chargingRecord.setChargeEndTime(orderBasicInfo.getChargeEndTime());
chargingRecord.setStartType(orderBasicInfo.getStartType());
chargingRecord.setReservationStartTime(orderBasicInfo.getReservedStartTime());
chargingRecord.setReservationEndTime(orderBasicInfo.getReservedEndTime());
chargingRecord.setStartSoc(orderBasicInfo.getStartSoc());
chargingRecord.setEndSoc(null);
// BigDecimal sharpUsedElectricity = new BigDecimal(data.getSharpUsedElectricity());
// chargingRecord.setSharpUsedElectricity(sharpUsedElectricity);
// BigDecimal peakUsedElectricity = new BigDecimal(data.getPeakUsedElectricity());
// chargingRecord.setPeakUsedElectricity(peakUsedElectricity);
// BigDecimal flatUsedElectricity = new BigDecimal(data.getFlatUsedElectricity());
// chargingRecord.setFlatUsedElectricity(flatUsedElectricity);
// BigDecimal valleyUsedElectricity = new BigDecimal(data.getValleyUsedElectricity());
// chargingRecord.setValleyUsedElectricity(valleyUsedElectricity);
// BigDecimal totalUsedElectricity = sharpUsedElectricity.add(peakUsedElectricity).add(flatUsedElectricity).add(valleyUsedElectricity);
// chargingRecord.setTotalUsedElectricity(totalUsedElectricity);
// chargingRecord.setReason(data.getStopReasonMsg());
// 创建或更新
personalChargingRecordMapper.insertOrUpdateSelective(chargingRecord);
}
}

View File

@@ -18,10 +18,7 @@ import com.jsowell.pile.domain.PileBasicInfo;
import com.jsowell.pile.domain.PileConnectorInfo;
import com.jsowell.pile.domain.PileModelInfo;
import com.jsowell.pile.domain.PileSimInfo;
import com.jsowell.pile.dto.IndexQueryDTO;
import com.jsowell.pile.dto.QueryPileDTO;
import com.jsowell.pile.dto.ReplaceMerchantStationDTO;
import com.jsowell.pile.dto.StartPersonPileDTO;
import com.jsowell.pile.dto.*;
import com.jsowell.pile.mapper.PileBasicInfoMapper;
import com.jsowell.pile.service.*;
import com.jsowell.pile.service.programlogic.AbstractProgramLogic;
@@ -37,6 +34,7 @@ import com.jsowell.pile.vo.uniapp.customer.GroundLockInfoVO;
import com.jsowell.pile.vo.uniapp.customer.PersonalPileInfoVO;
import com.jsowell.pile.vo.uniapp.customer.PileConnectorDetailVO;
import com.jsowell.pile.vo.web.*;
import com.jsowell.wxpay.service.WxAppletRemoteService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.RandomStringUtils;
@@ -89,6 +87,9 @@ public class PileBasicInfoServiceImpl implements PileBasicInfoService {
@Autowired
private PileReservationInfoService pileReservationInfoService;
@Autowired
private WxAppletRemoteService wxAppletRemoteService;
/**
* 查询设备管理
*
@@ -1211,4 +1212,13 @@ public class PileBasicInfoServiceImpl implements PileBasicInfoService {
String orderCode = orderLogic.startPersonalPileCharging(dto);
return orderCode;
}
/**
* 预约充电启动结果
*/
@Override
public void startupResult(ReservationChargingStartupResult chargingStartupResult) {
// 小程序通知
wxAppletRemoteService.reservationStartupResultSendMsg();
}
}

View File

@@ -1,6 +1,8 @@
package com.jsowell.pile.service.impl;
import com.google.common.collect.Lists;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.PileMemberRelation;
import com.jsowell.pile.mapper.PileMemberRelationMapper;
import com.jsowell.pile.service.PileConnectorInfoService;
@@ -108,10 +110,12 @@ public class PileMemberRelationServiceImpl implements PileMemberRelationService
@Override
public List<PileMemberRelation> selectPileMemberRelationByPileSn(String pileSn) {
if (StringUtils.isBlank(pileSn)) {
return Lists.newArrayList();
}
PileMemberRelation pileMemberRelation = new PileMemberRelation();
pileMemberRelation.setPileSn(pileSn);
return selectPileMemberRelationList(pileMemberRelation);
}
}

View File

@@ -1,18 +1,26 @@
package com.jsowell.pile.service.impl;
import com.alibaba.fastjson2.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.jsowell.common.constant.CacheConstants;
import com.jsowell.common.constant.Constants;
import com.jsowell.common.core.page.PageResponse;
import com.jsowell.common.core.redis.RedisCache;
import com.jsowell.common.enums.DelFlagEnum;
import com.jsowell.common.enums.ykc.ReturnCodeEnum;
import com.jsowell.common.exception.BusinessException;
import com.jsowell.common.util.DateUtils;
import com.jsowell.common.util.StringUtils;
import com.jsowell.pile.domain.PileMemberRelation;
import com.jsowell.pile.domain.ykcCommond.ReservationChargingCommand;
import com.jsowell.pile.dto.CreateReservedDTO;
import com.jsowell.pile.dto.PersonPileStopChargingDTO;
import com.jsowell.pile.dto.PileReservationDTO;
import com.jsowell.pile.dto.StartPersonPileDTO;
import com.jsowell.pile.service.MemberPlateNumberRelationService;
import com.jsowell.pile.service.PileBasicInfoService;
import com.jsowell.pile.service.PileRemoteService;
import com.jsowell.pile.service.*;
import com.jsowell.pile.vo.PileReservationInfoVO;
import com.jsowell.pile.vo.uniapp.customer.MemberPlateNumberVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
@@ -20,15 +28,17 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.sql.Date;
import java.sql.Time;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
import com.jsowell.pile.mapper.PileReservationInfoMapper;
import com.jsowell.pile.domain.PileReservationInfo;
import com.jsowell.pile.service.PileReservationInfoService;
@Slf4j
@Service
@@ -46,6 +56,12 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
@Autowired
private MemberPlateNumberRelationService memberPlateNumberRelationService;
@Autowired
private PileMemberRelationService pileMemberRelationService;
@Autowired
private RedisCache redisCache;
@Override
public int deleteByPrimaryKey(Integer id) {
return pileReservationInfoMapper.deleteByPrimaryKey(id);
@@ -63,6 +79,11 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
@Override
public int insertOrUpdateSelective(PileReservationInfo record) {
if (record.getId() == null) {
record.setCreateTime(DateUtils.getNowDate());
} else {
record.setUpdateTime(DateUtils.getNowDate());
}
return pileReservationInfoMapper.insertOrUpdateSelective(record);
}
@@ -106,24 +127,28 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
return pileReservationInfoMapper.findByMemberIdAndPileSn(memberId, pileSn);
}
public PileReservationInfo selectByPileConnectorCode(String pileConnectorCode) {
return pileReservationInfoMapper.selectByPileConnectorCode(pileConnectorCode);
}
/**
* 启用预约/开启预约/启动预约
*/
@Override
public void activateReserved(PileReservationDTO dto) {
// 查询其他生效中的预约
List<PileReservationInfo> infoList = pileReservationInfoMapper.findByMemberIdAndPileSnAndStatus(dto.getMemberId(), dto.getPileSn(), "1");
if (CollectionUtils.isNotEmpty(infoList)) {
throw new BusinessException(ReturnCodeEnum.CODE_RESERVATION_ALREADY_EXISTS_ERROR);
}
// List<PileReservationInfo> infoList = pileReservationInfoMapper.findByMemberIdAndPileSnAndStatus(dto.getMemberId(), dto.getPileSn(), "1");
// if (CollectionUtils.isNotEmpty(infoList)) {
// throw new BusinessException(ReturnCodeEnum.CODE_RESERVATION_ALREADY_EXISTS_ERROR);
// }
PileReservationInfo pileReservationInfo = pileReservationInfoMapper.selectByPrimaryKey(Integer.parseInt(dto.getReservedId()));
if (pileReservationInfo == null) {
return;
}
if (!StringUtils.equals(dto.getMemberId(), pileReservationInfo.getMemberId())) {
return;
}
// if (!StringUtils.equals(dto.getMemberId(), pileReservationInfo.getMemberId())) {
// return;
// }
pileReservationInfo.setStatus(Constants.ONE);
// 保存之前,校验时间是否重叠
int i = saveReservation(pileReservationInfo);
@@ -151,6 +176,7 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
.connectorCode(pileReservationInfo.getPileConnectorCode().replace(pileReservationInfo.getPileSn(), ""))
.operation("01")
.reservationType(type)
.verifyIdentity(pileReservationInfo.getVerifyIdentity())
.vin1(vinCodes.get(0))
.vin2(vinCodes.get(1))
.vin3(vinCodes.get(2))
@@ -171,9 +197,9 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
if (pileReservationInfo == null) {
return;
}
if (!StringUtils.equals(dto.getMemberId(), pileReservationInfo.getMemberId())) {
return;
}
// if (!StringUtils.equals(dto.getMemberId(), pileReservationInfo.getMemberId())) {
// return;
// }
// 校验通过可以修改预约
pileReservationInfo.setStatus(Constants.ZERO);
int i = pileReservationInfoMapper.updateByPrimaryKeySelective(pileReservationInfo);
@@ -201,6 +227,7 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
.connectorCode(pileReservationInfo.getPileConnectorCode().replace(pileReservationInfo.getPileSn(), ""))
.operation("02")
.reservationType(type)
.verifyIdentity(pileReservationInfo.getVerifyIdentity())
.vin1(vinCodes.get(0))
.vin2(vinCodes.get(1))
.vin3(vinCodes.get(2))
@@ -291,5 +318,217 @@ public class PileReservationInfoServiceImpl implements PileReservationInfoServic
pileReservationInfo.setDelFlag(DelFlagEnum.DELETE.getValue());
pileReservationInfoMapper.updateByPrimaryKey(pileReservationInfo);
}
@Override
public int createReservation(CreateReservedDTO dto) {
PileReservationInfo reservedInfo = selectByPileConnectorCode(dto.getPileConnectorCode());
if (reservedInfo == null) {
reservedInfo = new PileReservationInfo();
reservedInfo.setCreateBy(dto.getMemberId());
} else {
reservedInfo.setUpdateBy(dto.getMemberId());
}
reservedInfo.setMemberId(dto.getMemberId());
reservedInfo.setPileSn(dto.getPileSn());
reservedInfo.setPileConnectorCode(dto.getPileConnectorCode());
reservedInfo.setStatus(Constants.ONE); // 默认生效
// reservedInfo.setStartTime(DateUtils.parseDate(dto.getStartTime()));
reservedInfo.setStartTime(Time.valueOf(dto.getStartTime()));
// reservedInfo.setEndTime(DateUtils.parseDate(dto.getEndTime()));
if (StringUtils.isNotBlank(dto.getEndTime())) {
reservedInfo.setEndTime(Time.valueOf(dto.getEndTime()));
}
// 2024年7月25日14点36分, 此段代码注释掉, 采用默认设置
// if (StringUtils.isNotBlank(dto.getFreq())) {
// reservedInfo.setReservationType("recurring");
// reservedInfo.setFreq(dto.getFreq());
// } else {
// reservedInfo.setReservationType("single");
// reservedInfo.setFreq(null);
// }
// 默认每天
reservedInfo.setReservationType("recurring");
reservedInfo.setFreq("daily");
this.insertOrUpdateSelective(reservedInfo);
return reservedInfo.getId();
}
@Override
public PageResponse queryReservationList(PileReservationDTO dto) {
int pageNo = dto.getPageNo() == null ? Constants.one : dto.getPageNo();
int pageSize = dto.getPageSize() == null ? 10 : dto.getPageSize();
PageHelper.startPage(pageNo, pageSize);
List<PileReservationInfo> list = this.getReservationsByMemberIdAndPileSn(dto.getMemberId(), dto.getPileSn());
PageInfo<PileReservationInfo> pageInfo = new PageInfo<>(list);
PageResponse pageResponse = new PageResponse();
pageResponse.setPageNum(pageInfo.getPageNum());
pageResponse.setPageSize(pageInfo.getPageSize());
pageResponse.setPages(pageInfo.getPages());
pageResponse.setTotal(pageInfo.getTotal());
List<PileReservationInfoVO> resultList = Lists.newArrayList();
for (PileReservationInfo reservedInfo : pageInfo.getList()) {
resultList.add(
PileReservationInfoVO.builder()
// .reservationId(reservedInfo.getId() + "")
.pileSn(reservedInfo.getPileSn())
.startTime(reservedInfo.getStartTime().toString())
.endTime(reservedInfo.getEndTime().toString())
// .freq(reservedInfo.getFreq())
.status(reservedInfo.getStatus())
.build()
);
}
pageResponse.setList(resultList);
return pageResponse;
}
/**
* 修改预约状态
* @param dto
*/
@Override
public void updateReservationStatus(PileReservationDTO dto) {
if (StringUtils.equals(dto.getStatus(), Constants.ZERO)) {
// 停用
this.deactivateReserved(dto);
} else if (StringUtils.equals(dto.getStatus(), Constants.ONE)) {
// 启用
this.activateReserved(dto);
}
}
/**
* 修改预约充电信息
* @param dto
*/
@Override
public void updateReservation(PileReservationDTO dto) {
PileReservationInfo pileReservationInfo = pileReservationInfoMapper.selectByPrimaryKey(Integer.valueOf(dto.getReservedId()));
if (pileReservationInfo == null) {
return;
}
/**
* 操作
* 0x01:启动 0x02:取消 0x03:修改
*/
String operation = "03";
if (StringUtils.isNotBlank(dto.getStartTime())) {
pileReservationInfo.setStartTime(Time.valueOf(dto.getStartTime()));
operation = "03";
}
if (StringUtils.isNotBlank(dto.getEndTime())) {
pileReservationInfo.setEndTime(Time.valueOf(dto.getEndTime()));
operation = "03";
}
if (StringUtils.isNotBlank(dto.getStatus())) {
pileReservationInfo.setStatus(dto.getStatus());
if (StringUtils.equals(dto.getStatus(), Constants.ZERO)) {
// 停用
operation = "02";
} else if (StringUtils.equals(dto.getStatus(), Constants.ONE)) {
// 启用
operation = "01";
}
}
if (StringUtils.isNotBlank(dto.getVerifyIdentity())) {
pileReservationInfo.setVerifyIdentity(dto.getVerifyIdentity());
}
pileReservationInfo.setUpdateBy(dto.getMemberId());
this.insertOrUpdateSelective(pileReservationInfo);
// 查询会员的绑定vin列表 2024年7月30日11点04分 以当前请求会员的VIN为准
List<MemberPlateNumberVO> plateNumberVOList = memberPlateNumberRelationService.selectMemberPlateNumberRelation(dto.getMemberId());
List<String> vinCodes = Lists.newArrayList();
int count = 0;
for (MemberPlateNumberVO vo : plateNumberVOList) {
if (count < 3 && StringUtils.isNotBlank(vo.getVinCode())) {
vinCodes.add(vo.getVinCode());
count++;
}
}
// 如果 vinCodes 的数量少于 3用 "0" 补足
while (vinCodes.size() < 3) {
vinCodes.add("");
}
String type = StringUtils.equals(pileReservationInfo.getReservationType(), "single") ? "00" : "01";
// 发送指令
ReservationChargingCommand command = ReservationChargingCommand.builder()
.transactionCode(Constants.ILLEGAL_TRANSACTION_CODE)
.pileSn(pileReservationInfo.getPileSn())
.connectorCode(pileReservationInfo.getPileConnectorCode().replace(pileReservationInfo.getPileSn(), ""))
.operation(operation)
.reservationType(type)
.verifyIdentity(pileReservationInfo.getVerifyIdentity())
.vin1(vinCodes.get(0))
.vin2(vinCodes.get(1))
.vin3(vinCodes.get(2))
.reservedStartTime(pileReservationInfo.getStartTime().toLocalTime())
.reservedEndTime(pileReservationInfo.getEndTime().toLocalTime())
.amount(Constants.WHITELIST_DEFAULT_AMOUNT)
.build();
pileRemoteService.reservationCharging(command);
}
/**
* 个人桩停止充电
* @param dto
*/
@Override
public void personPileStopCharging(PersonPileStopChargingDTO dto) {
String pileConnectorCode = dto.getPileConnectorCode();
String pileSn = StringUtils.substring(pileConnectorCode, 0, pileConnectorCode.length() - 2);
String connectorCode = StringUtils.substring(pileConnectorCode, pileConnectorCode.length() - 2, pileConnectorCode.length());
// 查询个人桩信息
List<PileMemberRelation> pileMemberRelations = pileMemberRelationService.selectPileMemberRelationByPileSn(pileSn);
Map<String, List<String>> listMap = pileMemberRelations.stream()
.collect(Collectors.groupingBy(PileMemberRelation::getType, Collectors.mapping(PileMemberRelation::getMemberId, Collectors.toList())));
log.info("个人桩:{}, 使用者信息:{}", pileConnectorCode, JSON.toJSONString(listMap));
// 发送请求的用户有没有权限停止充电
boolean stopFlag = false;
List<String> pileManager = listMap.get("1");
List<String> pileUsers = listMap.get("2");
if (CollectionUtils.isNotEmpty(pileManager) && CollectionUtils.containsAny(pileManager, dto.getMemberId())) {
log.info("memberId:() 为管理员");
stopFlag = true;
}
if (CollectionUtils.isNotEmpty(pileUsers) && CollectionUtils.containsAny(pileUsers, dto.getMemberId())) {
log.info("memberId:() 为用户");
stopFlag = true;
}
if (stopFlag) {
String pileIsChargingKey = CacheConstants.PILE_IS_CHARGING + pileSn + connectorCode;
String redisResult = redisCache.getCacheObject(pileIsChargingKey);
// 发送停止充电指令
log.info("发送停止指令, pileSn:{}, connectorCode:{}, transactionCode:{}", pileSn, connectorCode, redisResult);
pileRemoteService.remoteStopCharging(pileSn, connectorCode, redisResult);
}
}
@Override
public PileReservationInfoVO queryReservationInfo(PileReservationDTO dto) {
PileReservationInfo pileReservationInfo = pileReservationInfoMapper.selectByPileConnectorCode(dto.getPileConnectorCode());
PileReservationInfoVO build = PileReservationInfoVO.builder()
.reservedId(pileReservationInfo.getId() + "")
.pileSn(pileReservationInfo.getPileSn())
.pileConnectorCode(pileReservationInfo.getPileConnectorCode())
.startTime(pileReservationInfo.getStartTime().toString())
.endTime(pileReservationInfo.getEndTime().toString())
.verifyIdentity(pileReservationInfo.getVerifyIdentity())
// .freq(pileReservationInfo.getFreq())
.status(pileReservationInfo.getStatus())
.build();
return build;
}
}

View File

@@ -20,7 +20,6 @@ import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.aspectj.weaver.ast.Var;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -59,7 +58,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
YKCUtils.frameType2Str(YKCFrameTypeCode.REMOTE_RESTART_CODE.getBytes()),
YKCUtils.frameType2Str(YKCFrameTypeCode.REMOTE_CONTROL_START_CODE.getBytes()),
YKCUtils.frameType2Str(YKCFrameTypeCode.REMOTE_STOP_CHARGING_CODE.getBytes()),
YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVE_CHARGING_CODE.getBytes())
YKCUtils.frameType2Str(YKCFrameTypeCode.RESERVATION_CHARGING_CODE.getBytes())
);
/**
@@ -183,7 +182,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
}
/**
* 发送停止ch
* 发送停止充电
*
* @param command
*/
@@ -254,7 +253,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
// push消息
boolean result = this.push(msg, pileSn, YKCFrameTypeCode.REMOTE_ISSUE_QRCODE_CODE);
log.info("=====平台下发指令===== pileSn:{}, 下发二维码,地址为:{}", pileSn, qrCodePrefix);
log.info("=====平台下发指令===== pileSn:{}, 下发二维码,地址为:{}", pileSn, qrCodePrefix);
}
/**
@@ -330,7 +329,7 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
// 额定功率
String ratedPower = pileModelInfoVO.getRatedPower();
int i = Integer.parseInt(ratedPower);
// int i = Integer.parseInt(ratedPower);
// byte[] ratedPowerByteArr = Base64.getDecoder().decode(ratedPower);
byte[] ratedPowerByteArr = BytesUtil.ensureLength(Constants.zeroByteArray, 2);
@@ -506,6 +505,10 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
String reservationType = command.getReservationType();
byte[] reservationTypeByteArr = BytesUtil.str2Bcd(reservationType);
// 身份验证
String verifyIdentity = command.getVerifyIdentity();
byte[] verifyIdentityByteArr = BytesUtil.str2Bcd(verifyIdentity);
// VIN1
String vin1 = command.getVin1();
byte[] vin1ByteArr = BytesUtil.str2Asc(vin1);
@@ -533,12 +536,12 @@ public class YKCPushCommandServiceImpl implements YKCPushCommandService {
// 拼装msg信息
byte[] msg = Bytes.concat(transactionCodeArr, pileSnByteArr, connectorCodeByteArr, operateByteArr,
reservationTypeByteArr, vin1ByteArr, vin2ByteArr, vin3ByteArr,
reservationTypeByteArr, verifyIdentityByteArr, vin1ByteArr, vin2ByteArr, vin3ByteArr,
reservedStartTimeByteArr, reservedEndTimeByteArr, amountByteArr);
this.push(msg, pileSn, YKCFrameTypeCode.RESERVE_CHARGING_CODE);
this.push(msg, pileSn, YKCFrameTypeCode.RESERVATION_CHARGING_CODE);
log.info("=====平台下发指令=====: 预约充电指令, 交易流水号:{}, 桩编号:{}, 枪口号:{}, 操作:{}, 开始时间:{}, 结束时间:{}, 启动金额:{}",
transactionCode, pileSn, connectorCode, operation, DateUtils.formatDateTime(reservedStartTime), DateUtils.formatDateTime(reservedEndTime), amount);
log.info("=====平台下发指令=====: 预约充电指令, 交易流水号:{}, 桩编号:{}, 枪口号:{}, 操作:{}, 身份验证:{}, 开始时间:{}, 结束时间:{}, 启动金额:{}",
transactionCode, pileSn, connectorCode, operation, verifyIdentity, DateUtils.formatDateTime(reservedStartTime), DateUtils.formatDateTime(reservedEndTime), amount);
}
}

View File

@@ -105,7 +105,10 @@ public abstract class AbstractProgramLogic implements InitializingBean {
protected MemberGroupService memberGroupService;
@Autowired
private PileStationWhitelistService pileStationWhitelistService;
protected PileStationWhitelistService pileStationWhitelistService;
@Autowired
protected PersonalChargingRecordService personalChargingRecordService;
@Autowired
protected RedisCache redisCache;
@@ -475,6 +478,10 @@ public abstract class AbstractProgramLogic implements InitializingBean {
BigDecimal tempAmount = new BigDecimal(orderAmount.toString()); // 临时金额
for (OrderPayRecord record : payRecordList) {
if (!StringUtils.equals(record.getPayMode(), OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue())) {
// 不是本金支付, 进行下一个循环
continue;
}
List<PaymentInfo> paymentInfos = orderPayRecordService.parseDeductionRecord(record.getDeductionRecord());
for (PaymentInfo object : paymentInfos) {
String paymentId = object.getPaymentId();

View File

@@ -718,7 +718,8 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
// 查支付记录
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
// 根据payMode分组
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream().collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream()
.collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
// 获取本金支付的记录
List<OrderPayRecord> principalPayRecordList = payRecordMap.get(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue());
BigDecimal principalPay = null;
@@ -737,7 +738,7 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
// 计算需要退回的金额
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount, discountAmount);
logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}",
orderCode, orderAmount, principalPay, null, JSON.toJSONString(returnAmountMap));
orderCode, orderAmount, principalPay, giftPay, JSON.toJSONString(returnAmountMap));
// 需要退回本金的金额
BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal");
@@ -843,7 +844,7 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
if (!b) {
throw new BusinessException("00600006", "个人桩启动失败,无启动权限");
}
String orderCode;
// 生成订单
GenerateOrderDTO generateOrderDTO = new GenerateOrderDTO();
generateOrderDTO.setMemberId(dto.getMemberId());
@@ -852,18 +853,28 @@ public class DelayMerchantProgramLogic extends AbstractProgramLogic {
generateOrderDTO.setStartType(dto.getStartType());
generateOrderDTO.setPileSn(pileSn);
generateOrderDTO.setConnectorCode(connectorCode);
OrderBasicInfo orderBasicInfo;
try {
OrderBasicInfo orderBasicInfo = generateOrder(generateOrderDTO);
orderCode = orderBasicInfo.getOrderCode();
orderBasicInfo = generateOrder(generateOrderDTO);
} catch (ParseException e) {
throw new RuntimeException(e);
}
// 支付订单
PayOrderDTO payOrderDTO = new PayOrderDTO();
payOrderDTO.setOrderCode(orderCode);
payOrderDTO.setOrderCode(orderBasicInfo.getOrderCode());
payOrderDTO.setPayMode(OrderPayModeEnum.PAYMENT_OF_WHITELIST.getValue());
payOrderDTO.setMemberId(dto.getMemberId());
payOrder(payOrderDTO);
return orderCode;
// 插入个人桩充电记录表
try {
personalChargingRecordService.processPersonalChargingRecord(orderBasicInfo);
} catch (Exception e) {
logger.error("插入个人桩充电记录表error, orderCode:{}, transactionCode:{}",
orderBasicInfo.getOrderCode(), orderBasicInfo.getTransactionCode());
}
return orderBasicInfo.getOrderCode();
}
}

View File

@@ -687,24 +687,35 @@ public class NotDelayMerchantProgramLogic extends AbstractProgramLogic {
// 查支付记录
List<OrderPayRecord> payRecordList = orderPayRecordService.getOrderPayRecordList(orderCode);
Map<String, OrderPayRecord> payRecordMap = payRecordList.stream()
.collect(Collectors.toMap(OrderPayRecord::getPayMode, Function.identity(), (k1, k2) -> k1));
// 取出本金支付金额
BigDecimal principalPay = null;
// 根据payMode分组
Map<String, List<OrderPayRecord>> payRecordMap = payRecordList.stream()
.collect(Collectors.groupingBy(OrderPayRecord::getPayMode));
// 获取本金支付的记录
OrderPayRecord principalPayRecord = payRecordMap.get(Constants.ONE);
if (principalPayRecord != null) {
principalPay = principalPayRecord.getPayAmount();
List<OrderPayRecord> principalPayRecordList = payRecordMap.get(OrderPayRecordEnum.PRINCIPAL_BALANCE_PAYMENT.getValue());
BigDecimal principalPay = null;
if (CollectionUtils.isNotEmpty(principalPayRecordList)) {
principalPay = principalPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
}
// 获取赠送金支付的记录
List<OrderPayRecord> giftPayRecordList = payRecordMap.get(OrderPayRecordEnum.GIFT_BALANCE_PAYMENT.getValue());
BigDecimal giftPay = null;
if (CollectionUtils.isNotEmpty(giftPayRecordList)) {
giftPay = giftPayRecordList.stream().map(OrderPayRecord::getPayAmount).reduce(BigDecimal.ZERO, BigDecimal::add);
}
BigDecimal discountAmount = orderBasicInfo.getDiscountAmount() == null ? BigDecimal.ZERO : orderBasicInfo.getDiscountAmount();
// 计算需要退回的金额
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, null, orderAmount);
Map<String, BigDecimal> returnAmountMap = calculateReturnAmount(principalPay, giftPay, orderAmount, discountAmount);
logger.info("结算订单:{}, 剩余金额退回余额, 订单消费金额:{}, 本金支付金额:{}, 赠送支付金额:{}, 退回金额map:{}",
orderCode, orderAmount, principalPay, null, JSON.toJSONString(returnAmountMap));
orderCode, orderAmount, principalPay, giftPay, JSON.toJSONString(returnAmountMap));
// 需要退回本金的金额
BigDecimal returnPrincipal = returnAmountMap.get("returnPrincipal");
// 需要退回赠送金的金额
BigDecimal returnGift = returnAmountMap.get("returnGift");
// 更新会员钱包/余额退回到钱包
UpdateMemberBalanceDTO updateMemberBalanceDTO = UpdateMemberBalanceDTO.builder()
@@ -712,6 +723,7 @@ public class NotDelayMerchantProgramLogic extends AbstractProgramLogic {
.type(MemberWalletEnum.TYPE_IN.getValue()) // 进账
.subType(MemberWalletEnum.SUBTYPE_ORDER_SETTLEMENT_REFUND.getValue()) // 订单结算退款
.updatePrincipalBalance(returnPrincipal)
.updateGiftBalance(returnGift)
.relatedOrderCode(orderCode)
.build();
memberBasicInfoService.updateMemberBalance(updateMemberBalanceDTO);

View File

@@ -7,7 +7,7 @@ import lombok.Setter;
@Getter
@Setter
@Builder
public class PileReservedVO {
public class PileReservationInfoVO {
private String reservedId;
/**
@@ -15,6 +15,11 @@ public class PileReservedVO {
*/
private String pileSn;
/**
* 充电桩枪口编号
*/
private String pileConnectorCode;
/**
* 预约开始时间
*/
@@ -28,11 +33,16 @@ public class PileReservedVO {
/**
* 周期性预约的频率对于单次预约该字段可以为 NULL可能的值包括 daily, weekly, monthly
*/
private String freq;
// private String freq;
/**
* 状态0-未生效1-生效
*/
private String status;
/**
* 验证身份(1-; 0-)
*/
private String verifyIdentity;
}

View File

@@ -45,4 +45,14 @@ public class PersonPileRealTimeVO {
* 实时功率
*/
private String instantPower;
/**
* 枪口状态
*/
private String status;
/**
* soc
*/
private String soc;
}

View File

@@ -72,19 +72,14 @@ public class WxAppletRemoteService {
@Value("${weixin.sendMsg.stopChargingTmpId}")
private String stopChargingTmpId;
@Value("${weixin.sendMsg.startupResultTmpId}")
private String startupResultTmpId;
/**
* 获取accessToken
*
* @return
*/
public String getAccessToken() {
// String appid = Constants.APP_ID;
// String secret = Constants.APP_SECRET;
// 这里我是从配置文件中取得appid和appsecret
// appid = properties.getAppId();
// secret = properties.getAppSecret();
//查询token是否存在
String redisKey = CacheConstants.ACCESS_TOKEN + appid;
// 使用缓存先查询AccessToken是否存在
@@ -236,7 +231,6 @@ public class WxAppletRemoteService {
return uniAppSendMsg(msgInfo);
}
/**
* 停止充电发送消息
* @param dto
@@ -281,7 +275,15 @@ public class WxAppletRemoteService {
}
/**
* 小程序发送消息方法
* 预约充电结果小程序服务通知
*/
public Map<String, String> reservationStartupResultSendMsg() {
AppletTemplateMessageSendDTO msgInfo = new AppletTemplateMessageSendDTO();
return uniAppSendMsg(msgInfo);
}
/**
* 小程序发送消息方法/小程序通知/服务通知
* @param dto
* @return
*/