Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
e41a3c8600 | ||
![]() |
ebe8aff954 | ||
![]() |
3d62321146 | ||
![]() |
12e627aac6 | ||
![]() |
842e6d94aa | ||
![]() |
9e328b469b | ||
![]() |
36664d298e | ||
![]() |
0bbbfa3c1e | ||
![]() |
169996cc8a | ||
![]() |
6d3891390f |
3
go.mod
3
go.mod
@@ -5,8 +5,11 @@ go 1.18.0
|
|||||||
require github.com/pkg/errors v0.9.1
|
require github.com/pkg/errors v0.9.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
|
github.com/redis/go-redis/v9 v9.10.0 // indirect
|
||||||
github.com/stretchr/testify v1.10.0 // indirect
|
github.com/stretchr/testify v1.10.0 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
6
go.sum
6
go.sum
@@ -1,9 +1,15 @@
|
|||||||
|
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
|
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
|
||||||
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/redis/go-redis/v9 v9.10.0 h1:FxwK3eV8p/CQa0Ch276C7u2d0eNC9kCmAYQ7mCXCzVs=
|
||||||
|
github.com/redis/go-redis/v9 v9.10.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package ip_tool
|
package ip_tool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
@@ -15,12 +16,14 @@ import (
|
|||||||
type HuaChenIpClient struct {
|
type HuaChenIpClient struct {
|
||||||
AppCode string
|
AppCode string
|
||||||
Host string
|
Host string
|
||||||
|
cache ICacheAdapter
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHuaChenIpClient(appCode string) *HuaChenIpClient {
|
func NewHuaChenIpClient(appCode string, cache ICacheAdapter) *HuaChenIpClient {
|
||||||
return &HuaChenIpClient{
|
return &HuaChenIpClient{
|
||||||
AppCode: appCode,
|
AppCode: appCode,
|
||||||
Host: "https://c2ba.api.huachen.cn",
|
Host: "https://c2ba.api.huachen.cn",
|
||||||
|
cache: cache,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,6 +90,37 @@ func (h *HuaChenIpClient) GetIpInfo(ip string) (res *ApiResult, err error) {
|
|||||||
return &apiResult, nil
|
return &apiResult, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *HuaChenIpClient) GetIpInfoFormCache(ctx context.Context, ip string, ttl time.Duration) (res *ApiResult, err error) {
|
||||||
|
getCache, err := h.cache.Get(ctx, h.ipKey(ip))
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "获取缓存失败,ip:%s", ip)
|
||||||
|
}
|
||||||
|
if getCache != nil {
|
||||||
|
return getCache, nil
|
||||||
|
}
|
||||||
|
res, err = h.GetIpInfo(ip)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "获取ip:%s信息失败,", ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
var infoJson []byte
|
||||||
|
infoJson, err = json.Marshal(res)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "无法将IP信息转换为JSON,ip:%s", ip)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = h.cache.Set(ctx, h.ipKey(ip), string(infoJson), ttl)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrapf(err, "缓存ip:%s信息失败,", ip)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// ipKey 生成Redis key
|
||||||
|
func (h *HuaChenIpClient) ipKey(ip string) string {
|
||||||
|
return fmt.Sprintf("ip:%s", ip)
|
||||||
|
}
|
||||||
|
|
||||||
type ApiResult struct {
|
type ApiResult struct {
|
||||||
Ret int `json:"ret"`
|
Ret int `json:"ret"`
|
||||||
Msg string `json:"msg"`
|
Msg string `json:"msg"`
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
package ip_tool
|
package ip_tool
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/pkg/errors"
|
||||||
|
"github.com/redis/go-redis/v9"
|
||||||
"log"
|
"log"
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHuaChenIpClient_GetIpInfo(t *testing.T) {
|
func TestHuaChenIpClient_GetIpInfo(t *testing.T) {
|
||||||
@@ -42,3 +48,73 @@ func TestHuaChenIpClient_GetIpInfo(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHuaChenIpClient_GetIpInfo1(t *testing.T) {
|
||||||
|
rdb := redis.NewClient(&redis.Options{
|
||||||
|
Addr: "",
|
||||||
|
Password: "",
|
||||||
|
DB: 1,
|
||||||
|
})
|
||||||
|
|
||||||
|
// 创建IP缓存实例
|
||||||
|
ipCache := NewRedisCache(rdb)
|
||||||
|
h := &HuaChenIpClient{
|
||||||
|
AppCode: "",
|
||||||
|
Host: "https://c2ba.api.huachen.cn",
|
||||||
|
cache: ipCache,
|
||||||
|
}
|
||||||
|
gotRes, err := h.GetIpInfoFormCache(context.Background(), "8.138.116.112")
|
||||||
|
log.Println(gotRes, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RedisCache struct {
|
||||||
|
client *redis.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRedisCache(client *redis.Client) *RedisCache {
|
||||||
|
return &RedisCache{client: client}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RedisCache) Set(ctx context.Context, ip string, info string, ttl time.Duration) error {
|
||||||
|
if ip == "" {
|
||||||
|
return errors.New("ip不能为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
return r.client.Set(ctx, ip, info, ttl).Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get 从Redis获取IP信息
|
||||||
|
func (r *RedisCache) Get(ctx context.Context, ip string) (*ApiResult, error) {
|
||||||
|
if ip == "" {
|
||||||
|
return nil, errors.New("ip不能为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := r.client.Get(ctx, ip).Bytes()
|
||||||
|
if err != nil {
|
||||||
|
if errors.Is(err, redis.Nil) {
|
||||||
|
return nil, nil // 键不存在,返回nil而不是错误
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("无法获取IP信息: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var info ApiResult
|
||||||
|
if err = json.Unmarshal(data, &info); err != nil {
|
||||||
|
return nil, fmt.Errorf("无法解析IP信息: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &info, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exists 检查IP是否存在缓存中
|
||||||
|
func (r *RedisCache) Exists(ctx context.Context, ip string) (bool, error) {
|
||||||
|
if ip == "" {
|
||||||
|
return false, errors.New("ip不能为空")
|
||||||
|
}
|
||||||
|
|
||||||
|
exists, err := r.client.Exists(ctx, ip).Result()
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("无法检查IP是否存在: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return exists > 0, nil
|
||||||
|
}
|
||||||
|
13
ip_tool/ip_cache.go
Normal file
13
ip_tool/ip_cache.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package ip_tool
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Cache 定义缓存接口,遵循接口隔离原则
|
||||||
|
type ICacheAdapter interface {
|
||||||
|
Set(ctx context.Context, ip string, info string, ttl time.Duration) error
|
||||||
|
Get(ctx context.Context, ip string) (*ApiResult, error)
|
||||||
|
Exists(ctx context.Context, ip string) (bool, error)
|
||||||
|
}
|
@@ -33,11 +33,11 @@ type CreateOrderData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SkuData struct {
|
type SkuData struct {
|
||||||
GoodSpecId string `json:"goodSpecId"` //商品ID(c_goods_id)
|
GoodSpecId string `json:"goodSpecId"` //商品ID(c_goods_id)
|
||||||
GoodsId string `json:"goodsId"` //商品ID(c_father_goods_id)
|
GoodsId string `json:"goodsId"` //商品ID(c_father_goods_id)
|
||||||
GoodName string `json:"goodName"` //商品名称
|
GoodName string `json:"goodName"` //商品名称
|
||||||
//Num string `json:"num"` //数量
|
Num interface{} `json:"num"` //数量
|
||||||
Num int `json:"num"` //数量
|
//Num int `json:"num"` //数量
|
||||||
Price string `json:"price"` //单价
|
Price string `json:"price"` //单价
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,6 +8,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@@ -268,6 +269,7 @@ func (w *WeiPinShangClient) WPSPost(url string, paramMap map[string]any) (res []
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
//req.Proto = "HTTP/2"
|
||||||
|
|
||||||
req.Header.Set("Content-Type", "application/json")
|
req.Header.Set("Content-Type", "application/json")
|
||||||
req.Header.Set("channelType", w.ChannelType)
|
req.Header.Set("channelType", w.ChannelType)
|
||||||
@@ -276,13 +278,15 @@ func (w *WeiPinShangClient) WPSPost(url string, paramMap map[string]any) (res []
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
req.Header.Set("md5", sign)
|
req.Header.Set("md5", sign)
|
||||||
|
//log.Printf("WPSPost req: %+v\n", req)
|
||||||
// 创建 HTTP 客户端
|
// 创建 HTTP 客户端
|
||||||
client := &http.Client{}
|
client := &http.Client{}
|
||||||
|
//log.Printf("WPSPost client: %+v\n", client)
|
||||||
// 发送请求
|
// 发送请求
|
||||||
resp, err := client.Do(req)
|
resp, err := client.Do(req)
|
||||||
|
//log.Printf("WPSPost resp: %+v\n", resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Printf("发送请求失败: %+v\n", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer func(Body io.ReadCloser) {
|
defer func(Body io.ReadCloser) {
|
||||||
|
@@ -80,14 +80,14 @@ func TestWeiPinShangClient_PreOrder(t *testing.T) {
|
|||||||
Key: "f654ea5bde7635c3f46191191e5c4c8e",
|
Key: "f654ea5bde7635c3f46191191e5c4c8e",
|
||||||
},
|
},
|
||||||
args: PreOrderReq{
|
args: PreOrderReq{
|
||||||
GoodsInfo: "[{\"goodsId\":\"WPS9_282520\",\"goodSpecId\":\"WPS9_1221183858889276\",\"num\":2}]",
|
GoodsInfo: "[{\"goodsId\":\"WPS2_1231155626421463\",\"goodSpecId\":\"WPS2_12311556265677476\",\"num\":1}]",
|
||||||
Province: "广东省",
|
Province: "广东省",
|
||||||
Address: "奥园",
|
Address: "奥园",
|
||||||
City: "广州市",
|
City: "广州市",
|
||||||
Area: "番禺区",
|
Area: "番禺区",
|
||||||
ConsigneePhone: "15375390426",
|
ConsigneePhone: "15375390426",
|
||||||
ConsigneeContacts: "张三",
|
ConsigneeContacts: "张三",
|
||||||
LockCode: "L100000000",
|
LockCode: "L100000004",
|
||||||
Source: "AILEHUI",
|
Source: "AILEHUI",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -135,8 +135,8 @@ func TestWeiPinShangClient_CreateOrder(t *testing.T) {
|
|||||||
Key: "f654ea5bde7635c3f46191191e5c4c8e",
|
Key: "f654ea5bde7635c3f46191191e5c4c8e",
|
||||||
},
|
},
|
||||||
args: CreateOrderReq{
|
args: CreateOrderReq{
|
||||||
LockCode: "L100000000",
|
LockCode: "L100000004",
|
||||||
OrderNo: "30000000000",
|
OrderNo: "2000000004",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@@ -292,7 +292,7 @@ func TestWeiPinShangClient_GetOrderInfoByThirdNO(t *testing.T) {
|
|||||||
Key: "f654ea5bde7635c3f46191191e5c4c8e",
|
Key: "f654ea5bde7635c3f46191191e5c4c8e",
|
||||||
},
|
},
|
||||||
args: args{
|
args: args{
|
||||||
orderNo: "570872619444771455",
|
orderNo: "570853643339733632",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user