fix: 完善多云同步验证与实例统计

- 修复华为云签名、账单字段与区域映射缓存
- 按真实云实例更新账号服务器数并补充并发测试
This commit is contained in:
Logan.Li committed 2026-07-29 06:35:54 +08:00
1 parent 132fe9ba97
commit 9b895efee3
6 files changed
+226 -64

No files matched your search

+59 -24
View File
@@ -11,6 +11,28 @@ import (
"time"
)
type huaweiBillRecord struct {
ServiceTypeCode string `json:"service_type_code"`
ServiceTypeName string `json:"service_type_name"`
CloudServiceType string `json:"cloud_service_type"`
CloudServiceTypeName string `json:"cloud_service_type_name"`
ResourceTypeName string `json:"resource_type_name"`
RegionCode string `json:"region_code"`
Region string `json:"region"`
RegionName string `json:"region_name"`
Amount json.RawMessage `json:"amount"`
ConsumeAmount json.RawMessage `json:"consume_amount"`
OfficialAmount json.RawMessage `json:"official_amount"`
DiscountAmount json.RawMessage `json:"discount_amount"`
}
type huaweiBillPage struct {
TotalCount int `json:"total_count"`
Currency string `json:"currency"`
Records []huaweiBillRecord `json:"records"`
FeeRecords []huaweiBillRecord `json:"fee_records"`
}
// FetchDailyBill 通过华为云 BSS 费用流水接口拉取单日账单。 // Logan.Li
func (p *HuaweiProvider) FetchDailyBill(billingDate string) ([]CloudBillingRecord, error) {
if _, err := time.Parse("2006-01-02", billingDate); err != nil {
@@ -21,10 +43,11 @@ func (p *HuaweiProvider) FetchDailyBill(billingDate string) ([]CloudBillingRecor
region string
}
aggregation := map[aggregationKey]float64{}
currency := "CNY"
const pageSize = 1000
for offset := 0; ; offset += pageSize {
query := url.Values{
"cycle": {billingDate[:7]},
"bill_cycle": {billingDate[:7]},
"bill_date_begin": {billingDate},
"bill_date_end": {billingDate},
"offset": {strconv.Itoa(offset)},
@@ -34,35 +57,27 @@ func (p *HuaweiProvider) FetchDailyBill(billingDate string) ([]CloudBillingRecor
if err != nil {
return nil, err
}
var response struct {
TotalCount int `json:"total_count"`
FeeRecords []struct {
CloudServiceType string `json:"cloud_service_type"`
CloudServiceTypeName string `json:"cloud_service_type_name"`
ResourceTypeName string `json:"resource_type_name"`
Region string `json:"region"`
RegionName string `json:"region_name"`
Amount json.RawMessage `json:"amount"`
OfficialAmount json.RawMessage `json:"official_amount"`
DiscountAmount json.RawMessage `json:"discount_amount"`
} `json:"fee_records"`
page, err := decodeHuaweiBillPage(body)
if err != nil {
return nil, err
}
if err = json.Unmarshal(body, &response); err != nil {
return nil, fmt.Errorf("解析华为云 BSS 响应失败: %w", err)
if page.Currency != "" {
currency = page.Currency
}
for _, item := range response.FeeRecords {
cost := huaweiBillAmount(item.Amount)
if cost == 0 {
cost = huaweiBillAmount(item.OfficialAmount) - huaweiBillAmount(item.DiscountAmount)
}
records := page.Records
if len(records) == 0 {
records = page.FeeRecords
}
for _, item := range records {
cost := huaweiBillRecordCost(item)
if cost == 0 {
continue
}
service := firstNonEmpty(item.CloudServiceTypeName, item.ResourceTypeName, item.CloudServiceType, "其他")
region := firstNonEmpty(item.RegionName, item.Region, "全局")
service := firstNonEmpty(item.ServiceTypeName, item.CloudServiceTypeName, item.ResourceTypeName, item.ServiceTypeCode, item.CloudServiceType, "其他")
region := firstNonEmpty(item.RegionName, item.RegionCode, item.Region, "全局")
aggregation[aggregationKey{service: service, region: region}] += cost
}
if len(response.FeeRecords) < pageSize || (response.TotalCount > 0 && offset+pageSize >= response.TotalCount) {
if len(records) < pageSize || (page.TotalCount > 0 && offset+pageSize >= page.TotalCount) {
break
}
}
@@ -80,13 +95,33 @@ func (p *HuaweiProvider) FetchDailyBill(billingDate string) ([]CloudBillingRecor
for _, key := range keys {
records = append(records, CloudBillingRecord{
BillingDate: billingDate, Provider: "huawei", Cost: math.Round(aggregation[key]*100) / 100,
Currency: "CNY", Service: key.service, Region: key.region,
Currency: currency, Service: key.service, Region: key.region,
Description: "云 API 自动同步(华为云 BSS)",
})
}
return records, nil
}
// decodeHuaweiBillPage 兼容华为云 records 与旧版 fee_records 响应。 // Logan.Li
func decodeHuaweiBillPage(body []byte) (huaweiBillPage, error) {
var page huaweiBillPage
if err := json.Unmarshal(body, &page); err != nil {
return page, fmt.Errorf("解析华为云 BSS 响应失败: %w", err)
}
return page, nil
}
// huaweiBillRecordCost 依次读取实际消费、流水金额和官网价减优惠。 // Logan.Li
func huaweiBillRecordCost(item huaweiBillRecord) float64 {
if cost := huaweiBillAmount(item.ConsumeAmount); cost != 0 {
return cost
}
if cost := huaweiBillAmount(item.Amount); cost != 0 {
return cost
}
return huaweiBillAmount(item.OfficialAmount) - huaweiBillAmount(item.DiscountAmount)
}
// huaweiBillAmount 兼容华为云金额字段的字符串和数字格式。 // Logan.Li
func huaweiBillAmount(raw json.RawMessage) float64 {
value := strings.Trim(strings.TrimSpace(string(raw)), "\"")