admin_backend/sdk/ship/model/test/test.go
2026-04-15 14:48:13 +08:00

201 lines
6.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package test
import (
"backend/Type"
"backend/client"
"backend/common"
"backend/middleware/feishu"
"backend/msg"
"backend/sdk/ship/model/base"
"backend/util"
"crypto/md5"
"encoding/json"
"fmt"
"log"
"reflect"
"sort"
"strings"
"time"
"github.com/gin-gonic/gin"
)
type TestModel struct {
}
type ChargeRequest struct {
ApiVer string `json:"apiver" form:"apiver" binding:"required" description:"SDK服务端支付API版本"`
AppID string `json:"appId" form:"appId" binding:"required" description:"cp应用ID"`
AppInfo string `json:"appInfo" form:"appInfo" description:"项目透传信息"`
ChargedDiamonds string `json:"chargedDiamonds" form:"chargedDiamonds" description:"充值钻石数量一般为充值金额的10倍"`
ChargedRmbs string `json:"chargedRmbs" form:"chargedRmbs" description:"充值金额(元)"`
ClientID string `json:"clientId" form:"clientId" binding:"required" description:"途游客户端包id"`
ConsumeCoin string `json:"consumeCoin" form:"consumeCoin" description:"消耗金币数量一般为充值金额的10倍"`
ConsumeID string `json:"consumeId" form:"consumeId" description:"本次消耗事务id"`
OrderID string `json:"orderId" form:"orderId" description:"CP订单号"`
PlatformOrder string `json:"platformOrder" form:"platformOrder" description:"SDK订单号"`
ProdCount string `json:"prodCount" form:"prodCount" description:"商品数量默认为1"`
UserID string `json:"userId" form:"userId" binding:"required" description:"SDK用户ID"`
ProdID string `json:"prodId" form:"prodId" description:"商品ID"`
ProdPrice string `json:"prodPrice" form:"prodPrice" description:"商品价格"`
Code string `json:"code" form:"code" binding:"required" description:"回调签名"`
}
const (
APP_KEY = "8001bd25832553c39d4b443f56480841"
)
// 增加 Sign 方法:按 json tag 名称收集参数,排除 code按 ASCII 升序拼接 key=value 用 & 连接,最后 MD5 并返回小写十六进制字符串。
func (r *ChargeRequest) Sign() string {
if r == nil {
return ""
}
// 收集参数到 map[key]=string(value)
params := make(map[string]string)
val := reflect.ValueOf(*r)
typ := reflect.TypeOf(*r)
for i := 0; i < typ.NumField(); i++ {
field := typ.Field(i)
// 使用 json tag 作为键名,若为空则 fallback 到字段名
tag := field.Tag.Get("json")
key := strings.Split(tag, ",")[0]
if key == "" {
key = field.Name
}
// 排除 code
if key == "code" {
continue
}
fv := val.Field(i)
var s string
if fv.Kind() == reflect.String {
s = fv.String()
} else {
s = fmt.Sprintf("%v", fv.Interface())
}
params[key] = s
}
// 排序键名
keys := make([]string, 0, len(params))
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)
// 拼接签名源字符串
var b strings.Builder
for i, k := range keys {
if i > 0 {
b.WriteByte('&')
}
b.WriteString(k)
b.WriteByte('=')
b.WriteString(params[k])
}
checkstr := b.String()
checkstr = APP_KEY + checkstr + APP_KEY
// 计算 MD5 并返回小写十六进制字符串
sum := md5.Sum([]byte(checkstr))
return fmt.Sprintf("%x", sum)
}
func Charge(c *gin.Context) {
var req ChargeRequest
if err := c.ShouldBind(&req); err != nil {
log.Print("binding error:", err)
c.JSON(400, gin.H{"error": err.Error()})
return
}
expectedSign := req.Sign()
if req.Code != expectedSign {
// FeishuNotify(fmt.Sprintf("invalid signature: got %s, expected %s", req.Code, expectedSign))
// log.Printf("invalid signature: got %s, expected %s", req.Code, expectedSign)
// c.JSON(401, gin.H{"error": "invalid signature"})
// return
}
var AppInfo base.Param
if err := json.Unmarshal([]byte(req.AppInfo), &AppInfo); err != nil {
FeishuNotify(fmt.Sprintf("unmarshal AppInfo error:%v", err))
log.Print("unmarshal AppInfo error:", err)
c.JSON(400, gin.H{"error": "invalid AppInfo"})
return
}
if AppInfo.Uid != 100001 {
log.Printf("test debug error request %v", AppInfo)
return
}
AppInfo.ChannelOrderId = req.PlatformOrder
err := AppInfo.ChangeOrderStatus("test", req.ProdPrice)
if err != nil {
//alibaba.SendStandardMsg("途游充值发货错误-测试", err.Error(), "red")
log.Print("change order status error:", err)
c.JSON(500, gin.H{"error": "failed to change order status"})
return
}
go Shipping(AppInfo)
c.String(200, "success")
}
// http://localhost:5240/api/tuyou/charge?apiver=2&appId=20659&appInfo=%7B%22appId%22%3A0%2C%22serverId%22%3A1%2C%22orderId%22%3A%22order_105372_20260125225337HhpqbU%22%2C%22uid%22%3A105372%7D&chargedDiamonds=20&chargedRmbs=1.99&clientId=Android_5.00_tyGuest%2Cfacebook.googleplay.0-hall20659.googleplay.Meowment&consumeCoin=20&consumeId=d50b32601260117387&orderId=-&platformOrder=e50b3260126045d972&prodCount=1&prodId=TY206590059&prodPrice=1.99&userId=3790944&code=fd7532d651bed4c3041aa3e628bef80b
func Shipping(AppInfo base.Param) {
if common.GetRpcSwitch() {
err := client.OrderShipping(AppInfo.AppId, AppInfo.ServerId, &msg.ReqOrderShipping{
OrderSn: AppInfo.OrderId,
Status: 1,
ChannelOrderSn: AppInfo.ChannelOrderId,
})
if err == nil {
log.Printf("rpc order shipping success;AppId:%d;ServerId:%d;OrderId:%s", AppInfo.AppId, AppInfo.ServerId, AppInfo.OrderId)
return
}
}
Adminreq := &msg.ReqAdminShipping{
OrderSn: AppInfo.OrderId,
Status: 1,
ChannelOrderSn: AppInfo.ChannelOrderId,
}
num := 0
log.Print("charge shipping start;AppId:", AppInfo.AppId, ";ServerId:", AppInfo.ServerId, ";OrderId:", AppInfo.OrderId)
for {
num++
if num > 100 {
log.Print("charge shipping break infinite loop;AppId:", AppInfo.AppId, ";ServerId:", AppInfo.ServerId, ";OrderId:", AppInfo.OrderId)
break
}
ws, err := util.GetWebsocket(AppInfo.AppId, AppInfo.ServerId)
if err != nil {
time.Sleep(time.Second)
continue
}
r, err := util.SendAdminMsg(ws, Adminreq)
// close the websocket immediately to avoid accumulating defers in the loop
if closeErr := ws.Close(); closeErr != nil {
log.Printf("failed to close websocket: %v", closeErr)
}
if err != nil {
time.Sleep(time.Second)
continue
}
if r != nil {
log.Printf("ws charge shipping success:orderSn:%s;res:%v", AppInfo.OrderId, r)
break
}
}
}
func FeishuNotify(EvnetName string) {
feishu.SendNotifyMsg(&Type.NotifyData{
NotifyMsg: "支付发货失败",
Host: "途游",
EventName: EvnetName,
Severity: "High",
AlarmTime: time.Unix(time.Now().Unix(), 0).Format("2006-01-02 15:04:05"),
})
}