package service import ( "fmt" "github.com/gofiber/fiber/v2" "os" "path/filepath" "xorm.io/builder" "geo/internal/biz" "geo/internal/config" "geo/internal/data/impl" "geo/internal/data/model" "geo/internal/entitys" "geo/internal/manager" "geo/pkg" "geo/tmpl/errcode" ) type AppService struct { cfg *config.Config tokenImpl *impl.TokenImpl userImpl *impl.UserImpl platImpl *impl.PlatImpl loginRelationImpl *impl.LoginRelationImpl publishBiz *biz.PublishBiz authBiz *biz.AuthBiz productBiz *biz.ProductBiz } func NewAppService( cfg *config.Config, tokenImpl *impl.TokenImpl, userImpl *impl.UserImpl, platImpl *impl.PlatImpl, publishBiz *biz.PublishBiz, authBiz *biz.AuthBiz, loginRelationImpl *impl.LoginRelationImpl, productBiz *biz.ProductBiz, ) *AppService { return &AppService{ cfg: cfg, tokenImpl: tokenImpl, loginRelationImpl: loginRelationImpl, userImpl: userImpl, platImpl: platImpl, publishBiz: publishBiz, authBiz: authBiz, productBiz: productBiz, } } func (a *AppService) LoginApp(c *fiber.Ctx, req *entitys.LoginAppRequest) error { cond := builder.NewCond(). And(builder.Eq{"secret": req.Secret}). And(builder.Eq{"status": 1}) tokenInfo := &model.Token{} err := a.tokenImpl.GetOneBySearchStruct(c.UserContext(), &cond, tokenInfo) if err != nil || tokenInfo == nil { return errcode.Forbidden("密钥无效") } accessToken := pkg.GenerateUUID() err = a.tokenImpl.UpdateByKey(c.UserContext(), a.tokenImpl.PrimaryKey(), tokenInfo.ID, &model.Token{ AccessToken: accessToken, }) if err != nil { return err } a.publishBiz.Notify(&entitys.NotifyData{ TokenId: int(tokenInfo.ID), NotifyUrl: tokenInfo.Notifyurl, Type: entitys.NotifyTypeToken, Status: 1, Msg: accessToken, }) return pkg.HandleResponse(c, fiber.Map{ "access_token": accessToken, "user_limit": tokenInfo.UserLimit, "expire_time": tokenInfo.ExpireTime, "user_name": tokenInfo.Name, }) } func (a *AppService) GetUserAndAutoStatus(c *fiber.Ctx, req *entitys.GetUserAndAutoStatusRequest) error { tokenInfo, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } cond := builder.NewCond(). And(builder.Eq{"token_id": tokenInfo.ID}). And(builder.Eq{"status": 1}) users := make([]model.User, 0) _, err = a.userImpl.GetListToStruct(c.UserContext(), &cond, nil, &users, "id desc") if err != nil { return err } pm, err := manager.GetPublishManager(a.cfg, a.tokenImpl.GetDb(), a.publishBiz) if err != nil { return err } return pkg.HandleResponse(c, fiber.Map{ "user": users, "auto_status": pm.AutoStatus, }) } func (a *AppService) AddUser(c *fiber.Ctx, req *entitys.AddUserRequest) error { tokenInfo, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } cond := builder.NewCond(). And(builder.Eq{"token_id": tokenInfo.ID}). And(builder.Eq{"status": 1}) userCount, err := a.userImpl.CountByCond(c.UserContext(), &cond) if err != nil { return err } if userCount >= int64(tokenInfo.UserLimit) { return errcode.ParamErr(fmt.Sprintf("用户已达上限(%d)", tokenInfo.UserLimit)) } userIndex := pkg.GenerateUserIndex() err = a.userImpl.Add(c.UserContext(), &model.User{ TokenID: tokenInfo.ID, UserIndex: userIndex, Name: req.Name, Status: 1, }) if err != nil { return errcode.SqlErr(err) } // 获取平台列表并关联 platCond := builder.NewCond().And(builder.Eq{"status": 1}) plats := make([]model.Plat, 0) _, err = a.platImpl.GetListToStruct(c.UserContext(), &platCond, nil, &plats, "id desc") if err != nil { return err } loginRelations := make([]model.LoginRelation, 0, len(plats)) for _, plat := range plats { loginRelations = append(loginRelations, model.LoginRelation{ UserIndex: userIndex, PlatIndex: plat.Index, LoginStatus: 2, Status: 1, }) } err = a.loginRelationImpl.Add(c.UserContext(), loginRelations) if err != nil { return err } return pkg.HandleResponse(c, fiber.Map{ "user_name": req.Name, "user_index": userIndex, }) } func (a *AppService) DelUser(c *fiber.Ctx, req *entitys.DelUserRequest) error { // 需要从请求中获取 access_token _, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } // 这里简化处理 err = a.userImpl.DeleteByKey(c.UserContext(), "user_index", req.UserIndex) if err != nil { return err } return pkg.HandleResponse(c, fiber.Map{}) } func (a *AppService) GetApp(c *fiber.Ctx, req *entitys.GetAppRequest) error { _, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } cond := builder.NewCond(). And(builder.Eq{"login_relation.user_index": req.UserIndex}). And(builder.Eq{"plat.status": 1}) result, err := a.platImpl.GetPlatListWithLoginStatus(c.UserContext(), &cond) if err != nil { return err } return pkg.HandleResponse(c, result) } func (a *AppService) SendCookie(c *fiber.Ctx, req *entitys.SendCookieRequest) error { _, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } dir := filepath.Join(a.cfg.Sys.CookiesDir, req.UserIndex) cookieFile := filepath.Join(dir, req.PlatIndex+".json") os.WriteFile(cookieFile, []byte(req.CookieData), 0644) _, _ = a.productBiz.OssUpload(c.UserContext(), req.UserIndex, req.PlatIndex, []byte(req.CookieData)) // 更新登录状态为未登录 err = a.publishBiz.UpdateLoginStatus(c.UserContext(), req.UserIndex, req.PlatIndex, 1) if err != nil { return err } return nil } func (a *AppService) PlatList(c *fiber.Ctx, req *entitys.PlatListRequest) error { _, err := a.authBiz.ValidateAccessToken(c.UserContext(), req.AccessToken) if err != nil { return err } cond := builder.NewCond(). And(builder.Eq{"status": 1}) if req.PlatType != 0 { cond.And(builder.Eq{"plat_type": req.PlatType}) } list, err := a.platImpl.GetRange(c.UserContext(), &cond) if err != nil { return err } return pkg.HandleResponse(c, list) }