diff --git a/app/admin/apis/migumanage/migu_music.go b/app/admin/apis/migumanage/migu_music.go index b04ae80..32e8fc9 100644 --- a/app/admin/apis/migumanage/migu_music.go +++ b/app/admin/apis/migumanage/migu_music.go @@ -24,6 +24,196 @@ import ( // @Param request body models.ResultFeedbackEvt true "咪咕音乐回调通知接口" // @Success 200 {object} models.MusicFeedbackResp // @Router /api/v1/migu/music/feedback [post] + +//func (e MiGuDeployService) MusicFeedback(c *gin.Context) { +// fmt.Println("MusicFeedback-start") +// logger.Info("MusicFeedback-start") +// +// // 打印请求 Header +// //fmt.Println("Headers:", c.Request.Header) +// +// // 打印 URL Query 参数 (GET 参数) +// //fmt.Println("Query Params:", c.Request.URL.RawQuery) +// +// // 打印 Form 参数 (x-www-form-urlencoded / form-data) +// //if err := c.Request.ParseForm(); err == nil { +// // fmt.Println("Form Params:", c.Request.Form) +// //} +// +// // 读取 Body 参数 (JSON/Raw) +// bodyBytes, err := io.ReadAll(c.Request.Body) +// if err != nil { +// fmt.Println("Failed to read body:", err) +// logger.Error(err) +// app.Error(c, http.StatusBadRequest, err, "读取Body失败") +// return +// } +// +// fmt.Println("Body Params:", string(bodyBytes)) +// logger.Info("Body Params:", string(bodyBytes)) +// +// // 反序列化 JSON 为 Map +// var jsonData map[string]interface{} +// if err = json.Unmarshal(bodyBytes, &jsonData); err == nil { +// fmt.Println("JSON Params:", jsonData) +// } else { +// fmt.Println("Failed to unmarshal JSON:", err) +// } +// +// // **不再调用 c.ShouldBindJSON**,直接从 bodyBytes 反序列化 +// req := &models.ResultFeedbackEvt{} +// if err = json.Unmarshal(bodyBytes, req); err != nil { +// logger.Errorf("MusicFeedback para err: %v", err) +// app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") +// return +// } +// +// logger.Info("MusicFeedback req:", req) +// +// // 初始化数据库 +// err = e.MakeContext(c).MakeOrm().Errors +// if err != nil { +// fmt.Println("MusicFeedback err:", err) +// e.Logger.Error(err) +// app.Error(c, http.StatusInternalServerError, err, "初始化失败") +// return +// } +// +// details, err := models.ParseMsg(req.Msg) +// if err != nil { +// logger.Errorf("MusicFeedback ParseMsg err:", err.Error()) +// app.Error(c, http.StatusInternalServerError, err, "msg格式有误") +// return +// } +// +// // 记录数据库 +// var sendLog models.MgTransactionLog +// sendLog.ProductID = models.MusicProductID +// sendLog.ChannelCode = details.ChannelCode +// sendLog.OutTradeNo = models.GetOrderSerial(e.Orm) +// sendLog.PhoneNumber = req.MSISDN +// sendLog.LinkId = details.CustomSerialNo +// sendLog.Result = req.ResCode +// sendLog.Reason = fmt.Sprintf("[%s]:%s", req.ResDesc, req.Msg) +// sendLog.ChannelTradeNo = details.CustomSerialNo +// if req.ResCode != "000000" { +// sendLog.VerificationCode = "999999" +// } else { +// if req.ResCode == "000000" && (details.OrderKeyword == "BJHY" || details.OrderKeyword == "SPGW") { +// sendLog.VerificationCode = "666666" +// } +// sendLog.Result = "00000" // 跟咪咕钻石会员保持一致 +// } +// +// err = e.Orm.Create(&sendLog).Error +// if err != nil { +// logger.Info("Create MgTransactionLog err:", err) +// app.MiGuError(c, http.StatusBadRequest, err, err.Error()) +// return +// } +// +// if req.ResCode == "000000" { // 提交订阅成功则记录到订单表 +// var lastOrder models.MgOrder +// result := e.Orm.Model(&models.MgOrder{}).Where("phone_number = ?", req.MSISDN). +// Order("subscribe_time DESC").First(&lastOrder) +// +// nowTime, err := models.ParseRevDate(req.RevDate) +// if err != nil { +// nowTime = time.Now() +// } +// +// if errors.Is(result.Error, gorm.ErrRecordNotFound) || (details.OrderKeyword == "BJHY" || details.OrderKeyword == "SPGW") { +// flag := true +// if lastOrder.ID != 0 { +// timeDiff := nowTime.Sub(lastOrder.CreatedAt) +// if timeDiff < 2*time.Minute { +// flag = false +// } +// } +// if flag { +// // 插入新记录 +// var orderInfo models.MgOrder +// orderInfo.ProductID = models.MusicProductID +// orderInfo.ChannelCode = details.ChannelCode +// orderInfo.OrderSerial = models.GetOrderSerial(e.Orm) +// orderInfo.SubscribeTime = &nowTime +// orderInfo.PhoneNumber = req.MSISDN +// orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.MSISDN) +// +// if details.CustomSerialNo == "" { +// details.CustomSerialNo = orderInfo.OrderSerial +// } +// orderInfo.ChannelTradeNo = details.CustomSerialNo +// orderInfo.ExternalOrderID = details.CustomSerialNo +// orderInfo.State = models.SubscribeOK +// +// if err = e.Orm.Create(&orderInfo).Error; err != nil { +// logger.Error(err) +// } +// } +// } else if details.OrderKeyword == "BJTD" || details.OrderKeyword == "SPTD" || details.OrderKeyword == "SPJF" || details.OrderKeyword == "TD" { +// if lastOrder.IsOneHourCancel != 1 { // 非1小时退订才更新,否则不用更新 +// // 未订购,更新订单状态 +// var cancelFlag int +// subscribeTime := lastOrder.CreatedAt +// unsubTime := time.Now().Format("2006-01-02 15:04:05") +// +// // 检查是否在1小时内取消 +// if models.IsWithinOneHourCancel(subscribeTime, unsubTime) { +// cancelFlag = 1 +// } +// +// // 更新订单状态 +// err = database.Db.Table("mg_order").Where("phone_number = ?", req.MSISDN).Updates(map[string]interface{}{ +// "state": models.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()) +// } +// } +// } +// +// //// 记录到订单列表 +// //var orderInfo models.MgOrder +// //orderInfo.ProductID = models.MusicProductID +// //orderInfo.ChannelCode = details.ChannelCode +// //orderInfo.OrderSerial = models.GetOrderSerial(e.Orm) +// //nowTime, err := models.ParseRevDate(req.RevDate) +// //if err != nil { +// // nowTime = time.Now() +// //} +// //orderInfo.SubscribeTime = &nowTime +// //orderInfo.PhoneNumber = req.MSISDN +// //orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.MSISDN) +// // +// //if details.CustomSerialNo == "" { +// // details.CustomSerialNo = orderInfo.OrderSerial +// //} +// //orderInfo.ChannelTradeNo = details.CustomSerialNo +// //orderInfo.ExternalOrderID = details.CustomSerialNo +// //orderInfo.State = models.SubscribeOK +// // +// //err = e.Orm.Create(&orderInfo).Error +// //if err != nil { +// // logger.Info("Create MgTransactionLog err:", err) +// // //app.Error(c, http.StatusBadRequest, err, err.Error()) +// // //return +// //} +// } +// +// fmt.Println("MusicFeedback-end") +// logger.Info("MusicFeedback-end") +// +// var resp models.MusicFeedbackResp +// resp.ReturnCode = "OK" +// +// app.MiGuOK(c, resp) +//} + func (e MiGuDeployService) MusicFeedback(c *gin.Context) { fmt.Println("MusicFeedback-start") logger.Info("MusicFeedback-start") @@ -86,7 +276,7 @@ func (e MiGuDeployService) MusicFeedback(c *gin.Context) { } // 记录数据库 - var sendLog models.MgTransactionLog + var sendLog models.MgTransactionLogAi sendLog.ProductID = models.MusicProductID sendLog.ChannelCode = details.ChannelCode sendLog.OutTradeNo = models.GetOrderSerial(e.Orm) @@ -112,16 +302,211 @@ func (e MiGuDeployService) MusicFeedback(c *gin.Context) { } if req.ResCode == "000000" { // 提交订阅成功则记录到订单表 + if details.OrderKeyword == "BJTD" || details.OrderKeyword == "SPTD" || details.OrderKeyword == "SPJF" || details.OrderKeyword == "TD" { + + if 1 == 1 { // 更新订单表的退订信息 + var lastOrder models.MgOrder + e.Orm.Model(&models.MgOrder{}).Where("phone_number = ?", req.MSISDN). + Order("subscribe_time DESC").First(&lastOrder) + + if lastOrder.IsOneHourCancel != 1 { // 非1小时退订才更新,否则不用更新 + // 未订购,更新订单状态 + var cancelFlag int + subscribeTime := lastOrder.CreatedAt + unsubTime := time.Now().Format("2006-01-02 15:04:05") + + // 检查是否在1小时内取消 + if models.IsWithinOneHourCancel(subscribeTime, unsubTime) { + cancelFlag = 1 + } + + // 更新订单状态 + err = database.Db.Table("mg_order").Where("phone_number = ?", req.MSISDN).Updates(map[string]interface{}{ + "state": models.UnsubscribeOK, + "is_one_hour_cancel": cancelFlag, + "unsubscribe_time": unsubTime, + "updated_at": time.Now(), + }).Error + if err != nil { + fmt.Println("Failed to update mg_order:", err.Error()) + logger.Error("Failed to update mg_order:", err.Error()) + } + } + } + + if 2 == 2 { // 更新订单log表的退订信息 + var lastOrderLog models.MgOrderLog + e.Orm.Model(&models.MgOrderLog{}).Where("phone_number = ?", req.MSISDN). + Order("subscribe_time DESC").First(&lastOrderLog) + + if lastOrderLog.IsOneHourCancel != 1 { // 非1小时退订才更新,否则不用更新 + // 未订购,更新订单状态 + var cancelFlagLog int + subscribeTimeLog := lastOrderLog.CreatedAt + unsubTimeLog := time.Now().Format("2006-01-02 15:04:05") + + // 检查是否在1小时内取消 + if models.IsWithinOneHourCancel(subscribeTimeLog, unsubTimeLog) { + cancelFlagLog = 1 + } + + // 更新订单状态 + err = database.Db.Table("mg_order_log").Where("phone_number = ?", req.MSISDN).Updates(map[string]interface{}{ + "state": models.UnsubscribeOK, + "is_one_hour_cancel": cancelFlagLog, + "unsubscribe_time": unsubTimeLog, + "updated_at": time.Now(), + }).Error + if err != nil { + fmt.Println("Failed to update mg_order_log:", err.Error()) + logger.Error("Failed to update mg_order_log:", err.Error()) + } + } + } + + } else { + var lastOrder models.MgOrderLog + err = e.Orm.Model(&models.MgOrderLog{}).Where("phone_number = ?", req.MSISDN). + Order("subscribe_time DESC").First(&lastOrder).Error + if err != nil && err != gorm.ErrRecordNotFound { + logger.Info("query mg_order_log err:", err) + app.MiGuError(c, http.StatusBadRequest, err, err.Error()) + return + } + + nowTime, err := models.ParseRevDate(req.RevDate) + if err != nil { + nowTime = time.Now() + } + + if (details.OrderKeyword == "BJHY" || details.OrderKeyword == "SPGW") && details.Price == "1990" { + flag := true + if lastOrder.ID != 0 { + timeDiff := nowTime.Sub(lastOrder.CreatedAt) + if timeDiff < 2*time.Minute { + flag = false + } + } + if flag { + // 插入新记录 + var orderInfo models.MgOrderLog + orderInfo.ProductID = models.MusicProductID + orderInfo.ChannelCode = details.ChannelCode + orderInfo.OrderSerial = models.GetOrderSerial(e.Orm) + orderInfo.SubscribeTime = &nowTime + orderInfo.PhoneNumber = req.MSISDN + orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.MSISDN) + + if details.CustomSerialNo == "" { + details.CustomSerialNo = orderInfo.OrderSerial + } + orderInfo.ChannelTradeNo = details.CustomSerialNo + orderInfo.ExternalOrderID = details.CustomSerialNo + orderInfo.State = models.SubscribeOK + + if err = e.Orm.Create(&orderInfo).Error; err != nil { + logger.Error(err) + } + } + } + } + } + + fmt.Println("MusicFeedback-end") + logger.Info("MusicFeedback-end") + + var resp models.MusicFeedbackResp + resp.ReturnCode = "OK" + + app.MiGuOK(c, resp) +} + +// AIMusicFeedback AI视频彩铃回调通知接口 +// @Summary AI视频彩铃回调通知接口 +// @Tags 2025-咪咕音乐-回调 +// @Produce json +// @Accept json +// @Param request body models.CallbackRequest true "AI视频彩铃回调通知接口" +// @Success 200 {object} models.MusicFeedbackResp +// @Router /api/v1/migu/music/order/feedback [post] +func (e MiGuDeployService) AIMusicFeedback(c *gin.Context) { + fmt.Println("AIMusicFeedback-start") + logger.Info("AIMusicFeedback-start") + + // 读取 Body 参数 (JSON/Raw) + bodyBytes, err := io.ReadAll(c.Request.Body) + if err != nil { + fmt.Println("Failed to read body:", err) + logger.Error(err) + app.Error(c, http.StatusBadRequest, err, "读取Body失败") + return + } + + fmt.Println("Body Params:", string(bodyBytes)) + logger.Info("Body Params:", string(bodyBytes)) + + // 反序列化 JSON 为 Map + var jsonData map[string]interface{} + if err = json.Unmarshal(bodyBytes, &jsonData); err == nil { + fmt.Println("JSON Params:", jsonData) + } else { + fmt.Println("Failed to unmarshal JSON:", err) + } + + // **不再调用 c.ShouldBindJSON**,直接从 bodyBytes 反序列化 + req := &models.CallbackRequest{} + if err = json.Unmarshal(bodyBytes, req); err != nil { + logger.Errorf("AIMusicFeedback para err: %v", err) + app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") + return + } + + logger.Info("AIMusicFeedback req:", req) + + // 初始化数据库 + err = e.MakeContext(c).MakeOrm().Errors + if err != nil { + fmt.Println("AIMusicFeedback err:", err) + e.Logger.Error(err) + app.Error(c, http.StatusInternalServerError, err, "初始化失败") + return + } + + // 记录数据库 + var sendLog models.MgTransactionLog + sendLog.ProductID = models.MusicProductID + sendLog.ChannelCode = req.ChannelCode + sendLog.OutTradeNo = models.GetOrderSerial(e.Orm) + sendLog.PhoneNumber = req.PhoneNumber + sendLog.LinkId = req.ExternalOrderNo + sendLog.ChannelTradeNo = req.ExternalOrderNo + if req.ResCode != 1 { + sendLog.Result = "999004" + sendLog.VerificationCode = "999999" + } else { + sendLog.Result = "00000" // 跟咪咕钻石会员保持一致 + sendLog.VerificationCode = "666666" + } + if req.ResDesc != "" { + sendLog.Reason = fmt.Sprintf("[%s]:%s", req.Province, req.ResDesc) + } else { + sendLog.Reason = fmt.Sprintf("[%s]", req.Province) + } + + err = e.Orm.Create(&sendLog).Error + if err != nil { + logger.Info("Create MgTransactionLog err:", err) + app.MiGuError(c, http.StatusBadRequest, err, err.Error()) + return + } + + if req.ResCode == 1 { // 成功消息 var lastOrder models.MgOrder - result := e.Orm.Model(&models.MgOrder{}).Where("phone_number = ?", req.MSISDN). + result := e.Orm.Model(&models.MgOrder{}).Where("phone_number = ?", req.PhoneNumber). Order("subscribe_time DESC").First(&lastOrder) - nowTime, err := models.ParseRevDate(req.RevDate) - if err != nil { - nowTime = time.Now() - } - - if errors.Is(result.Error, gorm.ErrRecordNotFound) || (details.OrderKeyword == "BJHY" || details.OrderKeyword == "SPGW") { + if errors.Is(result.Error, gorm.ErrRecordNotFound) { + nowTime := time.Now() flag := true if lastOrder.ID != 0 { timeDiff := nowTime.Sub(lastOrder.CreatedAt) @@ -129,83 +514,33 @@ func (e MiGuDeployService) MusicFeedback(c *gin.Context) { flag = false } } + if flag { // 插入新记录 var orderInfo models.MgOrder orderInfo.ProductID = models.MusicProductID - orderInfo.ChannelCode = details.ChannelCode + orderInfo.ChannelCode = req.ChannelCode orderInfo.OrderSerial = models.GetOrderSerial(e.Orm) orderInfo.SubscribeTime = &nowTime - orderInfo.PhoneNumber = req.MSISDN - orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.MSISDN) + orderInfo.PhoneNumber = req.PhoneNumber + orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.PhoneNumber) - if details.CustomSerialNo == "" { - details.CustomSerialNo = orderInfo.OrderSerial + if req.ExternalOrderNo == "" { + req.ExternalOrderNo = orderInfo.OrderSerial } - orderInfo.ChannelTradeNo = details.CustomSerialNo - orderInfo.ExternalOrderID = details.CustomSerialNo + orderInfo.ChannelTradeNo = req.ExternalOrderNo + orderInfo.ExternalOrderID = req.ExternalOrderNo orderInfo.State = models.SubscribeOK if err = e.Orm.Create(&orderInfo).Error; err != nil { logger.Error(err) } } - } else if details.OrderKeyword == "BJTD" || details.OrderKeyword == "SPTD" || details.OrderKeyword == "SPJF" || details.OrderKeyword == "TD" { - if lastOrder.IsOneHourCancel != 1 { // 非1小时退订才更新,否则不用更新 - // 未订购,更新订单状态 - var cancelFlag int - subscribeTime := lastOrder.CreatedAt - unsubTime := time.Now().Format("2006-01-02 15:04:05") - - // 检查是否在1小时内取消 - if models.IsWithinOneHourCancel(subscribeTime, unsubTime) { - cancelFlag = 1 - } - - // 更新订单状态 - err = database.Db.Table("mg_order").Where("phone_number = ?", req.MSISDN).Updates(map[string]interface{}{ - "state": models.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()) - } - } } - - //// 记录到订单列表 - //var orderInfo models.MgOrder - //orderInfo.ProductID = models.MusicProductID - //orderInfo.ChannelCode = details.ChannelCode - //orderInfo.OrderSerial = models.GetOrderSerial(e.Orm) - //nowTime, err := models.ParseRevDate(req.RevDate) - //if err != nil { - // nowTime = time.Now() - //} - //orderInfo.SubscribeTime = &nowTime - //orderInfo.PhoneNumber = req.MSISDN - //orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.MSISDN) - // - //if details.CustomSerialNo == "" { - // details.CustomSerialNo = orderInfo.OrderSerial - //} - //orderInfo.ChannelTradeNo = details.CustomSerialNo - //orderInfo.ExternalOrderID = details.CustomSerialNo - //orderInfo.State = models.SubscribeOK - // - //err = e.Orm.Create(&orderInfo).Error - //if err != nil { - // logger.Info("Create MgTransactionLog err:", err) - // //app.Error(c, http.StatusBadRequest, err, err.Error()) - // //return - //} } - fmt.Println("MusicFeedback-end") - logger.Info("MusicFeedback-end") + fmt.Println("AIMusicFeedback-end") + logger.Info("AIMusicFeedback-end") var resp models.MusicFeedbackResp resp.ReturnCode = "OK" diff --git a/app/admin/models/migu.go b/app/admin/models/migu.go index 27b49db..0653e30 100644 --- a/app/admin/models/migu.go +++ b/app/admin/models/migu.go @@ -68,6 +68,22 @@ type MgOrder struct { IsOneHourCancel int `json:"is_one_hour_cancel"` // 是否1小时内退订 1-是 其他-否 } +// MgOrderLog 订单管理表对应的结构体(回调备份) +type MgOrderLog struct { + Model + ProductID int64 `json:"product_id"` // 产品ID + ChannelCode string `gorm:"size:255" json:"channel_code"` // 渠道编码 + OrderSerial string `gorm:"size:255;not null" json:"order_serial"` // 订单流水号 + SubscribeTime *time.Time `json:"subscribe_time"` // 订阅时间 + PhoneNumber string `gorm:"size:20;not null" json:"phone_number"` // 手机号 + SM4PhoneNumber string `gorm:"size:255" json:"sm4_phone_number"` // SM4加密手机号 + ExternalOrderID string `gorm:"size:255" json:"external_order_id"` // 外部平台订单号(如咪咕等) + ChannelTradeNo string `gorm:"size:255" json:"channel_trade_no"` // 渠道订单号 + State int `gorm:"size:255" json:"state"` // 用户订阅状态 1-订阅成功 2-已取消订阅 + UnsubscribeTime *time.Time `json:"unsubscribe_time"` // 取消订阅时间 + IsOneHourCancel int `json:"is_one_hour_cancel"` // 是否1小时内退订 1-是 其他-否 +} + // MgChannel 渠道列表 type MgChannel struct { Model @@ -123,6 +139,22 @@ type MgTransactionLog struct { OrderTime *time.Time `gorm:"type:datetime" json:"order_time"` // 订单时间 } +// MgTransactionLogAi 交易流水记录表对应的结构体 +type MgTransactionLogAi struct { + Model + ProductID int64 `json:"product_id"` // 产品ID + ChannelCode string `gorm:"size:255" json:"channel_code"` // 渠道编码 + Province string `gorm:"size:255" json:"province"` // 省份 + PhoneNumber string `gorm:"size:20" json:"phone_number"` // 手机号 + OutTradeNo string `gorm:"size:255" json:"out_trade_no"` // 平台订单号 + LinkId string `gorm:"size:255" json:"link_id"` // linkId(咪咕订单号) + ChannelTradeNo string `gorm:"size:255" json:"channel_trade_no"` // 渠道订单号 + Result string `gorm:"size:255" json:"result"` // 交易结果 + Reason string `gorm:"size:255" json:"reason"` // 交易失败原因 + VerificationCode string `gorm:"size:255" json:"verification_code"` // 验证码 + OrderTime *time.Time `gorm:"type:datetime" json:"order_time"` // 订单时间 +} + // MgUserRetention 用户留存记录表对应的结构体 type MgUserRetention struct { RetentionMonth string `gorm:"size:7" json:"retention_month"` // 留存月份(格式:YYYY-MM) diff --git a/app/admin/models/music.go b/app/admin/models/music.go index 791893f..2c67a4e 100644 --- a/app/admin/models/music.go +++ b/app/admin/models/music.go @@ -27,6 +27,15 @@ const ( LoginSecretKey = "913efe5c6f274c278988af817f9d1c7d" // 登陆密钥 ) +type CallbackRequest struct { + ChannelCode string `json:"channel_code" binding:"required"` // 渠道编码,例如:00211NV + ExternalOrderNo string `json:"external_order_no"` // 外部平台流水号,例如:1909274381102424065 + PhoneNumber string `json:"phone_number" binding:"required"` // 手机号,例如:13590011234 + Province string `json:"province"` // 省份,例如:广东 + ResCode int `json:"res_code"` // 交易结果,1-成功,0-失败 + ResDesc string `json:"res_desc"` // 交易结果描述,例如:【OPEN】系统繁忙 +} + type ResultFeedbackEvt struct { MSISDN string `json:"MSISDN"` // 用户手机号码,长度11 RevDate string `json:"revdate"` // 平台接收时间戳,格式为:yyyymmddHHMMss @@ -93,6 +102,135 @@ func CheckMusicOrderState() { return } + // 查询订单列表中未退订的用户,查询其是否退订;如果退订,则更新退订时间,判断是否为1小时内退订 + var orderList []MgOrderLog + + // 获取当前时间前2个小时 + oneHourAgo := time.Now().Add(-2 * time.Hour) + fmt.Println("check oneHourAgo is:", oneHourAgo) + logger.Info("check oneHourAgo is:", oneHourAgo) + + err := database.Db.Where("state = 1"). + Where("created_at >= ?", oneHourAgo). + 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 loginResp LoginResponse + var token string + + // 获取手机号并检查Redis中是否已有token + phoneNumber := order.PhoneNumber + token, err = getTokenFromRedis(phoneNumber) // 假设有此函数查询Redis + + // 如果token不存在,则调用Login接口获取token,添加重试机制 + if err != nil || token == "" { + maxRetries := MaxRetries + for j := 0; j < maxRetries; j++ { + loginResp, err = Login(order.ChannelCode, LoginType, "", phoneNumber) + if err != nil || loginResp.ResCode != "000000" { + if err != nil { + fmt.Println("Login failed:", err.Error()) + logger.Error("query mg_order err:", err.Error()) + } else { + fmt.Println("Login failed, loginResp.ResCode:", loginResp.ResCode) + logger.Error("Login failed, loginResp.ResCode:", loginResp.ResCode) + } + + if j < maxRetries-1 { // 如果不是最后一次尝试,继续重试 + continue + } + break + } + + token = loginResp.Token + // 存储token到Redis + err = storeTokenInRedis(phoneNumber, token) // 假设有此函数存储到Redis + if err != nil { + fmt.Println("Failed to store token in Redis:", err.Error()) + logger.Error("Failed to store token in Redis:", err.Error()) + continue + } + break + } + } + + // 重试最大次数 + maxRetries := MaxRetries + + for j := 0; j < maxRetries; j++ { + // 尝试调用MonthlySubscriptionQuery接口获取订阅状态 + 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, loginResp.ResCode:", resp.ResCode) + logger.Error("MonthlySubscriptionQuery failed, loginResp.ResCode:", resp.ResCode) + } + if j < maxRetries-1 { // 如果不是最后一次尝试,继续重试 + continue + } + break + } + + if resp.Status == "0" { // 已订购 + // 订购状态为已订购,不处理 + break + } else if resp.Status == "1" { // 未订购 + // 未订购,更新订单状态 + var cancelFlag int + subscribeTime := order.CreatedAt + unsubTime := time.Now().Format("2006-01-02 15:04:05") + + // 检查是否在1小时内取消 + if IsWithinOneHourCancel(subscribeTime, unsubTime) { + cancelFlag = 1 + } + + // 更新订单状态 + err = database.Db.Table("mg_order_log").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()) + continue + } + break + } + } + } + + fmt.Println("****** CheckMusicOrderState end ******") + logger.Info("****** CheckMusicOrderState end ******") +} + +// CheckAIMusicOrderState 定时任务,检查订单状态,是否有1小时退订 +func CheckAIMusicOrderState() { + logger.Info("****** CheckAIMusicOrderState start ******") + fmt.Println("****** CheckAIMusicOrderState start ******") + if database.Db == nil { + logger.Error("Database connection is nil") + fmt.Println("Database connection is nil") + return + } + // 查询订单列表中未退订的用户,查询其是否退订;如果退订,则更新退订时间,判断是否为1小时内退订 var orderList []MgOrder @@ -208,8 +346,8 @@ func CheckMusicOrderState() { } } - fmt.Println("****** CheckMusicOrderState end ******") - logger.Info("****** CheckMusicOrderState end ******") + fmt.Println("****** CheckAIMusicOrderState end ******") + logger.Info("****** CheckAIMusicOrderState end ******") } type MonthlySubscriptionReq struct { diff --git a/app/admin/router/migu.go b/app/admin/router/migu.go index 81fe5a7..8512102 100644 --- a/app/admin/router/migu.go +++ b/app/admin/router/migu.go @@ -38,6 +38,8 @@ func registerMiGuControlManageUnAuthRouter(v1 *gin.RouterGroup) { { apiMusic.POST("feedback", apiMiGu.MusicFeedback) // 咪咕音乐回调通知 + apiMusic.POST("order/feedback", apiMiGu.AIMusicFeedback) // AI视频彩铃回调通知接口 + apiMusic.POST("login", apiMiGu.MusicLogin) // 咪咕音乐登陆 apiMusic.POST("query_order", apiMiGu.MusicQueryOrder) // 咪咕音乐查询订单 } diff --git a/cmd/api/server.go b/cmd/api/server.go index bbd5f56..b2c4a93 100644 --- a/cmd/api/server.go +++ b/cmd/api/server.go @@ -92,7 +92,14 @@ func run() error { // TODO s := gocron.NewScheduler() - err := s.Every(10).Minute().Do(models.CheckMusicOrderState) + // 定时查询 mg_order_log 表 + err := s.Every(15).Minute().Do(models.CheckMusicOrderState) + if err != nil { + fmt.Println("err:", err) + } + + // 定时查询 mg_order 表 + err = s.Every(10).Minute().Do(models.CheckAIMusicOrderState) if err != nil { fmt.Println("err:", err) }