kboss/b/cpcc/utils/widget_price.py
2025-07-16 14:27:17 +08:00

308 lines
10 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# -*- coding: utf-8 -*-
def widget_pricing(rows):
"""
核心汇算部件价格逻辑
"""
# 初始化资源字典
resources = {
"cpu": {},
"memory": {},
"disk": {},
"gpu": {}
}
# 处理查询结果并填充资源字典
for row in rows:
resource_type, model, unit_price, resource_unit, stock = row
if model == 'STANDARD':
model = 'STANDARD'
else:
model = model.strip()
if resource_type in resources:
resources[resource_type][model] = {
"unit_price": float(unit_price),
"resource_unit": resource_unit,
"stock": int(stock)
}
# 将资源字典转换为 JSON 字符串
return json.dumps(resources, indent=4)
def apply_discount(price, duration):
"""折扣策略"""
if duration >= 720: # 使用超过30天
return price * 0.9 # 9折优惠
return price
def get_memory_price(amount):
"""内存阶梯定价"""
if amount <= 4096: # 4GB以下
return 0.00012 # 较高单价
return 0.0001 # 量大优惠
def calculate_price(request_data, RESOURCE_PRICING, DURATION_FACTOR):
"""
计算多种资源组合的总价格
返回计算结果,包含总价和各资源明细
"""
# 初始化结果
result = {
"total_price": 0.0,
"currency": "",
"price_details": [],
"status": True,
"message": "汇算正常"
}
# 获取资源配置
resources = request_data.get("resources", [])
if not resources:
result["status"] = False
result["message"] = "异常:请求中必须包含资源信息"
return result
# 获取使用时长并转换为小时
duration = request_data.get("duration", 1)
duration_unit = request_data.get("duration_unit", "小时")
duration_hours = duration * DURATION_FACTOR.get(duration_unit, 1)
result["duration"] = duration
result["duration_unit"] = duration_unit
# 遍历计算每种资源的价格
for resource in resources:
resource_type = resource.get("type")
amount = resource.get("amount", 0)
if not resource_type or amount <= 0:
continue
try:
# 获取资源定价信息
if resource_type in ["cpu", "gpu", "disk", "memory"]:
# 需要查询型号的部件类型
model = resource.get("model")
if not model:
raise ValueError(f"{resource_type} 必须指定部件型号/系列")
if not RESOURCE_PRICING.get(resource_type):
raise ValueError(f"没有该类型组件")
resource_info = RESOURCE_PRICING[resource_type].get(model)
if not resource_info:
raise ValueError(f"无效的 {resource_type} 部件型号: {model}")
resource_name = f"{resource_type} {model}"
else:
raise ValueError(f"不支持的资源类型: {resource_type}")
# 检查库存
if resource_info["stock"] < amount:
raise ValueError(f'{resource_name} 库存不足 (库存: {resource_info["stock"]}, 请求: {amount})')
# 计算价格
unit_price = resource_info["unit_price"]
subtotal = unit_price * float(amount) * float(duration_hours)
# 更新总价和明细
result["total_price"] += subtotal
result["price_details"].append({
"resource_name": resource_name,
"resource_type": resource_type,
"amount": amount,
"resource_unit": resource_info["resource_unit"],
"unit_price": unit_price,
"duration": duration,
"duration_unit": duration_unit,
"subtotal": round(subtotal, 2)
})
except Exception as e:
# 记录错误并继续处理其他资源
result["price_details"].append({
"resource_type": resource_type,
"error": str(e)
})
if result["status"] == True:
result["status"] = False
result["message"] = str(e)
# 结果格式化
result["total_price"] = round(result["total_price"], 2)
return result
# 使用示例
if __name__ == "__main__":
# RESOURCE_PRICING = widget_pricing()
# 模拟资源定价数据(包含多种资源类型和型号)
RESOURCE_PRICING2 = {
# CPU 资源(按核计价,不同型号单价不同)
"cpu": {
"AMD EPYC 7542 32-Core Processor":
{"unit_price": 0.8, "resource_unit": "", "stock": 100},
"INTEL(R) XEON(R) PLATINUM 8582C":
{"unit_price": 1.5, "resource_unit": "", "stock": 50},
"STANDARD":
{"unit_price": 2.2, "resource_unit": "", "stock": 0}
},
# 内存资源(按 Mi 计价,统一单价
"memory": {
"Kingston FURY": # 高性能-便宜
{"unit_price": 0.0001, "resource_unit": "Mi", "stock": 1048576}, # 1024 Gi / 1TB
"Crucial P-series": # 性能一般-价格一般
{"unit_price": 0.0005, "resource_unit": "Mi", "stock": 1048576},
"Samsung DDR4 DIMMs": # 高性能-贵
{"unit_price": 0.005, "resource_unit": "Mi", "stock": 1048576},
"STANDARD":
{"unit_price": 0.0004, "resource_unit": "Mi", "stock": 0}, # Kyy自营
},
# 云盘资源(按 Gi 计价,不同类型单价不同)
"disk": {
"DATA": # 共享数据盘
{"unit_price": 0.01, "resource_unit": "Gi", "stock": 20480}, # 20 TiB
"SYS": # 系统盘
{"unit_price": 0.005, "resource_unit": "Gi", "stock": 51200}, # 50 TiB
},
# GPU 资源(按卡计价,不同型号单价不同)
"gpu": {
"RTX4090-24G":
{"unit_price": 4.0, "resource_unit": "", "stock": 12},
"RTX5090-32G":
{"unit_price": 6.0, "resource_unit": "", "stock": 10},
"A100-80G":
{"unit_price": 18.0, "resource_unit": "", "stock": 5},
"V100-32G":
{"unit_price": 12.0, "resource_unit": "", "stock": 8},
"STANDARD-8G":
{"unit_price": 2.0, "resource_unit": "", "stock": 1},
}
}
RESOURCE_PRICING = {
"cpu": {
"AMD EPYC 7542 32-Core Processor": {
"unit_price": 0.8,
"resource_unit": "",
"stock": 100
},
"STANDARD-9G": {
"unit_price": 1.22,
"resource_unit": "",
"stock": 2
},
"STANDARD": {
"unit_price": 2.2,
"resource_unit": "",
"stock": 0
},
"INTEL(R) XEON(R) PLATINUM 8582C": {
"unit_price": 1.5,
"resource_unit": "",
"stock": 50
}
},
"memory": {
"Kingston FURY": {
"unit_price": 0.0001,
"resource_unit": "Mi",
"stock": 1048576
},
"Crucial P-series": {
"unit_price": 0.0005,
"resource_unit": "Mi",
"stock": 1048576
},
"STANDARD": {
"unit_price": 0.0004,
"resource_unit": "Mi",
"stock": 0
},
"Samsung DDR4 DIMMs": {
"unit_price": 0.005,
"resource_unit": "Gi",
"stock": 1048576
}
},
"disk": {
"SYS": {
"unit_price": 0.005,
"resource_unit": "Gi",
"stock": 51200
},
"DATA": {
"unit_price": 0.01,
"resource_unit": "Gi",
"stock": 20480
}
},
"gpu": {
"V100-32G": {
"unit_price": 12,
"resource_unit": "",
"stock": 8
},
"RTX4090-24G": {
"unit_price": 4,
"resource_unit": "",
"stock": 12
},
"RTX5090-32G": {
"unit_price": 6,
"resource_unit": "",
"stock": 10
},
"A100-80G": {
"unit_price": 18,
"resource_unit": "",
"stock": 5
},
"STANDARD-8G": {
"unit_price": 2,
"resource_unit": "",
"stock": 1
}
}
}
# 计费周期转换系数(统一转换为小时)
DURATION_FACTOR = {
"小时": 1, # 按量付费(按小时计费)
"": 24,
"": 168,
"": 720 # 按30天计算(按月计费)
}
# HTTP请求示例
# 4核CPU-INTEL(R) XEON(R) PLATINUM 8582C +
# 8GB-Samsung DDR4 DIMMs内存 +
# 512GB-DATA数据盘 +
# 2张RTX5090-32G +
# 使用1天
params = {
"resources": [
{"type": "cpu", "model": "INTEL(R) XEON(R) PLATINUM 8582C", "amount": 4},
{"type": "memory", "model": "Samsung DDR4 DIMMs", "amount": 8192}, # 8GB必须转成8192Mi
{"type": "disk", "model": "DATA", "amount": 512},
{"type": "gpu", "model": "RTX5090-32G", "amount": 2}
],
"duration": 2,
"duration_unit": ""
}
# 计算价格
result = calculate_price(params, RESOURCE_PRICING, DURATION_FACTOR)
# 打印结果
print(f"状态: {result['status']}")
if result["message"]:
print(f"提示: {result['message']}")
print(f"实时总价: {result['total_price']}{result['currency']}/{result.get('duration')}{result.get('duration_unit')}")
print(f"价格明细: {result}")
for detail in result["price_details"]:
if "error" in detail:
print(f"{detail['resource_type']}: {detail['error']}")
else:
print(f"{detail['resource_name']} ({detail['amount']}{detail['resource_unit']}): "
f"{detail['subtotal']} 元 ({detail['unit_price']}元/{detail['resource_unit']}/小时 × "
f"{detail['duration']}{detail['duration_unit']})")