package service import ( "context" "fmt" v1 "github.com/go-nunu/nunu-layout-advanced/api/v1" "github.com/go-nunu/nunu-layout-advanced/internal/model" "github.com/go-nunu/nunu-layout-advanced/internal/repository" "github.com/spf13/viper" "strconv" "time" ) type GameShieldService interface { SubmitGameShield(ctx context.Context, req *v1.GameShieldSubmitRequest) (string, error) EditGameShield(ctx context.Context, req *v1.GameShieldSubmitRequest) (string, error) DeleteGameShield(ctx context.Context, req int) (string, error) GetGameShieldKey(ctx context.Context, id int) (string, error) } func NewGameShieldService( service *Service, gameShieldRepository repository.GameShieldRepository, crawlerService CrawlerService, gameShieldPublicIpService GameShieldPublicIpService, duedate DuedateService, formatter FormatterService, parser ParserService, required RequiredService, conf *viper.Viper, ) GameShieldService { return &gameShieldService{ Service: service, gameShieldRepository: gameShieldRepository, crawlerService: crawlerService, gameShieldPublicIpService: gameShieldPublicIpService, duedate: duedate, formatter: formatter, parser: parser, required: required, Url: conf.GetString("crawler.Url"), } } type gameShieldService struct { *Service config *viper.Viper crawlerService CrawlerService gameShieldRepository repository.GameShieldRepository gameShieldPublicIpService GameShieldPublicIpService duedate DuedateService formatter FormatterService Url string parser ParserService required RequiredService } func (service *gameShieldService) GetGameShieldrequired(ctx context.Context, req *v1.GameShieldSubmitRequest) (*v1.GetGameShieldRequiredResponse, error) { var res v1.GetGameShieldRequiredResponse var err error if req.Uid == 0 { return nil, fmt.Errorf("uid is required") } res.ExpiredAt, err = service.duedate.NextDueDate(ctx, req.Uid, req.HostId) if err != nil { return nil, err } nameCount, err := service.gameShieldRepository.GetGameShieldDuplicateName(ctx, req.AppName) if err != nil { return nil, err } if nameCount > 0 { return nil, fmt.Errorf("应用名称已存在") } res.Backend, err = service.formatter.FormatBackendData(ctx, req) if err != nil { return nil, err } res.Cookie, err = service.crawlerService.GetLoginCookie(ctx) if err != nil { return nil, err } return &res, nil } func (service *gameShieldService) SubmitGameShield(ctx context.Context, req *v1.GameShieldSubmitRequest) (string, error) { require, err := service.GetGameShieldrequired(ctx, req) if err != nil { return "", err } dunName := strconv.Itoa(req.Uid) + "_" + strconv.FormatInt(time.Now().Unix(), 10) + "_" + req.AppName formData := map[string]interface{}{ "app_name": dunName, "gateway_group_id": 4, "backend": require.Backend, "expired_at": require.ExpiredAt, "max_device_count": 0, } respBody, err := service.required.SendForm(ctx, "admin/info/rule/new", "admin/new/rule", formData) if err != nil { return "", err } // 解析响应内容中的 alert 消息 res, err := service.parser.ParseAlert(string(respBody)) if err != nil { return "", err } if res != "" { return "", fmt.Errorf(res) } KeyAndField, err := service.required.GetKeyAndField(ctx, dunName, "rule_id") if err != nil { return "", err } if err := service.gameShieldRepository.AddGameShield(ctx, &model.GameShield{ AppName: req.AppName, GatewayGroupId: 4, Backend: require.Backend, RuleId: KeyAndField.FieldId, Key: KeyAndField.Key, AddTime: time.Now(), Uid: req.Uid, HostId: req.HostId, AppIp: req.AppIp, Checked: req.Checked, DunName: dunName, }); err != nil { return "", err } return res, nil } func (service *gameShieldService) EditGameShield(ctx context.Context, req *v1.GameShieldSubmitRequest) (string, error) { require, err := service.GetGameShieldrequired(ctx, req) if err != nil { return "", err } tokenUrl := service.Url + "admin/info/rule/edit?&__goadmin_edit_pk=" + strconv.Itoa(req.RuleId) + "_" + req.AppName tokens, err := service.crawlerService.GetFormTokens(ctx, tokenUrl, require.Cookie) if err != nil { return "", err } sendUrl := service.Url + "admin/edit/rule" dunName := strconv.Itoa(req.Uid) + "_" + strconv.FormatInt(time.Now().Unix(), 10) formData := map[string]interface{}{ "app_name": dunName, "gateway_group_id": 4, "backend": require.Backend, "rule_id": req.RuleId, "expired_at": require.ExpiredAt, "max_device_count": 0, "__go_admin_previous_": tokens["previous"], "__go_admin_t_": tokens["t"], } respBody, err := service.crawlerService.SendFormData(ctx, sendUrl, require.Cookie, formData) if err != nil { return "", err } // 解析响应内容中的 alert 消息 res, err := service.parser.ParseAlert(string(respBody)) if err != nil { return "", err } if res != "" { return "", fmt.Errorf(res) } KeyAndField, err := service.required.GetKeyAndField(ctx, dunName, "rule_id") if err != nil { return "", err } if err := service.gameShieldRepository.UpdateGameShield(ctx, &model.GameShield{ AppName: req.AppName, GatewayGroupId: 4, Backend: require.Backend, RuleId: KeyAndField.FieldId, Key: KeyAndField.Key, Uid: req.Uid, HostId: req.HostId, AppIp: req.AppIp, Checked: req.Checked, DunName: dunName, }); err != nil { return "", err } return res, nil } func (service *gameShieldService) DeleteGameShield(ctx context.Context, id int) (string, error) { shieldInfo, err := service.gameShieldRepository.GetGameShieldById(ctx, int64(id)) if err != nil { return "", err } if err := service.gameShieldRepository.DeleteGameShield(ctx, shieldInfo.RuleId); err != nil { return "", err } res, err := service.crawlerService.DeleteRule(ctx, shieldInfo.RuleId, "admin/delete/rule?page=1&__pageSize=10&__sort=rule_id&__sort_type=desc") if err != nil { return "", err } return res, nil } func (service *gameShieldService) GetGameShieldKey(ctx context.Context, id int) (string, error) { dunName, err := service.gameShieldRepository.GetGameShieldIdByAppName(ctx, int64(id)) if err != nil { return "", err } if dunName == "" { return "", fmt.Errorf("没有该条数据") } res, err := service.crawlerService.GetKey(ctx, dunName) if err != nil { return "", err } return res, nil }