cdn.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367
  1. package service
  2. import (
  3. "context"
  4. "encoding/json"
  5. "fmt"
  6. v1 "github.com/go-nunu/nunu-layout-advanced/api/v1"
  7. "github.com/go-nunu/nunu-layout-advanced/internal/repository"
  8. "github.com/spf13/viper"
  9. )
  10. type CdnService interface {
  11. GetToken(ctx context.Context) (string, error)
  12. AddUser(ctx context.Context, req v1.User) (int64, error)
  13. CreateGroup(ctx context.Context, req v1.Group) (int64, error)
  14. BindPlan(ctx context.Context, req v1.Plan) (int64, error)
  15. RenewPlan(ctx context.Context, req v1.RenewalPlan) error
  16. CreateWebsite(ctx context.Context, req v1.Website) (int64, error)
  17. EditProtocol(ctx context.Context, req v1.ProxyJson,action string) error
  18. CreateOrigin(ctx context.Context, req v1.Origin) (int64, error)
  19. EditOrigin(ctx context.Context, req v1.Origin) error
  20. }
  21. func NewCdnService(
  22. service *Service,
  23. conf *viper.Viper,
  24. request RequestService,
  25. cdnRepository repository.CdnRepository,
  26. ) CdnService {
  27. return &cdnService{
  28. Service: service,
  29. Url: conf.GetString("flexCdn.Url"),
  30. AccessKeyID: conf.GetString("flexCdn.AccessKeyID"),
  31. AccessKeySecret: conf.GetString("flexCdn.AccessKeySecret"),
  32. request: request,
  33. cdnRepository: cdnRepository,
  34. }
  35. }
  36. type cdnService struct {
  37. *Service
  38. Url string
  39. AccessKeyID string
  40. AccessKeySecret string
  41. request RequestService
  42. cdnRepository repository.CdnRepository
  43. }
  44. func (s *cdnService) SendData(ctx context.Context, formData map[string]interface{}, apiUrl string,) ([]byte, error) {
  45. token, err := s.Toekn(ctx)
  46. if err != nil {
  47. return nil, err
  48. }
  49. resBody, err := s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", token)
  50. if err != nil {
  51. return nil, err
  52. }
  53. return resBody, nil
  54. }
  55. func (s *cdnService) GetToken(ctx context.Context) (string, error) {
  56. formData := map[string]interface{}{
  57. "type": "admin",
  58. "accessKeyId": s.AccessKeyID,
  59. "accessKey": s.AccessKeySecret,
  60. }
  61. apiUrl := s.Url + "APIAccessTokenService/getAPIAccessToken"
  62. resBody, err := s.request.Request(ctx, formData, apiUrl, "X-Cloud-Access-Token", "")
  63. if err != nil {
  64. return "", err
  65. }
  66. var res v1.GeneralResponse[v1.FlexCdnTokenResponse]
  67. if err := json.Unmarshal(resBody, &res); err != nil {
  68. return "", fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  69. }
  70. if res.Code != 200 {
  71. return "", fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  72. }
  73. err = s.cdnRepository.PutToken(ctx, res.Data.Token)
  74. if err != nil {
  75. return "", err
  76. }
  77. return res.Data.Token, nil
  78. }
  79. func (s *cdnService) Toekn(ctx context.Context) (string, error) {
  80. token, err := s.cdnRepository.GetToken(ctx)
  81. if err != nil {
  82. return "", err
  83. }
  84. if token == "" {
  85. token, err = s.GetToken(ctx)
  86. if err != nil {
  87. return "", err
  88. }
  89. }
  90. return token, nil
  91. }
  92. //注册用户
  93. func (s *cdnService) AddUser(ctx context.Context, req v1.User) (int64, error) {
  94. formData := map[string]interface{}{
  95. "id": req.ID,
  96. "username": req.Username,
  97. "password": "a7fKiKujgAzzsJ6",
  98. "fullname": req.Fullname,
  99. "mobile": req.Mobile,
  100. "tel": req.Tel,
  101. "email": req.Email,
  102. "remark": req.Remark,
  103. "source": req.Source,
  104. "nodeClusterId": 1,
  105. }
  106. apiUrl := s.Url + "UserService/createUser"
  107. resBody, err := s.SendData(ctx, formData, apiUrl)
  108. if err != nil {
  109. return 0, err
  110. }
  111. type DataStr struct {
  112. UserId int64 `json:"userId" form:"userId"`
  113. }
  114. var res v1.GeneralResponse[DataStr]
  115. if err := json.Unmarshal(resBody, &res); err != nil {
  116. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  117. }
  118. if res.Code != 200 {
  119. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  120. }
  121. if res.Data.UserId == 0 {
  122. return 0, fmt.Errorf("添加用户失败")
  123. }
  124. return res.Data.UserId, nil
  125. }
  126. //创建规则分组
  127. func (s *cdnService) CreateGroup(ctx context.Context, req v1.Group) (int64, error) {
  128. formData := map[string]interface{}{
  129. "name": req.Name,
  130. }
  131. apiUrl := s.Url + "ServerGroupService/createServerGroup"
  132. resBody, err := s.SendData(ctx, formData, apiUrl)
  133. if err != nil {
  134. return 0, err
  135. }
  136. type DataStr struct {
  137. ServerGroupId int64 `json:"serverGroupId" form:"serverGroupId"`
  138. }
  139. var res v1.GeneralResponse[DataStr]
  140. if err := json.Unmarshal(resBody, &res); err != nil {
  141. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  142. }
  143. if res.Code != 200 {
  144. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  145. }
  146. if res.Data.ServerGroupId == 0 {
  147. return 0, fmt.Errorf("创建规则分组失败")
  148. }
  149. return res.Data.ServerGroupId, nil
  150. }
  151. //分配套餐
  152. func (s *cdnService) BindPlan(ctx context.Context, req v1.Plan) (int64, error) {
  153. formData := map[string]interface{}{
  154. "userId": req.UserId,
  155. "planId": req.PlanId,
  156. "dayTo": req.DayTo,
  157. "period": req.Period,
  158. "countPeriod": req.CountPeriod,
  159. "name": req.Name,
  160. "isFree": req.IsFree,
  161. "periodDayTo": req.PeriodDayTo,
  162. }
  163. apiUrl := s.Url + "UserPlanService/buyUserPlan"
  164. resBody, err := s.SendData(ctx, formData, apiUrl)
  165. if err != nil {
  166. return 0, err
  167. }
  168. type DataStr struct {
  169. UserPlanId int64 `json:"userPlanId" form:"userPlanId"`
  170. }
  171. var res v1.GeneralResponse[DataStr]
  172. if err := json.Unmarshal(resBody, &res); err != nil {
  173. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  174. }
  175. if res.Code != 200 {
  176. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  177. }
  178. if res.Data.UserPlanId == 0 {
  179. return 0, fmt.Errorf("分配套餐失败")
  180. }
  181. return res.Data.UserPlanId, nil
  182. }
  183. //续费套餐
  184. func (s *cdnService) RenewPlan(ctx context.Context, req v1.RenewalPlan) error {
  185. formData := map[string]interface{}{
  186. "userPlanId": req.UserPlanId,
  187. "dayTo": req.DayTo,
  188. "period": req.Period,
  189. "countPeriod": req.CountPeriod,
  190. "isFree": req.IsFree,
  191. "periodDayTo": req.PeriodDayTo,
  192. }
  193. apiUrl := s.Url + "UserPlanService/renewUserPlan"
  194. resBody, err := s.SendData(ctx, formData, apiUrl)
  195. if err != nil {
  196. return err
  197. }
  198. var res v1.GeneralResponse[any]
  199. if err := json.Unmarshal(resBody, &res); err != nil {
  200. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  201. }
  202. if res.Code != 200 {
  203. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  204. }
  205. return nil
  206. }
  207. //创建网站
  208. func (s *cdnService) CreateWebsite(ctx context.Context, req v1.Website) (int64, error) {
  209. formData := map[string]interface{}{
  210. "userId": req.UserId,
  211. "type": req.Type,
  212. "name": req.Name,
  213. "description": req.Description,
  214. "serverNamesJSON": req.ServerNamesJSON,
  215. "httpJSON": req.HttpJSON,
  216. "httpsJSON": req.HttpsJSON,
  217. "tcpJSON": req.TcpJSON,
  218. "tlsJSON": req.TlsJSON,
  219. "udpJSON": req.UdpJSON,
  220. "webId": req.WebId,
  221. "reverseProxyJSON": req.ReverseProxyJSON,
  222. "serverGroupIds": req.ServerGroupIds,
  223. "userPlanId": req.UserPlanId,
  224. "nodeClusterId": req.NodeClusterId,
  225. }
  226. apiUrl := s.Url + "ServerService/createServer"
  227. resBody, err := s.SendData(ctx, formData, apiUrl)
  228. if err != nil {
  229. return 0, err
  230. }
  231. type DataStr struct {
  232. WebsiteId int64 `json:"websiteId" form:"websiteId"`
  233. }
  234. var res v1.GeneralResponse[DataStr]
  235. if err := json.Unmarshal(resBody, &res); err != nil {
  236. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  237. }
  238. if res.Code != 200 {
  239. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  240. }
  241. if res.Data.WebsiteId == 0 {
  242. return 0, fmt.Errorf("创建网站失败")
  243. }
  244. return res.Data.WebsiteId, nil
  245. }
  246. func (s *cdnService) EditProtocol(ctx context.Context, req v1.ProxyJson,action string) error {
  247. formData := map[string]interface{}{
  248. "serverId": req.ServerId,
  249. }
  250. var apiUrl string
  251. switch action {
  252. case "tcp":
  253. formData["tcpJSON"] = req.JSON
  254. apiUrl = s.Url + "ServerService/updateServerTCP"
  255. case "tls":
  256. formData["tlsJSON"] = req.JSON
  257. apiUrl = s.Url + "ServerService/updateServerTLS"
  258. case "udp":
  259. formData["udpJSON"] = req.JSON
  260. apiUrl = s.Url + "ServerService/updateServerUDP"
  261. case "http":
  262. formData["httpJSON"] = req.JSON
  263. apiUrl = s.Url + "ServerService/updateServerHTTP"
  264. case "https":
  265. formData["httpsJSON"] = req.JSON
  266. apiUrl = s.Url + "ServerService/updateServerHTTPS"
  267. default:
  268. return fmt.Errorf("不支持的协议类型")
  269. }
  270. resBody, err := s.SendData(ctx, formData, apiUrl)
  271. if err != nil {
  272. return err
  273. }
  274. var res v1.GeneralResponse[any]
  275. if err := json.Unmarshal(resBody, &res); err != nil {
  276. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  277. }
  278. if res.Code != 200 {
  279. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  280. }
  281. return nil
  282. }
  283. func (s *cdnService) CreateOrigin(ctx context.Context, req v1.Origin) (int64, error) {
  284. formData := map[string]interface{}{
  285. "name": req.Name,
  286. "addr": req.Addr,
  287. "ossJSON": req.OssJSON,
  288. "description": req.Description,
  289. "weight": req.Weight,
  290. "isOn": req.IsOn,
  291. "domains": req.Domains,
  292. "certRefJSON": req.CertRefJSON,
  293. "host": req.Host,
  294. "followPort": req.FollowPort,
  295. "http2Enabled": req.Http2Enabled,
  296. "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
  297. }
  298. apiUrl := s.Url + "OriginService/createOrigin"
  299. resBody, err := s.SendData(ctx, formData, apiUrl)
  300. if err != nil {
  301. return 0, err
  302. }
  303. type DataStr struct {
  304. OriginId int64 `json:"originId" form:"originId"`
  305. }
  306. var res v1.GeneralResponse[DataStr]
  307. if err := json.Unmarshal(resBody, &res); err != nil {
  308. return 0, fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  309. }
  310. if res.Code != 200 {
  311. return 0, fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  312. }
  313. if res.Data.OriginId == 0 {
  314. return 0, fmt.Errorf("创建源站失败")
  315. }
  316. return res.Data.OriginId, nil
  317. }
  318. func (s *cdnService) EditOrigin(ctx context.Context, req v1.Origin) error {
  319. formData := map[string]interface{}{
  320. "originId": req.OriginId,
  321. "name": req.Name,
  322. "addr": req.Addr,
  323. "ossJSON": req.OssJSON,
  324. "description": req.Description,
  325. "weight": req.Weight,
  326. "isOn": req.IsOn,
  327. "domains": req.Domains,
  328. "certRefJSON": req.CertRefJSON,
  329. "host": req.Host,
  330. "followPort": req.FollowPort,
  331. "http2Enabled": req.Http2Enabled,
  332. "tlsSecurityVerifyMode": req.TlsSecurityVerifyMode,
  333. }
  334. apiUrl := s.Url + "OriginService/updateOrigin"
  335. resBody, err := s.SendData(ctx, formData, apiUrl)
  336. if err != nil {
  337. return err
  338. }
  339. var res v1.GeneralResponse[any]
  340. if err := json.Unmarshal(resBody, &res); err != nil {
  341. return fmt.Errorf("反序列化响应 JSON 失败 (内容: %s): %w", string(resBody), err)
  342. }
  343. if res.Code != 200 {
  344. return fmt.Errorf("API 错误: code %d, msg '%s'", res.Code, res.Message)
  345. }
  346. return nil
  347. }