You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
4.3 KiB

5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
5 months ago
  1. package utility
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "github.com/gogf/gf/v2/frame/g"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. "io/ioutil"
  9. "link_homework/internal/consts"
  10. "link_homework/internal/model/dto"
  11. "net/http"
  12. "strconv"
  13. "strings"
  14. )
  15. // 获取 URL
  16. func getUrl(key, hashKey string) *dto.Result {
  17. ctx := gctx.New()
  18. // 1. 从 Redis 获取 URL
  19. redisUrl, err := g.Redis().Do(ctx, "HGET", key, hashKey)
  20. if err == nil && redisUrl.String() != "" {
  21. //g.Log().Infof(ctx, "从 Redis 获取到 URL: %s", redisUrl.String())
  22. return dto.SuccessWithData(redisUrl.String())
  23. }
  24. // 2. 如果 Redis 中没有,查询数据库
  25. urlResult := selectBaseUrl(hashKey)
  26. if urlResult.Code != 200 {
  27. return urlResult // 数据库查询失败,返回错误
  28. }
  29. url := urlResult.Data.(string)
  30. // 3. 将 URL 存入 Redis
  31. if _, err = g.Redis().Do(ctx, "HSET", key, hashKey, url); err != nil {
  32. //g.Log().Warningf(ctx, "将数据存入 Redis 失败: %v", err)
  33. }
  34. //g.Log().Infof(ctx, "将 URL 存入 Redis: %s", url)
  35. return dto.SuccessWithData(url)
  36. }
  37. // 查询数据库中的 URL
  38. func selectBaseUrl(hashKey string) *dto.Result {
  39. //ctx := gctx.New()
  40. // 查询数据库
  41. value, err := g.DB("cms").Model("env").Where("`key` = ?", hashKey).Value("value")
  42. if err != nil {
  43. //g.Log().Errorf(ctx, "数据库查询失败, 错误: %v, key: %s", err, hashKey)
  44. return dto.Error("数据库查询失败")
  45. }
  46. if value.IsNil() || value.String() == "" {
  47. //g.Log().Errorf(ctx, "未找到对应数据, key: %s", hashKey)
  48. return dto.Error("未找到对应数据")
  49. }
  50. return dto.SuccessWithData(value.String())
  51. }
  52. // 获取 jwcode
  53. // 获取 jwcode
  54. func GetJwcodeJSON(token string) (int, error) { // 返回类型为 int
  55. //ctx := gctx.New()
  56. // 1. 获取基础 URL
  57. urlResult := getUrl(consts.URL_KEY, consts.URL_HASH_KEY)
  58. if urlResult.Code != 200 {
  59. //g.Log().Errorf(ctx, "获取基础 URL 失败: %s", urlResult.Message)
  60. return 0, errors.New("获取基础 URL 失败: " + urlResult.Message)
  61. }
  62. baseUrl := urlResult.Data.(string)
  63. //g.Log().Debugf(ctx, "成功获取基础 URL: %s", baseUrl)
  64. // 2. 拼接完整的 URL
  65. url := baseUrl + "/api/v2/member/info"
  66. requestBody := strings.NewReader(`{"token":"` + token + `"}`)
  67. // 3. 创建 HTTP 请求
  68. req, err := http.NewRequest("POST", url, requestBody)
  69. if err != nil {
  70. //g.Log().Errorf(ctx, "HTTP 请求创建失败: %v", err)
  71. return 0, fmt.Errorf("HTTP 请求创建失败: %w", err)
  72. }
  73. req.Header.Set("Content-Type", "application/json")
  74. // 4. 发送请求
  75. client := &http.Client{}
  76. resp, err := client.Do(req)
  77. if err != nil {
  78. //g.Log().Errorf(ctx, "HTTP 请求失败: %v", err)
  79. return 0, fmt.Errorf("HTTP 请求失败: %w", err)
  80. }
  81. defer resp.Body.Close()
  82. // 5. 检查 HTTP 状态码
  83. if resp.StatusCode != http.StatusOK {
  84. //g.Log().Errorf(ctx, "HTTP 状态码错误: %d", resp.StatusCode)
  85. return 0, fmt.Errorf("HTTP 状态码错误: %d", resp.StatusCode)
  86. }
  87. // 6. 读取并解析响应体
  88. body, err := ioutil.ReadAll(resp.Body)
  89. if err != nil {
  90. //g.Log().Errorf(ctx, "读取响应失败: %v", err)
  91. return 0, fmt.Errorf("读取响应失败: %w", err)
  92. }
  93. //g.Log().Debugf(ctx, "响应体内容: %s", string(body))
  94. // 7. 解析 JSON 数据
  95. var jsonResponse map[string]interface{}
  96. if err = json.Unmarshal(body, &jsonResponse); err != nil {
  97. //g.Log().Errorf(ctx, "解析 JSON 失败: %v", err)
  98. return 0, fmt.Errorf("解析 JSON 失败: %w", err)
  99. }
  100. //g.Log().Debugf(ctx, "解析后的 JSON: %+v", jsonResponse)
  101. // 8. 提取 data 节点
  102. data, ok := jsonResponse["data"].(map[string]interface{})
  103. if !ok {
  104. //g.Log().Errorf(ctx, "响应体中没有 data 节点,完整响应: %+v", jsonResponse)
  105. return 0, errors.New("响应体中没有 data 节点")
  106. }
  107. // 9. 提取 jwcode 并转换为整数
  108. jwcode, ok := data["jwcode"].(string) // 首先尝试解析为字符串
  109. if ok {
  110. jwcodeInt, err := strconv.Atoi(jwcode) // 将字符串转换为整数
  111. if err != nil {
  112. //g.Log().Errorf(ctx, "解析 jwcode 字段失败: %v", err)
  113. return 0, fmt.Errorf("解析 jwcode 字段失败: %w", err)
  114. }
  115. //g.Log().Infof(ctx, "成功获取 jwcode: %d", jwcodeInt)
  116. return jwcodeInt, nil
  117. }
  118. // 如果 jwcode 不是字符串,记录错误日志
  119. //g.Log().Errorf(ctx, "data 节点中没有 jwcode 字段,或字段格式不正确,data: %+v", data)
  120. return 0, errors.New("响应体中没有有效的 jwcode 字段")
  121. }