package model import ( util "backend/util" "encoding/json" "fmt" ) type Log struct { Uid int `json:"Id"` PageSize int `json:"PageSize"` CurrentPage int `json:"CurrentPage"` AppId int `json:"AppId"` EventParam string `json:"Event"` StartTime int64 `json:"StartTime"` EndTime int64 `json:"EndTime"` ItemId int `json:"ItemId"` } type ResAsset struct { Total int `json:"total"` Data []*ResAssetDetail `json:"data"` Sum int `json:"sum"` // 总和 NSum int `json:"nsum"` // 负数和 PSum int `json:"psum"` // 正数和 } type ResEvent struct { Total int `json:"total"` Data []*Event `json:"data"` } type ResOrder struct { Total int `json:"total"` Data []*Order `json:"data"` } type Order struct { Id int `db:"id"` Uid int `db:"Uid"` AppId int `db:"AppId"` ServerId int `db:"ServerId"` OrderId string `db:"OrderId"` Price float64 `db:"Price"` PayChannelOrderId string `db:"PayChannelOrderId"` ProductId int `db:"ProductId"` CreateTime int `db:"CreateTime"` PayTime int `db:"PayTime"` PayType int `db:"PayType"` Param string `db:"Param"` Timestamp int `db:"Timestamp"` CreateTimeStr string PayTimeStr string } type ResAssetDetail struct { Uid int `json:"Uid"` ChangeType string `json:"change_type"` ChangeNum int `json:"change_num"` ChangeAfter int `json:"change_after"` ItemId int `json:"item_id"` Timestamp int `json:"timestamp"` } type Event struct { Id int `db:"id"` Uid int `db:"Uid"` AppId int `db:"AppId"` ServerId int `db:"ServerId"` Event string `db:"Event"` Label string Param string `db:"Param"` Timestamp int `db:"Timestamp"` } func (m *Log) Asset() (*ResAsset, error) { AppId, _ := util.ParseUid(m.Uid) AppConfig, err := util.GetAppConfig(AppId) if err != nil { return nil, err } StartTime := m.StartTime EndTime := m.EndTime Db := util.MPool.GetTopicDB(AppConfig.Topic) defer Db.Close() if Db == nil { return nil, fmt.Errorf("failed to get mysql database") } assets := []*Event{} value := make([]interface{}, 0) totalValue := make([]interface{}, 0) Sql := "SELECT * FROM log_event WHERE Uid = ? and `Event` = 'asset_change' and Timestamp >= ? and Timestamp <= ? " TotalSql := "SELECT COUNT(*) FROM log_event WHERE Uid = ? and `Event` = 'asset_change' and Timestamp >= ? and Timestamp <= ? " totalValue = append(totalValue, m.Uid, StartTime, EndTime) value = append(value, m.Uid, StartTime, EndTime) if m.ItemId != 0 { Sql += "and Param like ? " value = append(value, fmt.Sprintf("%%\"item_id\":%d%%", m.ItemId)) TotalSql += "and Param like ? " totalValue = append(totalValue, fmt.Sprintf("%%\"item_id\":%d%%", m.ItemId)) } if m.EventParam != "" { Sql += "and Param like ? " value = append(value, fmt.Sprintf("%%\"change_type\":\"%s\"%%", m.EventParam)) TotalSql += "and Param like ? " totalValue = append(totalValue, fmt.Sprintf("%%\"change_type\":\"%s\"%%", m.EventParam)) } value = append(value, (m.CurrentPage-1)*m.PageSize, m.PageSize) Sql += "ORDER BY Timestamp DESC LIMIT ?, ?" err = Db.Select(&assets, Sql, value...) if err != nil { return nil, fmt.Errorf("failed to get asset list: %v", err) } var total int err = Db.QueryRow(TotalSql, totalValue...).Scan(&total) if err != nil { return nil, fmt.Errorf("failed to get asset count: %v", err) } resData := []*ResAssetDetail{} Sum := 0 NSum := 0 PSum := 0 for _, asset := range assets { param := map[string]interface{}{} err := json.Unmarshal([]byte(asset.Param), ¶m) if err != nil { continue } Sum += util.Int(param["change_num"]) if param["change_type"].(string) == "gain" { PSum += util.Int(param["change_num"]) } else { NSum += util.Int(param["change_num"]) } resData = append(resData, &ResAssetDetail{ Uid: asset.Uid, ChangeType: param["change_type"].(string), ChangeNum: util.Int(param["change_num"]), ChangeAfter: util.Int(param["change_after"]), ItemId: util.Int(param["item_id"]), Timestamp: asset.Timestamp, }) } return &ResAsset{ Total: total, Data: resData, Sum: Sum, NSum: NSum, PSum: PSum, }, nil } func (m *Log) Event() (*ResEvent, error) { AppId, _ := util.ParseUid(m.Uid) AppConfig, err := util.GetAppConfig(AppId) if err != nil { return nil, err } Db := util.MPool.GetTopicDB(AppConfig.Topic) defer Db.Close() if Db == nil { return nil, fmt.Errorf("failed to get mysql database") } StartTime := m.StartTime EndTime := m.EndTime assets := []*Event{} Sql := "SELECT * FROM log_event WHERE Uid = ? and `Event` != 'asset_change' and Timestamp >= ? and Timestamp <= ? " Value := make([]interface{}, 0) Value = append(Value, m.Uid, StartTime, EndTime) if m.EventParam != "" { Sql += "and `Event` = ? " Value = append(Value, m.EventParam) } Sql += "ORDER BY Timestamp DESC LIMIT ?, ?" Value = append(Value, (m.CurrentPage-1)*m.PageSize, m.PageSize) err = Db.Select(&assets, Sql, Value...) // if m.EventParam != "" { // err = Db.Select(&assets, "SELECT * FROM log_event WHERE Uid = ? and `Event` = ? ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, m.EventParam, (m.CurrentPage-1)*m.PageSize, m.PageSize) // } else { // err = Db.Select(&assets, "SELECT * FROM log_event WHERE Uid = ? and `Event` != 'asset_change' ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize) // } if err != nil { return nil, fmt.Errorf("failed to get event list: %v", err) } var total int totalSql := "SELECT COUNT(*) FROM log_event WHERE Uid = ? and `Event` != 'asset_change' and Timestamp >= ? and Timestamp <= ? " totalValue := make([]interface{}, 0) totalValue = append(totalValue, m.Uid, StartTime, EndTime) if m.EventParam != "" { totalSql += "and `Event` = ? " totalValue = append(totalValue, m.EventParam) } err = Db.QueryRow(totalSql, totalValue...).Scan(&total) //err = Db.QueryRow("SELECT COUNT(*) FROM log_event WHERE Uid = ? and `Event` != 'asset_change'", m.Uid).Scan(&total) if err != nil { return nil, fmt.Errorf("failed to get event count: %v", err) } for _, asset := range assets { asset.Label = asset.Event } return &ResEvent{ Total: total, Data: assets, }, nil } func (m *Log) Order() (*ResOrder, error) { AppConfig, err := util.GetAppConfig(m.AppId) if err != nil { return nil, err } Db := util.MPool.GetTopicDB(AppConfig.Topic) defer Db.Close() if Db == nil { return nil, fmt.Errorf("failed to get mysql database") } assets := []*Order{} if m.Uid == 0 { err = Db.Select(&assets, "SELECT * FROM log_order where `PayTime` > 0 ORDER BY Timestamp DESC LIMIT ?, ?", (m.CurrentPage-1)*m.PageSize, m.PageSize) } else { err = Db.Select(&assets, "SELECT * FROM log_order WHERE Uid = ? ORDER BY Timestamp DESC LIMIT ?, ?", m.Uid, (m.CurrentPage-1)*m.PageSize, m.PageSize) } if err != nil { return nil, fmt.Errorf("failed to get asset list: %v", err) } var total int if m.Uid == 0 { err = Db.QueryRow("SELECT COUNT(*) FROM log_order").Scan(&total) } else { err = Db.QueryRow("SELECT COUNT(*) FROM log_order WHERE Uid = ? ", m.Uid).Scan(&total) } for _, asset := range assets { asset.CreateTimeStr = util.TimestampToDateTime(int64(asset.CreateTime), AppConfig.Tz) asset.PayTimeStr = util.TimestampToDateTime(int64(asset.PayTime), AppConfig.Tz) } if err != nil { return nil, fmt.Errorf("failed to get asset count: %v", err) } return &ResOrder{ Total: total, Data: assets, }, nil } type ResHeat struct { Date string `json:"date"` Value int `json:"value"` } func (m *Log) Heat() ([]*ResHeat, error) { m.AppId = m.Uid / 100000000 AppConfig, err := util.GetAppConfig(m.AppId) if err != nil { return nil, err } Db := util.MPool.GetTopicDB(AppConfig.Topic) defer Db.Close() if Db == nil { return nil, fmt.Errorf("failed to get mysql database") } assets := []*ResHeat{} year := util.Year() startDate := fmt.Sprintf("%d-01-01T00:00:00Z", year) endDate := fmt.Sprintf("%d-12-31T23:59:59Z", year) startTimestamp, err := util.ParseTimeToTimestamp(startDate, AppConfig.Tz) if err != nil { return nil, err } endTimestamp, err := util.ParseTimeToTimestamp(endDate, AppConfig.Tz) if err != nil { return nil, err } // 使用一次查询获取整年的数据,然后在Go中按日期分组 type LogRecord struct { Timestamp int64 `db:"Timestamp"` } var records []LogRecord simpleSQL := "SELECT Timestamp FROM log_event WHERE Uid= ? And Timestamp >= ? AND Timestamp <= ? AND Timestamp IS NOT NULL AND Timestamp > 0 " err = Db.Select(&records, simpleSQL, m.Uid, startTimestamp, endTimestamp) if err != nil { return nil, fmt.Errorf("failed to get log records: %v", err) } // 在Go中按日期分组统计 dateCountMap := make(map[string]int) for _, record := range records { date := util.TimestampToDate(record.Timestamp, AppConfig.Tz) if date != "" { dateCountMap[date]++ } } // 生成完整的日期范围,包括没有数据的日期 for i := startTimestamp; i <= endTimestamp; i += 24 * 3600 { date := util.TimestampToDate(i, AppConfig.Tz) if date == "" { continue // 跳过无效的日期 } count := dateCountMap[date] // 如果没有数据,默认为0 assets = append(assets, &ResHeat{ Date: date, Value: count, }) } return assets, nil }