cdn.go 10 KB

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