package service import ( "context" "encoding/json" "fmt" v1 "github.com/go-nunu/nunu-layout-advanced/api/v1" "github.com/go-nunu/nunu-layout-advanced/internal/repository" "github.com/spf13/viper" ) type CdnService interface { GetToken(ctx context.Context) (string, error) AddUser(ctx context.Context, req v1.User) (int64, error) CreateGroup(ctx context.Context, req v1.Group) (int64, error) BindPlan(ctx context.Context, req v1.Plan) (int64, error) RenewPlan(ctx context.Context, req v1.RenewalPlan) error CreateWebsite(ctx context.Context, req v1.Website) (int64, error) EditProtocol(ctx context.Context, req v1.ProxyJson,action string) error CreateOrigin(ctx context.Context, req v1.Origin) (int64, error) EditOrigin(ctx context.Context, req v1.Origin) error } func NewCdnService( service *Service, conf *viper.Viper, request RequestService, cdnRepository repository.CdnRepository, ) CdnService { return &cdnService{ Service: service, Url: conf.GetString("flexCdn.Url"), AccessKeyID: conf.GetString("flexCdn.AccessKeyID"), AccessKeySecret: conf.GetString("flexCdn.AccessKeySecret"), request: request, cdnRepository: cdnRepository, } } type cdnService struct { *Service Url string AccessKeyID string AccessKeySecret string request RequestService cdnRepository repository.CdnRepository } func (s *cdnService) SendData(ctx context.Context, formData map[string]interface{}, apiUrl string,) ([]byte, error) { token, err := s.Toekn(ctx) if err != nil { return nil, err } resBody, err := s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", token) if err != nil { return nil, err } return resBody, nil } func (s *cdnService) GetToken(ctx context.Context) (string, error) { formData := map[string]interface{}{ "type": "admin", "accessKeyId": s.AccessKeyID, "accessKey": s.AccessKeySecret, } apiUrl := s.Url + "APIAccessTokenService/getAPIAccessToken" resBody, err := s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", "") if err != nil { return "", err } var res v1.GeneralResponse[v1.FlexCdnTokenResponse] if err := json.Unmarshal(resBody, &res); err != nil { return "", fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return "", fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } err = s.cdnRepository.PutToken(ctx, res.Data.Token) if err != nil { return "", err } return res.Data.Token, nil } func (s *cdnService) Toekn(ctx context.Context) (string, error) { token, err := s.cdnRepository.GetToken(ctx) if err != nil { return "", err } if token == "" { token, err = s.GetToken(ctx) if err != nil { return "", err } } return token, nil } //注册用户 func (s *cdnService) AddUser(ctx context.Context, req v1.User) (int64, error) { formData := map[string]interface{}{ "id": req.ID, "username": req.Username, "password": "a7fKiKujgAzzsJ6", "fullname": req.Fullname, "mobile": req.Mobile, "tel": req.Tel, "email": req.Email, "remark": req.Remark, "source": req.Source, "nodeClusterId": 1, } apiUrl := s.Url + "UserService/createUser" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return 0, err } type DataStr struct { UserId int64 `json:"userId" form:"userId"` } var res v1.GeneralResponse[DataStr] if err := json.Unmarshal(resBody, &res); err != nil { return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } if res.Data.UserId == 0 { return 0, fmt.Errorf("添加用户失败") } return res.Data.UserId, nil } //创建规则分组 func (s *cdnService) CreateGroup(ctx context.Context, req v1.Group) (int64, error) { formData := map[string]interface{}{ "name": req.Name, } apiUrl := s.Url + "ServerGroupService/createServerGroup" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return 0, err } type DataStr struct { ServerGroupId int64 `json:"serverGroupId" form:"serverGroupId"` } var res v1.GeneralResponse[DataStr] if err := json.Unmarshal(resBody, &res); err != nil { return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } if res.Data.ServerGroupId == 0 { return 0, fmt.Errorf("创建规则分组失败") } return res.Data.ServerGroupId, nil } //分配套餐 func (s *cdnService) BindPlan(ctx context.Context, req v1.Plan) (int64, error) { formData := map[string]interface{}{ "userId": req.UserId, "planId": req.PlanId, "dayTo": req.DayTo, "period": req.Period, "countPeriod": req.CountPeriod, "name": req.Name, "isFree": req.IsFree, "periodDayTo": req.PeriodDayTo, } apiUrl := s.Url + "UserPlanService/buyUserPlan" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return 0, err } type DataStr struct { UserPlanId int64 `json:"userPlanId" form:"userPlanId"` } var res v1.GeneralResponse[DataStr] if err := json.Unmarshal(resBody, &res); err != nil { return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } if res.Data.UserPlanId == 0 { return 0, fmt.Errorf("分配套餐失败") } return res.Data.UserPlanId, nil } //续费套餐 func (s *cdnService) RenewPlan(ctx context.Context, req v1.RenewalPlan) error { formData := map[string]interface{}{ "userPlanId": req.UserPlanId, "dayTo": req.DayTo, "period": req.Period, "countPeriod": req.CountPeriod, "isFree": req.IsFree, "periodDayTo": req.PeriodDayTo, } apiUrl := s.Url + "UserPlanService/renewUserPlan" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return err } var res v1.GeneralResponse[any] if err := json.Unmarshal(resBody, &res); err != nil { return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } return nil } //创建网站 func (s *cdnService) CreateWebsite(ctx context.Context, req v1.Website) (int64, error) { formData := map[string]interface{}{ "userId": req.UserId, "type": req.Type, "name": req.Name, "description": req.Description, "serverNamesJSON": req.ServerNamesJSON, "httpJSON": req.HttpJSON, "httpsJSON": req.HttpsJSON, "tcpJSON": req.TcpJSON, "tlsJSON": req.TlsJSON, "udpJSON": req.UdpJSON, "webId": req.WebId, "reverseProxyJSON": req.ReverseProxyJSON, "serverGroupIds": req.ServerGroupIds, "userPlanId": req.UserPlanId, "nodeClusterId": req.NodeClusterId, } apiUrl := s.Url + "ServerService/createServer" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return 0, err } type DataStr struct { WebsiteId int64 `json:"websiteId" form:"websiteId"` } var res v1.GeneralResponse[DataStr] if err := json.Unmarshal(resBody, &res); err != nil { return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } if res.Data.WebsiteId == 0 { return 0, fmt.Errorf("创建网站失败") } return res.Data.WebsiteId, nil } func (s *cdnService) EditProtocol(ctx context.Context, req v1.ProxyJson,action string) error { formData := map[string]interface{}{ "serverId": req.ServerId, } var apiUrl string switch action { case "tcp": formData["tcpJSON"] = req.JSON apiUrl = s.Url + "ServerService/updateServerTCP" case "tls": formData["tlsJSON"] = req.JSON apiUrl = s.Url + "ServerService/updateServerTLS" case "udp": formData["udpJSON"] = req.JSON apiUrl = s.Url + "ServerService/updateServerUDP" case "http": formData["httpJSON"] = req.JSON apiUrl = s.Url + "ServerService/updateServerHTTP" case "https": formData["httpsJSON"] = req.JSON apiUrl = s.Url + "ServerService/updateServerHTTPS" default: return fmt.Errorf("不支持的协议类型") } resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return err } var res v1.GeneralResponse[any] if err := json.Unmarshal(resBody, &res); err != nil { return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } return nil } func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, error) { formData := map[string]interface{}{ "name": req.Name, "addr": req.Addr, "ossJSON": req.OssJSON, "description": req.Description, "weight": req.Weight, "isOn": req.IsOn, "domains": req.Domains, "certRefJSON": req.CertRefJSON, "host": req.Host, "followPort": req.FollowPort, "http2Enabled": req.Http2Enabled, "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode, } apiUrl := s.Url + "OriginService/createOrigin" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return 0, err } type DataStr struct { OriginId int64 `json:"originId" form:"originId"` } var res v1.GeneralResponse[DataStr] if err := json.Unmarshal(resBody, &res); err != nil { return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } if res.Data.OriginId == 0 { return 0, fmt.Errorf("创建源站失败") } return res.Data.OriginId, nil } func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error { formData := map[string]interface{}{ "originId": req.OriginId, "name": req.Name, "addr": req.Addr, "ossJSON": req.OssJSON, "description": req.Description, "weight": req.Weight, "isOn": req.IsOn, "domains": req.Domains, "certRefJSON": req.CertRefJSON, "host": req.Host, "followPort": req.FollowPort, "http2Enabled": req.Http2Enabled, "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode, } apiUrl := s.Url + "OriginService/updateOrigin" resBody, err := s.SendData(ctx, formData, apiUrl) if err != nil { return err } var res v1.GeneralResponse[any] if err := json.Unmarshal(resBody, &res); err != nil { return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err) } if res.Code != 200 { return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message) } return nil }