package main import ( "context" "encoding/json" "fmt" "io" "net/http" "net/url" "time" ) const ( apiBaseURL = "https://data.openinstall.com" apiKey = "a7596bc007f31a98ca551e33a75d3bb5997b0b94027c6e988d3c0af1" ) type APIResponse struct { Code int `json:"code"` Error *string `json:"error"` Body json.RawMessage `json:"body"` } type DistributionData struct { Key string `json:"key"` Value int64 `json:"value"` } func main() { fmt.Println("========================================") fmt.Println("测试各端下载量统计(1月份完整数据)") fmt.Println("========================================") fmt.Println() ctx := context.Background() // 测试1月份数据 now := time.Now() startOfLastMonth := time.Date(now.Year(), now.Month()-1, 1, 0, 0, 0, 0, now.Location()) endOfLastMonth := time.Date(now.Year(), now.Month(), 1, 0, 0, 0, 0, now.Location()).AddDate(0, 0, -1) fmt.Printf("测试时间段: %s 到 %s\n", startOfLastMonth.Format("2006-01-02"), endOfLastMonth.Format("2006-01-02")) fmt.Println("========================================\n") // 获取各平台数据 platforms := []struct { name string platform string display string }{ {"iOS", "ios", "iPhone/iPad"}, {"Android", "android", "Android"}, } totalCount := int64(0) platformCounts := make(map[string]int64) for _, p := range platforms { fmt.Printf("获取 %s 平台数据...\n", p.name) data, err := getDeviceDistribution(ctx, startOfLastMonth, endOfLastMonth, p.platform, "total") if err != nil { fmt.Printf(" ❌ 失败: %v\n\n", err) continue } count := int64(0) for _, item := range data { count += item.Value } platformCounts[p.display] = count totalCount += count fmt.Printf(" ✅ %s: %d\n\n", p.display, count) } // 输出汇总 fmt.Println("========================================") fmt.Println("汇总结果(按界面格式):") fmt.Println("========================================") fmt.Printf("\n各端下载量: %d\n", totalCount) fmt.Println("----------------------------------------") fmt.Printf("📱 iPhone/iPad: %d\n", platformCounts["iPhone/iPad"]) fmt.Printf("🤖 Android: %d\n", platformCounts["Android"]) fmt.Printf("💻 Windows: %d (暂不支持)\n", int64(0)) fmt.Printf("🍎 Mac: %d (暂不支持)\n\n", int64(0)) // 说明 fmt.Println("========================================") fmt.Println("注意事项:") fmt.Println("========================================") fmt.Println("1. OpenInstall 统计的是「安装激活量」,非纯下载量") fmt.Println("2. Windows/Mac 数据需要通过其他方式获取") fmt.Println("3. 如需当月数据,请在月中测试") } func getDeviceDistribution(ctx context.Context, startDate, endDate time.Time, platform, sumBy string) ([]DistributionData, error) { apiURL := fmt.Sprintf("%s/data/sum/growth", apiBaseURL) params := url.Values{} params.Add("apiKey", apiKey) params.Add("beginDate", startDate.Format("2006-01-02")) params.Add("endDate", endDate.Format("2006-01-02")) params.Add("platform", platform) params.Add("sumBy", sumBy) params.Add("excludeDuplication", "0") fullURL := fmt.Sprintf("%s?%s", apiURL, params.Encode()) req, err := http.NewRequestWithContext(ctx, http.MethodGet, fullURL, nil) if err != nil { return nil, fmt.Errorf("failed to create request: %w", err) } client := &http.Client{Timeout: 10 * time.Second} resp, err := client.Do(req) if err != nil { return nil, fmt.Errorf("failed to send request: %w", err) } defer resp.Body.Close() body, err := io.ReadAll(resp.Body) if err != nil { return nil, fmt.Errorf("failed to read response: %w", err) } var apiResp APIResponse if err := json.Unmarshal(body, &apiResp); err != nil { return nil, fmt.Errorf("failed to parse response: %w", err) } if apiResp.Code != 0 { errMsg := "unknown error" if apiResp.Error != nil { errMsg = *apiResp.Error } return nil, fmt.Errorf("API error (code=%d): %s", apiResp.Code, errMsg) } var distData []DistributionData if err := json.Unmarshal(apiResp.Body, &distData); err != nil { return nil, fmt.Errorf("failed to parse distribution data: %w", err) } return distData, nil }