From e51fe71dfe39c55b7e0bcf489cf5dc30307567b8 Mon Sep 17 00:00:00 2001 From: jingrow Date: Wed, 30 Jul 2025 23:23:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8D=87=E7=BA=A7=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=E7=9A=84=E7=9B=B8=E5=85=B3=E5=87=BD=E6=95=B0?= =?UTF-8?q?=E5=92=8Capi=E7=AB=AF=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jcloud/api/aliyun_server_light.py | 180 +++++++++++++++++++++++- jcloud/jcloud/pagetype/order/order.json | 4 +- jcloud/jcloud/pagetype/order/order.py | 2 +- 3 files changed, 180 insertions(+), 6 deletions(-) diff --git a/jcloud/api/aliyun_server_light.py b/jcloud/api/aliyun_server_light.py index a55baf1..822f78a 100644 --- a/jcloud/api/aliyun_server_light.py +++ b/jcloud/api/aliyun_server_light.py @@ -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: diff --git a/jcloud/jcloud/pagetype/order/order.json b/jcloud/jcloud/pagetype/order/order.json index 9508344..a653186 100644 --- a/jcloud/jcloud/pagetype/order/order.json +++ b/jcloud/jcloud/pagetype/order/order.json @@ -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", diff --git a/jcloud/jcloud/pagetype/order/order.py b/jcloud/jcloud/pagetype/order/order.py index d7d807d..7400c2d 100644 --- a/jcloud/jcloud/pagetype/order/order.py +++ b/jcloud/jcloud/pagetype/order/order.py @@ -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