diff --git a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCChargeChargeStatusResponse.java b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCChargeChargeStatusResponse.java new file mode 100644 index 00000000..98057b2b --- /dev/null +++ b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCChargeChargeStatusResponse.java @@ -0,0 +1,19 @@ +package com.xhpc.evcs.cyc.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; +import lombok.Data; + +@JsonPropertyOrder({ + "StartChargeSeq", + "SuccStat" +}) +@Data +public class CYCChargeChargeStatusResponse { + @JsonProperty("StartChargeSeq") + private String startChargeSeq; + + @JsonProperty("SuccStat") + private Integer succStat; + +} diff --git a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCChargeOrderInfoResponse.java b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCChargeOrderInfoResponse.java new file mode 100644 index 00000000..66533f03 --- /dev/null +++ b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCChargeOrderInfoResponse.java @@ -0,0 +1,66 @@ +package com.xhpc.evcs.cyc.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonPropertyOrder({ + "StartChargeSeq", + "SuccStat", + "FailReason", + "IdentCode" +}) +public class CYCChargeOrderInfoResponse { + @JsonProperty("StartChargeSeq") + private String startChargeSeq; + + @JsonProperty("SuccStat") + private Integer succStat; + + @JsonProperty("FailReason") + private Integer failReason; + + @JsonProperty("IdentCode") + private String identCode; + + public String getStartChargeSeq() { + return startChargeSeq; + } + + public void setStartChargeSeq(String startChargeSeq) { + this.startChargeSeq = startChargeSeq; + } + + public Integer getSuccStat() { + return succStat; + } + + public void setSuccStat(Integer succStat) { + this.succStat = succStat; + } + + public Integer getFailReason() { + return failReason; + } + + public void setFailReason(Integer failReason) { + this.failReason = failReason; + } + + public String getIdentCode() { + return identCode; + } + + public void setIdentCode(String identCode) { + this.identCode = identCode; + } + + @Override + public String toString() { + return "CYCChargeOrderInfoResponse{" + + "startChargeSeq='" + startChargeSeq + '\'' + + ", succStat=" + succStat + + ", failReason=" + failReason + + ", identCode='" + identCode + '\'' + + '}'; + } +} diff --git a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCConnectorChargeStatusInfo.java b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCConnectorChargeStatusInfo.java index e5862860..d5a6d858 100644 --- a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCConnectorChargeStatusInfo.java +++ b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCConnectorChargeStatusInfo.java @@ -18,14 +18,20 @@ import javax.persistence.Column; "ConnectorID", "ConnectorStatus", "CurrentA", + "CurrentB", + "CurrentC", "VoltageA", + "VoltageB", + "VoltageC", "Soc", "StartTime", "EndTime", "TotalPower", "ElecMoney", "SeviceMoney", - "TotalMoney" + "TotalMoney", + "SumPeriod", + "ChargeDetails" }) @Data public class CYCConnectorChargeStatusInfo { @@ -51,43 +57,36 @@ public class CYCConnectorChargeStatusInfo { @JsonProperty("ConnectorStatus") public Integer connectorStatus; - - -// /** -// * 车辆识别码 -// */ -// @JsonProperty("Vin") -// public String vin; /** * A 相电流 */ @JsonProperty("CurrentA") public Double currentA; -// /** -// * B 相电流 -// */ -// @JsonProperty("CurrentB") -// public Double currentB; -// /** -// * C 相电流 -// */ -// @JsonProperty("CurrentC") -// public Double currentC; + /** + * B 相电流 + */ + @JsonProperty("CurrentB") + public Double currentB; + /** + * C 相电流 + */ + @JsonProperty("CurrentC") + public Double currentC; /** * A 相电压 */ @JsonProperty("VoltageA") public Double voltageA; -// /** -// * B 相电压 -// */ -// @JsonProperty("VoltageB") -// public Double voltageB; -// /** -// * C 相电压 -// */ -// @JsonProperty("VoltageC") -// public Double voltageC; + /** + * B 相电压 + */ + @JsonProperty("VoltageB") + public Double voltageB; + /** + * C 相电压 + */ + @JsonProperty("VoltageC") + public Double voltageC; /** * 电池剩余电量 */ @@ -128,5 +127,12 @@ public class CYCConnectorChargeStatusInfo { @JsonProperty("TotalMoney") @Column(columnDefinition = "Decimal(10,2)") public Double totalMoney; + /** + * 时段数N + */ + @JsonProperty("SumPeriod") + public Integer sumPeriod; + @JsonProperty("ChargeDetails") + private com.xhpc.evcs.dto.ChargeDetails[] chargeDetails; } diff --git a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCNotificationStartChargeResultRequestData.java b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCNotificationStartChargeResultRequestData.java new file mode 100644 index 00000000..9028e66d --- /dev/null +++ b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/cyc/dto/CYCNotificationStartChargeResultRequestData.java @@ -0,0 +1,71 @@ +package com.xhpc.evcs.cyc.dto; + +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.JsonPropertyOrder; + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonPropertyOrder({ + "StartChargeSeq", + "StartChargeSeqStat", + "ConnectorID", + "StartTime", + "Mobile" +}) +public class CYCNotificationStartChargeResultRequestData { + + @JsonProperty("StartChargeSeq") + private String startChargeSeq; + + @JsonProperty("StartChargeSeqStat") + private Integer startChargeSeqStat; + + @JsonProperty("ConnectorID") + private String connectorId; + + @JsonProperty("StartTime") + private String startTime; + + @JsonProperty("Mobile") + private String mobile; + + public String getStartChargeSeq() { + return startChargeSeq; + } + + public void setStartChargeSeq(String startChargeSeq) { + this.startChargeSeq = startChargeSeq; + } + + public Integer getStartChargeSeqStat() { + return startChargeSeqStat; + } + + public void setStartChargeSeqStat(Integer startChargeSeqStat) { + this.startChargeSeqStat = startChargeSeqStat; + } + + public String getConnectorId() { + return connectorId; + } + + public void setConnectorId(String connectorId) { + this.connectorId = connectorId; + } + + public String getStartTime() { + return startTime; + } + + public void setStartTime(String startTime) { + this.startTime = startTime; + } + + public String getMobile() { + return mobile; + } + + public void setMobile(String mobile) { + this.mobile = mobile; + } +} diff --git a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/encryption/Aes128Cbc.java b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/encryption/Aes128Cbc.java index 15676852..e5a13832 100644 --- a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/encryption/Aes128Cbc.java +++ b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/encryption/Aes128Cbc.java @@ -1,5 +1,10 @@ package com.xhpc.evcs.encryption; +import com.xhpc.evcs.cyc.dto.CYCChargeOrderInfoResponse; +import com.xhpc.evcs.domain.AuthSecretToken; +import com.xhpc.evcs.dto.ChargeOrderInfoResponse; +import com.xhpc.evcs.dto.DTOJsonHelper; + import javax.crypto.*; import javax.crypto.spec.SecretKeySpec; import java.io.UnsupportedEncodingException; @@ -9,6 +14,9 @@ import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Base64; +import java.util.Optional; + +import static com.xhpc.evcs.domain.AuthSecretToken.SECRET_TOKEN_TYPE_OUT; public class Aes128Cbc { @@ -69,5 +77,12 @@ public class Aes128Cbc { System.out.println(encrypt("{\"StationIDs\":[\"1\"]}", "8LpncubmWiPCzY3V", "av6A8QdnRaVRMXu6")); System.out.println(encrypt("{\"OperatorID\":\"MA5FNJXW9\", \"OperatorSecret\":\"Ut5UFdqDthiJyncU\"}", "8LpncubmWiPCzY3V", "av6A8QdnRaVRMXu6")); + + //{"Ret":0,"Msg":"","Data":"pCA3UNQO1CqxRS6KvcNDpw==","Sig":"FCCCA9489FAD972722FB00E4E207F581"} + String responseBody = "{\"Ret\":0,\"Msg\":\"\",\"Data\":\"pCA3UNQO1CqxRS6KvcNDpw==\",\"Sig\":\"FCCCA9489FAD972722FB00E4E207F581\"}"; + + + + } } diff --git a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/utils/DateUtil.java b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/utils/DateUtil.java index 848357cc..6c518815 100644 --- a/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/utils/DateUtil.java +++ b/evcs-modules/evcs-common/src/main/java/com/xhpc/evcs/utils/DateUtil.java @@ -485,6 +485,10 @@ public class DateUtil { DateUtil.isWeekend(DateUtil.string2Date("2016-06-12", "yyyy-MM-dd")); DateUtil.isWeekend(DateUtil.string2Date("2016-06-13", "yyyy-MM-dd")); DateUtil.isWeekend(DateUtil.string2Date("2016-06-14", "yyyy-MM-dd")); + + + + } } diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cdjgpc/api/CDNotificationStationInfoController.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cdjgpc/api/CDNotificationStationInfoController.java index ad934f22..b8153cc3 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cdjgpc/api/CDNotificationStationInfoController.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cdjgpc/api/CDNotificationStationInfoController.java @@ -9,11 +9,15 @@ import com.xhpc.common.data.redis.CacheRateModel; import com.xhpc.common.data.redis.CacheRealtimeData; import com.xhpc.common.domain.XhpcTerminal; import com.xhpc.evcs.cdjgpc.dto.*; +import com.xhpc.evcs.cyc.dto.CYCNotificationStartChargeResultRequestData; import com.xhpc.evcs.domain.AuthSecretToken; import com.xhpc.evcs.domain.XhpcInternetUser; import com.xhpc.evcs.domain.XhpcStationInternetBlacklist; import com.xhpc.evcs.dto.*; +import com.xhpc.evcs.encryption.Aes128Cbc; import com.xhpc.evcs.encryption.EvcsConst; +import com.xhpc.evcs.http.ForbiddenException; +import com.xhpc.evcs.http.ServerInternalException; import com.xhpc.evcs.jpa.AuthSecretTokenRepository; import com.xhpc.evcs.jpa.XhpcInternetUserRepository; import com.xhpc.evcs.jpa.XhpcStationInternetBlacklistRepository; @@ -21,15 +25,20 @@ import com.xhpc.evcs.jpa.XhpcTerminalRepository; import com.xhpc.evcs.notification.CoreDispatcher; import com.xhpc.evcs.utils.JSONUtil; import lombok.extern.slf4j.Slf4j; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; import org.springframework.web.bind.annotation.*; import static cn.hutool.core.util.NumberUtil.isInteger; import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS; import javax.annotation.Resource; +import java.io.IOException; import java.math.BigDecimal; import java.time.Instant; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; import static com.xhpc.evcs.config.EvcsFilter.encryptReqOut; import static com.xhpc.evcs.domain.AuthSecretToken.SECRET_TOKEN_TYPE_IN; @@ -725,8 +734,8 @@ public class CDNotificationStationInfoController extends CoreDispatcher { @PostMapping("/v10/getEncrytReqout") public R getEncrytReqout(){ try{ - CommonRequest commonRequest = new CommonRequest<>(); - commonRequest.setOperatorId("MA6CC2LK7"); +// CommonRequest commonRequest = new CommonRequest<>(); +// commonRequest.setOperatorId("MA6CC2LK7"); // StationStatsRequest stationStatsRequest = new StationStatsRequest(); // stationStatsRequest.setStationID("20"); // stationStatsRequest.setStartTime("2023-10-01"); @@ -748,54 +757,49 @@ public class CDNotificationStationInfoController extends CoreDispatcher { // CDSuperviseQueryEquipmentPowerInfoRequest cdSuperviseQueryEquipmentPowerInfoRequest = new CDSuperviseQueryEquipmentPowerInfoRequest(); // cdSuperviseQueryEquipmentPowerInfoRequest.setStationID("20"); // cdSuperviseQueryEquipmentPowerInfoRequest.setDataTime("2023-10-13"); - CDEquipAuthRequest equipAuthRequest = new CDEquipAuthRequest(); - equipAuthRequest.setEquipAuthSeq("MA6DFCTD5202310161544441234"); - equipAuthRequest.setConnectorId("8083600020000101"); - equipAuthRequest.setQRCode("12312312312323"); - String data = JSONUtil.toJSONString(equipAuthRequest); - System.out.println("===data==="+data); +// CDEquipAuthRequest equipAuthRequest = new CDEquipAuthRequest(); +// equipAuthRequest.setEquipAuthSeq("MA6DFCTD5202310161544441234"); +// equipAuthRequest.setConnectorId("8083600020000101"); +// equipAuthRequest.setQRCode("12312312312323"); +// String data = JSONUtil.toJSONString(equipAuthRequest); +// System.out.println("===data==="+data); +// commonRequest.setData(data); +// AuthSecretToken authSecretTokenOut =authSecretTokenRepository.findByOperatorId3irdptyAndOperatorIdAndSecretTokenType( +// "MA6CC2LK7", "MA6DFCTD5", SECRET_TOKEN_TYPE_IN).orElse(null); +// String tData = encryptReqOut(authSecretTokenOut.getDataSecret(), authSecretTokenOut.getDataSecretIV(), +// authSecretTokenOut.getSigSecret(), commonRequest); +// System.out.println("===tData==="+tData); + + CommonRequest commonRequest = new CommonRequest<>(); + + Map map =new HashMap<>(); + map.put("PageNo","1"); + map.put("PageSize","10"); + String data = JSONUtil.toJSONString(map); + + //String data111 = Aes128Cbc.encrypt(data, "8LpncubmWiPCzY3V", "av6A8QdnRaVRMXu6"); commonRequest.setData(data); + commonRequest.setOperatorId("MA25CNM38"); AuthSecretToken authSecretTokenOut =authSecretTokenRepository.findByOperatorId3irdptyAndOperatorIdAndSecretTokenType( - "MA6CC2LK7", "MA6DFCTD5", SECRET_TOKEN_TYPE_IN).orElse(null); - String tData = encryptReqOut(authSecretTokenOut.getDataSecret(), authSecretTokenOut.getDataSecretIV(), - authSecretTokenOut.getSigSecret(), commonRequest); - System.out.println("===tData==="+tData); -// String bearerToken = authSecretTokenOut.getToken(); -// okhttp3.RequestBody body = okhttp3.RequestBody.create(JSON, tData); -// final Request.Builder req = new Request.Builder() -// .url("http://localhost:9009/v10" + "/query_station_stats") -// .header("Authorization", "Bearer " + bearerToken); -// Request request; -// request = req.post(body).build(); -// OkHttpClient.Builder builder = new OkHttpClient.Builder(); -// builder.connectTimeout(10, TimeUnit.SECONDS) -// .readTimeout(10, TimeUnit.SECONDS) -// .writeTimeout(10, TimeUnit.SECONDS); -// OkHttpClient client = builder.build(); -// -// String responseBody = null; -// try { -// Response response = client.newCall(request).execute(); -// if (response.isSuccessful()) { -// okhttp3.ResponseBody body1 = response.body(); -// responseBody = body1 == null ? null : body1.string(); -// } else { -// int code = response.code(); -// if (code == 401 || code == 403) { -// throw new ForbiddenException("Remote system returned " + code); -// } -// } -// } catch (IOException e) { -// String msg = e.getMessage(); -// log.error(msg); -// throw new ServerInternalException(msg); -// } -// System.out.println("=============responseBody=============="+responseBody); - return R.ok(null); + "MA25CNM38", "MA6DFCTD5", SECRET_TOKEN_TYPE_IN).orElse(null); + + String result = okYu(commonRequest, "/query_stations_info", authSecretTokenOut,"MA25CNM38"); + + + System.out.println("==========result=============="+result); + + +// String rawData = "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"; +// String dataSecret="8LpncubmWiPCzY3V"; +// String dataSecretIV="av6A8QdnRaVRMXu6"; +// String data = Aes128Cbc.encrypt(rawData, dataSecret, dataSecretIV); + +// System.out.println("==========data=============="+data); + }catch (Exception e){ e.printStackTrace(); } - return R.fail(); + return R.fail(); } diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cyc/api/CYCNotificationStationInfoController.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cyc/api/CYCNotificationStationInfoController.java index 2ae67226..de044d83 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cyc/api/CYCNotificationStationInfoController.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/cyc/api/CYCNotificationStationInfoController.java @@ -4,17 +4,19 @@ import cn.hutool.core.date.DateUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.xhpc.common.data.redis.CacheRateModel; import com.xhpc.common.data.redis.CacheRealtimeData; +import com.xhpc.evcs.cyc.dto.CYCChargeChargeStatusResponse; +import com.xhpc.evcs.cyc.dto.CYCChargeOrderInfoResponse; import com.xhpc.evcs.cyc.dto.CYCConnectorChargeStatusInfo; +import com.xhpc.evcs.cyc.dto.CYCNotificationStartChargeResultRequestData; import com.xhpc.evcs.domain.AuthSecretToken; import com.xhpc.evcs.dto.CommonRequest; -import com.xhpc.evcs.dto.ConnectorStatusInfoReq; +import com.xhpc.evcs.dto.DTOJsonHelper; import com.xhpc.evcs.jpa.AuthSecretTokenRepository; import com.xhpc.evcs.notification.CoreDispatcher; import com.xhpc.evcs.utils.JSONUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; @@ -22,6 +24,7 @@ import java.math.BigDecimal; import java.util.Date; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS; import static com.xhpc.evcs.domain.AuthSecretToken.SECRET_TOKEN_TYPE_OUT; @@ -39,6 +42,7 @@ public class CYCNotificationStationInfoController extends CoreDispatcher { @PostMapping("/v20/getCYCNotificationConnectorChargeStatus") public void getCYCNotificationConnectorChargeStatus(@RequestBody Map orderMap){ System.out.println("==================设备充电中状态变化推送(川逸充) =========================="); + System.out.println("==================设备充电中状态变化推送(川逸充) =============orderMap============="+orderMap.toString()); //先查订单号 在查实时数据 最后计算金额 try { String orderNo = orderMap.get("orderNo").toString(); @@ -65,55 +69,121 @@ public class CYCNotificationStationInfoController extends CoreDispatcher { if("已结束".equals(cacheMapOrder.get("status").toString())){ cdConnectorChargeStatusInfo.setConnectorStatus(1); cdConnectorChargeStatusInfo.setStartChargeSeqStat(4); + //cdConnectorChargeStatusInfo.setSoc((double)cacheMapOrder.get("endSoc")); }else{ cdConnectorChargeStatusInfo.setConnectorStatus(3); cdConnectorChargeStatusInfo.setStartChargeSeqStat(2); } } REDIS.setCacheMap("order:"+orderNo+".notification",cacheMap); - cdConnectorChargeStatusInfo.setStartChargeSeq(lord.getOrderNo()); + + Map pushOrder = REDIS.getCacheMap("pushOrder:"+orderNo); + cdConnectorChargeStatusInfo.setStartChargeSeq((String) pushOrder.get("internetSerialNumber")); cdConnectorChargeStatusInfo.setConnectorID(lord.getPileNo()+lord.getGunId()); cdConnectorChargeStatusInfo.setCurrentA((double)(lord.getWorkingCurrent()/10)); cdConnectorChargeStatusInfo.setVoltageA((double)(lord.getWorkingVoltage()/10)); - cdConnectorChargeStatusInfo.setSoc((double)lord.getSoc()); + cdConnectorChargeStatusInfo.setEndTime(formatTime); BigDecimal chargingDegree = new BigDecimal(lord.getChargingDegree()).divide(new BigDecimal(10000).setScale(2, BigDecimal.ROUND_UP)); - BigDecimal amountCharged = new BigDecimal(lord.getAmountCharged()).divide(new BigDecimal(10000).setScale(2, BigDecimal.ROUND_UP)); - cdConnectorChargeStatusInfo.setTotalPower(chargingDegree.doubleValue()); - cdConnectorChargeStatusInfo.setTotalMoney(amountCharged.doubleValue()); + cdConnectorChargeStatusInfo.setTotalPower(chargingDegree.setScale(2,BigDecimal.ROUND_CEILING).doubleValue()); Map cacheOrder = REDIS.getCacheMap("order:" + orderNo); if(cacheOrder !=null && cacheOrder.get("rateModelId") !=null){ - CacheRateModel rateModel = REDIS.getCacheObject("rateModel:" + cacheOrder.get("rateModelId").toString()); - if(rateModel.getT1SvcPrice().equals(rateModel.getT2SvcPrice()) && rateModel.getT3SvcPrice().equals(rateModel.getT4SvcPrice()) && - rateModel.getT1SvcPrice().equals(rateModel.getT3SvcPrice())){ - BigDecimal divide = new BigDecimal(rateModel.getT1SvcPrice()).divide(new BigDecimal(100000)).setScale(2, BigDecimal.ROUND_UP); - - BigDecimal bigDecimal = chargingDegree.multiply(divide).setScale(2, BigDecimal.ROUND_UP); - cdConnectorChargeStatusInfo.setSeviceMoney(bigDecimal.doubleValue()); - BigDecimal subtract = amountCharged.subtract(bigDecimal); - cdConnectorChargeStatusInfo.setElecMoney(subtract.doubleValue()); - }else{ - //暂时不考虑不同服务费 默认为0.2 - BigDecimal multiply = chargingDegree.multiply(new BigDecimal(0.2)).setScale(2, BigDecimal.ROUND_UP);; - cdConnectorChargeStatusInfo.setSeviceMoney(multiply.doubleValue()); - BigDecimal subtract = amountCharged.subtract(multiply); - cdConnectorChargeStatusInfo.setElecMoney(subtract.doubleValue()); - } + cdConnectorChargeStatusInfo.setElecMoney(new BigDecimal(orderMap.get("elecMoney").toString()).doubleValue()); + cdConnectorChargeStatusInfo.setSeviceMoney(new BigDecimal(orderMap.get("seviceMoney").toString()).doubleValue()); + cdConnectorChargeStatusInfo.setTotalMoney(new BigDecimal(orderMap.get("totalMoney").toString()).doubleValue()); AuthSecretToken authSecretTokenOut = authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType("MA6CC2LK7", SECRET_TOKEN_TYPE_OUT).orElse(null); //Map map =new HashMap<>(); //map.put("ConnectorChargeStatusInfo",cdConnectorChargeStatusInfo); String data = JSONUtil.toJSONString(cdConnectorChargeStatusInfo); - CommonRequest commonRequest = new CommonRequest<>(); + System.out.println("===川逸充设备充电中状态变化推送====data========"+data); + CommonRequest commonRequest = new CommonRequest<>(); commonRequest.setData(data); - String result = ok(commonRequest, "/notification_connector_charge_status", authSecretTokenOut); - System.out.println("===设备充电中状态变化推送====result========"+result); + String result = ok(commonRequest, "/notification_equip_charge_status", authSecretTokenOut); + System.out.println("===川逸充设备充电中状态变化推送====result========"+result); + CYCChargeChargeStatusResponse chargeStatusResponse = DTOJsonHelper.parseResponseData(result, CYCChargeChargeStatusResponse.class, authSecretTokenOut); + + System.out.println("===川逸充设备充电中状态变化推送====cycChargeOrderInfoResponse========"+chargeStatusResponse.toString()); } } catch (JsonProcessingException e) { e.printStackTrace(); } } + + + @PostMapping("/v20/getCYCNotificationStartChargeResult") + public void getCYCNotificationStartChargeResult(@RequestBody Map orderMap)throws Exception { + + Optional authSecretToken = + authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType("MA6CC2LK7",SECRET_TOKEN_TYPE_OUT); + + if(authSecretToken !=null){ + String orderNo = orderMap.get("orderNo").toString(); + + Map pushOrder = REDIS.getCacheMap("pushOrder:"+orderNo); + if (authSecretToken.isPresent()) { + CYCNotificationStartChargeResultRequestData notificationStartChargeResultRequestData = + new CYCNotificationStartChargeResultRequestData(); + notificationStartChargeResultRequestData.setStartChargeSeq((String) pushOrder.get("internetSerialNumber")); + notificationStartChargeResultRequestData.setStartChargeSeqStat((Integer) pushOrder.get("startChargeSeqStat")); + notificationStartChargeResultRequestData.setConnectorId((String) pushOrder.get("connectorID")); + notificationStartChargeResultRequestData.setStartTime((String) pushOrder.get("startTime")); + notificationStartChargeResultRequestData.setMobile((String) pushOrder.get("phone")); + + String data = JSONUtil.toJSONString(notificationStartChargeResultRequestData); + CommonRequest commonRequest = new CommonRequest<>(); + commonRequest.setOperatorId("MA6DFCTD5"); + + commonRequest.setData(data); + + String result = ok(commonRequest, "/notification_start_charge_result", authSecretToken.get()); + + System.out.println("===川逸充启动结果推送====result========"+result); + CYCChargeOrderInfoResponse cycChargeOrderInfoResponse = DTOJsonHelper.parseResponseData(result, CYCChargeOrderInfoResponse.class, authSecretToken.get()); + + System.out.println("===川逸充设备充电中状态变化推送====cycChargeOrderInfoResponse========"+cycChargeOrderInfoResponse.toString()); + } + }else{ + System.out.println("===川逸充启动结果失败====result========"); + } + } + + + @PostMapping("/v20/token") + public void token(@RequestBody Map orderMap)throws Exception { + + Optional authSecretToken = authSecretTokenRepository.findByOperatorId3irdptyAndSecretTokenType("MA6CC2LK7",SECRET_TOKEN_TYPE_OUT); + +// if(authSecretToken !=null){ +// Map map =new HashMap<>(); +// map.put("OperatorID","MA6DFCTD5"); +// map.put("OperatorSecret","9jG8qysc5RxdbjvnvdmuRYQg6J82FwjL"); +// String data = JSONUtil.toJSONString(map); +// CommonRequest commonRequest = new CommonRequest<>(); +// commonRequest.setOperatorId("MA6DFCTD5"); +// commonRequest.setData(data); +// String result = ok(commonRequest, "/query_token", authSecretToken.get()); +// System.out.println("===川逸充获取token====result========"+result); +// }else{ +// System.out.println("===川逸充获取token====result========"); +// } + + String result="{\"Ret\":0,\"Msg\":\"\",\"Data\":\"pCA3UNQO1CqxRS6KvcNDpw==\",\"Sig\":\"FCCCA9489FAD972722FB00E4E207F581\"}"; + + //String result="pCA3UNQO1CqxRS6KvcNDpw=="; + CYCChargeOrderInfoResponse cycChargeOrderInfoResponse = DTOJsonHelper.parseResponseData(result, CYCChargeOrderInfoResponse.class, authSecretToken.get()); + + System.out.println("===川逸充设备充电中状态变化推送====cycChargeOrderInfoResponse========"+cycChargeOrderInfoResponse.toString()); + + + } + + + + + + } diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/CoreDispatcher.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/CoreDispatcher.java index 925a7678..23eb1c1c 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/CoreDispatcher.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/CoreDispatcher.java @@ -53,6 +53,12 @@ public class CoreDispatcher { return ok(object, url, authSecretTokenOut, null); } + @Transactional + public String okYu(Object object, String url, AuthSecretToken authSecretTokenOut,String stationOperatorId) { + + return ok(object, url, authSecretTokenOut, stationOperatorId); + } + @Transactional public String ok(Object object, String url, AuthSecretToken authSecretTokenOut, String stationOperatorId) { if (authSecretTokenOut == null) { @@ -111,11 +117,13 @@ public class CoreDispatcher { bearerToken = authSecretTokenOut.getToken(); commonRequest.setData(originalData); tData = JSONUtil.toJSONString(commonRequest); + System.out.println("=========加密前data=============="+tData); log.debug("to [{}] {} out plain data:\n{}", authSecretTokenOut.getOperatorId3irdpty(), url, tData); if (authSecretTokenOut.isEncrypt()) { tData = encryptReqOut(authSecretTokenOut.getDataSecret(), authSecretTokenOut.getDataSecretIV(), authSecretTokenOut.getSigSecret(), commonRequest); // log.debug("notify out encrypt data:\n{}", tData); + System.out.println("=========加密data=============="+tData); } body = okhttp3.RequestBody.create(JSON, tData); // logger.info("==============平台推送值================="+tData); diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationCancelOrderTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationCancelOrderTask.java index 45870d4e..1f6b0ff9 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationCancelOrderTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationCancelOrderTask.java @@ -30,8 +30,8 @@ public class NotificationCancelOrderTask extends CoreDispatcher { //private Logger logger = LoggerFactory.getLogger(NotificationChargeOrderInfoTask.class); - //推送不开放 - //@Scheduled(fixedRate = 1000 * 15) + //推送不开放(evcs 放开) + @Scheduled(fixedRate = 1000 * 15) public void run() throws JsonProcessingException { //Getting the orders, which need to be notified. diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationChargeOrderInfoTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationChargeOrderInfoTask.java index e1398cb3..14ac23c8 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationChargeOrderInfoTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationChargeOrderInfoTask.java @@ -38,8 +38,8 @@ public class NotificationChargeOrderInfoTask extends CoreDispatcher { private AuthSecretTokenRepository authSecretTokenRepository; private final Logger logger = LoggerFactory.getLogger(NotificationChargeOrderInfoTask.class); - //推送不开放 - //@Scheduled(fixedRate = 1000 * 15) + //推送不开放(evcs 放开) + @Scheduled(fixedRate = 1000 * 15) public void run() throws JsonProcessingException { Collection orderKeys = REDIS.keys("order:*"); diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java index c0edf640..46f4079d 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationEquipChargeStatusTask.java @@ -45,11 +45,11 @@ public class NotificationEquipChargeStatusTask extends CoreDispatcher { private final Logger logger = LoggerFactory.getLogger(NotificationEquipChargeStatusTask.class); /** - * 推送充电状态 + * 推送充电状态(evcs 放开) * @throws IOException */ //推送不开放 - //@Scheduled(fixedRate = 1000 * 30) + @Scheduled(fixedRate = 1000 * 30) public void run() throws IOException { List authSecretTokenOutList = authSecretTokenRepository.findBySecretTokenType(SECRET_TOKEN_TYPE_OUT); diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStartChargeResultTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStartChargeResultTask.java index e248bb56..30e80381 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStartChargeResultTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStartChargeResultTask.java @@ -33,7 +33,7 @@ public class NotificationStartChargeResultTask extends CoreDispatcher { /** * Judging the 3rd whether it has got the start charging task. */ - //推送不开放 + //推送不开放(evcs 放开) @Scheduled(fixedRate = 1000 * 30) public void run() throws IOException { @@ -42,6 +42,10 @@ public class NotificationStartChargeResultTask extends CoreDispatcher { for (String pushOrderKey : pushOrderKeys) { Map pushOrder = REDIS.getCacheMap(pushOrderKey); if (pushOrder.get("startChargeSeqStat") != null && (Integer) pushOrder.get("startChargeSeqStat") > 1) { + if(pushOrder.get("operatorId3rdptyName") !=null && "CYC".equals((String)pushOrder.get("operatorId3rdptyName"))){ + continue; + } + logger.info("===============启动推送============================"+pushOrderKey); Integer startChargeNotificationStat = (Integer) pushOrder.get("startChargeNotificationStat"); if (null != startChargeNotificationStat && 1 != startChargeNotificationStat && startChargeNotificationStat <= 20) { String startChargeSeq = (String) pushOrder.get("internetSerialNumber"); @@ -77,10 +81,6 @@ public class NotificationStartChargeResultTask extends CoreDispatcher { String operatorIdEvcs = "MA6DFCTD5"; String data = JSONUtil.toJSONString(notificationStartChargeResultRequestData); - System.out.println("===============启动推送情况========================"); - System.out.println("===============启动推送情况============orderNo============"+orderNo); - System.out.println("===============启动推送情况============data============"+data); - System.out.println("===============启动推送情况========================"); CommonRequest commonRequest = new CommonRequest<>(); commonRequest.setData(data); @@ -89,16 +89,11 @@ public class NotificationStartChargeResultTask extends CoreDispatcher { DTOJsonHelper.parseResponseData(responseBody, NotificationStartStopChargeResultResponse.class, authSecretTokenOut); - System.out.println("===============启动推送情况============responseBody============"+responseBody); - System.out.println("===============启动推送情况========================"); - if (null != notificationStartStopChargeResultResponse) { //Ensuring that only when startChargeNotificationStat equals 1 won't be notified. if (notificationStartStopChargeResultResponse.getSuccStat() == 0) { - System.out.println("===============启动推送成功========orderNo================"+orderNo); REDIS.setCacheMapValue("pushOrder:".concat(orderNo), "startChargeNotificationStat", 1); } else { - System.out.println("===============启动推送失败========orderNo================"+orderNo); Integer startChargeNotificationStat = REDIS.getCacheMapValue("pushOrder:".concat(orderNo), "startChargeNotificationStat"); if (startChargeNotificationStat == 0) { diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStationStatusTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStationStatusTask.java index a425a723..21058254 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStationStatusTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStationStatusTask.java @@ -49,8 +49,8 @@ public class NotificationStationStatusTask extends CoreDispatcher { @Resource private XhpcTerminalRepository terminalRepository; - //推送不开放 - //@Scheduled(fixedRate = 1000 * 45) + //推送不开放(evcs 放开) + @Scheduled(fixedRate = 1000 * 45) protected void run() throws IOException { Collection stationTerminalKeys = REDIS.keys("stationTerminalStatus:*"); diff --git a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStopChargeResultTask.java b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStopChargeResultTask.java index a7d67af8..0ff844bc 100644 --- a/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStopChargeResultTask.java +++ b/evcs-modules/evcs-core/src/main/java/com/xhpc/evcs/notification/NotificationStopChargeResultTask.java @@ -26,7 +26,8 @@ public class NotificationStopChargeResultTask extends CoreDispatcher { @Autowired private AuthSecretTokenRepository authSecretTokenRepository; - //@Scheduled(fixedRate = 1000 * 3) + //(evcs 放开) + @Scheduled(fixedRate = 1000 * 3) public void run() throws Exception { notifyService(); diff --git a/evcs-modules/evcs-core/src/main/resources/bootstrap.yml b/evcs-modules/evcs-core/src/main/resources/bootstrap.yml index 200f8415..11df6db5 100644 --- a/evcs-modules/evcs-core/src/main/resources/bootstrap.yml +++ b/evcs-modules/evcs-core/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/ruoyi-auth/src/main/java/com/xhpc/auth/controller/TokenController.java b/ruoyi-auth/src/main/java/com/xhpc/auth/controller/TokenController.java index 0efffdd2..92353924 100644 --- a/ruoyi-auth/src/main/java/com/xhpc/auth/controller/TokenController.java +++ b/ruoyi-auth/src/main/java/com/xhpc/auth/controller/TokenController.java @@ -73,6 +73,24 @@ public class TokenController extends BaseController return R.ok(tokenService.createToken(userInfo)); } + /** + * 平台管理员登陆(过滤图形验证码) + * @param form + * @return + */ + @PostMapping("pcLogin") + public R pcLogin(@RequestBody LoginBody form) + { + String tenantId = "000000"; + if(tenantId==null || "".equals(tenantId)){ + throw new BaseException("租户ID码必须填写"); + } + // 用户登录 + LoginUser userInfo = sysLoginService.login(form.getUsername(), form.getPassword(),0,tenantId); + // 获取登录token + return R.ok(tokenService.createToken(userInfo)); + } + /** * 运营商登陆 * @param form diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/xhpc/common/core/constant/StatusConstants.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/xhpc/common/core/constant/StatusConstants.java index 30cdd39f..a0312d49 100644 --- a/ruoyi-common/ruoyi-common-core/src/main/java/com/xhpc/common/core/constant/StatusConstants.java +++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/xhpc/common/core/constant/StatusConstants.java @@ -12,6 +12,11 @@ public class StatusConstants { */ public static final String OPERATION_ALI_PAY_TYPE = "2"; + /** + * app操作渠道 + */ + public static final String OPERATION_APP_TYPE = "3"; + /** * 未进入黑名单 */ diff --git a/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/CustomRouteConfig.java b/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/CustomRouteConfig.java new file mode 100644 index 00000000..b3f0d920 --- /dev/null +++ b/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/CustomRouteConfig.java @@ -0,0 +1,13 @@ +package com.xhpc.gateway.config; + +import org.springframework.cloud.gateway.route.RouteLocator; +import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class CustomRouteConfig { + + + +} diff --git a/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/SwaggerProvider.java b/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/SwaggerProvider.java index f07f1805..84cceadd 100644 --- a/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/SwaggerProvider.java +++ b/ruoyi-gateway/src/main/java/com/xhpc/gateway/config/SwaggerProvider.java @@ -6,6 +6,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.gateway.config.GatewayProperties; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.support.NameUtils; +import org.springframework.context.annotation.Configuration; import org.springframework.stereotype.Component; import org.springframework.web.reactive.config.ResourceHandlerRegistry; import org.springframework.web.reactive.config.WebFluxConfigurer; @@ -73,4 +74,8 @@ public class SwaggerProvider implements SwaggerResourcesProvider, WebFluxConfigu registry.addResourceHandler("/swagger-ui/**") .addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); } + + + + } diff --git a/ruoyi-gateway/src/main/resources/bootstrap.yml b/ruoyi-gateway/src/main/resources/bootstrap.yml index 6fc5bed0..5bbe74ea 100644 --- a/ruoyi-gateway/src/main/resources/bootstrap.yml +++ b/ruoyi-gateway/src/main/resources/bootstrap.yml @@ -16,10 +16,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 @@ -35,7 +35,7 @@ spring: datasource: ds1: nacos: - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 dataId: sentinel-ruoyi-gateway groupId: DEFAULT_GROUP data-type: json diff --git a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml index 6c2cdb09..020707b3 100644 --- a/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml index de9b5154..d6293b3a 100644 --- a/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-gen/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml index cce34971..bb947c6e 100644 --- a/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-job/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml index 6881c7e6..d0362649 100644 --- a/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml +++ b/ruoyi-modules/ruoyi-system/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml index e61a355f..09a81fa8 100644 --- a/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml +++ b/ruoyi-visual/ruoyi-monitor/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/sql/ry_config_20210531.sql b/sql/ry_config_20210531.sql index a77f61e0..b327bdaf 100644 --- a/sql/ry_config_20210531.sql +++ b/sql/ry_config_20210531.sql @@ -40,17 +40,17 @@ INSERT INTO `config_info` (`id`, `data_id`, `group_id`, `content`, `md5`, `gmt_c (2, 'ruoyi-gateway-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net \n port: 6379\n password: tingsun@7645313\n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestFilter\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n # 充电桩服务\n - id: xhpc-power-pole\n uri: lb://xhpc-power-pole\n predicates:\n - Path=/pp/**\n filters:\n - StripPrefix=1\n # 账号服务\n - id: xhpc-user\n uri: lb://xhpc-user\n predicates:\n - Path=/xhpc-user/**\n filters:\n - StripPrefix=1\n # 支付服务\n - id: xhpc-payment\n uri: lb://xhpc-payment\n predicates:\n - Path=/xhpc-payment/**\n filters:\n - StripPrefix=1\n # 订单服务\n - id: xhpc-order\n uri: lb://xhpc-order\n predicates:\n - Path=/xhpc-order/**\n filters:\n - StripPrefix=1\n\n# 不校验白名单\nignore:\n whites:\n - /auth/logout\n - /auth/login\n - /*/v2/api-docs\n - /csrf\n - /xhpc-user/app/user/jscode2session\n - /xhpc-user/app/user/register\n - /xhpc-user/app/user/login\n - /xhpc-user/app/user/loginOut\n - /xhpc-user/app/user/voluntaryLogin\n - /xhpc-user/app/user/logout\n - /xhpc-user/app/user/alipayEmpower\n - /xhpc-user/app/user/appInfo\n - /xhpc-payment/wx/paymentCallback', '5a3b5371bf88b6b46ffe8271c7cae24c', '2020-05-14 14:17:55', '2021-07-28 07:50:28', 'nacos', '171.88.42.96', '', '', '网关模块', 'null', 'null', 'yaml', 'null'), (3, 'ruoyi-auth-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net \n port: 6379\n password: tingsun@7645313\n', '364ff5f362097c96a2ad12596b5ff9fd', '2020-11-20 00:00:00', '2021-07-23 09:21:25', 'nacos', '0:0:0:0:0:0:0:1', '', '', '认证中心', 'null', 'null', 'yaml', 'null'), (4, 'ruoyi-monitor-dev.yml', 'DEFAULT_GROUP', '# spring\r\nspring: \r\n security:\r\n user:\r\n name: ruoyi\r\n password: 123456\r\n boot:\r\n admin:\r\n ui:\r\n title: 若依服务状态监控\r\n', 'd8997d0707a2fd5d9fc4e8409da38129', '2020-11-20 00:00:00', '2020-12-21 16:28:07', NULL, '0:0:0:0:0:0:0:1', '', '', '监控中心', 'null', 'null', 'yaml', 'null'), -(5, 'ruoyi-system-dev.yml', 'DEFAULT_GROUP', '# spring配置\nspring: \n redis:\n host: tingsun-znc.f3322.net \n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n # 主库数据源\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n # 从库数据源\n # slave:\n # username: \n # password: \n # url: \n # driver-class-name: \n # seata: true # 开启seata代理,开启后默认每个数据源都代理,如果某个不需要代理可单独关闭\n\n# seata配置\nseata:\n # 默认关闭,如需启用spring.datasource.dynami.seata需要同时开启\n enabled: false\n # Seata 应用编号,默认为 ${spring.application.name}\n application-id: ${spring.application.name}\n # Seata 事务组编号,用于 TC 集群名\n tx-service-group: ${spring.application.name}-group\n # 关闭自动代理\n enable-auto-data-source-proxy: false\n # 服务配置项\n service:\n # 虚拟组和分组的映射\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: 120.26.46.180:8858\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: 120.26.46.180:8858\n namespace:\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.xhpc\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n title: 系统模块接口文档\n license: Powered By ruoyi\n licenseUrl: https://ruoyi.vip', '58d5723fa8c81b12563941261fd7e758', '2020-11-20 00:00:00', '2021-07-28 10:44:08', 'nacos', '0:0:0:0:0:0:0:1', '', '', '系统模块', 'null', 'null', 'yaml', 'null'), +(5, 'ruoyi-system-dev.yml', 'DEFAULT_GROUP', '# spring配置\nspring: \n redis:\n host: tingsun-znc.f3322.net \n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n # 主库数据源\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n # 从库数据源\n # slave:\n # username: \n # password: \n # url: \n # driver-class-name: \n # seata: true # 开启seata代理,开启后默认每个数据源都代理,如果某个不需要代理可单独关闭\n\n# seata配置\nseata:\n # 默认关闭,如需启用spring.datasource.dynami.seata需要同时开启\n enabled: false\n # Seata 应用编号,默认为 ${spring.application.name}\n application-id: ${spring.application.name}\n # Seata 事务组编号,用于 TC 集群名\n tx-service-group: ${spring.application.name}-group\n # 关闭自动代理\n enable-auto-data-source-proxy: false\n # 服务配置项\n service:\n # 虚拟组和分组的映射\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n namespace:\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.xhpc\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n title: 系统模块接口文档\n license: Powered By ruoyi\n licenseUrl: https://ruoyi.vip', '58d5723fa8c81b12563941261fd7e758', '2020-11-20 00:00:00', '2021-07-28 10:44:08', 'nacos', '0:0:0:0:0:0:0:1', '', '', '系统模块', 'null', 'null', 'yaml', 'null'), (6, 'ruoyi-gen-dev.yml', 'DEFAULT_GROUP', '# spring配置\r\nspring: \r\n redis:\r\n host: tingsun-znc.f3322.net \r\n port: 6379\r\n password: tingsun@7645313\r\n datasource: \r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: ry-cloud\r\n password: xiaohua123\r\n\r\n# mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.xhpc.gen.domain\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger配置\r\nswagger:\r\n title: 代码生成接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n\r\n# 代码生成\r\ngen: \r\n # 作者\r\n author: ruoyi\r\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\r\n packageName: com.xhpc.system\r\n # 自动去除表前缀,默认是false\r\n autoRemovePre: false\r\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\r\n tablePrefix: sys_\r\n', 'a21c5fa4c7c5731e62453614cf2e7d3f', '2020-11-20 00:00:00', '2021-07-24 14:16:06', NULL, '0:0:0:0:0:0:0:1', '', '', '代码生成', 'null', 'null', 'yaml', 'null'), (7, 'ruoyi-job-dev.yml', 'DEFAULT_GROUP', '# spring配置\nspring: \n redis:\n host: tingsun-znc.f3322.net \n port: 6379\n password: tingsun@7645313\n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/quartz?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: quartz\n password: quartz123\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.xhpc.job\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# swagger配置\nswagger:\n title: 定时任务接口文档\n license: Powered By ruoyi\n licenseUrl: https://ruoyi.vip\n', 'e9233f5ce3b3de95233ad88bb1a4231a', '2020-11-20 00:00:00', '2021-07-29 08:51:36', 'nacos', '0:0:0:0:0:0:0:1', '', '', '定时任务', 'null', 'null', 'yaml', 'null'), -(8, 'ruoyi-file-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313 \n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: 120.26.46.180:8858\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: 120.26.46.180:8858\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.file\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n configuration:\n call-setters-on-nulls: true\n\n# 本地文件上传 \nfile:\n domain: http://127.0.0.1:9300\n path: D:/ruoyi/uploadPath\n prefix: /statics\n\n# FastDFS配置\nfdfs:\n domain: http://8.129.231.12\n soTimeout: 3000\n connectTimeout: 2000\n trackerList: 8.129.231.12:22122\n\n# Minio配置\nminio:\n url: http://8.129.231.12:9000\n accessKey: minioadmin\n secretKey: minioadmin\n bucketName: test\n#oss默认配置\noss:\n enabled: true\n name: qiniu\n tenant-mode: true\n endpoint: oss-accelerate.aliyuncs.com\n access-key: LTAIhOKfUxeutGeh\n secret-key: 2TvKIoX03bnP5WRLxtTaEYQufrtbav\n bucket-name: dx-gzxh\n', '435441353d3fbaa4ee8165d6f4b0374b', '2020-11-20 00:00:00', '2021-07-29 02:42:04', 'nacos', '171.88.42.96', '', '', '文件服务', 'null', 'null', 'yaml', 'null'), +(8, 'ruoyi-file-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313 \n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.file\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n configuration:\n call-setters-on-nulls: true\n\n# 本地文件上传 \nfile:\n domain: http://127.0.0.1:9300\n path: D:/ruoyi/uploadPath\n prefix: /statics\n\n# FastDFS配置\nfdfs:\n domain: http://8.129.231.12\n soTimeout: 3000\n connectTimeout: 2000\n trackerList: 8.129.231.12:22122\n\n# Minio配置\nminio:\n url: http://8.129.231.12:9000\n accessKey: minioadmin\n secretKey: minioadmin\n bucketName: test\n#oss默认配置\noss:\n enabled: true\n name: qiniu\n tenant-mode: true\n endpoint: oss-accelerate.aliyuncs.com\n access-key: LTAIhOKfUxeutGeh\n secret-key: 2TvKIoX03bnP5WRLxtTaEYQufrtbav\n bucket-name: dx-gzxh\n', '435441353d3fbaa4ee8165d6f4b0374b', '2020-11-20 00:00:00', '2021-07-29 02:42:04', 'nacos', '171.88.42.96', '', '', '文件服务', 'null', 'null', 'yaml', 'null'), (9, 'sentinel-ruoyi-gateway', 'DEFAULT_GROUP', '[\r\n {\r\n "resource": "ruoyi-auth",\r\n "count": 500,\r\n "grade": 1,\r\n "limitApp": "default",\r\n "strategy": 0,\r\n "controlBehavior": 0\r\n },\r\n {\r\n "resource": "ruoyi-system",\r\n "count": 1000,\r\n "grade": 1,\r\n "limitApp": "default",\r\n "strategy": 0,\r\n "controlBehavior": 0\r\n },\r\n {\r\n "resource": "ruoyi-gen",\r\n "count": 200,\r\n "grade": 1,\r\n "limitApp": "default",\r\n "strategy": 0,\r\n "controlBehavior": 0\r\n },\r\n {\r\n "resource": "ruoyi-job",\r\n "count": 300,\r\n "grade": 1,\r\n "limitApp": "default",\r\n "strategy": 0,\r\n "controlBehavior": 0\r\n }\r\n]', '9f3a3069261598f74220bc47958ec252', '2020-11-20 00:00:00', '2020-11-20 00:00:00', NULL, '0:0:0:0:0:0:0:1', '', '', '限流策略', 'null', 'null', 'json', 'null'), -(20, 'xhpc-power-pile-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: 120.26.46.180:8858\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: 120.26.46.180:8858\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.pp\n mapperLocations: classpath:mapper/**/*.xml\n', 'e1cad28a4df29955413fa360a40a03dc', '2021-07-19 06:40:44', '2021-07-23 09:05:47', 'nacos', '0:0:0:0:0:0:0:1', '', '', '充电桩协议服务', '', '', 'yaml', ''), -(22, 'xhpc-charging-station-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: 120.26.46.180:8858\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: 120.26.46.180:8858\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc\n mapperLocations: classpath:mapper/**/*.xml\n', '5c9e25c8e8775649c0d5dcb5aed95715', '2021-07-19 08:22:12', '2021-07-28 08:51:17', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''), -(23, 'xhpc-general-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: 120.26.46.180:8858\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: 120.26.46.180:8858\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.general\n mapperLocations: classpath:mapper/**/*.xml\n', 'c31f612a8d2c67dc69888b7c02bae5d0', '2021-07-20 20:39:06', '2021-07-21 10:03:06', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''), -(24, 'xhpc-user', 'DEFAULT_GROUP', 'spring: \r\n redis:\r\n host: tingsun-znc.f3322.net\r\n port: 6379\r\n password: tingsun@7645313 \r\n jackson:\r\n date-format: yyyy-MM-dd HH:mm:ss\r\n time-zone: GMT+8\r\n datasource:\r\n druid:\r\n stat-view-servlet:\r\n enabled: true\r\n loginUsername: admin\r\n loginPassword: 123456\r\n dynamic:\r\n druid:\r\n initial-size: 5\r\n min-idle: 5\r\n maxActive: 20\r\n maxWait: 60000\r\n timeBetweenEvictionRunsMillis: 60000\r\n minEvictableIdleTimeMillis: 300000\r\n validationQuery: SELECT 1 FROM DUAL\r\n testWhileIdle: true\r\n testOnBorrow: false\r\n testOnReturn: false\r\n poolPreparedStatements: true\r\n maxPoolPreparedStatementPerConnectionSize: 20\r\n filters: stat,slf4j\r\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\r\n datasource:\r\n master:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: ry-cloud\r\n password: xiaohua123\r\n\r\nseata:\r\n enabled: false\r\n application-id: ${spring.application.name}\r\n tx-service-group: ${spring.application.name}-group\r\n enable-auto-data-source-proxy: false\r\n service:\r\n vgroup-mapping:\r\n ruoyi-system-group: default\r\n config:\r\n type: nacos\r\n nacos:\r\n serverAddr: 120.26.46.180:8858\r\n group: SEATA_GROUP\r\n namespace:\r\n registry:\r\n type: nacos\r\n nacos:\r\n application: seata-server\r\n server-addr: 120.26.46.180:8858\r\n namespace: \r\n\r\nmybatis:\r\n typeAliasesPackage: com.xhpc.user\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n configuration:\r\n call-setters-on-nulls: true\r\n', 'a5bc394601350c323c9ebe171864089b', '2021-07-21 12:11:14', '2021-07-29 16:21:37', NULL, '0:0:0:0:0:0:0:1', '', '', 'null', 'null', 'null', 'yaml', 'null'), +(20, 'xhpc-power-pile-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.pp\n mapperLocations: classpath:mapper/**/*.xml\n', 'e1cad28a4df29955413fa360a40a03dc', '2021-07-19 06:40:44', '2021-07-23 09:05:47', 'nacos', '0:0:0:0:0:0:0:1', '', '', '充电桩协议服务', '', '', 'yaml', ''), +(22, 'xhpc-charging-station-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc\n mapperLocations: classpath:mapper/**/*.xml\n', '5c9e25c8e8775649c0d5dcb5aed95715', '2021-07-19 08:22:12', '2021-07-28 08:51:17', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''), +(23, 'xhpc-general-dev.yml', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.general\n mapperLocations: classpath:mapper/**/*.xml\n', 'c31f612a8d2c67dc69888b7c02bae5d0', '2021-07-20 20:39:06', '2021-07-21 10:03:06', 'nacos', '0:0:0:0:0:0:0:1', '', '', '', '', '', 'yaml', ''), +(24, 'xhpc-user', 'DEFAULT_GROUP', 'spring: \r\n redis:\r\n host: tingsun-znc.f3322.net\r\n port: 6379\r\n password: tingsun@7645313 \r\n jackson:\r\n date-format: yyyy-MM-dd HH:mm:ss\r\n time-zone: GMT+8\r\n datasource:\r\n druid:\r\n stat-view-servlet:\r\n enabled: true\r\n loginUsername: admin\r\n loginPassword: 123456\r\n dynamic:\r\n druid:\r\n initial-size: 5\r\n min-idle: 5\r\n maxActive: 20\r\n maxWait: 60000\r\n timeBetweenEvictionRunsMillis: 60000\r\n minEvictableIdleTimeMillis: 300000\r\n validationQuery: SELECT 1 FROM DUAL\r\n testWhileIdle: true\r\n testOnBorrow: false\r\n testOnReturn: false\r\n poolPreparedStatements: true\r\n maxPoolPreparedStatementPerConnectionSize: 20\r\n filters: stat,slf4j\r\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\r\n datasource:\r\n master:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: ry-cloud\r\n password: xiaohua123\r\n\r\nseata:\r\n enabled: false\r\n application-id: ${spring.application.name}\r\n tx-service-group: ${spring.application.name}-group\r\n enable-auto-data-source-proxy: false\r\n service:\r\n vgroup-mapping:\r\n ruoyi-system-group: default\r\n config:\r\n type: nacos\r\n nacos:\r\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\r\n group: SEATA_GROUP\r\n namespace:\r\n registry:\r\n type: nacos\r\n nacos:\r\n application: seata-server\r\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\r\n namespace: \r\n\r\nmybatis:\r\n typeAliasesPackage: com.xhpc.user\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n configuration:\r\n call-setters-on-nulls: true\r\n', 'a5bc394601350c323c9ebe171864089b', '2021-07-21 12:11:14', '2021-07-29 16:21:37', NULL, '0:0:0:0:0:0:0:1', '', '', 'null', 'null', 'null', 'yaml', 'null'), (32, 'xhpc-payment', 'DEFAULT_GROUP', 'spring: \n redis:\n host: tingsun-znc.f3322.net\n port: 6379\n password: tingsun@7645313 \n jackson:\n date-format: yyyy-MM-dd HH:mm:ss\n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: admin\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: ry-cloud\n password: xiaohua123\n\nseata:\n enabled: false\n application-id: ${spring.application.name}\n tx-service-group: ${spring.application.name}-group\n enable-auto-data-source-proxy: false\n service:\n vgroup-mapping:\n ruoyi-system-group: default\n config:\n type: nacos\n nacos:\n serverAddr: 118.24.137.203:8848\n group: SEATA_GROUP\n namespace:\n registry:\n type: nacos\n nacos:\n application: seata-server\n server-addr: 118.24.137.203:8848\n namespace: \n\nmybatis:\n typeAliasesPackage: com.xhpc.payment\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n configuration:\n call-setters-on-nulls: true\n', '406756afa55d157cb60305f89f29ec0c', '2021-07-22 16:44:26', '2021-07-22 11:10:56', 'nacos', '110.184.240.136', '', '', '', '', '', 'yaml', ''), -(45, 'xhpc-order', 'DEFAULT_GROUP', 'spring: \r\n redis:\r\n host: tingsun-znc.f3322.net\r\n port: 6379\r\n password: tingsun@7645313 \r\n jackson:\r\n date-format: yyyy-MM-dd HH:mm:ss\r\n datasource:\r\n druid:\r\n stat-view-servlet:\r\n enabled: true\r\n loginUsername: admin\r\n loginPassword: 123456\r\n dynamic:\r\n druid:\r\n initial-size: 5\r\n min-idle: 5\r\n maxActive: 20\r\n maxWait: 60000\r\n timeBetweenEvictionRunsMillis: 60000\r\n minEvictableIdleTimeMillis: 300000\r\n validationQuery: SELECT 1 FROM DUAL\r\n testWhileIdle: true\r\n testOnBorrow: false\r\n testOnReturn: false\r\n poolPreparedStatements: true\r\n maxPoolPreparedStatementPerConnectionSize: 20\r\n filters: stat,slf4j\r\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\r\n datasource:\r\n master:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: ry-cloud\r\n password: xiaohua123\r\n\r\nseata:\r\n enabled: false\r\n application-id: ${spring.application.name}\r\n tx-service-group: ${spring.application.name}-group\r\n enable-auto-data-source-proxy: false\r\n service:\r\n vgroup-mapping:\r\n ruoyi-system-group: default\r\n config:\r\n type: nacos\r\n nacos:\r\n serverAddr: 120.26.46.180:8858\r\n group: SEATA_GROUP\r\n namespace:\r\n registry:\r\n type: nacos\r\n nacos:\r\n application: seata-server\r\n server-addr: 120.26.46.180:8858\r\n namespace: \r\n\r\nmybatis:\r\n typeAliasesPackage: com.xhpc.order\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n configuration:\r\n call-setters-on-nulls: true\r\n', 'dda0f504b5a217c72b8e9cc62f449da5', '2021-07-26 15:35:37', '2021-07-26 15:35:37', NULL, '0:0:0:0:0:0:0:1', '', '', NULL, NULL, NULL, 'yaml', NULL); +(45, 'xhpc-order', 'DEFAULT_GROUP', 'spring: \r\n redis:\r\n host: tingsun-znc.f3322.net\r\n port: 6379\r\n password: tingsun@7645313 \r\n jackson:\r\n date-format: yyyy-MM-dd HH:mm:ss\r\n datasource:\r\n druid:\r\n stat-view-servlet:\r\n enabled: true\r\n loginUsername: admin\r\n loginPassword: 123456\r\n dynamic:\r\n druid:\r\n initial-size: 5\r\n min-idle: 5\r\n maxActive: 20\r\n maxWait: 60000\r\n timeBetweenEvictionRunsMillis: 60000\r\n minEvictableIdleTimeMillis: 300000\r\n validationQuery: SELECT 1 FROM DUAL\r\n testWhileIdle: true\r\n testOnBorrow: false\r\n testOnReturn: false\r\n poolPreparedStatements: true\r\n maxPoolPreparedStatementPerConnectionSize: 20\r\n filters: stat,slf4j\r\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\r\n datasource:\r\n master:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://182.140.223.172:8036/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: ry-cloud\r\n password: xiaohua123\r\n\r\nseata:\r\n enabled: false\r\n application-id: ${spring.application.name}\r\n tx-service-group: ${spring.application.name}-group\r\n enable-auto-data-source-proxy: false\r\n service:\r\n vgroup-mapping:\r\n ruoyi-system-group: default\r\n config:\r\n type: nacos\r\n nacos:\r\n serverAddr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\r\n group: SEATA_GROUP\r\n namespace:\r\n registry:\r\n type: nacos\r\n nacos:\r\n application: seata-server\r\n server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848\r\n namespace: \r\n\r\nmybatis:\r\n typeAliasesPackage: com.xhpc.order\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n configuration:\r\n call-setters-on-nulls: true\r\n', 'dda0f504b5a217c72b8e9cc62f449da5', '2021-07-26 15:35:37', '2021-07-26 15:35:37', NULL, '0:0:0:0:0:0:0:1', '', '', NULL, NULL, NULL, 'yaml', NULL); /*!40000 ALTER TABLE `config_info` ENABLE KEYS */; /*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; diff --git a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/PileLogController.java b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/PileLogController.java index 4f5bc391..16708ade 100644 --- a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/PileLogController.java +++ b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/PileLogController.java @@ -37,7 +37,10 @@ public class PileLogController extends BaseController { @RequestParam(required = false) String stationName, @RequestParam(required = false) String pileName, @RequestParam(required = false) String pileSerialNumber, - @RequestParam(required = false) Integer number) { + @RequestParam(required = false) Integer number, + @RequestParam(required = false) Long operatorId, + @RequestParam(required = false) Long chargingStationId, + @RequestParam(required = false) Long chargingPileId) { LoginUser loginUser = logUserUtils.getLogUser(request); @@ -46,7 +49,9 @@ public class PileLogController extends BaseController { Map params = new HashMap<>(); params.put("stationName", stationName); params.put("pileName", pileName); - params.put("operatorId", SecurityUtils.getUserId()); + params.put("operatorId", operatorId); + params.put("chargingStationId", chargingStationId); + params.put("chargingPileId", chargingPileId); params.put("number", number); params.put("pileSerialNumber", pileSerialNumber); params.put("tenantId", loginUser.getTenantId()); diff --git a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/StationLogController.java b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/StationLogController.java index 8c7221f5..09391c4e 100644 --- a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/StationLogController.java +++ b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/controller/StationLogController.java @@ -25,10 +25,11 @@ public class StationLogController extends BaseController { public TableDataInfo getPilePage( HttpServletRequest request, @RequestParam(required = false) String tenantId, - @RequestParam(required = false) Integer number) { + @RequestParam(required = false) Integer number, + @RequestParam(required = false) Long operatorId) { startPage(); Map params = new HashMap<>(); - params.put("operatorId", SecurityUtils.getUserId()); + params.put("operatorId", operatorId); params.put("number", number); params.put("tenantId", tenantId); return getDataTable(stationLogService.getStationPage(request,params)); diff --git a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/mapper/XhpcChargingPileMapper.java b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/mapper/XhpcChargingPileMapper.java index 129a7671..cec51c2b 100644 --- a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/mapper/XhpcChargingPileMapper.java +++ b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/mapper/XhpcChargingPileMapper.java @@ -19,6 +19,11 @@ public interface XhpcChargingPileMapper { */ List> selectXhpcChargingPileList(@Param("params")Map params); + /** + * 获取登陆用户信息 + */ + Map getLandUser(@Param("userId")Long userId); + /** * 终端 * diff --git a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/PileLogServiceImpl.java b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/PileLogServiceImpl.java index 517fceb4..d9d7d5ec 100644 --- a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/PileLogServiceImpl.java +++ b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/PileLogServiceImpl.java @@ -3,21 +3,27 @@ package com.xhpc.activity.service.impl; import cn.hutool.core.io.IoUtil; import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelWriter; +import com.xhpc.common.core.web.service.BaseService; import com.xhpc.common.enums.StationDeviceEnum; import com.xhpc.activity.mapper.XhpcChargingPileMapper; import com.xhpc.activity.mapper.XhpcDeviceMessageMapper; import com.xhpc.activity.service.PileLogService; +import com.xhpc.common.security.service.TokenService; +import com.xhpc.common.util.UserTypeUtil; +import com.xhpc.system.api.model.LoginUser; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; +import java.util.ArrayList; import java.util.List; import java.util.Map; @Service -public class PileLogServiceImpl implements PileLogService { +public class PileLogServiceImpl extends BaseService implements PileLogService { @Resource XhpcChargingPileMapper pileMapper; @@ -25,10 +31,44 @@ public class PileLogServiceImpl implements PileLogService { @Resource XhpcDeviceMessageMapper deviceMessageMapper; + @Resource + private TokenService tokenService; @Override public List> getPilePage(Map params){ + LoginUser loginUser = tokenService.getLoginUser(); + + Long userId = loginUser.getUserid(); + //桩的统计、该时段金额 + List> list = new ArrayList<>(); + if (userId != UserTypeUtil.USER_ID) { + Map landUser = pileMapper.getLandUser(userId); + if (landUser != null) { + if (landUser.get("userType") != null) { + startPage(); + if (UserTypeUtil.SYS_USER_TYPE_ONE.equals(landUser.get("userType").toString())) { + Long logOperatorId = Long.valueOf(landUser.get("operatorId").toString()); + + params.put("logOperatorId", logOperatorId); + params.put("status", 1); + //运营商看自己的场站 + list = pileMapper.selectXhpcChargingPileList(params); + } else { + params.put("logOperatorId", userId); + params.put("status", 2); + //查询赋值的场站 + list = pileMapper.selectXhpcChargingPileList(params); + } + } + } + + } else { + startPage(); + params.put("logOperatorId", userId); + params.put("status", 0); + list = pileMapper.selectXhpcChargingPileList(params); + } + return list; - return pileMapper.selectXhpcChargingPileList(params); } diff --git a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/StationLogServiceImpl.java b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/StationLogServiceImpl.java index afabc29e..35417a5e 100644 --- a/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/StationLogServiceImpl.java +++ b/xhpc-modules/xhpc-activity/src/main/java/com/xhpc/activity/service/impl/StationLogServiceImpl.java @@ -34,24 +34,32 @@ public class StationLogServiceImpl extends BaseService implements StationLogServ Long sysUserId = sysUser.getUserId(); //桩的统计、该时段金额 List> list =new ArrayList<>(); - - if(!UserTypeUtil.SYS_USER_TYPE_ADMIN.equals(sysUser.getUserId())){ - if(UserTypeUtil.SYS_USER_TYPE_ONE.equals(sysUser.getUserType())){ - Long operatorId = sysUser.getOperatorId(); - params.put("type",1); - params.put("operatorId",operatorId); - //运营商看自己的场站 - list = stationMapper.selectXhpcChargingStationList(params); + if(UserTypeUtil.SYS_USER_TYPE_FOUR.equals(sysUser.getUserType())){ + //运维管理人员 + startPage(); + params.put("type",2); + params.put("operatorId",sysUserId); + list = stationMapper.selectXhpcChargingStationList(params); + }else{ + if(sysUser.getUserId() !=UserTypeUtil.USER_ID){ + Long logOperatorId = sysUser.getOperatorId(); + startPage(); + if ("01".equals(sysUser.getUserType())) { + params.put("type",1); + params.put("operatorId",logOperatorId); + //运营商看自己的场站 + list = stationMapper.selectXhpcChargingStationList(params); + }else{ + startPage(); + params.put("type",2); + params.put("operatorId",sysUserId); + list = stationMapper.selectXhpcChargingStationList(params); + } }else{ - //查询赋值的场站 - params.put("type",2); - params.put("operatorId",sysUserId); + startPage(); + params.put("type",0); list = stationMapper.selectXhpcChargingStationList(params); } - }else{ - startPage(); - params.put("type",0); - list = stationMapper.selectXhpcChargingStationList(params); } return list; } diff --git a/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcChargingPileMapper.xml b/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcChargingPileMapper.xml index f93a9eb7..aa09549e 100644 --- a/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcChargingPileMapper.xml +++ b/xhpc-modules/xhpc-activity/src/main/resources/mapper/XhpcChargingPileMapper.xml @@ -86,20 +86,17 @@ from xhpc_charging_pile as cp left join xhpc_charging_station as st on st.charging_station_id =cp.charging_station_id where cp.del_flag =0 - - - - - - - - - - - - + + and cp.charging_station_id in (select charging_station_id from xhpc_charging_station where operator_id=#{params.operatorId}) + + + and st.charging_station_id=#{params.chargingStationId} + + + and cp.charging_pile_id=#{params.chargingPileId} + - and cp.serial_number = #{params.pileSerialNumber} + and cp.serial_number like CONCAT('%',#{params.pileSerialNumber},'%') and concat(cp.name,'号桩') like concat ('%', #{params.pileName},'%') @@ -107,11 +104,11 @@ and st.name like CONCAT('%',#{params.stationName},'%') - - and cp.charging_station_id in(select charging_station_id from xhpc_charging_station where operator_id=#{params.operatorId}) + + and cp.charging_station_id in (select charging_station_id from xhpc_charging_station where operator_id=#{params.logOperatorId}) - - and cp.charging_station_id in(select charging_station_id from xhpc_user_privilege where user_id=#{params.operatorId}) + + and cp.charging_station_id in (select charging_station_id from xhpc_user_privilege where user_id=#{params.logOperatorId}) and cp.tenant_id = #{params.tenantId} @@ -119,6 +116,10 @@ order by cp.charging_station_id, cp.charging_pile_id + + insert into xhpc_charging_pile diff --git a/xhpc-modules/xhpc-card/src/main/java/com/xhpc/card/service/impl/XhpcCardServiceImpl.java b/xhpc-modules/xhpc-card/src/main/java/com/xhpc/card/service/impl/XhpcCardServiceImpl.java index 23e3a15c..d2d63503 100644 --- a/xhpc-modules/xhpc-card/src/main/java/com/xhpc/card/service/impl/XhpcCardServiceImpl.java +++ b/xhpc-modules/xhpc-card/src/main/java/com/xhpc/card/service/impl/XhpcCardServiceImpl.java @@ -94,7 +94,11 @@ public class XhpcCardServiceImpl implements IXhpcCardService { String tenantId=xhpcIcCardInfo.getTenantId(); Integer type =Integer.valueOf(iccardInfo.getCardtype());//改成卡授权的类型 String grantOperator=iccardInfo.getCorpno();//改成卡授权的运营商 - return cardHistoryOrderService.cardStartup(userId, serialNumber, userType,tenantId,type,grantOperator,rateModelId); + R r = cardHistoryOrderService.cardStartup(userId, serialNumber, userType, tenantId, type, grantOperator, rateModelId); + + System.out.println("===============<<<<卡启动充电返回>>>>>==================="+r.getMsg()); + System.out.println("===============<<<<卡启动充电返回>>>>>==================="+r.getCode()); + return r; } @Override @@ -116,6 +120,9 @@ public class XhpcCardServiceImpl implements IXhpcCardService { dataDTO.setDeviceNumber(tIccardDevice.getSerialnumber()); Integer corpindex = tIccardDevice.getCorpindex(); if (corpindex != null) { + System.out.println("======corpindex===="+corpindex); + System.out.println("======corpindex===="+corpindex); + System.out.println("======corpindex===="+corpindex); XhpcOperator xhpcOperator = xhpcOperatorMapper.selectOneByCorpNoAndTenantId(String.valueOf(corpindex), tokenService.getLoginUser().getSysUser().getTenantId()); dataDTO.setGrantOperator(xhpcOperator.getName()); } diff --git a/xhpc-modules/xhpc-card/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-card/src/main/resources/bootstrap.yml index 949381e6..7b26271c 100644 --- a/xhpc-modules/xhpc-card/src/main/resources/bootstrap.yml +++ b/xhpc-modules/xhpc-card/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/xhpc-modules/xhpc-card/src/main/resources/mapper/XhpcCardMapper.xml b/xhpc-modules/xhpc-card/src/main/resources/mapper/XhpcCardMapper.xml index e01f2bed..65882d93 100644 --- a/xhpc-modules/xhpc-card/src/main/resources/mapper/XhpcCardMapper.xml +++ b/xhpc-modules/xhpc-card/src/main/resources/mapper/XhpcCardMapper.xml @@ -207,7 +207,7 @@ diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcBarrierGateRecordController.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcBarrierGateRecordController.java new file mode 100644 index 00000000..a3a077d8 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcBarrierGateRecordController.java @@ -0,0 +1,87 @@ +package com.xhpc.charging.station.controller; + +import cn.hutool.core.date.DateUtil; +import com.alibaba.excel.EasyExcel; +import com.xhpc.charging.station.service.IXhpcBarrierGateRecordService; +import com.xhpc.common.core.domain.R; +import com.xhpc.common.core.web.controller.BaseController; +import com.xhpc.common.core.web.page.TableDataInfo; +import com.xhpc.common.dto.XhpcBarrierGateRecordExcel; +import io.swagger.annotations.ApiOperation; +import org.apache.commons.codec.Charsets; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletResponse; +import java.net.URLEncoder; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/barrierGateRecord") +public class XhpcBarrierGateRecordController extends BaseController { + + @Resource + private IXhpcBarrierGateRecordService xhpcBarrierGateRecordService; + + + @GetMapping("/list") + public TableDataInfo list(String barrierGateCompany, String chargingStationName, String phone, + String plateNum, String serialNumber, String internetSerialNumber, + Integer status, String startTime, String endTime){ + Map params = new HashMap<>(); + params.put("barrierGateCompany", barrierGateCompany); + params.put("chargingStationName", chargingStationName); + params.put("phone", phone); + params.put("plateNum", plateNum); + params.put("serialNumber", serialNumber); + params.put("internetSerialNumber", internetSerialNumber); + params.put("status", status); + params.put("startTime", startTime); + params.put("endTime", endTime); + List> list = xhpcBarrierGateRecordService.getLsit(params); + return getDataTable(list); + } + + @GetMapping("/getXhpcBarrierGateRecordById") + public R getXhpcBarrierGateRecordById(Long barrierGateRecordId) { + Map map = xhpcBarrierGateRecordService.getXhpcBarrierGateRecordById(barrierGateRecordId); + return R.ok(map); + } + + /** + * 导出数据(单位) + */ + @PostMapping("/export") + @ApiOperation(value = "导出数据", notes = "传入channelInfo") + public void export(String barrierGateCompany, String chargingStationName, String phone, + String plateNum, String serialNumber, String internetSerialNumber, + Integer status, String startTime, String endTime, HttpServletResponse response) { + Map params = new HashMap<>(); + params.put("barrierGateCompany", barrierGateCompany); + params.put("chargingStationName", chargingStationName); + params.put("phone", phone); + params.put("plateNum", plateNum); + params.put("serialNumber", serialNumber); + params.put("internetSerialNumber", internetSerialNumber); + params.put("status", status); + params.put("startTime", startTime); + params.put("endTime", endTime); + List list = xhpcBarrierGateRecordService.export(params); + try { + response.setContentType("application/vnd.ms-excel"); + response.setCharacterEncoding(Charsets.UTF_8.name()); + String fileName = URLEncoder.encode("道闸记录", Charsets.UTF_8.name()); + response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx"); + EasyExcel.write(response.getOutputStream(), XhpcBarrierGateRecordExcel.class).sheet("道闸记录").doWrite(list); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingPileController.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingPileController.java index 778c6edb..4fc447b5 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingPileController.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingPileController.java @@ -27,6 +27,8 @@ import javax.servlet.http.HttpServletRequest; import java.util.List; import java.util.Map; +import static com.xhpc.common.data.redis.StaticBeanUtil.REDIS; + /** * @author yuyang * @date 2021/7/27 14:44 @@ -229,5 +231,24 @@ public class XhpcChargingPileController extends BaseController { return xhpcChargingPileService.getChargingPileSerialNumber(serialNumber); } + //充电桩工作参数设置 + @GetMapping("/configSettings") + public AjaxResult configSettings(String serialNumber,Integer powerNumber) { + if(serialNumber==null || "".equals(serialNumber)){ + return AjaxResult.error("桩号为空"); + } + if(powerNumber==null){ + return AjaxResult.error("充电桩最大允许输出功率为空"); + } + if(powerNumber<1 || powerNumber>100){ + return AjaxResult.error("充电桩最大允许输出功率1~100之内"); + } + REDIS.setCacheObject(serialNumber+":powerNumber",powerNumber); + R r = powerPileService.pileConfigSettings(serialNumber,powerNumber.toString()); + if(r.getCode() !=200){ + return AjaxResult.error(r.getMsg()); + } + return AjaxResult.success("设置成功"); + } } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingStationController.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingStationController.java index 248458c3..2be60d91 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingStationController.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcChargingStationController.java @@ -11,6 +11,7 @@ import com.xhpc.common.log.annotation.Log; import com.xhpc.common.log.enums.BusinessType; import com.xhpc.common.security.annotation.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Scheduled; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; @@ -228,4 +229,14 @@ public class XhpcChargingStationController extends BaseController { public R getNotificationStationInfo(Long stationId){ return xhpcChargingStationService.getNotificationStationInfo(stationId); } + + /** + * 定时获取场站允许充电方式 + */ + @GetMapping("/chargingMethod") + @Scheduled(cron = "0 0/5 * * * ? ") + public void chargingMethod(){ + xhpcChargingStationService.getchargingMethodList(); + } + } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcTimingChargingPowerController.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcTimingChargingPowerController.java new file mode 100644 index 00000000..5352f602 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/controller/XhpcTimingChargingPowerController.java @@ -0,0 +1,86 @@ +package com.xhpc.charging.station.controller; + +import com.xhpc.charging.station.service.IXhpcTimingChargingPowerService; +import com.xhpc.common.core.domain.R; +import com.xhpc.common.core.web.controller.BaseController; +import com.xhpc.common.core.web.page.TableDataInfo; +import com.xhpc.common.domain.XhpcTimingChargingPowerModel; +import com.xhpc.common.log.annotation.Log; +import com.xhpc.common.log.enums.BusinessType; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/timingChargingPower") +public class XhpcTimingChargingPowerController extends BaseController { + + + @Resource + private IXhpcTimingChargingPowerService xhpcTimingChargingPowerService; + + + @GetMapping("/list") + public TableDataInfo list(HttpServletRequest request, String tenantId, Long operatorId, String reason, Integer status, String startTime, String endTime, Long chargingStationId) { + startPage(); + List> list = xhpcTimingChargingPowerService.list(request,tenantId,operatorId,reason, status, startTime,endTime, chargingStationId); + return getDataTable(list); + } + + + /** + * 添加定时功率调整 + * @param xhpcTimingChargingPowerModel + * @return + */ + @Log(title = "添加定时功率调整", businessType = BusinessType.INSERT) + @PostMapping(value = "/addXhpcTimingChargingPowerModel") + public R addXhpcTimingChargingModel(HttpServletRequest request, @RequestBody XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel) { + return xhpcTimingChargingPowerService.addXhpcTimingChargingPowerModel(request,xhpcTimingChargingPowerModel); + } + + /** + * 删除 + */ + @Log(title = "删除", businessType = BusinessType.UPDATE) + @DeleteMapping("/{timingChargingPowerId}") + public R updateXhpcTimingChargingModel(@PathVariable Long timingChargingPowerId) { + return xhpcTimingChargingPowerService.updateXhpcTimingChargingPowerModel(timingChargingPowerId); + } + + /** + * 详情 + * + * @return + */ + @GetMapping(value = "/getXhpcTimingChargingPowerModelMessage") + public R getXhpcTimingChargingPowerModelMessage(Long timingChargingPowerId) { + return xhpcTimingChargingPowerService.getXhpcTimingChargingPowerModelMessage(timingChargingPowerId); + } + + + /** + * 编辑定时计费模型 + * @param xhpcTimingChargingPowerModel + * @return + */ + @Log(title = "编辑定时功率调整", businessType = BusinessType.INSERT) + @PostMapping(value = "/updateXhpcTimingChargingPowerModel") + public R updateXhpcTimingChargingPowerModel(HttpServletRequest request, @RequestBody XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel) { + return xhpcTimingChargingPowerService.addXhpcTimingChargingPowerModel(request,xhpcTimingChargingPowerModel); + } + + /** + * 每30秒执行一次 + */ + //@Scheduled(cron = "0/30 * * * * ?") + @PostMapping(value = "/getXhpcTimingChargingPowerModelCron") + public void getXhpcTimingChargingPowerModelCron(){ + xhpcTimingChargingPowerService.getXhpcTimingChargingPowerModelCron(); + } + +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcBarrierGateRecordMapper.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcBarrierGateRecordMapper.java new file mode 100644 index 00000000..0bb00d3a --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcBarrierGateRecordMapper.java @@ -0,0 +1,15 @@ +package com.xhpc.charging.station.mapper; + +import com.xhpc.common.dto.XhpcBarrierGateRecordExcel; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface XhpcBarrierGateRecordMapper { + + List> getLsit(@Param("params")Map params); + + List export(@Param("params")Map params); + Map getXhpcBarrierGateRecordById(@Param("barrierGateRecordId")Long barrierGateRecordId); +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingPileMapper.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingPileMapper.java index b23d6370..32f45eab 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingPileMapper.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingPileMapper.java @@ -127,4 +127,7 @@ public interface XhpcChargingPileMapper { * @return */ int xhpcTerminalSataus(@Param("chargingPileId") Long chargingPileId,@Param("status") Integer status,@Param("prompt")String prompt); + + + void updateXhpcChargingPile(@Param("serialNumber")String serialNumber,@Param("powerNumber")Integer powerNumber); } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingStationMapper.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingStationMapper.java index d9279900..dc87b941 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingStationMapper.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcChargingStationMapper.java @@ -278,4 +278,7 @@ public interface XhpcChargingStationMapper { //获取运营商信息 Map getXhpcOperator(@Param("operatorId") Long operatorId); + + List> getchargingMethodList(); + } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcTimingChargingPowerMapper.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcTimingChargingPowerMapper.java new file mode 100644 index 00000000..53adf761 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/mapper/XhpcTimingChargingPowerMapper.java @@ -0,0 +1,24 @@ +package com.xhpc.charging.station.mapper; + +import com.xhpc.common.domain.XhpcTimingChargingPowerModel; +import org.apache.ibatis.annotations.Param; + +import java.util.List; +import java.util.Map; + +public interface XhpcTimingChargingPowerMapper { + + List> list(@Param("operatorId")Long operatorId, @Param("reason")String reason, @Param("status") Integer status, @Param("startTime") String startTime, @Param("endTime") String endTime, @Param("chargingStationId") Long chargingStationId, @Param("logOperatorId")Long logOperatorId, @Param("type")Integer type, @Param("tenantId")String tenantId); + + int insertXhpcTimingChargingPowerModel(XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel); + + XhpcTimingChargingPowerModel getXhpcTimingChargingPowerModelById(@Param("timingChargingPowerId")Long timingChargingPowerId, @Param("tenantId")String tenantId); + + int updateXhpcTimingChargingPowerModel(XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel); + + List getXhpcTimingChargingPowerModelCron(); + + String getXhpcChargingPile(@Param("chargingPileId")Long chargingPileId,@Param("chargingStationId")Long chargingStationId); + + void updateXhpcChargingPile(@Param("chargingPileId")Long chargingPileId,@Param("powerNumber")Integer powerNumber); +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcBarrierGateRecordService.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcBarrierGateRecordService.java new file mode 100644 index 00000000..14acd552 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcBarrierGateRecordService.java @@ -0,0 +1,14 @@ +package com.xhpc.charging.station.service; + +import com.xhpc.common.dto.XhpcBarrierGateRecordExcel; + +import java.util.List; +import java.util.Map; + +public interface IXhpcBarrierGateRecordService { + + List> getLsit(Map params); + + List export(Map params); + Map getXhpcBarrierGateRecordById(Long barrierGateRecordId ); +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingPileService.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingPileService.java index a8037dd9..2db999fc 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingPileService.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingPileService.java @@ -89,4 +89,6 @@ public interface IXhpcChargingPileService { R getChargingPileSerialNumber(String serialNumber); + + void updateXhpcChargingPilePowerNumber(String serialNumber,Integer powerNumber); } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingStationService.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingStationService.java index 0022d120..f88e8662 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingStationService.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcChargingStationService.java @@ -256,4 +256,7 @@ public interface IXhpcChargingStationService { R getNotificationStationInfo(Long stationId); + + void getchargingMethodList(); + } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcTimingChargingPowerService.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcTimingChargingPowerService.java new file mode 100644 index 00000000..59b218bc --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/IXhpcTimingChargingPowerService.java @@ -0,0 +1,21 @@ +package com.xhpc.charging.station.service; + +import com.xhpc.common.core.domain.R; +import com.xhpc.common.domain.XhpcTimingChargingPowerModel; + +import javax.servlet.http.HttpServletRequest; +import java.util.List; +import java.util.Map; + +public interface IXhpcTimingChargingPowerService { + + List> list(HttpServletRequest request, String tenantId, Long operatorId, String reason, Integer status, String startTime, String endTime, Long chargingStationId); + + R addXhpcTimingChargingPowerModel(HttpServletRequest request, XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel); + + R updateXhpcTimingChargingPowerModel(Long timingChargingPowerId); + + R getXhpcTimingChargingPowerModelMessage(Long timingChargingPowerId); + + R getXhpcTimingChargingPowerModelCron(); +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcBarrierGateRecordServiceImpl.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcBarrierGateRecordServiceImpl.java new file mode 100644 index 00000000..f87b71f8 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcBarrierGateRecordServiceImpl.java @@ -0,0 +1,33 @@ +package com.xhpc.charging.station.service; + +import com.xhpc.charging.station.mapper.XhpcBarrierGateRecordMapper; +import com.xhpc.common.core.web.service.BaseService; +import com.xhpc.common.dto.XhpcBarrierGateRecordExcel; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.Map; + +@Service +public class XhpcBarrierGateRecordServiceImpl extends BaseService implements IXhpcBarrierGateRecordService { + + @Resource + private XhpcBarrierGateRecordMapper xhpcBarrierGateRecordMapper; + + @Override + public List> getLsit(Map params) { + startPage(); + return xhpcBarrierGateRecordMapper.getLsit(params); + } + + @Override + public List export(Map params) { + return xhpcBarrierGateRecordMapper.export(params); + } + + @Override + public Map getXhpcBarrierGateRecordById(Long barrierGateRecordId) { + return xhpcBarrierGateRecordMapper.getXhpcBarrierGateRecordById(barrierGateRecordId); + } +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingPileServiceImpl.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingPileServiceImpl.java index 5948c647..d6fea441 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingPileServiceImpl.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingPileServiceImpl.java @@ -39,9 +39,7 @@ import javax.servlet.http.HttpServletRequest; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.util.*; -import java.util.concurrent.ArrayBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.*; import static com.aliyun.oss.internal.OSSConstants.URL_ENCODING; @@ -71,6 +69,7 @@ public class XhpcChargingPileServiceImpl extends BaseService implements IXhpcCha @Autowired RedisService redisService; + private final ExecutorService executorService = Executors.newFixedThreadPool(20); //字母集合 private static Map letterMap; @@ -189,16 +188,21 @@ public class XhpcChargingPileServiceImpl extends BaseService implements IXhpcCha addXhpcTerminal(xhpcChargingPile.getName(), chargingStationId, rateModelId, serialNumber, chargingPileId, i, number + 1, xhpcChargingPile.getConnectorType(),tenantId); } } + executorService.execute(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(3000); + //插入redis 桩的编号 + HashSet noSet = new HashSet<>(); + noSet.add(serialNumber); + R r = powerPileService.addPileWhitelist(chargingStationId, xhpcChargingPile.getCommunicationProtocolVersion(), noSet); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }); - //插入redis 桩的编号 - HashSet noSet = new HashSet<>(); - noSet.add(serialNumber); - R r = powerPileService.addPileWhitelist(chargingStationId, xhpcChargingPile.getCommunicationProtocolVersion(), noSet); - if (r.getCode() != 200) { - //数据回滚-手动回滚 - TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); - return AjaxResult.error("添加桩入缓存失败,请稍后在试"); - } return AjaxResult.success(); } @@ -289,14 +293,21 @@ public class XhpcChargingPileServiceImpl extends BaseService implements IXhpcCha }else{ Long chargingStationId = xhpcChargingPile.getChargingStationId(); String serialNumber = xhpcChargingPile.getSerialNumber(); - HashSet noSet = new HashSet<>(); - noSet.add(serialNumber); - R r = powerPileService.addPileWhitelist(chargingStationId, xhpcChargingPile.getCommunicationProtocolVersion(), noSet); - if (r.getCode() != 200) { - //数据回滚-手动回滚 - TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); - return AjaxResult.error("添加桩入缓存失败,请稍后在试"); - } + + executorService.execute(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(3000); + HashSet noSet = new HashSet<>(); + noSet.add(serialNumber); + R r = powerPileService.addPileWhitelist(chargingStationId, xhpcChargingPile.getCommunicationProtocolVersion(), noSet); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + }); + } xhpcChargingPileMapper.updaeXhpcChargingPile(xhpcChargingPile); @@ -627,4 +638,9 @@ public class XhpcChargingPileServiceImpl extends BaseService implements IXhpcCha return R.ok(xhpc); } + @Override + public void updateXhpcChargingPilePowerNumber(String serialNumber, Integer powerNumber) { + xhpcChargingPileMapper.updateXhpcChargingPile(serialNumber,powerNumber); + } + } diff --git a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingStationServiceImpl.java b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingStationServiceImpl.java index ab1937af..3ce8985a 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingStationServiceImpl.java +++ b/xhpc-modules/xhpc-charging-station/src/main/java/com/xhpc/charging/station/service/XhpcChargingStationServiceImpl.java @@ -390,6 +390,9 @@ public class XhpcChargingStationServiceImpl extends BaseService implements IXhpc if (xhpcChargingStationDto.getParkNums() == null) { return AjaxResult.error(1001, "侧位数量不能为空"); } + if (xhpcChargingStationDto.getChargingMethod() == null) { + return AjaxResult.error(1001, "允许充电方式为空"); + } //判断费率和费率时间段 是否有值 if (xhpcChargingStationDto.getXhpcRateList() == null && xhpcChargingStationDto.getXhpcRateList().size() == 0) { @@ -692,10 +695,16 @@ public class XhpcChargingStationServiceImpl extends BaseService implements IXhpc powerPileService.getNotificationStationFee(chargingStationId); //生成场站推送数据信息 powerPileService.addNotificationStationInfo(chargingStationId); + //生成场站运行充电方式 + Map chargingMethodMap =new HashMap<>(); + String[] split = xhpcChargingStation.getChargingMethod().split(","); + for (int k = 0; k 50) { return AjaxResult.error(1001, "电站名称不能超过50字"); } + if (xhpcChargingStation.getChargingMethod() == null) { + return AjaxResult.error(1001, "允许充电方式为空"); + } xhpcChargingStation.setServiceFee(xhpcChargingStation.getServiceFeeDescribe()); //获取之前的模板id - XhpcChargingStation xhpc = xhpcChargingStationMapper.selectXhpcChargingStationById(xhpcChargingStation.getChargingStationId()); + Long chargingStationId = xhpcChargingStation.getChargingStationId(); + XhpcChargingStation xhpc = xhpcChargingStationMapper.selectXhpcChargingStationById(chargingStationId); xhpcChargingStation.setRateModelId(xhpc.getRateModelId()); xhpcChargingStationMapper.updateXhpcChargingStation(xhpcChargingStation); //生成场站推送数据信息 - powerPileService.addNotificationStationInfo(xhpcChargingStation.getChargingStationId()); - + powerPileService.addNotificationStationInfo(chargingStationId); + //生成场站运行充电方式 + Map chargingMethodMap =new HashMap<>(); + String[] split = xhpcChargingStation.getChargingMethod().split(","); + for (int k = 0; k > mapList = xhpcChargingStationMapper.getchargingMethodList(); + for (int i = 0; i < mapList.size(); i++) { + Map map = mapList.get(i); + String chargingStationId = map.get("chargingStationId").toString(); + String chargingNethod = map.get("chargingNethod").toString(); + if(chargingNethod!=null && !chargingNethod.equals("")){ + Map chargingMethodMap =new HashMap<>(); + String[] split = chargingNethod.split(","); + for (int k = 0; k > list(HttpServletRequest request, String tenantId, Long operatorId, String reason, Integer status, String startTime, String endTime, Long chargingStationId) { + LoginUser loginUser = tokenService.getLoginUser(request); + SysUser sysUser = loginUser.getSysUser(); + + Long sysUserId = sysUser.getUserId(); + if(!UserTypeUtil.SYS_USER_TYPE_ADMIN.equals(sysUserId)){ + if(UserTypeUtil.SYS_USER_TYPE_ONE.equals(sysUser.getUserType())){ + Long logOperatorId = sysUser.getOperatorId(); + //运营商看自己的场站 + return xhpcTimingChargingPowerMapper.list(operatorId,reason,status,startTime,endTime,chargingStationId,logOperatorId, 1,tenantId); + }else{ + //查询赋值的场站 + return xhpcTimingChargingPowerMapper.list(operatorId,reason,status,startTime,endTime,chargingStationId,sysUserId, 2,tenantId); + } + }else{ + return xhpcTimingChargingPowerMapper.list(operatorId,reason,status,startTime,endTime,chargingStationId,sysUserId, 0,tenantId); + } + + } + + @Override + public R addXhpcTimingChargingPowerModel(HttpServletRequest request, XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel) { + + LoginUser loginUser = tokenService.getLoginUser(request); + if(loginUser ==null){ + return R.fail(1001, "登录信息为空"); + } + if (xhpcTimingChargingPowerModel.getReason() == null || "".equals(xhpcTimingChargingPowerModel.getReason())) { + return R.fail(1001, "调整原因不能为空"); + } + if (xhpcTimingChargingPowerModel.getChargingStationId() == null || "".equals(xhpcTimingChargingPowerModel.getChargingStationId())) { + return R.fail(1001, "场站不能为空"); + } + if (xhpcTimingChargingPowerModel.getTimingTime() == null || "".equals(xhpcTimingChargingPowerModel.getTimingTime())) { + return R.fail(1001, "调整时间不能为空"); + }else{ + if(System.currentTimeMillis()>xhpcTimingChargingPowerModel.getTimingTime().getTime()){ + return R.fail(1001, "调整时间不能小于现在时间"); + } + } + + if (xhpcTimingChargingPowerModel.getPowerNumber() == null) { + return R.fail(1001, "桩功率百分比不能为空"); + }else { + if(xhpcTimingChargingPowerModel.getPowerNumber()<1 || xhpcTimingChargingPowerModel.getPowerNumber()>100){ + return R.fail(1001, "桩功率百分比范围在1~100之间"); + } + } + if(xhpcTimingChargingPowerModel.getChargingPileIds().length==0){ + return R.fail(1001, "请选择桩"); + } + Integer[] chargingPileIds = xhpcTimingChargingPowerModel.getChargingPileIds(); + String st =""; + for (int i = 0; i 1){ + st =st+chargingPileIds[i]+","; + }else if(chargingPileIds.length==1){ + st =chargingPileIds[i]+""; + }else{ + st =st+","+chargingPileIds[i]; + } + } + xhpcTimingChargingPowerModel.setPileIds(st); + + if(xhpcTimingChargingPowerModel.getTimingChargingPowerId() !=null){ + xhpcTimingChargingPowerMapper.updateXhpcTimingChargingPowerModel(xhpcTimingChargingPowerModel); + }else{ + xhpcTimingChargingPowerMapper.insertXhpcTimingChargingPowerModel(xhpcTimingChargingPowerModel); + } + return R.ok(); + } + + @Override + public R updateXhpcTimingChargingPowerModel(Long timingChargingPowerId) { + LoginUser loginUser = tokenService.getLoginUser(); + if(loginUser ==null){ + return R.ok(); + } + //查询是否是未执行状态 + XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel = xhpcTimingChargingPowerMapper.getXhpcTimingChargingPowerModelById(timingChargingPowerId,null); + if(xhpcTimingChargingPowerModel ==null){ + return R.fail("数据不存在"); + }else if (xhpcTimingChargingPowerModel.getStatus()==0){ + xhpcTimingChargingPowerModel.setDelFlag(2); + xhpcTimingChargingPowerMapper.updateXhpcTimingChargingPowerModel(xhpcTimingChargingPowerModel); + return R.ok(); + }else if (xhpcTimingChargingPowerModel.getStatus()==1){ + return R.fail("该数据已执行,不能删除"); + }else { + return R.fail("该数据执行错误,不能删除"); + } + } + + @Override + public R getXhpcTimingChargingPowerModelMessage(Long timingChargingPowerId) { + + Map map =new HashMap<>(); + LoginUser loginUser = tokenService.getLoginUser(); + if(loginUser ==null){ + return R.ok(map); + } + //查询是否是未执行状态 + XhpcTimingChargingPowerModel xhpcTimingChargingPowerModelById = xhpcTimingChargingPowerMapper.getXhpcTimingChargingPowerModelById(timingChargingPowerId, loginUser.getTenantId()); + + if(xhpcTimingChargingPowerModelById.getPileIds().length()>0){ + String pileIds = xhpcTimingChargingPowerModelById.getPileIds(); + String[] split = pileIds.split(","); + Integer [] piles =new Integer [split.length]; + for (int i = 0; i list = xhpcTimingChargingPowerMapper.getXhpcTimingChargingPowerModelCron(); + if(list !=null && list.size()>0){ + for (int i = 0; i < list.size(); i++) { + XhpcTimingChargingPowerModel xhpcTimingChargingPowerModel = list.get(i); + String pileIds = xhpcTimingChargingPowerModel.getPileIds(); + + List piles = Arrays.asList(pileIds.split(",")); + //获取桩号 + for (String pileId:piles) { + String xhpcChargingPile = xhpcTimingChargingPowerMapper.getXhpcChargingPile(Long.getLong(pileId),xhpcTimingChargingPowerModel.getChargingStationId()); + + R r =powerPileService.pileConfigSettings(xhpcChargingPile,xhpcTimingChargingPowerModel.getPowerNumber().toString()); + if (r.getCode() != 200) { + executorService.execute(new Runnable() { + @Override + public void run() { + R r1 = powerPileService.pileConfigSettings(xhpcChargingPile, xhpcTimingChargingPowerModel.getPowerNumber().toString()); + if (r1.getCode() == 200) { + xhpcTimingChargingPowerMapper.updateXhpcChargingPile(Long.getLong(pileId),xhpcTimingChargingPowerModel.getPowerNumber()); + } + } + }); + }else{ + xhpcTimingChargingPowerMapper.updateXhpcChargingPile(Long.getLong(pileId),xhpcTimingChargingPowerModel.getPowerNumber()); + } + } + } + } + + + return null; + } +} diff --git a/xhpc-modules/xhpc-charging-station/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-charging-station/src/main/resources/bootstrap.yml index 658ae6ee..4263af98 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/resources/bootstrap.yml +++ b/xhpc-modules/xhpc-charging-station/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcBarrierGateRecord.xml b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcBarrierGateRecord.xml new file mode 100644 index 00000000..22f31379 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcBarrierGateRecord.xml @@ -0,0 +1,147 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingPileMapper.xml b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingPileMapper.xml index cd1e37f0..291e74ed 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingPileMapper.xml +++ b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingPileMapper.xml @@ -97,6 +97,7 @@ cp.type as type, cp.power as power, cp.gun_number as gunNumber, + cp.power_number as powerNumber, cp.status as status from xhpc_charging_pile as cp left join xhpc_charging_station as st on st.charging_station_id =cp.charging_station_id @@ -641,4 +642,8 @@ set status = #{status} and prompt=#{prompt} where charging_pile_id = #{chargingPileId} + + + update xhpc_charging_pile set power_number =#{powerNumber} where serial_number =#{serialNumber} and del_flag =0 + diff --git a/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingStationMapper.xml b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingStationMapper.xml index 17db62c5..5c05a2a1 100644 --- a/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingStationMapper.xml +++ b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcChargingStationMapper.xml @@ -36,7 +36,7 @@ - + @@ -249,6 +249,9 @@ running_total_power=#{runningTotalPower}, + + charging_method=#{chargingMethod}, + equipment_owner_id=#{equipmentOwnerId}, @@ -366,7 +369,9 @@ video_monitor=#{videoMonitor}, + barrier_gate_id=#{barrierGateId}, + where charging_station_id = #{chargingStationId} @@ -444,6 +449,7 @@ op.name as operatorName, ct.type as type, ct.construction_time as constructionTime, + ct.charging_method as chargingMethod, ct.open_all_day as openAllDay, ct.busine_hours as busineHours, ct.electricity_fee as electricityFee, @@ -896,6 +902,9 @@ barrier_gate_id, + + charging_method, + @@ -1110,6 +1119,9 @@ #{barrierGateId}, + + #{chargingMethod}, + @@ -1444,4 +1456,11 @@ operator_id_evcs as operatorIdEvcs from xhpc_operator where operator_id= #{operatorId} + + diff --git a/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcTimingChargingPowerMapper.xml b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcTimingChargingPowerMapper.xml new file mode 100644 index 00000000..7d878332 --- /dev/null +++ b/xhpc-modules/xhpc-charging-station/src/main/resources/mapper/XhpcTimingChargingPowerMapper.xml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + insert into xhpc_timing_charging_power + + + reason, + + + charging_station_id, + + + timing_time, + + + tenant_id, + + + status, + + + del_flag, + + + create_time, + + + create_by, + + + update_time, + + + update_by, + + + remark, + + + phone, + + + power_number, + + + pile_ids, + + + + + #{reason}, + + + #{chargingStationId}, + + + #{timingTime}, + + + #{tenantId}, + + + #{status}, + + + #{delFlag}, + + + #{createTime}, + + + #{createBy}, + + + #{updateTime}, + + + #{updateBy}, + + + #{remark}, + + + #{phone}, + + + #{powerNumber}, + + + #{pileIds}, + + + + + + + + update xhpc_timing_charging_power + + charging_station_id = #{chargingStationId}, + reason = #{reason}, + timing_time = #{timingTime}, + error_reason = #{errorReason}, + number = #{number}, + status = #{status}, + del_flag = #{delFlag}, + create_time = #{createTime}, + create_by = #{createBy}, + update_time = #{updateTime}, + update_by = #{updateBy}, + remark = #{remark}, + phone = #{phone}, + power_number = #{powerNumber}, + pile_ids = #{pileIds}, + + where timing_charging_power_id =#{timingChargingPowerId} + + + + + + + + + update xhpc_charging_pile set power_number =#{powerNumber} where charging_pile_id =#{chargingPileId} + + diff --git a/xhpc-modules/xhpc-common/pom.xml b/xhpc-modules/xhpc-common/pom.xml index 36682a4f..54b4b86a 100644 --- a/xhpc-modules/xhpc-common/pom.xml +++ b/xhpc-modules/xhpc-common/pom.xml @@ -70,5 +70,10 @@ 2.1.5 + + com.alibaba + easyexcel + 3.0.2 + diff --git a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/EvcsService.java b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/EvcsService.java index a853261e..39a77926 100644 --- a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/EvcsService.java +++ b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/EvcsService.java @@ -26,4 +26,8 @@ public interface EvcsService { @PostMapping("/v20/getCYCNotificationConnectorChargeStatus") R getCYCNotificationConnectorChargeStatus(@RequestBody Map orderMap); + + + @PostMapping("/v20/getCYCNotificationStartChargeResult") + R getCYCNotificationStartChargeResult(@RequestBody Map orderMap); } diff --git a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/PowerPileService.java b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/PowerPileService.java index 7b773361..757e2a74 100644 --- a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/PowerPileService.java +++ b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/PowerPileService.java @@ -20,6 +20,11 @@ public interface PowerPileService { @PostMapping("/charging/start") R startCharging(@Validated @RequestBody StartChargingData startChargingData); + + @PostMapping("/charging/capacity/start") + R startChargingCapacity(@Validated @RequestBody StartChargingData startChargingData); + + @PostMapping("/charging/balance/refresh") R refreshBalance(@Validated @RequestBody StartChargingData balanceRefreshData); @@ -95,4 +100,8 @@ public interface PowerPileService { //推送充电站实时功率 @GetMapping("/station/getSuperviseNotificationRealtimePowerInfo") R getSuperviseNotificationRealtimePowerInfo(@RequestParam("operatorIdEvcs")String operatorIdEvcs,@RequestParam("replace")String replace); + + //充电桩工作参数设置 + @PostMapping("/pile/{pileNo}/{powerNumber}/configSettings") + R pileConfigSettings(@PathVariable("pileNo") @Param("pileNo")String pileNo,@PathVariable("powerNumber") @Param("powerNumber")String powerNumber); } diff --git a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/EvcsServiceFallbackFactory.java b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/EvcsServiceFallbackFactory.java index 135c93da..5bbe8b11 100644 --- a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/EvcsServiceFallbackFactory.java +++ b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/EvcsServiceFallbackFactory.java @@ -40,6 +40,11 @@ public class EvcsServiceFallbackFactory implements FallbackFactory return R.fail(500,"Evcs服务--》川逸充设备充电结束状态变化推送接口失败:" + orderMap); } + @Override + public R getCYCNotificationStartChargeResult(Map orderMap) { + return R.fail(500,"Evcs服务--》川逸充启动结果推送接口失败:" + orderMap); + } + }; } } diff --git a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/PowerPileFallbackFactory.java b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/PowerPileFallbackFactory.java index f8a463f9..27860217 100644 --- a/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/PowerPileFallbackFactory.java +++ b/xhpc-modules/xhpc-common/src/main/java/com/xhpc/common/api/factory/PowerPileFallbackFactory.java @@ -28,6 +28,11 @@ public class PowerPileFallbackFactory implements FallbackFactory10000){ message = tenantId + UserTypeUtil.CYCUSER + userId; + if(code==200){ + Map map1 = new HashMap<>(); + map1.put("OperatorID", "MA6CC2LK7"); + map1.put("orderNo", orderNo); + logger.info(">>>启动回调>>川逸充启动结果推送接口>>>>>>>>>"); + evcsService.getCYCNotificationStartChargeResult(map1); + logger.info(">>>启动回调>>川逸充启动结果推送接口>>>>>>>>>"); + } } //消息对了内容 if(xhpcChargeOrder.getSource()==0){ @@ -132,6 +140,10 @@ public class XhpcPileOrderController extends BaseController { public R pileStop(@RequestParam(value = "orderNo")String orderNo, @RequestParam(value = "status")Integer status,@RequestParam(value = "remark") String remark) { logger.info("桩停止回调接口>>>>>状态:"+status+"备注++"+remark+"订单号"+orderNo); + if("".equals(orderNo) || orderNo==null){ + logger.info(">>>>>桩停止回调接口--订单号为空>>>>>>>>>"); + return R.ok(); + } XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo); //解析订单编号 if(historyOrder !=null){ @@ -247,12 +259,22 @@ public class XhpcPileOrderController extends BaseController { logger.info("桩实时数据回调接口--无效订单号>>>>>orderNo:" + orderNo); return R.fail(500,"无效订单号"); } + if(xhpcChargeOrder.getStatus()==null){ xhpcChargeOrder.setStatus(0); if(xhpcChargeOrder.getInternetSerialNumber()!=null && xhpcChargeOrder.getSource()==null){ xhpcChargeOrder.setSource(1); } } + + if(xhpcChargeOrder.getStatus()==1||xhpcChargeOrder.getStatus()==2||xhpcChargeOrder.getStatus()==3){ + XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo); + if(historyOrder!=null){ + logger.info("桩实时数据回调接口--重复订单号>>>>>orderNo:" + orderNo); + return R.fail(500,"无效订单号"); + } + } + Map cacheMap = redisService.getCacheMap("order:"+orderNo); if(cacheMap==null || cacheMap.get("startType")==null ){ logger.info("桩实时数据回调接口--无效订单号>>>>>orderNo:" + orderNo); @@ -420,6 +442,10 @@ public class XhpcPileOrderController extends BaseController { public R pileEndOrder(@RequestParam(value = "orderNo") String orderNo) { logger.info("桩订单结束回调>>>>>orderNo:"+orderNo); try{ + if("".equals(orderNo) || orderNo==null){ + logger.info(">>>>>桩停止回调接口--订单号为空>>>>>>>>>"); + return R.ok(); + } XhpcHistoryOrder historyOrder = xhpcHistoryOrderService.getHistoryOrderById(null, orderNo); if(historyOrder !=null){ logger.info("订单已结束不能重复结算>>>>>orderNo:"+orderNo); @@ -497,6 +523,8 @@ public class XhpcPileOrderController extends BaseController { BigDecimal money = new BigDecimal(cacheOrderData.getCost()).divide(bigDecimal,2,BigDecimal.ROUND_HALF_UP); if(cacheOrderData.getTotalPowerQuantity()==0 || totalPowerQuantity.compareTo(new BigDecimal(0.1))<1 || money.compareTo(new BigDecimal(0.1))<1){ + + xhpcChargeOrder.setStatus(3); xhpcChargeOrder.setUpdateTime(new Date()); int startSoc1 = cacheOrderData.getStartSoc(); @@ -504,10 +532,57 @@ public class XhpcPileOrderController extends BaseController { xhpcChargeOrder.setStartSoc(startSoc1 + ""); xhpcChargeOrder.setEndSoc(endSoc1 + ""); + Date date = new Date(); + BigDecimal bigDecimal1 = new BigDecimal(0); + xhpcChargeOrder.setStartTime(date); + xhpcChargeOrder.setEndTime(date); + xhpcChargeOrder.setChargingTime("0分"); + xhpcChargeOrder.setChargingDegree(bigDecimal1); + xhpcChargeOrder.setType("199"); + xhpcChargeOrder.setAmountCharged(bigDecimal1); + xhpcChargeOrder.setChargingTimeNumber(0L); xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder); - xhpcRealTimeOrderService.addZeroHistoryOrder(xhpcChargeOrder); + //xhpcRealTimeOrderService.addZeroHistoryOrder(xhpcChargeOrder); logger.info("*********************电量为0订单号>>>>>orderNo:" + orderNo); logger.info("*********************电量为0订单号>>>>>orderNo:" + orderNo); + //生成一条历史订单 + XhpcHistoryOrder xhpcHistoryOrder = new XhpcHistoryOrder(); + xhpcHistoryOrder.setStartTime(date); + xhpcHistoryOrder.setInternetSerialNumber(xhpcChargeOrder.getInternetSerialNumber()); + xhpcHistoryOrder.setEndTime(date); + xhpcHistoryOrder.setPowerPriceTotal(bigDecimal1); + xhpcHistoryOrder.setServicePriceTotal(bigDecimal1); + xhpcHistoryOrder.setTotalPower(0.0); + xhpcHistoryOrder.setMeterValueStartEvcs(cacheOrderData.getElectricMeterStart().doubleValue()); + xhpcHistoryOrder.setMeterValueEndEvcs(cacheOrderData.getElectricMeterEnd().doubleValue()); + xhpcHistoryOrder.setVinNormal(xhpcChargeOrder.getVinNormal()); + xhpcHistoryOrder.setType(1); + + Map userMessage =new HashMap<>(); + + if(!UserTypeUtil.INTERNET_TYPE.equals(source)||(UserTypeUtil.INTERNET_TYPE.equals(source) && userId>1000)){ + R user = userTypeService.getUser(null, userId, source, null, tenantId); + if(user !=null && user.getData() !=null ){ + userMessage = (Map)user.getData(); + if (userMessage == null || userMessage.get("balance") == null) { + logger.info("获取用户信息失败>>userMessage>>>orderNo:"+orderNo); + return R.fail(500,"添加订单回调失败"); + } + }else{ + logger.info("获取用户信息失败>>user>>>orderNo:"+orderNo); + return R.fail(500,"添加订单回调失败"); + } + }else{ + if(pushOrder !=null){ + if(pushOrder.get("internetSerialNumber") !=null){ + xhpcHistoryOrder.setInternetSerialNumber(pushOrder.get("internetSerialNumber").toString()); + } + if(pushOrder.get("operatorId3rdpty") !=null){ + xhpcHistoryOrder.setOperatorId3rdptyEvcs((String) pushOrder.get("operatorId3rdpty")); + } + } + } + xhpcRealTimeOrderService.addSettlement(bigDecimal1,bigDecimal1,bigDecimal1,bigDecimal1,bigDecimal1,xhpcChargeOrder,userId,userMessage,1,cacheOrderData.getVinNormal(),xhpcHistoryOrder); Map map = new HashMap<>(); map.put("code", 500); @@ -618,11 +693,11 @@ public class XhpcPileOrderController extends BaseController { }else{ money = powerPrice.add(servicePrice); } - if(money.compareTo(new BigDecimal(500)) > -1){ - logger.info("结算金额大于500>>"+money+">>>orderNo:" + orderNo); + if(money.compareTo(new BigDecimal(1000)) > -1){ + logger.info("结算金额大于1000>>"+money+">>>orderNo:" + orderNo); xhpcChargeOrder.setStatus(2); xhpcChargeOrder.setUpdateTime(new Date()); - xhpcChargeOrder.setErroRemark("充电金额大于500元"); + xhpcChargeOrder.setErroRemark("充电金额大于1000元"); xhpcChargeOrderService.updateXhpcChargeOrder(xhpcChargeOrder); return R.fail(500,"无效订单号:"+orderNo); } diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/controller/XhpcHistoryOrderController.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/controller/XhpcHistoryOrderController.java index 46d13abc..41648e80 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/controller/XhpcHistoryOrderController.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/controller/XhpcHistoryOrderController.java @@ -8,6 +8,7 @@ import com.xhpc.common.core.domain.R; import com.xhpc.common.core.web.controller.BaseController; import com.xhpc.common.core.web.domain.AjaxResult; import com.xhpc.common.core.web.page.TableDataInfo; +import com.xhpc.common.redis.service.RedisService; import com.xhpc.order.domain.XhpcHistoryOrder; import com.xhpc.order.domain.XhpcStatisticsStation; import com.xhpc.order.domain.XhpcStatisticsTimeInterval; @@ -48,6 +49,8 @@ public class XhpcHistoryOrderController extends BaseController { private IXhpcChargeOrderService chargeOrderService; @Autowired private WorkOrderYuService workOrderYuService; + @Autowired + private RedisService redisService; private static final Logger logger = LoggerFactory.getLogger(XhpcHistoryOrderController.class); @@ -889,24 +892,32 @@ public class XhpcHistoryOrderController extends BaseController { * 24小时异常订单自动结算 */ @GetMapping("/test4") - @Scheduled(cron = "0 0/5 * * * ?") + @Scheduled(cron = "0 0/10 * * * ?") public void test4(){ - //获取异常的订单 24小时之外的异常订单 - List> xhpcChargeOrderList= chargeOrderService.getXhpcChargeOrderStatus(2); + try { + //1自动 2 4小时 3 6小时 4 8小时 5 12小时 6 44小时 + Integer pilePrompts = redisService.getCacheObject("pilePrompt:000000"); + if(pilePrompts!=null && pilePrompts!=1){ + //获取异常的订单 24小时之外的异常订单 + List> xhpcChargeOrderList= chargeOrderService.getXhpcChargeOrderStatus(2,pilePrompts); - if(xhpcChargeOrderList !=null && xhpcChargeOrderList.size()>0){ - for (int i = 0; i map = xhpcChargeOrderList.get(i); - if(map !=null){ - Long chargeOrderId = Long.valueOf(map.get("chargeOrderId").toString()); - if(map.get("realTimeOrderId")!=null){ - Long realTimeOrderId = Long.valueOf(map.get("realTimeOrderId").toString()); - xhpcHistoryOrderService.addXhpcChargeOrder(realTimeOrderId,chargeOrderId); - }else{ - xhpcHistoryOrderService.addXhpcChargeOrder(null,chargeOrderId); + if(xhpcChargeOrderList !=null && xhpcChargeOrderList.size()>0){ + for (int i = 0; i map = xhpcChargeOrderList.get(i); + if(map !=null){ + Long chargeOrderId = Long.valueOf(map.get("chargeOrderId").toString()); + if(map.get("realTimeOrderId")!=null){ + Long realTimeOrderId = Long.valueOf(map.get("realTimeOrderId").toString()); + xhpcHistoryOrderService.addXhpcChargeOrder(realTimeOrderId,chargeOrderId); + }else{ + xhpcHistoryOrderService.addXhpcChargeOrder(null,chargeOrderId); + } + } } } } + }catch (Exception e){ + } } @@ -922,6 +933,30 @@ public class XhpcHistoryOrderController extends BaseController { chargeOrderService.updateStatus(); } + + /** + * 订单状态为null,每5分钟检测一次 + * @param + * @param + */ + @GetMapping("/test6") + @Scheduled(cron = "0 0/5 * * * ?") + public void test6(){ + chargeOrderService.updateStatusNull(); + } + + /** + * 订单状态为-1的流量方订单,每5分钟检测一次 + * @param + * @param + */ + @GetMapping("/test9") + @Scheduled(cron = "0 0/5 * * * ?") + public void test9(){ + chargeOrderService.updateStatusNegativeOne(); + } + + //@Scheduled(cron = "0 0/1 * * * ?") @GetMapping("/getInvoiceInfo") public void getInvoiceInfo(){ diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/domain/XhpcChargeOrder.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/domain/XhpcChargeOrder.java index 6bcd924c..3d3d2c07 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/domain/XhpcChargeOrder.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/domain/XhpcChargeOrder.java @@ -156,6 +156,7 @@ public class XhpcChargeOrder extends BaseEntity { private String vinNormal; + private Integer chargingCapacity; public Integer getStopReasonEvcs() { return stopReasonEvcs; @@ -485,4 +486,12 @@ public class XhpcChargeOrder extends BaseEntity { public void setVinNormal(String vinNormal) { this.vinNormal = vinNormal; } + + public Integer getChargingCapacity() { + return chargingCapacity; + } + + public void setChargingCapacity(Integer chargingCapacity) { + this.chargingCapacity = chargingCapacity; + } } diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcChargeOrderMapper.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcChargeOrderMapper.java index d9f76835..071dac47 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcChargeOrderMapper.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcChargeOrderMapper.java @@ -26,8 +26,9 @@ public interface XhpcChargeOrderMapper { * @param userId * @return */ - int getHistotyChargeOrderMessage(@Param("userId") Long userId,@Param("tenantId") String tenantId,@Param("userType") Integer userType); + Map getHistotyChargeOrderMessageMap(@Param("userId") Long userId,@Param("tenantId") String tenantId,@Param("userType") Integer userType,@Param("thirdCode")String thirdCode); + int getHistotyChargeOrderMessage(@Param("userId") Long userId,@Param("tenantId") String tenantId,@Param("userType") Integer userType); Map getMessage(@Param("userId") Long userId); /** @@ -180,7 +181,7 @@ public interface XhpcChargeOrderMapper { * @param status -1准备充电 0开始充电 1自动结算,2异常,3平台结算 * @return */ - List> getXhpcChargeOrderStatus(@Param("status") Integer status); + List> getXhpcChargeOrderStatus(@Param("status") Integer status,@Param("number") Integer number); /** * insert a row by 3rd. @@ -219,6 +220,10 @@ public interface XhpcChargeOrderMapper { List getFourTimsStatus(); List> getChargeOrderStatus(); + + void updateStatusNull(); + + void updateStatusNegativeOne(); /** * 查询相同桩之后是否有订单结算 * @param serialNumber 订单号 @@ -238,7 +243,7 @@ public interface XhpcChargeOrderMapper { Map getXhpcBarrierGate(@Param("chargingStationId")Long chargingStationId); //根据VIN码获取用户 - Map getvVinNumber(@Param("vinNumber")String vinNumber); + Map getvVinNumber(@Param("vinNumber")String vinNumber,@Param("reverseVinNumber")String reverseVinNumber); //获取充电站信息 Map getChargingStationById(@Param("chargingStationId")Long chargingStationId); diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcHistoryOrderMapper.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcHistoryOrderMapper.java index 3c880272..b0e975f0 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcHistoryOrderMapper.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/mapper/XhpcHistoryOrderMapper.java @@ -26,6 +26,9 @@ public interface XhpcHistoryOrderMapper { public int insertXhpcWorkHistoryOrderDto(XhpcWorkHistoryOrderDto xhpcWorkHistoryOrderDto); int updateXhpcHistoryOrderSerialNumber(XhpcHistoryOrder xhpcHistoryOrder); + + + int updateXhpcHistoryOrderParkingVoucher(XhpcHistoryOrder xhpcHistoryOrder); /** * 更新 历史订单信息 * diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcChargeOrderService.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcChargeOrderService.java index 218875d2..4ddb5565 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcChargeOrderService.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcChargeOrderService.java @@ -18,6 +18,16 @@ import java.util.Map; */ public interface IXhpcChargeOrderService { + + /** + * 判断实时订单 + * + * @param + * @return + */ + AjaxResult getCYCHistotyChargeOrderMessage(Long userId, Integer userType, String tenantId,String thirdCode); + + /** * 判断实时订单 * @@ -150,7 +160,7 @@ public interface IXhpcChargeOrderService { /** * 24小时异常结算 */ - List> getXhpcChargeOrderStatus(Integer status); + List> getXhpcChargeOrderStatus(Integer status,Integer number); R startUpBy3rd(String internetSerialNumber, String driverId, Integer chargingAmt, String plateNum, Integer status, String connectorId); @@ -160,6 +170,11 @@ public interface IXhpcChargeOrderService { */ void updateStatus(); + + void updateStatusNull(); + + void updateStatusNegativeOne(); + /** * 查询是否有异常订单 * @return @@ -191,4 +206,14 @@ public interface IXhpcChargeOrderService { * @return */ R cycStartUp(HttpServletRequest request, Long userId, String serialNumber, Integer type,Integer source,BigDecimal money,String phone,String PlateNum); + + + /** + * 启动充电 + * @param userId + * @param serialNumber 终端编码 + * @return + */ + AjaxResult chargingCapacityStartUp(HttpServletRequest request, Long userId, String serialNumber, Integer type,Integer chargingCapacity); + } diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcHistoryOrderService.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcHistoryOrderService.java index 48faddb7..d2ec1d7c 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcHistoryOrderService.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/IXhpcHistoryOrderService.java @@ -54,6 +54,13 @@ public interface IXhpcHistoryOrderService { int updateXhpcHistoryOrderSerialNumber(XhpcHistoryOrder xhpcHistoryOrder); + /** + * 修改停车优惠券是否发生 + * @param xhpcHistoryOrder + * @return + */ + int updateXhpcHistoryOrderParkingVoucher(XhpcHistoryOrder xhpcHistoryOrder); + /** * 历史订单记录(PC) diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcChargeOrderServiceImpl.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcChargeOrderServiceImpl.java index 5e08354d..7a4f6da9 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcChargeOrderServiceImpl.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcChargeOrderServiceImpl.java @@ -91,6 +91,27 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar REDIS =redisService; } + @Override + public AjaxResult getCYCHistotyChargeOrderMessage(Long userId, Integer userType, String tenantId,String thirdCode) { + Map map = xhpcChargeOrderMapper.getHistotyChargeOrderMessageMap(userId,tenantId,userType,thirdCode); + if(map !=null){ + if(map.get("status")==null){ + return AjaxResult.error(1201,"无实时数据"); + }else if("-1".equals(map.get("status").toString())){ + return AjaxResult.error(1201,"无实时数据"); + }else if("0".equals(map.get("status").toString())){ + return AjaxResult.success(map); + }else if("1".equals(map.get("status").toString()) ||"3".equals(map.get("status").toString())){ + return AjaxResult.success(map); + }else if("2".equals(map.get("status").toString())){ + return AjaxResult.success(map); + }{ + return AjaxResult.error(1201,"无实时数据"); + } + } + return AjaxResult.error(1201,"无实时数据"); + } + @Override public AjaxResult getHistotyChargeOrderMessage(HttpServletRequest request) { try{ @@ -145,6 +166,7 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar @Transactional public AjaxResult startUp(HttpServletRequest request, Long userId, String terminalSerialNumber, Integer type) { try{ + XhpcChargeOrder xhpcChargeOrder = new XhpcChargeOrder(); LoginUser loginUser = tokenService.getLoginUser(request); if (StringUtils.isNotNull(loginUser)) { String username = loginUser.getUsername(); @@ -169,6 +191,7 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar return AjaxResult.error(UserTypeUtil.LOGIN_TYPE, "此账号不能在该场站充电,请使用手机号登录"); } } + xhpcChargeOrder.setDriverId(userMessage.get("phone").toString()); String pattern = "^([0-9]{16})"; Pattern compile = Pattern.compile(pattern); Matcher m = compile.matcher(terminalSerialNumber); @@ -239,7 +262,17 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } logger.info("<<<<<<<<<<<<<<<<<<<<<<<<终端编号>>>>"+terminalSerialNumber+">>>>>>>>>>>>>"+tenantId); - logger.info("<<<<<<<<<<<<<<<<<<<<<<<<终端编号>>>>>>>>>>>>>>>>"); + //查询该场站是否有运行充电权限 + Map cacheMap1 = redisService.getCacheMap("chargingMethod:" + xhpcTerminal.getChargingStationId()); + + if(cacheMap1 ==null){ + return AjaxResult.error(1104, "该充电场站不支持扫描充电"); + }else{ + if(cacheMap1.get("1")==null){ + return AjaxResult.error(1104, "该充电场站不支持扫描充电"); + } + } + //余额 String balance = new BigDecimal(userMessage.get("balance").toString()).multiply(new BigDecimal(100)).toString(); //获取桩信息 @@ -252,6 +285,7 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar startChargingData.setOrderNo(orderNo); if(userMessage.get("phone") !=null){ startChargingData.setTel(userMessage.get("phone").toString()); + xhpcChargeOrder.setDriverId(userMessage.get("phone").toString()); } startChargingData.setPileNo(xhpcTerminal.getPileSerialNumber()); startChargingData.setGunId(xhpcTerminal.getSerialNumber().substring(14)); @@ -299,7 +333,7 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:"+number); logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:"+startChargingData.getSoc()); //创建充电订单(充电启动soc初始值,结束是获取,并修改状态) - XhpcChargeOrder xhpcChargeOrder = new XhpcChargeOrder(); + xhpcChargeOrder.setChargingStationId(xhpcTerminal.getChargingStationId()); xhpcChargeOrder.setUserId(userId); xhpcChargeOrder.setTerminalId(xhpcTerminal.getTerminalId()); @@ -313,8 +347,10 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } if (type == 1) { xhpcChargeOrder.setChargingMode("微信"); - } else { + } else if (type == 2){ xhpcChargeOrder.setChargingMode("支付宝"); + }else{ + xhpcChargeOrder.setChargingMode("App"); } xhpcChargeOrder.setCreateTime(Calendar.getInstance().getTime()); xhpcChargeOrder.setType("91"); @@ -497,8 +533,8 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } @Override - public List> getXhpcChargeOrderStatus(Integer status) { - return xhpcChargeOrderMapper.getXhpcChargeOrderStatus(status); + public List> getXhpcChargeOrderStatus(Integer status,Integer number) { + return xhpcChargeOrderMapper.getXhpcChargeOrderStatus(status,number); } @Override @@ -741,6 +777,15 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } } + @Override + public void updateStatusNull() { + xhpcChargeOrderMapper.updateStatusNull(); + } + + @Override + public void updateStatusNegativeOne() { + xhpcChargeOrderMapper.updateStatusNegativeOne(); + } /** * 查询是否有异常订单 * @@ -844,7 +889,16 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } } } + //查询该场站是否有运行充电权限 + Map cacheMap1 = redisService.getCacheMap("chargingMethod:" + xhpcTerminal.getChargingStationId()); + if(cacheMap1 ==null){ + return R.fail(1104, "该充电场站不支持刷卡充电"); + }else{ + if(cacheMap1.get("3")==null){ + return R.fail(1104, "该充电场站不支持扫描充电"); + } + } //创建订单 //订单流水号 终端号+年月日时分秒+自增4位 共32位 String orderNo = genOrder(serialNumber); @@ -911,12 +965,18 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar @Override public R pileVin(String serialNumber, String vinNumber) { try{ + System.out.println("=========vin======serialNumber======="+serialNumber); + System.out.println("=========vin======vinNumber======="+vinNumber); if("".equals(vinNumber) || vinNumber ==null ){ return R.fail(1888, "VIN码为空"); }else if (vinNumber.length()!=17){ return R.fail(1880, "无效VIN码"); } - Map stringObjectMap = xhpcChargeOrderMapper.getvVinNumber(vinNumber); + + XhpcChargeOrder xhpcChargeOrder = new XhpcChargeOrder(); + String reverseVinNumber = new StringBuilder(vinNumber).reverse().toString(); + System.out.println("=========vin======reverseVinNumber======="+reverseVinNumber); + Map stringObjectMap = xhpcChargeOrderMapper.getvVinNumber(vinNumber,reverseVinNumber); if(stringObjectMap ==null && stringObjectMap.get("appUerId")==null || stringObjectMap.get("source")==null){ return R.fail(1888, "无效VIN码"); } @@ -1006,6 +1066,18 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } } } + + //查询该场站是否有运行充电权限 + Map cacheMap1 = redisService.getCacheMap("chargingMethod:" + xhpcTerminal.getChargingStationId()); + + if(cacheMap1 ==null){ + return R.fail(1104, "该充电场站不支持刷卡充电"); + }else{ + if(cacheMap1.get("2")==null){ + return R.fail(1104, "该充电场站不支持扫描充电"); + } + } + //余额 String balance = new BigDecimal(userMessage.get("balance").toString()).multiply(new BigDecimal(100)).toString(); //获取桩信息 @@ -1018,6 +1090,7 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar startChargingData.setOrderNo(orderNo); if(userMessage.get("phone") !=null){ startChargingData.setTel(userMessage.get("phone").toString()); + xhpcChargeOrder.setDriverId(userMessage.get("phone").toString()); } startChargingData.setPileNo(xhpcTerminal.getPileSerialNumber()); startChargingData.setGunId(xhpcTerminal.getSerialNumber().substring(14)); @@ -1059,7 +1132,7 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:"+number); logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:"+startChargingData.getSoc()); //创建充电订单(充电启动soc初始值,结束是获取,并修改状态) - XhpcChargeOrder xhpcChargeOrder = new XhpcChargeOrder(); + xhpcChargeOrder.setChargingStationId(xhpcTerminal.getChargingStationId()); xhpcChargeOrder.setUserId(userId); xhpcChargeOrder.setTerminalId(xhpcTerminal.getTerminalId()); @@ -1357,10 +1430,6 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar } //终端状态是否空闲\是否插枪 Map cacheMap = REDIS.getCacheMap("gun:" + serialNumber); - logger.info("<<<<<<<<<<<<<<<<<川逸充<<<<<<>>>>>>>>>>>>>>>>"); - logger.info("<<<<<<<<<<<<<<<<<川逸充<<<<<<>>>>>>>>>>>>>>>>" + serialNumber); - logger.info("<<<<<<<<<<<<<<<<<川逸充<<<<<<>>>>>>>>>>>>>>>>" + cacheMap.toString()); - logger.info("<<<<<<<<<<<<<<<<<川逸充<<<<<<>>>>>>>>>>>>>>>>"); if (cacheMap == null) { r.setCode(500); r.setMsg("未注册的终端,请选择其他终端充电"); @@ -1466,20 +1535,6 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar int res = xhpcChargeOrderMapper.addXhpcChargeOrder(xhpcChargeOrder); logger.info("<<<<<<<<<<<<<<<<川逸充<<<<<<<<第三方启动订单号>>>>>>>>>>>>>>>>>:" + xhpcChargeOrder.getInternetSerialNumber()); - String connectorID = chargingStationMap.get("areaCode").toString(); - if(chargingStationId>999 && chargingStationId<=9999){ - connectorID =connectorID+chargingStationId.toString(); - }else if(chargingStationId>99 && chargingStationId<=999){ - connectorID =connectorID+"0"+chargingStationId.toString(); - }else if(chargingStationId>9 && chargingStationId<=99){ - connectorID =connectorID+"00"+chargingStationId.toString(); - }else { - connectorID =connectorID+"000"+chargingStationId.toString(); - } - connectorID=connectorID+serialNumber.substring(serialNumber.length()-2, serialNumber.length()); - - - String finalConnectorID = connectorID; executorService.execute(new Runnable() { @Override public void run() { @@ -1489,20 +1544,17 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar xhpcChargeOrder.setRateModelId(rateModelId); xhpcChargeOrderMapper.updateXhpcChargeOrder(xhpcChargeOrder); - System.out.println("===================finalConnectorID=========================="); - System.out.println("===================finalConnectorID=========================="+finalConnectorID); - System.out.println("===================finalConnectorID=========================="); - System.out.println("===================startTime=========================="); - System.out.println("===================startTime=========================="+DateUtil.format(date1,"yyyy-MM-dd HH:mm:ss")); - System.out.println("===================startTime=========================="); Map pushOrder = new HashMap<>(); - pushOrder.put("startChargeSeqStat", 1); + pushOrder.put("startChargeSeqStat", 2); pushOrder.put("internetSerialNumber", xhpcChargeOrder.getInternetSerialNumber()); - pushOrder.put("connectorID", finalConnectorID); + pushOrder.put("connectorID", serialNumber); pushOrder.put("startChargeNotificationStat", 0); pushOrder.put("chargeOrderInfoNotificationStat", 0); pushOrder.put("operatorId3rdpty", operatorIdEvcs); pushOrder.put("startTime", DateUtil.format(date1,"yyyy-MM-dd HH:mm:ss")); + pushOrder.put("phone", phone); + pushOrder.put("operatorId3rdptyName", "CYC"); + REDIS.setCacheMap("pushOrder:".concat(orderNo), pushOrder); String gun ="gun:"+serialNumber; @@ -1530,6 +1582,241 @@ public class XhpcChargeOrderServiceImpl extends BaseService implements IXhpcChar return r; } + @Override + @Transactional + public AjaxResult chargingCapacityStartUp(HttpServletRequest request, Long userId, String terminalSerialNumber, Integer type, Integer chargingCapacity) { + try{ + XhpcChargeOrder xhpcChargeOrder = new XhpcChargeOrder(); + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) { + String username = loginUser.getUsername(); + Integer userType = loginUser.getUserType(); + Long userid = loginUser.getUserid(); + if (chargingCapacity == null) { + return AjaxResult.error(1104, "请输入充电量"); + }else{ + if(chargingCapacity>=65535){ + return AjaxResult.error(1104, "输入充电量超出了限制"); + } + if(chargingCapacity<=0){ + return AjaxResult.error(1104, "输入充电量应该大于0"); + } + } + logger.info("<<<<<<<<<<<<<<<<<<<<<<<登录用户id>>>>>>>>>>>>>>>>>"+userid); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<桩号>>>>>>>>>>>>>>>>>"+terminalSerialNumber); + String openId = loginUser.getOpenId(); + String tenantId = loginUser.getTenantId(); + long l1 = System.currentTimeMillis(); + logger.info("<<<<<<<"+terminalSerialNumber+"开始启动充电获取用户时间>>>>>:"+l1); + R user = userTypeService.getUser(null, userid, userType, terminalSerialNumber,loginUser.getTenantId()); + long l2 = System.currentTimeMillis(); + logger.info("<<<<<<<"+terminalSerialNumber+"结束启动充电获取用户时间>>>>>:"+l2); + logger.info("<<<<<<<"+terminalSerialNumber+"启动充电时间差>>>>>:"+(l2-l1)); + if (!userid.equals(userId) || user == null || user.getData() == null) { + return AjaxResult.error(UserTypeUtil.LOGIN_TYPE, "请重新登录"); + } + Map userMessage = (Map)user.getData(); + if(UserTypeUtil.USER_TYPE !=userType){ + if(Integer.valueOf(userMessage.get("number").toString())==0){ + return AjaxResult.error(UserTypeUtil.LOGIN_TYPE, "此账号不能在该场站充电,请使用手机号登录"); + } + } + xhpcChargeOrder.setDriverId(userMessage.get("phone").toString()); + String pattern = "^([0-9]{16})"; + Pattern compile = Pattern.compile(pattern); + Matcher m = compile.matcher(terminalSerialNumber); + if (terminalSerialNumber.length() != 16 || !m.matches()) { + return AjaxResult.error(1104, "无效的终端编号"); + } + //终端信息 + XhpcTerminal xhpcTerminal = xhpcChargeOrderMapper.getXhpcTerminalSerialNumber(terminalSerialNumber,tenantId); + if (xhpcTerminal == null || xhpcTerminal.getTerminalId() == null || xhpcTerminal.getChargingPileId() == null || xhpcTerminal.getPileSerialNumber() == null) { + return AjaxResult.error(1104, "因限电该桩已停用,请选择其他桩进行充电"); + }else { + if(xhpcTerminal.getStatus()==1){ + if(xhpcTerminal.getPrompt() !=null){ + return AjaxResult.error(1104, xhpcTerminal.getPrompt()); + }else{ + return AjaxResult.error(1104, "桩已停用,请选择其他桩进行充电"); + } + } + } + //查看充电用户金额是否大于5元 + //Map userMessage = xhpcChargeOrderMapper.getUserMessage(userId); + BigDecimal a = new BigDecimal(5); + if (userMessage == null || userMessage.get("balance") == null || a.compareTo(new BigDecimal(userMessage.get("balance").toString())) == 1) { + return AjaxResult.error(1100, "金额小于5元,不能充电,请充值后再进行充电"); + } + //充电用户是否存在异常的订单 + int j = xhpcChargeOrderMapper.countXhpcChargeOrder(userId,userType,tenantId); + if (j > 0) { + return AjaxResult.error(1103, "你有异常订单未解决,请拨打客服电话进行解决"); + } + //查看充电用户是否有申请退款的订单,还未处理 + if (Integer.parseInt(userMessage.get("isRefundApplication").toString()) != 0) { + return AjaxResult.error(1101, "你有申请退款订单在审核中,需要充电请取消申请退款"); + } + //充电用户是否在充电中 + String i = xhpcChargeOrderMapper.countXhpcRealTimeOrder(userId,userType,tenantId); + if (!"".equals(i) && i!=null) { + return AjaxResult.error(1102, "车辆正在充电,请查询车辆充电信息"); + } + //终端状态是否空闲 + //是否插枪 + Map cacheMap = REDIS.getCacheMap("gun:" + terminalSerialNumber); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>"); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>" + terminalSerialNumber); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>" + cacheMap.toString()); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>"); + + if(cacheMap==null){ + return AjaxResult.error(1105, "未注册的终端,请选择其他终端充电"); + }else{ + if(cacheMap.get("status") ==null){ + return AjaxResult.error(1106, "未知的终端状态,请选择其他终端充电"); + }else{ + String status = cacheMap.get("status").toString(); + //不同的状态 + if("离线".equals(status)||"故障".equals(status) ||"充电".equals(status)){ + return AjaxResult.error(1107, "此终端"+status+"中,请选择其他终端充电"); + } + } + if(cacheMap.get("vehicleGunStatus") ==null){ + return AjaxResult.error(1108, "未知的枪状态,请选择其他终端充电"); + }else{ + String vehicleGunStatus = cacheMap.get("vehicleGunStatus").toString(); + if(!"是".equals(vehicleGunStatus)){ + return AjaxResult.error(1109, "请插好充电枪"); + } + } + } + logger.info("<<<<<<<<<<<<<<<<<<<<<<<<终端编号>>>>"+terminalSerialNumber+">>>>>>>>>>>>>"+tenantId); + + logger.info("<<<<<<<<<<<<<<<<<<<<<<<<终端编号>>>>>>>>>>>>>>>>"); + //余额 + String balance = new BigDecimal(userMessage.get("balance").toString()).multiply(new BigDecimal(100)).toString(); + //获取桩信息 + Map xhpcChargingPileById =xhpcChargeOrderMapper.getXhpcChargingPileById(xhpcTerminal.getChargingPileId(),tenantId); + //启动充电 + StartChargingData startChargingData = new StartChargingData(); + //订单流水号 终端号+年月日时分秒+自增4位 共32位 + String orderNo = genOrder(terminalSerialNumber); + + startChargingData.setOrderNo(orderNo); + if(userMessage.get("phone") !=null){ + startChargingData.setTel(userMessage.get("phone").toString()); + xhpcChargeOrder.setDriverId(userMessage.get("phone").toString()); + } + startChargingData.setPileNo(xhpcTerminal.getPileSerialNumber()); + startChargingData.setGunId(xhpcTerminal.getSerialNumber().substring(14)); + startChargingData.setBalance(Double.valueOf(balance).intValue()); + if(xhpcChargingPileById.get("communicationProtocolVersion")!=null && !"".equals(xhpcChargingPileById.get("communicationProtocolVersion").toString())){ + startChargingData.setVersion(xhpcChargingPileById.get("communicationProtocolVersion").toString()); + }else{ + startChargingData.setVersion("0A"); + } + //用户、桩、平台(最小的) + int number =0; + if(!"".equals(userMessage.get("socUser")) && userMessage.get("socUser") !=null && userMessage.get("socProtect") !=null && !"0".equals(userMessage.get("socProtect").toString())){ + number =Integer.parseInt(userMessage.get("socUser").toString()); + logger.info("=========用户、桩、平台(最小的)===number==="+number); + } + //平台 + String soc = redisService.getCacheObject("global:"+tenantId+":SOC"); + logger.info("=========用户、桩、平台(最小的)===soc==="+soc); + if(!"".equals(soc) && soc!=null){ + if(number!=0){ + if(Integer.parseInt(soc)-number<0){ + number=Integer.parseInt(soc); + logger.info("=========用户、桩、平台(最小的)1===number==="+number); + } + }else{ + number=Integer.parseInt(soc); + logger.info("=========用户、桩、平台(最小的)2===number==="+number); + } + } + Map operatorMessage = xhpcChargeOrderMapper.getOperatorMessage(xhpcTerminal.getChargingStationId()); + if(operatorMessage !=null && operatorMessage.get("soc") !=null && !"".equals(operatorMessage.get("soc"))){ + if(number!=0){ + if(Integer.parseInt(operatorMessage.get("soc").toString())-number<0){ + number=Integer.parseInt(operatorMessage.get("soc").toString()); + logger.info("=========用户、桩、平台(最小的)3===number==="+number); + } + }else{ + number=Integer.parseInt(operatorMessage.get("soc").toString()); + logger.info("=========用户、桩、平台(最小的)4===number==="+number); + } + } + if(number !=0){ + startChargingData.setSoc(number); + } + logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:"+number); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:"+startChargingData.getSoc()); + //创建充电订单(充电启动soc初始值,结束是获取,并修改状态) + + xhpcChargeOrder.setChargingStationId(xhpcTerminal.getChargingStationId()); + xhpcChargeOrder.setUserId(userId); + xhpcChargeOrder.setTerminalId(xhpcTerminal.getTerminalId()); + xhpcChargeOrder.setGunId(xhpcTerminal.getSerialNumber()); + xhpcChargeOrder.setSerialNumber(orderNo); + xhpcChargeOrder.setSource(userType); + xhpcChargeOrder.setStatus(-1); + xhpcChargeOrder.setTenantId(tenantId); + xhpcChargeOrder.setChargingCapacity(chargingCapacity); + startChargingData.setChargingCapacity(chargingCapacity); + if (xhpcChargingPileById != null && xhpcChargingPileById.get("power") != null) { + xhpcChargeOrder.setPower(xhpcChargingPileById.get("power").toString()); + } + if (type == 1) { + xhpcChargeOrder.setChargingMode("微信"); + } else if (type == 2){ + xhpcChargeOrder.setChargingMode("支付宝"); + }else{ + xhpcChargeOrder.setChargingMode("App"); + } + xhpcChargeOrder.setCreateTime(Calendar.getInstance().getTime()); + xhpcChargeOrder.setType("91"); + + //获取车牌 + Map xhpcUserVehicleMessage = xhpcChargeOrderMapper.getXhpcUserVehicleMessage(xhpcChargeOrder.getUserId(), xhpcChargeOrder.getSource()); + if(xhpcUserVehicleMessage !=null && xhpcUserVehicleMessage.get("vehicleName") !=null){ + xhpcChargeOrder.setPlateNum(xhpcUserVehicleMessage.get("vehicleName").toString()); + } + xhpcChargeOrderMapper.addXhpcChargeOrder(xhpcChargeOrder); + + executorService.execute(new Runnable() { + @Override + public void run() { + R r1 = powerPileService.startChargingCapacity(startChargingData); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<<充电返回>>>>>>>>>>>>>>>>>"); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<<" + r1.getCode() + ">>>>>>>>>>>>>>>>>"); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<<" + r1.getMsg() + ">>>>>>>>>>>>>>>>>"); + logger.info("<<<<<<<<<<<<<<<<<<<<<<<<" + r1.getData() + ">>>>>>>>>>>>>>>>>"); + if(r1.getCode() == 200){ + try{ + xhpcChargeOrder.setRateModelId(Long.valueOf(r1.getData().toString())); + xhpcChargeOrderMapper.updateXhpcChargeOrder(xhpcChargeOrder); + //插一帧实时数据 + extracted(xhpcChargeOrder); + }catch (Exception e){ + e.printStackTrace(); + logger.error("update order[{}] failed.", orderNo); + } + } + } + }); + logger.info("<<<<<<<<<1111<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:" + orderNo+"用户id:"+userId); + logger.info("<<<<<<<<<2222<<<<<<<<<<<<<<>>>>>>>>>>>>>>>>:" + orderNo+"用户id:"+userId); + return AjaxResult.success(); + }else{ + return AjaxResult.error(UserTypeUtil.LOGIN_TYPE, "请重新登录"); + } + }catch (Exception e){ + e.printStackTrace(); + } + return AjaxResult.error(UserTypeUtil.LOGIN_TYPE, "请确认设备网络状况正常和枪正确插好后重新尝试"); + } + public static void main(String[] args) { try{ // //String alipayPublicKey1 = getAlipayPublicKey("C:\\Users\\Administrator\\Downloads\\alipayCertPublicKey_RSA2.crt"); diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcHistoryOrderServiceImpl.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcHistoryOrderServiceImpl.java index 4fa57ed8..9985e2eb 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcHistoryOrderServiceImpl.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcHistoryOrderServiceImpl.java @@ -129,10 +129,11 @@ public class XhpcHistoryOrderServiceImpl extends BaseService implements IXhpcHis SM.put("88", "接收 BMS 充电统计报文超时(0X88)"); SM.put("89", "接收对侧 CCS 报文超时(0X89)"); SM.put("90", "未知原因中止(0X90)"); - SM.put("91", "远程重启应答(0X91)"); + SM.put("91", "平台结算(0X91)"); SM.put("92", "远程重启(0X92)"); SM.put("93", "远程更新应答(0X93)"); SM.put("94", "远程更新(0X94)"); + SM.put("199", "平台空订单(0X199)"); } @@ -289,6 +290,11 @@ public class XhpcHistoryOrderServiceImpl extends BaseService implements IXhpcHis return xhpcHistoryOrderMapper.updateXhpcHistoryOrderSerialNumber(xhpcHistoryOrder); } + @Override + public int updateXhpcHistoryOrderParkingVoucher(XhpcHistoryOrder xhpcHistoryOrder) { + return xhpcHistoryOrderMapper.updateXhpcHistoryOrderParkingVoucher(xhpcHistoryOrder); + } + @Override public List> getListPage(String tenantId,Long chargingStationId,Long chargingPileId,Long terminalId, String phone, String transactionNumber, Integer status, String chargingStationName, Long operatorId, Integer source, String beginStartTime, String beginEndTime, Long userId, Integer type,String affiliationOrganization,String evcsOrderNo,String plateNum,Integer internetId,String internetSerialNumber,String terminalName,String vinCode,String overStartTime,String overEndTime,Long personnelId,Integer confirmResult) { @@ -531,7 +537,7 @@ public class XhpcHistoryOrderServiceImpl extends BaseService implements IXhpcHis if(map.get("startTime")!=null && map.get("endTime")!=null){ xhpcRealTimeOrderService.getExamine(chargeOrderId,powerPriceTotal,servicePriceTotal,chargingDegree,map.get("startTime").toString(),map.get("endTime").toString()); }else{ - xhpcRealTimeOrderService.getExamine(chargeOrderId,powerPriceTotal,servicePriceTotal,chargingDegree,null,null); + xhpcRealTimeOrderService.getExamine(chargeOrderId,powerPriceTotal,servicePriceTotal,chargingDegree,map.get("createTime").toString(),map.get("createTime").toString()); } } } diff --git a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcRealTimeOrderServiceImpl.java b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcRealTimeOrderServiceImpl.java index dd0d4c78..cff62b68 100644 --- a/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcRealTimeOrderServiceImpl.java +++ b/xhpc-modules/xhpc-order/src/main/java/com/xhpc/order/service/impl/XhpcRealTimeOrderServiceImpl.java @@ -231,6 +231,7 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe Map message = xhpcRealTimeOrderMapper.getMessageChargeOrderId(chargeOrderId); message.put("powerPriceTotal",0); message.put("servicePriceTotal",0); + message.put("chargingDegree",0); return message; } //基本信息 @@ -1242,12 +1243,6 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe String openid =""; String refundType =""; if(!UserTypeUtil.INTERNET_TYPE.equals(source)){ - xhpcHistoryOrder.setUserNameEvcs(userMessage.get("phone").toString()); - if(UserTypeUtil.USER_TYPE.equals(source)){ - xhpcHistoryOrder.setPhone(userMessage.get("phone").toString()); - }else{ - xhpcHistoryOrder.setPhone(userMessage.get("account").toString()); - } //增加流水订单号 if(operatorMessage!=null && operatorMessage.get("operatorId")!=null){ String evcs = EvcsUtil.transferInternetOrderNo(xhpcChargeOrder.getSerialNumber(), operatorMessage.get("operatorId").toString()); @@ -1256,6 +1251,9 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe //扣除用户实际消费金额,添加消费记录 剩余的钱 BigDecimal balance1 =new BigDecimal(userMessage.get("balance").toString()); subtract = balance1.subtract(actPrice); + + logger.info("<<<<<<<<<<<<<<<<原本金额>>>>>>>>balance1>>>>>>>>>"+balance1.toString()); + logger.info("<<<<<<<<<<<<<<<<剩余金额>>>>>>>>subtract>>>>>>>>>"+subtract.toString()); int i = xhpcChargeOrderService.updateUserBalance(userId, subtract,xhpcChargeOrder.getSource(),xhpcChargeOrder.getTenantId()); if(i==0){ //扣钱失败 @@ -1263,6 +1261,11 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return R.fail(); }else{ + if(UserTypeUtil.USER_TYPE.equals(source)){ + Map userMessage1 = xhpcChargeOrderService.getUserMessage(userId); + logger.info("<<<<<<<<<<<<<<<<扣钱成功>>>>>>userMessage1>>>>>"+userMessage1.toString()); + } + logger.info("<<<<<<<<<<<<<<<<扣钱成功>>>>>>>>>>用户金额>>>>>>>"+balance1 +">>>>>>>>>>扣款金额>>>>>>>>>>"+actPrice+">>>>>>>>>>>>>剩余金额>>>>>>>>>>>>>>>>"+subtract+">>>>订单号>>>>>>>"+xhpcHistoryOrder.getSerialNumber()); //添加流水 xhpcChargeOrderService.addUserAccountStatement(userId, actPrice.negate(), subtract, xhpcChargeOrder.getChargeOrderId(), 3, date,xhpcChargeOrder.getSource()); map.put("userId",userId); @@ -1277,9 +1280,6 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe map.put("remark","充电结算自动申请退款"); } }else if(UserTypeUtil.INTERNET_TYPE.equals(source) && xhpcChargeOrder.getUserId()>10000){ - - xhpcHistoryOrder.setUserNameEvcs(userMessage.get("phone").toString()); - xhpcHistoryOrder.setPhone(userMessage.get("phone").toString()); //增加流水订单号 if(operatorMessage!=null && operatorMessage.get("operatorId")!=null){ String evcs = EvcsUtil.transferInternetOrderNo(xhpcChargeOrder.getSerialNumber(), operatorMessage.get("operatorId").toString()); @@ -1295,6 +1295,7 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); return R.fail(); }else{ + logger.info("<<<<<<<<<<<<<<<<扣钱成功>>>>>>>>>>用户金额>>>>>>>"+balance1 +">>>>>>>>>>扣款金额>>>>>>>>>>"+actPrice+">>>>>>>>>>>>>剩余金额>>>>>>>>>>>>>>>>"+subtract+">>>>订单号>>>>>>>"+xhpcHistoryOrder.getSerialNumber()); //添加流水 xhpcChargeOrderService.addUserAccountStatement(userId, actPrice.negate(), subtract, xhpcChargeOrder.getChargeOrderId(), 3, date,xhpcChargeOrder.getSource()); map.put("userId",userId); @@ -1305,6 +1306,10 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe map.put("remark","充电结算自动申请退款"); } } + xhpcHistoryOrder.setUserNameEvcs(xhpcChargeOrder.getDriverId()); + xhpcHistoryOrder.setPhone(xhpcChargeOrder.getDriverId()); + logger.info("<<<<<<<<<<<<<<<<订单结束异步之前>>>>>getUserNameEvcs>>>>>>>>>>>>"+xhpcHistoryOrder.getUserNameEvcs()); + logger.info("<<<<<<<<<<<<<<<<订单结束异步之前>>>>>getPhone>>>>>>>>>>>>"+xhpcHistoryOrder.getPhone()); int number = xhpcHistoryOrderService.updateXhpcHistoryOrderSerialNumber(xhpcHistoryOrder); if(number==0){ @@ -1408,49 +1413,61 @@ public class XhpcRealTimeOrderServiceImpl extends BaseService implements IXhpcRe logger.info("<<<<<<<<<11<<<<<<<川逸充,调用订单结束推送>>>>>>>>>>>>>>>>>"); Map orderMap =new HashMap<>(); orderMap.put("orderNo",xhpcHistoryOrder.getSerialNumber()); + orderMap.put("OperatorID","MA6CC2LK7"); + orderMap.put("elecMoney",xhpcHistoryOrder.getPowerPriceTotal()); + orderMap.put("seviceMoney",xhpcHistoryOrder.getServicePriceTotal()); + orderMap.put("totalMoney",xhpcHistoryOrder.getTotalPower()); + evcsService.getCYCNotificationConnectorChargeStatus(orderMap); - logger.info("<<<<<<<<<22<<<<<<<川逸充,调用订单结束推送>>>>>>>>>>>>>>>>>"); + logger.info("<<<<<<<<<22<<<<<<<川逸充,调用订单结束推送>>>>>>>>>>>>>orderMap>>>>"+orderMap.toString()); } } }); //小华充电二台子社区充电站 道闸 -// try{ -// if(xhpcChargeOrder.getPlateNum() !=null && !"".equals(xhpcChargeOrder.getPlateNum())){ -// Map xhpcBarrierGate = xhpcChargeOrderService.getXhpcBarrierGate(xhpcChargeOrder.getChargingStationId()); -// if(xhpcBarrierGate !=null && xhpcBarrierGate.get("url") !=null && xhpcBarrierGate.get("chargingStationNumber") !=null){ -// Map barrierGateMap = new HashMap<>(); -// barrierGateMap.put("plateNo", xhpcChargeOrder.getPlateNum()); -// barrierGateMap.put("chargingStationNumber", xhpcBarrierGate.get("chargingStationNumber").toString()); -// barrierGateMap.put("chargingStationName", xhpcBarrierGate.get("name").toString()); -// barrierGateMap.put("address", xhpcBarrierGate.get("address").toString()); -// barrierGateMap.put("longitude", xhpcBarrierGate.get("longitude").toString()); -// barrierGateMap.put("latitude", xhpcBarrierGate.get("latitude").toString()); -// barrierGateMap.put("startTime", xhpcHistoryOrder.getStartTime()); -// barrierGateMap.put("endTime", xhpcHistoryOrder.getEndTime()); -// JSONObject json = new JSONObject(barrierGateMap); -// String result = HttpUtils.post(xhpcBarrierGate.get("url").toString(), json); -// JSONObject jsonObject = JSON.parseObject(result); -// String code = jsonObject.getString("code"); -// XhpcBarrierGateRecord xhpcBarrierGateRecord = new XhpcBarrierGateRecord(); -// if("200".equals(code)){ -// xhpcBarrierGateRecord.setStatus(0); -// }else{ -// xhpcBarrierGateRecord.setStatus(1); -// } -// xhpcBarrierGateRecord.setBarrierGateId(Long.parseLong(xhpcBarrierGate.get("barrierGateId").toString())); -// xhpcBarrierGateRecord.setUserId(userId); -// xhpcBarrierGateRecord.setSource(source); -// xhpcBarrierGateRecord.setChargingStationId(xhpcChargeOrder.getChargingStationId()); -// xhpcBarrierGateRecord.setSendingTime(new Date()); -// xhpcBarrierGateRecord.setDelFlag(0); -// xhpcBarrierGateRecord.setRemark(result); -// xhpcRealTimeOrderMapper.insertXhpcBarrierGateRecord(xhpcBarrierGateRecord); -// } -// -// } -// }catch (Exception e){ -// e.printStackTrace(); -// } + try{ + if(xhpcChargeOrder.getPlateNum() !=null && !"".equals(xhpcChargeOrder.getPlateNum())){ + Map xhpcBarrierGate = xhpcChargeOrderService.getXhpcBarrierGate(xhpcChargeOrder.getChargingStationId()); + if(xhpcBarrierGate !=null && xhpcBarrierGate.get("url") !=null && xhpcBarrierGate.get("chargingStationNumber") !=null){ + Map barrierGateMap = new HashMap<>(); + barrierGateMap.put("plateNo", xhpcChargeOrder.getPlateNum()); + barrierGateMap.put("chargingStationNumber", xhpcBarrierGate.get("chargingStationNumber").toString()); + barrierGateMap.put("chargingStationName", xhpcBarrierGate.get("name").toString()); + barrierGateMap.put("address", xhpcBarrierGate.get("address").toString()); + barrierGateMap.put("longitude", xhpcBarrierGate.get("longitude").toString()); + barrierGateMap.put("latitude", xhpcBarrierGate.get("latitude").toString()); + barrierGateMap.put("startTime", xhpcHistoryOrder.getStartTime()); + barrierGateMap.put("endTime", xhpcHistoryOrder.getEndTime()); + JSONObject json = new JSONObject(barrierGateMap); + String result = HttpUtils.post(xhpcBarrierGate.get("url").toString(), json); + JSONObject jsonObject = JSON.parseObject(result); + String code = jsonObject.getString("ret"); + XhpcBarrierGateRecord xhpcBarrierGateRecord = new XhpcBarrierGateRecord(); + if("200".equals(code)){ + xhpcBarrierGateRecord.setStatus(0); + }else{ + xhpcBarrierGateRecord.setStatus(1); + } + xhpcBarrierGateRecord.setBarrierGateId(Long.parseLong(xhpcBarrierGate.get("barrierGateId").toString())); + xhpcBarrierGateRecord.setUserId(userId); + xhpcBarrierGateRecord.setSource(source); + xhpcBarrierGateRecord.setChargingStationId(xhpcChargeOrder.getChargingStationId()); + xhpcBarrierGateRecord.setSendingTime(new Date()); + xhpcBarrierGateRecord.setDelFlag(0); + xhpcBarrierGateRecord.setRemark(result); + xhpcBarrierGateRecord.setSerialNumber(xhpcChargeOrder.getSerialNumber()); + xhpcBarrierGateRecord.setInternetSerialNumber(xhpcChargeOrder.getInternetSerialNumber()); + xhpcBarrierGateRecord.setPlateNum(xhpcChargeOrder.getPlateNum()); + xhpcBarrierGateRecord.setPhone(xhpcHistoryOrder.getPhone()); + xhpcBarrierGateRecord.setHistoryOrderId(xhpcHistoryOrder.getHistoryOrderId()); + xhpcRealTimeOrderMapper.insertXhpcBarrierGateRecord(xhpcBarrierGateRecord); + xhpcHistoryOrder.setParkingVoucher(2); + xhpcHistoryOrderService.updateXhpcHistoryOrderParkingVoucher(xhpcHistoryOrder); + } + + } + }catch (Exception e){ + e.printStackTrace(); + } }catch (Exception e){ e.printStackTrace(); logger.info("<<<<<<<<<<<<<<<<运行异常,结算失败,数据回滚>>>>>>>>>>>>>>>>>"+xhpcChargeOrder.getSerialNumber()); diff --git a/xhpc-modules/xhpc-order/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-order/src/main/resources/bootstrap.yml index 70e117f3..8fd67a26 100644 --- a/xhpc-modules/xhpc-order/src/main/resources/bootstrap.yml +++ b/xhpc-modules/xhpc-order/src/main/resources/bootstrap.yml @@ -14,10 +14,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置 diff --git a/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcChargeOrderMapper.xml b/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcChargeOrderMapper.xml index c1f6e325..dd01d7ed 100644 --- a/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcChargeOrderMapper.xml +++ b/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcChargeOrderMapper.xml @@ -33,7 +33,7 @@ - + @@ -72,19 +72,33 @@ - select - count(charge_order_id) + charge_order_id as chargeOrderId, + status from xhpc_charge_order where user_id = #{userId} - and status=0 and del_flag =0 + and internet_serial_number=#{thirdCode} and tenant_id=#{tenantId} and source =#{userType} + + select xco.charge_order_id as chargeOrderId, - max(xrt.real_time_order_id) as realTimeOrderId + (select max(real_time_order_id) from xhpc_real_time_order where charging_order_id = xco.charge_order_id LIMIT 1) realTimeOrderId from xhpc_charge_order as xco - left join xhpc_real_time_order as xrt on xrt.charging_order_id = xco.charge_order_id where xco.del_flag = 0 and xco.status = #{status} - and datediff(now(), xco.create_time) > 1 + and NOW() > DATE_ADD(xco.create_time, INTERVAL #{number} HOUR) @@ -746,6 +765,16 @@ select count(charge_order_id) from xhpc_charge_order where serial_number like concat('%', #{serialNumber}, '%') and charge_order_id > #{chargeOrderId} and status=1 + + update xhpc_charge_order set status=2 where status is null and create_time < NOW() - INTERVAL 30 MINUTE + + + + update xhpc_charge_order set status=2 where status=-1 and source=1 and create_time < NOW() - INTERVAL 30 MINUTE + + + + diff --git a/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcHistoryOrderMapper.xml b/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcHistoryOrderMapper.xml index e8acb08b..6d263a61 100644 --- a/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcHistoryOrderMapper.xml +++ b/xhpc-modules/xhpc-order/src/main/resources/mapper/XhpcHistoryOrderMapper.xml @@ -59,6 +59,7 @@ + history_order_id, charging_station_id, charge_order_id, user_id, terminal_id, serial_number, @@ -915,7 +916,10 @@ te.name as terminalName, ho.act_price as actPrice, ho.total_power as chargingDegree, - co.charging_time as chargingTime + co.charging_time as chargingTime, + case when ho.parking_voucher=1 then '否' + else '是' + end as 'barrierGateRecordName' FROM xhpc_history_order as ho LEFT JOIN xhpc_charging_station as cs on cs.charging_station_id = ho.charging_station_id LEFT JOIN xhpc_terminal as te on te.terminal_id = ho.terminal_id @@ -954,7 +958,10 @@ ho.internet_serial_number as internetSerialNumber, te.serial_number as terminalSerialNumber, co.Plate_num as plateNum, - ho.stop_reason_evcs as typeName + ho.stop_reason_evcs as typeName, + case when ho.parking_voucher=2 then '是' + else '否' + end as 'barrierGateRecordName' FROM xhpc_history_order as ho LEFT JOIN xhpc_charging_station as cs on cs.charging_station_id = ho.charging_station_id LEFT JOIN xhpc_terminal as te on te.terminal_id = ho.terminal_id @@ -1007,7 +1014,7 @@ co.source as source, co.Plate_num as plateNum, dispute_order_status as disputeOrderStatus, - inu.phone as internetUserPhone, + co.driver_id as internetUserPhone, inu.name as internetName, apu.phone as appUserPhone, ho.power_price_total as powerPriceTotal, @@ -1034,6 +1041,9 @@ when co.source=2 then "社区用户" else "B端客户!" end sourceName, + case when ho.parking_voucher=1 then '否' + else '是' + end as 'barrierGateRecordName', case when ho.charging_mode="1" then "快电" when ho.charging_mode="2" then "恒大" when ho.charging_mode="3" then "新电途" @@ -1055,9 +1065,7 @@ left join xhpc_customers_personnel as cup on cup.customers_personnel_id = ho.user_id and ho.internet_serial_number is null and ho.source=3 inner join ( - select hio.history_order_id as history_order_id from xhpc_history_order as hio INNER JOIN xhpc_app_user as xau on xau.app_user_id = hio.user_id where hio.source=0 and xau.phone LIKE concat('%',#{phone}, '%') - union - select hio.history_order_id as history_order_id from xhpc_history_order as hio INNER JOIN xhpc_internet_user as xiu on xiu.internet_user_id = hio.user_id where hio.source=1 and xiu.phone LIKE concat('%',#{phone}, '%') + select hio.history_order_id as history_order_id from xhpc_history_order as hio INNER JOIN xhpc_app_user as xau on xau.app_user_id = hio.user_id where xau.phone LIKE concat('%',#{phone}, '%') union select hio.history_order_id as history_order_id from xhpc_history_order as hio INNER JOIN xhpc_community_personnel as xcp on xcp.community_personnel_id = hio.user_id where hio.source=2 and xcp.account LIKE concat('%',#{phone}, '%') union @@ -1239,7 +1247,7 @@ end sanDisputeReason, ed.check_order_seq as sanCheckOrderSeq, (SELECT phone FROM xhpc_app_user where app_user_id = co.user_id and ho.source=0) as appUserPhone, - (SELECT phone from xhpc_internet_user where internet_user_id = co.user_id and ho.source=1) as internetUserPhone, + co.driver_id as internetUserPhone, (SELECT account from xhpc_community_personnel where community_personnel_id = co.user_id and ho.source=2) as communityAccount, (SELECT account from xhpc_customers_personnel where customers_personnel_id = co.user_id and ho.source=3) as customersAccount, co.Plate_num as plateNum, @@ -1606,10 +1614,17 @@ phone = #{phone}, + + parking_voucher = #{parkingVoucher}, + where internet_serial_number = #{internetSerialNumber} + + + UPDATE xhpc_history_order set parking_voucher = 2 where history_order_id = #{historyOrderId} + + + update from xhpc_charging_pile set power_number=#{powerNumber} where serial_number =#{serialNumber} + diff --git a/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml b/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml index b2414a07..5b029f3a 100644 --- a/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml +++ b/xhpc-modules/xhpc-power-pile/src/main/resources/svcmainlogic.xml @@ -30,6 +30,7 @@ + diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java index 6d827f68..85ff9122 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/controller/XhpcAppUserController.java @@ -144,6 +144,25 @@ public class XhpcAppUserController extends BaseController { return iXhpcAppUserUserService.login(map); } + /** + * app用户登录 + */ + @ApiOperation("app用户登录") + @PostMapping("/appUserLogin") + public R appUserLogin(@RequestBody Map map) { + return iXhpcAppUserUserService.appUserLogin(map); + } + + /** + * APP用户注册 + * @param map + * @return + */ + @ApiOperation("APP用户注册") + @PostMapping("/apprRegister") + public R apprRegister(@RequestBody Map map) { + return iXhpcAppUserUserService.apprRegister(map); + } /** * C端用户授权登录 @@ -172,6 +191,15 @@ public class XhpcAppUserController extends BaseController { return iXhpcAppUserUserService.loginOut(request, type); } + /** + * app用户退出 + */ + @ApiOperation("app用户退出") + @GetMapping("/appLoginOut") + public R appLoginOut(HttpServletRequest request) { + return iXhpcAppUserUserService.appLoginOut(request); + } + /** * C端用户自动登录 */ @@ -181,6 +209,15 @@ public class XhpcAppUserController extends BaseController { return iXhpcAppUserUserService.voluntaryLogin(map); } + /** + * app用户自动登录 + */ + @ApiOperation("app用户自动登录") + @PostMapping("/appVoluntaryLogin") + public R appVoluntaryLogin(@RequestBody Map map) { + return iXhpcAppUserUserService.appVoluntaryLogin(map); + } + /* * TODO 获取微信权限标识 openid ,session_key,unionid * @author fjd diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppInternetUserMapper.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppInternetUserMapper.java index a8534378..f3afd22c 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppInternetUserMapper.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppInternetUserMapper.java @@ -31,4 +31,6 @@ public interface XhpcAppInternetUserMapper { int getXhpcTerminal(@Param("deviceCode") String deviceCode); + Map getXhpcChargeOrder(@Param("internetSerialNumber")String internetSerialNumber); + } diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppUserMapper.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppUserMapper.java index f5121119..ed9cf5d7 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppUserMapper.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/mapper/XhpcAppUserMapper.java @@ -67,6 +67,24 @@ public interface XhpcAppUserMapper { */ public XhpcAppUser getAppUserByPhone(@Param("phone") String phone,@Param("tenantId") String tenantId); + + /** + * 账号+密码查询用户信息 + * + * @param phone 手机号 + * @return 结果 + */ + public XhpcAppUser getAppUserPhoneByPassword(@Param("phone") String phone,@Param("password") String password,@Param("tenantId") String tenantId); + + /** + * 账号+用户ID查询用户信息 + * + * @param phone 手机号 + * @return 结果 + */ + public XhpcAppUser getAppUserPhoneByUserId(@Param("phone") String phone,@Param("userId") Long userId,@Param("tenantId") String tenantId); + + /** * openid查询C端用户信息 * @@ -102,6 +120,9 @@ public interface XhpcAppUserMapper { */ Map getUserLoginTime(@Param("type")Integer type,@Param("openid")String openid,@Param("tenantId")String tenantId); + Map getAppUserLoginTime(@Param("type")Integer type,@Param("userId")Long userId,@Param("phone")String phone,@Param("tenantId")String tenantId); + + /** * 修改该账号之前的登录信息,进行退出操作 * @param account diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/IXhpcAppUserUserService.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/IXhpcAppUserUserService.java index a04ecf29..373d4e03 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/IXhpcAppUserUserService.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/IXhpcAppUserUserService.java @@ -66,6 +66,23 @@ public interface IXhpcAppUserUserService { */ public R login(Map map); + /** + * C端用户登录 + * + * @param map C端用户 phone 手机号 code 验证码 type 登录方式1微信2小程序 + * @return 结果 + */ + public R appUserLogin(Map map); + + /** + * APP用户注册 + * + * @param map C端用户 phone 手机号 code 验证码 type 登录方式1微信2小程序 + * @return 结果 + */ + public R apprRegister(Map map); + + public R loginPhone(Map map); /** @@ -77,6 +94,13 @@ public interface IXhpcAppUserUserService { */ public R loginOut(HttpServletRequest request, String type); + /** + * 小程序用户退出 + * + * @param request + * @return + */ + public R appLoginOut(HttpServletRequest request); /** * C端用户自动登录 * @@ -85,6 +109,13 @@ public interface IXhpcAppUserUserService { */ public R voluntaryLogin(Map map); + /** + * app用户自动登录 + * + * @param map + * @return + */ + public R appVoluntaryLogin(Map map); /** * 小程序用户详情 * diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppInternetUserServiceImpl.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppInternetUserServiceImpl.java index 4d23e584..8ceb9467 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppInternetUserServiceImpl.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppInternetUserServiceImpl.java @@ -80,6 +80,24 @@ public class XhpcAppInternetUserServiceImpl extends BaseService implements IXhpc Map userToken = tokenService.createToken(userInfo); userToken.put("phone",mobile); + + //判断该订单号是否已充电完成、充电中、没有充电订单 + Map xhpcChargeOrder = xhpcAppInternetUserMapper.getXhpcChargeOrder(thirdCode); + if(xhpcChargeOrder==null){ + userToken.put("orderStatus","-1"); + }else{ + if("-1".equals(xhpcChargeOrder.get("status").toString())){ + userToken.put("orderStatus","-1"); + }else if("0".equals(xhpcChargeOrder.get("status").toString())){ + userToken.put("orderStatus","0"); + }else if("1".equals(xhpcChargeOrder.get("status").toString()) ||"3".equals(xhpcChargeOrder.get("status").toString())){ + userToken.put("orderStatus","1"); + }else if("2".equals(xhpcChargeOrder.get("status").toString())){ + userToken.put("orderStatus","2"); + }{ + userToken.put("orderStatus","-1"); + } + } return R.ok(userToken); } } diff --git a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppUserServiceImpl.java b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppUserServiceImpl.java index 98584b65..48298bd3 100644 --- a/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppUserServiceImpl.java +++ b/xhpc-modules/xhpc-user/src/main/java/com/xhpc/user/service/impl/XhpcAppUserServiceImpl.java @@ -235,6 +235,132 @@ public class XhpcAppUserServiceImpl extends BaseService implements IXhpcAppUserU return appLogin(phone, type, openid, tenantId); } + @Override + public R appUserLogin(Map map) { + + String phone = StringUtils.valueOf(map.get("phone")); + String password = StringUtils.valueOf(map.get("password")); + String tenantId = StringUtils.valueOf(map.get("tenantId")); + + if (StringUtils.isAnyBlank(phone)) { + return R.fail(HttpStatus.NOT_NULL, "账号必须填写"); + } + if (StringUtils.isAnyBlank(password)) { + return R.fail(HttpStatus.NOT_NULL, "密码必须填写"); + } + if (StringUtils.isAnyBlank(tenantId)) { + return R.fail(HttpStatus.NOT_NULL, "租户必须填写"); + } + + if (phone.length() < UserConstants.USERNAME_MIN_LENGTH + || phone.length() > UserConstants.USERNAME_MAX_LENGTH) { + return R.fail(HttpStatus.ERROR_STATUS, "用户名不在指定范围"); + } + + XhpcAppUser user =new XhpcAppUser(); + if("18123374652".equals(phone) && "123456".equals(password)){ + phone ="18123374652"; + password="123456"; + } + user = xhpcAppUserMapper.getAppUserPhoneByPassword(phone,null,tenantId); + if (StringUtils.isNull(user)) { + return R.fail(HttpStatus.DATA_ERROR, "账号和密码错误请重新登录"); + }else{ + boolean b = SecurityUtils.matchesPassword(password, user.getPassword()); + if(!b){ + return R.fail(HttpStatus.DATA_ERROR, "账号和密码错误请重新登录"); + } + } + LoginUser userInfo = new LoginUser(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(user.getPhone()); + sysUser.setUserId(user.getAppUserId()); + userInfo.setSysUser(sysUser); + userInfo.setUserType(UserTypeUtil.USER_TYPE); + userInfo.setUsername(phone); + userInfo.setUserid(user.getAppUserId()); + userInfo.setTenantId(tenantId); + userInfo.setUserTypeUtil(UserTypeUtil.USER); + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { + return R.fail(HttpStatus.DATA_ERROR, "对不起,您的账号:" + phone + " 已被删除"); + } + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + return R.fail(HttpStatus.DATA_ERROR, "对不起,您的账号:" + phone + " 已停用"); + } + redisService.deleteObject("pvToken:" + user.getPhone()); + //去退出账号之前登录的信息 + xhpcAppUserMapper.updateUserLoginTime(phone); + //添加最后一次登录数据 + xhpcAppUserMapper.addUserLoginTime(user.getAppUserId(),phone,userInfo.getUserType(),null,3,UserConstants.LOGIN,tenantId,new Date()); + // 获取登录token + Map token = tokenService.createToken(userInfo); + token.put("phone",phone); + return R.ok(token); + + } + + @Override + public R apprRegister(Map map) { + String phone = StringUtils.valueOf(map.get("phone")); + String password = StringUtils.valueOf(map.get("password")); + String confirmPassword = StringUtils.valueOf(map.get("confirmPassword")); + String tenantId = StringUtils.valueOf(map.get("tenantId")); + if (StringUtils.isAnyBlank(phone)) { + return R.fail(HttpStatus.NOT_NULL, "账号必须填写"); + } + if (StringUtils.isAnyBlank(password)) { + return R.fail(HttpStatus.NOT_NULL, "密码必须填写"); + } + if (StringUtils.isAnyBlank(confirmPassword)) { + return R.fail(HttpStatus.NOT_NULL, "确认密码必须填写"); + } + if (StringUtils.isAnyBlank(tenantId)) { + return R.fail(HttpStatus.NOT_NULL, "租户必须填写"); + } + if (phone.length() < UserConstants.USERNAME_MIN_LENGTH + || phone.length() > UserConstants.USERNAME_MAX_LENGTH) { + return R.fail(HttpStatus.ERROR_STATUS, "用户名不在指定范围"); + } + if (password.length() < UserConstants.USERNAME_MIN_LENGTH + || password.length() > UserConstants.USERNAME_MAX_LENGTH) { + return R.fail(HttpStatus.ERROR_STATUS, "密码不在指定范围"); + } + if(!password.equals(confirmPassword)){ + return R.fail(HttpStatus.NOT_NULL, "密码和确认密码不一致,请重新输入"); + } + XhpcAppUser user = xhpcAppUserMapper.getAppUserPhoneByPassword(phone,null,tenantId); + if (!StringUtils.isNull(user)) { + return R.fail(HttpStatus.DATA_ERROR, "该账号已存在请登录"); + } + + XhpcAppUser xhpcAppUser = new XhpcAppUser(); + xhpcAppUser.setPhone(phone); + xhpcAppUser.setPassword(SecurityUtils.encryptPassword(password)); + xhpcAppUser.setCreateTime(new Date()); + xhpcAppUser.setTenantId(tenantId); + xhpcAppUserMapper.insert(xhpcAppUser); + LoginUser userInfo = new LoginUser(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(xhpcAppUser.getPhone()); + sysUser.setUserId(xhpcAppUser.getAppUserId()); + userInfo.setSysUser(sysUser); + userInfo.setUserType(UserTypeUtil.USER_TYPE); + userInfo.setUsername(phone); + userInfo.setUserid(xhpcAppUser.getAppUserId()); + userInfo.setTenantId(tenantId); + userInfo.setUserTypeUtil(UserTypeUtil.USER); + + redisService.deleteObject("pvToken:" + xhpcAppUser.getPhone()); + //去退出账号之前登录的信息 + xhpcAppUserMapper.updateUserLoginTime(phone); + //添加最后一次登录数据 + xhpcAppUserMapper.addUserLoginTime(xhpcAppUser.getAppUserId(),phone,userInfo.getUserType(),null,3,UserConstants.LOGIN,tenantId,new Date()); + // 获取登录token + Map token = tokenService.createToken(userInfo); + token.put("phone",phone); + return R.ok(token); + } + @Override public R loginPhone(Map map) { String phone = StringUtils.valueOf(map.get("phone")); @@ -433,6 +559,23 @@ public class XhpcAppUserServiceImpl extends BaseService implements IXhpcAppUserU return R.ok(); } + @Override + public R appLoginOut(HttpServletRequest request) { + LoginUser loginUser = tokenService.getLoginUser(request); + if (StringUtils.isNotNull(loginUser)) { + String phone = loginUser.getUsername(); + Long userid = loginUser.getUserid(); + String tenantId = loginUser.getTenantId(); + Integer userType = loginUser.getUserType(); + XhpcAppUser appUser = xhpcAppUserMapper.getAppUserPhoneByUserId(phone, userid, tenantId); + //添加最后一次登录数据 + xhpcAppUserMapper.addUserLoginTime(appUser.getAppUserId(),phone,userType,null,3,UserConstants.NO_LOGIN,tenantId,new Date()); + // 删除用户缓存记录 + tokenService.delLoginUser(loginUser.getToken()); + } + return R.ok(); + } + /** * C端用户自动登录 * @@ -470,6 +613,71 @@ public class XhpcAppUserServiceImpl extends BaseService implements IXhpcAppUserU } } + @Override + public R appVoluntaryLogin(Map map) { + String phone = StringUtils.valueOf(map.get("phone")); + String password = StringUtils.valueOf(map.get("password")); + String tenantId = StringUtils.valueOf(map.get("tenantId")); + if (StringUtils.isAnyBlank(phone)) { + return R.fail(HttpStatus.NOT_NULL, "账号必须填写"); + } + if (StringUtils.isAnyBlank(password)) { + return R.fail(HttpStatus.NOT_NULL, "密码必须填写"); + } + if (StringUtils.isAnyBlank(tenantId)) { + return R.fail(HttpStatus.NOT_NULL, "租户必须填写"); + } + + XhpcAppUser user = xhpcAppUserMapper.getAppUserPhoneByPassword(phone,null,tenantId); + if (StringUtils.isNull(user)) { + return R.fail(HttpStatus.NOT_NULL, "请重新登录"); + }else{ + boolean b = SecurityUtils.matchesPassword(password, user.getPassword()); + if(!b){ + return R.fail(HttpStatus.NOT_NULL, "请重新登录"); + } + } + Map userLoginTime = xhpcAppUserMapper.getAppUserLoginTime(3,user.getAppUserId(), phone,tenantId); + if(userLoginTime ==null){ + return R.fail(HttpStatus.USER_LOGIN, "请重新登录"); + }else{ + if("0".equals(userLoginTime.get("status").toString())){ + return R.fail(HttpStatus.USER_LOGIN, "请重新登录"); + } + } + XhpcAppUser xhpcAppUser = new XhpcAppUser(); + xhpcAppUser.setPhone(phone); + xhpcAppUser.setPassword(SecurityUtils.encryptPassword(password)); + xhpcAppUser.setCreateTime(new Date()); + xhpcAppUser.setTenantId(tenantId); + xhpcAppUserMapper.insert(xhpcAppUser); + LoginUser userInfo = new LoginUser(); + SysUser sysUser = new SysUser(); + sysUser.setUserName(user.getPhone()); + sysUser.setUserId(user.getAppUserId()); + userInfo.setSysUser(sysUser); + userInfo.setUserType(UserTypeUtil.USER_TYPE); + userInfo.setUsername(phone); + userInfo.setUserid(user.getAppUserId()); + userInfo.setTenantId(tenantId); + userInfo.setUserTypeUtil(UserTypeUtil.USER); + if (UserStatus.DELETED.getCode().equals(user.getDelFlag())) { + return R.fail(HttpStatus.DATA_ERROR, "对不起,您的账号:" + phone + " 已被删除"); + } + if (UserStatus.DISABLE.getCode().equals(user.getStatus())) { + return R.fail(HttpStatus.DATA_ERROR, "对不起,您的账号:" + phone + " 已停用"); + } + redisService.deleteObject("pvToken:" + user.getPhone()); + //去退出账号之前登录的信息 + xhpcAppUserMapper.updateUserLoginTime(phone); + //添加最后一次登录数据 + xhpcAppUserMapper.addUserLoginTime(user.getAppUserId(),phone,userInfo.getUserType(),null,3,UserConstants.LOGIN,tenantId,new Date()); + // 获取登录token + Map token = tokenService.createToken(userInfo); + token.put("phone",phone); + return R.ok(token); + } + /** * 小程序用户详情 * @param diff --git a/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppInternetUserMapper.xml b/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppInternetUserMapper.xml index 92404c69..cabe4156 100644 --- a/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppInternetUserMapper.xml +++ b/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppInternetUserMapper.xml @@ -156,4 +156,9 @@ select count(terminal_id) from xhpc_terminal where serial_number =#{deviceCode} and del_flag =0 and status =0 + + + diff --git a/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppUserMapper.xml b/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppUserMapper.xml index b434f481..6e28fb48 100644 --- a/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppUserMapper.xml +++ b/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcAppUserMapper.xml @@ -235,6 +235,26 @@ WHERE del_flag = 0 and phone = #{phone} and tenant_id=#{tenantId} LIMIT 1 + + + + + + update xhpc_user_login set status =0 where account=#{account} and status=1 diff --git a/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcCommonMapper.xml b/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcCommonMapper.xml index 9a71c919..a45f4ca1 100644 --- a/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcCommonMapper.xml +++ b/xhpc-modules/xhpc-user/src/main/resources/mapper/XhpcCommonMapper.xml @@ -66,7 +66,7 @@ xcp.soc_protect socProtect, ten.status tenantStatus, concat("ST") as userTypeName, - (select vehicle_name as vehicleName from xhpc_user_vehicle where app_user_id = xau.app_user_id and source=2 and del_flag=0 and vin_blacklist !=1 order by type,create_time desc LIMIT 1) as vehicleName, + (select vehicle_name as vehicleName from xhpc_user_vehicle where app_user_id = xcp.community_personnel_id and source=2 and del_flag=0 and vin_blacklist !=1 order by type,create_time desc LIMIT 1) as vehicleName, (select count(charging_station_id) from xhpc_mechanism where community_id=mechanism_id and source=0 and charging_station_id in (select charging_station_id from xhpc_terminal where 1=1 and del_flag=0 and serial_number=#{serialNumber})) as number, @@ -106,7 +106,7 @@ xcp.soc_protect socProtect, ten.status tenantStatus, concat("BE") as userTypeName, - (select vehicle_name as vehicleName from xhpc_user_vehicle where app_user_id = xau.app_user_id and source=3 and del_flag=0 and vin_blacklist !=1 order by type,create_time desc LIMIT 1) as vehicleName, + (select vehicle_name as vehicleName from xhpc_user_vehicle where app_user_id = xcp.customers_personnel_id and source=3 and del_flag=0 and vin_blacklist !=1 order by type,create_time desc LIMIT 1) as vehicleName, (select count(charging_station_id) from xhpc_mechanism where customers_id=mechanism_id and source=1 and charging_station_id in (select charging_station_id from xhpc_terminal where 1=1 and del_flag=0 and serial_number=#{serialNumber})) as number, diff --git a/xhpc-modules/xhpc-wxma/090ac4cbd7f185446277f378c4e36ce.jpg b/xhpc-modules/xhpc-wxma/090ac4cbd7f185446277f378c4e36ce.jpg new file mode 100644 index 00000000..3327bdd0 Binary files /dev/null and b/xhpc-modules/xhpc-wxma/090ac4cbd7f185446277f378c4e36ce.jpg differ diff --git a/xhpc-modules/xhpc-wxma/src/main/resources/bootstrap.yml b/xhpc-modules/xhpc-wxma/src/main/resources/bootstrap.yml index c6ad3564..6287bed8 100644 --- a/xhpc-modules/xhpc-wxma/src/main/resources/bootstrap.yml +++ b/xhpc-modules/xhpc-wxma/src/main/resources/bootstrap.yml @@ -16,10 +16,10 @@ spring: nacos: discovery: # 服务注册地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 config: # 配置中心地址 - server-addr: 172.31.183.135:8848 + server-addr: mse-e2a05960-nacos-ans.mse.aliyuncs.com:8848 # 配置文件格式 file-extension: yml # 共享配置