1.新增"AI视频彩铃回调通知接口",调整部分代码逻辑;
2.新增mg_order_log、mg_transaction_log_ai表;
This commit is contained in:
parent
4319617a05
commit
88a0cb8fc3
|
@ -24,6 +24,196 @@ import (
|
||||||
// @Param request body models.ResultFeedbackEvt true "咪咕音乐回调通知接口"
|
// @Param request body models.ResultFeedbackEvt true "咪咕音乐回调通知接口"
|
||||||
// @Success 200 {object} models.MusicFeedbackResp
|
// @Success 200 {object} models.MusicFeedbackResp
|
||||||
// @Router /api/v1/migu/music/feedback [post]
|
// @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) {
|
func (e MiGuDeployService) MusicFeedback(c *gin.Context) {
|
||||||
fmt.Println("MusicFeedback-start")
|
fmt.Println("MusicFeedback-start")
|
||||||
logger.Info("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.ProductID = models.MusicProductID
|
||||||
sendLog.ChannelCode = details.ChannelCode
|
sendLog.ChannelCode = details.ChannelCode
|
||||||
sendLog.OutTradeNo = models.GetOrderSerial(e.Orm)
|
sendLog.OutTradeNo = models.GetOrderSerial(e.Orm)
|
||||||
|
@ -112,45 +302,13 @@ func (e MiGuDeployService) MusicFeedback(c *gin.Context) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if req.ResCode == "000000" { // 提交订阅成功则记录到订单表
|
if req.ResCode == "000000" { // 提交订阅成功则记录到订单表
|
||||||
|
if details.OrderKeyword == "BJTD" || details.OrderKeyword == "SPTD" || details.OrderKeyword == "SPJF" || details.OrderKeyword == "TD" {
|
||||||
|
|
||||||
|
if 1 == 1 { // 更新订单表的退订信息
|
||||||
var lastOrder models.MgOrder
|
var lastOrder models.MgOrder
|
||||||
result := e.Orm.Model(&models.MgOrder{}).Where("phone_number = ?", req.MSISDN).
|
e.Orm.Model(&models.MgOrder{}).Where("phone_number = ?", req.MSISDN).
|
||||||
Order("subscribe_time DESC").First(&lastOrder)
|
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小时退订才更新,否则不用更新
|
if lastOrder.IsOneHourCancel != 1 { // 非1小时退订才更新,否则不用更新
|
||||||
// 未订购,更新订单状态
|
// 未订购,更新订单状态
|
||||||
var cancelFlag int
|
var cancelFlag int
|
||||||
|
@ -170,38 +328,88 @@ func (e MiGuDeployService) MusicFeedback(c *gin.Context) {
|
||||||
"updated_at": time.Now(),
|
"updated_at": time.Now(),
|
||||||
}).Error
|
}).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Failed to update order:", err.Error())
|
fmt.Println("Failed to update mg_order:", err.Error())
|
||||||
logger.Error("Failed to update order:", err.Error())
|
logger.Error("Failed to update mg_order:", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//// 记录到订单列表
|
if 2 == 2 { // 更新订单log表的退订信息
|
||||||
//var orderInfo models.MgOrder
|
var lastOrderLog models.MgOrderLog
|
||||||
//orderInfo.ProductID = models.MusicProductID
|
e.Orm.Model(&models.MgOrderLog{}).Where("phone_number = ?", req.MSISDN).
|
||||||
//orderInfo.ChannelCode = details.ChannelCode
|
Order("subscribe_time DESC").First(&lastOrderLog)
|
||||||
//orderInfo.OrderSerial = models.GetOrderSerial(e.Orm)
|
|
||||||
//nowTime, err := models.ParseRevDate(req.RevDate)
|
if lastOrderLog.IsOneHourCancel != 1 { // 非1小时退订才更新,否则不用更新
|
||||||
//if err != nil {
|
// 未订购,更新订单状态
|
||||||
// nowTime = time.Now()
|
var cancelFlagLog int
|
||||||
//}
|
subscribeTimeLog := lastOrderLog.CreatedAt
|
||||||
//orderInfo.SubscribeTime = &nowTime
|
unsubTimeLog := time.Now().Format("2006-01-02 15:04:05")
|
||||||
//orderInfo.PhoneNumber = req.MSISDN
|
|
||||||
//orderInfo.SM4PhoneNumber, _ = tools.SM4Encrypt(models.SM4KEy, req.MSISDN)
|
// 检查是否在1小时内取消
|
||||||
//
|
if models.IsWithinOneHourCancel(subscribeTimeLog, unsubTimeLog) {
|
||||||
//if details.CustomSerialNo == "" {
|
cancelFlagLog = 1
|
||||||
// details.CustomSerialNo = orderInfo.OrderSerial
|
}
|
||||||
//}
|
|
||||||
//orderInfo.ChannelTradeNo = details.CustomSerialNo
|
// 更新订单状态
|
||||||
//orderInfo.ExternalOrderID = details.CustomSerialNo
|
err = database.Db.Table("mg_order_log").Where("phone_number = ?", req.MSISDN).Updates(map[string]interface{}{
|
||||||
//orderInfo.State = models.SubscribeOK
|
"state": models.UnsubscribeOK,
|
||||||
//
|
"is_one_hour_cancel": cancelFlagLog,
|
||||||
//err = e.Orm.Create(&orderInfo).Error
|
"unsubscribe_time": unsubTimeLog,
|
||||||
//if err != nil {
|
"updated_at": time.Now(),
|
||||||
// logger.Info("Create MgTransactionLog err:", err)
|
}).Error
|
||||||
// //app.Error(c, http.StatusBadRequest, err, err.Error())
|
if err != nil {
|
||||||
// //return
|
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")
|
fmt.Println("MusicFeedback-end")
|
||||||
|
@ -213,6 +421,133 @@ func (e MiGuDeployService) MusicFeedback(c *gin.Context) {
|
||||||
app.MiGuOK(c, resp)
|
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) {
|
func (e MiGuDeployService) MusicLogin(c *gin.Context) {
|
||||||
fmt.Println("MusicLogin-start")
|
fmt.Println("MusicLogin-start")
|
||||||
logger.Info("MusicLogin-start")
|
logger.Info("MusicLogin-start")
|
||||||
|
|
|
@ -68,6 +68,22 @@ type MgOrder struct {
|
||||||
IsOneHourCancel int `json:"is_one_hour_cancel"` // 是否1小时内退订 1-是 其他-否
|
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 渠道列表
|
// MgChannel 渠道列表
|
||||||
type MgChannel struct {
|
type MgChannel struct {
|
||||||
Model
|
Model
|
||||||
|
@ -123,6 +139,22 @@ type MgTransactionLog struct {
|
||||||
OrderTime *time.Time `gorm:"type:datetime" json:"order_time"` // 订单时间
|
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 用户留存记录表对应的结构体
|
// MgUserRetention 用户留存记录表对应的结构体
|
||||||
type MgUserRetention struct {
|
type MgUserRetention struct {
|
||||||
RetentionMonth string `gorm:"size:7" json:"retention_month"` // 留存月份(格式:YYYY-MM)
|
RetentionMonth string `gorm:"size:7" json:"retention_month"` // 留存月份(格式:YYYY-MM)
|
||||||
|
|
|
@ -27,6 +27,15 @@ const (
|
||||||
LoginSecretKey = "913efe5c6f274c278988af817f9d1c7d" // 登陆密钥
|
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 {
|
type ResultFeedbackEvt struct {
|
||||||
MSISDN string `json:"MSISDN"` // 用户手机号码,长度11
|
MSISDN string `json:"MSISDN"` // 用户手机号码,长度11
|
||||||
RevDate string `json:"revdate"` // 平台接收时间戳,格式为:yyyymmddHHMMss
|
RevDate string `json:"revdate"` // 平台接收时间戳,格式为:yyyymmddHHMMss
|
||||||
|
@ -93,6 +102,135 @@ func CheckMusicOrderState() {
|
||||||
return
|
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小时内退订
|
// 查询订单列表中未退订的用户,查询其是否退订;如果退订,则更新退订时间,判断是否为1小时内退订
|
||||||
var orderList []MgOrder
|
var orderList []MgOrder
|
||||||
|
|
||||||
|
@ -208,8 +346,8 @@ func CheckMusicOrderState() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("****** CheckMusicOrderState end ******")
|
fmt.Println("****** CheckAIMusicOrderState end ******")
|
||||||
logger.Info("****** CheckMusicOrderState end ******")
|
logger.Info("****** CheckAIMusicOrderState end ******")
|
||||||
}
|
}
|
||||||
|
|
||||||
type MonthlySubscriptionReq struct {
|
type MonthlySubscriptionReq struct {
|
||||||
|
|
|
@ -38,6 +38,8 @@ func registerMiGuControlManageUnAuthRouter(v1 *gin.RouterGroup) {
|
||||||
{
|
{
|
||||||
apiMusic.POST("feedback", apiMiGu.MusicFeedback) // 咪咕音乐回调通知
|
apiMusic.POST("feedback", apiMiGu.MusicFeedback) // 咪咕音乐回调通知
|
||||||
|
|
||||||
|
apiMusic.POST("order/feedback", apiMiGu.AIMusicFeedback) // AI视频彩铃回调通知接口
|
||||||
|
|
||||||
apiMusic.POST("login", apiMiGu.MusicLogin) // 咪咕音乐登陆
|
apiMusic.POST("login", apiMiGu.MusicLogin) // 咪咕音乐登陆
|
||||||
apiMusic.POST("query_order", apiMiGu.MusicQueryOrder) // 咪咕音乐查询订单
|
apiMusic.POST("query_order", apiMiGu.MusicQueryOrder) // 咪咕音乐查询订单
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,7 +92,14 @@ func run() error {
|
||||||
// TODO
|
// TODO
|
||||||
s := gocron.NewScheduler()
|
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 {
|
if err != nil {
|
||||||
fmt.Println("err:", err)
|
fmt.Println("err:", err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user