Files
stat_center/service/botser/handler.go
T
2026-05-20 16:13:58 +08:00

686 lines
25 KiB
Go

package botser
import (
"bytes"
"context"
"errors"
"fmt"
"os"
"stat/common/crypt"
"stat/common/statutils"
"stat/common/stdLog"
"stat/common/tgbot"
"stat/common/utils"
"stat/models/appInfoMod"
"stat/models/botdailyhourstat"
"stat/models/botreport"
"stat/models/channelmod"
"stat/models/channelpackage"
"stat/models/versionMod"
"stat/service/crossSer"
"stat/service/innerserverser"
"stat/service/versionSer"
"stat/skd/job/monitor"
"stat/statg"
"strings"
"time"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/bson"
"golang.org/x/exp/slices"
)
func DisplayAppButtons(ctx context.Context, cmd *tgbot.Command) error {
list, err := appInfoMod.GetAllAppInfoEx(ctx)
if err != nil {
return err
}
title := fmt.Sprintf("请选择您要查询%s的应用:", cmd.GetFlagStringValue("-title"))
keyboard := GetAppKeyboard(list, cmd.Message().Text, 2)
return cmd.SendEdit(title, keyboard)
}
func DisplayStatProjectButtons(ctx context.Context, cmd *tgbot.Command) error {
title := fmt.Sprintf("请选择统计项目:")
keyboard := GetStatProjectKeyboard(cmd.Message().Text)
return cmd.SendEdit(title, keyboard)
}
func HandleMenuCmd(ctx context.Context, cmd *tgbot.Command) error {
return cmd.SendReply("请选择命令:", MenuKeyboard)
}
func HandleWhatCmd(ctx context.Context, cmd *tgbot.Command) error {
text := fmt.Sprintf("会话信息:\n")
text += fmt.Sprintf("用户:【%s】\n", cmd.Message().From.FirstName+cmd.Message().From.LastName)
text += fmt.Sprintf("UID:【%d】\n", cmd.Message().From.ID)
text += fmt.Sprintf("聊天:【%s】\n", cmd.Message().Chat.Title)
text += fmt.Sprintf("CID:【%d】\n", cmd.Message().Chat.ID)
return cmd.SendText(text)
}
func HandleMenuCmd0(ctx context.Context, cmd *tgbot.Command) error {
text := "前一天旧的 /recharge\n 综合统计前一天的 /rechargenew\n" +
"综合从第几天到第几天/rechargedate -begin=2024-01-01 -end=2024-01-21 @bot\n 综合统计具体年月日/rechargeoneday -date=2024-01-01\n"
return cmd.SendText(text)
}
// channel_apk
func HandleChannelApkCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return tgbot.NewUserError(cmd, "请输入应用ID,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
channel := cmd.GetFlagStringValue("-channel")
if channel == "" {
return tgbot.NewUserError(cmd, "请输入渠道名称,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
debug := cmd.GetFlagStringValue("-debug")
appNames, err := appInfoMod.GetAllAppIdNameMap(ctx)
if err != nil {
return err
}
appId := appIds[0]
version, err := versionMod.ButtonClick(ctx, appId, "android", 0)
if err != nil {
return tgbot.NewUserError(cmd, fmt.Sprintf("获取应用【%s】(id=%d) 版本信息失败: %s\n", appNames[appId], appId, err.Error()))
}
pack, serr := channelpackage.FindOneChannelPackage(ctx, bson.M{
channelpackage.FN.ChannelPackage.AppId: appId,
channelpackage.FN.ChannelPackage.Channel: channel,
channelpackage.FN.ChannelPackage.Version: version.VersionNum,
channelpackage.FN.ChannelPackage.FileName: version.Md5,
})
if serr != nil && serr.Code != stdLog.DataNotExist {
return tgbot.NewUserError(cmd, fmt.Sprintf("查找渠道包出错【app=%s】(id=%d) 渠道【%s】, Error:%s\n", appNames[appId], appId, channel, serr.Error()))
}
logBody := bytes.NewBuffer(nil)
if pack != nil {
if pack.Status == channelpackage.ChanApkStatusSuccess {
text := fmt.Sprintf("渠道包已经存在:\n")
text += fmt.Sprintf("应用:【%s】(%d)\n", appNames[appId], appId)
text += fmt.Sprintf("渠道:【%s】\n", channel)
text += fmt.Sprintf("版本:【%s】\n", version.VersionNum)
text += fmt.Sprintf("文件:【%s】\n", version.Md5)
text += fmt.Sprintf("发布:【%s】\n", version.CreatedAt.Format(time.DateTime))
text += fmt.Sprintf("生成:【%s】\n", pack.GenTime.Format(time.DateTime))
baseUrls := versionSer.GetPackageBaseDomain(appId)
for index, baseUrl := range baseUrls {
text += fmt.Sprintf("下载链接-%d: %s\n", index, pack.GetRandomLink([]string{baseUrl}))
}
return cmd.SendReply(text, nil)
}
if pack.Status == channelpackage.ChanApkStatusMaking && time.Now().Sub(pack.GenTime) < 10*time.Minute {
return tgbot.NewUserError(cmd, fmt.Sprintf("渠道包正在生成中【app=%s】(id=%d) 渠道【%s】请稍后再试。。。\n", appNames[appId], appId, channel))
}
if pack, err = versionSer.TryMakeChannelApk(ctx, appId, channel, version, pack, "渠道包不在成功状态很久了", true, logBody); err != nil {
return tgbot.NewUserError(cmd, fmt.Sprintf("生成渠道包出错【app=%s】(id=%d) 渠道【%s】, Error:%s\n", appNames[appId], appId, channel, err.Error()))
}
text := fmt.Sprintf("渠道包生成成功:\n")
text += fmt.Sprintf("应用:【%s】(%d)\n", appNames[appId], appId)
text += fmt.Sprintf("渠道:【%s】\n", channel)
text += fmt.Sprintf("版本:【%s】\n", version.VersionNum)
text += fmt.Sprintf("文件:【%s】\n", version.Md5)
text += fmt.Sprintf("发布:【%s】\n", version.CreatedAt.Format(time.DateTime))
text += fmt.Sprintf("生成:【%s】\n", pack.GenTime.Format(time.DateTime))
baseUrls := versionSer.GetPackageBaseDomain(appId)
for index, baseUrl := range baseUrls {
text += fmt.Sprintf("下载链接-%d: %s\n", index, pack.GetRandomLink([]string{baseUrl}))
}
if strings.ToLower(debug) == strings.ToLower(crypt.StrToMd5(fmt.Sprintf("#<%s>$", time.Now().Format(time.DateOnly)))) {
text += logBody.String()
}
return cmd.SendReply(text, nil)
} else {
// 生成apk
reason := fmt.Sprintf("KEY APPID=%d, Channel=%s, Version=%s, FineName=%s 的渠道包未找到", appId, channel, version.VersionNum, version.Md5)
if pack, err = versionSer.TryMakeChannelApk(ctx, appId, channel, version, pack, reason, true, logBody); err != nil {
return tgbot.NewUserError(cmd, fmt.Sprintf("生成渠道包出错【app=%s】(id=%d) 渠道【%s】, Error:%s\n", appNames[appId], appId, channel, err.Error()))
}
text := fmt.Sprintf("渠道包生成成功:\n")
text += fmt.Sprintf("应用:【%s】(%d)\n", appNames[appId], appId)
text += fmt.Sprintf("渠道:【%s】\n", channel)
text += fmt.Sprintf("版本:【%s】\n", version.VersionNum)
text += fmt.Sprintf("文件:【%s】\n", version.Md5)
text += fmt.Sprintf("发布:【%s】\n", version.CreatedAt.Format(time.DateTime))
text += fmt.Sprintf("生成:【%s】\n", pack.GenTime.Format(time.DateTime))
baseUrls := versionSer.GetPackageBaseDomain(appId)
for index, baseUrl := range baseUrls {
text += fmt.Sprintf("下载链接-%d: %s\n", index, pack.GetRandomLink([]string{baseUrl}))
}
if strings.ToLower(debug) == strings.ToLower(crypt.StrToMd5(fmt.Sprintf("#<%s>$", time.Now().Format(time.DateOnly)))) {
text += logBody.String()
}
return cmd.SendReply(text, nil)
}
}
// channel_analyze
func HandleChannelAnalyzeCmd(ctx context.Context, cmd *tgbot.Command) error {
channel := cmd.GetFlagStringValue("-channel")
if channel == "" {
return tgbot.NewUserError(cmd, "请输入渠道名称,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
sBegin := cmd.GetFlagStringValue("-begin")
if sBegin == "" {
return tgbot.NewUserError(cmd, "请输入查询开始日期,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
sEnd := cmd.GetFlagStringValue("-end")
if sEnd == "" {
return tgbot.NewUserError(cmd, "请输入查询结束日期,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
count, err := channelmod.CountChannelInfos(ctx, bson.M{channelmod.FN.ChannelInfo.Channel: channel})
if err != nil {
return tgbot.NewUserError(cmd, "查询渠道出错:"+err.Error())
}
if count == 0 {
return tgbot.NewUserError(cmd, "服务器没有这个渠道:"+channel)
}
begin, err := time.ParseInLocation("2006-01-02", sBegin, time.Local)
if err != nil {
return tgbot.NewUserError(cmd, "解析开始日期出错, 格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
end, err := time.ParseInLocation("2006-01-02", sEnd, time.Local)
if err != nil {
return tgbot.NewUserError(cmd, "解析结束日期出错, 格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
item, err := ChannelAnalyze(ctx, channel, begin, end)
if err != nil {
return tgbot.NewUserError(cmd, "分析渠道出错:"+err.Error())
}
top, _ := cmd.GetFlagInt32Value("-top")
if top <= 0 {
top = 10
}
text := fmt.Sprintf("渠道分析:%s\n", channel)
text += fmt.Sprintf("开始时间:%s\n", sBegin)
text += fmt.Sprintf("结束时间:%s\n", sEnd)
text += "=====渠道分析结果=====\n"
text += fmt.Sprintf("注册用户:%d\n", item.RegisterCount)
text += fmt.Sprintf("注册IP数:%d\n", item.RegisterIpCount)
text += fmt.Sprintf("访问用户:%d\n", len(item.VisitCountMap))
text += fmt.Sprintf("注册1小时后访问:%d\n", len(item.ValidVisitAfterHourMap))
text += fmt.Sprintf("注册1天后访问:%d\n", len(item.ValidVisitAfterDayMap))
text += fmt.Sprintf("注册2天后访问:%d\n", len(item.ValidVisitAfterTowDayMap))
text += fmt.Sprintf("充值次数:%d\n", item.RechargeCount)
text += fmt.Sprintf("充值用户:%d\n", len(item.RegisterUserMap))
text += fmt.Sprintf("充值钱数:%d元\n", item.RechargeAmount/100)
text += fmt.Sprintf("游戏充值:%d\n", item.GameRecharge/100)
text += fmt.Sprintf("游戏提现:%d\n", item.GameWithdraw/100)
text += "=====IP注册数前10名=====\n"
ranks := item.IpRank(int(top))
for _, rank := range ranks {
text += fmt.Sprintf("注册:%d, IP:%s\n", rank.Count, rank.Ip)
}
return cmd.SendReply(text, nil)
}
func HandleGameReportCmd(ctx context.Context, cmd *tgbot.Command) error {
appMap, err := appInfoMod.GetAllAppIdNameMap(ctx)
if err != nil {
return err
}
if _, ok := appMap[888]; !ok {
return errors.New("本服务器没有游戏统计")
}
back, err := cmd.GetFlagInt32Value("-back")
if err != nil {
return tgbot.NewUserError(cmd, "请输入回退天数,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
if back > 0 {
back *= -1
}
fileName, err := GetGameReportFile(ctx, time.Now().AddDate(0, 0, int(back)))
if err != nil {
return err
}
cmd.FilePath = fileName
return cmd.SendReply("游戏统计报表文件", nil)
}
func HandleAutoTaskStatusCmd(ctx context.Context, cmd *tgbot.Command) error {
if cmd.HasFlag("-file") {
content := statutils.ServerMon.ToJson()
filePath := fmt.Sprintf("/tmp/%s.json", utils.UUID())
err := os.WriteFile(filePath, []byte(content), 0666)
if err != nil {
return err
}
cmd.FilePath = filePath
return cmd.SendReply("自动任务数据", nil)
} else {
content := statutils.ServerMon.Display()
return cmd.SendReply(content, nil)
}
}
func HandleCloseCmd(ctx context.Context, cmd *tgbot.Command) error {
return cmd.SendDelete()
}
func HandleAppListCmd(ctx context.Context, cmd *tgbot.Command) error {
list, err := appInfoMod.GetAllAppInfo(ctx)
if err != nil {
return err
}
allIds := make([]int32, 0, len(list))
dbApps := make(map[int32]*appInfoMod.AppInfo)
for _, app := range list {
_app := app
dbApps[app.AppId] = &_app
allIds = append(allIds, app.AppId)
}
endpoints := statg.GlobalEndpoints.GetIndexEndpoints(statg.Conf.ServerIndex)
for _, endpoint := range endpoints {
if _, exists := dbApps[endpoint.AppId]; !exists {
allIds = append(allIds, endpoint.AppId)
}
}
text := fmt.Sprintf("应用列表:【%s】\n", time.Now().Format("2006-01-02T15:04:05"))
for _, id := range allIds {
end := endpoints.GetEndpointByAppId(id)
app := dbApps[id]
if end != nil && app != nil {
text += fmt.Sprintf("【%s】【%s】【%s】【%d】\n", end.NameFull, end.NameShort, end.NameEn, end.AppId)
warns := make([]string, 0)
if end.ServerUrl == "" {
warns = append(warns, "服务器地址没配‼️")
}
if end.NameEn == "" {
warns = append(warns, "名称英文缩写没配‼️")
}
if end.H5Config == "" {
warns = append(warns, "H5Config没配‼️")
}
if end.H5Origin == "" {
warns = append(warns, "H5Origin没配‼️")
}
if end.H5Target == "" {
warns = append(warns, "H5Target没配‼️")
}
if len(warns) > 0 {
text += fmt.Sprintf("【%s】", strings.Join(warns, ";"))
}
} else if app == nil && end != nil {
text += fmt.Sprintf("【%s】【%s】【%s】【%d】数据库未添加该APP‼️\n", end.NameFull, end.NameShort, end.NameEn, end.AppId)
} else if app != nil && end == nil {
text += fmt.Sprintf("【%s】【%d】数据库存在该APP,但是没有配置文件没有‼️\n", app.Name, app.AppId)
}
}
return cmd.SendBack(text)
}
func HandleSyncStatusCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return DisplayAppButtons(ctx, cmd)
}
appNames, err := appInfoMod.GetAllAppIdNameMap(ctx)
if err != nil {
return err
}
isDetail := slices.Contains(cmd.Params, "-detail")
var lastAppId int32
text := fmt.Sprintf("同步状态:%s\n", time.Now().Format("2006-01-02T15:04:05"))
statutils.GlobalSyncMonitor.Traverse(func(item *statutils.SyncItem) {
if len(appIds) > 0 && !slices.Contains(appIds, item.AppID) {
return
}
if item.AppID != lastAppId {
lastAppId = item.AppID
text += fmt.Sprintf("\U0001F7E2【%d:%s】\n", item.AppID, appNames[item.AppID])
}
text += fmt.Sprintf("1️⃣描述【%s】\n", item.JobDesc)
if isDetail {
text += fmt.Sprintf("2️⃣名称【%s】\n", item.JobName)
text += fmt.Sprintf("3️⃣开始【%s】\n", item.JobBegin().Format("2006-01-02T15:04:05"))
if item.JobEnd().Before(item.JobBegin()) { // 未完成
text += fmt.Sprintf("4️⃣用时【%s】\n", fmt.Sprintf("%s", time.Now().Sub(item.JobBegin())))
text += fmt.Sprintf("5️⃣结束【正在执行...】\n")
} else {
text += fmt.Sprintf("4️⃣用时【%s】\n", fmt.Sprintf("%s", item.JobEnd().Sub(item.JobBegin())))
text += fmt.Sprintf("5️⃣结束【%s】\n", item.JobEnd().Format("2006-01-02T15:04:05"))
}
text += fmt.Sprintf("6️⃣当前【%d条】\n", item.CurrentCount)
text += fmt.Sprintf("7️⃣当日【%d条】\n", item.TodayCount())
if !item.RequestBegin.Before(item.JobBegin()) {
text += fmt.Sprintf("ℹ请求开始【%s】\n", item.RequestBegin.Format("2006-01-02T15:04:05"))
text += fmt.Sprintf("ℹ请求用时【%s】\n", fmt.Sprintf("%s", item.RequestEnd.Sub(item.RequestBegin)))
text += fmt.Sprintf("ℹ请求结束【%s】\n", item.RequestEnd.Format("2006-01-02T15:04:05"))
}
if !item.ProcessBegin.Before(item.JobBegin()) {
text += fmt.Sprintf("ℹ处理开始【%s】\n", item.ProcessBegin.Format("2006-01-02T15:04:05"))
text += fmt.Sprintf("ℹ处理用时【%s】\n", fmt.Sprintf("%s", item.ProcessEnd.Sub(item.ProcessBegin)))
text += fmt.Sprintf("ℹ处理结束【%s】\n", item.ProcessEnd.Format("2006-01-02T15:04:05"))
}
} else {
text += fmt.Sprintf("2️⃣名称【%s】\n", item.JobName)
text += fmt.Sprintf("3️⃣开始【%s】\n", item.JobBegin().Format("2006-01-02T15:04:05"))
if item.JobEnd().Before(item.JobBegin()) { // 未完成
text += fmt.Sprintf("4️⃣用时【%s】\n", fmt.Sprintf("%s", time.Now().Sub(item.JobBegin())))
text += fmt.Sprintf("5️⃣结束【正在执行...】\n")
} else {
text += fmt.Sprintf("4️⃣用时【%s】\n", fmt.Sprintf("%s", item.JobEnd().Sub(item.JobBegin())))
text += fmt.Sprintf("5️⃣结束【%s】\n", item.JobEnd().Format("2006-01-02T15:04:05"))
}
text += fmt.Sprintf("6️⃣当前【%d条】\n", item.CurrentCount)
text += fmt.Sprintf("7️⃣当日【%d条】\n", item.TodayCount())
}
if item.Error != nil {
text += fmt.Sprintf("🛑错误【%s】\n", item.Error.Error())
}
text += fmt.Sprintf("\n")
})
return cmd.SendBack(text)
}
func HandleTodayStatCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return DisplayAppButtons(ctx, cmd)
}
back, _ := cmd.GetFlagInt32Value("-back")
return DailyStat(ctx, cmd, int(back))
}
func HandleYesterdayStatCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return DisplayAppButtons(ctx, cmd)
}
return DailyStat(ctx, cmd, -1)
}
func HandleDailyStatCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return DisplayAppButtons(ctx, cmd)
}
back, err := cmd.GetFlagInt32Value("-back")
if err != nil {
return tgbot.NewUserError(cmd, "请输入回退天数,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
return DailyStat(ctx, cmd, int(back))
}
func HandleDailyHourStatCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return DisplayAppButtons(ctx, cmd)
}
project := cmd.GetFlagStringValue("-stat")
if project == "" {
return DisplayStatProjectButtons(ctx, cmd)
}
back, err := cmd.GetFlagInt32Value("-back")
if err != nil {
return tgbot.NewUserError(cmd, "请输入回退天数,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
return DailyHourStat(ctx, cmd, int(back))
}
func HandleHourStatCmd(ctx context.Context, cmd *tgbot.Command) error {
appIds := cmd.GetFlagInt32Slice("-app")
if len(appIds) <= 0 {
return DisplayAppButtons(ctx, cmd)
}
back, err := cmd.GetFlagInt32Value("-back")
if err != nil {
return tgbot.NewUserError(cmd, "请输入回退小时数,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
return HourStat(ctx, cmd, int(back))
}
func DailyStat(ctx context.Context, cmd *tgbot.Command, moveBackDays int) error {
appId, err := cmd.GetFlagInt32Value("-app")
if err != nil {
return tgbot.NewUserError(cmd, "请输入应用ID,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
filter := bson.M{}
appMap, err := appInfoMod.GetAllAppIdMap(ctx, filter)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
appInfo := appMap[appId]
if appInfo == nil {
return tgbot.NewUserError(cmd, fmt.Sprintf("应用ID【%d】不存在", appId))
}
if moveBackDays > 0 {
moveBackDays = moveBackDays * -1
}
reportTime := utils.RecentMinute(time.Now(), 60)
if moveBackDays != 0 {
reportTime = utils.BeginWithTime(time.Now().AddDate(0, 0, moveBackDays+1))
}
reportFilter := bson.M{
botreport.FN.BotReport.AppId: appId,
botreport.FN.BotReport.SumDate: reportTime,
}
report, err := botdailyhourstat.FindOneBotHourStatEx(ctx, reportFilter)
if err != nil {
if err == mongo.ErrNoDocuments {
report, err = BotDailyHourStat(ctx, appId, reportTime, false)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
} else {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
}
HistoryFilter := bson.M{
botreport.FN.BotReport.AppId: appId,
botreport.FN.BotReport.SumDate: reportTime.AddDate(0, 0, -1),
}
historyReport, err := botdailyhourstat.FindOneBotHourStatEx(ctx, HistoryFilter)
if err != nil {
if err == mongo.ErrNoDocuments {
historyReport, err = BotDailyHourStat(ctx, appId, reportTime.AddDate(0, 0, -1), true)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
} else {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
}
text, title, desc := report.DisplayDayHourTextWithTitle(appInfo.Name, historyReport)
et := tgbot.NewEntityList(title, desc, []*tgbot.Entity{
{
Content: text,
},
})
return cmd.SendEntity(et)
}
func HourStat(ctx context.Context, cmd *tgbot.Command, moveBackHours int) error {
appId, err := cmd.GetFlagInt32Value("-app")
if err != nil {
return tgbot.NewUserError(cmd, "请输入应用ID,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
filter := bson.M{}
appMap, err := appInfoMod.GetAllAppIdMap(ctx, filter)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
appInfo := appMap[appId]
if appInfo == nil {
return tgbot.NewUserError(cmd, fmt.Sprintf("应用ID【%d】不存在", appId))
}
if moveBackHours > 0 {
moveBackHours = moveBackHours * -1
}
reportTime := utils.RecentMinute(time.Now(), 60)
if moveBackHours != 0 {
reportTime = reportTime.Add(time.Duration(moveBackHours) * time.Hour)
}
reportFilter := bson.M{
botreport.FN.BotReport.SumDate: reportTime,
botreport.FN.BotReport.AppId: appId,
}
report, err := botreport.FindOneBotReport(ctx, reportFilter)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
if report.SumDate != reportTime {
return tgbot.NewUserError(cmd, "数据记录尚未生成,请过五分钟再试")
}
HistoryFilter := bson.M{
botreport.FN.BotReport.SumDate: reportTime.AddDate(0, 0, -1),
botreport.FN.BotReport.AppId: appId,
}
historyReport, err := botreport.FindOneBotReport(ctx, HistoryFilter)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
text := DisplayHourStat(report, historyReport, appInfo, GetHourDesc(moveBackHours))
return cmd.SendBack(text)
}
func DailyHourStat(ctx context.Context, cmd *tgbot.Command, moveBackDays int) error {
appId, err := cmd.GetFlagInt32Value("-app")
if err != nil {
return tgbot.NewUserError(cmd, "请输入应用ID,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
statName := cmd.GetFlagStringValue("-stat")
if statName == "" {
return tgbot.NewUserError(cmd, "请输入统计项目的细分名称:\n"+cmd.Help+"\n"+cmd.Desc)
}
filter := bson.M{}
appMap, err := appInfoMod.GetAllAppIdMap(ctx, filter)
if err != nil {
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
appInfo := appMap[appId]
if appInfo == nil {
return tgbot.NewUserError(cmd, fmt.Sprintf("应用ID【%d】不存在", appId))
}
if moveBackDays > 0 {
moveBackDays = moveBackDays * -1
}
reportTime := utils.RecentMinute(time.Now(), 60)
if moveBackDays != 0 {
reportTime = reportTime.AddDate(0, 0, moveBackDays)
}
reportFilter := bson.M{
botreport.FN.BotReport.AppId: appId,
botreport.FN.BotReport.SumDate: reportTime,
}
report, err := botdailyhourstat.FindOneBotHourStatEx(ctx, reportFilter)
if err != nil {
if err == mongo.ErrNoDocuments {
return tgbot.NewUserError(cmd, "统计记录尚未生成,请过5分钟再试")
}
return tgbot.NewUserError(cmd, "服务器错误:"+err.Error())
}
HistoryFilter := bson.M{
botreport.FN.BotReport.AppId: appId,
botreport.FN.BotReport.SumDate: reportTime.AddDate(0, 0, -1),
}
historyReport, _ := botdailyhourstat.FindOneBotHourStatEx(ctx, HistoryFilter)
photo := fmt.Sprintf("/tmp/%s.png", utils.UUID())
var text string
title := fmt.Sprintf("%s%s%s", appInfo.Name, GetDateDesc(moveBackDays), statutils.StatProjectNameDict[statName])
text, err = report.GenerateTodayTable(title, statName, photo, historyReport)
if err != nil {
return err
}
cmd.PhotoPath = photo
return cmd.SendBack(text)
}
func HandleDistrictDataCmd(ctx context.Context, cmd *tgbot.Command) error {
lanpageinfo := monitor.RunLandPageMonitor()
cmd.SendReply(lanpageinfo, nil)
channelMsg := monitor.ChannelMonitor()
cmd.SendReply(channelMsg, nil)
return nil
}
func HandleCrossDayStatCmd(ctx context.Context, cmd *tgbot.Command) error {
project := cmd.GetFlagStringValue("-stat")
if project == "" {
return DisplayStatProjectButtons(ctx, cmd)
}
if !cmd.HasFlag("-back") {
return tgbot.NewUserError(cmd, "请输入回退天数,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
if cmd.HasFlag("-stat") {
sType := cmd.GetFlagStringValue("-stat")
statMethod, ok := crossSer.CrossStatMethodMap[sType]
if !ok {
return tgbot.NewUserError(cmd, fmt.Sprintf("-stat=%s,没有注册对应的统计方法", sType))
}
return statMethod(ctx, cmd)
} else {
return tgbot.NewUserError(cmd, "-stat 没有填写, 格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
}
func HandleCrossMonthStatCmd(ctx context.Context, cmd *tgbot.Command) error {
if statg.Conf.ServerIndex.IsMadou() {
monthStr := cmd.GetFlagStringValue("-month")
if monthStr == "" {
return tgbot.NewUserError(cmd, "请输入统计月份,格式:\n"+cmd.Help+"\n"+cmd.Desc)
}
return crossSer.CrossMonthStat(ctx, cmd)
}
return nil
}
func HandleVersionCmd(ctx context.Context, cmd *tgbot.Command) error {
text := GetServerInformation()
return cmd.SendReply(text, nil)
}
func HandleRchssendCmd(ctx context.Context, cmd *tgbot.Command) error {
err := innerserverser.InnerServerDailyStat(ctx)
if err != nil {
fmt.Println("HandleRchssendCmd" + err.Error())
return tgbot.NewUserError(cmd, "HandleRchssendCmd:"+err.Error())
}
return nil
}
func HandleRchsMonthBotsendCmd(ctx context.Context, cmd *tgbot.Command) error {
err := innerserverser.InnerServerMonthStat2(ctx, nil, nil, cmd)
if err != nil {
fmt.Println("HandleRchsbotsendCmd" + err.Error())
return tgbot.NewUserError(cmd, "HandleRchsbotsendCmd:"+err.Error())
}
return nil
}
func HandleRchsMonthBotDatetodatesendCmd(ctx context.Context, cmd *tgbot.Command) error {
err := innerserverser.InnerServerBotDateMonthStat(ctx, cmd)
if err != nil {
fmt.Println("HandleRchsbotsendCmd" + err.Error())
return tgbot.NewUserError(cmd, "HandleRchsbotsendCmd:"+err.Error())
}
return nil
}
func HandleRchsDateBotsendCmd(ctx context.Context, cmd *tgbot.Command) error {
err := innerserverser.InnerServerBotDateDayStat(ctx, cmd)
if err != nil {
fmt.Println("HandleRchsbotsendCmd" + err.Error())
return tgbot.NewUserError(cmd, "HandleRchsbotsendCmd:"+err.Error())
}
return nil
}