From dfc493c655c796c579701788930ca309caeb28dd Mon Sep 17 00:00:00 2001 From: chenlin Date: Wed, 26 Mar 2025 18:09:34 +0800 Subject: [PATCH] =?UTF-8?q?1=E3=80=81=E6=96=B0=E5=A2=9E=E5=92=AA=E5=92=95?= =?UTF-8?q?=E9=9F=B3=E4=B9=90=E5=AE=9A=E6=97=B6=E4=BB=BB=E5=8A=A1=EF=BC=8C?= =?UTF-8?q?=E6=AF=8F=E5=A4=A900:30=E8=BF=9B=E8=A1=8C=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=EF=BC=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/admin/models/migu.go | 5 +- app/admin/models/migu_music.go | 313 +++++++++++++++++++++++++++++++++ cmd/api/server.go | 6 + 3 files changed, 323 insertions(+), 1 deletion(-) create mode 100644 app/admin/models/migu_music.go diff --git a/app/admin/models/migu.go b/app/admin/models/migu.go index d40729f..ebc746c 100644 --- a/app/admin/models/migu.go +++ b/app/admin/models/migu.go @@ -1184,7 +1184,9 @@ func CheckAllOrderState() { // 查询订单列表中未退订的用户,查询其是否退订;如果退订,则更新退订时间,判断是否为1小时内退订 var orderList []MgOrder - err := database.Db.Where("state = 1").Order("created_at desc"). + err := database.Db.Where("state = 1"). + Where("product_id = ?", ProductID). + Order("created_at desc"). Find(&orderList).Error //err := database.Db.Where("state = 1 and created_at >= ? and created_at <= ?", "2024-10-01 00:00:00", "2024-10-31 23:59:59").Order("created_at desc"). @@ -1280,6 +1282,7 @@ func CheckCancelOrderState() { err := database.Db.Where("state = 2"). Where("unsubscribe_time >= ?", twoDaysAgo). + Where("product_id = ?", ProductID). Order("created_at desc"). Find(&orderList).Error diff --git a/app/admin/models/migu_music.go b/app/admin/models/migu_music.go new file mode 100644 index 0000000..28b89f6 --- /dev/null +++ b/app/admin/models/migu_music.go @@ -0,0 +1,313 @@ +package models + +import ( + "crypto/md5" + "encoding/hex" + "encoding/json" + "fmt" + "github.com/go-admin-team/go-admin-core/logger" + "go-admin/common/database" + "io" + "net/http" + "net/url" + "time" +) + +const ( + MusicProductID = 2 + MaxRetries = 3 + LoginType = "3" + ServiceId = "698039049108516515" + + MiGuSubscriptionUrl = "http://hz.migu.cn/order/rest/201906/all/bjhy/and/package/query.do" + MiGuLoginUrl = "http://hz.migu.cn/order/rest/login/secret/url.do" + SignSecretKey = "1524b4ed9eef4cdca934056499a1dd14" // 签名密钥 + LoginSecretKey = "913efe5c6f274c278988af817f9d1c7d" // 登陆密钥 +) + +type MonthlySubscriptionReq struct { + ChannelCode string `json:"channelCode"` + Timestamp string `json:"timestamp"` + Signature string `json:"signature"` + Token string `json:"token"` + ServiceId string `json:"serviceId"` +} + +type MonthlySubscriptionResp struct { + ResCode string `json:"resCode"` + ResMsg string `json:"resMsg"` + Status string `json:"status"` + ValidTime string `json:"validTime"` +} + +func generateSignature(channelCode, timestamp string) string { + data := channelCode + timestamp + SignSecretKey + hash := md5.Sum([]byte(data)) + return hex.EncodeToString(hash[:]) +} + +func MonthlySubscriptionQuery(token, serviceId, channelCode string) (MonthlySubscriptionResp, error) { + fmt.Println("MonthlySubscriptionQuery start") + logger.Info("MonthlySubscriptionQuery start") + + var respData MonthlySubscriptionResp + + timestamp := time.Now().Format("20060102150405") + signature := generateSignature(channelCode, timestamp) + + reqBody := MonthlySubscriptionReq{ + ChannelCode: channelCode, + Timestamp: timestamp, + Signature: signature, + Token: token, + ServiceId: serviceId, + } + + jsonData, err := json.Marshal(reqBody) + if err != nil { + fmt.Println("Error marshalling request body:", err) + return respData, err + } + fmt.Println("MonthlySubscriptionQuery req:", string(jsonData)) + logger.Info("MonthlySubscriptionQuery req:", string(jsonData)) + + client := &http.Client{} + req, err := http.NewRequest("GET", MiGuSubscriptionUrl+"?data="+url.QueryEscape(string(jsonData)), nil) + if err != nil { + fmt.Println("Error creating HTTP request:", err) + logger.Error("Error creating HTTP request:", err) + return respData, err + } + + req.Header.Set("Content-Type", "application/json; charset=utf-8") + + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making HTTP request:", err) + logger.Error("Error making HTTP request:", err) + return respData, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error reading response body:", err) + logger.Error("Error reading response body:", err) + return respData, err + } + + fmt.Println("MonthlySubscriptionQuery resp:", string(body)) + logger.Info("MonthlySubscriptionQuery resp:", string(body)) + + err = json.Unmarshal(body, &respData) + if err != nil { + fmt.Println("Error unmarshalling response body:", err) + logger.Error("Error unmarshalling response body:", err) + return respData, err + } + + fmt.Println("MonthlySubscriptionQuery end") + logger.Info("MonthlySubscriptionQuery end") + + return respData, nil +} + +type LoginRequest struct { + ChannelCode string `json:"channelCode"` + Timestamp string `json:"timestamp"` + Signature string `json:"signature"` + LoginType string `json:"loginType"` + CallBackUrl string `json:"callBackUrl,omitempty"` + Key string `json:"key,omitempty"` + Msisdn string `json:"msisdn,omitempty"` +} + +type LoginResponse struct { + ResCode string `json:"resCode"` + ResMsg string `json:"resMsg"` + Token string `json:"token"` +} + +func Login(channelCode, loginType, callBackUrl, msisdn string) (LoginResponse, error) { + fmt.Println("login start") + logger.Info("login start") + var respData LoginResponse + + timestamp := time.Now().Format("20060102150405") + signature := generateSignature(channelCode, timestamp) + + reqBody := LoginRequest{ + ChannelCode: channelCode, + Timestamp: timestamp, + Signature: signature, + LoginType: loginType, + } + + if loginType == "1" && callBackUrl != "" { + reqBody.CallBackUrl = callBackUrl + } else if loginType == "3" { + reqBody.Key = LoginSecretKey + reqBody.Msisdn = msisdn + } + + jsonData, err := json.Marshal(reqBody) + if err != nil { + fmt.Println("Error marshalling request body:", err) + return respData, err + } + fmt.Println("login req:", string(jsonData)) + logger.Info("login req:", string(jsonData)) + + client := &http.Client{} + req, err := http.NewRequest("GET", MiGuLoginUrl+"?data="+url.QueryEscape(string(jsonData)), nil) + if err != nil { + fmt.Println("Error creating HTTP request:", err) + logger.Error("Error creating HTTP request:", err) + return respData, err + } + + req.Header.Set("Content-Type", "application/json; charset=utf-8") + + resp, err := client.Do(req) + if err != nil { + fmt.Println("Error making HTTP request:", err) + logger.Error("Error making HTTP request:", err) + return respData, err + } + defer resp.Body.Close() + + body, err := io.ReadAll(resp.Body) + if err != nil { + fmt.Println("Error reading response body:", err) + logger.Error("Error reading response body:", err) + return respData, err + } + + fmt.Println("login resp:", string(body)) + logger.Info("login resp:", string(body)) + + err = json.Unmarshal(body, &respData) + if err != nil { + fmt.Println("Error unmarshalling response body:", err) + logger.Error("Error unmarshalling response body:", err) + return respData, err + } + + fmt.Println("login end") + logger.Info("login end") + + return respData, nil +} + +// CheckMusicOrderState 定时任务,检查咪咕音乐的订单是否有退订 +func CheckMusicOrderState() { + logger.Info("****** CheckMusicOrderState start ******") + fmt.Println("****** CheckMusicOrderState start ******") + if database.Db == nil { + logger.Error("Database connection is nil") + fmt.Println("Database connection is nil") + return + } + + // 查询订单列表中未退订的用户,查询其是否退订;如果退订,则更新退订时间 + var orderList []MgOrder + + err := database.Db.Where("state = 1"). + Where("product_id = ?", MusicProductID). + Order("created_at desc"). + Find(&orderList).Error + + if err != nil { + fmt.Println("query mg_order err:", err.Error()) + logger.Error("query mg_order err:", err.Error()) + return + } + + fmt.Println("orderList size is:", len(orderList)) + logger.Info("orderList size is:", len(orderList)) + + for _, order := range orderList { + var token string + + // 登录接口调用 + if !attemptLogin(&token, order) { + continue + } + + // 订阅状态查询 + if !checkSubscriptionStatus(token, order) { + continue + } + } + + fmt.Println("****** CheckMusicOrderState end ******") + logger.Info("****** CheckMusicOrderState end ******") +} + +func attemptLogin(token *string, order MgOrder) bool { + for j := 0; j < MaxRetries; j++ { + resp, err := Login(order.ChannelCode, LoginType, "", order.PhoneNumber) + if err != nil || resp.ResCode != "000000" { + if err != nil { + fmt.Println("Login failed:", err.Error()) + logger.Error("Login failed:", err.Error()) + } else { + fmt.Println("Login failed, loginResp:", resp) + logger.Error("Login failed, loginResp:", resp) + } + + if j < MaxRetries-1 { + continue + } + return false + } + *token = resp.Token + return true + } + return false +} + +func checkSubscriptionStatus(token string, order MgOrder) bool { + for j := 0; j < MaxRetries; j++ { + resp, err := MonthlySubscriptionQuery(token, ServiceId, order.ChannelCode) + if err != nil || resp.ResCode != "000000" { + if err != nil { + fmt.Println("MonthlySubscriptionQuery failed:", err.Error()) + logger.Error("MonthlySubscriptionQuery failed:", err.Error()) + } else { + fmt.Println("MonthlySubscriptionQuery failed, MonthlySubscriptionResp:", resp.ResCode) + logger.Error("MonthlySubscriptionQuery failed, MonthlySubscriptionResp:", resp.ResCode) + } + + if j < MaxRetries-1 { + continue + } + return false + } + + if resp.Status == "0" { + return true + } else if resp.Status == "1" { + subscribeTime := order.CreatedAt + unsubTime := time.Now().Format("2006-01-02 15:04:05") + cancelFlag := 0 + + if IsWithinOneHourCancel(subscribeTime, unsubTime) { + cancelFlag = 1 + } + + err = database.Db.Table("mg_order").Where("order_serial = ?", order.OrderSerial).Updates(map[string]interface{}{ + "state": UnsubscribeOK, + "is_one_hour_cancel": cancelFlag, + "unsubscribe_time": unsubTime, + "updated_at": time.Now(), + }).Error + if err != nil { + fmt.Println("Failed to update order:", err.Error()) + logger.Error("Failed to update order:", err.Error()) + } + return false + } + } + return false +} diff --git a/cmd/api/server.go b/cmd/api/server.go index 3a1b587..bbcf2ae 100644 --- a/cmd/api/server.go +++ b/cmd/api/server.go @@ -102,6 +102,12 @@ func run() error { fmt.Println("err:", err) } + // 咪咕音乐订阅数据检测 + err = s.Every(1).Day().At("00:30").Do(models.CheckMusicOrderState) + if err != nil { + fmt.Println("err:", err) + } + //err = s.Every(1).Day().At("09:50").Do(models.CheckOneHourCancelOrderState) //if err != nil { // fmt.Println("err:", err)