diff --git a/jsowell-admin/src/main/java/com/jsowell/lianlian/LianLianController.java b/jsowell-admin/src/main/java/com/jsowell/lianlian/LianLianController.java index b702e057f..673ac4fa0 100644 --- a/jsowell-admin/src/main/java/com/jsowell/lianlian/LianLianController.java +++ b/jsowell-admin/src/main/java/com/jsowell/lianlian/LianLianController.java @@ -32,6 +32,24 @@ public class LianLianController extends BaseController { private LianLianService lianLianService; + @PostMapping("/pushStationInfo") + public RestApiResponse pushStationInfo(@RequestBody QueryStationInfoDTO dto) { + logger.info("推送联联平台充电站信息 params:{}", JSONObject.toJSONString(dto)); + RestApiResponse response = null; + try { + lianLianService.pushStationInfo(Long.parseLong(dto.getStationID())); + response = new RestApiResponse<>(); + }catch (BusinessException e) { + logger.error("推送联联平台充电站信息 error",e); + response = new RestApiResponse<>(e.getCode(), e.getMessage()); + }catch (Exception e) { + logger.error("推送联联平台充电站信息 error", e); + response = new RestApiResponse<>(e); + } + logger.info("推送联联平台充电站信息 result:{}", response); + return response; + } + /** * 联联平台查询充电站信息 * http://localhost:8080/LianLian/query_stations_info @@ -58,6 +76,7 @@ public class LianLianController extends BaseController { /** * 联联平台查询充电站状态信息 + * http://localhost:8080/LianLian/query_station_status * @param StationIDs * @return */ @@ -84,6 +103,8 @@ public class LianLianController extends BaseController { /** * 查询统计信息 + * http://localhost:8080/LianLian/query_station_stats + * * @param dto * @return */ @@ -107,6 +128,7 @@ public class LianLianController extends BaseController { /** * 请求设备认证 + * http://localhost:8080/LianLian/query_equip_auth * @param dto * @return */ @@ -130,6 +152,7 @@ public class LianLianController extends BaseController { /** * 请求启动充电 + * http://localhost:8080/LianLian/query_start_charge * @param dto * @return */ @@ -153,6 +176,7 @@ public class LianLianController extends BaseController { /** * 查询充电状态 + * http://localhost:8080/LianLian/query_equip_charge_status/{startChargeSeq} * @param startChargeSeq * @return */ @@ -176,6 +200,7 @@ public class LianLianController extends BaseController { /** * 请求停止充电 + * http://localhost:8080/LianLian/query_stop_charge * @param dto * @return */ diff --git a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java index a78b6e4fd..055d75f75 100644 --- a/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java +++ b/jsowell-admin/src/main/java/com/jsowell/service/OrderService.java @@ -842,6 +842,15 @@ public class OrderService { MemberVO memberVO = memberService.getMemberInfoByMemberId(orderBasicInfo.getMemberId()); vo.setMemberInfo(memberVO); + try { + // 因为原来的数据在redis中是永久保存,所以这里做下查询详情的时候,发现已经是完成的订单,redis数据存到表中 + if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) { + // 如果是已完成的订单,把redis中的实时数据存到表中 + orderBasicInfoService.realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode()); + } + } catch (Exception e) { + log.error("后管查询订单详情时把redis中的实时数据存到表发生异常", e); + } return vo; } @@ -934,10 +943,17 @@ public class OrderService { UniAppOrderVO.BillingDetails billingDetails = new UniAppOrderVO.BillingDetails(); BeanUtils.copyBeanProp(billingDetails, orderDetail); vo.setBillingDetails(billingDetails); - // orderDetail.getSharpElectricityPrice() + } - + try { + // 因为原来的数据在redis中是永久保存,所以这里做下查询详情的时候,发现已经是完成的订单,redis数据存到表中 + if (StringUtils.equals(orderBasicInfo.getOrderStatus(), OrderStatusEnum.ORDER_COMPLETE.getValue())) { + // 如果是已完成的订单,把redis中的实时数据存到表中 + orderBasicInfoService.realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode()); + } + } catch (Exception e) { + log.error("后管查询订单详情时把redis中的实时数据存到表发生异常", e); } return vo; } diff --git a/jsowell-admin/src/test/java/SpringBootTestController.java b/jsowell-admin/src/test/java/SpringBootTestController.java index 448ba4a33..daf542892 100644 --- a/jsowell-admin/src/test/java/SpringBootTestController.java +++ b/jsowell-admin/src/test/java/SpringBootTestController.java @@ -13,15 +13,12 @@ import com.jsowell.common.core.domain.ykc.TransactionRecordsData; import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.ykc.OrderStatusEnum; import com.jsowell.common.exception.BusinessException; -import com.jsowell.common.util.BytesUtil; -import com.jsowell.common.util.DateUtils; -import com.jsowell.common.util.DictUtils; -import com.jsowell.common.util.JWTUtils; -import com.jsowell.common.util.StringUtils; -import com.jsowell.common.util.YKCUtils; +import com.jsowell.common.util.*; +import com.jsowell.common.util.http.HttpUtils; import com.jsowell.common.util.id.SnUtils; import com.jsowell.common.util.id.SnowflakeIdWorker; import com.jsowell.common.util.ip.AddressUtils; +import com.jsowell.common.util.lianlian.LianLianUtils; import com.jsowell.netty.command.ykc.IssueQRCodeCommand; import com.jsowell.netty.command.ykc.ProofreadTimeCommand; import com.jsowell.netty.handler.HeartbeatRequestHandler; @@ -33,14 +30,7 @@ import com.jsowell.pile.domain.PileBillingDetail; import com.jsowell.pile.domain.PileBillingTemplate; import com.jsowell.pile.domain.PileStationInfo; import com.jsowell.pile.domain.WxpayCallbackRecord; -import com.jsowell.pile.dto.BasicPileDTO; -import com.jsowell.pile.dto.BatchCreatePileDTO; -import com.jsowell.pile.dto.ImportBillingTemplateDTO; -import com.jsowell.pile.dto.QueryOrderDTO; -import com.jsowell.pile.dto.QueryPileDTO; -import com.jsowell.pile.dto.QueryStationDTO; -import com.jsowell.pile.dto.RefundableWxPayOrderData; -import com.jsowell.pile.dto.WeixinPayDTO; +import com.jsowell.pile.dto.*; import com.jsowell.pile.mapper.MemberBasicInfoMapper; import com.jsowell.pile.mapper.PileBillingTemplateMapper; import com.jsowell.pile.service.IOrderBasicInfoService; @@ -59,6 +49,8 @@ import com.jsowell.service.MemberService; import com.jsowell.service.OrderService; import com.jsowell.service.PileRemoteService; import com.jsowell.service.PileService; +import com.jsowell.thirdparty.domain.StationInfo; +import com.jsowell.thirdparty.service.LianLianService; import com.jsowell.wxpay.common.WeChatPayParameter; import com.jsowell.wxpay.dto.AppletTemplateMessageSendDTO; import com.jsowell.wxpay.dto.WeChatRefundDTO; @@ -77,13 +69,7 @@ import org.springframework.util.StopWatch; import java.math.BigDecimal; import java.text.ParseException; import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @ActiveProfiles("dev") @SpringBootTest(classes = JsowellApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -161,6 +147,13 @@ public class SpringBootTestController { @Autowired private AdapayService adapayService; + @Autowired + private LianLianService lianLianService; + + static final String MAC_KEY = "53TtFpc4gdVZbF3x"; + + static final String ALGORITHM_MAC = "HmacMD5"; + @Test public void testCreateAdapay() { adapayService.createTransactionObject(); @@ -190,6 +183,7 @@ public class SpringBootTestController { } } + @Test public void testupdateElecAmount() { orderBasicInfoService.updateElecAmount(); @@ -201,6 +195,70 @@ public class SpringBootTestController { System.out.println(pileAuthCard); } + @Test + public void testLianLian() throws Exception { + // Long stationId = 2L; + // // 通过id查询站点相关信息 + // PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(stationId); + // // 组装联联平台所需要的数据格式 + // StationInfo info = StationInfo.builder() + // .StationID(String.valueOf(stationId)) + // .OperatorID(Constants.OPERATORID_LIANLIAN) + // .EquipmentOwnerID(Constants.OPERATORID_LIANLIAN) + // .StationName(pileStationInfo.getStationName()) + // .IsAloneApply(Integer.valueOf(pileStationInfo.getAloneApply())) + // .IsPublicParkingLot(Integer.valueOf(pileStationInfo.getPublicParking())) + // .CountryCode(pileStationInfo.getCountryCode()) + // .AreaCode(pileStationInfo.getAreaCode()) + // .Address(pileStationInfo.getAddress()) + // .ServiceTel(pileStationInfo.getServiceTel()) + // .StationType(Integer.valueOf(pileStationInfo.getStationType())) + // .StationStatus(Integer.valueOf(pileStationInfo.getStationStatus())) + // .ParkNums(Integer.valueOf(pileStationInfo.getParkNums())) + // .StationLng(new BigDecimal(pileStationInfo.getStationLng())) + // .StationLat(new BigDecimal(pileStationInfo.getStationLat())) + // .Construction(Integer.valueOf(pileStationInfo.getConstruction())) + // .OpenAllDay(Integer.valueOf(pileStationInfo.getOpenAllDay())) + // // .MinElectricityPrice() + // // .ElectricityFee() + // // .ServiceFee() + // .ParkFree(Integer.valueOf(pileStationInfo.getParkFree())) + // // .ParkFee() + // .Payment(pileStationInfo.getPayment()) + // .SupportOrder(Integer.valueOf(pileStationInfo.getSupportOrder())) + // // .equipmentInfos() + // // .ParkFeeType() + // .ToiletFlag(Integer.valueOf(pileStationInfo.getToiletFlag())) + // .StoreFlag(Integer.valueOf(pileStationInfo.getStoreFlag())) + // .RestaurantFlag(Integer.valueOf(pileStationInfo.getRestaurantFlag())) + // .LoungeFlag(Integer.valueOf(pileStationInfo.getLoungeFlag())) + // .CanopyFlag(Integer.valueOf(pileStationInfo.getCanopyFlag())) + // .PrinterFlag(Integer.valueOf(pileStationInfo.getPrinterFlag())) + // .BarrierFlag(Integer.valueOf(pileStationInfo.getBarrierFlag())) + // .ParkingLockFlag(Integer.valueOf(pileStationInfo.getParkingLockFlag())) + // + // .build(); + + // List pileList = lianLianService.getPileList(pileStationInfo); + // if (CollectionUtils.isNotEmpty(pileList)) { + // info.setEquipmentInfos(pileList); // 充电设备信息列表 + // } + + String url = "http://testdataexchange.evchargeonline.com:82/shevcs/v1/" + "notification_stationInfo"; + JSONObject json = new JSONObject(); + json.put("OperatorID", "MA1JLFUU8"); + json.put("OperatorSecret", "Nh62XxllR5OjAzFj"); + // json.put("StationInfo", info); + + LianLianGetTokenDTO dto = new LianLianGetTokenDTO(); + dto.setOperatorId("987654321"); + dto.setOperatorSecret("1234567890abcdef"); + String token = lianLianService.getToken(dto); + System.out.println("token:" + token); + + } + + @Test public void testRefundForBalance() { BigDecimal refundAmount = new BigDecimal("2"); diff --git a/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java b/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java index 478fc9724..96d68d6b9 100644 --- a/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java +++ b/jsowell-common/src/main/java/com/jsowell/common/constant/Constants.java @@ -33,6 +33,8 @@ public class Constants { public static final String partnerId = "1632405339"; // 商户号Id + public static final String OPERATORID_LIANLIAN = "MA1JLFUU8"; + // public static final String APP_ID = "wxbb3e0d474569481d"; // 举视充电网 wxbb3e0d474569481d // // public static final String APP_SECRET = "bbac689f4654b209de4d6944808ec80b"; // 举视充电网 bbac689f4654b209de4d6944808ec80b diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/LianLianUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/LianLianUtils.java deleted file mode 100644 index 712ea2107..000000000 --- a/jsowell-common/src/main/java/com/jsowell/common/util/LianLianUtils.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.jsowell.common.util;/** - * TODO - * - * @author JS-ZZA - * @date 2023/5/6 14:22 - */public class LianLianUtils { -} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Cryptos.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Cryptos.java new file mode 100644 index 000000000..9e4da21f2 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Cryptos.java @@ -0,0 +1,248 @@ +/** + */ +package com.jsowell.common.util.lianlian; + +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.SecureRandom; +import java.util.Arrays; + +public class Cryptos { + + private static final String AES = "AES"; + private static final String AES_CBC = "AES/CBC/PKCS5Padding"; + private static final String HMACSHA1 = "HmacSHA1"; + + private static final String DEFAULT_URL_ENCODING = "UTF-8"; + private static final int DEFAULT_HMACSHA1_KEYSIZE = 160; //RFC2401 + private static final int DEFAULT_AES_KEYSIZE = 128; + private static final int DEFAULT_IVSIZE = 16; + + private static final byte[] DEFAULT_KEY = new byte[]{-97,88,-94,9,70,-76,126,25,0,3,-20,113,108,28,69,125}; + + private static SecureRandom random = new SecureRandom(); + + //-- HMAC-SHA1 funciton --// + /** + * 使用HMAC-SHA1进行消息签名, 返回字节数组,长度为20字节. + * + * @param input 原始输入字符数组 + * @param key HMAC-SHA1密钥 + */ + public static byte[] hmacSha1(byte[] input, byte[] key) { + try { + SecretKey secretKey = new SecretKeySpec(key, HMACSHA1); + Mac mac = Mac.getInstance(HMACSHA1); + mac.init(secretKey); + return mac.doFinal(input); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 校验HMAC-SHA1签名是否正确. + * + * @param expected 已存在的签名 + * @param input 原始输入字符串 + * @param key 密钥 + */ + public static boolean isMacValid(byte[] expected, byte[] input, byte[] key) { + byte[] actual = hmacSha1(input, key); + return Arrays.equals(expected, actual); + } + + /** + * 生成HMAC-SHA1密钥,返回字节数组,长度为160位(20字节). + * HMAC-SHA1算法对密钥无特殊要求, RFC2401建议最少长度为160位(20字节). + */ + public static byte[] generateHmacSha1Key() { + try { + KeyGenerator keyGenerator = KeyGenerator.getInstance(HMACSHA1); + keyGenerator.init(DEFAULT_HMACSHA1_KEYSIZE); + SecretKey secretKey = keyGenerator.generateKey(); + return secretKey.getEncoded(); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + //-- AES funciton --// + + /** + * 使用AES加密原始字符串. + * + * @param input 原始输入字符数组 + */ + public static String aesEncrypt(String input) { + try { + return Encodes.encodeHex(aesEncrypt(input.getBytes(DEFAULT_URL_ENCODING), DEFAULT_KEY)); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + + /** + * 使用AES加密原始字符串. + * + * @param input 原始输入字符数组 + * @param key 符合AES要求的密钥 + */ + public static String aesEncrypt(String input, String key) { + try { + return Encodes.encodeHex(aesEncrypt(input.getBytes(DEFAULT_URL_ENCODING), Encodes.decodeHex(key))); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + + /** + * 使用AES加密原始字符串. + * + * @param input 原始输入字符数组 + * @param key 符合AES要求的密钥 + */ + public static byte[] aesEncrypt(byte[] input, byte[] key) { + return aes(input, key, Cipher.ENCRYPT_MODE); + } + + /** + * 使用AES加密原始字符串. + * + * @param input 原始输入字符数组 + * @param key 符合AES要求的密钥 + * @param iv 初始向量 + */ + public static byte[] aesEncrypt(byte[] input, byte[] key, byte[] iv) { + return aes(input, key, iv, Cipher.ENCRYPT_MODE); + } + + /** + * 使用AES解密字符串, 返回原始字符串. + * + * @param input Hex编码的加密字符串 + */ + public static String aesDecrypt(String input) { + try { + return new String(aesDecrypt(Encodes.decodeHex(input), DEFAULT_KEY), DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + + /** + * 使用AES解密字符串, 返回原始字符串. + * + * @param input Hex编码的加密字符串 + * @param key 符合AES要求的密钥 + */ + public static String aesDecrypt(String input, String key) { + try { + return new String(aesDecrypt(Encodes.decodeHex(input), Encodes.decodeHex(key)), DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + + /** + * 使用AES解密字符串, 返回原始字符串. + * + * @param input Hex编码的加密字符串 + * @param key 符合AES要求的密钥 + */ + public static byte[] aesDecrypt(byte[] input, byte[] key) { + return aes(input, key, Cipher.DECRYPT_MODE); + } + + /** + * 使用AES解密字符串, 返回原始字符串. + * + * @param input Hex编码的加密字符串 + * @param key 符合AES要求的密钥 + * @param iv 初始向量 + */ + public static byte[] aesDecrypt(byte[] input, byte[] key, byte[] iv) { + return aes(input, key, iv, Cipher.DECRYPT_MODE); + } + + /** + * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果. + * + * @param input 原始字节数组 + * @param key 符合AES要求的密钥 + * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE + */ + private static byte[] aes(byte[] input, byte[] key, int mode) { + try { + SecretKey secretKey = new SecretKeySpec(key, AES); + Cipher cipher = Cipher.getInstance(AES); + cipher.init(mode, secretKey); + return cipher.doFinal(input); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 使用AES加密或解密无编码的原始字节数组, 返回无编码的字节数组结果. + * + * @param input 原始字节数组 + * @param key 符合AES要求的密钥 + * @param iv 初始向量 + * @param mode Cipher.ENCRYPT_MODE 或 Cipher.DECRYPT_MODE + */ + private static byte[] aes(byte[] input, byte[] key, byte[] iv, int mode) { + try { + SecretKey secretKey = new SecretKeySpec(key, AES); + IvParameterSpec ivSpec = new IvParameterSpec(iv); + Cipher cipher = Cipher.getInstance(AES_CBC); + cipher.init(mode, secretKey, ivSpec); + return cipher.doFinal(input); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 生成AES密钥,返回字节数组, 默认长度为128位(16字节). + */ + public static String generateAesKeyString() { + return Encodes.encodeHex(generateAesKey(DEFAULT_AES_KEYSIZE)); + } + + /** + * 生成AES密钥,返回字节数组, 默认长度为128位(16字节). + */ + public static byte[] generateAesKey() { + return generateAesKey(DEFAULT_AES_KEYSIZE); + } + + /** + * 生成AES密钥,可选长度为128,192,256位. + */ + public static byte[] generateAesKey(int keysize) { + try { + KeyGenerator keyGenerator = KeyGenerator.getInstance(AES); + keyGenerator.init(keysize); + SecretKey secretKey = keyGenerator.generateKey(); + return secretKey.getEncoded(); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 生成随机向量,默认大小为cipher.getBlockSize(), 16字节. + */ + public static byte[] generateIV() { + byte[] bytes = new byte[DEFAULT_IVSIZE]; + random.nextBytes(bytes); + return bytes; + } +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Digests.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Digests.java new file mode 100644 index 000000000..32d885051 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Digests.java @@ -0,0 +1,113 @@ +/** + */ +package com.jsowell.common.util.lianlian; + +import org.apache.commons.lang3.Validate; + +import java.io.IOException; +import java.io.InputStream; +import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.security.SecureRandom; + +public class Digests { + + private static final String SHA1 = "SHA-1"; + private static final String MD5 = "MD5"; + + private static SecureRandom random = new SecureRandom(); + + /** + * 对输入字符串进行md5散列. + */ + public static byte[] md5(byte[] input) { + return digest(input, MD5, null, 1); + } + public static byte[] md5(byte[] input, int iterations) { + return digest(input, MD5, null, iterations); + } + + /** + * 对输入字符串进行sha1散列. + */ + public static byte[] sha1(byte[] input) { + return digest(input, SHA1, null, 1); + } + + public static byte[] sha1(byte[] input, byte[] salt) { + return digest(input, SHA1, salt, 1); + } + + public static byte[] sha1(byte[] input, byte[] salt, int iterations) { + return digest(input, SHA1, salt, iterations); + } + + /** + * 对字符串进行散列, 支持md5与sha1算法. + */ + private static byte[] digest(byte[] input, String algorithm, byte[] salt, int iterations) { + try { + MessageDigest digest = MessageDigest.getInstance(algorithm); + + if (salt != null) { + digest.update(salt); + } + + byte[] result = digest.digest(input); + + for (int i = 1; i < iterations; i++) { + digest.reset(); + result = digest.digest(result); + } + return result; + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * 生成随机的Byte[]作为salt. + * + * @param numBytes byte数组的大小 + */ + public static byte[] generateSalt(int numBytes) { + Validate.isTrue(numBytes > 0, "numBytes argument must be a positive integer (1 or larger)", numBytes); + + byte[] bytes = new byte[numBytes]; + random.nextBytes(bytes); + return bytes; + } + + /** + * 对文件进行md5散列. + */ + public static byte[] md5(InputStream input) throws IOException { + return digest(input, MD5); + } + + /** + * 对文件进行sha1散列. + */ + public static byte[] sha1(InputStream input) throws IOException { + return digest(input, SHA1); + } + + private static byte[] digest(InputStream input, String algorithm) throws IOException { + try { + MessageDigest messageDigest = MessageDigest.getInstance(algorithm); + int bufferLength = 8 * 1024; + byte[] buffer = new byte[bufferLength]; + int read = input.read(buffer, 0, bufferLength); + + while (read > -1) { + messageDigest.update(buffer, 0, read); + read = input.read(buffer, 0, bufferLength); + } + + return messageDigest.digest(); + } catch (GeneralSecurityException e) { + throw Exceptions.unchecked(e); + } + } + +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Encodes.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Encodes.java new file mode 100644 index 000000000..7f37dfdb3 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Encodes.java @@ -0,0 +1,142 @@ +/** + * Copyright (c) 2005-2012 springside.org.cn + */ +package com.jsowell.common.util.lianlian; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang3.StringEscapeUtils; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; + +public class Encodes { + + private static final String DEFAULT_URL_ENCODING = "UTF-8"; + private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray(); + + /** + * Hex编码. + */ + public static String encodeHex(byte[] input) { + return new String(Hex.encodeHex(input)); + } + + /** + * Hex解码. + */ + public static byte[] decodeHex(String input) { + try { + return Hex.decodeHex(input.toCharArray()); + } catch (DecoderException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * Base64编码. + */ + public static String encodeBase64(byte[] input) { + return new String(Base64.encodeBase64(input)); + } + + /** + * Base64编码. + */ + public static String encodeBase64(String input) { + try { + return new String(Base64.encodeBase64(input.getBytes(DEFAULT_URL_ENCODING))); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + +// /** +// * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548). +// */ +// public static String encodeUrlSafeBase64(byte[] input) { +// return Base64.encodeBase64URLSafe(input); +// } + + /** + * Base64解码. + */ + public static byte[] decodeBase64(String input) { + return Base64.decodeBase64(input.getBytes()); + } + + /** + * Base64解码. + */ + public static String decodeBase64String(String input) { + try { + return new String(Base64.decodeBase64(input.getBytes()), DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + return ""; + } + } + + /** + * Base62编码。 + */ + public static String encodeBase62(byte[] input) { + char[] chars = new char[input.length]; + for (int i = 0; i < input.length; i++) { + chars[i] = BASE62[((input[i] & 0xFF) % BASE62.length)]; + } + return new String(chars); + } + + /** + * Html 转码. + */ + public static String escapeHtml(String html) { + return StringEscapeUtils.escapeHtml4(html); + } + + /** + * Html 解码. + */ + public static String unescapeHtml(String htmlEscaped) { + return StringEscapeUtils.unescapeHtml4(htmlEscaped); + } + + /** + * Xml 转码. + */ + public static String escapeXml(String xml) { + return StringEscapeUtils.escapeXml10(xml); + } + + /** + * Xml 解码. + */ + public static String unescapeXml(String xmlEscaped) { + return StringEscapeUtils.unescapeXml(xmlEscaped); + } + + /** + * URL 编码, Encode默认为UTF-8. + */ + public static String urlEncode(String part) { + try { + return URLEncoder.encode(part, DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * URL 解码, Encode默认为UTF-8. + */ + public static String urlDecode(String part) { + + try { + return URLDecoder.decode(part, DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + throw Exceptions.unchecked(e); + } + } +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Exceptions.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Exceptions.java new file mode 100644 index 000000000..02ce6e0af --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/Exceptions.java @@ -0,0 +1,72 @@ +package com.jsowell.common.util.lianlian; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletRequest; +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 关于异常的工具类. + */ +public class Exceptions { + private static Logger logger = LoggerFactory.getLogger(Exceptions.class); + + /** + * 将CheckedException转换为UncheckedException. + */ + public static RuntimeException unchecked(Exception e) { + if (e instanceof RuntimeException) { + return (RuntimeException) e; + } else { + return new RuntimeException(e); + } + } + + /** + * 将ErrorStack转化为String. + */ + public static String getStackTraceAsString(Throwable e) { + if (e == null) { + return ""; + } + StringWriter stringWriter = new StringWriter(); + e.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + + /** + * 判断异常是否由某些底层的异常引起. + */ + public static boolean isCausedBy(Exception ex, Class... causeExceptionClasses) { + Throwable cause = ex.getCause(); + while (cause != null) { + for (Class causeClass : causeExceptionClasses) { + if (causeClass.isInstance(cause)) { + return true; + } + } + cause = cause.getCause(); + } + return false; + } + + /** + * 在request中获取异常类 + * + * @param request + * @return + */ + public static Throwable getThrowable(HttpServletRequest request) { + Throwable ex = null; + if (request.getAttribute("exception") != null) { + ex = (Throwable) request.getAttribute("exception"); + } else if (request.getAttribute("javax.servlet.error.exception") != null) { + ex = (Throwable) request.getAttribute("javax.servlet.error.exception"); + } + return ex; + } + + +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/GBSignUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/GBSignUtils.java new file mode 100644 index 000000000..1dace0d68 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/GBSignUtils.java @@ -0,0 +1,58 @@ +package com.jsowell.common.util.lianlian; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.util.Map; + +public class GBSignUtils { + + public static final Logger logger = LoggerFactory.getLogger(GBSignUtils.class); + + public static String sign(Map paramValues, String secret) { + try { + StringBuilder sb = new StringBuilder(); + for (String value : paramValues.values()) { + if (StringUtils.isNotBlank(value)) { + sb.append(value); + } + } + logger.debug("需要签名的内容:{},密钥{}", sb.toString(), secret); + byte[] md5Digest = HmacMD5Encrypt(sb.toString(), secret); + String result = Encodes.encodeHex(md5Digest).toUpperCase(); + logger.debug("HmacSHA1的签名内容:{}", result); + return result; + } catch (Exception e) { + throw new RuntimeException("数据签名出错", e); + } + } + + /** + * 使用 HMAC-MD5 签名方法对对encryptText进行签名 + * + * @param encryptText + * 被签名的字符串 + * @param encryptKey + * 密钥 + * @return + * @throws Exception + */ + public static byte[] HmacMD5Encrypt(String encryptText, String encryptKey) throws Exception { + byte[] data = encryptKey.getBytes("UTF-8"); + // 根据给定的字节数组构造一个密钥,第二参数指定一个密钥算法的名称 + SecretKey secretKey = new SecretKeySpec(data, "HmacMD5"); + // 生成一个指定 Mac 算法 的 Mac 对象 + Mac mac = Mac.getInstance("HmacMD5"); + // 用给定密钥初始化 Mac 对象 + mac.init(secretKey); + + byte[] text = encryptText.getBytes("UTF-8"); + // 完成 Mac 操作 + return mac.doFinal(text); + } + +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/HttpRequestUtil.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/HttpRequestUtil.java new file mode 100644 index 000000000..847e26aa2 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/HttpRequestUtil.java @@ -0,0 +1,85 @@ +package com.jsowell.common.util.lianlian; + +import lombok.extern.slf4j.Slf4j; +import org.apache.http.HttpEntity; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; + +/** + * @author 联联充电 + */ +@Slf4j +@SuppressWarnings(value = "unused") +public class HttpRequestUtil { + + + /** + * httpClient--post请求--http + * + * @param url + * @param json + * @return + */ + public static String httpPost(String url, String json, String token) { + CloseableHttpClient httpClient = HttpClients.createDefault(); + CloseableHttpResponse response = null; + try { + //创建httpPost + HttpPost httpPost = new HttpPost(url); + + //设置Content-Type + httpPost.setHeader("Content-Type", "application/json"); + httpPost.setHeader("Authorization", token); + + //写入json数据 + httpPost.setEntity(new StringEntity(json)); + + RequestConfig requestConfig = RequestConfig.custom() + .setConnectTimeout(50000) + .setConnectionRequestTimeout(50000) + .setSocketTimeout(50000) + .build(); + httpPost.setConfig(requestConfig); + + //发起请求,获取response对象 + response = httpClient.execute(httpPost); + + //获取结果状态码 + int resultCode = response.getStatusLine().getStatusCode(); + if (resultCode == 200) { + //获取返回数据实体对象 + HttpEntity entity = response.getEntity(); + + //转化为字符串 + String result = EntityUtils.toString(entity, "UTF-8"); + //封装统一的返回数据接收类 + //ResponseMsg responseMsg = (ResponseMsg) JSON.parse(result); + return result; + } else { + log.info("http请求失败"); + } + } catch (Exception e) { + log.info("http请求异常"); + } finally { + try { + if (httpClient != null) { + httpClient.close(); + } + if (response != null) { + response.close(); + } + } catch (Exception e) { + log.info(e.getMessage(), e); + } + } + + return null; + } + + +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/LianLianUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/LianLianUtils.java new file mode 100644 index 000000000..8379cfb50 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/LianLianUtils.java @@ -0,0 +1,48 @@ +package com.jsowell.common.util.lianlian; + +import com.jsowell.common.constant.Constants; +import com.jsowell.common.util.BytesUtil; +import com.jsowell.common.util.DateUtils; + +import javax.crypto.Mac; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.util.Locale; + +/** + * 联联平台工具类 + * + * @author JS-ZZA + * @date 2023/5/6 14:22 + */ +public class LianLianUtils { + static final String ALGORITHM_MAC = "HmacMD5"; + + /** 密钥 **/ + static final String MAC_KEY = "TmsdVaFVTtjzZbLi"; + + + /** + * HMAC加密 + * @return + * @throws Exception + */ + public static String encryptionHMAC(String source) throws Exception { + SecretKey secretKey = new SecretKeySpec(MAC_KEY.getBytes("UTF-8"), ALGORITHM_MAC); + Mac mac = Mac.getInstance(ALGORITHM_MAC); + mac.init(secretKey); + mac.update(source.getBytes("UTF-8")); + return BytesUtil.binary(mac.doFinal(), 16).toUpperCase(Locale.ROOT); + } + + /** + * 拼接参数 + * @param Data + * @return + */ + public static String connectData(String Data){ + String timeStamp = DateUtils.dateTimeNow(DateUtils.YYYYMMDDHHMMSS); + String number = "0001"; + return Constants.OPERATORID_LIANLIAN + Data + timeStamp + number; + } +} diff --git a/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/SignUtils.java b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/SignUtils.java new file mode 100644 index 000000000..e92ae8008 --- /dev/null +++ b/jsowell-common/src/main/java/com/jsowell/common/util/lianlian/SignUtils.java @@ -0,0 +1,116 @@ +package com.jsowell.common.util.lianlian; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.util.*; + +public class SignUtils { + + private static String UTF_8 = "UTF-8"; + + /** + * 使用secret对paramValues按以下算法进行签名:
+ * uppercase(hex(sha1(secretkey1value1key2value2...secret)) + * + * @param paramValues + * 参数列表 + * @param secret + * @return + */ + public static String sign(Map paramValues, String secret) { + return sign(paramValues, null, secret); + } + + /** + * 对paramValues进行签名,其中ignoreParamNames这些参数不参与签名 + * + * @param paramValues + * @param ignoreParamNames + * @param secret + * @return + */ + public static String sign(Map paramValues, List ignoreParamNames, String secret) { + try { + StringBuilder sb = new StringBuilder(); + List paramNames = new ArrayList(paramValues.size()); + paramNames.addAll(paramValues.keySet()); + if (ignoreParamNames != null && ignoreParamNames.size() > 0) { + for (String ignoreParamName : ignoreParamNames) { + paramNames.remove(ignoreParamName); + } + } + Collections.sort(paramNames); + + sb.append(secret); + for (String paramName : paramNames) { + sb.append(paramName).append(paramValues.get(paramName)); + } + sb.append(secret); + System.out.println("原始的签名:" + sb.toString()); + byte[] sha1Digest = getSHA1Digest(sb.toString()); + System.out.println("sha-1的二进制码:" + String.valueOf(sha1Digest)); + return byte2hex(sha1Digest); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static String utf8Encoding(String value, String sourceCharsetName) { + try { + return new String(value.getBytes(sourceCharsetName), UTF_8); + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException(e); + } + } + + private static byte[] getSHA1Digest(String data) throws IOException { + byte[] bytes = null; + try { + MessageDigest md = MessageDigest.getInstance("SHA-1"); + bytes = md.digest(data.getBytes(UTF_8)); + } catch (GeneralSecurityException gse) { + throw new IOException(gse.getMessage()) ; + } + return bytes; + } + + // private static byte[] getMD5Digest(String data) throws IOException { + // byte[] bytes = null; + // try { + // MessageDigest md = MessageDigest.getInstance("MD5"); + // bytes = md.digest(data.getBytes(UTF_8)); + // } catch (GeneralSecurityException gse) { + // throw new IOException(gse.getMessage()); + // } + // return bytes; + // } + + /** + * 二进制转十六进制字符串 + * + * @param bytes + * @return + */ + private static String byte2hex(byte[] bytes) { + StringBuilder sign = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + String hex = Integer.toHexString(bytes[i] & 0xFF); + if (hex.length() == 1) { + sign.append("0"); + } + sign.append(hex.toUpperCase()); + } + System.out.println("最终的签名:" + sign); + return sign.toString(); + } + + public static String getUUID() { + UUID uuid = UUID.randomUUID(); + return uuid.toString().toUpperCase(); + } + + + +} diff --git a/jsowell-pile/pom.xml b/jsowell-pile/pom.xml index 7b3711aba..d399d27d5 100644 --- a/jsowell-pile/pom.xml +++ b/jsowell-pile/pom.xml @@ -87,6 +87,11 @@ com.huifu.adapay adapay-java-sdk + + + com.alibaba.fastjson2 + fastjson2 + diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/BillDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/BillDemo.java index 141890f97..d4d10c35a 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/BillDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/BillDemo.java @@ -1,8 +1,6 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; -import com.huifu.adapay.model.AdapayTools; -import com.huifu.adapay.model.Bill; import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/CorpMemberDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/CorpMemberDemo.java index 5d28e068c..76cf8bed3 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/CorpMemberDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/CorpMemberDemo.java @@ -1,7 +1,6 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; -import com.huifu.adapay.model.CorpMember; import java.io.File; import java.util.HashMap; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/FastPayDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/FastPayDemo.java index 048e690bd..5d4cf195a 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/FastPayDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/FastPayDemo.java @@ -1,7 +1,6 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; -import com.huifu.adapay.model.FastPay; import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MainDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MainDemo.java index 4b58791b9..141a01e5c 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MainDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MainDemo.java @@ -1,7 +1,5 @@ package com.jsowell.adapay.demo; -import com.huifu.adapay.Adapay; -import com.huifu.adapay.model.MerConfig; import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MemberDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MemberDemo.java index 677098e58..d1277decd 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MemberDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/MemberDemo.java @@ -1,7 +1,6 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; -import com.huifu.adapay.model.Member; import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentDemo.java index 3453b7d15..d4f538e62 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentDemo.java @@ -2,10 +2,7 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; import com.huifu.adapay.core.exception.BaseAdaPayException; -import com.huifu.adapay.model.Checkout; -import com.huifu.adapay.model.Payment; -import com.huifu.adapay.model.PaymentConfirm; -import com.huifu.adapay.model.PaymentReverse; + import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentRegionAndRequestTimeOutDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentRegionAndRequestTimeOutDemo.java index 45c4e7702..10ffeb858 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentRegionAndRequestTimeOutDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/PaymentRegionAndRequestTimeOutDemo.java @@ -2,7 +2,6 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; import com.huifu.adapay.core.exception.BaseAdaPayException; -import com.huifu.adapay.model.Payment; import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/RefundDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/RefundDemo.java index 36079389d..87d7136c1 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/RefundDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/RefundDemo.java @@ -1,7 +1,6 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; -import com.huifu.adapay.model.Refund; import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/SettleAccountDemo.java b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/SettleAccountDemo.java index 0e240857b..4ebac53d2 100644 --- a/jsowell-pile/src/main/java/com/jsowell/adapay/demo/SettleAccountDemo.java +++ b/jsowell-pile/src/main/java/com/jsowell/adapay/demo/SettleAccountDemo.java @@ -1,8 +1,7 @@ package com.jsowell.adapay.demo; import com.alibaba.fastjson.JSON; -import com.huifu.adapay.model.Drawcash; -import com.huifu.adapay.model.SettleAccount; + import java.util.HashMap; import java.util.Map; diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/domain/OrderMonitorData.java b/jsowell-pile/src/main/java/com/jsowell/pile/domain/OrderMonitorData.java new file mode 100644 index 000000000..2d8338f8d --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/domain/OrderMonitorData.java @@ -0,0 +1,43 @@ +package com.jsowell.pile.domain; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.time.LocalDateTime; + +@Getter +@Setter +@ToString +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class OrderMonitorData { + /** + * 主键 + */ + private Integer id; + + /** + * 订单编号 + */ + private String orderCode; + + /** + * 交易流水号 + */ + private String transactionCode; + + /** + * 实时监控数据 + */ + private String monitorData; + + /** + * 创建时间 + */ + private LocalDateTime createTime; +} \ No newline at end of file diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/dto/LianLianGetTokenDTO.java b/jsowell-pile/src/main/java/com/jsowell/pile/dto/LianLianGetTokenDTO.java new file mode 100644 index 000000000..0517e605a --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/dto/LianLianGetTokenDTO.java @@ -0,0 +1,19 @@ +package com.jsowell.pile.dto; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.Data; + +/** + * 联联充电获取令牌 + * + * @author JS-ZZA + * @date 2023/5/9 13:54 + */ +@Data +public class LianLianGetTokenDTO { + @JsonProperty(value = "OperatorID") + private String operatorId; + + @JsonProperty(value = "OperatorSecret") + private String operatorSecret; +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderMonitorDataMapper.java b/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderMonitorDataMapper.java new file mode 100644 index 000000000..fb597f7fd --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/mapper/OrderMonitorDataMapper.java @@ -0,0 +1,37 @@ +package com.jsowell.pile.mapper; + +import com.jsowell.pile.domain.OrderMonitorData; + +public interface OrderMonitorDataMapper { + /** + * delete by primary key + * @param id primaryKey + * @return deleteCount + */ + int deleteByPrimaryKey(Integer id); + + /** + * insert record to table + * @param record the record + * @return insert count + */ + int insert(OrderMonitorData record); + + /** + * insert record to table selective + * @param record the record + * @return insert count + */ + int insertSelective(OrderMonitorData record); + + /** + * select by primary key + * @param id primary key + * @return object by primary key + */ + OrderMonitorData selectByPrimaryKey(Integer id); + + OrderMonitorData selectByOrderCode(String orderCode); + + OrderMonitorData selectByTransactionCode(String transactionCode); +} \ No newline at end of file diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java index 473b8554c..34afc2aa4 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/IOrderBasicInfoService.java @@ -119,6 +119,8 @@ public interface IOrderBasicInfoService { List getListByMemberIdAndOrderStatus(String memberId, List orderStatusList, LocalDateTime dateTime); + void realTimeMonitorDataRedis2DB(String transactionCode, String orderCode); + void updateElecAmount(); /** diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderMonitorDataService.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderMonitorDataService.java new file mode 100644 index 000000000..2ce3c7f04 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/OrderMonitorDataService.java @@ -0,0 +1,18 @@ +package com.jsowell.pile.service; + +import com.jsowell.pile.domain.OrderMonitorData; + +public interface OrderMonitorDataService{ + + int deleteByPrimaryKey(Integer id); + + int insert(OrderMonitorData record); + + int insertSelective(OrderMonitorData record); + + OrderMonitorData selectByPrimaryKey(Integer id); + + OrderMonitorData selectByOrderCode(String orderCode); + + OrderMonitorData selectByTransactionCode(String transactionCode); +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java index f95f78efd..1885e4d98 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderBasicInfoServiceImpl.java @@ -32,6 +32,7 @@ import com.jsowell.common.util.id.SnowflakeIdWorker; import com.jsowell.pile.domain.OrderAbnormalRecord; import com.jsowell.pile.domain.OrderBasicInfo; import com.jsowell.pile.domain.OrderDetail; +import com.jsowell.pile.domain.OrderMonitorData; import com.jsowell.pile.domain.OrderPayRecord; import com.jsowell.pile.domain.PileAuthCard; import com.jsowell.pile.domain.PileBasicInfo; @@ -53,6 +54,7 @@ import com.jsowell.pile.service.IPileAuthCardService; import com.jsowell.pile.service.IPileBasicInfoService; import com.jsowell.pile.service.IPileBillingTemplateService; import com.jsowell.pile.service.IPileConnectorInfoService; +import com.jsowell.pile.service.OrderMonitorDataService; import com.jsowell.pile.service.WechatPayService; import com.jsowell.pile.service.WxpayCallbackRecordService; import com.jsowell.pile.service.WxpayRefundCallbackService; @@ -151,6 +153,9 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { @Autowired private IPileAuthCardService pileAuthCardService; + @Autowired + private OrderMonitorDataService orderMonitorDataService; + /** * 条件查询订单基本信息 * @@ -197,6 +202,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { /** * 通过订单状态和支付状态 转换订单状态描述 + * * @param orderStatus * @param payStatus * @return @@ -620,7 +626,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { orderDetail.setSharpAmount(new BigDecimal(data.getSharpAmount())); } // 计算该时段电费 - BigDecimal multiply = orderDetail.getSharpElectricityPrice().multiply(new BigDecimal(sharpUsedElectricity)).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getSharpElectricityPrice().multiply(new BigDecimal(sharpUsedElectricity)).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -635,7 +641,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { orderDetail.setPeakAmount(new BigDecimal(data.getPeakAmount())); } // 计算该时段电费 - BigDecimal multiply = orderDetail.getPeakElectricityPrice().multiply(new BigDecimal(peakUsedElectricity)).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getPeakElectricityPrice().multiply(new BigDecimal(peakUsedElectricity)).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -650,7 +656,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { orderDetail.setFlatAmount(new BigDecimal(data.getFlatAmount())); } // 计算该时段电费 - BigDecimal multiply = orderDetail.getFlatElectricityPrice().multiply(new BigDecimal(flatUsedElectricity)).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getFlatElectricityPrice().multiply(new BigDecimal(flatUsedElectricity)).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -665,7 +671,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { orderDetail.setValleyAmount(new BigDecimal(data.getValleyAmount())); } // 计算该时段电费 - BigDecimal multiply = orderDetail.getValleyElectricityPrice().multiply(new BigDecimal(valleyUsedElectricity)).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getValleyElectricityPrice().multiply(new BigDecimal(valleyUsedElectricity)).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -692,6 +698,63 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { } catch (Exception e) { logger.error("小程序发送充电停止推送消息 error", e); } + + try { + realTimeMonitorDataRedis2DB(orderBasicInfo.getTransactionCode(), orderBasicInfo.getOrderCode()); + } catch (Exception e) { + logger.error("redis中取出实时记录保存到表 发生异常", e); + } + } + + /** + * 从redis中取出实时记录保存到表中 + * 当订单完成的时候调用 + */ + @Override + public void realTimeMonitorDataRedis2DB(String transactionCode, String orderCode) { + if (StringUtils.isBlank(transactionCode) || StringUtils.isBlank(orderCode)) { + return; + } + // 校验有没有保存过 + OrderMonitorData orderMonitorData = orderMonitorDataService.selectByOrderCode(orderCode); + if (orderMonitorData != null) { + return; + } + List chargingRealTimeData = getChargingRealTimeData(transactionCode); + if (CollectionUtils.isEmpty(chargingRealTimeData)) { + return; + } + List list = Lists.newArrayList(); + for (RealTimeMonitorData data : chargingRealTimeData) { + RealTimeMonitorData build = RealTimeMonitorData.builder() + .outputCurrent(data.getOutputCurrent()) + .outputCurrent(data.getOutputCurrent()) // 电流 + .outputVoltage(data.getOutputVoltage()) // 电压 + .outputPower(data.getOutputPower()) // 功率 + .SOC(data.getSOC()) // soc + .dateTime(data.getDateTime()) // 时间 + .batteryMaxTemperature(data.getBatteryMaxTemperature()) + .chargingAmount(data.getChargingAmount()) + .chargingDegree(data.getChargingDegree()) + .sumChargingTime(data.getSumChargingTime()) + .timeRemaining(data.getTimeRemaining()) + .gunLineTemperature(data.getGunLineTemperature()) + .build(); + list.add(build); + } + + OrderMonitorData record = new OrderMonitorData(); + record.setOrderCode(orderCode); + record.setTransactionCode(transactionCode); + record.setMonitorData(JSONObject.toJSONString(list)); + int insert = orderMonitorDataService.insertSelective(record); + if (insert > 0) { + // 删除redis中缓存 + String pileConnectorCode = transactionCode.substring(0, 16); + String redisKey = CacheConstants.PILE_REAL_TIME_MONITOR_DATA + pileConnectorCode + "_" + transactionCode; + redisCache.deleteObject(redisKey); + } + } @Override @@ -734,7 +797,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { BigDecimal sharpUsedElectricity = orderDetail.getSharpUsedElectricity(); if (sharpUsedElectricity != null) { // 计算该时段电费 - BigDecimal multiply = orderDetail.getSharpElectricityPrice().multiply(sharpUsedElectricity).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getSharpElectricityPrice().multiply(sharpUsedElectricity).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -742,7 +805,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { BigDecimal peakUsedElectricity = orderDetail.getPeakUsedElectricity(); if (peakUsedElectricity != null) { // 计算该时段电费 - BigDecimal multiply = orderDetail.getPeakElectricityPrice().multiply(peakUsedElectricity).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getPeakElectricityPrice().multiply(peakUsedElectricity).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -750,7 +813,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { BigDecimal flatUsedElectricity = orderDetail.getFlatUsedElectricity(); if (flatUsedElectricity != null) { // 计算该时段电费 - BigDecimal multiply = orderDetail.getFlatElectricityPrice().multiply(flatUsedElectricity).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getFlatElectricityPrice().multiply(flatUsedElectricity).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } @@ -758,13 +821,13 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { BigDecimal valleyUsedElectricity = orderDetail.getValleyUsedElectricity(); if (valleyUsedElectricity != null) { // 计算该时段电费 - BigDecimal multiply = orderDetail.getValleyElectricityPrice().multiply(valleyUsedElectricity).setScale(2,BigDecimal.ROUND_DOWN); + BigDecimal multiply = orderDetail.getValleyElectricityPrice().multiply(valleyUsedElectricity).setScale(2, BigDecimal.ROUND_DOWN); totalElectricityAmount = totalElectricityAmount.add(multiply); } orderDetail.setTotalElectricityAmount(totalElectricityAmount); orderDetail.setTotalServiceAmount(orderDetail.getTotalOrderAmount().subtract(totalElectricityAmount)); - }catch (Exception e) { + } catch (Exception e) { logger.info("发生异常", e); } } @@ -882,7 +945,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { orderBasicInfo.setLogicCard(data.getLogicCard()); // 订单状态 (2023.4.6 要求改成“订单完成”) orderBasicInfo.setOrderStatus(OrderStatusEnum.ORDER_COMPLETE.getValue()); - }else { + } else { // 订单状态 可疑 orderBasicInfo.setOrderStatus(OrderStatusEnum.SUSPICIOUS.getValue()); } @@ -1007,6 +1070,15 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { RealTimeMonitorData data = JSONObject.parseObject((String) o, RealTimeMonitorData.class); resultList.add(data); } + } else { + logger.debug("redis中没有实时数据了,去数据库查"); + // redis中为空,去查库 + OrderMonitorData orderMonitorData = orderMonitorDataService.selectByTransactionCode(transactionCode); + if (orderMonitorData != null) { + String monitorData = orderMonitorData.getMonitorData(); + List dataList = JSON.parseArray(monitorData, RealTimeMonitorData.class); + resultList.addAll(dataList); + } } return resultList; } @@ -1320,6 +1392,7 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { /** * 生成订单 返回交易流水号 + * * @param dto * @return */ @@ -1404,22 +1477,24 @@ public class OrderBasicInfoServiceImpl implements IOrderBasicInfoService { /** * 联联平台 获取累计数据用 + * * @param dto * @return */ - @Override - public List getAccumulativeInfoForLianLian(QueryStationInfoDTO dto) { - return orderBasicInfoMapper.getAccumulativeInfoForLianLian(dto); - } + @Override + public List getAccumulativeInfoForLianLian(QueryStationInfoDTO dto) { + return orderBasicInfoMapper.getAccumulativeInfoForLianLian(dto); + } /** * 联联平台生成订单 + * * @param dto * @return */ @Override public Map generateOrderForLianLian(QueryStartChargeDTO dto) { - // 联联平台生成订单 + // 联联平台生成订单 String orderCode = dto.getStartChargeSeq(); String pileConnectorCode = dto.getConnectorID(); String pileSn = StringUtils.substring(pileConnectorCode, 0, 14); diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderMonitorDataServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderMonitorDataServiceImpl.java new file mode 100644 index 000000000..f38fb1782 --- /dev/null +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/OrderMonitorDataServiceImpl.java @@ -0,0 +1,46 @@ +package com.jsowell.pile.service.impl; + +import com.jsowell.pile.domain.OrderMonitorData; +import com.jsowell.pile.mapper.OrderMonitorDataMapper; +import com.jsowell.pile.service.OrderMonitorDataService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +@Service +public class OrderMonitorDataServiceImpl implements OrderMonitorDataService { + + @Resource + private OrderMonitorDataMapper orderMonitorDataMapper; + + @Override + public int deleteByPrimaryKey(Integer id) { + return orderMonitorDataMapper.deleteByPrimaryKey(id); + } + + @Override + public int insert(OrderMonitorData record) { + return orderMonitorDataMapper.insert(record); + } + + @Override + public int insertSelective(OrderMonitorData record) { + return orderMonitorDataMapper.insertSelective(record); + } + + @Override + public OrderMonitorData selectByPrimaryKey(Integer id) { + return orderMonitorDataMapper.selectByPrimaryKey(id); + } + + @Override + public OrderMonitorData selectByOrderCode(String orderCode) { + return orderMonitorDataMapper.selectByOrderCode(orderCode); + } + + @Override + public OrderMonitorData selectByTransactionCode(String transactionCode) { + return orderMonitorDataMapper.selectByTransactionCode(transactionCode); + } + +} diff --git a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileConnectorInfoServiceImpl.java b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileConnectorInfoServiceImpl.java index be7b3c4b0..bda70444c 100644 --- a/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileConnectorInfoServiceImpl.java +++ b/jsowell-pile/src/main/java/com/jsowell/pile/service/impl/PileConnectorInfoServiceImpl.java @@ -467,8 +467,8 @@ public class PileConnectorInfoServiceImpl implements IPileConnectorInfoService { pileConnectorInfoVO.setChargingTime(realTimeMonitorData.getSumChargingTime()); // 已充时长 // 计算实时功率(单位:kw) BigDecimal instantPowerTemp = outputVoltage.multiply(outputCurrent); - BigDecimal instantPower = instantPowerTemp.divide(new BigDecimal(1000)); - pileConnectorInfoVO.setInstantPower(instantPower.setScale(2, BigDecimal.ROUND_HALF_UP)); + BigDecimal instantPower = instantPowerTemp.divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP); + pileConnectorInfoVO.setInstantPower(instantPower); log.info("枪口实时数据:{}", JSONObject.toJSONString(pileConnectorInfoVO)); } diff --git a/jsowell-pile/src/main/resources/mapper/pile/OrderMonitorDataMapper.xml b/jsowell-pile/src/main/resources/mapper/pile/OrderMonitorDataMapper.xml new file mode 100644 index 000000000..d74d5d164 --- /dev/null +++ b/jsowell-pile/src/main/resources/mapper/pile/OrderMonitorDataMapper.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + id, order_code, transaction_code, monitor_data, create_time + + + + + delete from order_monitor_data + where id = #{id,jdbcType=INTEGER} + + + + insert into order_monitor_data (id, order_code, transaction_code, monitor_data, + create_time) + values (#{id,jdbcType=INTEGER}, #{orderCode,jdbcType=VARCHAR}, #{transactionCode,jdbcType=VARCHAR}, #{monitorData,jdbcType=VARCHAR}, + #{createTime,jdbcType=TIMESTAMP}) + + + + insert into order_monitor_data + + + id, + + + order_code, + + + transaction_code, + + + monitor_data, + + + create_time, + + + + + #{id,jdbcType=INTEGER}, + + + #{orderCode,jdbcType=VARCHAR}, + + + #{transactionCode,jdbcType=VARCHAR}, + + + #{monitorData,jdbcType=VARCHAR}, + + + #{createTime,jdbcType=TIMESTAMP}, + + + + + + + + \ No newline at end of file diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/LianLianService.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/LianLianService.java index d616513a2..94a7860c7 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/LianLianService.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/LianLianService.java @@ -1,5 +1,6 @@ package com.jsowell.thirdparty.service; +import com.jsowell.pile.dto.LianLianGetTokenDTO; import com.jsowell.pile.dto.QueryEquipmentDTO; import com.jsowell.pile.dto.QueryStartChargeDTO; import com.jsowell.thirdparty.domain.StationStatsInfo; @@ -16,6 +17,12 @@ public interface LianLianService { */ void pushMerchantInfo(Long merchantId); + /** + * 根据充电站id,推送充电站信息 + * @param stationId + */ + void pushStationInfo(Long stationId) throws Exception; + /** * 联联平台获取充电站信息 * @param dto @@ -67,4 +74,6 @@ public interface LianLianService { * @return */ QueryStopChargeVO query_stop_charge(QueryStartChargeDTO dto); + + String getToken(LianLianGetTokenDTO dto); } diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/impl/LianLianServiceImpl.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/impl/LianLianServiceImpl.java index e4cbda691..a526b1f89 100644 --- a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/impl/LianLianServiceImpl.java +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/service/impl/LianLianServiceImpl.java @@ -1,20 +1,28 @@ package com.jsowell.thirdparty.service.impl; import cn.hutool.core.util.PageUtil; +import cn.hutool.http.HttpUtil; +import cn.hutool.json.JSONUtil; +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONObject; import com.github.pagehelper.PageInfo; import com.google.common.collect.Lists; +import com.jsowell.common.constant.Constants; import com.jsowell.common.core.domain.ykc.RealTimeMonitorData; -import com.jsowell.common.core.redis.RedisCache; import com.jsowell.common.enums.ykc.OrderStatusEnum; import com.jsowell.common.enums.ykc.PileConnectorDataBaseStatusEnum; import com.jsowell.common.exception.BusinessException; -import com.jsowell.common.util.DateUtils; -import com.jsowell.common.util.PageUtils; -import com.jsowell.common.util.StringUtils; +import com.jsowell.common.util.*; +import com.jsowell.common.util.http.HttpUtils; +import com.jsowell.common.util.lianlian.Cryptos; +import com.jsowell.common.util.lianlian.Encodes; +import com.jsowell.common.util.lianlian.GBSignUtils; +import com.jsowell.common.util.lianlian.LianLianUtils; import com.jsowell.netty.command.ykc.StartChargingCommand; import com.jsowell.netty.command.ykc.StopChargingCommand; import com.jsowell.netty.service.yunkuaichong.YKCPushCommandService; import com.jsowell.pile.domain.*; +import com.jsowell.pile.dto.LianLianGetTokenDTO; import com.jsowell.pile.dto.QueryEquipmentDTO; import com.jsowell.pile.dto.QueryStartChargeDTO; import com.jsowell.pile.dto.QueryStationInfoDTO; @@ -27,7 +35,6 @@ import com.jsowell.pile.service.IPileStationInfoService; import com.jsowell.pile.vo.base.ConnectorInfoVO; import com.jsowell.pile.vo.base.MerchantInfoVO; import com.jsowell.pile.vo.lianlian.AccumulativeInfoVO; -import com.jsowell.pile.vo.uniapp.SendMessageVO; import com.jsowell.pile.vo.web.PileConnectorInfoVO; import com.jsowell.pile.vo.web.PileModelInfoVO; import com.jsowell.thirdparty.domain.ConnectorChargeStatusInfo; @@ -47,9 +54,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.math.BigDecimal; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.stream.Collectors; @Service @@ -82,13 +87,81 @@ public class LianLianServiceImpl implements LianLianService { MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfo(String.valueOf(merchantId)); // 组装联联平台所需要的数据格式 OperatorInfo operatorInfo = OperatorInfo.builder() - .OperatorID(merchantInfo.getOrganizationCode()) // 组织机构代码 + .OperatorID(Constants.OPERATORID_LIANLIAN) // 组织机构代码 .OperatorName(merchantInfo.getMerchantName()) // 机构全称 .OperatorTel1(merchantInfo.getMerchantTel()) // 对接平台客服电话1 .build(); // 调用联联平台接口 + } + + /** + * 根据站点id推送站点信息 + * @param stationId + */ + @Override + public void pushStationInfo(Long stationId) throws Exception { + // 通过id查询站点相关信息 + PileStationInfo pileStationInfo = pileStationInfoService.selectPileStationInfoById(stationId); + // 组装联联平台所需要的数据格式 + StationInfo info = StationInfo.builder() + .StationID(String.valueOf(stationId)) + .OperatorID(Constants.OPERATORID_LIANLIAN) + .EquipmentOwnerID(Constants.OPERATORID_LIANLIAN) + .StationName(pileStationInfo.getStationName()) + .IsAloneApply(Integer.valueOf(pileStationInfo.getAloneApply())) + .IsPublicParkingLot(Integer.valueOf(pileStationInfo.getPublicParking())) + .CountryCode(pileStationInfo.getCountryCode()) + .AreaCode(pileStationInfo.getAreaCode()) + .Address(pileStationInfo.getAddress()) + .ServiceTel(pileStationInfo.getServiceTel()) + .StationType(Integer.valueOf(pileStationInfo.getStationType())) + .StationStatus(Integer.valueOf(pileStationInfo.getStationStatus())) + .ParkNums(Integer.valueOf(pileStationInfo.getParkNums())) + .StationLng(new BigDecimal(pileStationInfo.getStationLng())) + .StationLat(new BigDecimal(pileStationInfo.getStationLat())) + .Construction(Integer.valueOf(pileStationInfo.getConstruction())) + .OpenAllDay(Integer.valueOf(pileStationInfo.getOpenAllDay())) + // .MinElectricityPrice() + // .ElectricityFee() + // .ServiceFee() + .ParkFree(Integer.valueOf(pileStationInfo.getParkFree())) + // .ParkFee() + .Payment(pileStationInfo.getPayment()) + .SupportOrder(Integer.valueOf(pileStationInfo.getSupportOrder())) + // .equipmentInfos() + // .ParkFeeType() + .ToiletFlag(Integer.valueOf(pileStationInfo.getToiletFlag())) + .StoreFlag(Integer.valueOf(pileStationInfo.getStoreFlag())) + .RestaurantFlag(Integer.valueOf(pileStationInfo.getRestaurantFlag())) + .LoungeFlag(Integer.valueOf(pileStationInfo.getLoungeFlag())) + .CanopyFlag(Integer.valueOf(pileStationInfo.getCanopyFlag())) + .PrinterFlag(Integer.valueOf(pileStationInfo.getPrinterFlag())) + .BarrierFlag(Integer.valueOf(pileStationInfo.getBarrierFlag())) + .ParkingLockFlag(Integer.valueOf(pileStationInfo.getParkingLockFlag())) + + .build(); + + List pileList = getPileList(pileStationInfo); + if (CollectionUtils.isNotEmpty(pileList)) { + info.setEquipmentInfos(pileList); // 充电设备信息列表 + } + + // 调用联联平台接口 + String url = "http://dataexchange.evchargeonline.com:81/shevcs/v1/" + "notification_stationInfo"; + + JSONObject jsonObject = new JSONObject(); + // Map map = new HashMap<>(); + jsonObject.put("StationInfo", info); + String s = HttpUtils.sendPost(url, jsonObject.toJSONString()); + + System.out.println(s); + + } + + public static void main(String[] args) throws Exception { + } /** @@ -112,8 +185,8 @@ public class LianLianServiceImpl implements LianLianService { for (PileStationInfo pileStationInfo : pageInfo.getList()) { StationInfo stationInfo = new StationInfo(); stationInfo.setStationID(String.valueOf(pileStationInfo.getId())); - MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfo(String.valueOf(pileStationInfo.getMerchantId())); - stationInfo.setOperatorID(merchantInfo.getOrganizationCode()); // 组织机构代码 + // MerchantInfoVO merchantInfo = pileMerchantInfoService.getMerchantInfo(String.valueOf(pileStationInfo.getMerchantId())); + stationInfo.setOperatorID(Constants.OPERATORID_LIANLIAN); // 组织机构代码 stationInfo.setEquipmentOwnerID(String.valueOf(pileStationInfo.getMerchantId())); stationInfo.setStationName(pileStationInfo.getStationName()); stationInfo.setIsAloneApply(Integer.valueOf(pileStationInfo.getAloneApply())); @@ -481,6 +554,60 @@ public class LianLianServiceImpl implements LianLianService { return vo; } + /** + * 获取令牌 + * @param dto + * @return + */ + @Override + public String getToken(LianLianGetTokenDTO dto) { + String operatorId = dto.getOperatorId(); + String operatorSecret = dto.getOperatorSecret(); + String token = ""; + try { + //测试用请求地址 + String requestUrl = "http://testdataexchange.evchargeonline.com:82/shevcs/v1/query_token"; + + //请求data + Map data = new HashMap<>(); + data.put("OperatorID", operatorId); + data.put("OperatorSecret", operatorSecret); + String dataJson = JSONUtil.toJsonStr(data); + + //加密 + byte[] encryptText = Cryptos.aesEncrypt(dataJson.getBytes("UTF-8"), + operatorSecret.getBytes(), operatorSecret.getBytes()); + String strData = Encodes.encodeBase64(encryptText); + + Map request = new LinkedHashMap<>(); + request.put("OperatorID", operatorId); + request.put("Data", strData); + request.put("TimeStamp", System.currentTimeMillis() + ""); + request.put("Seq", "0001"); + + //生成签名 + String sig = GBSignUtils.sign(request, operatorSecret); + request.put("Sig", sig); + + String tokenRequest = JSONUtil.toJsonStr(request); + + String response = HttpUtil.post(requestUrl, tokenRequest); + LianLianResultVO result = JSON.parseObject(response, LianLianResultVO.class); + + if (result.getRet() == 0) { + //解密data + byte[] plainText = Cryptos.aesDecrypt(Encodes.decodeBase64((String) result.getData()), + operatorSecret.getBytes(), operatorSecret.getBytes()); + String dataStr = new String(plainText, "UTF-8"); + Map resultMap = (Map) JSON.parse(dataStr); + token = resultMap.get("AccessToken"); + } + } catch (Exception e) { + return token; + } + return token; + } + // TODO 推送停止充电结果 notification_stop_charge_result // TODO 推送充电订单信息 notification_charge_order_info diff --git a/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/vo/LianLianResultVO.java b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/vo/LianLianResultVO.java new file mode 100644 index 000000000..e861791af --- /dev/null +++ b/jsowell-thirdparty/src/main/java/com/jsowell/thirdparty/vo/LianLianResultVO.java @@ -0,0 +1,43 @@ +package com.jsowell.thirdparty.vo; + +import com.fasterxml.jackson.annotation.JsonProperty; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 联联平台接口返回对象 + * + * @author JS-ZZA + * @date 2023/5/10 8:36 + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class LianLianResultVO { + /** + * 系统错误码 + */ + @JsonProperty("Ret") + int ret = 0; + + /** + * 返回提示信息 + */ + @JsonProperty("Msg") + String msg = ""; + + /** + * 返回结果 + */ + @JsonProperty("Data") + Object data; + + /** + * 签名 + */ + @JsonProperty("Sig") + String sig; +} diff --git a/jsowell-ui/src/components/MapContainer/MapContainer.vue b/jsowell-ui/src/components/MapContainer/MapContainer.vue index 9c158b16e..ea9f29442 100644 --- a/jsowell-ui/src/components/MapContainer/MapContainer.vue +++ b/jsowell-ui/src/components/MapContainer/MapContainer.vue @@ -43,6 +43,7 @@ window._AMapSecurityConfig = { securityJsCode: "829b6b73f84682c2eb982eaa47a745b8", }; export default { + props:['stationLat','stationLng'], data() { return { dialogImageUrl: '', @@ -68,7 +69,6 @@ export default { }; }, methods: { - // 点击搜索按钮 send() { this.searchPlaceInput = this.inputObject.userInput; @@ -76,16 +76,16 @@ export default { // 向表单 site-info传值 bus.$emit("inp", this.searchPlaceInput); }, - queryStationInfo() { - getStation(this.stationId).then((response) => { - this.lat = response.data.stationLat; - this.lng = response.data.stationLng; - console.log(this.lat, this.lng); - this.initMap(this.lat, this.lng); - }); - }, + // queryStationInfo() { + // getStation(this.stationId).then((response) => { + // this.lat = response.data.stationLat; + // this.lng = response.data.stationLng; + // console.log(this.lat, this.lng); + // this.initMap(this.lat, this.lng); + // }); + // }, - initMap(lat, lng) { + initMap() { // console.log(lat, lng); AMapLoader.load({ key: "61436c9c789d301a5b73853d176710cf", // 申请好的Web端开发者Key,首次调用 load 时必填 @@ -97,7 +97,7 @@ export default { //设置地图容器id viewMode: "3D", //是否为3D地图模式 zoom: 15, //初始化地图级别 - center: [+lng, +lat], //初始化地图中心点位置 + center: [+this.stationLng, +this.stationLat], //初始化地图中心点位置 }); // this.map.addControl(new AMap.Geolocation()); // console.log("map", this.map); @@ -105,12 +105,12 @@ export default { this.map.setDefaultCursor("pointer"); // 点标记 let marker = new AMap.Marker({ - position: new AMap.LngLat(+lng, +lat), + position: new AMap.LngLat(+this.stationLng, +this.stationLat), }); // 将创建的点标记添加到已有的地图实例 this.map.add(marker); AMap.plugin("AMap.AutoComplete", function () { - auto = new AMap.AutoComplete(this.autoOptions); + let auto = new AMap.AutoComplete(this.autoOptions); //构造地点查询类 auto.on("select", this.select); }); @@ -170,29 +170,10 @@ export default { } }); }, - onFileChange(e) { - console.log(e,'上传图片') - // 1.获取用户选择的文件列表 - const fileList = e.target.files; - console.log(fileList); - // 2.判断有没有选中图片 - if (fileList.length !== 0) { - // 3.选择了图片 - const reader = new FileReader(); - reader.readAsDataURL(fileList[0]); - // 监听load事件,读取完成触发回调函数 - reader.addEventListener("load", () => { - this.avatar = reader.result; - }); - } else { - // 没有选择图片 - this.avatar = ""; - } - }, }, mounted() { //DOM初始化完成进行地图初始化 - // this.queryStationInfo(); + // this.queryStationInfo() }, created() { // this.send(); diff --git a/jsowell-ui/src/views/homeIndex/homeIndex.vue b/jsowell-ui/src/views/homeIndex/homeIndex.vue index 5251f23a5..2d383d470 100644 --- a/jsowell-ui/src/views/homeIndex/homeIndex.vue +++ b/jsowell-ui/src/views/homeIndex/homeIndex.vue @@ -1,11 +1,61 @@