package migumanage import ( "encoding/json" "errors" "fmt" "github.com/gin-gonic/gin" "github.com/go-admin-team/go-admin-core/logger" "go-admin/app/admin/models" "go-admin/common/database" "go-admin/tools" "go-admin/tools/app" "gorm.io/gorm" "io" "net/http" "time" ) // MusicFeedback 咪咕音乐回调通知接口 // @Summary 咪咕音乐回调通知接口 // @Tags 2025-咪咕音乐-回调 // @Produce json // @Accept json // @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") // 打印请求 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.MgTransactionLogAi 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" { // 提交订阅成功则记录到订单表 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.PhoneNumber). Order("subscribe_time DESC").First(&lastOrder) if errors.Is(result.Error, gorm.ErrRecordNotFound) { nowTime := time.Now() 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 = req.ChannelCode orderInfo.OrderSerial = models.GetOrderSerial(e.Orm) orderInfo.SubscribeTime = &nowTime orderInfo.PhoneNumber = req.PhoneNumber orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.PhoneNumber) if req.ExternalOrderNo == "" { req.ExternalOrderNo = orderInfo.OrderSerial } orderInfo.ChannelTradeNo = req.ExternalOrderNo orderInfo.ExternalOrderID = req.ExternalOrderNo orderInfo.State = models.SubscribeOK if err = e.Orm.Create(&orderInfo).Error; err != nil { logger.Error(err) } } } } fmt.Println("AIMusicFeedback-end") logger.Info("AIMusicFeedback-end") var resp models.MusicFeedbackResp resp.ReturnCode = "OK" app.MiGuOK(c, resp) } func (e MiGuDeployService) MusicLogin(c *gin.Context) { fmt.Println("MusicLogin-start") logger.Info("MusicLogin-start") err := e.MakeContext(c).MakeOrm().Errors if err != nil { fmt.Println("MusicLogin MakeContext err:", err) e.Logger.Error(err) app.Error(c, http.StatusInternalServerError, err, "初始化失败") return } req := &models.LoginRequest{} if c.ShouldBindJSON(req) != nil { logger.Errorf("MusicLogin para err") app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") return } logger.Info("MusicLogin req:", req) resp, err := models.Login(req.ChannelCode, req.LoginType, req.CallBackUrl, req.Msisdn) if err != nil { logger.Errorf("MusicLogin Login err:", err.Error()) app.Error(c, http.StatusBadRequest, err, err.Error()) return } fmt.Println("MusicLogin-end") logger.Info("MusicLogin-end") app.MiGuOK(c, resp) } func (e MiGuDeployService) MusicQueryOrder(c *gin.Context) { fmt.Println("MusicQueryOrder-start") logger.Info("MusicQueryOrder-start") err := e.MakeContext(c).MakeOrm().Errors if err != nil { fmt.Println("MusicQueryOrder MakeContext err:", err) e.Logger.Error(err) app.Error(c, http.StatusInternalServerError, err, "初始化失败") return } req := &models.MonthlySubscriptionReq{} if c.ShouldBindJSON(req) != nil { logger.Errorf("MusicQueryOrder para err") app.Error(c, http.StatusBadRequest, errors.New("para err"), "参数错误") return } logger.Info("MusicQueryOrder req:", req) resp, err := models.MonthlySubscriptionQuery(req.Token, req.ServiceId, req.ChannelCode) if err != nil { logger.Errorf("MusicQueryOrder MonthlySubscriptionQuery err:", err.Error()) app.Error(c, http.StatusBadRequest, err, err.Error()) return } fmt.Println("MusicQueryOrder-end") logger.Info("MusicQueryOrder-end") app.MiGuOK(c, resp) }