171 lines
5.5 KiB
Go
171 lines
5.5 KiB
Go
package dao
|
||
|
||
import (
|
||
"time"
|
||
|
||
"gorm.io/datatypes"
|
||
"gorm.io/gorm"
|
||
"gorm.io/gorm/clause"
|
||
)
|
||
|
||
// AnalyticsEvent 数据埋点事件表
|
||
type AnalyticsEvent struct {
|
||
ID int64 `gorm:"bigint;primaryKey;autoIncrement;column:id;comment:主键ID" json:"id"`
|
||
UserID int64 `gorm:"column:user_id;not null;index:idx_user_id;comment:用户ID" json:"user_id"`
|
||
EventName string `gorm:"column:event_name;varchar(128);not null;index:idx_event_name;comment:事件名称" json:"event_name"`
|
||
Properties datatypes.JSON `gorm:"column:properties;type:json;comment:事件属性(JSON)" json:"properties"`
|
||
DeviceInfo datatypes.JSON `gorm:"column:device_info;type:json;comment:设备信息(JSON)" json:"device_info"`
|
||
MetaData datatypes.JSON `gorm:"column:meta_data;type:json;comment:元数据(JSON,包含task_id等)" json:"meta_data"`
|
||
CreatedAt time.Time `gorm:"column:created_at;comment:创建时间;not null;default:current_timestamp;index:idx_created_at" json:"created_at"`
|
||
}
|
||
|
||
func (e *AnalyticsEvent) TableName() string {
|
||
return "analytics_events"
|
||
}
|
||
|
||
// AnalyticsEventDao 数据埋点事件DAO
|
||
type AnalyticsEventDao struct{}
|
||
|
||
func NewAnalyticsEventDao() *AnalyticsEventDao {
|
||
return &AnalyticsEventDao{}
|
||
}
|
||
|
||
// Create 创建事件记录
|
||
func (dao *AnalyticsEventDao) Create(tx *gorm.DB, event *AnalyticsEvent) error {
|
||
return tx.Create(event).Error
|
||
}
|
||
|
||
// BatchCreate 批量创建事件记录
|
||
func (dao *AnalyticsEventDao) BatchCreate(tx *gorm.DB, events []*AnalyticsEvent) error {
|
||
if len(events) == 0 {
|
||
return nil
|
||
}
|
||
return tx.CreateInBatches(events, 100).Error
|
||
}
|
||
|
||
// GetByID 根据ID获取事件
|
||
func (dao *AnalyticsEventDao) GetByID(tx *gorm.DB, id int64) (*AnalyticsEvent, error) {
|
||
event := &AnalyticsEvent{}
|
||
err := tx.Where("id = ?", id).First(event).Error
|
||
if err != nil {
|
||
if err == gorm.ErrRecordNotFound {
|
||
return nil, nil
|
||
}
|
||
return nil, err
|
||
}
|
||
return event, nil
|
||
}
|
||
|
||
// GetUserEvents 获取用户的事件列表
|
||
func (dao *AnalyticsEventDao) GetUserEvents(tx *gorm.DB, userID int64, page, pageSize int) ([]*AnalyticsEvent, int64, error) {
|
||
var events []*AnalyticsEvent
|
||
var total int64
|
||
|
||
offset := (page - 1) * pageSize
|
||
query := tx.Model(&AnalyticsEvent{}).Where("user_id = ?", userID)
|
||
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, 0, err
|
||
}
|
||
|
||
err = query.Offset(offset).Limit(pageSize).
|
||
Order(clause.OrderByColumn{Column: clause.Column{Name: "created_at"}, Desc: true}).
|
||
Find(&events).Error
|
||
|
||
return events, total, err
|
||
}
|
||
|
||
// GetEventsByName 根据事件名称获取事件列表
|
||
func (dao *AnalyticsEventDao) GetEventsByName(tx *gorm.DB, eventName string, page, pageSize int) ([]*AnalyticsEvent, int64, error) {
|
||
var events []*AnalyticsEvent
|
||
var total int64
|
||
|
||
offset := (page - 1) * pageSize
|
||
query := tx.Model(&AnalyticsEvent{}).Where("event_name = ?", eventName)
|
||
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, 0, err
|
||
}
|
||
|
||
err = query.Offset(offset).Limit(pageSize).
|
||
Order(clause.OrderByColumn{Column: clause.Column{Name: "created_at"}, Desc: true}).
|
||
Find(&events).Error
|
||
|
||
return events, total, err
|
||
}
|
||
|
||
// GetUserEventsByName 获取用户指定事件的列表
|
||
func (dao *AnalyticsEventDao) GetUserEventsByName(tx *gorm.DB, userID int64, eventName string, page, pageSize int) ([]*AnalyticsEvent, int64, error) {
|
||
var events []*AnalyticsEvent
|
||
var total int64
|
||
|
||
offset := (page - 1) * pageSize
|
||
query := tx.Model(&AnalyticsEvent{}).Where("user_id = ? AND event_name = ?", userID, eventName)
|
||
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, 0, err
|
||
}
|
||
|
||
err = query.Offset(offset).Limit(pageSize).
|
||
Order(clause.OrderByColumn{Column: clause.Column{Name: "created_at"}, Desc: true}).
|
||
Find(&events).Error
|
||
|
||
return events, total, err
|
||
}
|
||
|
||
// GetEventsByTimeRange 根据时间范围获取事件列表
|
||
func (dao *AnalyticsEventDao) GetEventsByTimeRange(tx *gorm.DB, startTime, endTime time.Time, page, pageSize int) ([]*AnalyticsEvent, int64, error) {
|
||
var events []*AnalyticsEvent
|
||
var total int64
|
||
|
||
offset := (page - 1) * pageSize
|
||
query := tx.Model(&AnalyticsEvent{}).Where("created_at BETWEEN ? AND ?", startTime, endTime)
|
||
|
||
err := query.Count(&total).Error
|
||
if err != nil {
|
||
return nil, 0, err
|
||
}
|
||
|
||
err = query.Offset(offset).Limit(pageSize).
|
||
Order(clause.OrderByColumn{Column: clause.Column{Name: "created_at"}, Desc: true}).
|
||
Find(&events).Error
|
||
|
||
return events, total, err
|
||
}
|
||
|
||
// CountEventsByName 统计指定事件的数量
|
||
func (dao *AnalyticsEventDao) CountEventsByName(tx *gorm.DB, eventName string) (int64, error) {
|
||
var count int64
|
||
err := tx.Model(&AnalyticsEvent{}).Where("event_name = ?", eventName).Count(&count).Error
|
||
return count, err
|
||
}
|
||
|
||
// CountUserEvents 统计用户的事件数量
|
||
func (dao *AnalyticsEventDao) CountUserEvents(tx *gorm.DB, userID int64) (int64, error) {
|
||
var count int64
|
||
err := tx.Model(&AnalyticsEvent{}).Where("user_id = ?", userID).Count(&count).Error
|
||
return count, err
|
||
}
|
||
|
||
// GetEventStats 获取事件统计信息(按事件名称分组)
|
||
func (dao *AnalyticsEventDao) GetEventStats(tx *gorm.DB, startTime, endTime time.Time) ([]map[string]interface{}, error) {
|
||
var results []map[string]interface{}
|
||
|
||
err := tx.Model(&AnalyticsEvent{}).
|
||
Select("event_name, COUNT(*) as count, COUNT(DISTINCT user_id) as unique_users").
|
||
Where("created_at BETWEEN ? AND ?", startTime, endTime).
|
||
Group("event_name").
|
||
Order("count DESC").
|
||
Find(&results).Error
|
||
|
||
return results, err
|
||
}
|
||
|
||
// DeleteOldEvents 删除旧事件(数据清理)
|
||
func (dao *AnalyticsEventDao) DeleteOldEvents(tx *gorm.DB, beforeTime time.Time) error {
|
||
return tx.Where("created_at < ?", beforeTime).Delete(&AnalyticsEvent{}).Error
|
||
}
|