| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469 |
- package com.zsElectric.boot.thirdParty.service.impl;
- import cn.hutool.core.util.IdUtil;
- import cn.hutool.core.util.ObjectUtil;
- import cn.hutool.core.util.StrUtil;
- import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
- import com.baomidou.mybatisplus.core.metadata.IPage;
- import com.baomidou.mybatisplus.core.toolkit.Wrappers;
- import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
- import com.fasterxml.jackson.databind.ObjectMapper;
- import com.zsElectric.boot.business.mapper.RechargeLevelMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyEquipmentInfoMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyInfoMapper;
- import com.zsElectric.boot.business.mapper.ThirdPartyStationInfoMapper;
- import com.zsElectric.boot.business.model.vo.applet.AppletConnectorDetailVO;
- import com.zsElectric.boot.charging.mapper.ThirdPartyConnectorInfoMapper;
- import com.zsElectric.boot.business.mapper.UserAccountMapper;
- import com.zsElectric.boot.business.mapper.UserOrderInfoMapper;
- import com.zsElectric.boot.business.model.entity.RechargeLevel;
- import com.zsElectric.boot.business.model.entity.ThirdPartyInfo;
- import com.zsElectric.boot.business.model.entity.UserAccount;
- import com.zsElectric.boot.business.model.entity.UserInfo;
- import com.zsElectric.boot.business.model.entity.UserOrderInfo;
- import com.zsElectric.boot.business.model.query.StationInfoQuery;
- import com.zsElectric.boot.business.model.vo.AppletStationDetailVO;
- import com.zsElectric.boot.business.model.vo.StationInfoVO;
- import com.zsElectric.boot.charging.entity.ThirdPartyConnectorInfo;
- import com.zsElectric.boot.charging.entity.ThirdPartyEquipmentInfo;
- import com.zsElectric.boot.charging.entity.ThirdPartyStationInfo;
- import com.zsElectric.boot.business.service.UserInfoService;
- import com.zsElectric.boot.business.service.UserAccountService;
- import com.zsElectric.boot.business.service.ChargeOrderInfoService;
- import com.zsElectric.boot.business.model.form.applet.AppInvokeChargeForm;
- import com.zsElectric.boot.business.model.form.applet.AppStopChargeForm;
- import com.zsElectric.boot.business.model.vo.applet.AppChargeVO;
- import com.zsElectric.boot.common.constant.SystemConstants;
- import com.zsElectric.boot.common.util.AESCryptoUtils;
- import com.zsElectric.boot.common.util.HmacMD5Util;
- import com.zsElectric.boot.thirdParty.model.*;
- import com.zsElectric.boot.thirdParty.service.ThirdPartyTokenService;
- import lombok.RequiredArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.data.redis.core.RedisTemplate;
- import org.springframework.stereotype.Service;
- import org.springframework.transaction.annotation.Transactional;
- import java.math.BigDecimal;
- import java.time.LocalDateTime;
- import java.time.LocalTime;
- import java.time.format.DateTimeFormatter;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import java.util.concurrent.TimeUnit;
- import java.util.stream.Collectors;
- /**
- * 第三方Token服务实现类
- *
- * @author wzq
- */
- @Slf4j
- @Service
- @RequiredArgsConstructor
- public class ThirdPartyTokenServiceImpl implements ThirdPartyTokenService {
- private final ThirdPartyInfoMapper thirdPartyInfoMapper;
- private final RechargeLevelMapper rechargeLevelMapper;
- private final RedisTemplate<String, Object> redisTemplate;
- private final UserInfoService userInfoService;
- private final UserAccountMapper userAccountMapper;
- private final UserAccountService userAccountService;
- private final UserOrderInfoMapper userOrderInfoMapper;
- private final ThirdPartyStationInfoMapper thirdPartyStationInfoMapper;
- private final ThirdPartyEquipmentInfoMapper thirdPartyEquipmentInfoMapper;
- private final ThirdPartyConnectorInfoMapper thirdPartyConnectorInfoMapper;
- private final ChargeOrderInfoService chargeOrderInfoService;
- private final ObjectMapper objectMapper = new ObjectMapper();
- /**
- * Redis Token Key 前缀
- */
- private static final String TOKEN_KEY_PREFIX = "third_party_access:token:";
- /**
- * Redis OperatorId Token映射 Key 前缀
- */
- private static final String OPERATOR_TOKEN_KEY_PREFIX = "third_party_access:operator:";
- /**
- * 默认Token有效期(秒)
- */
- private static final int DEFAULT_TOKEN_EXPIRE_SECONDS = 7200;
- @Override
- public ThirdPartyResponse queryToken(ThirdPartyRequest request) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- QueryTokenRequestData tokenRequest = objectMapper.readValue(decryptedData, QueryTokenRequestData.class);
- if (tokenRequest == null || StrUtil.isBlank(tokenRequest.getOperatorId()) || StrUtil.isBlank(tokenRequest.getOperatorSecret())) {
- return buildErrorResponse(4004, "请求的业务参数不合法", thirdPartyInfo);
- }
- // 5. 验证运营商ID和密钥
- if (!thirdPartyInfo.getOperatorId().equals(tokenRequest.getOperatorId())
- || !thirdPartyInfo.getOperatorSecret().equals(tokenRequest.getOperatorSecret())) {
- log.warn("运营商ID或密钥错误, operatorId: {}", tokenRequest.getOperatorId());
- // 返回失败响应数据
- QueryTokenResponseData failData = QueryTokenResponseData.fail(tokenRequest.getOperatorId(), 1);
- return buildSuccessResponse(failData, thirdPartyInfo);
- }
- // 6. 生成或获取已有Token
- String accessToken = getOrGenerateToken(tokenRequest.getOperatorId());
- Integer remainingTTL = getRemainingTTL(accessToken);
- // 7. 构建成功响应
- QueryTokenResponseData responseData = QueryTokenResponseData.success(
- tokenRequest.getOperatorId(),
- accessToken,
- remainingTTL
- );
- log.info("生成Token成功, operatorId: {}, token有效期: {}秒", tokenRequest.getOperatorId(), remainingTTL);
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_token请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- @Override
- public ThirdPartyResponse queryRechargeLevelPage(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- RechargeLevelPageRequestData pageRequest = objectMapper.readValue(decryptedData, RechargeLevelPageRequestData.class);
- if (pageRequest == null) {
- pageRequest = new RechargeLevelPageRequestData();
- }
- // 6. 查询充值档位分页数据
- IPage<RechargeLevel> pageResult = queryRechargeLevelFromDb(pageRequest);
- // 7. 转换为响应数据
- List<RechargeLevelPageResponseData.RechargeLevelItem> records = pageResult.getRecords().stream()
- .map(this::convertToItem)
- .collect(Collectors.toList());
- RechargeLevelPageResponseData responseData = RechargeLevelPageResponseData.of(
- pageResult.getTotal(),
- pageResult.getCurrent(),
- pageResult.getSize(),
- pageResult.getPages(),
- records
- );
- log.info("查询充值档位成功, operatorId: {}, total: {}", request.getOperatorId(), pageResult.getTotal());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_recharge_level_page请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- @Override
- public ThirdPartyResponse queryUserInfo(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- QueryUserInfoRequestData userInfoRequest = objectMapper.readValue(decryptedData, QueryUserInfoRequestData.class);
- if (userInfoRequest == null || StrUtil.isBlank(userInfoRequest.getPhone())) {
- log.warn("手机号为空, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "请求的业务参数不合法,手机号不能为空", thirdPartyInfo);
- }
- String phone = userInfoRequest.getPhone();
- // 6. 根据手机号查询用户信息
- UserInfo userInfo = userInfoService.getUserInfoByPhone(phone);
- Integer isNewUser = 0;
- if (userInfo == null) {
- // 用户不存在,注册新用户
- log.info("用户不存在,注册新用户, phone: {}", phone);
- userInfo = userInfoService.registerOrUpdateUserByPhone(phone, null);
- if (userInfo == null) {
- log.error("注册用户失败, phone: {}", phone);
- return buildErrorResponse(500, "注册用户失败", thirdPartyInfo);
- }
- isNewUser = 1;
- }
- // 7. 查询用户账户信息
- UserAccount userAccount = userAccountMapper.selectOne(
- Wrappers.<UserAccount>lambdaQuery()
- .eq(UserAccount::getUserId, userInfo.getId())
- .eq(UserAccount::getIsDeleted, 0)
- );
- // 如果账户不存在,创建账户
- if (userAccount == null) {
- log.info("用户账户不存在,创建账户, userId: {}", userInfo.getId());
- userAccount = new UserAccount();
- userAccount.setUserId(userInfo.getId());
- userAccount.setBalance(BigDecimal.ZERO);
- userAccount.setRedeemBalance(BigDecimal.ZERO);
- userAccount.setIntegral(BigDecimal.ZERO);
- userAccountMapper.insert(userAccount);
- }
- // 8. 构建响应数据
- QueryUserInfoResponseData.UserInfoItem userInfoItem = new QueryUserInfoResponseData.UserInfoItem();
- userInfoItem.setUserId(userInfo.getId());
- userInfoItem.setNickName(userInfo.getNickName());
- userInfoItem.setPhone(userInfo.getPhone());
- userInfoItem.setOpenid(userInfo.getOpenid());
- QueryUserInfoResponseData.AccountInfoItem accountInfoItem = new QueryUserInfoResponseData.AccountInfoItem();
- accountInfoItem.setAccountId(userAccount.getId());
- accountInfoItem.setBalance(userAccount.getBalance() != null ? userAccount.getBalance() : BigDecimal.ZERO);
- accountInfoItem.setRedeemBalance(userAccount.getRedeemBalance() != null ? userAccount.getRedeemBalance() : BigDecimal.ZERO);
- accountInfoItem.setIntegral(userAccount.getIntegral() != null ? userAccount.getIntegral() : BigDecimal.ZERO);
- QueryUserInfoResponseData responseData = QueryUserInfoResponseData.of(isNewUser, userInfoItem, accountInfoItem);
- log.info("根据手机号查询用户信息成功, operatorId: {}, phone: {}, isNewUser: {}", request.getOperatorId(), phone, isNewUser);
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_user_info请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- @Override
- public ThirdPartyResponse chargeOrderPay(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- ChangeOrderPayRequestData payRequest = objectMapper.readValue(decryptedData, ChangeOrderPayRequestData.class);
- if (payRequest == null || StrUtil.isBlank(payRequest.getPhone()) || StrUtil.isBlank(payRequest.getOrderNo())) {
- log.warn("请求参数不完整, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "请求的业务参数不合法,手机号和订单号不能为空", thirdPartyInfo);
- }
- Long userId = payRequest.getUserId();
- String phone = payRequest.getPhone();
- //根据userId和phone校验用户
- UserInfo userInfo = userInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class).eq(UserInfo::getPhone, phone).eq(UserInfo::getId, userId).last("limit 1"));
- if (ObjectUtil.isNull(userInfo)) {
- log.warn("用户不存在, userId: {}, phone: {}", userId, phone);
- ChargeOrderPayResponseData failData = ChargeOrderPayResponseData.fail("用户不存在");
- return buildSuccessResponse(failData, thirdPartyInfo);
- }
- String orderNo = payRequest.getOrderNo();
- UserAccount userAccount = userAccountService.getOne(Wrappers.lambdaQuery(UserAccount.class).eq(UserAccount::getUserId, userId).last("limit 1"));
- // 如果账户不存在,创建账户
- if (ObjectUtil.isNull(userAccount)) {
- log.info("用户账户不存在,创建账户, userId: {}", userInfo.getId());
- userAccount = new UserAccount();
- userAccount.setUserId(userInfo.getId());
- userAccount.setBalance(BigDecimal.ZERO);
- userAccount.setRedeemBalance(BigDecimal.ZERO);
- userAccount.setIntegral(BigDecimal.ZERO);
- userAccountMapper.insert(userAccount);
- }
- // 6. 幂等性检查 - 通过Redis检查订单是否已处理
- String orderKey = "third_party_pay:order:" + orderNo;
- Boolean isProcessed = redisTemplate.hasKey(orderKey);
- if (Boolean.TRUE.equals(isProcessed)) {
- log.warn("订单已处理,请勿重复提交, orderNo: {}", orderNo);
- ChargeOrderPayResponseData failData = ChargeOrderPayResponseData.fail("订单已处理,请勿重复提交");
- return buildSuccessResponse(failData, thirdPartyInfo);
- }
- // 7. 查询充值档位信息(如果有levelId)
- BigDecimal rechargeMoney;
- if (payRequest.getLevelId() != null) {
- RechargeLevel rechargeLevel = rechargeLevelMapper.selectById(payRequest.getLevelId());
- if (rechargeLevel == null) {
- log.warn("充值档位不存在, levelId: {}", payRequest.getLevelId());
- ChargeOrderPayResponseData failData = ChargeOrderPayResponseData.fail("充值档位不存在");
- return buildSuccessResponse(failData, thirdPartyInfo);
- }
- rechargeMoney = rechargeLevel.getMoney();
- } else if (StrUtil.isNotBlank(payRequest.getTotalMoney())) {
- // 使用传入的金额
- rechargeMoney = new BigDecimal(payRequest.getTotalMoney());
- } else {
- log.warn("充值金额未指定, operatorId: {}", request.getOperatorId());
- ChargeOrderPayResponseData failData = ChargeOrderPayResponseData.fail("充值金额未指定");
- return buildSuccessResponse(failData, thirdPartyInfo);
- }
- // 8. 增加充值订单记录到c_user_order_info表
- UserOrderInfo orderInfo = new UserOrderInfo();
- orderInfo.setUserId(userId);
- orderInfo.setOrderNo(orderNo);
- orderInfo.setOrderMoney(rechargeMoney);
- orderInfo.setPayMoney(rechargeMoney);
- orderInfo.setLastMoney(rechargeMoney);
- // 解析支付时间
- if (StrUtil.isNotBlank(payRequest.getPayTime())) {
- try {
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- orderInfo.setPayTime(LocalDateTime.parse(payRequest.getPayTime(), formatter));
- } catch (Exception e) {
- orderInfo.setPayTime(LocalDateTime.now());
- }
- } else {
- orderInfo.setPayTime(LocalDateTime.now());
- }
- orderInfo.setLevelId(payRequest.getLevelId());
- orderInfo.setOutTradeNo(orderNo); // 第三方订单号
- orderInfo.setOrderStatus(2); // 已支付
- orderInfo.setOrderType(3); // 渠道方
- orderInfo.setRemark("第三方渠道充值-" + request.getOperatorId());
- userOrderInfoMapper.insert(orderInfo);
- log.info("创建充值订单记录成功, orderNo: {}, userId: {}", orderNo, userId);
- // 9. 充值账户余额并记录日志
- // 使用订单号的Id值作为变更记录ID
- Long changeId = orderInfo.getId();
- UserAccount updatedAccount = userAccountService.updateAccountBalanceAndLog(
- userId,
- rechargeMoney,
- SystemConstants.CHANGE_TYPE_ADD,
- SystemConstants.ACCOUNT_LOG_THIRD_PARTY_PAY_NOTE + "-" + orderNo,
- changeId
- );
- BigDecimal balanceAfter = updatedAccount != null ? updatedAccount.getBalance() : userAccount.getBalance().add(rechargeMoney);
- // 10. 构建成功响应
- ChargeOrderPayResponseData responseData = ChargeOrderPayResponseData.success(
- userId,
- rechargeMoney,
- balanceAfter,
- orderNo
- );
- log.info("充电券购买成功, operatorId: {}, phone: {}, orderNo: {}, rechargeMoney: {}, balanceAfter: {}",
- request.getOperatorId(), phone, orderNo, rechargeMoney, balanceAfter);
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理charge_order_pay请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- /**
- * 从Authorization Header中解析Token
- * 支持格式: "Bearer {token}" 或直接传 "{token}"
- */
- private String parseAccessToken(String authorization) {
- if (StrUtil.isBlank(authorization)) {
- return null;
- }
- // 支持 Bearer Token 格式
- if (authorization.startsWith("Bearer ")) {
- return authorization.substring(7).trim();
- }
- // 直接返回Token
- return authorization.trim();
- }
- /**
- * 验证访问Token
- */
- private boolean validateAccessToken(String accessToken, String operatorId) {
- String tokenKey = TOKEN_KEY_PREFIX + accessToken;
- String storedOperatorId = (String) redisTemplate.opsForValue().get(tokenKey);
- return operatorId.equals(storedOperatorId);
- }
- /**
- * 从数据库查询充值档位分页数据
- */
- private IPage<RechargeLevel> queryRechargeLevelFromDb(RechargeLevelPageRequestData pageRequest) {
- Page<RechargeLevel> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
- LambdaQueryWrapper<RechargeLevel> queryWrapper = new LambdaQueryWrapper<>();
- // 按ID排序
- queryWrapper.eq(RechargeLevel::getStatus, SystemConstants.STATUS_ONE);
- queryWrapper.orderByAsc(RechargeLevel::getId);
- return rechargeLevelMapper.selectPage(page, queryWrapper);
- }
- /**
- * 转换为响应项
- */
- private RechargeLevelPageResponseData.RechargeLevelItem convertToItem(RechargeLevel entity) {
- RechargeLevelPageResponseData.RechargeLevelItem item = new RechargeLevelPageResponseData.RechargeLevelItem();
- item.setId(entity.getId());
- item.setName(entity.getName());
- item.setMoney(entity.getMoney());
- item.setStatus(entity.getStatus());
- item.setTips(entity.getTips());
- return item;
- }
- /**
- * 通过operatorId查询第三方配置信息
- */
- private ThirdPartyInfo getThirdPartyInfoByOperatorId(String operatorId) {
- LambdaQueryWrapper<ThirdPartyInfo> queryWrapper = new LambdaQueryWrapper<>();
- queryWrapper.eq(ThirdPartyInfo::getOperatorId, operatorId)
- .eq(ThirdPartyInfo::getStatus, 0) // 状态正常
- .last("LIMIT 1");
- return thirdPartyInfoMapper.selectOne(queryWrapper);
- }
- /**
- * 校验请求参数完整性
- */
- private boolean validateRequestParams(ThirdPartyRequest request) {
- return request != null
- && StrUtil.isNotBlank(request.getOperatorId())
- && StrUtil.isNotBlank(request.getData())
- && StrUtil.isNotBlank(request.getTimeStamp())
- && StrUtil.isNotBlank(request.getSeq())
- && StrUtil.isNotBlank(request.getSig());
- }
- /**
- * 获取或生成Token
- * 如果Redis中存在有效Token则返回,否则生成新Token
- */
- private String getOrGenerateToken(String operatorId) {
- // 检查是否有已存在的有效Token
- String operatorTokenKey = OPERATOR_TOKEN_KEY_PREFIX + operatorId;
- String existingToken = (String) redisTemplate.opsForValue().get(operatorTokenKey);
- if (StrUtil.isNotBlank(existingToken)) {
- // 验证Token是否仍然有效
- String tokenKey = TOKEN_KEY_PREFIX + existingToken;
- Boolean hasKey = redisTemplate.hasKey(tokenKey);
- if (Boolean.TRUE.equals(hasKey)) {
- log.info("返回已存在的有效Token, operatorId: {}", operatorId);
- return existingToken;
- }
- }
- // 生成新Token
- String newToken = IdUtil.fastSimpleUUID() + IdUtil.fastSimpleUUID();
- // 存储Token
- String tokenKey = TOKEN_KEY_PREFIX + newToken;
- redisTemplate.opsForValue().set(tokenKey, operatorId, DEFAULT_TOKEN_EXPIRE_SECONDS, TimeUnit.SECONDS);
- // 存储OperatorId与Token的映射关系
- redisTemplate.opsForValue().set(operatorTokenKey, newToken, DEFAULT_TOKEN_EXPIRE_SECONDS, TimeUnit.SECONDS);
- log.info("生成新Token, operatorId: {}, expireSeconds: {}", operatorId, DEFAULT_TOKEN_EXPIRE_SECONDS);
- return newToken;
- }
- /**
- * 获取Token剩余有效时间(秒)
- */
- private Integer getRemainingTTL(String token) {
- String tokenKey = TOKEN_KEY_PREFIX + token;
- Long ttl = redisTemplate.getExpire(tokenKey, TimeUnit.SECONDS);
- return ttl != null && ttl > 0 ? ttl.intValue() : 0;
- }
- /**
- * 构建成功响应(通用)
- */
- private ThirdPartyResponse buildSuccessResponse(Object responseData, ThirdPartyInfo thirdPartyInfo) throws Exception {
- String jsonData = objectMapper.writeValueAsString(responseData);
- String encryptedData = AESCryptoUtils.encrypt(
- jsonData,
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- String sig = HmacMD5Util.genSign(0, "", encryptedData, thirdPartyInfo.getSigSecret());
- return ThirdPartyResponse.success(encryptedData, sig);
- }
- /**
- * 构建错误响应
- */
- private ThirdPartyResponse buildErrorResponse(Integer ret, String msg, ThirdPartyInfo thirdPartyInfo) {
- try {
- String sigSecret = thirdPartyInfo != null ? thirdPartyInfo.getSigSecret() : "";
- String sig = StrUtil.isNotBlank(sigSecret) ? HmacMD5Util.genSign(ret, msg, "", sigSecret) : "";
- return ThirdPartyResponse.error(ret, msg, sig);
- } catch (Exception e) {
- log.error("生成错误响应签名失败", e);
- ThirdPartyResponse response = new ThirdPartyResponse();
- response.setRet(ret);
- response.setMsg(msg);
- response.setData("");
- response.setSig("");
- return response;
- }
- }
- // ==================== 充电站与设备查询接口 ====================
- /**
- * 时间格式化器 HHmmss
- */
- private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HHmmss");
- @Override
- public ThirdPartyResponse queryChargeStationList(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- ChargeStationListRequestData listRequest = objectMapper.readValue(decryptedData, ChargeStationListRequestData.class);
- if (listRequest == null) {
- listRequest = new ChargeStationListRequestData();
- }
- // 6. 查询充电站分页数据
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
- // 构建分页对象
- Page<StationInfoVO> page = new Page<>(listRequest.getPageNum(), listRequest.getPageSize());
- StationInfoQuery stationInfoQuery = new StationInfoQuery().setLatitude(listRequest.getLatitude()).setLongitude(listRequest.getLongitude()).setSortType(listRequest.getSortType());
- // 执行查询
- IPage<StationInfoVO> pageResult = thirdPartyStationInfoMapper.selectAppletStationInfoPage(
- page, stationInfoQuery, currentTime, null
- );
- // 7. 转换为响应数据
- List<ChargeStationListResponseData.StationItem> records = pageResult.getRecords().stream()
- .map(this::convertToStationItem)
- .collect(Collectors.toList());
- ChargeStationListResponseData responseData = ChargeStationListResponseData.of(
- pageResult.getTotal(),
- pageResult.getCurrent(),
- pageResult.getSize(),
- pageResult.getPages(),
- records
- );
- log.info("查询充电站列表成功, operatorId: {}, total: {}", request.getOperatorId(), pageResult.getTotal());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_charge_station_list请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- @Override
- public ThirdPartyResponse queryChargeStationDetail(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- ChargeStationDetailRequestData detailRequest = objectMapper.readValue(decryptedData, ChargeStationDetailRequestData.class);
- if (detailRequest == null || (detailRequest.getStationId() == null )) {
- return buildErrorResponse(4003, "请求的业务参数不合法", thirdPartyInfo);
- }
- // 6. 查询充电站详情
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
- // 查询站点详情基本信息
- AppletStationDetailVO result = thirdPartyStationInfoMapper.selectStationDetail(
- detailRequest.getStationId(), detailRequest.getLongitude(), detailRequest.getLatitude(), currentTime, null
- );
- if (result == null) {
- return buildErrorResponse(4004, "充电站不存在", thirdPartyInfo);
- }
- // 查询站点对应的stationId
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(detailRequest.getStationId());
- if (stationInfo == null) {
- return buildErrorResponse(4004, "充电站不存在", thirdPartyInfo);
- }
- // 根据站点stationId查询设备列表(third_party_equipment_info)
- List<ThirdPartyEquipmentInfo> equipmentList = thirdPartyEquipmentInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyEquipmentInfo>()
- .eq(ThirdPartyEquipmentInfo::getStationId, stationInfo.getStationId())
- );
- // 构建设备ID到设备类型的映射
- Map<String, Integer> equipmentTypeMap = equipmentList.stream()
- .collect(Collectors.toMap(
- ThirdPartyEquipmentInfo::getEquipmentId,
- e -> e.getEquipmentType() != null ? e.getEquipmentType() : 0,
- (v1, v2) -> v1
- ));
- // 根据设备列表的equipmentId查询充电接口信息(third_party_connector_info)
- List<ThirdPartyConnectorInfo> connectorList = new ArrayList<>();
- if (!equipmentList.isEmpty()) {
- List<String> equipmentIds = equipmentList.stream()
- .map(ThirdPartyEquipmentInfo::getEquipmentId)
- .collect(Collectors.toList());
- connectorList = thirdPartyConnectorInfoMapper.selectList(
- new LambdaQueryWrapper<ThirdPartyConnectorInfo>()
- .in(ThirdPartyConnectorInfo::getEquipmentId, equipmentIds)
- );
- }
- // 统计终端状态
- int idleCount = 0;
- int occupiedCount = 0;
- int offlineCount = 0;
- List<AppletStationDetailVO.ConnectorInfoVO> connectorVOList = new ArrayList<>();
- for (ThirdPartyConnectorInfo connector : connectorList) {
- AppletStationDetailVO.ConnectorInfoVO vo = new AppletStationDetailVO.ConnectorInfoVO();
- vo.setConnectorId(connector.getId());
- vo.setConnectorName(connector.getConnectorName());
- vo.setConnectorCode(connector.getConnectorId());
- // 设备分类:从设备表获取设备类型(1-直流设备,2-交流设备,3-交直流一体设备,4-无线设备,5-其他)
- Integer equipmentType = equipmentTypeMap.get(connector.getEquipmentId());
- if (equipmentType != null) {
- switch (equipmentType) {
- case 1:
- vo.setEquipmentType("直流设备");
- break;
- case 2:
- vo.setEquipmentType("交流设备");
- break;
- case 3:
- vo.setEquipmentType("交直流一体设备");
- break;
- case 4:
- vo.setEquipmentType("无线设备");
- break;
- case 5:
- vo.setEquipmentType("其他");
- break;
- default:
- vo.setEquipmentType("未知");
- }
- }
- // 从充电接口表获取实际状态
- // 0-离网,1-空闲,2-占用(未充电),3-占用(充电中),4-占用(预约锁定),255-故障
- Integer connectorStatus = connector.getStatus();
- if (connectorStatus == null) {
- // 默认为离网
- connectorStatus = 0;
- }
- vo.setStatus(connectorStatus);
- // 设置状态名称并统计
- switch (connectorStatus) {
- case 0:
- vo.setStatusName("离网");
- offlineCount++;
- break;
- case 1:
- vo.setStatusName("空闲");
- idleCount++;
- break;
- case 2:
- vo.setStatusName("占用(未充电)");
- occupiedCount++;
- break;
- case 3:
- vo.setStatusName("占用(充电中)");
- occupiedCount++;
- break;
- case 4:
- vo.setStatusName("占用(预约锁定)");
- occupiedCount++;
- break;
- case 255:
- vo.setStatusName("故障");
- offlineCount++;
- break;
- default:
- vo.setStatusName("未知");
- offlineCount++;
- }
- connectorVOList.add(vo);
- }
- result.setConnectorList(connectorVOList);
- result.setIdleCount(idleCount);
- result.setOccupiedCount(occupiedCount);
- result.setOfflineCount(offlineCount);
- // 7. 转换为响应数据
- ChargeStationDetailResponseData responseData = convertToStationDetail(result);
- log.info("查询充电站详情成功, operatorId: {}, stationId: {}", request.getOperatorId(), stationInfo.getStationId());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_charge_station_detail请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- @Override
- public ThirdPartyResponse queryChargeDeviceDetail(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("解密后的请求数据: {}", decryptedData);
- ChargeDeviceDetailRequestData detailRequest = objectMapper.readValue(decryptedData, ChargeDeviceDetailRequestData.class);
- if (detailRequest == null || (detailRequest.getId() == null && StrUtil.isBlank(detailRequest.getEquipmentId()))) {
- return buildErrorResponse(4003, "请求的业务参数不合法", thirdPartyInfo);
- }
- // 6. 查询充电设备详情
- // 获取当前时间(HHmmss格式)
- String currentTime = LocalTime.now().format(TIME_FORMATTER);
- AppletConnectorDetailVO result = thirdPartyConnectorInfoMapper.selectConnectorDetailById(
- detailRequest.getEquipmentId(), null, currentTime, null, null
- );
- // 8. 转换为响应数据
- ChargeDeviceDetailResponseData responseData = convertToDeviceDetail(result);
- log.info("查询充电终端详情成功, operatorId: {}, equipmentId: {}", request.getOperatorId(), result.getConnectorId());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_charge_device_detail请求异常", e);
- return buildErrorResponse(500, "系统错误", null);
- }
- }
- /**
- * 转换充电站信息为详情响应(从AppletStationDetailVO转换)
- */
- private ChargeStationDetailResponseData convertToStationDetail(AppletStationDetailVO result) {
- ChargeStationDetailResponseData detail = new ChargeStationDetailResponseData();
- detail.setStationId(result.getStationId());
- detail.setStationName(result.getStationName());
- detail.setTips(result.getTips());
- detail.setDistance(result.getDistance());
- detail.setAddress(result.getAddress());
- detail.setLongitude(result.getLongitude());
- detail.setLatitude(result.getLatitude());
- detail.setPictures(result.getPictures());
- detail.setCurrentPrice(result.getCurrentPrice());
- detail.setCurrentPeriod(result.getCurrentPeriod());
- detail.setOriginalPrice(result.getOriginalPrice());
- detail.setPeriodFlag(result.getPeriodFlag());
- detail.setIdleCount(result.getIdleCount());
- detail.setOccupiedCount(result.getOccupiedCount());
- detail.setOfflineCount(result.getOfflineCount());
- detail.setBusinessHours(result.getBusinessHours());
- detail.setServiceProvider(result.getServiceProvider());
- detail.setInvoiceProvider(result.getInvoiceProvider());
- detail.setCustomerServiceHotline(result.getCustomerServiceHotline());
- // 转换充电终端列表
- if (result.getConnectorList() != null) {
- List<ChargeStationDetailResponseData.ConnectorInfoVO> connectorVOList = result.getConnectorList().stream()
- .map(connector -> {
- ChargeStationDetailResponseData.ConnectorInfoVO vo = new ChargeStationDetailResponseData.ConnectorInfoVO();
- vo.setConnectorId(connector.getConnectorId());
- vo.setConnectorName(connector.getConnectorName());
- vo.setEquipmentType(connector.getEquipmentType());
- vo.setConnectorCode(connector.getConnectorCode());
- vo.setStatus(connector.getStatus());
- vo.setStatusName(connector.getStatusName());
- return vo;
- })
- .collect(Collectors.toList());
- detail.setConnectorList(connectorVOList);
- }
- return detail;
- }
- /**
- * 转换充电站信息为列表项
- */
- private ChargeStationListResponseData.StationItem convertToStationItem(StationInfoVO stationInfoVO) {
- ChargeStationListResponseData.StationItem item = new ChargeStationListResponseData.StationItem();
- item.setStationId(stationInfoVO.getStationId());
- item.setStationName(stationInfoVO.getStationName());
- item.setTips(stationInfoVO.getTips());
- item.setDistance(stationInfoVO.getDistance());
- item.setFastCharging(stationInfoVO.getFastCharging());
- item.setSlowCharging(stationInfoVO.getSlowCharging());
- item.setPeakValue(stationInfoVO.getPeakValue());
- item.setPeakTime(stationInfoVO.getPeakTime());
- item.setPeriodFlag(stationInfoVO.getPeriodFlag());
- item.setPlatformPrice(stationInfoVO.getPlatformPrice());
- return item;
- }
- /**
- * 转换充电设备信息为详情响应(从AppletConnectorDetailVO转换)
- */
- private ChargeDeviceDetailResponseData convertToDeviceDetail(AppletConnectorDetailVO connectorDetail) {
- ChargeDeviceDetailResponseData detail = new ChargeDeviceDetailResponseData();
- detail.setConnectorId(connectorDetail.getConnectorId());
- detail.setConnectorCode(connectorDetail.getConnectorCode());
- detail.setConnectorName(connectorDetail.getConnectorName());
- detail.setStationId(connectorDetail.getStationId());
- detail.setStationName(connectorDetail.getStationName());
- detail.setStationAddress(connectorDetail.getStationAddress());
- detail.setEquipmentId(connectorDetail.getEquipmentId());
- detail.setEquipmentCode(connectorDetail.getEquipmentCode());
- detail.setEquipmentName(connectorDetail.getEquipmentName());
- detail.setEquipmentType(connectorDetail.getEquipmentType());
- detail.setEquipmentTypeName(connectorDetail.getEquipmentTypeName());
- detail.setParkNo(connectorDetail.getParkNo());
- detail.setStatus(connectorDetail.getStatus());
- detail.setStatusName(connectorDetail.getStatusName());
- detail.setConnectorType(connectorDetail.getConnectorType());
- detail.setConnectorTypeName(connectorDetail.getConnectorTypeName());
- detail.setVoltageUpperLimits(connectorDetail.getVoltageUpperLimits());
- detail.setVoltageLowerLimits(connectorDetail.getVoltageLowerLimits());
- detail.setCurrent(connectorDetail.getCurrent());
- detail.setPower(connectorDetail.getPower());
- detail.setNationalStandard(connectorDetail.getNationalStandard());
- detail.setNationalStandardName(connectorDetail.getNationalStandardName());
- detail.setCurrentPrice(connectorDetail.getCurrentPrice());
- detail.setPeriodFlag(connectorDetail.getPeriodFlag());
- detail.setCurrentPeriodDesc(connectorDetail.getCurrentPeriodDesc());
- detail.setParkingTips(connectorDetail.getParkingTips());
- return detail;
- }
- @Override
- public ThirdPartyResponse invokeCharge(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("启动充电-解密后的请求数据: {}", decryptedData);
- InvokeChargeRequestData invokeRequest = objectMapper.readValue(decryptedData, InvokeChargeRequestData.class);
- if (invokeRequest == null || StrUtil.isBlank(invokeRequest.getEquipmentId())
- || StrUtil.isBlank(invokeRequest.getStationId()) || StrUtil.isBlank(invokeRequest.getConnectorId())) {
- return buildErrorResponse(4003, "请求的业务参数不合法", thirdPartyInfo);
- }
- // 6. 构建启动充电表单
- AppInvokeChargeForm formData = new AppInvokeChargeForm();
- formData.setOrderType(2); // 渠道方订单
- formData.setEquipmentId(invokeRequest.getEquipmentId());
- formData.setStationId(invokeRequest.getStationId());
- formData.setConnectorId(invokeRequest.getConnectorId());
- formData.setChannelOrderNo(invokeRequest.getChannelOrderNo());
- formData.setChannelUserPhone(invokeRequest.getChannelUserPhone());
- formData.setChannelPreAmt(invokeRequest.getChannelPreAmt());
- // 7. 调用启动充电服务
- AppChargeVO chargeVO = chargeOrderInfoService.invokeCharge(formData);
- // 8. 构建响应数据
- InvokeChargeResponseData responseData = InvokeChargeResponseData.success(
- chargeVO.getChargeOrderId(),
- chargeVO.getChargeOrderNo(),
- chargeVO.getStatus()
- );
- log.info("启动充电成功, chargeOrderNo: {}", chargeVO.getChargeOrderNo());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理invoke_charge请求异常", e);
- return buildErrorResponse(500, "系统错误: " + e.getMessage(), null);
- }
- }
- @Override
- public ThirdPartyResponse stopCharge(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("停止充电-解密后的请求数据: {}", decryptedData);
- StopChargeRequestData stopRequest = objectMapper.readValue(decryptedData, StopChargeRequestData.class);
- if (stopRequest == null || StrUtil.isBlank(stopRequest.getChargeOrderNo())) {
- return buildErrorResponse(4003, "请求的业务参数不合法", thirdPartyInfo);
- }
- // 6. 构建停止充电表单
- AppStopChargeForm formData = new AppStopChargeForm();
- formData.setChargeOrderNo(stopRequest.getChargeOrderNo());
- // 7. 调用停止充电服务
- AppChargeVO chargeVO = chargeOrderInfoService.stopCharge(formData);
- // 8. 构建响应数据
- StopChargeResponseData responseData = StopChargeResponseData.success(
- chargeVO.getChargeOrderId(),
- chargeVO.getChargeOrderNo(),
- chargeVO.getStatus()
- );
- log.info("停止充电成功, chargeOrderNo: {}", chargeVO.getChargeOrderNo());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理stop_charge请求异常", e);
- return buildErrorResponse(500, "系统错误: " + e.getMessage(), null);
- }
- }
- @Override
- public ThirdPartyResponse queryChargeOrderList(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("查询充电订单列表-解密后的请求数据: {}", decryptedData);
- ChargeOrderListRequestData listRequest = objectMapper.readValue(decryptedData, ChargeOrderListRequestData.class);
- if (listRequest == null) {
- listRequest = new ChargeOrderListRequestData();
- }
- // 6. 构建查询条件(只查询渠道类型订单 order_type=2)
- LambdaQueryWrapper<com.zsElectric.boot.business.model.entity.ChargeOrderInfo> queryWrapper = Wrappers.lambdaQuery();
- queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOrderType, SystemConstants.CHARGE_ORDER_TYPE_CHANNEL);
- queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOperatorId, listRequest.getOperatorId());
- queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getIsDeleted, 0);
- // 可选条件:userId
- if (listRequest.getUserId() != null) {
- queryWrapper.eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getUserId, listRequest.getUserId());
- }
- // 可选条件:chargeOrderNo
- if (StrUtil.isNotBlank(listRequest.getChargeOrderNo())) {
- queryWrapper.like(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getChargeOrderNo, listRequest.getChargeOrderNo());
- }
- // 按创建时间倒序
- queryWrapper.orderByDesc(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getCreateTime);
- // 7. 分页查询
- long pageNo = listRequest.getPageNo() != null && listRequest.getPageNo() > 0 ? listRequest.getPageNo() : 1L;
- long pageSize = listRequest.getPageSize() != null && listRequest.getPageSize() > 0 ? listRequest.getPageSize() : 10L;
- Page<com.zsElectric.boot.business.model.entity.ChargeOrderInfo> page = new Page<>(pageNo, pageSize);
- IPage<com.zsElectric.boot.business.model.entity.ChargeOrderInfo> pageResult = chargeOrderInfoService.page(page, queryWrapper);
- // 8. 转换为响应数据
- List<ChargeOrderListResponseData.ChargeOrderItem> records = pageResult.getRecords().stream()
- .map(this::convertToChargeOrderItem)
- .collect(Collectors.toList());
- ChargeOrderListResponseData responseData = ChargeOrderListResponseData.of(
- pageResult.getTotal(),
- pageResult.getCurrent(),
- pageResult.getSize(),
- pageResult.getPages(),
- records
- );
- log.info("查询充电订单列表成功, operatorId: {}, total: {}", request.getOperatorId(), pageResult.getTotal());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_charge_order_list请求异常", e);
- return buildErrorResponse(500, "系统错误: " + e.getMessage(), null);
- }
- }
- /**
- * 将ChargeOrderInfo转换为ChargeOrderItem
- */
- private ChargeOrderListResponseData.ChargeOrderItem convertToChargeOrderItem(com.zsElectric.boot.business.model.entity.ChargeOrderInfo order) {
- ChargeOrderListResponseData.ChargeOrderItem item = new ChargeOrderListResponseData.ChargeOrderItem();
- item.setId(order.getId());
- item.setUserId(order.getUserId());
- item.setChargeOrderNo(order.getChargeOrderNo());
- item.setEquipmentId(order.getEquipmentId());
- item.setConnectorId(order.getConnectorId());
- item.setStartTime(order.getStartTime());
- item.setEndTime(order.getEndTime());
- item.setChargeTime(order.getChargeTime());
- item.setTotalCharge(order.getTotalCharge());
- item.setStatus(order.getStatus());
- item.setPreAmt(order.getPreAmt());
- item.setPhoneNum(order.getPhoneNum());
- item.setPlateNum(order.getPlateNum());
- item.setStopType(order.getStopType());
- item.setStopReason(order.getStopReason());
- item.setCreateTime(order.getCreateTime() != null ? order.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
- // 查询充电站名称
- if (order.getThirdPartyStationId() != null) {
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(order.getThirdPartyStationId());
- if (stationInfo != null) {
- item.setStationName(stationInfo.getStationName());
- }
- }
- // 查询充电设备接口名称
- if (StrUtil.isNotBlank(order.getConnectorId())) {
- ThirdPartyConnectorInfo connectorInfo = thirdPartyConnectorInfoMapper.selectOne(
- Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
- .eq(ThirdPartyConnectorInfo::getConnectorId, order.getConnectorId())
- .last("LIMIT 1")
- );
- if (connectorInfo != null) {
- item.setConnectorName(connectorInfo.getConnectorName());
- }
- }
- return item;
- }
- @Override
- public ThirdPartyResponse queryChargeOrderInfo(ThirdPartyRequest request, String authorization) {
- try {
- // 1. 参数校验
- if (!validateRequestParams(request)) {
- return buildErrorResponse(4003, "参数不合法,缺少必需的参数", null);
- }
- // 2. 通过operatorId查询第三方配置信息
- ThirdPartyInfo thirdPartyInfo = getThirdPartyInfoByOperatorId(request.getOperatorId());
- if (thirdPartyInfo == null) {
- log.warn("运营商不存在, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4004, "运营商不存在", null);
- }
- // 3. 验证签名
- String signContent = request.getOperatorId() + request.getData() + request.getTimeStamp() + request.getSeq();
- if (!HmacMD5Util.verify(signContent, thirdPartyInfo.getSigSecret(), request.getSig())) {
- log.warn("签名验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4001, "签名错误", thirdPartyInfo);
- }
- // 4. 从Header中解析并验证Token
- String accessToken = parseAccessToken(authorization);
- if (StrUtil.isBlank(accessToken)) {
- log.warn("Token为空或格式错误, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- if (!validateAccessToken(accessToken, request.getOperatorId())) {
- log.warn("Token验证失败, operatorId: {}", request.getOperatorId());
- return buildErrorResponse(4002, "token错误", thirdPartyInfo);
- }
- // 5. 解密并解析业务参数
- String decryptedData = AESCryptoUtils.decrypt(
- request.getData(),
- thirdPartyInfo.getDataSecret(),
- thirdPartyInfo.getDataSecretIV()
- );
- log.info("查询充电订单详情-解密后的请求数据: {}", decryptedData);
- ChargeOrderDetailRequestData detailRequest = objectMapper.readValue(decryptedData, ChargeOrderDetailRequestData.class);
- if (detailRequest == null || StrUtil.isBlank(detailRequest.getChargeOrderNo())) {
- return buildErrorResponse(4003, "请求的业务参数不合法,chargeOrderNo不能为空", thirdPartyInfo);
- }
- // 6. 查询订单(只查询渠道类型订单 order_type=2)
- com.zsElectric.boot.business.model.entity.ChargeOrderInfo order = chargeOrderInfoService.getOne(
- Wrappers.<com.zsElectric.boot.business.model.entity.ChargeOrderInfo>lambdaQuery()
- .eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getChargeOrderNo, detailRequest.getChargeOrderNo())
- .eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getOrderType, SystemConstants.CHARGE_ORDER_TYPE_CHANNEL)
- .eq(com.zsElectric.boot.business.model.entity.ChargeOrderInfo::getIsDeleted, 0)
- .last("LIMIT 1")
- );
- if (order == null) {
- log.warn("充电订单不存在或不是渠道订单, chargeOrderNo: {}", detailRequest.getChargeOrderNo());
- ChargeOrderDetailResponseData failData = ChargeOrderDetailResponseData.fail("充电订单不存在或不是渠道订单");
- return buildSuccessResponse(failData, thirdPartyInfo);
- }
- // 7. 构建响应数据
- ChargeOrderDetailResponseData responseData = ChargeOrderDetailResponseData.success();
- responseData.setId(order.getId());
- responseData.setUserId(order.getUserId());
- responseData.setChargeOrderNo(order.getChargeOrderNo());
- responseData.setEquipmentId(order.getEquipmentId());
- responseData.setConnectorId(order.getConnectorId());
- responseData.setStartTime(order.getStartTime());
- responseData.setEndTime(order.getEndTime());
- responseData.setChargeTime(order.getChargeTime());
- responseData.setTotalCharge(order.getTotalCharge());
- responseData.setStatus(order.getStatus());
- responseData.setPreAmt(order.getPreAmt());
- responseData.setPhoneNum(order.getPhoneNum());
- responseData.setPlateNum(order.getPlateNum());
- responseData.setStopType(order.getStopType());
- responseData.setStopReason(order.getStopReason());
- responseData.setCreateTime(order.getCreateTime() != null ? order.getCreateTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) : null);
- // 查询充电站名称
- if (order.getThirdPartyStationId() != null) {
- ThirdPartyStationInfo stationInfo = thirdPartyStationInfoMapper.selectById(order.getThirdPartyStationId());
- if (stationInfo != null) {
- responseData.setStationName(stationInfo.getStationName());
- }
- }
- // 查询充电设备接口名称
- if (StrUtil.isNotBlank(order.getConnectorId())) {
- ThirdPartyConnectorInfo connectorInfo = thirdPartyConnectorInfoMapper.selectOne(
- Wrappers.<ThirdPartyConnectorInfo>lambdaQuery()
- .eq(ThirdPartyConnectorInfo::getConnectorId, order.getConnectorId())
- .last("LIMIT 1")
- );
- if (connectorInfo != null) {
- responseData.setConnectorName(connectorInfo.getConnectorName());
- }
- }
- log.info("查询充电订单详情成功, chargeOrderNo: {}", detailRequest.getChargeOrderNo());
- return buildSuccessResponse(responseData, thirdPartyInfo);
- } catch (Exception e) {
- log.error("处理query_charge_order_info请求异常", e);
- return buildErrorResponse(500, "系统错误: " + e.getMessage(), null);
- }
- }
- }
|