Initial commit

This commit is contained in:
2026-05-20 16:13:58 +08:00
commit ceffbe382e
500 changed files with 157469 additions and 0 deletions
+345
View File
@@ -0,0 +1,345 @@
package applicationser
import (
"context"
"stat/api/proto"
"stat/common/log"
"stat/common/redis"
"stat/common/stdLog"
"stat/common/utils"
"stat/models/appcategory"
"stat/models/applicationLocMod"
"stat/models/applicationmod"
"time"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo/options"
)
// 外部获取配置应用
func GetApplication(ctx context.Context, req proto.CenterApplicationReq) (code stdLog.CodeType, data interface{}, err error) {
resp := proto.CenterApplicationRes{
List: make([]*proto.CenterApplication, 0),
AppCategoryList: make([]*proto.CenterAppCategory, 0)}
list, err := applicationmod.FindAppByAppId(ctx, req.ParentAppId)
if err != nil {
code = stdLog.AppDbError
return
}
filter := bson.M{"parentAppId": req.ParentAppId, "status": true}
//filter := bson.M{"status": true}
sort := bson.D{{Key: "rank", Value: -1}}
opt := options.Find().SetSort(sort)
categorylist, serr := appcategory.FindManyAppCategory(ctx, filter, opt)
if serr != nil {
code = stdLog.AppCategoryDbError
return
}
if len(list) > 0 {
for _, info := range list {
app := &proto.CenterApplication{
Id: info.Id,
AppId: info.AppId,
ParentAppId: info.ParentAppId,
Name: info.Name,
//Tag: info.Tag,
Internal: info.Internal,
Categories: info.Categories,
Desc: info.Desc,
DownloadUrl: info.DownloadUrl,
IosUrl: info.IosUrl,
AndroidUrl: info.AndroidUrl,
Avatar: info.Avatar,
Status: info.Status,
Rank: info.Rank,
Total: info.Total,
CreatedId: info.CreatedId,
UpdatedId: info.UpdatedId,
CreatedAt: info.CreatedAt,
UpdatedAt: info.UpdatedAt,
IsGame: info.IsGame,
IsRecommend: info.IsRecommend,
NineShow: info.NineShow,
RecreationShow: info.RecreationShow,
HomeShow: info.HomeShow,
LocIds: info.LocIds,
SmallImg: info.SmallImg,
BigImg: info.BigImg,
IsHighQuality: info.IsHighQuality,
HighQualityType: info.HighQualityType,
}
resp.List = append(resp.List, app)
}
}
if len(categorylist) > 0 {
for _, info := range categorylist {
app := &proto.CenterAppCategory{
Id: info.Id,
ParentAppId: info.ParentAppId,
Name: info.Name,
Desc: info.Desc,
Status: info.Status,
Rank: info.Rank,
CreatedAt: info.CreatedAt,
UpdatedAt: info.UpdatedAt,
ImgType: info.ImgType,
}
resp.AppCategoryList = append(resp.AppCategoryList, app)
}
}
data = resp
code = stdLog.Success
return
}
// IncApplicationClickCount
func IncApplicationClickCount(ctx context.Context, param *proto.ApplicationClickReq) (serr *stdLog.SrvErr) {
id, err := primitive.ObjectIDFromHex(param.Id)
if err != nil {
return stdLog.New(stdLog.ParamError, "", err.Error())
}
_, serr = applicationmod.FindOneApplication(ctx, bson.M{"_id": id})
if serr != nil {
return serr
}
// 写入redis
now := time.Now().Local()
set := redis.GetAppClickDaySet(now)
name := redis.GetAppClickHourName(param.Id, now.Hour())
//name := redis.GetAppClickHourNameByAppId(application.AppId, application.ParentAppId, now.Hour())
if _, err := set.IncInt(name, 1); err != nil {
return stdLog.New(stdLog.RedisSet, "", err.Error())
}
// 写入db
update := bson.M{"$inc": bson.M{"total": 1}}
serr = applicationmod.UpdateOneApplication(ctx, bson.M{"_id": id}, update)
if serr != nil {
return serr
}
return nil
}
// AddApplication 添加应用
func AddApplication(ctx context.Context, param *applicationmod.Application, account string) *stdLog.SrvErr {
param.Id = primitive.NewObjectID()
now := utils.Now()
param.CreatedAt = now
//param.CreatedId = userId
param.UpdatedAt = now
//param.UpdatedId = userId
err := applicationmod.InsertOneApplication(ctx, param)
if err != nil {
log.Error("AddApplication:InsertOneApplication", log.E(err))
return err
}
CheckChange(ctx, nil, param, account)
return nil
}
// DelApplication 删除应用
func DelApplication(ctx context.Context, id primitive.ObjectID, account string) *stdLog.SrvErr {
filter := bson.M{"_id": id}
oldDoc, serr := applicationmod.FindOneApplication(ctx, filter)
if serr != nil {
log.Error("UpdateApplication:FindOneApplication", log.Any("id", id), log.E(serr))
return serr
}
count, err := applicationmod.DelOneApplication(ctx, filter)
if err != nil {
log.Error("DelApplication:DelOneApplication", log.Any("appId", id), log.E(err))
return err
}
if count == 0 {
return stdLog.New(stdLog.ErrApplicationNotExist, "", "")
}
CheckChange(ctx, oldDoc, nil, account)
return nil
}
// UpdateApplication 更新应用
func UpdateApplication(ctx context.Context, req *applicationmod.AppUpdate, account string) *stdLog.SrvErr {
id, err := primitive.ObjectIDFromHex(req.Id)
if err != nil {
log.Error("UpdateApplication:ObjectIDFromHex", log.Any("id", req.Id), log.E(err))
return stdLog.New(stdLog.ParamError, "", err.Error())
}
filter := bson.M{"_id": id}
now := utils.Now()
oldDoc, serr := applicationmod.FindOneApplication(ctx, filter)
if serr != nil {
log.Error("UpdateApplication:FindOneApplication", log.Any("id", req.Id), log.E(serr))
return serr
}
doc := &applicationmod.AppUpdateInfo{
AppId: req.Param.AppId,
ParentAppId: req.Param.ParentAppId,
Name: req.Param.Name,
DaoLiangTitle: req.Param.DaoLiangTitle,
//Tag: req.Param.Tag,
Internal: req.Param.Internal,
Categories: req.Param.Categories,
Desc: req.Param.Desc,
DownloadUrl: req.Param.DownloadUrl,
IosUrl: req.Param.IosUrl,
AndroidUrl: req.Param.AndroidUrl,
Avatar: req.Param.Avatar,
Status: req.Param.Status,
Rank: req.Param.Rank,
Total: req.Param.Total,
UpdatedAt: now,
NineShow: req.Param.NineShow,
RecreationShow: req.Param.RecreationShow,
IsGame: req.Param.IsGame,
IsRecommend: req.Param.IsRecommend,
HomeShow: req.Param.HomeShow,
LocIds: req.Param.LocIds,
SmallImg: req.Param.SmallImg,
BigImg: req.Param.BigImg,
IsHighQuality: req.Param.IsHighQuality,
HighQualityType: req.Param.HighQualityType,
StartTime: req.Param.StartTime,
EndTime: req.Param.EndTime,
}
serr = applicationmod.UpdateOneApplication(ctx, filter, bson.M{
"$set": doc,
})
if serr != nil {
log.Error("UpdateApplication:UpdateOneApplication", log.Any("id", req.Id), log.E(serr))
return serr
}
newDoc, serr := applicationmod.FindOneApplication(ctx, filter)
if serr != nil {
log.Error("UpdateApplication:FindOneApplication", log.Any("id", req.Id), log.E(serr))
return serr
}
CheckChange(ctx, oldDoc, newDoc, account)
return nil
}
// GetAppList 获取应用列表
func GetAppList(ctx context.Context, param *proto.GetApplicationsReq) (*proto.GetApplicationsResp, *stdLog.SrvErr) {
filter := bson.M{}
sort := bson.M{applicationmod.FN.Application.Rank: -1}
if param.Id != nil && *param.Id != "" {
id, serr := primitive.ObjectIDFromHex(*param.Id)
if serr != nil {
return nil, stdLog.New(stdLog.ParamError, "", "id错误")
}
filter["_id"] = id
}
if param.Name != nil && *param.Name != "" {
filter["name"] = bson.M{"$regex": *param.Name}
}
if param.DaoLiangTitle != nil && *param.DaoLiangTitle != "" {
filter["daoLiangTitle"] = bson.M{"$regex": *param.DaoLiangTitle}
}
/*if param.Tag != nil && *param.Tag != 0 {
filter["tag"] = *param.Tag
}
*/
if param.Status != nil {
filter["status"] = *param.Status
}
if param.Category != nil {
filter["categories.cid"] = *param.Category
sort["categories.rank"] = 1
} else {
sort["categories.rank"] = 1
}
if param.ParentAppId != nil {
filter["parentAppId"] = param.ParentAppId
}
if len(param.LocIds) > 0 {
filter["locIds"] = bson.M{"$in": param.LocIds}
}
if param.DownloadUrl != nil {
filter["download_url"] = *param.DownloadUrl
}
if param.IosUrl != nil {
filter["iosUrl"] = *param.IosUrl
}
if param.AndroidUrl != nil {
filter["androidUrl"] = *param.AndroidUrl
}
if param.IsHighQuality != nil {
filter["isHighQuality"] = *param.IsHighQuality
}
count, serr := applicationmod.CountApplications(ctx, filter)
if serr != nil {
log.Error("GetAppList:CountApplications", log.E(serr))
return nil, serr
}
if count == 0 {
return &proto.GetApplicationsResp{
List: nil,
Total: count,
}, nil
}
opt := &options.FindOptions{}
opt.SetSort(sort)
opt.SetLimit(param.PageSize)
opt.SetSkip((param.PageNum - 1) * param.PageSize)
applicationList, serr := applicationmod.FindManyApplication(ctx, filter, opt)
if serr != nil {
log.Error("GetAppList:FindManyApplication", log.E(serr))
return nil, serr
}
// 给前端提供分类名字
dict, serr := appcategory.GetAppCategoryIdNameMap(ctx)
if serr != nil {
return nil, serr
}
locDict, err := applicationLocMod.GetAppLocIdNameMap(ctx)
if err != nil {
return nil, err
}
for i, app := range applicationList {
applicationList[i].LocNames = make([]string, 0)
if len(app.LocIds) == 0 {
applicationList[i].LocIds = make([]int64, 0)
} else {
for _, id := range app.LocIds {
if loc, ok := locDict[id]; ok {
applicationList[i].LocNames = append(applicationList[i].LocNames, loc.Name)
}
}
}
for _, item := range app.Categories {
if category := dict[item.CID]; category != nil {
item.Name = category.Name
}
}
}
resp := &proto.GetApplicationsResp{
List: applicationList,
Total: count,
}
return resp, nil
}
+152
View File
@@ -0,0 +1,152 @@
package applicationser
import (
"context"
"stat/api/proto"
"stat/common/genId"
"stat/common/stdLog"
"stat/common/utils"
"stat/models/applicationLocMod"
"stat/models/applicationmod"
"stat/models/appInfoMod"
"time"
)
// 获取广告位置列表
func ListAppLoc(ctx context.Context, param proto.ListAppLocReq) (code stdLog.CodeType, data interface{}, err error) {
resp := proto.ListAppLocRes{
Total: 0,
List: make([]proto.AppLocInfo, 0),
}
skip, limit := utils.ToDBPage(param.PageNum, param.PageSize)
// 获取广告位置信息
total, adsList, err := applicationLocMod.FindApplicationLocationList(ctx, param.AppId, skip, limit)
if err != nil {
code = stdLog.Failure
return
}
resp.Total = total
// 获取app信息
appIds := make([]int32, 0)
for _, v := range adsList {
appIds = append(appIds, v.AppId)
}
appList, err := appInfoMod.GetAppInfosByAppIds(ctx, appIds)
if err != nil {
code = stdLog.Failure
return
}
appMap := make(map[int32]appInfoMod.AppInfo)
for _, v := range appList {
appMap[v.AppId] = v
}
for _, v := range adsList {
appName := ""
if appInfo, ok := appMap[v.AppId]; ok {
appName = appInfo.Name
}
tmp := proto.AppLocInfo{
Id: v.Id,
AppId: v.AppId,
AppName: appName,
LocId: v.LocId,
Name: v.Name,
ImgSizeDesc: v.ImgSizeDesc,
Remark: v.Remark,
CreatedAt: v.CreatedAt,
UpdatedAt: v.UpdatedAt,
}
resp.List = append(resp.List, tmp)
}
code = stdLog.Success
data = resp
return
}
// 新增广告位置
func AddAppLoc(ctx context.Context, param proto.AddAppLocReq) (code stdLog.CodeType, data interface{}, err error) {
// 获取位置信息
locInfo, err := applicationLocMod.FindLocationByAppIdAndLocId(ctx, *param.AppId, *param.LocId)
if err != nil || locInfo.Id > 0 {
code = stdLog.ApplicationLocExists
return
}
adsLocId := genId.GetNextAppLocId()
now := time.Now()
doc := applicationLocMod.ApplicationLocation{
Id: adsLocId,
AppId: *param.AppId,
LocId: *param.LocId,
Name: *param.Name,
ImgSizeDesc: param.ImgSizeDesc,
Remark: param.Remark,
CreatedAt: now,
UpdatedAt: now,
}
if err = applicationLocMod.AddApplicationLocation(ctx, &doc); err != nil {
code = stdLog.Failure
return
}
code = stdLog.Success
return
}
// 修改广告位置
func UpdateAppLoc(ctx context.Context, param proto.UpdateAppLocReq) (code stdLog.CodeType, data interface{}, err error) {
// 获取位置信息
locInfo, err := applicationLocMod.FindLocationById(ctx, *param.Id)
if err != nil {
code = stdLog.Failure
return
}
now := time.Now()
doc := applicationLocMod.UpdateAppLoc{
AppId: param.AppId,
LocId: param.LocId,
Name: param.Name,
ImgSizeDesc: param.ImgSizeDesc,
Remark: param.Remark,
UpdatedAt: &now,
}
if err = applicationLocMod.UpdateApplicationLocation(ctx, *param.Id, doc); err != nil {
code = stdLog.Failure
return
}
// 修改广告的位置id
if param.LocId != nil && *param.LocId != locInfo.LocId {
if err = applicationmod.UpdateLocInfo(ctx, locInfo.AppId, locInfo.LocId, *param.LocId); err != nil {
code = stdLog.Failure
return code, data, err
}
}
code = stdLog.Success
return
}
// 删除广告位置
func DelAppLoc(ctx context.Context, param proto.DelAppLocReq) (code stdLog.CodeType, data interface{}, err error) {
if err = applicationLocMod.DelApplicationLocation(ctx, *param.Id); err != nil {
code = stdLog.Failure
return
}
code = stdLog.Success
return
}
+121
View File
@@ -0,0 +1,121 @@
package applicationser
import (
"context"
"fmt"
"stat/common/enum/consts"
"stat/common/utils"
"stat/models/applicationLocMod"
"stat/models/applicationmod"
"stat/statg"
"time"
)
func CheckChange(ctx context.Context, oldDoc, newDoc *applicationmod.Application, account string) {
msg := ""
changed := false
// 检测更新
if oldDoc != nil && newDoc != nil {
warnChar := "🔴"
msg += fmt.Sprintf("检测到应用变更:\n应用ID:【%s】\n应用名称:【%s】\n", oldDoc.Id.Hex(), oldDoc.Name)
if oldDoc.DownloadUrl != newDoc.DownloadUrl {
changed = true
msg += fmt.Sprintf("下载链接变更:\n┏旧值【%v】\n┗新值【%v】\n", oldDoc.DownloadUrl, newDoc.DownloadUrl)
}
if oldDoc.AndroidUrl != newDoc.AndroidUrl {
changed = true
msg += fmt.Sprintf("安卓链接变更:\n┏旧值【%v】\n┗新值【%v】\n", oldDoc.AndroidUrl, newDoc.AndroidUrl)
}
if oldDoc.IosUrl != newDoc.IosUrl {
changed = true
msg += fmt.Sprintf("IOS链接变更:\n┏旧值【%v】\n┗新值【%v】\n", oldDoc.IosUrl, newDoc.IosUrl)
}
if oldDoc.ParentAppId != newDoc.ParentAppId {
changed = true
msg += fmt.Sprintf("所属appId变更:\n┏旧值【%v】\n┗新值【%v】\n", oldDoc.ParentAppId, newDoc.ParentAppId)
} else {
oSet := utils.NewSet(oldDoc.LocIds)
nSet := utils.NewSet(newDoc.LocIds)
if !oSet.Equal(nSet) { // 两个集合不相等
changed = true
dict := applicationLocMod.FindApplicationLocationDict(ctx, oldDoc.ParentAppId)
oldLocations := ""
for _, id := range oldDoc.LocIds {
oldLocations += fmt.Sprintf("%s,", dict[id].Name)
}
nowLocations := ""
for _, id := range newDoc.LocIds {
nowLocations += fmt.Sprintf("%s,", dict[id].Name)
}
msg += fmt.Sprintf("应用中心位置变更:\n┏旧值【%s】\n┗新值【%s】\n", oldLocations, nowLocations)
}
}
if oldDoc.Status != newDoc.Status {
changed = true
msg += fmt.Sprintf("激活变更:\n┏旧值【%v】【%v】\n┗新值【%v】【%v】\n", oldDoc.Status, consts.StatusDesc[oldDoc.Status],
newDoc.Status, consts.StatusDesc[newDoc.Status])
}
if oldDoc.Internal != newDoc.Internal {
changed = true
msg += fmt.Sprintf("是否内部应用展示,状态变更:\n┏旧值【%v】【%v】\n┗新值【%v】【%v】\n", oldDoc.Internal, consts.IsShowDesc[oldDoc.Internal],
newDoc.Internal, consts.IsShowDesc[newDoc.Internal])
}
if oldDoc.NineShow != newDoc.NineShow {
changed = true
msg += fmt.Sprintf("是否九宫格展示,状态变更:\n┏旧值【%v】【%v】\n┗新值【%v】【%v】\n", oldDoc.NineShow, consts.IsShowDesc[oldDoc.NineShow],
newDoc.NineShow, consts.IsShowDesc[newDoc.NineShow])
}
if oldDoc.RecreationShow != newDoc.RecreationShow {
changed = true
msg += fmt.Sprintf("是否娱乐中心展示,状态变更:\n┏旧值【%v】【%v】\n┗新值【%v】【%v】\n", oldDoc.RecreationShow, consts.IsShowDesc[oldDoc.RecreationShow],
newDoc.RecreationShow, consts.IsShowDesc[newDoc.RecreationShow])
}
if oldDoc.HomeShow != newDoc.HomeShow {
changed = true
msg += fmt.Sprintf("是否首页展示,状态变更:\n┏旧值【%v】【%v】\n┗新值【%v】【%v】\n", oldDoc.HomeShow, consts.IsShowDesc[oldDoc.HomeShow],
newDoc.HomeShow, consts.IsShowDesc[newDoc.HomeShow])
}
if !oldDoc.StartTime.Equal(newDoc.StartTime) {
changed = true
msg += fmt.Sprintf("开始时间变更:\n┏旧值【%v】\n┗新值【%v】\n", oldDoc.StartTime, newDoc.StartTime)
}
if !oldDoc.EndTime.Equal(newDoc.EndTime) {
changed = true
msg += fmt.Sprintf("结束时间变更:\n┏旧值【%v】\n┗新值【%v】\n", oldDoc.EndTime, newDoc.EndTime)
}
msg = warnChar + msg
} else if oldDoc == nil && newDoc != nil {
changed = true
warnChar := "🟣"
msg += fmt.Sprintf("检测到应用新增:\n应用ID:【%s】\n名称:【%s】\n", newDoc.Id.Hex(), newDoc.Name)
msg += fmt.Sprintf("下载链接:【%v】\n", newDoc.DownloadUrl)
msg += fmt.Sprintf("安卓链接:【%v】\n", newDoc.AndroidUrl)
msg += fmt.Sprintf("IOS链接:【%v】\n", newDoc.IosUrl)
msg += fmt.Sprintf("激活状态:\n┏【%v】【%s】\n", newDoc.Status, consts.StatusDesc[newDoc.Status])
msg = warnChar + msg
} else if oldDoc != nil && newDoc == nil {
changed = true
warnChar := "🟠"
msg += fmt.Sprintf("检测到应用删除:\n应用ID:【%s】\n名称:【%s】\n", oldDoc.Id.Hex(), oldDoc.Name)
msg += fmt.Sprintf("下载链接:【%v】\n", oldDoc.DownloadUrl)
msg += fmt.Sprintf("安卓链接:【%v】\n", oldDoc.AndroidUrl)
msg += fmt.Sprintf("IOS链接:【%v】\n", oldDoc.IosUrl)
msg = warnChar + msg
}
if changed {
if newDoc != nil {
dict := applicationLocMod.FindApplicationLocationDict(ctx, newDoc.ParentAppId)
msg += fmt.Sprintf("所属APP:【%s】\n", statg.GlobalEndpoints.GetAppShortNameById(int32(newDoc.ParentAppId)))
nowLocations := ""
for _, id := range newDoc.LocIds {
nowLocations += fmt.Sprintf("%s,", dict[id].Name)
}
msg += fmt.Sprintf("应用位置:【%s】\n", nowLocations)
msg += fmt.Sprintf("激活状态:【%s】\n", consts.StatusDesc[newDoc.Status])
}
msg += fmt.Sprintf("操作人员账号:【%s】\n", account)
msg += fmt.Sprintf("操作发生时间:【%s】\n", time.Now().Format("2006-01-02T15:04:05"))
msg += fmt.Sprintf("请确认是否异常: %s \n", statg.Tgbotsend)
statg.Bot.SendAdvertiseMessage(msg)
}
}