diff --git a/sever/test/server2.go b/sever/test/server2.go index 2328b98a..1d35a404 100644 --- a/sever/test/server2.go +++ b/sever/test/server2.go @@ -1,9 +1,6 @@ package main import ( - "crypto/aes" - "crypto/cipher" - "encoding/base64" "encoding/json" "fmt" "io/ioutil" @@ -14,6 +11,7 @@ import ( openApiSdkClient "github.com/bytedance/douyin-openapi-sdk-go/client" ) +// 定义抖音 API 响应的结构体 type APIResponse struct { BaseResp struct { StatusCode int `json:"StatusCode"` @@ -58,79 +56,12 @@ func GetAccessToken() (string, error) { // 调用 SDK 获取 access_token sdkResponse, err := sdkClient.AppsV2Token(sdkRequest) if err != nil { - fmt.Println("sdk call err:", err) - return "", nil + return "", fmt.Errorf("SDK 调用失败: %v", err) } - fmt.Println("sdk数据", sdkResponse.Data) // 返回 access_token return *sdkResponse.Data.AccessToken, nil } -func DecryptAES128CBC(encryptedData, sessionKey, iv string) ([]byte, error) { - // Base64 解码 key 和 iv - aesKey, err := base64.StdEncoding.DecodeString(sessionKey) - if err != nil { - return nil, fmt.Errorf("sessionKey Base64 解码失败: %v", err) - } - - initialVector, err := base64.StdEncoding.DecodeString(iv) - if err != nil { - return nil, fmt.Errorf("iv Base64 解码失败: %v", err) - } - - // 检查 key 和 iv 长度是否为 16 字节 - if len(aesKey) != 16 { - return nil, fmt.Errorf("AES key 长度必须为 16 字节") - } - if len(initialVector) != 16 { - return nil, fmt.Errorf("IV 长度必须为 16 字节") - } - - // Base64 解码密文 - ciphertext, err := base64.StdEncoding.DecodeString(encryptedData) - if err != nil { - return nil, fmt.Errorf("encryptedData Base64 解码失败: %v", err) - } - - // 创建 AES 块 - block, err := aes.NewCipher(aesKey) - if err != nil { - return nil, fmt.Errorf("创建 AES Cipher 失败: %v", err) - } - - // 检查密文长度是否为块大小的倍数 - if len(ciphertext)%aes.BlockSize != 0 { - return nil, fmt.Errorf("密文长度必须是 AES 块大小的倍数") - } - - // 创建 CBC 解密器 - mode := cipher.NewCBCDecrypter(block, initialVector) - - // 解密数据 - decrypted := make([]byte, len(ciphertext)) - mode.CryptBlocks(decrypted, ciphertext) - - // 去除 PKCS#7 填充 - decrypted, err = PKCS7Unpad(decrypted) - if err != nil { - return nil, fmt.Errorf("去除 PKCS#7 填充失败: %v", err) - } - - return decrypted, nil -} - -// PKCS#7 填充去除函数 -func PKCS7Unpad(data []byte) ([]byte, error) { - length := len(data) - if length == 0 { - return nil, fmt.Errorf("解密后数据长度为 0") - } - padding := int(data[length-1]) - if padding > length || padding == 0 { - return nil, fmt.Errorf("无效的填充数据") - } - return data[:length-padding], nil -} func main() { // 定义 HTTP 路由和处理函数 @@ -142,25 +73,27 @@ func main() { } // 从请求中获取参数 - openID := r.URL.Query().Get("open_id") // 获取 open_id - mpID := r.URL.Query().Get("mp_id") // 获取 mp_id - dateHour := r.URL.Query().Get("date_hour") // 获取 date_hour - pageNo := r.URL.Query().Get("pageNo") // 获取 date_hour - pageSize := r.URL.Query().Get("pageSize") // 获取 date_hour + openID := r.URL.Query().Get("open_id") // 获取 open_id 参数 + mpID := r.URL.Query().Get("mp_id") // 获取 mp_id 参数 + dateHour := r.URL.Query().Get("date_hour") // 获取 date_hour 参数 + pageNo := r.URL.Query().Get("pageNo") // 获取 pageNo 参数 + pageSize := r.URL.Query().Get("pageSize") // 获取 pageSize 参数 - // 检查是否有缺少参数 + // 检查是否缺少必要参数 if mpID == "" || dateHour == "" { - http.Error(w, "缺少必要的参数", http.StatusBadRequest) + http.Error(w, "缺少必要的参数 mp_id 或 date_hour", http.StatusBadRequest) return } - // 动态获取 access_token + + // 获取动态的 access_token accessToken, err := GetAccessToken() - apiURL := "https://minigame.zijieapi.com/mgplatform/api/apps/data/get_ecpm" if err != nil { http.Error(w, fmt.Sprintf("获取 access_token 失败: %v", err), http.StatusInternalServerError) return } - fmt.Println("动态token为", accessToken) + + // 构造抖音 API 请求的 URL + apiURL := "https://minigame.zijieapi.com/mgplatform/api/apps/data/get_ecpm" params := url.Values{} params.Add("open_id", openID) params.Add("mp_id", mpID) @@ -168,22 +101,10 @@ func main() { params.Add("access_token", accessToken) params.Add("page_no", pageNo) params.Add("page_size", pageSize) - // 构造请求体 - // requestBody := map[string]string{ - // "open_id": openID, - // "mp_id": mpID, - // "date_hour": dateHour, - // "access_token": accessToken, - // "page_no": pageNo, - // "page_size": pageSize, - // } - fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode()) - // requestBodyJSON, err := json.Marshal(requestBody) // 转为 JSON 格式 - // if err != nil { - // http.Error(w, "请求体编码失败", http.StatusInternalServerError) - // return - // } + fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode()) + + // 调用抖音 API resp, err := http.Get(fullURL) if err != nil { http.Error(w, "调用抖音 API 失败", http.StatusInternalServerError) @@ -191,22 +112,28 @@ func main() { } defer resp.Body.Close() - // 读取抖音 API 的响应 + // 读取抖音 API 响应数据 responseBody, err := ioutil.ReadAll(resp.Body) if err != nil { http.Error(w, "读取抖音 API 响应失败", http.StatusInternalServerError) return } + + // 解析抖音 API 响应数据 var apiResponse APIResponse err = json.Unmarshal(responseBody, &apiResponse) if err != nil { - fmt.Printf("Error while parsing response JSON: %v\n", err) + http.Error(w, "解析 API 响应数据失败", http.StatusInternalServerError) return } + + // 检查 API 是否返回错误 if apiResponse.ErrNo != 0 { - fmt.Printf("API Error: %s (ErrNo: %d)\n", apiResponse.ErrMsg, apiResponse.ErrNo) + http.Error(w, fmt.Sprintf("抖音 API 返回错误: %s (错误码: %d)", apiResponse.ErrMsg, apiResponse.ErrNo), http.StatusInternalServerError) return } + + // 计算 ECPM totalCost := 0 totalRecords := len(apiResponse.Data.Records) @@ -214,75 +141,30 @@ func main() { totalCost += record.Cost } + // 如果没有记录,则返回错误 if totalRecords == 0 { - fmt.Println("No records found. Unable to calculate ECPM.") + http.Error(w, "未找到记录,无法计算 ECPM", http.StatusOK) return } ecpm := float64(totalCost) / 100000 * 1000 / float64(totalRecords) - fmt.Println("返回值为", responseBody) - // 根据key返回相应的值(这里可以替换为实际的业务逻辑) - value := fmt.Sprintf("Value for key '%s'", ecpm) - // 将抖音 API 的响应返回给客户端 - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(resp.StatusCode) - w.Write([]byte(value)) - }) - http.HandleFunc("/Login", func(w http.ResponseWriter, r *http.Request) { - // 检查请求方法是否为GET - if r.Method != http.MethodGet { - http.Error(w, "Invalid request method", http.StatusMethodNotAllowed) - return + + // 构造返回的 JSON 数据 + result := map[string]interface{}{ + "total_cost": float64(totalCost) / 100000, + "total_records": totalRecords, + "ecpm": ecpm, } - - // 从请求参数中获取"code"和"Anonymous" - code := r.URL.Query().Get("code") - Anonymous := r.URL.Query().Get("Anonymous") - - fmt.Println("code:", code) - fmt.Println("Anonymous:", Anonymous) - - // 参数校验 - if code == "" { - http.Error(w, "Missing 'code' or 'Anonymous' parameter", http.StatusBadRequest) - return - } - - // 初始化 SDK 客户端 - opt := new(credential.Config). - SetClientKey("tt8b32fd8f14071db707"). - SetClientSecret("44018e80b1bde34395a52de67ce1e0c37c572d80") - - sdkClient, err := openApiSdkClient.NewClient(opt) + resultJSON, err := json.Marshal(result) if err != nil { - fmt.Println("sdk init err:", err) - http.Error(w, "SDK 初始化失败", http.StatusInternalServerError) + http.Error(w, "生成返回 JSON 数据失败", http.StatusInternalServerError) return } - // 构建请求参数 - sdkRequest := &openApiSdkClient.V2Jscode2sessionRequest{} - sdkRequest.SetAnonymousCode(Anonymous) - sdkRequest.SetAppid("tt8b32fd8f14071db707") - sdkRequest.SetCode(code) - sdkRequest.SetSecret("44018e80b1bde34395a52de67ce1e0c37c572d80") - - // 调用 SDK - sdkResponse, err := sdkClient.V2Jscode2session(sdkRequest) - if err != nil { - fmt.Println("sdk call err:", err) - http.Error(w, "SDK 调用失败", http.StatusInternalServerError) - return - } - - // 打印登录数据 - fmt.Println("登录数据:", sdkResponse) - - // 返回响应 - value := fmt.Sprintf("Session Data: %v", sdkResponse.Data) + // 返回 JSON 格式的 ECPM 数据 w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusOK) - w.Write([]byte(value)) + w.Write(resultJSON) }) // 启动 HTTP 服务器