Files
51dj_server/app/service/reportser/report.go
T
2026-10-08 16:50:13 +08:00

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))
}