Feat: Api 联通 + 地区整理
This commit is contained in:
parent
aad3d0b5b6
commit
ff6b022eae
|
|
@ -7,7 +7,8 @@ import lombok.Getter;
|
|||
@Getter
|
||||
public enum ApiFrom {
|
||||
LianTong(1L,"联通Api"),
|
||||
GuangZhouDX(2L,"广州电信Api");;
|
||||
GuangZhouDX(2L,"广州电信Api"),
|
||||
HaiNanDX(3L,"海南电信Api");
|
||||
private final Long id;
|
||||
private final String name;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package cn.iocoder.yudao.module.haoka.api;
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.api.hainandianxin.HaiNanDianXinApi;
|
||||
import com.mashape.unirest.http.exceptions.UnirestException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
@Service
|
||||
public class ApiHaiNanDXService extends ApiConfigService {
|
||||
|
||||
public static final String Key_url = "url";
|
||||
public static final String Key_appCode = "appCode";
|
||||
public static final String Key_abilityCod = "abilityCode";
|
||||
public static final String Key_md5Key = "md5Key";
|
||||
public static final String Key_publicKey = "publicKey";
|
||||
public static final String Key_privateKey = "privateKey";
|
||||
|
||||
private HaiNanDianXinApi.HaiNanDianXinApiConfig getConfig() {
|
||||
Map<String, String> devConfig = this.getDevConfig(ApiFrom.HaiNanDX);
|
||||
|
||||
String url = devConfig.get(Key_url);
|
||||
String appCode = devConfig.get(Key_appCode);
|
||||
String abilityCode = devConfig.get(Key_abilityCod);
|
||||
String md5Key = devConfig.get(Key_md5Key);
|
||||
String publicKey = devConfig.get(Key_publicKey);
|
||||
String privateKey = devConfig.get(Key_privateKey);
|
||||
HaiNanDianXinApi.HaiNanDianXinApiConfig config = new HaiNanDianXinApi.HaiNanDianXinApiConfig();
|
||||
config.setUrl(url);
|
||||
config.setAppCode(appCode);
|
||||
config.setAbilityCode(abilityCode);
|
||||
config.setMd5Key(md5Key);
|
||||
config.setPublicKey(publicKey);
|
||||
config.setPrivateKey(privateKey);
|
||||
return config;
|
||||
}
|
||||
|
||||
public HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.QryNbrListResponse>
|
||||
qryNbrList(HaiNanDianXinApi.QryNbrListRequest param) throws UnirestException {
|
||||
return HaiNanDianXinApi.qryNbrList(this.getConfig(), param);
|
||||
}
|
||||
|
||||
public HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.FraudCheckResponse>
|
||||
fraudCheck(HaiNanDianXinApi.FraudCheckRequest param) throws UnirestException {
|
||||
return HaiNanDianXinApi.fraudCheck(this.getConfig(), param);
|
||||
}
|
||||
|
||||
public HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.QueryOrderInfoResponse>
|
||||
queryOrderInfo(HaiNanDianXinApi.QueryOrderInfoRequest param) throws UnirestException {
|
||||
return HaiNanDianXinApi.queryOrderInfo(this.getConfig(), param);
|
||||
}
|
||||
|
||||
public HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.GetLogisticsTrajectoryResponse>
|
||||
getLogisticsTrajectory(HaiNanDianXinApi.GetLogisticsTrajectoryRequest param) throws UnirestException {
|
||||
return HaiNanDianXinApi.getLogisticsTrajectory(this.getConfig(), param);
|
||||
}
|
||||
|
||||
public HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.SynOrderInfoResponse>
|
||||
synOrderInfo(HaiNanDianXinApi.SynOrderInfoRequest param) throws UnirestException {
|
||||
return HaiNanDianXinApi.synOrderInfo(this.getConfig(), param);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,341 @@
|
|||
package cn.iocoder.yudao.module.haoka.api.hainandianxin;
|
||||
|
||||
import cn.iocoder.yudao.module.haoka.api.liantong.util.StringUtils;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.alibaba.fastjson.TypeReference;
|
||||
import com.mashape.unirest.http.HttpResponse;
|
||||
import com.mashape.unirest.http.Unirest;
|
||||
import com.mashape.unirest.http.exceptions.UnirestException;
|
||||
import lombok.Data;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
|
||||
/**
|
||||
* 海南电信互联网支撑平台号卡接口工具类
|
||||
*/
|
||||
public class HaiNanDianXinApi {
|
||||
|
||||
|
||||
@Data
|
||||
public static class HaiNanDianXinApiConfig {
|
||||
private String url = "https://openeop.dcoos.189.cn:8100/serviceAgent/rest/uop-web/executeEnhanced";
|
||||
private String appCode = "your_app_code"; // 合作商编码,由海南电信互联网支撑平台提供
|
||||
private String abilityCode = "your_ability_code"; // 能力编码,由海南电信互联网支撑平台提供
|
||||
private String md5Key = "your_md5_key"; // 平台分配的密钥
|
||||
private String publicKey = "your_rsa_public_key"; // RSA加密公钥
|
||||
private String privateKey = ""; // RSA 私钥
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class HaiNanResponseInfo<T> {
|
||||
private T data;
|
||||
private String biz;
|
||||
private String code;
|
||||
private String errMsg;
|
||||
private String resTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成 x-auth 请求头
|
||||
*
|
||||
* @param abilityCode 能力编码
|
||||
* @param requestBody 请求体(未加密的原始 JSON 字符串)
|
||||
* @return x-auth 请求头
|
||||
*/
|
||||
private static String generateXAuthHeader(HaiNanDianXinApiConfig config, String abilityCode, String requestBody) {
|
||||
SimpleDateFormat dtf = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String reqTime = dtf.format(new Date());
|
||||
String transactionId = config.appCode + abilityCode + reqTime + UUID.randomUUID().toString().replace("-", "");
|
||||
String sign = UopMD5Utils.encryptByMD5_utf8(config.appCode + abilityCode + transactionId + config.md5Key + requestBody).toLowerCase();
|
||||
return config.appCode + ";" + abilityCode + ";" + transactionId + ";" + sign + ";" + reqTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* 防诈校验接口查询
|
||||
*
|
||||
* @param request 防诈校验请求参数
|
||||
* @return 防诈校验返回结果
|
||||
* @throws UnirestException 请求异常
|
||||
*/
|
||||
public static HaiNanResponseInfo<FraudCheckResponse> fraudCheck(HaiNanDianXinApiConfig config, FraudCheckRequest request) throws UnirestException {
|
||||
return doPost(config, "fraudCheck", request, FraudCheckResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 号码查询列表
|
||||
*
|
||||
* @param request 号码查询列表请求参数
|
||||
* @return 号码查询列表返回结果
|
||||
* @throws UnirestException 请求异常
|
||||
*/
|
||||
public static HaiNanResponseInfo<QryNbrListResponse> qryNbrList(HaiNanDianXinApiConfig config, QryNbrListRequest request) throws UnirestException {
|
||||
return doPost(config, "qryNbrList", request, QryNbrListResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单信息查询
|
||||
*
|
||||
* @param request 订单信息查询请求参数
|
||||
* @return 订单信息查询返回结果
|
||||
* @throws UnirestException 请求异常
|
||||
*/
|
||||
public static HaiNanResponseInfo<QueryOrderInfoResponse> queryOrderInfo(HaiNanDianXinApiConfig config, QueryOrderInfoRequest request) throws UnirestException {
|
||||
return doPost(config, "queryOrderInfo", request, QueryOrderInfoResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流轨迹查询
|
||||
*
|
||||
* @param request 物流轨迹查询请求参数
|
||||
* @return 物流轨迹查询返回结果
|
||||
* @throws UnirestException 请求异常
|
||||
*/
|
||||
public static HaiNanResponseInfo<GetLogisticsTrajectoryResponse> getLogisticsTrajectory(HaiNanDianXinApiConfig config, GetLogisticsTrajectoryRequest request) throws UnirestException {
|
||||
return doPost(config, "getLogisticsTrajectory", request, GetLogisticsTrajectoryResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 号卡订单收敛
|
||||
*
|
||||
* @param request 号卡订单收敛请求参数
|
||||
* @return 号卡订单收敛返回结果
|
||||
* @throws UnirestException 请求异常
|
||||
*/
|
||||
public static HaiNanResponseInfo<SynOrderInfoResponse> synOrderInfo(HaiNanDianXinApiConfig config, SynOrderInfoRequest request) throws UnirestException {
|
||||
return doPost(config, "synOrderInfo", request, SynOrderInfoResponse.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用 POST 请求方法
|
||||
*
|
||||
* @param method 接口方法名
|
||||
* @param param 请求参数
|
||||
* @param rClass 返回结果类型
|
||||
* @param <R> 返回结果泛型
|
||||
* @param <P> 请求参数泛型
|
||||
* @return 返回结果
|
||||
* @throws UnirestException 请求异常
|
||||
*/
|
||||
private static <R, P> HaiNanResponseInfo<R> doPost(HaiNanDianXinApiConfig config, String method, P param, Class<R> rClass) throws UnirestException {
|
||||
String jsonString = JSON.toJSONString(param);
|
||||
String encryptedBody = UopRSAUtils.encryptByPublicKey(jsonString, config.publicKey);
|
||||
String xAuthHeader = generateXAuthHeader(config, method, jsonString);
|
||||
HttpResponse<String> response = Unirest.post(config.url)
|
||||
.header("Content-Type", "application/json")
|
||||
.header("x-auth", xAuthHeader)
|
||||
.body(encryptedBody)
|
||||
.asString();
|
||||
return dealResponse(response, rClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理响应结果
|
||||
*
|
||||
* @param response HTTP 响应
|
||||
* @param tClass 返回结果类型
|
||||
* @param <T> 返回结果泛型
|
||||
* @return 返回结果
|
||||
*/
|
||||
private static <T> HaiNanResponseInfo<T> dealResponse(HttpResponse<String> response, Class<T> tClass) {
|
||||
// int status = response.getStatus();
|
||||
// if (status != 200) {
|
||||
// return null;
|
||||
// }
|
||||
String body = response.getBody();
|
||||
|
||||
HaiNanResponseInfo<T> haiNanResponseInfo = JSON.parseObject(body, new TypeReference<HaiNanResponseInfo<T>>() {
|
||||
});
|
||||
String biz = haiNanResponseInfo.getBiz();
|
||||
if (StringUtils.isNotEmpty(biz)) {
|
||||
String bizDecrypt = UopRSAUtils.decryptByPrivateKey(body, biz);
|
||||
// T t = JSON.parseObject(bizDecrypt, tClass);
|
||||
T t = JSON.parseObject(body, new TypeReference<T>() {
|
||||
});
|
||||
haiNanResponseInfo.setData(t);
|
||||
}
|
||||
|
||||
|
||||
return haiNanResponseInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 防诈校验请求参数类
|
||||
*/
|
||||
@Data
|
||||
public static class FraudCheckRequest {
|
||||
private String custName; // 客户名称
|
||||
private String custCertNo; // 身份证号
|
||||
private String province; // 省份(如:海南省)
|
||||
private String city; // 市(如:海口市)
|
||||
private String county; // 区县(如:龙华区)
|
||||
private String street; // 街道(如:龙华街道)
|
||||
private String detailedAddr; // 详细地址
|
||||
private String consignee; // 收货人
|
||||
private String receiContact; // 收货联系手机号
|
||||
private String scenarioCode; // 场景编码
|
||||
}
|
||||
|
||||
/**
|
||||
* 防诈校验返回结果类
|
||||
*/
|
||||
@Data
|
||||
public static class FraudCheckResponse {
|
||||
private String code; // 状态编码:0:校验通过,可以下单;其他:校验不通过,不能下单
|
||||
private String errMsg; // 失败原因
|
||||
private String biz; // 成功返回报文
|
||||
private String resTime; // 请求返回时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 号码查询列表请求参数类
|
||||
*/
|
||||
@Data
|
||||
public static class QryNbrListRequest {
|
||||
private String goodsId; // 商品编码
|
||||
}
|
||||
|
||||
/**
|
||||
* 号码查询列表返回结果类
|
||||
*/
|
||||
@Data
|
||||
public static class QryNbrListResponse {
|
||||
private String code; // 结果编码 2000 成功 1400 无效的销售品 id 9996 其他异常
|
||||
private String errMsg; // 相关信息说明
|
||||
private String biz; // 成功返回报文
|
||||
private String resTime; // 请求返回时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单信息查询请求参数类
|
||||
*/
|
||||
@Data
|
||||
public static class QueryOrderInfoRequest {
|
||||
private String queryType; // 查询类型(1:电渠业务订单号;2:接入方信息)
|
||||
private String orderCode; // 电渠业务订单号
|
||||
private String openNo; // 第三方流水号(查询类型为2时必填)
|
||||
private String devStaffCode; // 发展工号(查询类型为2时必填)
|
||||
private String devMobile; // 发展手机号(查询类型为2时必填)
|
||||
}
|
||||
|
||||
/**
|
||||
* 订单信息查询返回结果类
|
||||
*/
|
||||
@Data
|
||||
public static class QueryOrderInfoResponse {
|
||||
private String code; // 状态编码:0:成功;-1:失败
|
||||
private String errMsg; // 失败原因
|
||||
private String biz; // 成功返回报文
|
||||
private String resTime; // 请求返回时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流轨迹查询请求参数类
|
||||
*/
|
||||
@Data
|
||||
public static class GetLogisticsTrajectoryRequest {
|
||||
private String orderCode; // 订单编码
|
||||
private String logisticNbr; // 物流单号
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流轨迹查询返回结果类
|
||||
*/
|
||||
@Data
|
||||
public static class GetLogisticsTrajectoryResponse {
|
||||
private String code; // 状态编码:0:成功,返回0既是代表有物流轨迹返回,否则无
|
||||
private String errMsg; // 失败原因
|
||||
private String biz; // 成功返回报文
|
||||
private String resTime; // 请求返回时间
|
||||
}
|
||||
|
||||
/**
|
||||
* 产品信息类
|
||||
*/
|
||||
@Data
|
||||
public static class OrderProdInst {
|
||||
public String prodName; // 产品名称
|
||||
public String prodInstAct; // 产品动作:ADD/DEL/EDIT
|
||||
}
|
||||
|
||||
/**
|
||||
* 物流信息类
|
||||
*/
|
||||
@Data
|
||||
public static class OrderLogisticInfo {
|
||||
public String receiverName; // 收货人
|
||||
public String receiverAddr; // 收获地址(寄送地址)
|
||||
public String receiverPhone; // 收获人电话(联系电话)
|
||||
public String receiverType; // 收货方式(10:物流寄送;11:面对面;12:送货上门;13:京东到家;14:京东配送;不传默认为10)
|
||||
public String provinceAddr; // 省级地址(收货方式为13、14时必填)
|
||||
public String cityAddr; // 市级地址(收货方式为13、14时必填)
|
||||
public String areaAddr; // 区县地址(收货方式为13、14时必填)
|
||||
public String streetAddr; // 城镇/街道地址
|
||||
}
|
||||
|
||||
/**
|
||||
* 客户信息类
|
||||
*/
|
||||
@Data
|
||||
public static class OrderBusiInfo {
|
||||
public String custName; // 入网姓名
|
||||
public String custCertType; // 入网证件类型:默认10 身份证号码
|
||||
public String custCertNo; // 入网证件号码
|
||||
public String custAddr; // 入网证件地址
|
||||
public String accNbr; // 入网号码(要送当前办理的业务号码),宽带新装无需该节点
|
||||
public String regionAddr; // 所在省 / 市 / 县
|
||||
public String detailAddr; // 详细地址(装机地址)
|
||||
public String jthtNo; // 集团活体流水,接入方有能力接入集团情况,才需要提供
|
||||
public String openId; // 微信openId
|
||||
public String addrId; // 地址Id(宽带新装实时单需传值,调用5.15、5.16接口获取)
|
||||
public String exchId; // 支局Id(宽带新装实时单需传值,调用5.15、5.16接口获取)
|
||||
public String measureId; // 测量室Id(宽带新装实时单需传值,调用5.15、5.16接口获取)
|
||||
public String townFlag; // 城乡标识(宽带新装实时单需传值,调用5.15、5.16接口获取)
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付信息类
|
||||
*/
|
||||
@Data
|
||||
public static class OrderPayInfo {
|
||||
public String ordPayType; // 支付类型 10、微信 11、支付宝 12、翼支付 13、银行卡 14、打入话费
|
||||
public String ordPayMethod; // 支付方法(宽带新装传11) 10、在线支付 11、先装后付 12、话费抵扣
|
||||
public String ordPayMoney; // 支付金额
|
||||
public String ordPayStatus; // 支付状态(1000:待支付 1100:已支付)
|
||||
}
|
||||
|
||||
/**
|
||||
* 号卡订单收敛请求参数类
|
||||
*/
|
||||
@Data
|
||||
public static class SynOrderInfoRequest {
|
||||
private String orderType; // 订单类型,28:新装天翼(实时),26:宽带新装(甩单)
|
||||
private String orderAmount; // 订购金额(分)
|
||||
private String openNo; // 第三方流水
|
||||
private String statusCd; // 流程环节(宽带新装预约单传1500,宽带新装实时单传3100)
|
||||
private String orderDate; // 受理时间yyyy-mm-dd HH:mm:ss
|
||||
private String orderArea; // 订单区域, 海南目前默认只有一个本地网460
|
||||
private OrderProdInst orderProdInst; // 订购的产品信息
|
||||
private OrderLogisticInfo orderLogisticInfo; // 物流信息
|
||||
private OrderBusiInfo orderBusiInfo; // 客户信息
|
||||
private OrderPayInfo orderPayInfo; // 支付信息
|
||||
private String busiScenarioCode; // 场景编码
|
||||
private String devStaffCode; // 发展工号
|
||||
private String devMobile; // 发展手机号
|
||||
private String remark; // 订单备注
|
||||
}
|
||||
|
||||
/**
|
||||
* 号卡订单收敛返回结果类
|
||||
*/
|
||||
@Data
|
||||
public static class SynOrderInfoResponse {
|
||||
private String resultCode; // 1000:成功 其他值:失败
|
||||
private String codeMessage; // 原因(失败时返回)
|
||||
private String orderCode; // 订单编码(成功时返回)
|
||||
private String orderSerialNo; // 外系统单号(代理商不需要)
|
||||
private String preOrderNo; // 外系统单号(代理商不需要)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,164 @@
|
|||
package cn.iocoder.yudao.module.haoka.api.hainandianxin;
|
||||
|
||||
import java.security.MessageDigest;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author LAIYONGMIN@FFCS.CN
|
||||
* @ClassName: UOPMD5Utils
|
||||
* @Description: MD5工具类
|
||||
* @date 2017年9月4日 上午9:57:15
|
||||
*/
|
||||
public class UopMD5Utils {
|
||||
|
||||
/**
|
||||
* MD5 加密
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static String encryptByMD5(String src) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(src.getBytes());
|
||||
return byte2hex(md5.digest());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二进制转十六进制
|
||||
*
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
private static String byte2hex(byte[] b) {
|
||||
String hs = "";
|
||||
String stmp = "";
|
||||
for (int n = 0; n < b.length; n++) {
|
||||
stmp = (Integer.toHexString(b[n] & 0XFF));
|
||||
if (stmp.length() == 1) {
|
||||
hs = hs + "0" + stmp;
|
||||
} else {
|
||||
hs = hs + stmp;
|
||||
}
|
||||
}
|
||||
return hs.toUpperCase();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
String appCode = "nblh";
|
||||
String abilityCode = "checkWaistOrder";
|
||||
SimpleDateFormat dtf = new SimpleDateFormat("yyyyMMddHHmmss");
|
||||
String transactionId = appCode + abilityCode + dtf.format(new Date()) + UUID.randomUUID();
|
||||
String md5Key = "密钥";
|
||||
String uri = "/agent/openapi/waist/check";
|
||||
String body = "{\"cityCode\": \"002034001\",\"contactNumber\": \"15858333480\",\"countyCode\": \"002034001005\",\"custCertNo\": \"113405196802181122\",\"custName\": \"华云\",\"detailAddr\": \"广州塔大厦llq04s6d\",\"provinceCode\": \"002034\",\"saleNo\": \"1043\",\"supplierCode\": \"nxdx\"}";
|
||||
String origin = appCode + abilityCode + transactionId + md5Key + uri + body;
|
||||
System.out.println(origin);
|
||||
String sign1 = UopMD5Utils.encryptByMD5_utf8(origin).toLowerCase(Locale.ROOT);
|
||||
System.out.println(sign1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* MD5 加密
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static String encryptByMD5_utf8(String src) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update(src.getBytes("UTF-8"));
|
||||
return byte2hex(md5.digest());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 小程序支付生成MD5工具
|
||||
*/
|
||||
private static class MD5Util {
|
||||
private static String byteArrayToHexString(byte b[]) {
|
||||
StringBuffer resultSb = new StringBuffer();
|
||||
for (int i = 0; i < b.length; i++) {
|
||||
resultSb.append(byteToHexString(b[i]));
|
||||
}
|
||||
return resultSb.toString();
|
||||
}
|
||||
|
||||
private static String byteToHexString(byte b) {
|
||||
int n = b;
|
||||
if (n < 0) {
|
||||
n += 256;
|
||||
}
|
||||
int d1 = n / 16;
|
||||
int d2 = n % 16;
|
||||
return hexDigits[d1] + hexDigits[d2];
|
||||
}
|
||||
|
||||
public static String MD5Encode(String origin, String charsetname) {
|
||||
String resultString = null;
|
||||
try {
|
||||
resultString = new String(origin);
|
||||
MessageDigest md = MessageDigest.getInstance("MD5");
|
||||
if (charsetname == null || "".equals(charsetname)) {
|
||||
resultString = byteArrayToHexString(md.digest(resultString
|
||||
.getBytes()));
|
||||
} else {
|
||||
resultString = byteArrayToHexString(md.digest(resultString
|
||||
.getBytes(charsetname)));
|
||||
}
|
||||
} catch (Exception exception) {
|
||||
}
|
||||
return resultString;
|
||||
}
|
||||
|
||||
private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5",
|
||||
"6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
|
||||
|
||||
}
|
||||
|
||||
public static String MD5min(String str) {
|
||||
String result = "";
|
||||
try {
|
||||
MessageDigest md5 = MessageDigest.getInstance("MD5");
|
||||
md5.update((str).getBytes("UTF-8"));
|
||||
byte b[] = md5.digest();
|
||||
|
||||
int i;
|
||||
StringBuffer buf = new StringBuffer("");
|
||||
|
||||
for (int offset = 0; offset < b.length; offset++) {
|
||||
i = b[offset];
|
||||
if (i < 0) {
|
||||
i += 256;
|
||||
}
|
||||
if (i < 16) {
|
||||
buf.append("0");
|
||||
}
|
||||
buf.append(Integer.toHexString(i));
|
||||
}
|
||||
result = buf.toString();
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
package cn.iocoder.yudao.module.haoka.api.hainandianxin;
|
||||
|
||||
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.*;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.util.Base64;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @Description: RSA加解密工具类
|
||||
* @Author: ffchenxiaodong
|
||||
* @Date: 2023/1/27 10:12
|
||||
* @Vsersion: 1.0
|
||||
*/
|
||||
public class UopRSAUtils {
|
||||
|
||||
/**
|
||||
* 定义加密方式
|
||||
*/
|
||||
public static final String KEY_RSA = "RSA";
|
||||
|
||||
/**
|
||||
* 定义公钥关键词
|
||||
*/
|
||||
public static final String KEY_RSA_PUBLICKEY = "RSAPublicKey";
|
||||
|
||||
/**
|
||||
* 定义私钥关键词
|
||||
*/
|
||||
public static final String KEY_RSA_PRIVATEKEY = "RSAPrivateKey";
|
||||
|
||||
/**
|
||||
* **
|
||||
* RSA最大加密大小
|
||||
*/
|
||||
private final static int MAX_ENCRYPT_BLOCK = 117;
|
||||
|
||||
/**
|
||||
* **
|
||||
* RSA最大解密大小
|
||||
*/
|
||||
private final static int MAX_DECRYPT_BLOCK = 128;
|
||||
|
||||
|
||||
/**
|
||||
* 公钥加密
|
||||
*
|
||||
* @param encryptingStr
|
||||
* @param publicKeyStr
|
||||
* @return
|
||||
*/
|
||||
public static String encryptByPublicKey(String encryptingStr, String publicKeyStr) {
|
||||
try {
|
||||
// 将公钥由字符串转为UTF-8格式的字节数组
|
||||
byte[] publicKeyBytes = decryptBASE64(publicKeyStr);
|
||||
// 获得公钥
|
||||
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
|
||||
// 取得待加密数据
|
||||
byte[] data = encryptingStr.getBytes("UTF-8");
|
||||
KeyFactory factory;
|
||||
factory = KeyFactory.getInstance(KEY_RSA);
|
||||
PublicKey publicKey = factory.generatePublic(keySpec);
|
||||
// 对数据加密
|
||||
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
|
||||
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
|
||||
// 返回加密后由Base64编码的加密信息
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_ENCRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return replaceBlank(encryptBASE64(decryptedData));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 私钥解密
|
||||
*
|
||||
* @param encryptedStr
|
||||
* @param privateKeyStr
|
||||
* @return
|
||||
*/
|
||||
public static String decryptByPrivateKey(String encryptedStr, String privateKeyStr) {
|
||||
try {
|
||||
// 对私钥解密
|
||||
byte[] privateKeyBytes = decryptBASE64(privateKeyStr);
|
||||
// 获得私钥
|
||||
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
|
||||
// 获得待解密数据
|
||||
byte[] data = decryptBASE64(encryptedStr);
|
||||
KeyFactory factory = KeyFactory.getInstance(KEY_RSA);
|
||||
PrivateKey privateKey = factory.generatePrivate(keySpec);
|
||||
// 对数据解密
|
||||
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
|
||||
cipher.init(Cipher.DECRYPT_MODE, privateKey);
|
||||
// 返回UTF-8编码的解密信息
|
||||
int inputLen = data.length;
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
int offSet = 0;
|
||||
byte[] cache;
|
||||
int i = 0;
|
||||
// 对数据分段解密
|
||||
while (inputLen - offSet > 0) {
|
||||
if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
|
||||
cache = cipher.doFinal(data, offSet, MAX_DECRYPT_BLOCK);
|
||||
} else {
|
||||
cache = cipher.doFinal(data, offSet, inputLen - offSet);
|
||||
}
|
||||
out.write(cache, 0, cache.length);
|
||||
i++;
|
||||
offSet = i * MAX_DECRYPT_BLOCK;
|
||||
}
|
||||
byte[] decryptedData = out.toByteArray();
|
||||
out.close();
|
||||
return replaceBlank(new String(decryptedData, "UTF-8"));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 解决编码问题,去掉换行
|
||||
* @param str
|
||||
* @return
|
||||
*/
|
||||
public static String replaceBlank(String str) {
|
||||
String dest = "";
|
||||
if (str != null) {
|
||||
Pattern p = Pattern.compile("\t|\r|\n");
|
||||
Matcher m = p.matcher(str);
|
||||
dest = m.replaceAll("");
|
||||
}
|
||||
return dest;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成RSA公私钥对
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static Map<String, Object> generateRSAKeyPlain() throws Exception {
|
||||
//获得对象 KeyPairGenerator 参数 RSA 1024个字节
|
||||
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_RSA);
|
||||
keyPairGen.initialize(1024);
|
||||
//通过对象 KeyPairGenerator 获取对象KeyPair
|
||||
KeyPair keyPair = keyPairGen.generateKeyPair();
|
||||
//通过对象 KeyPair 获取RSA公私钥对象RSAPublicKey RSAPrivateKey
|
||||
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
|
||||
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
|
||||
//公私钥对象存入map中
|
||||
Map<String, Object> keyMap = new HashMap<String, Object>(2);
|
||||
keyMap.put(KEY_RSA_PUBLICKEY, publicKey);
|
||||
keyMap.put(KEY_RSA_PRIVATEKEY, privateKey);
|
||||
return keyMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公钥
|
||||
* @param
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPublicKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(KEY_RSA_PUBLICKEY);
|
||||
return encryptBASE64(key.getEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取私钥
|
||||
* @param
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String getPrivateKey(Map<String, Object> keyMap) throws Exception {
|
||||
Key key = (Key) keyMap.get(KEY_RSA_PRIVATEKEY);
|
||||
return encryptBASE64(key.getEncoded());
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码返回byte
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static byte[] decryptBASE64(String key) throws Exception {
|
||||
return Base64.getDecoder().decode(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 编码返回字符串
|
||||
* @param key
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String encryptBASE64(byte[] key) {
|
||||
return Base64.getEncoder().encodeToString (key);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Map<String, Object> keyMap = generateRSAKeyPlain();
|
||||
|
||||
System.out.println("生成的公钥:" + getPublicKey(keyMap));
|
||||
System.out.println("生成的私钥:" + getPrivateKey(keyMap));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.api;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.haoka.api.ApiHaiNanDXService;
|
||||
import cn.iocoder.yudao.module.haoka.api.hainandianxin.HaiNanDianXinApi;
|
||||
import com.mashape.unirest.http.exceptions.UnirestException;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "API----------上游接口-------海南电信")
|
||||
@RestController
|
||||
@RequestMapping("/haoka/api/hainan-dx")
|
||||
@Validated
|
||||
public class HaokaApiHaiNanDXController {
|
||||
|
||||
@Resource
|
||||
private ApiHaiNanDXService apiHaiNanDXService;
|
||||
|
||||
@PostMapping("/qryNbrList")
|
||||
@Operation(summary = "海南电信-选号接口")
|
||||
public CommonResult<HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.QryNbrListResponse>>
|
||||
lianTongSelectNumber(@RequestBody HaiNanDianXinApi.QryNbrListRequest param) throws UnirestException {
|
||||
return success(apiHaiNanDXService.qryNbrList(param));
|
||||
}
|
||||
|
||||
@PostMapping("/fraudCheck")
|
||||
@Operation(summary = "海南电信-防诈校验接口")
|
||||
public CommonResult<HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.FraudCheckResponse>>
|
||||
fraudCheck(@RequestBody HaiNanDianXinApi.FraudCheckRequest param) throws UnirestException {
|
||||
return success(apiHaiNanDXService.fraudCheck(param));
|
||||
}
|
||||
|
||||
@PostMapping("/queryOrderInfo")
|
||||
@Operation(summary = "海南电信-订单信息查询接口")
|
||||
public CommonResult<HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.QueryOrderInfoResponse>>
|
||||
queryOrderInfo(@RequestBody HaiNanDianXinApi.QueryOrderInfoRequest param) throws UnirestException {
|
||||
return success(apiHaiNanDXService.queryOrderInfo(param));
|
||||
}
|
||||
|
||||
@PostMapping("/getLogisticsTrajectory")
|
||||
@Operation(summary = "海南电信-物流轨迹查询接口")
|
||||
public CommonResult<HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.GetLogisticsTrajectoryResponse>>
|
||||
getLogisticsTrajectory(@RequestBody HaiNanDianXinApi.GetLogisticsTrajectoryRequest param) throws UnirestException {
|
||||
return success(apiHaiNanDXService.getLogisticsTrajectory(param));
|
||||
}
|
||||
|
||||
@PostMapping("/synOrderInfo")
|
||||
@Operation(summary = "海南电信-号卡订单收敛接口")
|
||||
public CommonResult<HaiNanDianXinApi.HaiNanResponseInfo<HaiNanDianXinApi.SynOrderInfoResponse>>
|
||||
synOrderInfo(@RequestBody HaiNanDianXinApi.SynOrderInfoRequest param) throws UnirestException {
|
||||
return success(apiHaiNanDXService.synOrderInfo(param));
|
||||
}
|
||||
}
|
||||
|
|
@ -18,79 +18,79 @@ import java.util.List;
|
|||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "API----上游接口")
|
||||
@Tag(name = "API----------上游接口-------联通-集团")
|
||||
@RestController
|
||||
@RequestMapping("/haoka/api")
|
||||
@RequestMapping("/haoka/api/lian-tong")
|
||||
@Validated
|
||||
public class HaokaApiController {
|
||||
public class HaokaApiLianTongController {
|
||||
|
||||
@Resource
|
||||
private ApiLianTongService haokaAllSuperiorApiService;
|
||||
|
||||
@PostMapping("/lian-tong/select-number")
|
||||
@PostMapping("/select-number")
|
||||
@Operation(summary = "联通选号接口")
|
||||
public CommonResult<KingNumSelectResponse> lianTongSelectNumber(@RequestBody KingNumSelectRequest kingNumSelectRequest) {
|
||||
KingNumSelectResponse zopResponse = haokaAllSuperiorApiService.lianTongSelectNumber(kingNumSelectRequest);
|
||||
return success(zopResponse);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/zhan-hao")
|
||||
@PostMapping("/zhan-hao")
|
||||
@Operation(summary = "联通占号接口")
|
||||
public CommonResult<KingNumStateChangeResponse> lianTongZhanHao(@RequestBody KingNumStateChangeRequest request) {
|
||||
KingNumStateChangeResponse response = haokaAllSuperiorApiService.lianTongZhanHao(request);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/submit-user-info")
|
||||
@PostMapping("/submit-user-info")
|
||||
@Operation(summary = "联通资料提交接口")
|
||||
public CommonResult<KingIdentityCustV2Response> lianTongSubmitUserInfo(@RequestBody KingIdentityCustV2Request request) {
|
||||
KingIdentityCustV2Response response = haokaAllSuperiorApiService.lianTongSubmitUserInfo(request);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/order-sync-v2")
|
||||
@PostMapping("/order-sync-v2")
|
||||
@Operation(summary = "联通订单同步接口")
|
||||
public CommonResult<KingOrderSyncResponse> lianTongOrderSyncV2(@RequestBody KingOrderSyncV2Request request) {
|
||||
KingOrderSyncResponse response = haokaAllSuperiorApiService.lianTongOrderSyncV2(request);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@GetMapping("/lian-tong/message-get")
|
||||
@GetMapping("/message-get")
|
||||
@Operation(summary = "联通消息获取接口")
|
||||
public CommonResult<KingMessageGetResponse> lianTongMessageGet(@RequestParam String type) {
|
||||
KingMessageGetResponse response = haokaAllSuperiorApiService.lianTongMessageGet(type);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/message-del")
|
||||
@PostMapping("/message-del")
|
||||
@Operation(summary = "联通消息删除接口")
|
||||
public CommonResult<KingMessageDelResponse> lianTongMessageDel(@RequestParam String type, @RequestParam String megIds) {
|
||||
KingMessageDelResponse response = haokaAllSuperiorApiService.lianTongMessageDel(type, megIds);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/pre-order-sync")
|
||||
@PostMapping("/pre-order-sync")
|
||||
@Operation(summary = "联通意向单同步接口")
|
||||
public CommonResult<KingPreOrderSyncResponse> lianTongPreOrderSync(@RequestBody KingPreOrderSyncRequest request) {
|
||||
KingPreOrderSyncResponse response = haokaAllSuperiorApiService.lianTongPreOrderSync(request);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/post-info-query")
|
||||
@PostMapping("/post-info-query")
|
||||
@Operation(summary = "联通收货地址和号码信息查询接口")
|
||||
public CommonResult<KingPostInfoResponse> lianTongPostInfoQuery(@RequestBody KingPostInfoRequest request) {
|
||||
KingPostInfoResponse response = haokaAllSuperiorApiService.lianTongPostInfoQuery(request);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/token-select-number")
|
||||
@PostMapping("/token-select-number")
|
||||
@Operation(summary = "联通token选号接口")
|
||||
public CommonResult<KingNumSelectResponse> lianTongTokenSelectNumber(@RequestBody KingNumTokenSelectRequest request) {
|
||||
KingNumSelectResponse response = haokaAllSuperiorApiService.lianTongTokenSelectNumber(request);
|
||||
return success(response);
|
||||
}
|
||||
|
||||
@PostMapping("/lian-tong/select-area")
|
||||
@PostMapping("/select-area")
|
||||
@Operation(summary = "联通-地址-归属地查询")
|
||||
public CommonResult<List<LianTongAreaVo>> lianTongAreaInfo(@RequestParam(required = false, defaultValue = "1") String code) {
|
||||
LianTongArea area = LianTongAreaUtils.getArea(code);
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package cn.iocoder.yudao.module.haoka.controller.admin.api;
|
||||
|
||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||
import cn.iocoder.yudao.module.haoka.api.ApiGuangZhouDXService;
|
||||
import cn.iocoder.yudao.module.haoka.api.guangdong.GdOrderCreateRequestParam;
|
||||
import cn.iocoder.yudao.module.haoka.api.guangdong.inner.GdOrderQueryRequestParam;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||
|
||||
@Tag(name = "API----------上游接口-------广州电信")
|
||||
@RestController
|
||||
@RequestMapping("/haoka/api/guangzhou-dx")
|
||||
@Validated
|
||||
public class HaokaGuangZhouDXController {
|
||||
|
||||
@Resource
|
||||
private ApiGuangZhouDXService apiGuangZhouDXService;
|
||||
|
||||
@PostMapping("/createOrder")
|
||||
@Operation(summary = "广州电信-创建订单接口")
|
||||
public CommonResult<String> createOrder(@RequestBody GdOrderCreateRequestParam param) {
|
||||
return success(apiGuangZhouDXService.createOrder(param));
|
||||
}
|
||||
|
||||
@PostMapping("/queryOrder")
|
||||
@Operation(summary = "广州电信-查询订单接口")
|
||||
public CommonResult<String> queryOrder(@RequestBody GdOrderQueryRequestParam param) {
|
||||
return success(apiGuangZhouDXService.queryOrder(param));
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue