From df195a049c5b7f8b6bae6a8eb4c00d53be057e0a Mon Sep 17 00:00:00 2001 From: jingrow Date: Tue, 1 Jul 2025 16:00:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=B0=E6=9C=9F=E5=90=8E?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=81=9C=E7=94=A8=E7=AB=99=E7=82=B9=E7=9A=84?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- jcloud/api/billing.py | 73 +++++++++++------------------ jcloud/hooks.py | 3 ++ jcloud/jcloud/pagetype/site/site.py | 22 +++++++++ 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/jcloud/api/billing.py b/jcloud/api/billing.py index 1dd5c1e..0adbc82 100644 --- a/jcloud/api/billing.py +++ b/jcloud/api/billing.py @@ -8,7 +8,6 @@ import json import segno import io import base64 -import traceback import jingrow from jingrow import _ # Import this for translation functionality from jingrow.core.utils import find @@ -783,28 +782,24 @@ def handle_transaction_result(transaction_response, integration_request): create_mpesa_request_log( transaction_response, "Host", "Mpesa Exjcloud", integration_request, None, status ) - jingrow.log_error(f"Mpesa: Transaction failed with error {e}") elif result_code == 1037: # User unreachable (Phone off or timeout) status = "Failed" create_mpesa_request_log( transaction_response, "Host", "Mpesa Exjcloud", integration_request, None, status ) - jingrow.log_error("Mpesa: User cannot be reached (Phone off or timeout)") elif result_code == 1032: # User cancelled the request status = "Cancelled" create_mpesa_request_log( transaction_response, "Host", "Mpesa Exjcloud", integration_request, None, status ) - jingrow.log_error("Mpesa: Request cancelled by user") else: # Other failure codes status = "Failed" create_mpesa_request_log( transaction_response, "Host", "Mpesa Exjcloud", integration_request, None, status ) - jingrow.log_error(f"Mpesa: Transaction failed with ResultCode {result_code}") return status @@ -1003,7 +998,7 @@ def handle_alipay_notification(): return "success" except Exception as e: - jingrow.log_error(f"处理失败: {str(e)}\n{traceback.format_exc()}", "支付宝错误") + jingrow.log_error("支付宝错误", f"处理失败: {str(e)}") return "fail" @jingrow.whitelist(allow_guest=True) @@ -1075,17 +1070,11 @@ def handle_wechatpay_notification(): return "SUCCESS" except Exception as e: - jingrow.log_error( - f"处理微信支付通知数据失败: {str(e)}\n调用栈: {traceback.format_exc()}\n请求头: {headers}\n请求体: {body}", - "微信支付解密错误" - ) + jingrow.log_error("微信支付解密错误", f"处理微信支付通知数据失败: {str(e)}\n请求头: {headers}\n请求体: {body}") return "SUCCESS" # 返回成功避免微信重复发送通知 except Exception as e: - jingrow.log_error( - f"处理微信支付通知失败: {str(e)}\n调用栈: {traceback.format_exc()}", - "微信支付错误" - ) + jingrow.log_error("微信支付错误", f"处理微信支付通知失败: {str(e)}") return "SUCCESS" # 返回成功避免微信重复发送通知 @@ -1102,10 +1091,7 @@ def handle_order_payment_complete(order_id): return True except Exception as e: - jingrow.log_error( - f"处理订单 {order_id} 支付完成事件失败: {str(e)}\n{traceback.format_exc()}", - f"订单处理错误" - ) + jingrow.log_error("订单处理错误", f"处理订单 {order_id} 支付完成事件失败: {str(e)}") return False def process_balance_recharge(order): @@ -1129,10 +1115,7 @@ def process_balance_recharge(order): jingrow.db.commit() except Exception as e: - jingrow.log_error( - f"余额充值失败: 团队 {order.team}, 金额 {order.total_amount}, 错误: {str(e)}\n{traceback.format_exc()}", - "余额充值错误" - ) + jingrow.log_error("余额充值错误", f"余额充值失败: 团队 {order.team}, 金额 {order.total_amount}, 错误: {str(e)}") raise def process_site_renew(order_id): @@ -1170,16 +1153,17 @@ def process_site_renew(order_id): # 更新站点到期日期 site.site_end_date = new_end_date site.save(ignore_permissions=True) + + # 续费后自动激活站点(如有需要) + if site.status in ["Inactive", "Suspended"]: + try: + site.activate() + except Exception as e: + jingrow.log_error("站点自动激活失败", f"站点 {site_name} 续费后自动激活失败: {str(e)}") # 更新订单状态为交易成功,防止重复处理 jingrow.db.set_value("Order", order.name, "status", "交易成功") - # 记录成功的审计日志 - jingrow.log_error( - message=f"网站续费成功: {site_name}, 支付方式:{order.payment_method}, 订单号:{order_id}, 续费 {renewal_months} 个月, 到期日延长至 {new_end_date}", - title="网站续费成功" - ) - return { "name": site.name, "url": site_name, @@ -1254,7 +1238,7 @@ def create_alipay_order_for_recharge(amount): "payment_record": payment_record.name } except Exception as e: - jingrow.log_error(f"创建支付宝订单失败: {str(e)}", "Order") + jingrow.log_error("Order", f"创建支付宝订单失败: {str(e)}") jingrow.throw(f"创建支付宝订单失败: {str(e)}") @@ -1303,7 +1287,7 @@ def create_wechatpay_order_for_recharge(amount): # 检查URL是否为空 if not qr_code_url: - jingrow.log_error("微信支付URL生成为空", "微信支付错误") + jingrow.log_error("微信支付错误", "微信支付URL生成为空") # 使用提供的函数生成二维码图片 qr_code_image = generate_qr_code(qr_code_url) @@ -1316,7 +1300,7 @@ def create_wechatpay_order_for_recharge(amount): return result except Exception as e: - jingrow.log_error(f"创建微信支付订单失败: {str(e)}\n{traceback.format_exc()}", "微信支付错误") + jingrow.log_error("微信支付错误", f"创建微信支付订单失败: {str(e)}") jingrow.throw(f"创建微信支付订单失败") @@ -1361,7 +1345,7 @@ def create_order(**kwargs): } except Exception as e: - jingrow.log_error(f"创建站点订单失败: {str(e)}\n{traceback.format_exc()}", "订单错误") + jingrow.log_error("订单错误", f"创建站点订单失败: {str(e)}") return { "success": False, "message": f"创建订单失败: {str(e)}" @@ -1418,7 +1402,7 @@ def create_renewal_order(site, renewal_months=1): "order": order.as_dict() } except Exception as e: - jingrow.log_error(f"创建续费订单失败: {str(e)}", "续费订单错误") + jingrow.log_error("续费订单错误", f"创建续费订单失败: {str(e)}") return { "success": False, "message": f"创建续费订单失败: {str(e)}" @@ -1484,7 +1468,7 @@ def process_balance_payment_for_order(order_id): } except Exception as e: - jingrow.log_error(f"余额支付失败: {str(e)}\n{traceback.format_exc()}", "支付错误") + jingrow.log_error("支付错误", f"余额支付失败: {str(e)}") return { "status": "Error", "message": f"余额支付失败: {str(e)}" @@ -1574,10 +1558,7 @@ def process_balance_payment_for_renew_order(order_id): raise inner_error except Exception as e: - jingrow.log_error( - message=f"余额支付续费失败: {str(e)}\n{traceback.format_exc()}", - title="续费支付错误" - ) + jingrow.log_error("续费支付错误", f"余额支付续费失败: {str(e)}") return { "success": False, "status": "Error", @@ -1628,7 +1609,7 @@ def process_alipay_order(order_id): "success": True } except Exception as e: - jingrow.log_error(f"创建支付宝订单失败: {str(e)}", "Order") + jingrow.log_error("Order", f"创建支付宝订单失败: {str(e)}") jingrow.throw(f"创建支付宝订单失败: {str(e)}") @jingrow.whitelist() @@ -1668,7 +1649,7 @@ def process_wechatpay_order(order_id): # 检查URL是否为空 if not qr_code_url: - jingrow.log_error("微信支付URL生成为空", "微信支付错误") + jingrow.log_error("微信支付错误", "微信支付URL生成为空") jingrow.throw("生成支付URL失败") # 生成二维码图片 @@ -1686,11 +1667,11 @@ def process_wechatpay_order(order_id): } except Exception as e: - jingrow.log_error(f"创建微信支付订单失败: {str(e)}\n{traceback.format_exc()}", "微信支付错误") + jingrow.log_error("微信支付错误", f"创建微信支付订单失败: {str(e)}") jingrow.throw(f"创建微信支付订单失败") except Exception as e: - jingrow.log_error(f"创建微信支付订单失败: {str(e)}\n{traceback.format_exc()}", "微信支付错误") + jingrow.log_error("微信支付错误", f"创建微信支付订单失败: {str(e)}") jingrow.throw(f"创建微信支付订单失败") @jingrow.whitelist() @@ -1709,7 +1690,7 @@ def check_site_order_payment_status(order_id): } except Exception as e: - jingrow.log_error(f"检查订单状态失败: {str(e)}\n{traceback.format_exc()}", "订单错误") + jingrow.log_error("订单错误", f"检查订单状态失败: {str(e)}") return { "success": False, "message": f"检查订单状态失败: {str(e)}" @@ -1774,7 +1755,7 @@ def get_orders(page=1, page_size=20, search=None): } except Exception as e: - jingrow.log_error(f"获取订单列表失败: {str(e)}\n{traceback.format_exc()}", "订单列表错误") + jingrow.log_error("订单列表错误", f"获取订单列表失败: {str(e)}") return { "orders": [], "total": 0, @@ -1811,7 +1792,7 @@ def get_order_details(name): } except Exception as e: - jingrow.log_error(f"获取订单详情失败: {str(e)}\n{traceback.format_exc()}", "订单详情错误") + jingrow.log_error("订单详情错误", f"获取订单详情失败: {str(e)}") return { "error": str(e) } @@ -1882,7 +1863,7 @@ def get_balance_transactions(page=1, page_size=20, search=None): } except Exception as e: - jingrow.log_error(f"获取余额记录失败: {str(e)}\n{traceback.format_exc()}", "余额记录错误") + jingrow.log_error("余额记录错误", f"获取余额记录失败: {str(e)}") return { "transactions": [], "total": 0, diff --git a/jcloud/hooks.py b/jcloud/hooks.py index f394760..371794b 100644 --- a/jcloud/hooks.py +++ b/jcloud/hooks.py @@ -302,6 +302,9 @@ scheduler_events = { "jcloud.jcloud.pagetype.tls_certificate.tls_certificate.retrigger_failed_wildcard_tls_callbacks", "jcloud.infrastructure.pagetype.ssh_access_audit.ssh_access_audit.run", ], + "0 1 * * *": [ + "jcloud.jcloud.pagetype.site.site.deactivate_expired_sites", + ], }, } diff --git a/jcloud/jcloud/pagetype/site/site.py b/jcloud/jcloud/pagetype/site/site.py index 9fbbf2e..9d08df5 100644 --- a/jcloud/jcloud/pagetype/site/site.py +++ b/jcloud/jcloud/pagetype/site/site.py @@ -3885,3 +3885,25 @@ def send_renew_notification(): ) except Exception as e: jingrow.log_error(f"站点 {site.name} 发送续费通知失败: {str(e)}", "Renewal Notification Error") + +@jingrow.whitelist(allow_guest=True) +def deactivate_expired_sites(): + """ + 自动将已到期的站点(site_end_date<=今天,且状态为Active或Suspended)设为Inactive。 + 每天定时任务调用。 + """ + today = jingrow.utils.today() + sites = jingrow.get_all( + "Site", + filters={ + "status": ["in", ["Active", "Suspended"]], + "site_end_date": ["<", today] + }, + fields=["name", "status"] + ) + for site in sites: + try: + site_pg = jingrow.get_pg("Site", site.name) + site_pg.deactivate() + except Exception as e: + jingrow.log_error("Auto Inactivate Site Error", f"站点 {site.name} 到期自动停用失败: {str(e)}")