ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/factory/ParkingLotFallbackFactory.java
@@ -35,6 +35,12 @@ return R.fail("通过站点id查询停车场信息调用失败:" + throwable.getMessage()); } @Override public R<List<TParkingLot>> getAllParkingLot() { return R.fail("获取所有停车场数据失败:" + throwable.getMessage()); } @Override public R<TParkingRecord> getRecordById(Long siteId) { return R.fail("通过id查询停车场记录:" + throwable.getMessage()); ruoyi-api/ruoyi-api-chargingPile/src/main/java/com/ruoyi/chargingPile/api/feignClient/ParkingLotClient.java
@@ -27,13 +27,21 @@ * 通过站点id查询停车场信息 */ @PostMapping(value = "/t-parking-lot/getLotBySiteId") public R<TParkingLot> getLotBySiteId(@RequestParam("siteId") Integer siteId); R<TParkingLot> getLotBySiteId(@RequestParam("siteId") Integer siteId); /** * 获取所有停车场数据 */ @PostMapping(value = "/t-parking-lot/getAllParkingLot") R<List<TParkingLot>> getAllParkingLot(); @GetMapping(value = "/t-parking-lot/getRecordById") public R<TParkingRecord> getRecordById(@RequestParam("id") Long siteId); R<TParkingRecord> getRecordById(@RequestParam("id") Long siteId); @PostMapping(value = "/t-parking-lot/getRecordAmount") public R<BigDecimal> getRecordAmount(@RequestParam("sixBefore") LocalDate sixBefore); R<BigDecimal> getRecordAmount(@RequestParam("sixBefore") LocalDate sixBefore); /** ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/factory/TCECClientFallbackFactory.java
@@ -5,6 +5,8 @@ import com.ruoyi.integration.api.vo.StartChargeResult; import org.springframework.cloud.openfeign.FallbackFactory; import java.util.List; /** * @author zhibing.pu * @Date 2025/1/24 10:33 @@ -40,6 +42,11 @@ public R notificationChargeOrderInfo(String startChargeSeq, Integer operatorId) { return R.fail("推送订单信息失败:" + cause.getMessage()); } @Override public R notificationStationChange(List<Integer> siteIds) { return R.fail("站点变更推送通知失败:" + cause.getMessage()); } }; } } ruoyi-api/ruoyi-api-integration/src/main/java/com/ruoyi/integration/api/feignClient/TCECClient.java
@@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestParam; import java.util.List; /** * @author zhibing.pu * @Date 2025/1/24 10:32 @@ -64,6 +66,17 @@ * @param startChargeSeq * @return */ @PostMapping("/notificationChargeOrderInfo") @PostMapping("/evcs/v1.0/notificationChargeOrderInfo") R notificationChargeOrderInfo(@RequestParam("startChargeSeq") String startChargeSeq, @RequestParam("operatorId") Integer operatorId); /** * 站点变更推送通知 * @param siteIds * @return */ @PostMapping("/evcs/v1.0/notificationStationChange") R notificationStationChange(@RequestParam("siteIds") List<Integer> siteIds); } ruoyi-api/ruoyi-api-order/src/main/java/com/ruoyi/order/api/model/AddTripartitePlatformOrder.java
@@ -2,6 +2,7 @@ import lombok.Data; import javax.validation.constraints.Null; import java.math.BigDecimal; /** @@ -30,4 +31,9 @@ * 充电余额 */ private BigDecimal paymentAmount; /** * 充电车牌号 */ @Null private String PlateNum; } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/factory/OperatorFallbackFactory.java
@@ -24,6 +24,11 @@ } @Override public R<Operator> getOperatorByName(String name) { return R.fail("获取运营商数据失败:" + cause.getMessage()); } @Override public R<Operator> getOperator(String operatorId) { return R.fail("获取运营商数据失败:" + cause.getMessage()); } ruoyi-api/ruoyi-api-other/src/main/java/com/ruoyi/other/api/feignClient/OperatorClient.java
@@ -30,6 +30,16 @@ /** * 获取运营商数据 * @param name * @return */ @PostMapping("/operator/getOperatorByName") R<Operator> getOperatorByName(@RequestParam("name") String name); /** * 获取运营商数据 * @param operatorId * @return */ ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/SiteController.java
@@ -332,8 +332,7 @@ return R.ok(divide); } @Resource private SiteClient siteClient; ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TAccountingStrategyController.java
@@ -28,6 +28,7 @@ import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.integration.api.feignClient.IntegrationClient; import com.ruoyi.integration.api.feignClient.TCECClient; import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.feignClient.SysUserClient; import io.swagger.annotations.ApiOperation; @@ -44,6 +45,7 @@ import java.util.Arrays; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; import static com.ruoyi.common.core.context.SecurityContextHolder.getUserId; @@ -66,11 +68,14 @@ private TChargingPileService chargingPileService; @Autowired private ISiteService siteService; @Autowired @Resource private SysUserClient sysUserClient; @Resource private IntegrationClient integrationClient; @Resource private TCECClient tcecClient; @Autowired @@ -386,12 +391,12 @@ site.setAccountingStrategyId(byId.getId()); } siteService.updateBatchById(list); // // accountingStrategyService.removeById(one.getId()); //推送三方平台 List<Integer> siteIds = list.stream().map(Site::getId).collect(Collectors.toList()); tcecClient.notificationStationChange(siteIds); } //硬件 ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/controller/TParkingLotController.java
@@ -158,6 +158,18 @@ } /** * 获取所有停车场数据 */ @PostMapping(value = "/getAllParkingLot") public R<List<TParkingLot>> getAllParkingLot(){ List<TParkingLot> list = parkingLotService.list(new LambdaQueryWrapper<TParkingLot>().eq(TParkingLot::getDelFlag, 0)); return R.fail(list); } @RequiresPermissions(value = {"/paymentOrder/order"}, logical = Logical.OR) @GetMapping(value = "/getRecordById") public R<TParkingRecord> getRecordById(@RequestParam("id") Long id){ ruoyi-service/ruoyi-chargingPile/src/main/java/com/ruoyi/chargingPile/service/impl/SiteServiceImpl.java
@@ -25,6 +25,7 @@ import com.ruoyi.common.security.service.TokenService; import com.ruoyi.common.security.utils.SecurityUtils; import com.ruoyi.integration.api.feignClient.IntegrationClient; import com.ruoyi.integration.api.feignClient.TCECClient; import com.ruoyi.other.api.domain.TVip; import com.ruoyi.other.api.feignClient.RoleSiteClient; import com.ruoyi.other.api.feignClient.UserSiteClient; @@ -72,8 +73,6 @@ @Resource private AppUserClient appUserClient; @Resource private VipClient vipClient; @Resource private SysUserRoleClient sysUserRoleClient; @Resource private TParkingLotService parkingLotService; @@ -88,6 +87,9 @@ @Resource private TPartnerSiteService partnerSiteService; @Resource private TCECClient tcecClient; /** @@ -462,5 +464,8 @@ for (TChargingPile tChargingPile : list1) { integrationClient.setupBillingModel1(tChargingPile.getCode(), JSON.toJSONString(accountingStrategyDetails)); } //推送三方平台 tcecClient.notificationStationChange(Arrays.asList(id)); } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECController.java
@@ -1,18 +1,16 @@ package com.ruoyi.integration.drainage; import com.alibaba.fastjson.JSON; import com.ruoyi.chargingPile.api.feignClient.AccountingStrategyDetailClient; import com.ruoyi.chargingPile.api.feignClient.ChargingGunClient; import com.ruoyi.chargingPile.api.feignClient.ChargingPileClient; import com.ruoyi.chargingPile.api.feignClient.SiteClient; import com.ruoyi.chargingPile.api.model.Site; import com.ruoyi.chargingPile.api.model.TAccountingStrategyDetail; import com.ruoyi.chargingPile.api.model.TChargingGun; import com.ruoyi.chargingPile.api.model.TChargingPile; import com.ruoyi.chargingPile.api.feignClient.*; import com.ruoyi.chargingPile.api.model.*; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.dto.ChargingPercentProvinceDto; import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.integration.drainage.kuaidian.TCECKDUtil; import com.ruoyi.integration.drainage.kuaidian.model.NotificationStationChangeResult; import com.ruoyi.integration.drainage.kuaidian.model.QueryTerminalCode; import com.ruoyi.integration.drainage.kuaidian.model.QueryTerminalCodeResult; import com.ruoyi.integration.drainage.model.*; import com.ruoyi.integration.drainage.model.enu.*; import com.ruoyi.order.api.feignClient.ChargingOrderAccountingStrategyClient; @@ -73,6 +71,10 @@ private TokenUtil tokenUtil; private static Map<Long, Integer> map = new HashMap<>(); @Resource private ParkingLotClient parkingLotClient; /** @@ -234,11 +236,12 @@ pageSize = 10; } PageInfo<Site> siteListPaging = siteClient.getSiteListPaging(pageNo, pageSize); List<TParkingLot> parkingLots = parkingLotClient.getAllParkingLot().getData(); QueryStationsInfoResult queryStationsInfoResult = new QueryStationsInfoResult(); queryStationsInfoResult.setPageNo(pageNo); queryStationsInfoResult.setPageCount((0 == (siteListPaging.getTotal() % pageSize) ? 0 : 1) + Double.valueOf(siteListPaging.getTotal() / pageSize).intValue()); queryStationsInfoResult.setItemSize(Long.valueOf(siteListPaging.getTotal()).intValue()); queryStationsInfoResult.setStationInfos(buildSite(siteListPaging.getRecords())); queryStationsInfoResult.setStationInfos(buildSite(parkingLots, siteListPaging.getRecords())); //参数加密 String jsonString = JSON.toJSONString(queryStationsInfoResult); String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv()); @@ -253,7 +256,7 @@ * @param sites * @return */ public List<StationInfo> buildSite(List<Site> sites){ public List<StationInfo> buildSite(List<TParkingLot> parkingLots, List<Site> sites){ List<Integer> siteIds = sites.stream().map(Site::getId).collect(Collectors.toList()); List<TChargingPile> tChargingPiles = chargingPileClient.getChargingPileBySiteIds(siteIds).getData(); List<Integer> collect1 = tChargingPiles.stream().map(TChargingPile::getId).collect(Collectors.toList()); @@ -312,12 +315,42 @@ stationInfo.setMatchCars(datum.getVehicleDescription()); stationInfo.setBusineHours(datum.getStartServiceTime() + "-" + datum.getEndServiceTime()); stationInfo.setElectricityFee(datum.getRateDescription()); //添加停车费信息 Optional<TParkingLot> first = parkingLots.stream().filter(s -> s.getSiteId().equals(datum.getId())).findFirst(); if(first.isPresent()){ TParkingLot tParkingLot = first.get(); buildPlaceHolder(tParkingLot, stationInfo); } //构建充电设备信息数据 stationInfo.setEquipmentInfos(buildEquipmentInfo(datum.getId(), tChargingPiles, chargingGunList)); StationInfos.add(stationInfo); } return StationInfos; } /** * 构建停车费信息 * @param tParkingLot * @param stationInfo */ public void buildPlaceHolder(TParkingLot tParkingLot, StationInfo stationInfo){ stationInfo.setOvertimeFee(tParkingLot.getName() + "停车费"); PlaceHolder placeHolder = new PlaceHolder(); placeHolder.setFreeTime(tParkingLot.getChargeFreeDuration()); placeHolder.setMaxFee(tParkingLot.getChargeCapping()); List<PlaceHolderPrice> PlaceHolderPrices = new ArrayList<>(); PlaceHolderPrice placeHolderPrice = new PlaceHolderPrice(); placeHolderPrice.setStartTime("00:00"); placeHolderPrice.setEndTime("23:59"); placeHolderPrice.setPrice(tParkingLot.getChargeRate()); PlaceHolderPrices.add(placeHolderPrice); placeHolder.setPlaceHolderPrices(PlaceHolderPrices); stationInfo.setPlaceHolder(placeHolder); } @@ -357,7 +390,7 @@ } //构建设备接口信息 equipmentInfo.setConnectorInfos(buildConnectorInfos(tChargingPile.getId(), chargingGunList)); equipmentInfo.setConnectorInfos(buildConnectorInfos(tChargingPile.getId(), tChargingPile.getCode(), chargingGunList)); equipmentInfos.add(equipmentInfo); } return equipmentInfos; @@ -369,7 +402,7 @@ * @param chargingGunList * @return */ public List<ConnectorInfo> buildConnectorInfos(Integer chargingPileId, List<TChargingGun> chargingGunList){ public List<ConnectorInfo> buildConnectorInfos(Integer chargingPileId, String code, List<TChargingGun> chargingGunList){ List<ConnectorInfo> connectorInfos = new ArrayList<>(); List<TChargingGun> collect = chargingGunList.stream().filter(s -> s.getChargingPileId().equals(chargingPileId)).collect(Collectors.toList()); for (TChargingGun chargingGun : collect) { @@ -402,6 +435,7 @@ connectorInfo.setPower(chargingGun.getRatedPower()); connectorInfo.setParkNo(chargingGun.getParkingNumber()); connectorInfo.setNationalStandard(Integer.valueOf(chargingGun.getNationalStandard())); connectorInfo.setQRCode("https://mxcd.zhinenganguan.com?No=" + code + chargingGun.getCode()); connectorInfos.add(connectorInfo); } return connectorInfos; @@ -732,6 +766,49 @@ /** * 站点变更推送通知(快电) * @param siteIds * @return */ @PostMapping("/notificationStationChange") public R notificationStationChange(@RequestParam("siteIds") List<Integer> siteIds){ Operator operator = operatorClient.getOperatorByName("KuaiDian").getData(); NotificationStationChangeResult notificationStationChange = TCECKDUtil.notificationStationChange(operator, 3, siteIds); //启动重试推送机制 if(null == notificationStationChange || 1 == notificationStationChange.getSuccStat()){ ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()); threadPoolExecutor.execute(new Runnable() { //计数器 Integer size = 0; @Override public void run() { NotificationStationChangeResult notificationStationChange1 = TCECKDUtil.notificationStationChange(operator, 3, siteIds); //启动重试推送机制 if(null != notificationStationChange1 && 0 == notificationStationChange1.getSuccStat()){ threadPoolExecutor.shutdown(); return; } size++; if(size >= 5){ threadPoolExecutor.shutdown(); return; } //间隔一分钟重试一次 try { Thread.sleep(60000); } catch (InterruptedException e) { throw new RuntimeException(e); } } }); } return R.ok(); } /** * 请求定充电 * @return */ @@ -788,6 +865,7 @@ addTripartitePlatformOrder.setOperatorId(operator.getOperatorId()); addTripartitePlatformOrder.setPaymentAmount(queryStartCharge.getPaymentAmount()); addTripartitePlatformOrder.setRechargePaymentType(queryStartCharge.getPaymentType()); addTripartitePlatformOrder.setPlateNum(queryStartCharge.getPlateNum()); R order = chargingOrderClient.addTripartitePlatformOrder(addTripartitePlatformOrder); //启动失败 if(200 != order.getCode()){ @@ -1238,4 +1316,37 @@ notificationChargeOrderInfo.setChargeDetails(chargeDetails); return notificationChargeOrderInfo; } /** * 二维码查询抢号(快电) * @param baseRequest * @param request * @return */ @PostMapping("/query_terminal_code") public BaseResult queryTerminalCode(@RequestBody BaseRequest baseRequest, HttpServletRequest request){ //校验token和签名 BaseResult baseResult = requestCheck(true, baseRequest, request); if(0 != baseResult.getRet()){ baseResult.setData(""); baseResult.setSig(TCECUtil.buildSign(baseResult)); return baseResult; } Operator operator = baseResult.getOperator(); //解密参数 String decrypt = AESUtil.decrypt(baseRequest.getData(), operator.getDataSecret(), operator.getDataSecretIv()); QueryTerminalCode queryTerminalCode = JSON.parseObject(decrypt, QueryTerminalCode.class); String qrCode = queryTerminalCode.getQRCode(); String substring = qrCode.substring(qrCode.indexOf("=") + 1); QueryTerminalCodeResult queryTerminalCodeResult = new QueryTerminalCodeResult(); queryTerminalCodeResult.setTerminalCode(substring); //参数加密 String jsonString = JSON.toJSONString(queryTerminalCodeResult); String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv()); baseResult.setData(encrypt); baseResult.setSig(TCECUtil.buildSign(baseResult)); return baseResult; } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/TCECUtil.java
@@ -4,6 +4,8 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.integration.drainage.kuaidian.model.NotificationStationChangeResult; import com.ruoyi.integration.drainage.kuaidian.model.StationChange; import com.ruoyi.integration.drainage.model.*; import com.ruoyi.integration.drainage.model.enu.InterfaceUrlEnum; import com.ruoyi.other.api.domain.Operator; @@ -15,7 +17,9 @@ import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 中电联TCEC标准 @@ -96,6 +100,32 @@ /** * 站点变更通知 * @param operator * @param type * @param siteIds * @return */ public static NotificationStationChangeResult notificationStationChange(Operator operator, Integer type, List<Integer> siteIds) { StationChange stationChange = new StationChange(); stationChange.setOperatorId(OperatorID); stationChange.setType(type); List<String> collect = siteIds.stream().map(String::valueOf).collect(Collectors.toList()); stationChange.setStationIds(collect); HttpRequest post = HttpUtil.createPost(operator.getTestUrl() + InterfaceUrlEnum.NOTIFICATION_STATION_CHANGE.getUrl()); buildBody(post, stationChange, operator); HttpResponse execute = post.execute(); if(200 != execute.getStatus()){ log.error("推送站点变更通知失败:" + execute.body()); return null; } return JSON.parseObject(execute.body(), NotificationStationChangeResult.class); } /** * 推送启动充电结果 * @param info * @return ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/TCECKDUtil.java
New file @@ -0,0 +1,159 @@ package com.ruoyi.integration.drainage.kuaidian; import cn.hutool.http.HttpRequest; import cn.hutool.http.HttpResponse; import cn.hutool.http.HttpUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.ruoyi.common.core.utils.SpringUtils; import com.ruoyi.integration.drainage.AESUtil; import com.ruoyi.integration.drainage.SignUtil; import com.ruoyi.integration.drainage.kuaidian.model.NotificationStationChangeResult; import com.ruoyi.integration.drainage.kuaidian.model.StationChange; import com.ruoyi.integration.drainage.model.*; import com.ruoyi.integration.drainage.model.enu.InterfaceUrlEnum; import com.ruoyi.other.api.domain.Operator; import com.ruoyi.other.api.feignClient.OperatorClient; import lombok.extern.slf4j.Slf4j; import java.time.Instant; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.format.DateTimeFormatter; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * 中电联TCEC标准(快电) * @author zhibing.pu * @Date 2025/1/21 11:48 */ @Slf4j public class TCECKDUtil { /** * 运营商标识 */ private static final String OperatorID = ""; private static OperatorClient operatorClient = SpringUtils.getBean(OperatorClient.class); private static Map<Long, Integer> map = new HashMap<>(); /** * 获取token */ public static String queryToken(Operator operator){ HttpRequest post = HttpUtil.createPost(""); post.contentType("application/json;charset=utf-8"); JSONObject body = new JSONObject(); body.put("OperatorID", OperatorID); body.put("OperatorSecret", operator.getOurOperatorSecret()); post.body(body.toJSONString()); HttpResponse execute = post.execute(); if(200 != execute.getStatus()){ log.error("获取三方token失败:" + execute.body()); return null; } JSONObject jsonObject = JSON.parseObject(execute.body()); Integer succStat = jsonObject.getInteger("SuccStat"); if(0 != succStat){ log.error("获取三方token失败:" + jsonObject.getString("FailReason")); return null; } String token = jsonObject.getString("AccessToken"); Long tokenAvailableTime = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) + jsonObject.getLong("TokenAvailableTime"); LocalDateTime localDateTime = Instant.ofEpochSecond(tokenAvailableTime).atOffset(ZoneOffset.UTC).toLocalDateTime(); operator.setAccessToken(token); operator.setTokenAvailableTime(localDateTime); operatorClient.editOperator(operator); return token; } /** * 获取token * @return */ public static String getToken(Operator operator){ if(null != operator.getTokenAvailableTime() && operator.getTokenAvailableTime().isBefore(LocalDateTime.now())){ return operator.getAccessToken(); }else{ return queryToken(operator); } } /** * 站点变更通知 * @param operator * @param type * @param siteIds * @return */ public static NotificationStationChangeResult notificationStationChange(Operator operator, Integer type, List<Integer> siteIds) { StationChange stationChange = new StationChange(); stationChange.setOperatorId(OperatorID); stationChange.setType(type); List<String> collect = siteIds.stream().map(String::valueOf).collect(Collectors.toList()); stationChange.setStationIds(collect); HttpRequest post = HttpUtil.createPost(operator.getTestUrl() + InterfaceUrlEnum.NOTIFICATION_STATION_CHANGE.getUrl()); buildBody(post, stationChange, operator); HttpResponse execute = post.execute(); if(200 != execute.getStatus()){ log.error("推送站点变更通知失败:" + execute.body()); return null; } return JSON.parseObject(execute.body(), NotificationStationChangeResult.class); } /** * 构建请求参数和消息头 * @param post * @param o */ public static void buildBody(HttpRequest post, Object o, Operator operator){ Long timeStamp = Long.valueOf(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); Integer integer = map.get(timeStamp); if(null == integer){ integer = 1; }else{ integer++; } map.put(timeStamp, integer); post.contentType("application/json;charset=utf-8"); post.header("Authorization", "Bearer " + getToken(operator)); BaseRequest baseRequest = new BaseRequest(); baseRequest.setOperatorID(OperatorID); baseRequest.setTimeStamp(timeStamp); baseRequest.setSeq(String.format("%04d", integer)); String jsonString = JSON.toJSONString(o); String encrypt = AESUtil.encrypt(jsonString, operator.getDataSecret(), operator.getDataSecretIv()); baseRequest.setData(encrypt); baseRequest.setOperator(operator); baseRequest.setSig(buildSign(baseRequest)); post.body(JSON.toJSONString(baseRequest)); //清空小于当前时间的map中的无效数据 for (Long k : map.keySet()) { if(k <= (timeStamp - 10)){ map.remove(k); } } } public static String buildSign(BaseModel model){ Operator operator = model.getOperator(); //签名秘钥SigSecret String key = operator.getSigSecret(); String sign = SignUtil.hmacSign(model.getData(), key); return sign; } } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/NotificationStationChangeResult.java
New file @@ -0,0 +1,40 @@ package com.ruoyi.integration.drainage.kuaidian.model; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; /** * 站点变更通知返回结果 * @author zhibing.pu * @Date 2025/1/26 10:45 */ @Data public class NotificationStationChangeResult { /** * 运营商ID */ @NotNull private String OperatorId; /** * 站点ID */ @NotNull private List<String> StationIds; /** * 成功状态 * 0:成功 * 1:失败 */ @NotNull private Integer SuccStat; /** * 失败原因 * 0:无 * 1:无效站点 * 2`9:自定义 */ @NotNull private Integer FailReason; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryTerminalCode.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.integration.drainage.kuaidian.model; import lombok.Data; import javax.validation.constraints.NotNull; /** * 二维码查询抢号 * @author zhibing.pu * @Date 2025/1/26 11:12 */ @Data public class QueryTerminalCode { /** * 二维码信息 */ @NotNull private String QRCode; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/QueryTerminalCodeResult.java
New file @@ -0,0 +1,19 @@ package com.ruoyi.integration.drainage.kuaidian.model; import lombok.Data; import javax.validation.constraints.NotNull; /** * 二维码查询抢号结果 * @author zhibing.pu * @Date 2025/1/26 11:18 */ @Data public class QueryTerminalCodeResult { /** * 枪号 */ @NotNull private String TerminalCode; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/kuaidian/model/StationChange.java
New file @@ -0,0 +1,31 @@ package com.ruoyi.integration.drainage.kuaidian.model; import lombok.Data; import javax.validation.constraints.NotNull; import java.util.List; /** * 站点变更通知 * @author zhibing.pu * @Date 2025/1/26 10:34 */ @Data public class StationChange { /** * 运营商ID */ @NotNull private String operatorId; /** * 变更类型 * 3:站点计费策略变更 */ @NotNull private Integer type; /** * 站点ID */ @NotNull private List<String> stationIds; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/ConnectorInfo.java
@@ -60,4 +60,9 @@ */ @NotNull private Integer NationalStandard; /** * 枪二维码 */ @Null private String QRCode; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PlaceHolder.java
New file @@ -0,0 +1,42 @@ package com.ruoyi.integration.drainage.model; import lombok.Data; import javax.validation.constraints.NotNull; import java.math.BigDecimal; import java.util.List; /** * 占位费信息 * @author zhibing.pu * @Date 2025/1/26 9:29 */ @Data public class PlaceHolder { /** * 免费时长 */ @NotNull private Integer FreeTime; /** * 嘴阀占位费 */ @NotNull private BigDecimal MaxFee; /** * 生效开始时间 * yyyy-MM-dd HH:mm:ss */ @NotNull private String EffectStartTime; /** * 生效结束时间 */ @NotNull private String EffectEndTime; /** * 占位费价格 */ @NotNull private List<PlaceHolderPrice> PlaceHolderPrices; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/PlaceHolderPrice.java
New file @@ -0,0 +1,32 @@ package com.ruoyi.integration.drainage.model; import lombok.Data; import javax.validation.constraints.NotNull; import java.math.BigDecimal; /** * 占位费价格 * @author zhibing.pu * @Date 2025/1/26 9:33 */ @Data public class PlaceHolderPrice { /** * 开始时段 * HH:mm */ @NotNull private String StartTime; /** * 结束时段 * HH:mm */ @NotNull private String EndTime; /** * 单价 */ @NotNull private BigDecimal Price; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStartCharge.java
@@ -3,6 +3,7 @@ import lombok.Data; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; import java.math.BigDecimal; /** @@ -37,4 +38,9 @@ */ @NotNull private BigDecimal paymentAmount; /** * 充电车牌号 */ @Null private String PlateNum; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStartChargeResult.java
@@ -3,6 +3,7 @@ import lombok.Data; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; /** * 请求启动充电返回结果 ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/QueryStationsInfoResult.java
@@ -2,6 +2,8 @@ import lombok.Data; import javax.validation.constraints.NotNull; import javax.validation.constraints.Null; import java.util.List; /** @@ -14,17 +16,21 @@ /** * 当前页数 */ @NotNull private Integer PageNo; /** * 页码总数 */ @NotNull private Integer PageCount; /** * 总记录条数 */ @NotNull private Integer ItemSize; /** * 充电站信息列表 */ @NotNull private List<StationInfo> StationInfos; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/StationInfo.java
@@ -151,4 +151,14 @@ */ @NotNull private List<EquipmentInfo> EquipmentInfos; /** * 占位费描述 */ @Null private String OvertimeFee; /** * 占位费信息 */ @Null private PlaceHolder PlaceHolder; } ruoyi-service/ruoyi-integration/src/main/java/com/ruoyi/integration/drainage/model/enu/InterfaceUrlEnum.java
@@ -7,6 +7,7 @@ */ public enum InterfaceUrlEnum { NOTIFICATION_STATION_STATUS("/notification_station_status", "设备状态变化推送"), NOTIFICATION_STATION_CHANGE("/notification_station_change", "站点计费策略变更推送"), NOTIFICATION_START_CHARGE_RESULT("/notification_start_charge_result", "推送启动充电结果"), NOTIFICATION_EQUIP_CHARGE_STATUS("/notification_equip_charge_status", "推送充电状态"), NOTIFICATION_STOP_CHARGE_RESULT("/notification_stop_charge_result", "推送停止充电结果"), ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/controller/TChargingOrderController.java
@@ -2101,10 +2101,7 @@ */ @PostMapping("/addTripartitePlatformOrder") public R addTripartitePlatformOrder(@RequestBody AddTripartitePlatformOrder query){ return chargingOrderService.addTripartitePlatformOrder(query.getChargingGunId(), query.getOperatorId(), query.getRechargePaymentType(), query.getPaymentAmount(), query.getStartChargeSeq()); return chargingOrderService.addTripartitePlatformOrder(query); } ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/TChargingOrderService.java
@@ -7,10 +7,7 @@ import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.page.PageInfo; import com.ruoyi.order.api.dto.SettlementConfirmAdd; import com.ruoyi.order.api.model.ChargingListQuery; import com.ruoyi.order.api.model.TChargingOrder; import com.ruoyi.order.api.model.TChargingOrderRefund; import com.ruoyi.order.api.model.TSettlementConfirm; import com.ruoyi.order.api.model.*; import com.ruoyi.order.api.query.ChargingOrderQuery; import com.ruoyi.order.api.query.SettlementListQuery; import com.ruoyi.order.api.query.UploadRealTimeMonitoringDataQuery; @@ -292,9 +289,9 @@ /** * 添加三方平台充电订单数据 * @param chargingGunId * @param query */ R addTripartitePlatformOrder(Integer chargingGunId, String operatorId, Integer rechargePaymentType, BigDecimal paymentAmount, String startChargeSeq); R addTripartitePlatformOrder(AddTripartitePlatformOrder query); /** ruoyi-service/ruoyi-order/src/main/java/com/ruoyi/order/service/impl/TChargingOrderServiceImpl.java
@@ -4019,12 +4019,12 @@ /** * 添加三方平台充电订单数据 * @param chargingGunId * @param query */ @Override public R addTripartitePlatformOrder(Integer chargingGunId, String operatorId, Integer rechargePaymentType, BigDecimal paymentAmount, String startChargeSeq) { public R addTripartitePlatformOrder(AddTripartitePlatformOrder query) { //检查当前枪是否是正在使用中 TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, chargingGunId) TChargingOrder one = this.getOne(new LambdaQueryWrapper<TChargingOrder>().eq(TChargingOrder::getChargingGunId, query.getChargingGunId()) .in(TChargingOrder::getStatus, Arrays.asList(1, 2, 3)).eq(TChargingOrder::getDelFlag, 0)); if(null != one){ return R.fail("充电枪正在充电中,启动失败"); @@ -4037,21 +4037,30 @@ chargingOrder.setCode(code); chargingOrder.setOrderType(1); chargingOrder.setOrderClassification(1); TChargingGun tChargingGun = chargingGunClient.getChargingGunById(chargingGunId).getData(); TChargingGun tChargingGun = chargingGunClient.getChargingGunById(query.getChargingGunId()).getData(); TChargingPile chargingPile = chargingPileClient.getChargingPileById(tChargingGun.getChargingPileId()).getData(); chargingOrder.setSiteId(tChargingGun.getSiteId()); chargingOrder.setChargingPileId(tChargingGun.getChargingPileId()); chargingOrder.setChargingGunId(chargingGunId); chargingOrder.setRechargePaymentType(rechargePaymentType); chargingOrder.setChargingGunId(query.getChargingGunId()); chargingOrder.setRechargePaymentType(query.getRechargePaymentType()); chargingOrder.setRechargePaymentStatus(2); chargingOrder.setRechargeAmount(paymentAmount); chargingOrder.setRechargeAmount(query.getPaymentAmount()); chargingOrder.setVipDiscountAmount(BigDecimal.ZERO); chargingOrder.setOrderSource(2); Operator operator = operatorClient.getOperator(operatorId).getData(); Operator operator = operatorClient.getOperator(query.getOperatorId()).getData(); chargingOrder.setOperatorId(operator.getId()); chargingOrder.setAppUserId(operator.getId().longValue()); chargingOrder.setTripartitePlatformName(operator.getName()); chargingOrder.setStartChargeSeq(startChargeSeq); chargingOrder.setStartChargeSeq(query.getStartChargeSeq()); //车辆信息 if(StringUtils.hasLength(query.getPlateNum())){ TAppUserCar appUserCar = appUserCarClient.getAppUserCarByLicensePlate(query.getPlateNum()).getData(); if(null != appUserCar){ chargingOrder.setAppUserCarId(appUserCar.getId()); } } chargingOrder.setTitle("【充电桩充电】" + chargingPile.getNumber() + "号桩/" + tChargingGun.getCode() + "号枪"); chargingOrder.setStatus(2); chargingOrder.setPayTime(LocalDateTime.now()); ruoyi-service/ruoyi-other/src/main/java/com/ruoyi/other/controller/OperatorController.java
@@ -35,6 +35,19 @@ /** * 获取运营商数据 * @param name * @return */ @PostMapping("/getOperatorByName") public R<Operator> getOperatorByName(@RequestParam("name") String name){ Operator operator = operatorService.getOne(new LambdaQueryWrapper<Operator>().eq(Operator::getName, name)); return R.ok(operator); } /** * 获取运营商数据