diff --git a/yudao-module-haoka/yudao-module-haoka-biz/pom.xml b/yudao-module-haoka/yudao-module-haoka-biz/pom.xml index faad50ee8a..40d7789c6c 100644 --- a/yudao-module-haoka/yudao-module-haoka-biz/pom.xml +++ b/yudao-module-haoka/yudao-module-haoka-biz/pom.xml @@ -47,5 +47,13 @@ cn.iocoder.boot yudao-spring-boot-starter-excel + + + + com.mashape.unirest + unirest-java + 1.4.9 + + diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/CreateOrder.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/CreateOrder.java new file mode 100644 index 0000000000..7c56d18e2b --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/CreateOrder.java @@ -0,0 +1,169 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + + +import java.util.*; + +import com.alibaba.fastjson.JSON; +import com.mashape.unirest.http.Unirest; + + +public class CreateOrder { + public static String getStr() { + // 创建 OrderDataEN 对象 + OrderDataEN orderData = new OrderDataEN(); + + // 填充字段 + orderData.agentAccount = "代理商账号"; + orderData.userName = "使用人姓名"; + orderData.userIDNumber = "370102199003072994"; + orderData.businessType = "移动业务"; + orderData.handlingType = "新装主卡"; + + // 填充发票信息 + OrderDataEN.InvoiceInfo invoiceInfo = new OrderDataEN.InvoiceInfo(); + invoiceInfo.invoiceDeliveryMethod = "不需要"; + invoiceInfo.invoiceTitle = ""; + invoiceInfo.email = ""; + orderData.invoiceInfo = invoiceInfo; + + // 填充客户信息 + OrderDataEN.CustomerInfo customerInfo = new OrderDataEN.CustomerInfo(); + customerInfo.customerType = "普通客户"; + customerInfo.customerIDNumber = "445121199609133***"; + customerInfo.customerName = "曾锦鑫"; + customerInfo.customerIDType = "身份证"; + customerInfo.contactPerson = "曾锦鑫"; + customerInfo.contactPhone = "17807688***"; + orderData.customerInfo = customerInfo; + + // 填充接口下单分发账号 + orderData.interfaceDispatchAccount = ""; + orderData.interfaceDispatchAccountName = ""; + orderData.interfaceOrderAccount = "pcesurf"; + + // 填充揽装信息 + OrderDataEN.LiftingInfo liftingInfo = new OrderDataEN.LiftingInfo(); + liftingInfo.liftingStaffNumber = "30296079"; + liftingInfo.assistantStaffNumber = ""; + orderData.liftingInfo = liftingInfo; + + // 填充一次性费用项 + OrderDataEN.OneTimeFee oneTimeFee = new OrderDataEN.OneTimeFee(); + OrderDataEN.OneTimeFee.FeeItem feeItem = new OrderDataEN.OneTimeFee.FeeItem(); + feeItem.paymentMethod = "穗易付"; + feeItem.feeItemName = "预存50得100"; + feeItem.feeItemAmount = "50"; + oneTimeFee.feeItemList = Collections.singletonList(feeItem); + orderData.oneTimeFee = oneTimeFee; + + // 填充月租费用项 + OrderDataEN.MonthlyFee monthlyFee = new OrderDataEN.MonthlyFee(); + OrderDataEN.MonthlyFee.FeeItem monthlyFeeItem = new OrderDataEN.MonthlyFee.FeeItem(); + monthlyFeeItem.feeItemName = "(AI受理)19元星卡+3G+9元通行证"; + monthlyFee.paymentMethod = "现金支付"; + monthlyFee.feeItemList = Collections.singletonList(monthlyFeeItem); + orderData.monthlyFee = monthlyFee; + + // 填充物流信息 + OrderDataEN.LogisticsInfo logisticsInfo = new OrderDataEN.LogisticsInfo(); + logisticsInfo.shippingType = "同德仓发货"; + logisticsInfo.deliveryCompany = "EMS"; + logisticsInfo.deliveryType = "高值服务"; + logisticsInfo.returnOnDeliveryFailure = "否"; + orderData.logisticsInfo = logisticsInfo; + + // 填充移动接入 + OrderDataEN.MobileAccess mobileAccess = new OrderDataEN.MobileAccess(); + mobileAccess.mobileAccessNumber = "随机"; + mobileAccess.uimPhysicalSerialNumber = ""; + mobileAccess.numberType = "主卡"; + mobileAccess.orderType = "新装"; + orderData.mobileAccess = Collections.singletonList(mobileAccess); + + // 填充订单备注 + orderData.orderRemark = ""; + orderData.orderSourceNumber = ""; + + // 填充订购产品 + OrderDataEN.OrderProduct orderProduct = new OrderDataEN.OrderProduct(); + orderProduct.productName = "19元星卡+3G+9元通行证"; + orderProduct.aiCode = "DE58674702734165B55F3BFE402813C5"; + orderProduct.paymentType = "预付费"; + OrderDataEN.OrderProduct.ProductProperty productProperty = new OrderDataEN.OrderProduct.ProductProperty(); + productProperty.propertyName = ""; + productProperty.propertyValue = ""; + orderProduct.propertyList = Collections.singletonList(productProperty); + orderData.orderProduct = orderProduct; + + // 填充配送信息 + OrderDataEN.DeliveryInfo deliveryInfo = new OrderDataEN.DeliveryInfo(); + deliveryInfo.province = "广东省"; + deliveryInfo.city = "潮州市"; + deliveryInfo.district = "潮安县"; + deliveryInfo.detailedAddress = "凤塘镇南门村老农机对面惠信手机"; + deliveryInfo.contactPerson = "曾锦鑫"; + deliveryInfo.contactPhone = "17807688***"; + OrderDataEN.DeliveryInfo.DeliveryProduct deliveryProduct = new OrderDataEN.DeliveryInfo.DeliveryProduct(); + deliveryProduct.productName = "实名卡套YXS471"; + deliveryProduct.productQuantity = "1"; + deliveryProduct.productType = "礼品"; + deliveryInfo.deliveryProduct = Collections.singletonList(deliveryProduct); + orderData.deliveryInfo = deliveryInfo; + + // 打印结果 + System.out.println(orderData); + + OrderDataCN orderDataCN = OrderDataConverter.convertToCN(orderData); + String jsonString = JSON.toJSONString(orderDataCN); + System.out.println(jsonString); + + return jsonString; + } + + public static int idSn = 0; + + public static void main(String[] args) throws Exception { + + String publicKey = + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAok8DnvM2OBwtzNoJb4nA" + + "jn4lgCkSxLyRw5lLiUfsi+40h00CGAC1arvbinTTbtrSnm4YDYlaJwveiOeDKdk0" + + "f2Yglb/8loEbNTqb1OqNxUeM1wYLRBXvAkkZ5fZllajWzFMkoNU/JQ4+T8sMATxm" + + "1d1XRcgM6zlgVwX6siDoLZ5Dm23CTS7SXhyMLtS9cgLefHcOckPQyXoB/IJqb0K1" + + "P0Sk0PE1OSRzpsI9JVzhsSW164fwYpxEbygj9O9JAmAszixwItt2j5zLJ6zRnK3R" + + "OrcAVMN/vpXTN2dCLGZXQrsTK9sAWASzIWTiQRzmnwxsQY7y4u2h+k41n8Z5tw03" + + "wwIDAQAB"; + System.out.println(publicKey); + String data = "{\"order_data\":{\"代理商账号\":\"代理商账号\",\"使用人姓名\":\"使用人姓名\",\"使用人证件号\":\"370102199003072994\",\"业务类型\":\"移动业务\",\"办理类型\":\"新装主卡\",\"发票信息\":{\"发票投递方式\":\"不需要\",\"发票抬头\":\"\",\"电子邮箱\":\"\"},\"客户信息\":{\"客户类型\":\"普通客户\",\"客户证件号码\":\"445121199609133***\",\"客户证件姓名\":\"曾锦鑫\",\"客户证件类型\":\"身份证\",\"联系人\":\"曾锦鑫\",\"联系电话\":\"17807688***\"},\"接口下单分发账号\":\"\",\"接口下单分发账号名称\":\"\",\"接口下单账号\":\"pcesurf\",\"揽装信息\":{\"协销工号\":\"\",\"揽装工号\":\"30296079\"},\"一次性费用项\":{\"费用项列表\":[{\"缴费方式\":\"穗易付\",\"费用项名称\":\"预存50得100\",\"费用项类型\":\"\",\"费用项金额\":\"50\"}]},\"月租费用项\":{\"缴费方式\":\"现金支付\",\"费用项列表\":[{\"费用项名称\":\"(AI受理)19元星卡+3G+9元通行证\"}]},\"物流信息\":{\"发货类型\":\"同德仓发货\",\"受理类型\":\"后置受理\",\"回收资料\":\"\",\"配送公司\":\"EMS\",\"配送失败是否需要回退\":\"否\",\"配送类型\":\"高值服务\"},\"移动接入\":[{\"UIM实物串号\":\"\",\"号码类型\":\"主卡\",\"移动接入号\":\"随机\",\"订购类型\":\"新装\"}],\"订单备注\":\"\",\"订单来源单号\":\"\",\"订购产品\":{\"AI编码\":\"DE58674702734165B55F3BFE402813C5\",\"产品名称\":\"19元星卡+3G+9元通行证\",\"付费类型\":\"预付费\",\"属性列表\":[{\"属性值\":\"\",\"属性名\":\"\"}]},\"配送信息\":{\"区\":\"潮安县\",\"市\":\"潮州市\",\"省\":\"广东省\",\"联系人\":\"曾锦鑫\",\"联系电话\":\"17807688***\",\"详细地址\":\"凤塘镇南门村老农机对面惠信手机\",\"配送产品\":[{\"产品名称\":\"实名卡套YXS471\",\"产品数量\":\"1\",\"产品类型\":\"礼品\"}]}}}"; + // String dataOLD = getStr(); + // System.out.println(dataOLD); + System.out.println("---"+data); + // 获得md5串 + String sign = MD5Utils.md5Digest(data); // OK + System.out.println("MD5--"+sign); + // 获得小写md5串 + sign = sign.toLowerCase(); + System.out.println(sign); + // RSA加密 + byte[] encodedData = RSAUtils.encryptByPublicKey(sign, publicKey); + sign = Base64.getEncoder().encodeToString(encodedData); + System.out.println("签名:"+sign); + //去除换行 + sign = sign.replaceAll("[\\r\\n]", ""); + // sign = getSign(data,publicKey); + System.out.println("签名2 :"+sign); + try { + com.mashape.unirest.http.HttpResponse response = Unirest.post("https://applet.mini189.cn/pgprod/generate?turbo=1") + .header("Content-Type", "application/json") + .header("X-Sign", sign) + .body(data) + .asString(); + System.out.println("调用下单接口[https://applet.mini189.cn/dev/generate?turbo=1]入参:"+data); + System.out.println(" 返回:"+response.getStatus()); + System.out.println(" 返回:"+response.getBody()); + } catch (Exception e) { + System.out.println("调用下单接口异常"+e.getMessage()); + } + } + + +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/MD5Utils.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/MD5Utils.java new file mode 100644 index 0000000000..30b96e7a22 --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/MD5Utils.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +public class MD5Utils { + + /** + * 生成 MD5 哈希值 + * + * @param data 输入的字符串 + * @return 32 位的 MD5 哈希值(小写) + */ + public static String md5Digest(String data) { + try { + // 获取 MD5 实例 + MessageDigest md = MessageDigest.getInstance("MD5"); + // 将输入字符串转换为字节数组 + byte[] inputBytes = data.getBytes(); + // 计算 MD5 哈希值 + byte[] hashBytes = md.digest(inputBytes); + // 将字节数组转换为十六进制字符串 + return bytesToHex(hashBytes); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException("MD5 algorithm not found", e); + } + } + + /** + * 将字节数组转换为十六进制字符串 + * + * @param bytes 字节数组 + * @return 十六进制字符串 + */ + private static String bytesToHex(byte[] bytes) { + StringBuilder hexString = new StringBuilder(); + for (byte b : bytes) { + String hex = Integer.toHexString(0xff & b); + if (hex.length() == 1) { + hexString.append('0'); + } + hexString.append(hex); + } + return hexString.toString(); + } + + // 测试方法 + public static void main(String[] args) { + String data = "Hello, World!"; + String sign = MD5Utils.md5Digest(data); + System.out.println("MD5: " + sign); + } +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataCN.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataCN.java new file mode 100644 index 0000000000..c600bc848a --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataCN.java @@ -0,0 +1,437 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + +import java.util.List; + +public class OrderDataCN { + /** + * 代理商账号 + * 是否必填:N + */ + public String 代理商账号; + + /** + * 使用人姓名 + * 是否必填:N + */ + public String 使用人姓名; + + /** + * 使用人证件号 + * 是否必填:N + */ + public String 使用人证件号; + + /** + * 业务类型 + * 是否必填:Y + * 说明:固定传值,现支持业务类型有: + * 融合业务, 单宽业务, 移动业务, 老用户更换套餐业务, 杂项甩单业务, 政企模板甩单业务, 政企融合业务, 政企移动业务, 政企建档业务, 增值业务, 预付费派卡业务, 后付费派卡业务, 老用户续约业务, 预付费礼包业务, 礼品配送业务, 登录业务, 赋能产品业务, 一户一案业务, 政企一户一案业务 + */ + public String 业务类型; + + /** + * 办理类型 + * 是否必填:N + * 说明:新宽新移, 新宽旧移, 旧宽新移, 旧宽旧移, 新装主卡, 话费充值 + */ + public String 办理类型; + + /** + * 发票信息 + * 是否必填:N + */ + public 发票信息 发票信息; + + /** + * 客户信息 + * 是否必填:N + */ + public 客户信息 客户信息; + + /** + * 接口下单分发账号 + * 是否必填:N + */ + public String 接口下单分发账号; + + /** + * 接口下单分发账号名称 + * 是否必填:N + */ + public String 接口下单分发账号名称; + + /** + * 接口下单账号 + * 是否必填:Y + * 说明:系统的下单账号,私下提供 + */ + public String 接口下单账号; + + /** + * 揽装信息 + * 是否必填:Y + */ + public 揽装信息 揽装信息; + + /** + * 一次性费用项 + * 是否必填:N + */ + public 一次性费用项 一次性费用项; + + /** + * 月租费用项 + * 是否必填:N + */ + public 月租费用项 月租费用项; + + /** + * 物流信息 + * 是否必填:N + */ + public 物流信息 物流信息; + + /** + * 移动接入 + * 是否必填:N + * 说明:移动接入为数组,可以为多个。号码新装时传入,其他时候传空值 + */ + public List<移动接入> 移动接入; + + /** + * 订单备注 + * 是否必填:N + */ + public String 订单备注; + + /** + * 订单来源单号 + * 是否必填:N + */ + public String 订单来源单号; + + /** + * 订购产品 + * 是否必填:Y + */ + public 订购产品 订购产品; + + /** + * 配送信息 + * 是否必填:N + */ + public 配送信息 配送信息; + + // 嵌套类定义 + + public static class 发票信息 { + /** + * 发票投递方式 + * 是否必填:Y + * 说明:[一次性发票],[分月发票],[不需要] + */ + public String 发票投递方式; + + /** + * 发票抬头 + * 是否必填:N + * 说明:发票投递方式=不需要的时候不需要传,其他情况必传 + */ + public String 发票抬头; + + /** + * 电子邮箱 + * 是否必填:N + * 说明:发票投递方式=不需要的时候不需要传,其他情况必传 + */ + public String 电子邮箱; + } + + public static class 客户信息 { + /** + * 客户类型 + * 是否必填:N + * 说明:政企客户或普通客户,默认为普通客户 + */ + public String 客户类型; + + /** + * 客户证件号码 + * 是否必填:Y + */ + public String 客户证件号码; + + /** + * 客户证件姓名 + * 是否必填:Y + */ + public String 客户证件姓名; + + /** + * 客户证件类型 + * 是否必填:Y + * 说明:[身份证],[工商营业执照] + */ + public String 客户证件类型; + + /** + * 联系人 + * 是否必填:Y + * 说明:订单联系人 + */ + public String 联系人; + + /** + * 联系电话 + * 是否必填:Y + * 说明:订单联系电话 + */ + public String 联系电话; + + /** + * 客户证件地址 + * 是否必填:N + */ + public String 客户证件地址; + + /** + * 通讯地址 + * 是否必填:N + */ + public String 通讯地址; + } + + public static class 揽装信息 { + /** + * 揽装工号 + * 是否必填:Y + */ + public String 揽装工号; + + /** + * 协销工号 + * 是否必填:N + */ + public String 协销工号; + } + + public static class 一次性费用项 { + /** + * 费用项列表 + * 是否必填:Y + */ + public List<费用项> 费用项列表; + + public static class 费用项 { + /** + * 缴费方式 + * 是否必填:N + */ + public String 缴费方式; + + /** + * 费用项名称 + * 是否必填:Y + */ + public String 费用项名称; + + /** + * 费用项金额 + * 是否必填:Y + */ + public String 费用项金额; + } + } + + public static class 月租费用项 { + /** + * 缴费方式 + * 是否必填:Y + * 说明:银行划扣, 穗易付, 现金支付, 托收签约, 与已有接入号一致, 原套餐缴费方式 + */ + public String 缴费方式; + + /** + * 费用项列表 + * 是否必填:Y + */ + public List<费用项> 费用项列表; + + public static class 费用项 { + /** + * 费用项名称 + * 是否必填:Y + */ + public String 费用项名称; + } + } + + public static class 物流信息 { + /** + * 发货类型 + * 是否必填:N + * 说明:同德仓发货/代理商自行发货/面对面交付/京东仓发货/京东上门实名,默认:面对面交付 + */ + public String 发货类型; + + /** + * 配送公司 + * 是否必填:N + * 说明:同德仓发货时必传,可选:EMS/京东快递/极兔,非同德仓发货时不传 + */ + public String 配送公司; + + /** + * 配送类型 + * 是否必填:N + * 说明:同德仓发货时必传,普通服务/高值服务,默认:普通服务 + */ + public String 配送类型; + + /** + * 配送失败是否需要回退 + * 是否必填:N + * 说明:同德仓发货时必传,是/否,默认:是,非同德仓发货时不传 + */ + public String 配送失败是否需要回退; + } + + public static class 移动接入 { + /** + * 移动接入号 + * 是否必填:Y + */ + public String 移动接入号; + + /** + * UIM实物串号 + * 是否必填:N + * 说明:旧宽新移,旧宽旧移需要填写 + */ + public String UIM实物串号; + + /** + * 号码类型 + * 是否必填:N + * 说明:[主卡],[副卡1],[副卡2]...,不填默认主卡 + */ + public String 号码类型; + + /** + * 订购类型 + * 是否必填:N + * 说明:[新装],[已有],[携转],默认为新装 + */ + public String 订购类型; + } + + public static class 订购产品 { + /** + * 产品名称 + * 是否必填:Y + */ + public String 产品名称; + + /** + * AI编码 + * 是否必填:N + * 说明:多个用,分隔,下单产品使用 AI 受理时,必传,产品对应 AI 编码找机器人组确认 + */ + public String AI编码; + + /** + * 付费类型 + * 是否必填:N + * 说明:预付费、后付费、其他 + */ + public String 付费类型; + + /** + * 属性列表 + * 是否必填:N + */ + public List<属性> 属性列表; + + public static class 属性 { + /** + * 属性名 + * 是否必填:Y + * 说明:产品属性的中文名,现不需要传属性英文名,会根据中文名查找英文名 + */ + public String 属性名; + + /** + * 属性值 + * 是否必填:Y + * 说明:如果有多个值用,分隔 + */ + public String 属性值; + } + } + + public static class 配送信息 { + /** + * 省 + * 是否必填:Y + */ + public String 省; + + /** + * 市 + * 是否必填:Y + */ + public String 市; + + /** + * 区 + * 是否必填:Y + */ + public String 区; + + /** + * 详细地址 + * 是否必填:Y + * 说明:不含省、市、区,会导致配送地址校验失败 + */ + public String 详细地址; + + /** + * 联系人 + * 是否必填:Y + */ + public String 联系人; + + /** + * 联系电话 + * 是否必填:Y + */ + public String 联系电话; + + /** + * 配送产品 + * 是否必填:N + */ + public List<配送产品> 配送产品; + + public static class 配送产品 { + /** + * 产品名称 + * 是否必填:Y + */ + public String 产品名称; + + /** + * 产品数量 + * 是否必填:Y + */ + public String 产品数量; + + /** + * 产品类型 + * 是否必填:Y + * 说明:礼品, 终端, 号卡 + */ + public String 产品类型; + } + } +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataConverter.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataConverter.java new file mode 100644 index 0000000000..6fef99aa52 --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataConverter.java @@ -0,0 +1,199 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + +import java.util.List; +import java.util.stream.Collectors; + +public class OrderDataConverter { + + public static OrderDataCN convertToCN(OrderDataEN enOrder) { + OrderDataCN cnOrder = new OrderDataCN(); + + // 直接赋值字段 + cnOrder.代理商账号 = enOrder.agentAccount; + cnOrder.使用人姓名 = enOrder.userName; + cnOrder.使用人证件号 = enOrder.userIDNumber; + cnOrder.业务类型 = enOrder.businessType; + cnOrder.办理类型 = enOrder.handlingType; + cnOrder.发票信息 = convertInvoiceInfo(enOrder.invoiceInfo); + cnOrder.客户信息 = convertCustomerInfo(enOrder.customerInfo); + cnOrder.接口下单分发账号 = enOrder.interfaceDispatchAccount; + cnOrder.接口下单分发账号名称 = enOrder.interfaceDispatchAccountName; + cnOrder.接口下单账号 = enOrder.interfaceOrderAccount; + cnOrder.揽装信息 = convertLiftingInfo(enOrder.liftingInfo); + cnOrder.一次性费用项 = convertOneTimeFee(enOrder.oneTimeFee); + cnOrder.月租费用项 = convertMonthlyFee(enOrder.monthlyFee); + cnOrder.物流信息 = convertLogisticsInfo(enOrder.logisticsInfo); + cnOrder.移动接入 = convertMobileAccessList(enOrder.mobileAccess); + cnOrder.订单备注 = enOrder.orderRemark; + cnOrder.订单来源单号 = enOrder.orderSourceNumber; + cnOrder.订购产品 = convertOrderProduct(enOrder.orderProduct); + cnOrder.配送信息 = convertDeliveryInfo(enOrder.deliveryInfo); + + return cnOrder; + } + + private static OrderDataCN.发票信息 convertInvoiceInfo(OrderDataEN.InvoiceInfo enInvoiceInfo) { + if (enInvoiceInfo == null) { + return null; + } + OrderDataCN.发票信息 cnInvoiceInfo = new OrderDataCN.发票信息(); + cnInvoiceInfo.发票投递方式 = enInvoiceInfo.invoiceDeliveryMethod; + cnInvoiceInfo.发票抬头 = enInvoiceInfo.invoiceTitle; + cnInvoiceInfo.电子邮箱 = enInvoiceInfo.email; + return cnInvoiceInfo; + } + + private static OrderDataCN.客户信息 convertCustomerInfo(OrderDataEN.CustomerInfo enCustomerInfo) { + if (enCustomerInfo == null) { + return null; + } + OrderDataCN.客户信息 cnCustomerInfo = new OrderDataCN.客户信息(); + cnCustomerInfo.客户类型 = enCustomerInfo.customerType; + cnCustomerInfo.客户证件号码 = enCustomerInfo.customerIDNumber; + cnCustomerInfo.客户证件姓名 = enCustomerInfo.customerName; + cnCustomerInfo.客户证件类型 = enCustomerInfo.customerIDType; + cnCustomerInfo.联系人 = enCustomerInfo.contactPerson; + cnCustomerInfo.联系电话 = enCustomerInfo.contactPhone; + cnCustomerInfo.客户证件地址 = enCustomerInfo.customerAddress; + cnCustomerInfo.通讯地址 = enCustomerInfo.mailingAddress; + return cnCustomerInfo; + } + + private static OrderDataCN.揽装信息 convertLiftingInfo(OrderDataEN.LiftingInfo enLiftingInfo) { + if (enLiftingInfo == null) { + return null; + } + OrderDataCN.揽装信息 cnLiftingInfo = new OrderDataCN.揽装信息(); + cnLiftingInfo.揽装工号 = enLiftingInfo.liftingStaffNumber; + cnLiftingInfo.协销工号 = enLiftingInfo.assistantStaffNumber; + return cnLiftingInfo; + } + + private static OrderDataCN.一次性费用项 convertOneTimeFee(OrderDataEN.OneTimeFee enOneTimeFee) { + if (enOneTimeFee == null) { + return null; + } + OrderDataCN.一次性费用项 cnOneTimeFee = new OrderDataCN.一次性费用项(); + cnOneTimeFee.费用项列表 = enOneTimeFee.feeItemList.stream() + .map(OrderDataConverter::convertFeeItem) + .collect(Collectors.toList()); + return cnOneTimeFee; + } + + private static OrderDataCN.一次性费用项.费用项 convertFeeItem(OrderDataEN.OneTimeFee.FeeItem enFeeItem) { + if (enFeeItem == null) { + return null; + } + OrderDataCN.一次性费用项.费用项 cnFeeItem = new OrderDataCN.一次性费用项.费用项(); + cnFeeItem.缴费方式 = enFeeItem.paymentMethod; + cnFeeItem.费用项名称 = enFeeItem.feeItemName; + cnFeeItem.费用项金额 = enFeeItem.feeItemAmount; + return cnFeeItem; + } + + private static OrderDataCN.月租费用项 convertMonthlyFee(OrderDataEN.MonthlyFee enMonthlyFee) { + if (enMonthlyFee == null) { + return null; + } + OrderDataCN.月租费用项 cnMonthlyFee = new OrderDataCN.月租费用项(); + cnMonthlyFee.缴费方式 = enMonthlyFee.paymentMethod; + cnMonthlyFee.费用项列表 = enMonthlyFee.feeItemList.stream() + .map(OrderDataConverter::convertMonthlyFeeItem) + .collect(Collectors.toList()); + return cnMonthlyFee; + } + + private static OrderDataCN.月租费用项.费用项 convertMonthlyFeeItem(OrderDataEN.MonthlyFee.FeeItem enFeeItem) { + if (enFeeItem == null) { + return null; + } + OrderDataCN.月租费用项.费用项 cnFeeItem = new OrderDataCN.月租费用项.费用项(); + cnFeeItem.费用项名称 = enFeeItem.feeItemName; + return cnFeeItem; + } + + private static OrderDataCN.物流信息 convertLogisticsInfo(OrderDataEN.LogisticsInfo enLogisticsInfo) { + if (enLogisticsInfo == null) { + return null; + } + OrderDataCN.物流信息 cnLogisticsInfo = new OrderDataCN.物流信息(); + cnLogisticsInfo.发货类型 = enLogisticsInfo.shippingType; + cnLogisticsInfo.配送公司 = enLogisticsInfo.deliveryCompany; + cnLogisticsInfo.配送类型 = enLogisticsInfo.deliveryType; + cnLogisticsInfo.配送失败是否需要回退 = enLogisticsInfo.returnOnDeliveryFailure; + return cnLogisticsInfo; + } + + private static List convertMobileAccessList(List enMobileAccessList) { + if (enMobileAccessList == null) { + return null; + } + return enMobileAccessList.stream() + .map(OrderDataConverter::convertMobileAccess) + .collect(Collectors.toList()); + } + + private static OrderDataCN.移动接入 convertMobileAccess(OrderDataEN.MobileAccess enMobileAccess) { + if (enMobileAccess == null) { + return null; + } + OrderDataCN.移动接入 cnMobileAccess = new OrderDataCN.移动接入(); + cnMobileAccess.移动接入号 = enMobileAccess.mobileAccessNumber; + cnMobileAccess.UIM实物串号 = enMobileAccess.uimPhysicalSerialNumber; + cnMobileAccess.号码类型 = enMobileAccess.numberType; + cnMobileAccess.订购类型 = enMobileAccess.orderType; + return cnMobileAccess; + } + + private static OrderDataCN.订购产品 convertOrderProduct(OrderDataEN.OrderProduct enOrderProduct) { + if (enOrderProduct == null) { + return null; + } + OrderDataCN.订购产品 cnOrderProduct = new OrderDataCN.订购产品(); + cnOrderProduct.产品名称 = enOrderProduct.productName; + cnOrderProduct.AI编码 = enOrderProduct.aiCode; + cnOrderProduct.付费类型 = enOrderProduct.paymentType; + cnOrderProduct.属性列表 = enOrderProduct.propertyList.stream() + .map(OrderDataConverter::convertProductProperty) + .collect(Collectors.toList()); + return cnOrderProduct; + } + + private static OrderDataCN.订购产品.属性 convertProductProperty(OrderDataEN.OrderProduct.ProductProperty enProperty) { + if (enProperty == null) { + return null; + } + OrderDataCN.订购产品.属性 cnProperty = new OrderDataCN.订购产品.属性(); + cnProperty.属性名 = enProperty.propertyName; + cnProperty.属性值 = enProperty.propertyValue; + return cnProperty; + } + + private static OrderDataCN.配送信息 convertDeliveryInfo(OrderDataEN.DeliveryInfo enDeliveryInfo) { + if (enDeliveryInfo == null) { + return null; + } + OrderDataCN.配送信息 cnDeliveryInfo = new OrderDataCN.配送信息(); + cnDeliveryInfo.省 = enDeliveryInfo.province; + cnDeliveryInfo.市 = enDeliveryInfo.city; + cnDeliveryInfo.区 = enDeliveryInfo.district; + cnDeliveryInfo.详细地址 = enDeliveryInfo.detailedAddress; + cnDeliveryInfo.联系人 = enDeliveryInfo.contactPerson; + cnDeliveryInfo.联系电话 = enDeliveryInfo.contactPhone; + cnDeliveryInfo.配送产品 = enDeliveryInfo.deliveryProduct.stream() + .map(OrderDataConverter::convertDeliveryProduct) + .collect(Collectors.toList()); + return cnDeliveryInfo; + } + + private static OrderDataCN.配送信息.配送产品 convertDeliveryProduct(OrderDataEN.DeliveryInfo.DeliveryProduct enDeliveryProduct) { + if (enDeliveryProduct == null) { + return null; + } + OrderDataCN.配送信息.配送产品 cnDeliveryProduct = new OrderDataCN.配送信息.配送产品(); + cnDeliveryProduct.产品名称 = enDeliveryProduct.productName; + cnDeliveryProduct.产品数量 = enDeliveryProduct.productQuantity; + cnDeliveryProduct.产品类型 = enDeliveryProduct.productType; + return cnDeliveryProduct; + } +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataEN.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataEN.java new file mode 100644 index 0000000000..2dbb7a5f2d --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderDataEN.java @@ -0,0 +1,437 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + +import java.util.List; + +public class OrderDataEN { + /** + * 代理商账号 + * 是否必填:N + */ + public String agentAccount; + + /** + * 使用人姓名 + * 是否必填:N + */ + public String userName; + + /** + * 使用人证件号 + * 是否必填:N + */ + public String userIDNumber; + + /** + * 业务类型 + * 是否必填:Y + * 说明:固定传值,现支持业务类型有: + * 融合业务, 单宽业务, 移动业务, 老用户更换套餐业务, 杂项甩单业务, 政企模板甩单业务, 政企融合业务, 政企移动业务, 政企建档业务, 增值业务, 预付费派卡业务, 后付费派卡业务, 老用户续约业务, 预付费礼包业务, 礼品配送业务, 登录业务, 赋能产品业务, 一户一案业务, 政企一户一案业务 + */ + public String businessType; + + /** + * 办理类型 + * 是否必填:N + * 说明:新宽新移, 新宽旧移, 旧宽新移, 旧宽旧移, 新装主卡, 话费充值 + */ + public String handlingType; + + /** + * 发票信息 + * 是否必填:N + */ + public InvoiceInfo invoiceInfo; + + /** + * 客户信息 + * 是否必填:N + */ + public CustomerInfo customerInfo; + + /** + * 接口下单分发账号 + * 是否必填:N + */ + public String interfaceDispatchAccount; + + /** + * 接口下单分发账号名称 + * 是否必填:N + */ + public String interfaceDispatchAccountName; + + /** + * 接口下单账号 + * 是否必填:Y + * 说明:系统的下单账号,私下提供 + */ + public String interfaceOrderAccount; + + /** + * 揽装信息 + * 是否必填:Y + */ + public LiftingInfo liftingInfo; + + /** + * 一次性费用项 + * 是否必填:N + */ + public OneTimeFee oneTimeFee; + + /** + * 月租费用项 + * 是否必填:N + */ + public MonthlyFee monthlyFee; + + /** + * 物流信息 + * 是否必填:N + */ + public LogisticsInfo logisticsInfo; + + /** + * 移动接入 + * 是否必填:N + * 说明:移动接入为数组,可以为多个。号码新装时传入,其他时候传空值 + */ + public List mobileAccess; + + /** + * 订单备注 + * 是否必填:N + */ + public String orderRemark; + + /** + * 订单来源单号 + * 是否必填:N + */ + public String orderSourceNumber; + + /** + * 订购产品 + * 是否必填:Y + */ + public OrderProduct orderProduct; + + /** + * 配送信息 + * 是否必填:N + */ + public DeliveryInfo deliveryInfo; + + // 嵌套类定义 + + public static class InvoiceInfo { + /** + * 发票投递方式 + * 是否必填:Y + * 说明:[一次性发票],[分月发票],[不需要] + */ + public String invoiceDeliveryMethod; + + /** + * 发票抬头 + * 是否必填:N + * 说明:发票投递方式=不需要的时候不需要传,其他情况必传 + */ + public String invoiceTitle; + + /** + * 电子邮箱 + * 是否必填:N + * 说明:发票投递方式=不需要的时候不需要传,其他情况必传 + */ + public String email; + } + + public static class CustomerInfo { + /** + * 客户类型 + * 是否必填:N + * 说明:政企客户或普通客户,默认为普通客户 + */ + public String customerType; + + /** + * 客户证件号码 + * 是否必填:Y + */ + public String customerIDNumber; + + /** + * 客户证件姓名 + * 是否必填:Y + */ + public String customerName; + + /** + * 客户证件类型 + * 是否必填:Y + * 说明:[身份证],[工商营业执照] + */ + public String customerIDType; + + /** + * 联系人 + * 是否必填:Y + * 说明:订单联系人 + */ + public String contactPerson; + + /** + * 联系电话 + * 是否必填:Y + * 说明:订单联系电话 + */ + public String contactPhone; + + /** + * 客户证件地址 + * 是否必填:N + */ + public String customerAddress; + + /** + * 通讯地址 + * 是否必填:N + */ + public String mailingAddress; + } + + public static class LiftingInfo { + /** + * 揽装工号 + * 是否必填:Y + */ + public String liftingStaffNumber; + + /** + * 协销工号 + * 是否必填:N + */ + public String assistantStaffNumber; + } + + public static class OneTimeFee { + /** + * 费用项列表 + * 是否必填:Y + */ + public List feeItemList; + + public static class FeeItem { + /** + * 缴费方式 + * 是否必填:N + */ + public String paymentMethod; + + /** + * 费用项名称 + * 是否必填:Y + */ + public String feeItemName; + + /** + * 费用项金额 + * 是否必填:Y + */ + public String feeItemAmount; + } + } + + public static class MonthlyFee { + /** + * 缴费方式 + * 是否必填:Y + * 说明:银行划扣, 穗易付, 现金支付, 托收签约, 与已有接入号一致, 原套餐缴费方式 + */ + public String paymentMethod; + + /** + * 费用项列表 + * 是否必填:Y + */ + public List feeItemList; + + public static class FeeItem { + /** + * 费用项名称 + * 是否必填:Y + */ + public String feeItemName; + } + } + + public static class LogisticsInfo { + /** + * 发货类型 + * 是否必填:N + * 说明:同德仓发货/代理商自行发货/面对面交付/京东仓发货/京东上门实名,默认:面对面交付 + */ + public String shippingType; + + /** + * 配送公司 + * 是否必填:N + * 说明:同德仓发货时必传,可选:EMS/京东快递/极兔,非同德仓发货时不传 + */ + public String deliveryCompany; + + /** + * 配送类型 + * 是否必填:N + * 说明:同德仓发货时必传,普通服务/高值服务,默认:普通服务 + */ + public String deliveryType; + + /** + * 配送失败是否需要回退 + * 是否必填:N + * 说明:同德仓发货时必传,是/否,默认:是,非同德仓发货时不传 + */ + public String returnOnDeliveryFailure; + } + + public static class MobileAccess { + /** + * 移动接入号 + * 是否必填:Y + */ + public String mobileAccessNumber; + + /** + * UIM实物串号 + * 是否必填:N + * 说明:旧宽新移,旧宽旧移需要填写 + */ + public String uimPhysicalSerialNumber; + + /** + * 号码类型 + * 是否必填:N + * 说明:[主卡],[副卡1],[副卡2]...,不填默认主卡 + */ + public String numberType; + + /** + * 订购类型 + * 是否必填:N + * 说明:[新装],[已有],[携转],默认为新装 + */ + public String orderType; + } + + public static class OrderProduct { + /** + * 产品名称 + * 是否必填:Y + */ + public String productName; + + /** + * AI编码 + * 是否必填:N + * 说明:多个用,分隔,下单产品使用 AI 受理时,必传,产品对应 AI 编码找机器人组确认 + */ + public String aiCode; + + /** + * 付费类型 + * 是否必填:N + * 说明:预付费、后付费、其他 + */ + public String paymentType; + + /** + * 属性列表 + * 是否必填:N + */ + public List propertyList; + + public static class ProductProperty { + /** + * 属性名 + * 是否必填:Y + * 说明:产品属性的中文名,现不需要传属性英文名,会根据中文名查找英文名 + */ + public String propertyName; + + /** + * 属性值 + * 是否必填:Y + * 说明:如果有多个值用,分隔 + */ + public String propertyValue; + } + } + + public static class DeliveryInfo { + /** + * 省 + * 是否必填:Y + */ + public String province; + + /** + * 市 + * 是否必填:Y + */ + public String city; + + /** + * 区 + * 是否必填:Y + */ + public String district; + + /** + * 详细地址 + * 是否必填:Y + * 说明:不含省、市、区,会导致配送地址校验失败 + */ + public String detailedAddress; + + /** + * 联系人 + * 是否必填:Y + */ + public String contactPerson; + + /** + * 联系电话 + * 是否必填:Y + */ + public String contactPhone; + + /** + * 配送产品 + * 是否必填:N + */ + public List deliveryProduct; + + public static class DeliveryProduct { + /** + * 产品名称 + * 是否必填:Y + */ + public String productName; + + /** + * 产品数量 + * 是否必填:Y + */ + public String productQuantity; + + /** + * 产品类型 + * 是否必填:Y + * 说明:礼品, 终端, 号卡 + */ + public String productType; + } + } +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderQuery.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderQuery.java new file mode 100644 index 0000000000..b0bc9a2893 --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/OrderQuery.java @@ -0,0 +1,53 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + +import java.net.URLEncoder; +import java.util.Base64; + +import com.mashape.unirest.http.Unirest; + + +public class OrderQuery { + + public static int idSn = 0; + + public static void main(String[] args) throws Exception { + + String publicKey = + "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAok8DnvM2OBwtzNoJb4nA" + + "jn4lgCkSxLyRw5lLiUfsi+40h00CGAC1arvbinTTbtrSnm4YDYlaJwveiOeDKdk0" + + "f2Yglb/8loEbNTqb1OqNxUeM1wYLRBXvAkkZ5fZllajWzFMkoNU/JQ4+T8sMATxm" + + "1d1XRcgM6zlgVwX6siDoLZ5Dm23CTS7SXhyMLtS9cgLefHcOckPQyXoB/IJqb0K1" + + "P0Sk0PE1OSRzpsI9JVzhsSW164fwYpxEbygj9O9JAmAszixwItt2j5zLJ6zRnK3R" + + "OrcAVMN/vpXTN2dCLGZXQrsTK9sAWASzIWTiQRzmnwxsQY7y4u2h+k41n8Z5tw03" + + "wwIDAQAB"; + + + String data = "{\"route\":\"赋能平台订单查询\",\"代理商账号\":\"v-hzs\",\"使用人证件号\":\"440000000000000000\",\"使用人姓名\":\"黄先生\",\"订单编码\":\"211012093958di4pw44t\"}"; + + String eurl_data = URLEncoder.encode(data, "UTF-8"); + System.out.println(eurl_data); + String url_data = "data="+eurl_data; + // 获得md5串 + String sign = MD5Utils.md5Digest(url_data); + // 获得小写md5串 + sign = sign.toLowerCase(); + System.out.println(sign); + // RSA加密 + byte[] encodedData = RSAUtils.encryptByPublicKey(sign, publicKey); + sign = Base64.getEncoder().encodeToString(encodedData); + System.out.println("签名:"+sign); + //去除换行 + sign = sign.replaceAll("\\r|\\n", ""); + System.out.println("签名2 :"+sign); + try { + com.mashape.unirest.http.HttpResponse response = Unirest.get(" https://applet.mini189.cn/pgprod/query/query-order-info?"+url_data) + .header("Content-Type", "application/json") + .header("X-Sign", sign) + .asString(); + System.out.println("调用下单接口[https://applet.mini189.cn/dev/query/query-order-info]入参:"+data); + System.out.println(" 返回:"+response.getStatus()+response.getBody()); + } catch (Exception e) { + System.out.println("调用下单接口异常"+e.getMessage()); + } + } +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/RSAUtils.java b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/RSAUtils.java new file mode 100644 index 0000000000..fa32072ed6 --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/RSAUtils.java @@ -0,0 +1,216 @@ +package cn.iocoder.yudao.module.haoka.api.guangdong; + +import javax.crypto.Cipher; +import java.security.*; +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.util.Base64; +import java.util.HashMap; +import java.util.Map; + +class RSAUtils { + private static final String KEY_ALGORITHM = "RSA"; + private static final String SIGNATURE_ALGORITHM = "MD5withRSA"; + private static final String PUBLIC_KEY = "RSAPublicKey"; + private static final String PRIVATE_KEY = "RSAPrivateKey"; + + public static byte[] decryptBASE64(String key) { + return Base64.getDecoder().decode(key); + } + + public static String encryptBASE64(byte[] bytes) { + return Base64.getEncoder().encodeToString(bytes); + } + + /** + * 用私钥对信息生成数字签名 + * + * @param data 加密数据字节数组 + * @param privateKey 私钥 + * @return base64数字签名 + * @throws Exception 异常 + */ + public static String sign(byte[] data, String privateKey) throws Exception { + // 解密由base64编码的私钥 + byte[] keyBytes = decryptBASE64(privateKey); + // 构造PKCS8EncodedKeySpec对象 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); + // KEY_ALGORITHM 指定的加密算法 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + // 取私钥匙对象 + PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec); + // 用私钥对信息生成数字签名 + Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); + signature.initSign(priKey); + signature.update(data); + return encryptBASE64(signature.sign()); + } + + /** + * 校验数字签名 + * + * @param data 加密数据字节数组 + * @param publicKey 公钥 + * @param sign base64数字签名 + * @return 校验成功返回true 失败返回false + * @throws Exception 异常 + */ + public static boolean verify(byte[] data, String publicKey, String sign) + throws Exception { + // 解密由base64编码的公钥 + byte[] keyBytes = decryptBASE64(publicKey); + // 构造X509EncodedKeySpec对象 + X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes); + // KEY_ALGORITHM 指定的加密算法 + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + // 取公钥匙对象 + PublicKey pubKey = keyFactory.generatePublic(keySpec); + Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM); + signature.initVerify(pubKey); + signature.update(data); + // 验证签名是否正常 + return signature.verify(decryptBASE64(sign)); + } + + /** + * 通过私钥解密 + * + * @param data 加密数据字节数组 + * @param privateKey 私钥 + * @return 解密后数据字节数组 + * @throws Exception 异常 + **/ + public static byte[] decryptByPrivateKey(byte[] data, String privateKey) + throws Exception { + // 对密钥解密 + byte[] keyBytes = decryptBASE64(privateKey); + // 取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + Key key = keyFactory.generatePrivate(pkcs8KeySpec); + // 对数据解密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(data); + } + + /** + * 通过私钥解密 + * + * @param data 加密数据 + * @param privateKey 私钥 + * @return 解密后数据字节数组 + * @throws Exception 异常 + */ + public static byte[] decryptByPrivateKey(String data, String privateKey) + throws Exception { + return decryptByPrivateKey(decryptBASE64(data), privateKey); + } + + /** + * 通过公钥解密 + * + * @param data 加密数据字节数组 + * @param publicKey 公钥 + * @return 解密后数据字节数组 + * @throws Exception 异常 + */ + public static byte[] decryptByPublicKey(byte[] data, String publicKey) + throws Exception { + // 对密钥解密 + byte[] keyBytes = decryptBASE64(publicKey); + // 取得公钥 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + Key key = keyFactory.generatePublic(x509KeySpec); + // 对数据解密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.DECRYPT_MODE, key); + return cipher.doFinal(data); + } + + /** + * 通过公钥加密 + * + * @param data 加密前数据 + * @param publicKey 公钥 + * @return 加密后数据字节数组 + * @throws Exception 异常 + */ + public static byte[] encryptByPublicKey(String data, String publicKey) + throws Exception { + // 对公钥解密 + byte[] keyBytes = decryptBASE64(publicKey); + // 取得公钥 + X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + Key key = keyFactory.generatePublic(x509KeySpec); + // 对数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(data.getBytes()); + } + + /** + * 通过私钥加密 + * + * @param data 加密前数据字节数组 + * @param privateKey 私钥 + * @return 加密后数据字节数组 + * @throws Exception 异常 + */ + public static byte[] encryptByPrivateKey(byte[] data, String privateKey) + throws Exception { + // 对密钥解密 + byte[] keyBytes = decryptBASE64(privateKey); + // 取得私钥 + PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); + KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM); + Key key = keyFactory.generatePrivate(pkcs8KeySpec); + // 对数据加密 + Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm()); + cipher.init(Cipher.ENCRYPT_MODE, key); + return cipher.doFinal(data); + } + + /** + * 取得私钥 + * + * @param keyMap keyMap + * @return 私钥 + * @throws Exception 异常 + */ + public static String getPrivateKey(Map keyMap) { + Key key = keyMap.get(PRIVATE_KEY); + return encryptBASE64(key.getEncoded()); + } + + /** + * 取得公钥 + * + * @param keyMap keyMap + * @return 公钥 + * @throws Exception 异常 + */ + public static String getPublicKey(Map keyMap) { + Key key = keyMap.get(PUBLIC_KEY); + return encryptBASE64(key.getEncoded()); + } + + /** + * 初始化密钥 + * + * @return keyMap + * @throws Exception 异常 + */ + public static Map initKey() throws Exception { + KeyPairGenerator keyPairGen = KeyPairGenerator + .getInstance(KEY_ALGORITHM); + keyPairGen.initialize(1024); + KeyPair keyPair = keyPairGen.generateKeyPair(); + Map keyMap = new HashMap(2); + keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥 + keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥 + return keyMap; + } +} diff --git a/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/a.json b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/a.json new file mode 100644 index 0000000000..1977a6ac42 --- /dev/null +++ b/yudao-module-haoka/yudao-module-haoka-biz/src/main/java/cn/iocoder/yudao/module/haoka/api/guangdong/a.json @@ -0,0 +1,172 @@ +{ + "data": { + "q": [ + { + "订单编码": "211206153441gwipscrt", + "下单时间": "2021-12-06T15:34:42+08:00", + "订单当前状态": { + "订单状态名称": "待用户号卡实名中", + "订单状态ID": 63, + "订单当前状态|状态更新时间": "2021-12-07T13:13:12+08:00", + "状态备注": "" + }, + "办理业务": { + "业务类型": "移动业务", + "办理业务|办理类型": "新装主卡" + }, + "订单揽装": { + "揽装工号": "30410945", + "揽装人联系电话": "13711111111", + "人员编码": "Y44010061628" + }, + "订购产品": { + "产品名称": "(AI受理)5G畅享129元套餐(小额预存)", + "付费类型": "后付费" + }, + "订购移动电话": [ + { + "移动接入号": "移动接入号", + "UIM实物串号": "UIM实物串号", + "号码类型": "主卡", + "订购类型": "新装", + "预占密码": "30410945" + } + ], + "订单配送方式": { + "发货类型": "同德仓发货", + "配送公司": "EMS", + "配送类型": "普通服务", + "配送失败是否需要回退": "是", + "订单配送方式|受理类型": "前置受理", + "订单配送方式|回收资料": "协议单,业务单(白单签名回收)" + }, + "收件人地址": [ + { + "区": "天河区", + "市": "广州市", + "省": "广东省", + "详细地址": "博汇街6号智汇park-E****" + } + ], + "生成运单": [ + { + "运单号": "1140638417168", + "运单号获取时间": "2021-12-06T15:41:25+08:00", + "妥投时间": "2021-12-07T11:27:27+08:00", + "揽件时间": "2021-12-06T19:07:41+08:00", + "路由详情": [ + "" + ], + "收件联系人": { + "联系电话": "1986669****", + "联系人": "黄*璐" + }, + "联系客户": [ + { + "联系电话": "1986669****", + "联系人": "黄*璐" + } + ], + "下单客户": { + "证件号码": "5110111998****3224", + "证件姓名": "黄*璐", + "证件类型": "身份证", + "下单客户|发票投递方式": "不需要", + "下单客户|发票抬头": "", + "下单客户|客户类型": "普通客户", + "下单客户|电子邮箱": "" + } + } + ] + }, + "extensions": + { + "server_latency": { + "parsing_ns": 611950, + "processing_ns": 4826998, + "encoding_ns": 299859, + "assign_timestamp_ns": 913333, + "total_ns": 7257446 + }, + "txn": { + "start_ts": 104314707 + }, + "metrics": { + "num_uids": { + "City.name": 1, + "City.refProvince": 1, + "County.name": 1, + "IPTV接入号": 0, + "Province.name": 1, + "UIM实物串号": 1, + "_total": 64, + "下单人揽装": 1, + "下单客户": 1, + "下单时间": 1, + "下单网点": 1, + "业务类型": 1, + "产品名称": 1, + "人员编码": 1, + "付费类型": 1, + "办理业务": 1, + "发货类型": 1, + "号码类型": 1, + "固话接入号": 0, + "地址所属": 1, + "地址所属区": 1, + "外部订单号": 0, + "妥投时间": 1, + "宽带接入号": 0, + "拒收时间": 1, + "揽件时间": 1, + "揽装人联系电话": 1, + "揽装姓名": 0, + "揽装工号": 1, + "携转码": 1, + "携转码有效期": 1, + "携转网格": 1, + "收件人地址": 1, + "收件联系人": 1, + "核验意向单号": 1, + "生成运单": 1, + "电信电视接入号": 0, + "移动接入号": 1, + "经办客户": 1, + "网点名称": 0, + "联系人": 0, + "联系人tm": 2, + "联系客户": 1, + "联系电话": 0, + "联系电话tm": 2, + "装机电话": 1, + "订单协销": 1, + "订单当前状态": 1, + "订单揽装": 1, + "订单来源": 1, + "订单来源单号": 0, + "订单状态ID": 1, + "订单状态名称": 1, + "订单编码": 1, + "订单配送方式": 1, + "订购IPTV": 1, + "订购产品": 1, + "订购固话": 1, + "订购宽带": 1, + "订购电信电视": 1, + "订购移动电话": 1, + "订购类型": 1, + "证件号码tm": 1, + "证件姓名tm": 1, + "证件类型": 1, + "详细地址tm": 1, + "路由详情": 1, + "运单号": 1, + "运单号获取时间": 1, + "配送公司": 1, + "配送失败是否需要回退": 1, + "配送类型": 1, + "预占密码": 1 + } + } + } + }