2025-03-26 10:09:34 +00:00
|
|
|
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" {
|
2025-03-28 05:59:48 +00:00
|
|
|
if order.State == SubscribeOK {
|
|
|
|
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
|
2025-03-26 10:09:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false
|
|
|
|
}
|