接入靓号Api测试demo完成

This commit is contained in:
Owen 2025-03-10 18:08:14 +08:00
parent d4115d3306
commit 64ee91bd30
4 changed files with 463 additions and 1 deletions

View File

@ -10,7 +10,8 @@ public enum ApiFrom {
LianTong(1L, "联通Api", ApiFrom.LianTongApiDealStrategy),
GuangZhouDX(2L, "广州电信Api", ApiFrom.GuangZhouDXApiDealStrategy),
HaiNanDX(3L, "海南电信Api", ApiFrom.HaiNanDXApiDealStrategy),
HuNanDX(4L, "湖南电信Api", ApiFrom.HuNanDXApiDealStrategy);
HuNanDX(4L, "湖南电信Api", ApiFrom.HuNanDXApiDealStrategy),
LiangHao(5L,"靓号Api",ApiFrom.LiangHaoApiDealStrategy);
private final Long id;
private final String name;
private final String apiDealStrategy;
@ -21,6 +22,7 @@ public enum ApiFrom {
public static final String GuangZhouDXApiDealStrategy = "GuangZhouDXApiDealStrategy";
public static final String HaiNanDXApiDealStrategy = "HaiNanDXApiDealStrategy";
public static final String HuNanDXApiDealStrategy = "HuNanDXApiDealStrategy";
public static final String LiangHaoApiDealStrategy = "LiangHaoApiDealStrategy";
public static ApiFrom fromId(Long id) {
ApiFrom[] values = values();

View File

@ -0,0 +1,59 @@
package cn.iocoder.yudao.module.haoka.api;
import cn.iocoder.yudao.module.haoka.api.lianghaoapi.LiangHaoApiClient;
import org.springframework.stereotype.Service;
import java.util.Map;
@Service
public class LiangHaoApiClientService extends ApiConfigService {
// 原有联通方法保持不变...
// ================== 靓号API集成 ==================
/**
* 获取靓号API客户端配置
*/
private LiangHaoApiClient.Config getLiangHaoConfig(Long haokaSuperiorApiId) {
Map<String, String> devConfig = this.getDevConfig(haokaSuperiorApiId);
LiangHaoApiClient.Config config = new LiangHaoApiClient.Config();
// 从devConfig中映射配置项假设配置键与联通类似需要调整
config.setSecretKey(devConfig.get("secretKey"));
config.setSelectUrl(devConfig.get("selectUrl"));
config.setSubmitUrl(devConfig.get("submitUrl"));
config.setQueryUrl(devConfig.get("queryUrl"));
config.setAgentMark(devConfig.get("agentMark"));
return config;
}
/**
* 靓号选号接口
*/
public LiangHaoApiClient.SelectNumberResponse liangHaoSelectNumber(
Long haokaSuperiorApiId,
LiangHaoApiClient.SelectNumberRequest request) throws Exception {
LiangHaoApiClient.Config config = getLiangHaoConfig(haokaSuperiorApiId);
return LiangHaoApiClient.selectNumber(config, request);
}
/**
* 靓号下单接口
*/
public LiangHaoApiClient.SubmitOrderResponse liangHaoSubmitOrder(
Long haokaSuperiorApiId,
LiangHaoApiClient.SubmitOrderRequest request) throws Exception {
LiangHaoApiClient.Config config = getLiangHaoConfig(haokaSuperiorApiId);
return LiangHaoApiClient.submitOrder(config, request);
}
/**
* 靓号订单查询接口
*/
public LiangHaoApiClient.QueryOrderResponse liangHaoQueryOrder(
Long haokaSuperiorApiId,
LiangHaoApiClient.QueryOrderRequest request) throws Exception {
LiangHaoApiClient.Config config = getLiangHaoConfig(haokaSuperiorApiId);
return LiangHaoApiClient.queryOrder(config, request);
}
}

View File

@ -0,0 +1,262 @@
package cn.iocoder.yudao.module.haoka.api.lianghaoapi;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Data;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 接口调用工具类
*/
public class LiangHaoApiClient {
// //
// 生产环境接口地址 http://ddkb.hfswcz.com/api/openapi/
//
// 平台名称 美美靓号
// 代理商标识 meimeilianghao
// 秘钥 0fb47e1ab69a7fc236456ee32c53b773
/**
* 配置类需根据实际信息填充
*/
@Data
public static class Config {
private String secretKey = "0fb47e1ab69a7fc236456ee32c53b773"; // 需联系管理员获取
private String selectUrl = "https://ddkb.hfswcz.com/api/openapi/select";
private String submitUrl = "https://ddkb.hfswcz.com/api/openapi/submit";
private String queryUrl = "https://ddkb.hfswcz.com/api/openapi/query";
private String agentMark = "meimeilianghao";
private String platformName = "美美靓号";
}
/**
* 请求参数基类包含公共字段
*/
@Data
public static abstract class BaseRequest {
protected String sign;
protected String timeStamp;
}
/**
* 选号接口请求参数
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class SelectNumberRequest extends BaseRequest {
private String agentMark;
private String productCode;
private String searchKey;
}
/**
* 选号接口响应数据
*/
@Data
public static class SelectNumberResponse {
private Integer code;
private String msg;
private List<PhoneNumberData> data;
@Data
public static class PhoneNumberData {
private String serialNumber;
private Integer monthFee;
private Integer protocolTime;
private String location;
}
}
/**
* 下单接口请求参数
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class SubmitOrderRequest extends BaseRequest {
private String contactNumber;
private String userName;
private String idNumber;
private String agentMark;
private String productCode;
private String serialNumber;
private String province;
private String city;
private String area;
private String address;
private String apiNumber;
}
/**
* 下单接口响应数据
*/
@Data
public static class SubmitOrderResponse {
private Integer code;
private String msg;
private String sysOrderNo;
}
/**
* 查询订单接口请求参数
*/
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
public static class QueryOrderRequest extends BaseRequest {
private String sysOrderNo;
private String agentMark;
private String apiNumber;
}
/**
* 查询订单接口响应数据
*/
@Data
public static class QueryOrderResponse {
private Integer code;
private String msg;
private Integer orderStatus;
private String reason;
private String sysOrderNo;
private String serialNumber;
private String apiNumber;
private String creatTime;
}
/**
* 签名工具类
*/
private static class SignUtil {
/**
* 生成签名
*/
public static String generateSign(Object req, String secretKey) throws Exception {
JSONObject params = JSON.parseObject(JSON.toJSONString(req));
// 按字段名排序
List<String> sortedKeys = new ArrayList<>(params.keySet());
sortedKeys.sort(String::compareTo);
// 拼接值
StringBuilder sb = new StringBuilder();
for (String key : sortedKeys) sb.append(params.get(key));
sb.append(secretKey);
// MD5加密
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(sb.toString().getBytes(StandardCharsets.UTF_8));
StringBuilder hexString = new StringBuilder();
for (byte b : digest) {
hexString.append(String.format("%02X", b));
}
return hexString.toString();
}
/**
* 生成时间戳
*/
public static String generateTimestamp() {
return new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
}
}
/**
* HTTP工具类
*/
private static class HttpClientUtil {
private static final ObjectMapper mapper = new ObjectMapper();
public static <T> T post(String url, Object request, Class<T> responseType) throws IOException {
HttpClient client = HttpClients.createDefault();
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/json;charset=utf-8");
String json = mapper.writeValueAsString(request);
post.setEntity(new StringEntity(json, StandardCharsets.UTF_8));
HttpResponse response = client.execute(post);
String result = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
return mapper.readValue(result, responseType);
}
}
// -------------------- 接口调用方法 --------------------
/**
* 选号接口
*/
public static SelectNumberResponse selectNumber(LiangHaoApiClient.Config config, SelectNumberRequest request) throws Exception {
request.setTimeStamp(SignUtil.generateTimestamp());
request.setSign(SignUtil.generateSign(JSON.parseObject(JSON.toJSONString(request)), config.getSecretKey()));
request.setAgentMark(config.getAgentMark());
return HttpClientUtil.post(config.getSelectUrl(), request, SelectNumberResponse.class);
}
/**
* 下单接口
*/
public static SubmitOrderResponse submitOrder(LiangHaoApiClient.Config config,SubmitOrderRequest request) throws Exception {
request.setTimeStamp(SignUtil.generateTimestamp());
request.setSign(SignUtil.generateSign(request, config.getSecretKey()));
request.setAgentMark(config.getAgentMark());
return HttpClientUtil.post(config.getSubmitUrl(), request, SubmitOrderResponse.class);
}
/**
* 查询订单接口
*/
public static QueryOrderResponse queryOrder(LiangHaoApiClient.Config config,QueryOrderRequest request) throws Exception {
request.setTimeStamp(SignUtil.generateTimestamp());
request.setSign(SignUtil.generateSign(request, config.getSecretKey()));
request.setAgentMark(config.getAgentMark());
return HttpClientUtil.post(config.getQueryUrl(), request, QueryOrderResponse.class);
}
// -------------------- 示例调用 --------------------
public static void main(String[] args) throws Exception {
LiangHaoApiClient.Config config = new LiangHaoApiClient.Config();
// 示例选号接口调用
SelectNumberRequest selectReq = new SelectNumberRequest();
selectReq.setAgentMark("meimeilianghao");
selectReq.setProductCode("8C9909E8F1CE3D95");
selectReq.setSearchKey("1221");
SelectNumberResponse selectRes = selectNumber(config,selectReq);
System.out.println("选号结果:" + selectRes);
// 示例下单接口调用
SubmitOrderRequest submitReq = new SubmitOrderRequest();
submitReq.setContactNumber("12345678910");
submitReq.setUserName("周海彬");
submitReq.setIdNumber("450821xxxxxxxxxxxx");
submitReq.setAgentMark("meimeilianghao");
submitReq.setProductCode("838D90200D0B0");
submitReq.setSerialNumber("13026537852");
submitReq.setProvince("广东");
submitReq.setCity("广州市");
submitReq.setArea("天河区");
submitReq.setAddress("天河路228号");
submitReq.setApiNumber("sd11221221");
SubmitOrderResponse submitRes = submitOrder(config,submitReq);
System.out.println("下单结果:" + submitRes);
// 示例查询订单接口调用
QueryOrderRequest queryReq = new QueryOrderRequest();
queryReq.setSysOrderNo("D202111021402373923341");
queryReq.setAgentMark("meimeilianghao");
QueryOrderResponse queryRes = queryOrder(config,queryReq);
System.out.println("查询结果:" + queryRes);
}
}

View File

@ -0,0 +1,139 @@
package cn.iocoder.yudao.module.haoka.service.api.strategy;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.haoka.api.ApiFrom;
import cn.iocoder.yudao.module.haoka.api.LiangHaoApiClientService;
import cn.iocoder.yudao.module.haoka.api.lianghaoapi.LiangHaoApiClient;
import cn.iocoder.yudao.module.haoka.controller.admin.address.vo.AddressVo;
import cn.iocoder.yudao.module.haoka.controller.admin.onsaleproduct.vo.OnSaleProductPreOrderRespVO;
import cn.iocoder.yudao.module.haoka.controller.admin.superiorapilog.vo.SuperiorApiLogSaveReqVO;
import cn.iocoder.yudao.module.haoka.controller.admin.superiorproductconfig.vo.SuperiorProductConfigRespVO;
import cn.iocoder.yudao.module.haoka.dal.dataobject.superiorapi.SuperiorApiDO;
import cn.iocoder.yudao.module.haoka.dal.dataobject.superiorproductconfig.SuperiorProductConfigDO;
import cn.iocoder.yudao.module.haoka.service.address.HaoKaAddressService;
import cn.iocoder.yudao.module.haoka.service.api.*;
import cn.iocoder.yudao.module.haoka.service.api.models.*;
import cn.iocoder.yudao.module.haoka.service.onsaleproduct.OnSaleProductService;
import cn.iocoder.yudao.module.haoka.service.superiorapi.SuperiorApiService;
import cn.iocoder.yudao.module.haoka.service.superiorproductconfig.SuperiorProductConfigService;
import com.alibaba.fastjson.JSON;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
@Slf4j
@Component(ApiFrom.LiangHaoApiDealStrategy)
public class LiangHaoApiDealStrategy implements ApiDealStrategy {
@Resource
private LiangHaoApiClientService liangHaoApiClientService;
@Resource
private OnSaleProductService onSaleProductService;
@Resource
private SuperiorApiService superiorApiService;
@Resource
private SuperiorProductConfigService superiorProductConfigService;
@Resource
private HaoKaAddressService haoKaAddressService;
@Override
public ApiDealResp<OrderApiCreateResp> createOrder(SuperiorApiLogSaveReqVO logVO, OrderApiCreateParam param) {
try {
// 1. 校验商品及配置
OnSaleProductPreOrderRespVO preProduct = onSaleProductService.getOnSaleProductPreOrder(param.getOnSaleProductId());
if (preProduct == null) {
return ApiDealResp.failed("商品下架或不存在");
}
SuperiorApiDO superiorApi = superiorApiService.getSuperiorApi(param.getSuperiorApiId());
SuperiorProductConfigDO skuConfig = superiorProductConfigService.getById(param.getSuperiorProductConfigId());
if (skuConfig == null) {
return ApiDealResp.failed("商品上游配置不存在");
}
// 2. 构建靓号API请求参数
LiangHaoApiClient.SubmitOrderRequest submitReq = new LiangHaoApiClient.SubmitOrderRequest();
submitReq.setContactNumber(param.getAddressMobile());
submitReq.setUserName(param.getIdCardName());
submitReq.setIdNumber(param.getIdCardNum());
// submitReq.setAgentMark(superiorApi.getAgentMark()); // 从配置获取代理标识
submitReq.setProductCode(skuConfig.getSuperiorCode()); // 上游商品编码
submitReq.setSerialNumber(param.getPlanMobile()); // 预占号码
submitReq.setApiNumber(param.getId().toString()); // 使用订单ID作为API流水号
AddressVo addressDistrict = haoKaAddressService.getAddress(param.getAddressDistrictCode());
submitReq.setArea(addressDistrict.getName());
AddressVo addressProvince = haoKaAddressService.getAddress(addressDistrict.getProvinceCode());
submitReq.setProvince(addressProvince.getName());
AddressVo addressCity = haoKaAddressService.getAddress(addressDistrict.getCityCode());
submitReq.setCity(addressCity.getName());
submitReq.setAddress(param.getAddress());
// 3. 调用下单接口
logVO.setParam(JSON.toJSONString(submitReq));
LiangHaoApiClient.SubmitOrderResponse response = liangHaoApiClientService.liangHaoSubmitOrder(
superiorApi.getId(), submitReq);
logVO.setResponse(JSON.toJSONString(response));
// 4. 处理响应
OrderApiCreateResp resp = new OrderApiCreateResp();
if (response.getCode() != 0) { // 假设0为成功状态码
resp.setOrderStatusCode("0");
resp.setSupplierOrderStatusDesc(response.getMsg());
return ApiDealResp.ok(resp);
}
resp.setSupplierOrderId(response.getSysOrderNo());
resp.setOrderStatusCode("470"); // 订单创建成功状态码
resp.setPlanMobileProduced(param.getPlanMobile());
return ApiDealResp.ok(resp);
} catch (Exception e) {
log.error("靓号API创建订单异常: {}", e.getMessage());
return ApiDealResp.failed("系统异常: " + e.getMessage());
}
}
@Override
public ApiDealResp<OrderApiQueryResp> queryOrder(SuperiorApiLogSaveReqVO logVO, OrderApiQueryParam param) {
try {
// 1. 校验必要参数
if (param.getSupplierOrderId() == null) {
return ApiDealResp.failed("订单号不能为空");
}
// 2. 构建查询请求
LiangHaoApiClient.QueryOrderRequest queryReq = new LiangHaoApiClient.QueryOrderRequest();
queryReq.setSysOrderNo(param.getSupplierOrderId());
// queryReq.setAgentMark(param.getAgentMark()); // 从参数或配置获取
// 3. 调用查询接口
logVO.setParam(JSON.toJSONString(queryReq));
LiangHaoApiClient.QueryOrderResponse response = liangHaoApiClientService.liangHaoQueryOrder(
param.getSuperiorApiId(), queryReq);
logVO.setResponse(JSON.toJSONString(response));
// 4. 处理响应
OrderApiQueryResp resp = new OrderApiQueryResp();
if (response.getCode() != 0) {
resp.setSupplierOrderStatusDesc(response.getMsg());
return ApiDealResp.ok(resp);
}
// resp.setSupplierOrderStatus(response.getOrderStatus().toString());
resp.setSupplierOrderStatusDesc(response.getReason());
resp.setTrackingNumber(response.getSerialNumber()); // 物流单号映射
return ApiDealResp.ok(resp);
} catch (Exception e) {
log.error("靓号API查询订单异常: {}", e.getMessage());
return ApiDealResp.failed("查询失败: " + e.getMessage());
}
}
}