205 lines
7.5 KiB
Go
205 lines
7.5 KiB
Go
package reportser
|
|
|
|
import (
|
|
"91jd-server/common/dataReport"
|
|
"91jd-server/common/db"
|
|
"91jd-server/middleware/ua"
|
|
"91jd-server/models/v/eventmod"
|
|
"91jd-server/models/v/rchgordmod"
|
|
"91jd-server/models/v/usermod"
|
|
"91jd-server/models/v/vidmod"
|
|
"crypto/md5"
|
|
"encoding/hex"
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
// ReportOrderCreatedEvent 订单创建事件
|
|
func ReportOrderCreatedEvent(t *db.MongoTool, user *usermod.User, ua ua.UA, ip string, order *rchgordmod.RechargeOrder) (err error) {
|
|
orderType := "coin_purchase"
|
|
page := KeyCoinPage
|
|
coin := order.Amount
|
|
if order.Category == 1 {
|
|
orderType = "vip_subscription"
|
|
page = KeyVipPage
|
|
coin = 0
|
|
}
|
|
eventId := newEventId(dataReport.ReportAppId(), user.UID, order.ID.Hex(), order.CreatedAt.Unix())
|
|
event := dataReport.NewCommonField(eventId, dataReport.EventTypeOrderCreated, user.UID, user.DistrictCode, ua, ip)
|
|
|
|
var vipDurationID string
|
|
var vipDurationName string
|
|
if order.Category == 1 {
|
|
vipDurationID = order.ProductID.Hex()
|
|
vipDurationName = order.ProductName
|
|
}
|
|
event.Payload = jsonRawMessage(&dataReport.OrderCreatedEvent{
|
|
OrderID: order.ID.Hex(), // 订单号(唯一标识)
|
|
OrderType: orderType, // 订单类型
|
|
ProductID: order.ProductID.Hex(), // 商品ID
|
|
ProductName: order.ProductName, // 商品名称
|
|
Amount: jsonNumber(order.Money), // 订单金额(分)
|
|
Currency: "CNY", // 货币类型
|
|
CoinQuantity: jsonNumber(coin), // 金币数量
|
|
VIPDurationID: vipDurationID,
|
|
VIPDurationName: vipDurationName,
|
|
SourcePageKey: page.Key(), // 来源页面标识
|
|
SourcePageName: page.Name(), // 来源页面名称
|
|
CreateTime: jsonNumber(order.CreatedAt.Unix()),
|
|
})
|
|
b, _ := json.Marshal(event)
|
|
// 写入数据库
|
|
return eventmod.Insert(t, &eventmod.Event{
|
|
EventId: event.EventID,
|
|
EventType: event.Event,
|
|
Data: string(b),
|
|
Status: eventmod.Default,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
})
|
|
}
|
|
|
|
// ReportOrderPaidEvent 订单支付事件
|
|
func ReportOrderPaidEvent(t *db.MongoTool, order rchgordmod.RechargeOrder, transactionID string, amount int64, coin int64, vipExpirationTime, successAt time.Time) (err error) {
|
|
user, err := usermod.FindUserByUID(order.UID)
|
|
if err != nil || user == nil {
|
|
return
|
|
}
|
|
orderType := "coin_purchase"
|
|
var vipExpirationUnix int64
|
|
if order.Category == 1 {
|
|
orderType = "vip_subscription"
|
|
coin = 0
|
|
if vipExpirationTime.Unix() > 0 {
|
|
vipExpirationUnix = vipExpirationTime.Unix()
|
|
}
|
|
}
|
|
eventId := newEventId(dataReport.ReportAppId(), user.UID, order.ID.Hex(), successAt.Unix())
|
|
event := dataReport.NewCommonField(eventId, dataReport.EventTypeOrderPaid, user.UID, user.DistrictCode, order.Ua, order.UserIP)
|
|
event.Payload = jsonRawMessage(&dataReport.OrderPaidEvent{
|
|
OrderID: order.ID.Hex(), // 订单号(关联创建事件)
|
|
OrderType: orderType, // 订单类型:coin_purchase, vip_subscription
|
|
ProductID: order.ProductID.Hex(), // 商品ID
|
|
Amount: jsonNumber(amount), // 实际支付金额(分)
|
|
Currency: "CNY", // 货币类型:CNY, USD
|
|
CoinQuantity: jsonNumber(coin), // 金币数量(仅金币订单)
|
|
VIPExpirationTime: jsonNumber(vipExpirationUnix), // VIP过期时间(10位时间戳)
|
|
PayType: order.RechargeType, // 支付方式:wechat, alipay, bank_card
|
|
PayChannel: "", // 支付渠道:银行名称
|
|
TransactionID: transactionID, // 第三方支付交易号
|
|
CreateTime: jsonNumber(successAt.Unix()),
|
|
})
|
|
b, _ := json.Marshal(event)
|
|
// 写入数据库
|
|
return eventmod.Insert(t, &eventmod.Event{
|
|
EventId: event.EventID,
|
|
EventType: event.Event,
|
|
Data: string(b),
|
|
Status: eventmod.Default,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
})
|
|
}
|
|
|
|
// ReportCoinConsumeEvent 金币消耗事件
|
|
func ReportCoinConsumeEvent(t *db.MongoTool, orderId string, orderCreatedAt time.Time, user *usermod.User, ua ua.UA, ip string, productId, productName string, amount, balanceBefore, balanceAfter int64, reason Key) (err error) {
|
|
if amount == 0 {
|
|
return
|
|
}
|
|
if productId == "" {
|
|
if productName == "" {
|
|
productName = "金币消耗"
|
|
}
|
|
productId = Md5String(productName)
|
|
}
|
|
|
|
eventId := newEventId(dataReport.ReportAppId(), user.UID, orderId, orderCreatedAt.Unix())
|
|
event := dataReport.NewCommonField(eventId, dataReport.EventTypeCoinConsume, user.UID, user.DistrictCode, ua, ip)
|
|
event.Payload = jsonRawMessage(&dataReport.CoinConsumeEvent{
|
|
ProductID: productId, // 商品ID
|
|
ProductName: productName, // 商品名称
|
|
CoinConsumeAmount: jsonNumber(amount), // 金币消耗数量
|
|
CoinBalanceBefore: jsonNumber(balanceBefore), // 消耗前金币余额
|
|
CoinBalanceAfter: jsonNumber(balanceAfter), // 消耗后金币余额
|
|
ConsumeReasonKey: reason.Key(), // 消耗原因
|
|
ConsumeReasonName: reason.Name(), // 消耗原因名称
|
|
CreateTime: jsonNumber(orderCreatedAt.Unix()),
|
|
OrderId: orderId,
|
|
})
|
|
b, _ := json.Marshal(event)
|
|
// 写入数据库
|
|
return eventmod.Insert(t, &eventmod.Event{
|
|
EventId: event.EventID,
|
|
EventType: event.Event,
|
|
Data: string(b),
|
|
Status: eventmod.Default,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
})
|
|
}
|
|
|
|
// ReportVideoPurchase 视频购买事件
|
|
func ReportVideoPurchase(t *db.MongoTool, user *usermod.User, ua ua.UA, ip string, video *vidmod.VideoModel, orderId string) (err error) {
|
|
meta := extractVideoMeta(video)
|
|
event := dataReport.NewCommonField(dataReport.GenerateGlobalEventID(), dataReport.EventTypeVideoPurchase, user.UID, user.DistrictCode, ua, ip)
|
|
event.Payload = jsonRawMessage(&dataReport.VideoPurchaseEvent{
|
|
VideoEventCore: meta.toEventCore(video.ID.Hex(), video.Title, ""),
|
|
CoinQuantity: jsonNumber(video.Coins), // 金币数量
|
|
OrderID: orderId, // 订单号
|
|
})
|
|
b, _ := json.Marshal(event)
|
|
// 写入数据库
|
|
return eventmod.Insert(t, &eventmod.Event{
|
|
EventId: event.EventID,
|
|
EventType: event.Event,
|
|
Data: string(b),
|
|
Status: eventmod.Default,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
})
|
|
}
|
|
|
|
// ReportUserRegister 用户注册事件
|
|
func ReportUserRegister(t *db.MongoTool, user *usermod.User, ua ua.UA, ip string) (err error) {
|
|
registerType := "deviceid"
|
|
eventId := newEventId(dataReport.ReportAppId(), user.UID, "", user.CreatedAt.Unix())
|
|
event := dataReport.NewCommonField(eventId, dataReport.EventTypeUserRegister, user.UID, user.DistrictCode, ua, ip)
|
|
event.Payload = jsonRawMessage(&dataReport.UserRegisterEvent{
|
|
Type: registerType,
|
|
TraceID: user.Tid,
|
|
CreateTime: jsonNumber(user.CreatedAt.Unix()),
|
|
})
|
|
b, _ := json.Marshal(event)
|
|
// 写入数据库
|
|
return eventmod.Insert(t, &eventmod.Event{
|
|
EventId: event.EventID,
|
|
EventType: event.Event,
|
|
Data: string(b),
|
|
Status: eventmod.Default,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
})
|
|
}
|
|
|
|
func newEventId(appId string, uid uint64, orderId string, createTime int64) string {
|
|
input := fmt.Sprintf("%v%v%v%v", appId, uid, orderId, createTime)
|
|
return Md5String(input)
|
|
}
|
|
|
|
func jsonNumber(v int64) json.Number {
|
|
return json.Number(strconv.FormatInt(v, 10))
|
|
}
|
|
|
|
func jsonRawMessage(v interface{}) json.RawMessage {
|
|
b, _ := json.Marshal(v)
|
|
return b
|
|
}
|
|
|
|
func Md5String[T string | []byte](input T) string {
|
|
h := md5.New()
|
|
h.Write([]byte(input))
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
}
|