增加升级服务器的相关函数和api端点

This commit is contained in:
jingrow 2025-07-30 23:23:05 +08:00
parent 4d2c648fe2
commit e51fe71dfe
3 changed files with 180 additions and 6 deletions

View File

@ -536,9 +536,47 @@ def monitor_server_status(instance_id, region_id):
@jingrow.whitelist()
def upgrade_aliyun_instance(instance_id, plan_id, region_id='cn-shanghai'):
"""升级实例配置"""
manager = _get_manager()
return manager.upgrade_instance(instance_id, plan_id, region_id)
"""升级实例配置并更新状态"""
try:
# 1. 查找对应的Jsite Server记录
server = jingrow.get_pg("Jsite Server", {"instance_id": instance_id})
if not server:
return {"success": False, "message": "找不到对应的服务器记录"}
# 2. 立即更新状态为"升级中"
server.status = "Upgrading"
server.save(ignore_permissions=True)
jingrow.db.commit()
# 3. 调用阿里云API升级实例
manager = _get_manager()
result = manager.upgrade_instance(instance_id, plan_id, region_id)
if not result or not result.get('success'):
# 如果升级失败,恢复状态
server.status = "Running"
server.save(ignore_permissions=True)
jingrow.db.commit()
return result
# 4. 启动后台任务监控升级状态延迟10秒开始
time.sleep(10)
jingrow.enqueue(
"jcloud.api.aliyun_server_light.monitor_server_status",
instance_id=instance_id,
region_id=region_id,
timeout=600
)
return {
"success": True,
"message": "升级命令已发送,正在监控升级状态...",
"server_name": server.name
}
except Exception as e:
jingrow.log_error("升级实例失败", f"升级实例 {instance_id} 时发生错误: {str(e)}")
return {"success": False, "error": str(e), "message": "升级实例失败"}
@jingrow.whitelist()
def renew_aliyun_instance(instance_id, period=1, region_id='cn-shanghai'):
@ -916,6 +954,97 @@ def create_server_renew_order(**kwargs):
"message": f"创建续费订单失败: {str(e)}"
}
@jingrow.whitelist()
def create_server_upgrade_order(**kwargs):
"""创建服务器升级订单"""
try:
server = kwargs.get('server')
new_plan_id = kwargs.get('new_plan_id')
if not server or not new_plan_id:
jingrow.throw("缺少必要参数")
# 验证输入
server_pg = jingrow.get_pg("Jsite Server", server)
if not server_pg:
jingrow.throw("服务器不存在")
team = server_pg.team
# 验证当前用户权限
current_team = get_current_team(True)
if current_team.name != team:
jingrow.throw("您没有权限为此服务器创建升级订单")
# 获取当前套餐和新套餐信息
current_plan_price = server_pg.plan_price or 0
# 获取新套餐价格
plans_response = get_aliyun_plans(server_pg.region)
new_plan = None
if plans_response and plans_response.get('success'):
plans = plans_response['data'].get('plans', [])
new_plan = next((p for p in plans if p.get('plan_id') == new_plan_id), None)
if not new_plan:
jingrow.throw("新套餐不存在")
new_plan_price = float(new_plan.get('origin_price', 0))
# 计算剩余天数
if server_pg.end_date:
end_date = jingrow.utils.getdate(server_pg.end_date)
current_date = jingrow.utils.nowdate()
remaining_days = (end_date - current_date).days
if remaining_days <= 0:
remaining_days = 1 # 至少1天
else:
remaining_days = 30 # 默认30天
# 计算升级费用:按天计费,全额补差价
daily_price_diff = (new_plan_price - current_plan_price) / 30
upgrade_amount = daily_price_diff * remaining_days
# 确保升级费用不为负数
if upgrade_amount < 0:
upgrade_amount = 0
# 生成唯一订单号
order_id = datetime.now().strftime('%Y%m%d%H%M%S%f')[:-3] + ''.join(random.choices('0123456789', k=6))
# 创建订单记录
order = jingrow.get_pg({
"pagetype": "Order",
"order_id": order_id,
"order_type": "服务器升级",
"team": team,
"status": "待支付",
"total_amount": upgrade_amount,
"title": server_pg.instance_id,
"description": new_plan_id # 存储新套餐ID
})
order.insert(ignore_permissions=True)
jingrow.db.commit()
return {
"success": True,
"order": order.as_dict(),
"upgrade_info": {
"current_plan_price": current_plan_price,
"new_plan_price": new_plan_price,
"remaining_days": remaining_days,
"daily_price_diff": daily_price_diff,
"upgrade_amount": upgrade_amount
}
}
except Exception as e:
jingrow.log_error("升级订单错误", f"创建升级订单失败: {str(e)}")
return {
"success": False,
"message": f"创建升级订单失败: {str(e)}"
}
def renew_server(order_name):
"""支付成功后异步续费服务器"""
try:
@ -955,6 +1084,51 @@ def renew_server(order_name):
jingrow.log_error("服务器续费失败", f"订单 {order_name}: {str(e)}")
raise e
def upgrade_server(order_name):
"""支付成功后异步升级服务器"""
try:
order = jingrow.get_pg("Order", order_name)
if not order:
raise Exception("订单不存在")
# 从订单中获取信息
instance_id = order.title # 实例ID
new_plan_id = order.description # 新套餐ID
# 查找服务器记录获取区域信息
server = jingrow.get_pg("Jsite Server", {"instance_id": instance_id})
if not server:
raise Exception("找不到对应的服务器记录")
# 调用阿里云API升级实例
result = upgrade_aliyun_instance(instance_id, new_plan_id, server.region)
# 打印result到后台日志
jingrow.log_error("阿里云升级实例结果", f"订单 {order_name} 的升级结果: {result}")
if not result or not result.get('success'):
raise Exception(f"阿里云升级失败: {result.get('message', '未知错误')}")
# 更新订单状态
order.status = "交易成功"
order.save(ignore_permissions=True)
jingrow.db.commit()
# 延迟60秒执行update_server_record来更新服务器详细信息
time.sleep(60)
jingrow.enqueue(
"jcloud.api.aliyun_server_light.update_server_record",
instance_ids=json.dumps([instance_id]),
timeout=120
)
return True
except Exception as e:
jingrow.log_error("服务器升级失败", f"订单 {order_name}: {str(e)}")
raise e
def create_aliyun_server(order_name):
"""异步创建服务器"""
try:

View File

@ -77,14 +77,14 @@
"fieldtype": "Select",
"in_list_view": 1,
"label": "Order Type",
"options": "\n余额充值\n新建网站\n网站续费\n域名续费\n新建服务器\n服务器续费",
"options": "\n余额充值\n新建网站\n网站续费\n域名续费\n新建服务器\n服务器续费\n服务器升级",
"read_only": 1
}
],
"grid_page_length": 50,
"index_web_pages_for_search": 1,
"links": [],
"modified": "2025-07-27 17:29:16.088188",
"modified": "2025-07-30 23:11:19.817353",
"modified_by": "Administrator",
"module": "Jcloud",
"name": "Order",

View File

@ -16,7 +16,7 @@ class Order(Document):
description: DF.Data | None
order_id: DF.Data | None
order_type: DF.Literal["", "\u4f59\u989d\u5145\u503c", "\u65b0\u5efa\u7f51\u7ad9", "\u7f51\u7ad9\u7eed\u8d39", "\u57df\u540d\u7eed\u8d39", "\u65b0\u5efa\u670d\u52a1\u5668", "\u670d\u52a1\u5668\u7eed\u8d39"]
order_type: DF.Literal["", "\u4f59\u989d\u5145\u503c", "\u65b0\u5efa\u7f51\u7ad9", "\u7f51\u7ad9\u7eed\u8d39", "\u57df\u540d\u7eed\u8d39", "\u65b0\u5efa\u670d\u52a1\u5668", "\u670d\u52a1\u5668\u7eed\u8d39", "\u670d\u52a1\u5668\u5347\u7ea7"]
payment_method: DF.Literal["", "\u652f\u4ed8\u5b9d", "\u5fae\u4fe1\u652f\u4ed8", "\u4f59\u989d\u652f\u4ed8", "\u94f6\u884c\u8f6c\u8d26", "\u5176\u4ed6"]
status: DF.Literal["\u5f85\u652f\u4ed8", "\u5df2\u652f\u4ed8", "\u4ea4\u6613\u6210\u529f", "\u5df2\u53d6\u6d88", "\u5df2\u9000\u6b3e"]
team: DF.Link | None