This commit is contained in:
Hsy
2025-02-20 17:32:53 +08:00
commit 144c1788f7
57 changed files with 2827 additions and 0 deletions

72
pkg/util/172/172.go Normal file
View File

@ -0,0 +1,72 @@
package _72
import (
"encoding/json"
"fmt"
"hk/pkg/util/httpUtil"
"time"
)
const (
productsUrl = "https://haokaopenapi.lot-ml.com/api/order/GetProducts" // 商品列表查询Url
productsV2Url = "https://haokaopenapi.lot-ml.com/api/order/GetProductsV2" // 商品信息查询Url
pickNumberUrl = "https://haokaopenapi.lot-ml.com/api/order/PickNumber" // 商品选号Url
blackUserUrl = "https://haokaopenapi.lot-ml.com/api/black/BlackCheckCus" // 用户黑名单Url
blackAgentUrl = "https://haokaopenapi.lot-ml.com/api/black/BlackCheckAgent" // 代理黑名单Url
upFileUrl = "https://haokaopenapi.lot-ml.com/api/order/UpPicFile" // 证件照上传Url
addOrderUrl = "https://haokaopenapi.lot-ml.com/api/order/ApiToOrder" // 下单Url
orderInfoUrl = "https://haokaopenapi.lot-ml.com/api/order/GetOrderInfo" // 订单查询Url
)
type BaseParams struct {
Timestamp string `json:"Timestamp"` // Y 时间戳
UserID string `json:"user_id"` // Y 用户ID
UserSign string `json:"user_sign"` // Y 密钥
}
// GoodsReq 商品请求参数
type GoodsReq struct {
ProductID string `json:"ProductID"`
BaseParams
// Timestamp string `json:"Timestamp"` // Y 时间戳
// UserID string `json:"user_id"` // Y 用户ID
// UserSign string `json:"user_sign"` // Y 密钥
}
// ProductResp 定义产品信息的结构体
type ProductResp struct {
ProductID int64 `json:"productID"`
ProductName string `json:"productName"`
Flag string `json:"flag"` // 上架中
}
// GetProduct 获取上架中商品列表
func GetProduct(params GoodsReq) (ApiResponse[[]ProductResp], error) {
// 设置时间戳
timestamp := fmt.Sprintf("%d", time.Now().Unix()) // 当前时间戳长度为10位
params.Timestamp = timestamp
// 生成 MD5 签名
userSign := generateMD5SignV2(params, params.UserSign)
formParams := map[string]string{
"ProductID": params.ProductID,
"Timestamp": params.Timestamp,
"user_sign": userSign,
"user_id": params.UserID,
}
body, err := httpUtil.NewRequest().SendFormData(productsUrl, nil, formParams)
if err != nil {
return ApiResponse[[]ProductResp]{}, err
}
// 解析 JSON 响应
var apiResponse ApiResponse[[]ProductResp]
err = json.Unmarshal([]byte(body), &apiResponse)
if err != nil {
fmt.Println("解析响应体时发生错误:", err)
return ApiResponse[[]ProductResp]{}, err
}
return apiResponse, nil
}

198
pkg/util/172/172_test.go Normal file
View File

@ -0,0 +1,198 @@
package _72
import (
"fmt"
"testing"
"time"
)
func TestGetProduct(t *testing.T) {
key := "devttl"
secret := "2eed544990ff898cf4fe47ef90b1ce3a"
productID := ""
timestamp := fmt.Sprintf("%d", time.Now().Unix()) // 当前时间戳长度为10位
// 创建请求参数
params := GoodsReq{
ProductID: productID,
BaseParams: BaseParams{
Timestamp: timestamp,
UserID: key,
UserSign: secret,
},
}
// 发送 POST 请求
apiResponse, err := GetProduct(params)
if err != nil {
return
}
// 如果成功,处理 data 中的数据
if apiResponse.Code == 0 {
for index, item := range apiResponse.Data {
fmt.Printf("------------------%d\n", index)
fmt.Printf("产品ID: %v\n", item.ProductID)
fmt.Printf("产品名称: %v\n", item.ProductName)
fmt.Printf("产品状态: %v\n", item.Flag)
}
}
}
func TestGetProductV2(t *testing.T) {
key := "devttl"
secret := "2eed544990ff898cf4fe47ef90b1ce3a"
productID := "1128"
timestamp := fmt.Sprintf("%d", time.Now().Unix()) // 当前时间戳长度为10位
// 创建请求参数
params := GoodsReq{
ProductID: productID,
BaseParams: BaseParams{
Timestamp: timestamp,
UserID: key,
},
}
// 生成 MD5 签名
userSign := generateMD5SignV2(params, secret)
params.UserSign = userSign
fmt.Print(params)
// 发送 POST 请求
apiResponse, err := getProductV2(params)
if err != nil {
return
}
// 如果成功,处理 data 中的数据
if apiResponse.Code == 0 {
for index, item := range apiResponse.Data {
fmt.Printf("------------------%d\n", index)
fmt.Printf("产品ID: %v\n", item.ProductID)
fmt.Printf("产品名称: %v\n", item.ProductName)
fmt.Printf("产品主图: %v\n", item.MainPic)
fmt.Printf("发货地区: %v\n", item.Area)
fmt.Printf("禁发地区: %v\n", item.DisableArea)
fmt.Printf("详情图片: %v\n", item.LittlePicture)
fmt.Printf("详情链接: %v\n", item.NetAddr)
fmt.Printf("产品状态: %v\n", item.Flag)
fmt.Printf("是否选号: %v\n", item.NumberSel)
}
}
}
func TestGetPickNumber(t *testing.T) {
key := "devttl"
secret := "2eed544990ff898cf4fe47ef90b1ce3a"
productID := "1128"
timestamp := fmt.Sprintf("%d", time.Now().Unix()) // 当前时间戳长度为10位
// 创建请求参数
params := PickNumberReq{
ProductID: productID,
SearchCategory: "3",
BaseParams: BaseParams{
UserID: key,
Timestamp: timestamp,
},
}
// 生成 MD5 签名
userSign := generateMD5SignV2(params, secret)
params.UserSign = userSign
fmt.Println(params)
// 发送 POST 请求
apiResponse, err := GetPickNumber(params)
if err != nil {
return
}
// 如果成功,处理 data 中的数据
if apiResponse.Code == 0 {
for index, item := range apiResponse.Data {
fmt.Printf("------------------%d\n", index)
fmt.Printf("号码: %v\n", item.Number)
fmt.Printf("号码类型: %v\n", item.Type)
fmt.Printf("号码ID: %v\n", item.NumberId)
fmt.Printf("号码池ID: %v\n", item.NumberPoolId)
}
}
}
func TestCheckUserBlack(t *testing.T) {
key := "devttl"
secret := "2eed544990ff898cf4fe47ef90b1ce3a"
number := "15538654901"
numberType := "1"
timestamp := fmt.Sprintf("%d", time.Now().Unix()) // 当前时间戳长度为10位
// 创建请求参数
params := BlackReq{
Number: number,
Type: numberType,
Timestamp: timestamp,
UserID: key,
UserSign: secret,
}
// 发送 POST 请求
apiResponse, err := CheckBlackUser(params)
if err != nil {
return
}
// 如果成功,处理 data 中的数据
if apiResponse.Code == 0 {
fmt.Println("此用户是黑名单")
}
if apiResponse.Code == 1 {
fmt.Println("此用户不是黑名单")
}
if apiResponse.Code == -1 {
fmt.Println("请输入正确的手机号")
}
}
func TestCheckAgentBlack(t *testing.T) {
key := "devttl"
secret := "2eed544990ff898cf4fe47ef90b1ce3a"
number := "15538654901"
numberType := "1"
// 创建请求参数
params := BlackReq{
Number: number,
Type: numberType,
UserID: key,
}
// 生成 MD5 签名
userSign := generateMD5SignV2(params, secret)
params.UserSign = userSign
fmt.Println(params)
// 发送 POST 请求
apiResponse, err := CheckBlackAgent(params)
if err != nil {
return
}
// 如果成功,处理 data 中的数据
if apiResponse.Code == 0 {
fmt.Println("此用户是黑名单代理")
}
if apiResponse.Code == 1 {
fmt.Println("此用户不是黑名单代理")
}
if apiResponse.Code == -1 {
fmt.Println("请输入正确的代理手机号")
}
}

View File

@ -0,0 +1,70 @@
package _72
import (
"crypto/md5"
"encoding/hex"
"fmt"
"reflect"
"strings"
)
// ApiResponse 定义响应体的结构体
type ApiResponse[T any] struct {
Code int `json:"code"`
Message string `json:"message"`
Errs *string `json:"errs"`
Data T `json:"data"`
}
// 优化后的 generateMD5Sign 方法
func generateMD5SignV2(params interface{}, secret string) string {
// 获取结构体中的字段信息
var strBuilder strings.Builder
// 获取参数类型
v := reflect.ValueOf(params)
// 遍历结构体中的字段
for i := 0; i < v.NumField(); i++ {
// 获取字段名和值
field := v.Type().Field(i)
jsonTag := field.Tag.Get("json") // 获取 json 标签
value := v.Field(i)
// 如果字段是嵌套结构体,跳过
if value.Kind() == reflect.Struct {
continue
}
// 获取字段值
fieldValue := value.String()
// 排除 user_id 和空字符串字段
if field.Name != "UserID" && field.Name != "UserSign" {
// 拼接字段名和值
strBuilder.WriteString(fmt.Sprintf("%s=%s&", jsonTag, fieldValue))
}
}
// 使用反射获取字段并拼接
timestamp := v.FieldByName("Timestamp")
if timestamp.IsValid() {
timestampTag, _ := v.Type().FieldByName("Timestamp")
strBuilder.WriteString(fmt.Sprintf("%s=%s&", timestampTag.Tag.Get("json"), timestamp.String()))
}
userID := v.FieldByName("UserID")
if userID.IsValid() {
userIDTag, _ := v.Type().FieldByName("UserID")
strBuilder.WriteString(fmt.Sprintf("%s=%s", userIDTag.Tag.Get("json"), userID.String()))
}
// 拼接 secret 到最后
strBuilder.WriteString(secret)
// 获取拼接后的字符串
concatenatedStr := strBuilder.String()
fmt.Println(concatenatedStr)
// 计算 MD5 哈希
hash := md5.New()
hash.Write([]byte(concatenatedStr))
return hex.EncodeToString(hash.Sum(nil))
}

View File

@ -0,0 +1,69 @@
package _72
import (
"encoding/json"
"fmt"
"hk/pkg/util/httpUtil"
)
// BlackReq 黑名单请求
type BlackReq struct {
Number string `json:"number"` // Y 手机号或身份证号
Type string `json:"type"` // Y 查询类别 1手机号 2身份证号
Timestamp string `json:"Timestamp"` // Y 时间戳
UserID string `json:"username"` // Y 用户ID
UserSign string `json:"sign"` // Y 密钥
}
// CheckBlackUser 判断用户是否为黑名单用户
func CheckBlackUser(params BlackReq) (ApiResponse[any], error) {
formParams := map[string]string{
"number": params.Number,
"type": params.Type,
"Timestamp": params.Timestamp,
"username": params.UserID,
"sign": params.UserSign,
}
body, err := httpUtil.NewRequest().SendFormData(blackUserUrl, nil, formParams)
if err != nil {
return ApiResponse[any]{}, err
}
// 解析 JSON 响应
var apiResponse ApiResponse[any]
err = json.Unmarshal([]byte(body), &apiResponse)
if err != nil {
fmt.Println("解析响应体时发生错误:", err)
return ApiResponse[any]{}, err
}
return apiResponse, nil
}
// CheckBlackAgent 判断用户是否为黑名单代理
func CheckBlackAgent(params BlackReq) (ApiResponse[any], error) {
formParams := map[string]string{
"number": params.Number,
"type": params.Type,
"username": params.UserID,
"sign": params.UserSign,
}
body, err := httpUtil.NewRequest().SendFormData(blackAgentUrl, nil, formParams)
if err != nil {
return ApiResponse[any]{}, err
}
// 解析 JSON 响应
var apiResponse ApiResponse[any]
err = json.Unmarshal([]byte(body), &apiResponse)
if err != nil {
fmt.Println("解析响应体时发生错误:", err)
return ApiResponse[any]{}, err
}
return apiResponse, nil
}

50
pkg/util/172/goods_v2.go Normal file
View File

@ -0,0 +1,50 @@
package _72
import (
"encoding/json"
"fmt"
"hk/pkg/util/httpUtil"
"time"
)
const ()
// ProductV2Resp 定义商品套餐的结构
type ProductV2Resp struct {
ProductID int64 `json:"productID"`
ProductName string `json:"productName"`
MainPic string `json:"mainPic"`
Area string `json:"area"`
DisableArea string `json:"disableArea"`
LittlePicture string `json:"littlepicture"`
NetAddr string `json:"netAddr"`
Flag bool `json:"flag"`
NumberSel int `json:"numberSel"`
}
// GetProductV2 获取单个商品信息
func GetProductV2(params GoodsReq) (ApiResponse[[]ProductV2Resp], error) {
// 设置时间戳
timestamp := fmt.Sprintf("%d", time.Now().Unix()) // 当前时间戳长度为10位
params.Timestamp = timestamp
// 生成 MD5 签名
userSign := generateMD5SignV2(params, params.UserSign)
formParams := map[string]string{
"ProductID": params.ProductID,
"user_id": params.UserID,
"Timestamp": params.Timestamp,
"user_sign": userSign,
}
body, err := httpUtil.NewRequest().SendFormData(productsV2Url, nil, formParams)
// 解析 JSON 响应
var apiResponse ApiResponse[[]ProductV2Resp]
err = json.Unmarshal([]byte(body), &apiResponse)
if err != nil {
return ApiResponse[[]ProductV2Resp]{}, fmt.Errorf("解析响应体时发生错误: %v", err)
}
// 返回解析后的响应
return apiResponse, nil
}

View File

@ -0,0 +1,53 @@
package _72
import (
"encoding/json"
"fmt"
"hk/pkg/util/httpUtil"
)
const ()
type PickNumberReq struct {
City string `json:"city"` // 市
ProductID string `json:"prodID"` // Y 商品ID
Province string `json:"province"` // 省
SearchCategory string `json:"searchCategory"` // 查询分类 默认3
SearchValue string `json:"searchValue"` // 查询关键字2-4位
BaseParams
}
type PickNumberResp struct {
Type string `json:"type"` // 号码类型 普通
Number string `json:"number"` // 号码
NumberId string `json:"numberId"` // 号码ID
NumberPoolId string `json:"numberPoolId"` // 号码池ID
}
// GetPickNumber 商品选号
func GetPickNumber(params PickNumberReq) (ApiResponse[[]PickNumberResp], error) {
formParams := map[string]string{
"city": params.City,
"prodID": params.ProductID,
"province": params.Province,
"searchCategory": "3",
"searchValue": params.SearchValue,
"Timestamp": params.Timestamp,
"user_id": params.UserID,
"user_sign": params.UserSign,
}
body, err := httpUtil.NewRequest().SendFormData(pickNumberUrl, nil, formParams)
// 解析 JSON 响应
var apiResponse ApiResponse[[]PickNumberResp]
err = json.Unmarshal([]byte(body), &apiResponse)
if err != nil {
return ApiResponse[[]PickNumberResp]{}, fmt.Errorf("解析响应体时发生错误: %v", err)
}
// 返回解析后的响应
return apiResponse, nil
}