优化和平小店碎片兑换链路
This commit is contained in:
@@ -256,6 +256,7 @@ type xiaodianRecommendation struct {
|
||||
type xiaodianItem struct {
|
||||
GoodsID string `json:"iGoodsId"`
|
||||
GoodsName string `json:"sGoodsName"`
|
||||
ActionID xiaodianFlexibleString `json:"iActionId"`
|
||||
Category xiaodianFlexibleString `json:"iCategoryId"`
|
||||
Price string `json:"iPrice"`
|
||||
JB2Price string `json:"iJb2Price"`
|
||||
@@ -264,7 +265,6 @@ type xiaodianItem struct {
|
||||
GoodsPic string `json:"sGoodsPic"`
|
||||
ShowBegin string `json:"dtShowBeginTime"`
|
||||
ShowEnd string `json:"dtShowEndTime"`
|
||||
ActionID string `json:"iActionId"`
|
||||
}
|
||||
|
||||
type xiaodianFlexibleString string
|
||||
@@ -328,6 +328,16 @@ type xiaodianBuyInfo struct {
|
||||
|
||||
// xiaodianEmbedQuery 获取斗鱼为当前账号签发的短时道具城参数。
|
||||
func (c *DouyuClient) xiaodianEmbedQuery(cookie string) (url.Values, error) {
|
||||
return c.xiaodianEmbedQueryWithCache(cookie, true)
|
||||
}
|
||||
|
||||
// xiaodianEmbedQueryFresh 每次调用都重新获取 H5 授权,供会真实扣款的兑换请求使用。
|
||||
// code/sig/timestamp 是短时凭证,不应跨兑换轮次长期复用。
|
||||
func (c *DouyuClient) xiaodianEmbedQueryFresh(cookie string) (url.Values, error) {
|
||||
return c.xiaodianEmbedQueryWithCache(cookie, false)
|
||||
}
|
||||
|
||||
func (c *DouyuClient) xiaodianEmbedQueryWithCache(cookie string, useCache bool) (url.Values, error) {
|
||||
uid := cookieValue(cookie, "acf_uid")
|
||||
stk := cookieValue(cookie, "acf_stk")
|
||||
ltkid := cookieValue(cookie, "acf_ltkid")
|
||||
@@ -335,8 +345,10 @@ func (c *DouyuClient) xiaodianEmbedQuery(cookie string) (url.Values, error) {
|
||||
return nil, errors.New("斗鱼 Cookie 缺少 acf_uid、acf_stk 或 acf_ltkid,无法获取和平小店授权")
|
||||
}
|
||||
cacheKey := uid + ":" + c.Activity.ActAlias + ":" + c.Activity.RoomID
|
||||
if cached, ok := c.getXiaodianEmbedCache(cacheKey); ok {
|
||||
return cached, nil
|
||||
if useCache {
|
||||
if cached, ok := c.getXiaodianEmbedCache(cacheKey); ok {
|
||||
return cached, nil
|
||||
}
|
||||
}
|
||||
endpoint, err := url.Parse(c.Activity.RoleParamURL)
|
||||
if err != nil {
|
||||
@@ -539,6 +551,7 @@ func (c *DouyuClient) xiaodianProducts(cookie string, options types.XiaodianProd
|
||||
products = append(products, types.Product{
|
||||
CommodityID: item.GoodsID,
|
||||
CommodityName: item.GoodsName,
|
||||
ActionID: string(item.ActionID),
|
||||
Category: string(item.Category),
|
||||
Score: price,
|
||||
PayType: payType,
|
||||
@@ -1231,7 +1244,7 @@ func (c *DouyuClient) xiaodianExchange(cookie string, product types.Product) (st
|
||||
if strings.TrimSpace(product.CommodityID) == "" {
|
||||
return "", errors.New("商品 ID 为空")
|
||||
}
|
||||
embedQuery, err := c.xiaodianEmbedQuery(cookie)
|
||||
embedQuery, err := c.xiaodianEmbedQueryFresh(cookie)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -1254,7 +1267,11 @@ func (c *DouyuClient) xiaodianExchange(cookie string, product types.Product) (st
|
||||
query.Set("_jsvar", "buyInfo")
|
||||
query.Set("acctype", "livelink")
|
||||
query.Set("_app_id", "2123")
|
||||
query.Set("iActionId", c.Activity.ActID)
|
||||
actionID := strings.TrimSpace(product.ActionID)
|
||||
if actionID == "" {
|
||||
actionID = c.Activity.ActID
|
||||
}
|
||||
query.Set("iActionId", actionID)
|
||||
query.Set("propid", product.CommodityID)
|
||||
query.Set("paytype", strconv.Itoa(payType))
|
||||
query.Set("source", c.Activity.RoomID)
|
||||
|
||||
@@ -177,7 +177,7 @@ func TestProductsAutomaticallyResolvesXiaodianRoleAndPaginates(t *testing.T) {
|
||||
} else {
|
||||
switch offset {
|
||||
case "0":
|
||||
items = []map[string]string{{"iGoodsId": "g1", "sGoodsName": "商品一", "iCategoryId": "1", "iPrice": "10", "sPayType": "qpqb", "iGoodsLeft": "-1"}, {"iGoodsId": "g2", "sGoodsName": "特惠商品", "iCategoryId": "45", "iPrice": "0", "iJb2Price": "20", "sPayType": "jb2", "iGoodsLeft": "3"}}
|
||||
items = []map[string]string{{"iGoodsId": "g1", "iActionId": "act-g1", "sGoodsName": "商品一", "iCategoryId": "1", "iPrice": "10", "sPayType": "qpqb", "iGoodsLeft": "-1"}, {"iGoodsId": "g2", "sGoodsName": "特惠商品", "iCategoryId": "45", "iPrice": "0", "iJb2Price": "20", "sPayType": "jb2", "iGoodsLeft": "3"}}
|
||||
case "2":
|
||||
items = []map[string]string{{"iGoodsId": "g2", "sGoodsName": "重复商品", "iCategoryId": "45", "iPrice": "0", "iJb2Price": "20", "sPayType": "jb2", "iGoodsLeft": "3"}, {"iGoodsId": "g4", "sGoodsName": "商品四", "iCategoryId": "1", "iPrice": "40", "sPayType": "qpqb", "iGoodsLeft": "0"}}
|
||||
}
|
||||
@@ -219,6 +219,9 @@ func TestProductsAutomaticallyResolvesXiaodianRoleAndPaginates(t *testing.T) {
|
||||
if products[1].Category != "45" || products[3].Score != 30 {
|
||||
t.Fatalf("商品字段 = %#v", products)
|
||||
}
|
||||
if products[0].ActionID != "act-g1" {
|
||||
t.Fatalf("商品动作 ID = %q", products[0].ActionID)
|
||||
}
|
||||
if products[0].PayType != 1 || products[0].PayLabel != "点券" || products[1].PayType != 5 || products[1].PayLabel != "扭蛋碎片" || products[1].Score != 20 {
|
||||
t.Fatalf("支付字段 = %#v", products)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user