package svc import ( "context" "encoding/json" "errors" "gitea.youtukeji.com.cn/xiabin/youtu_server/game_open_api/internal/config" "gitea.youtukeji.com.cn/xiabin/youtu_server/game_open_api/model" helper "gitea.youtukeji.com.cn/youtu/openapi-helper" "github.com/golang-jwt/jwt/v4" redisCache "github.com/silenceper/wechat/v2/cache" "github.com/zeromicro/go-zero/core/stores/sqlx" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" "math/rand" "time" ) type ServiceContext struct { Config config.Config AppUser model.AppUserModel GameScore model.GameScoreModel AppAccount model.AppAccountModel DouyinCli *helper.DouYinOpenApiClient WechatCli *helper.WechatApi ZapLogger *zap.Logger } func NewServiceContext(c config.Config) *ServiceContext { svc := &ServiceContext{ Config: c, AppUser: model.NewAppUserModel(sqlx.NewMysql(c.DB.DataSource), c.Cache), GameScore: model.NewGameScoreModel(sqlx.NewMysql(c.DB.DataSource), c.Cache), AppAccount: model.NewAppAccountModel(sqlx.NewMysql(c.DB.DataSource), c.Cache), } dwCache := redisCache.NewRedis(context.Background(), &redisCache.RedisOpts{Host: c.DWCache.Host, IdleTimeout: c.DWCache.IdleTimeout}) svc.DouyinCli = helper.NewDouYinOpenApiClient() svc.WechatCli = helper.NewWechatOpenApiClient() result, err := svc.AppAccount.FindAll(context.Background()) if err != nil { panic(err) } for _, v := range *result { if v.Type == 0 { svc.DouyinCli.NewAndStoreDouYinOpenApi(v.AppID, v.Secret, v.EcpmValue.V, v.EcpmView.V, dwCache) } else { svc.WechatCli.NewAndStoreWechatOpenApi(v.AppID, v.Secret, dwCache) } } //初始化一个zap日志对象用于写入ecpm日志 svc.ZapLogger = zap.New(zapcore.NewCore( zapcore.NewJSONEncoder(zapcore.EncoderConfig{ TimeKey: "ts", LevelKey: "level", NameKey: "logger", CallerKey: "caller", FunctionKey: zapcore.OmitKey, MessageKey: "msg", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeTime: zapcore.EpochTimeEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }), zapcore.NewMultiWriteSyncer(zapcore.AddSync(&lumberjack.Logger{ Filename: c.EcpmLogPath, // Log file path 日志文件的路径 MaxSize: 1024, // Maximum size unit for each log file: M 每个日志最大大小 MaxBackups: 30, // The maximum number of backups that can be saved for log files 可以保存的日志文件数量 MaxAge: 7, // Maximum number of days the file can be saved 日志文件保存的最大天数 Compress: true, // Compression or not 是否对日志文件进行压缩 })), zapcore.InfoLevel, )) return svc } type AccessToken struct { AppId uint64 `json:"appId"` UserId uint64 `json:"userId"` AppIdStr string `json:"appIdStr"` OpenId string `json:"openId"` } func UnmarshalAccessToken(d any) (ac AccessToken, err error) { m, ok := d.(map[string]interface{}) if !ok { err = errors.New("invalid access token") return } appId, _ := m["appId"].(json.Number).Int64() ac.AppId = uint64(appId) userId, _ := m["userId"].(json.Number).Int64() ac.UserId = uint64(userId) ac.AppIdStr = m["appIdStr"].(string) ac.OpenId = m["openId"].(string) return } func GetCtxToken(ctx context.Context) (ac AccessToken, err error) { return UnmarshalAccessToken(ctx.Value("payload")) } // GenerateAccessToken 生成 JWT 认证的 token // 会从ServiceContext中获取配置信息 func (svc *ServiceContext) GenerateAccessToken(at *AccessToken) (token string, err error) { claims := make(jwt.MapClaims) claims["exp"] = time.Now().Unix() + svc.Config.Auth.AccessExpire claims["iat"] = svc.Config.Auth.AccessExpire claims["payload"] = at t := jwt.New(jwt.SigningMethodHS256) t.Claims = claims token, err = t.SignedString([]byte(svc.Config.Auth.AccessSecret)) return } var DefaultUsername = []string{ "甜蜜糖果", "糖果爱好者", "软糖粉丝", "巧克力糖果控", "棒棒糖迷", "小熊软糖达人", "硬糖狂人", "焦糖糖果控", "水果糖行家", "棉花糖达人", } // GetRandomUsername 随机获取一个糖果相关的用户名 func GetRandomUsername() string { // 初始化随机数种子 r := rand.New(rand.NewSource(time.Now().UnixNano())) // 生成一个 0 到列表长度减 1 之间的随机索引 randomIndex := r.Intn(len(DefaultUsername)) // 根据随机索引返回对应的用户名 return DefaultUsername[randomIndex] }