package service import ( "encoding/json" "fmt" "gadmin/config" "gadmin/internal/admin/consts" "gadmin/internal/admin/data" "gadmin/internal/admin/forms" "gadmin/internal/elastic/eapi" "gadmin/internal/gorm/model" "gadmin/internal/gorm/query" "gadmin/utility" "gadmin/utility/serializer" "github.com/gin-gonic/gin" "github.com/sirupsen/logrus" "os" "sort" ) var ChangedLogs = new(sChangedLogs) type sChangedLogs struct{} func (s *sChangedLogs) ItemRanking(ctx *gin.Context, req forms.ItemRankingReq) serializer.Response { type mods struct { ID int64 `json:"id"` UserId int64 `json:"user_id"` T int64 `json:"total"` NickName string `json:"nickName"` Source int64 `json:"source"` } var ( where eapi.M index = fmt.Sprintf("%s%s", os.Getenv("ELASTIC_TOPIC"), "changed_logs_*") lists []*mods ) must := []eapi.M{ { "term": eapi.M{ "source": req.Source, }, }, { "range": eapi.M{ "times": eapi.M{ "gt": 0, }, }, }, } if req.ServerId > 0 { must = append(must, eapi.M{ "term": eapi.M{ "server_id": req.ServerId, }, }) } if len(req.Createtime) == 2 { must = append(must, eapi.M{ "range": eapi.M{ "time": eapi.M{ "gte": req.Createtime[0], "lte": req.Createtime[1], }, }}) } where = eapi.M{ "query": eapi.M{ "bool": eapi.M{ "must": must, }, }, } logrus.Warnf("where:%+v", utility.DumpToJSON(where)) topList, err := eapi.TopSumScore(ctx, index, where, "user_id", "times", 100) if err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 TopList", err) } var ( models forms.ListRes ) for i := 0; i < len(topList); i++ { v := new(mods) v.ID = int64(i + 1) v.UserId = topList[i].Key v.T = int64(topList[i].SumScore.Value) v.Source = req.Source user := data.GetUser(v.UserId) if user != nil { v.NickName = user.NickName } lists = append(lists, v) } models.List = lists models.Page = req.Page models.PerPage = req.PerPage models.PageCount = 0 return serializer.Suc(models) } func (s *sChangedLogs) DiamondRanking(ctx *gin.Context, req forms.DiamondRankingReq) serializer.Response { type Result struct { ID int64 `json:"id"` UserId int64 `json:"user_id"` T int64 `json:"total"` NickName string `json:"nickName"` RechargeAmount float64 `json:"rechargeAmount"` } type Counter struct { Total float64 `json:"total"` } var ( models forms.ListRes field = "expend_diamond" offset int64 = 0 result []Result count int64 = 0 ) if req.Type == 2 { field = "expend_coin" } req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage) countSql := fmt.Sprintf("SELECT sum(`%v`) as t FROM `changed_player` WHERE `%v` < 0", field, field) if req.ServerId > 0 { countSql = fmt.Sprintf(countSql+" and server_id = %v", req.ServerId) } countSql = countSql + " GROUP BY `playerid` ORDER BY t ASC" config.DB.Raw(countSql).Count(&count) if count > 0 { listSql := fmt.Sprintf("SELECT `playerid` as user_id,sum(`%v`) as t FROM `changed_player` WHERE `%v` < 0", field, field) if req.ServerId > 0 { listSql = fmt.Sprintf(listSql+" and server_id = %v", req.ServerId) } listSql = fmt.Sprintf("%v GROUP BY `playerid` ORDER BY t ASC LIMIT %d OFFSET %d", listSql, req.PerPage, offset) config.DB.Raw(listSql).Find(&result) for i := 0; i < len(result); i++ { result[i].ID = offset + int64(i) + 1 result[i].T = result[i].T * -1 user := data.GetUser(result[i].UserId) if user != nil { result[i].NickName = user.NickName } var ( orderQuery = query.Use(config.DB).Order rechargeAmountCounter Counter ) err := orderQuery.WithContext(ctx).Select(orderQuery.Money.Sum().As("total")). Where(orderQuery.PlayerID.Eq(result[i].UserId), orderQuery.Status.Eq(consts.OrderStateSuccess)). Scan(&rechargeAmountCounter) if err != nil { return serializer.Err( consts.CodeParamErr, "查询出错 DiamondRanking RechargeAmount count", err, ) } result[i].RechargeAmount = rechargeAmountCounter.Total } } models.List = result models.Page = req.Page models.PerPage = req.PerPage models.PageCount = (count + req.PerPage - 1) / req.PerPage return serializer.Suc(models) } func (s *sChangedLogs) unionModel(ctx *gin.Context, where string) (unionALL string, err error) { type Table struct { Value string } dbName := config.GetDBName(os.Getenv("MYSQL_DSN")) var sql = "SELECT TABLE_NAME as `value` FROM information_schema.`TABLES` WHERE TABLE_SCHEMA ='" + dbName + "' AND TABLE_NAME LIKE 'changed_logs%'" tx := config.DB.Raw(sql) var tables []string if err = tx.Scan(&tables).Error; err != nil { return } logrus.Warnf("tables:%+v", tables) for k, table := range tables { if k == 0 { unionALL = fmt.Sprintf("(SELECT * FROM %s %s)", table, where) continue } unionALL += fmt.Sprintf(" UNION ALL (SELECT * FROM %s %s)", table, where) } return unionALL, nil } func (s *sChangedLogs) List(ctx *gin.Context, req forms.ChangedLogsListReq) serializer.Response { type ChangedLog struct { model.ChangedLog NickName string `json:"nickName"` } var ( //c = query.Use(config.DB).PlayerChannel //q = query.Use(config.DB).ChangedLog //m = q.WithContext(ctx) offset int64 = 0 models forms.UserAccountListRes lists []ChangedLog hasWhere bool where string count int64 masterWhere string ) if req.ServerId > 0 { if hasWhere { where += fmt.Sprintf(" and server_id = %v", req.ServerId) } else { hasWhere = true where += fmt.Sprintf(" where server_id = %v", req.ServerId) } } if len(req.Createtime) == 2 { if hasWhere { where += fmt.Sprintf(" and `time` BETWEEN %v AND %v", int32(req.Createtime[0]), int32(req.Createtime[1])) } else { hasWhere = true where += fmt.Sprintf(" where `time` BETWEEN %v AND %v", int32(req.Createtime[0]), int32(req.Createtime[1])) } } if req.Source > 0 { if hasWhere { where += fmt.Sprintf(" and source = %v", req.Source) } else { hasWhere = true where += fmt.Sprintf(" where source = %v", req.Source) } } if req.UserId > 0 { if hasWhere { where += fmt.Sprintf(" and user_id = %v", req.UserId) } else { hasWhere = true where += fmt.Sprintf(" where user_id = %v", req.UserId) } } switch req.ChannelId { case consts.ChannelIdNone: // 不选择渠道 case consts.ChannelIdAllAdv, consts.ChannelIdAllWx, consts.ChannelIdAllTT: var cls = Channel.GetIdsByTypeToString(req.ChannelId) if hasWhere { where += fmt.Sprintf(" and channel_id in (%v)", cls) } else { hasWhere = true where += fmt.Sprintf(" where channel_id in (%v)", cls) } default: // 指定渠道 if hasWhere { where += fmt.Sprintf(" and channel_id = %v", req.ChannelId) } else { hasWhere = true where += fmt.Sprintf(" where channel_id = %v", req.ChannelId) } } unionALL, err := s.unionModel(ctx, where) if err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 unionModel", err) } countSql := fmt.Sprintf("SELECT count(1) FROM(%s) as a", unionALL) getSql := fmt.Sprintf("SELECT * FROM(%s) as a", unionALL) // 排序 masterWhere += " ORDER BY time DESC" // 分页 req.Page, req.PerPage, offset = forms.CalculatePage(req.Page, req.PerPage) config.DB.Raw(countSql + masterWhere).Scan(&count) if count > 0 { masterWhere += fmt.Sprintf(" LIMIT %v", req.PerPage) if offset > 0 { masterWhere += fmt.Sprintf(" OFFSET %v", offset) } config.DB.Raw(getSql + masterWhere).Scan(&lists) } for k, v := range lists { user := data.GetUser(v.UserID) if user != nil { lists[k].NickName = user.NickName } } models.List = lists models.Page = req.Page models.PerPage = req.PerPage models.PageCount = (count + req.PerPage - 1) / req.PerPage return serializer.Suc(models) } type StatisticsResult struct { Type int32 `json:"type"` Source int32 `json:"source"` UserCount int `json:"user_count"` Counts int64 `json:"counts"` Amount int64 `json:"amount"` Players []int64 `json:"-"` } type StatisticsResults []*StatisticsResult func (s StatisticsResults) Len() int { return len(s) } func (s StatisticsResults) Less(i, j int) bool { return s[i].Amount < s[j].Amount } func (s StatisticsResults) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // Statistics 消费统计 func (s *sChangedLogs) Statistics(ctx *gin.Context, req forms.ConsumptionStatisticsReq) serializer.Response { var ( q = query.Use(config.DB).ChangedStatistic m = q.WithContext(ctx) models forms.UserAccountListRes lists []*model.ChangedStatistic results StatisticsResults ) if req.Type == 1 { // 钻石 m = m.Where(q.Type.Eq(1)) } else { // 金币 m = m.Where(q.Type.Eq(2)) } if req.ServerId > 0 { m = m.Where(q.ServerID.Eq(req.ServerId)) } if req.Source > 0 { m = m.Where(q.Source.Eq(req.Source)) } if len(req.Date) == 2 { m = m.Where(q.Date.Between(req.Date[0], req.Date[1])) } switch req.ChannelId { case consts.ChannelIdNone: // 不选择渠道 case consts.ChannelIdAllAdv, consts.ChannelIdAllWx, consts.ChannelIdAllTT: // 所有的广告渠道 m = m.Where(q.ChannelID.In(Channel.GetIdsByType(req.ChannelId)...)) default: // 指定渠道 m = m.Where(q.ChannelID.Eq(req.ChannelId)) } if err := m.Scan(&lists); err != nil { return serializer.Err(consts.CodeParamErr, "查询出错 lists", err) } for _, v := range lists { var ( exist bool players []int64 ) for _, vv := range results { if vv.Source == v.Source { exist = true vv.Amount = vv.Amount + v.Amount vv.Counts = vv.Counts + v.Counts if err := json.Unmarshal([]byte(v.Players), &players); err != nil { logrus.Warnf("json.Unmarshal err:%+v, v:%+v", err, v) return serializer.Err(consts.CodeParamErr, "json.Unmarshal err", err) } vv.Players = append(vv.Players, players...) } } if exist == false { if err := json.Unmarshal([]byte(v.Players), &players); err != nil { logrus.Warnf("json.Unmarshal2 err:%+v, v:%+v", err, v) return serializer.Err(consts.CodeParamErr, "json.Unmarshal2 err", err) } results = append(results, &StatisticsResult{ Type: v.Type, Source: v.Source, Amount: v.Amount, Counts: v.Counts, Players: players, }) } } for _, v := range results { v.UserCount = len(utility.UniqueInt64s(v.Players)) } sort.Sort(results) models.List = results return serializer.Suc(models) }