fix: auto-fix code issues (cron)

- 修复重复导入/字段
- 修复异常处理
- 修复PEP8格式问题
- 添加类型注解
- 修复缺失的urllib.parse导入
This commit is contained in:
OpenClaw Bot
2026-02-28 06:03:09 +08:00
parent ff83cab6c7
commit fe3d64a1d2
41 changed files with 4501 additions and 1176 deletions

View File

@@ -21,6 +21,7 @@ from typing import Any
logger = logging.getLogger(__name__)
class SubscriptionStatus(StrEnum):
"""订阅状态"""
@@ -31,6 +32,7 @@ class SubscriptionStatus(StrEnum):
TRIAL = "trial" # 试用中
PENDING = "pending" # 待支付
class PaymentProvider(StrEnum):
"""支付提供商"""
@@ -39,6 +41,7 @@ class PaymentProvider(StrEnum):
WECHAT = "wechat" # 微信支付
BANK_TRANSFER = "bank_transfer" # 银行转账
class PaymentStatus(StrEnum):
"""支付状态"""
@@ -49,6 +52,7 @@ class PaymentStatus(StrEnum):
REFUNDED = "refunded" # 已退款
PARTIAL_REFUNDED = "partial_refunded" # 部分退款
class InvoiceStatus(StrEnum):
"""发票状态"""
@@ -59,6 +63,7 @@ class InvoiceStatus(StrEnum):
VOID = "void" # 作废
CREDIT_NOTE = "credit_note" # 贷项通知单
class RefundStatus(StrEnum):
"""退款状态"""
@@ -68,6 +73,7 @@ class RefundStatus(StrEnum):
COMPLETED = "completed" # 已完成
FAILED = "failed" # 失败
@dataclass
class SubscriptionPlan:
"""订阅计划数据类"""
@@ -86,6 +92,7 @@ class SubscriptionPlan:
updated_at: datetime
metadata: dict[str, Any]
@dataclass
class Subscription:
"""订阅数据类"""
@@ -106,6 +113,7 @@ class Subscription:
updated_at: datetime
metadata: dict[str, Any]
@dataclass
class UsageRecord:
"""用量记录数据类"""
@@ -120,6 +128,7 @@ class UsageRecord:
description: str | None
metadata: dict[str, Any]
@dataclass
class Payment:
"""支付记录数据类"""
@@ -141,6 +150,7 @@ class Payment:
created_at: datetime
updated_at: datetime
@dataclass
class Invoice:
"""发票数据类"""
@@ -164,6 +174,7 @@ class Invoice:
created_at: datetime
updated_at: datetime
@dataclass
class Refund:
"""退款数据类"""
@@ -186,6 +197,7 @@ class Refund:
created_at: datetime
updated_at: datetime
@dataclass
class BillingHistory:
"""账单历史数据类"""
@@ -201,6 +213,7 @@ class BillingHistory:
created_at: datetime
metadata: dict[str, Any]
class SubscriptionManager:
"""订阅与计费管理器"""
@@ -213,7 +226,13 @@ class SubscriptionManager:
"price_monthly": 0.0,
"price_yearly": 0.0,
"currency": "CNY",
"features": ["basic_analysis", "export_png", "3_projects", "100_mb_storage", "60_min_transcription"],
"features": [
"basic_analysis",
"export_png",
"3_projects",
"100_mb_storage",
"60_min_transcription",
],
"limits": {
"max_projects": 3,
"max_storage_mb": 100,
@@ -280,9 +299,17 @@ class SubscriptionManager:
# 按量计费单价CNY
USAGE_PRICING = {
"transcription": {"unit": "minute", "price": 0.5, "free_quota": 60}, # 0.5元/分钟 # 每月免费额度
"transcription": {
"unit": "minute",
"price": 0.5,
"free_quota": 60,
}, # 0.5元/分钟 # 每月免费额度
"storage": {"unit": "gb", "price": 10.0, "free_quota": 0.1}, # 10元/GB/月 # 100MB免费
"api_call": {"unit": "1000_calls", "price": 5.0, "free_quota": 1000}, # 5元/1000次 # 每月免费1000次
"api_call": {
"unit": "1000_calls",
"price": 5.0,
"free_quota": 1000,
}, # 5元/1000次 # 每月免费1000次
"export": {"unit": "page", "price": 0.1, "free_quota": 100}, # 0.1元/页PDF导出
}
@@ -456,21 +483,39 @@ class SubscriptionManager:
""")
# 创建索引
cursor.execute("CREATE INDEX IF NOT EXISTS idx_subscriptions_tenant ON subscriptions(tenant_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_subscriptions_plan ON subscriptions(plan_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_usage_tenant ON usage_records(tenant_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_usage_type ON usage_records(resource_type)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_usage_recorded ON usage_records(recorded_at)")
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_subscriptions_tenant ON subscriptions(tenant_id)"
)
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_subscriptions_status ON subscriptions(status)"
)
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_subscriptions_plan ON subscriptions(plan_id)"
)
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_usage_tenant ON usage_records(tenant_id)"
)
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_usage_type ON usage_records(resource_type)"
)
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_usage_recorded ON usage_records(recorded_at)"
)
cursor.execute("CREATE INDEX IF NOT EXISTS idx_payments_tenant ON payments(tenant_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_payments_status ON payments(status)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_invoices_tenant ON invoices(tenant_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_invoices_status ON invoices(status)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_invoices_number ON invoices(invoice_number)")
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_invoices_number ON invoices(invoice_number)"
)
cursor.execute("CREATE INDEX IF NOT EXISTS idx_refunds_tenant ON refunds(tenant_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_refunds_status ON refunds(status)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_billing_tenant ON billing_history(tenant_id)")
cursor.execute("CREATE INDEX IF NOT EXISTS idx_billing_created ON billing_history(created_at)")
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_billing_tenant ON billing_history(tenant_id)"
)
cursor.execute(
"CREATE INDEX IF NOT EXISTS idx_billing_created ON billing_history(created_at)"
)
conn.commit()
logger.info("Subscription tables initialized successfully")
@@ -542,7 +587,9 @@ class SubscriptionManager:
conn = self._get_connection()
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM subscription_plans WHERE tier = ? AND is_active = 1", (tier,))
cursor.execute(
"SELECT * FROM subscription_plans WHERE tier = ? AND is_active = 1", (tier,)
)
row = cursor.fetchone()
if row:
@@ -561,7 +608,9 @@ class SubscriptionManager:
if include_inactive:
cursor.execute("SELECT * FROM subscription_plans ORDER BY price_monthly")
else:
cursor.execute("SELECT * FROM subscription_plans WHERE is_active = 1 ORDER BY price_monthly")
cursor.execute(
"SELECT * FROM subscription_plans WHERE is_active = 1 ORDER BY price_monthly"
)
rows = cursor.fetchall()
return [self._row_to_plan(row) for row in rows]
@@ -679,7 +728,7 @@ class SubscriptionManager:
cursor = conn.cursor()
cursor.execute(
f"""
UPDATE subscription_plans SET {', '.join(updates)}
UPDATE subscription_plans SET {", ".join(updates)}
WHERE id = ?
""",
params,
@@ -901,7 +950,7 @@ class SubscriptionManager:
cursor = conn.cursor()
cursor.execute(
f"""
UPDATE subscriptions SET {', '.join(updates)}
UPDATE subscriptions SET {", ".join(updates)}
WHERE id = ?
""",
params,
@@ -913,7 +962,9 @@ class SubscriptionManager:
finally:
conn.close()
def cancel_subscription(self, subscription_id: str, at_period_end: bool = True) -> Subscription | None:
def cancel_subscription(
self, subscription_id: str, at_period_end: bool = True
) -> Subscription | None:
"""取消订阅"""
conn = self._get_connection()
try:
@@ -965,7 +1016,9 @@ class SubscriptionManager:
finally:
conn.close()
def change_plan(self, subscription_id: str, new_plan_id: str, prorate: bool = True) -> Subscription | None:
def change_plan(
self, subscription_id: str, new_plan_id: str, prorate: bool = True
) -> Subscription | None:
"""更改订阅计划"""
conn = self._get_connection()
try:
@@ -1214,7 +1267,9 @@ class SubscriptionManager:
finally:
conn.close()
def confirm_payment(self, payment_id: str, provider_payment_id: str | None = None) -> Payment | None:
def confirm_payment(
self, payment_id: str, provider_payment_id: str | None = None
) -> Payment | None:
"""确认支付完成"""
conn = self._get_connection()
try:
@@ -1525,7 +1580,9 @@ class SubscriptionManager:
# ==================== 退款管理 ====================
def request_refund(self, tenant_id: str, payment_id: str, amount: float, reason: str, requested_by: str) -> Refund:
def request_refund(
self, tenant_id: str, payment_id: str, amount: float, reason: str, requested_by: str
) -> Refund:
"""申请退款"""
conn = self._get_connection()
try:
@@ -1632,7 +1689,9 @@ class SubscriptionManager:
finally:
conn.close()
def complete_refund(self, refund_id: str, provider_refund_id: str | None = None) -> Refund | None:
def complete_refund(
self, refund_id: str, provider_refund_id: str | None = None
) -> Refund | None:
"""完成退款"""
conn = self._get_connection()
try:
@@ -1825,7 +1884,12 @@ class SubscriptionManager:
# ==================== 支付提供商集成 ====================
def create_stripe_checkout_session(
self, tenant_id: str, plan_id: str, success_url: str, cancel_url: str, billing_cycle: str = "monthly"
self,
tenant_id: str,
plan_id: str,
success_url: str,
cancel_url: str,
billing_cycle: str = "monthly",
) -> dict[str, Any]:
"""创建 Stripe Checkout 会话(占位实现)"""
# 这里应该集成 Stripe SDK
@@ -1837,7 +1901,9 @@ class SubscriptionManager:
"provider": "stripe",
}
def create_alipay_order(self, tenant_id: str, plan_id: str, billing_cycle: str = "monthly") -> dict[str, Any]:
def create_alipay_order(
self, tenant_id: str, plan_id: str, billing_cycle: str = "monthly"
) -> dict[str, Any]:
"""创建支付宝订单(占位实现)"""
# 这里应该集成支付宝 SDK
plan = self.get_plan(plan_id)
@@ -1852,7 +1918,9 @@ class SubscriptionManager:
"provider": "alipay",
}
def create_wechat_order(self, tenant_id: str, plan_id: str, billing_cycle: str = "monthly") -> dict[str, Any]:
def create_wechat_order(
self, tenant_id: str, plan_id: str, billing_cycle: str = "monthly"
) -> dict[str, Any]:
"""创建微信支付订单(占位实现)"""
# 这里应该集成微信支付 SDK
plan = self.get_plan(plan_id)
@@ -1905,10 +1973,14 @@ class SubscriptionManager:
limits=json.loads(row["limits"] or "{}"),
is_active=bool(row["is_active"]),
created_at=(
datetime.fromisoformat(row["created_at"]) if isinstance(row["created_at"], str) else row["created_at"]
datetime.fromisoformat(row["created_at"])
if isinstance(row["created_at"], str)
else row["created_at"]
),
updated_at=(
datetime.fromisoformat(row["updated_at"]) if isinstance(row["updated_at"], str) else row["updated_at"]
datetime.fromisoformat(row["updated_at"])
if isinstance(row["updated_at"], str)
else row["updated_at"]
),
metadata=json.loads(row["metadata"] or "{}"),
)
@@ -1949,10 +2021,14 @@ class SubscriptionManager:
payment_provider=row["payment_provider"],
provider_subscription_id=row["provider_subscription_id"],
created_at=(
datetime.fromisoformat(row["created_at"]) if isinstance(row["created_at"], str) else row["created_at"]
datetime.fromisoformat(row["created_at"])
if isinstance(row["created_at"], str)
else row["created_at"]
),
updated_at=(
datetime.fromisoformat(row["updated_at"]) if isinstance(row["updated_at"], str) else row["updated_at"]
datetime.fromisoformat(row["updated_at"])
if isinstance(row["updated_at"], str)
else row["updated_at"]
),
metadata=json.loads(row["metadata"] or "{}"),
)
@@ -2001,10 +2077,14 @@ class SubscriptionManager:
),
failure_reason=row["failure_reason"],
created_at=(
datetime.fromisoformat(row["created_at"]) if isinstance(row["created_at"], str) else row["created_at"]
datetime.fromisoformat(row["created_at"])
if isinstance(row["created_at"], str)
else row["created_at"]
),
updated_at=(
datetime.fromisoformat(row["updated_at"]) if isinstance(row["updated_at"], str) else row["updated_at"]
datetime.fromisoformat(row["updated_at"])
if isinstance(row["updated_at"], str)
else row["updated_at"]
),
)
@@ -2048,10 +2128,14 @@ class SubscriptionManager:
),
void_reason=row["void_reason"],
created_at=(
datetime.fromisoformat(row["created_at"]) if isinstance(row["created_at"], str) else row["created_at"]
datetime.fromisoformat(row["created_at"])
if isinstance(row["created_at"], str)
else row["created_at"]
),
updated_at=(
datetime.fromisoformat(row["updated_at"]) if isinstance(row["updated_at"], str) else row["updated_at"]
datetime.fromisoformat(row["updated_at"])
if isinstance(row["updated_at"], str)
else row["updated_at"]
),
)
@@ -2086,10 +2170,14 @@ class SubscriptionManager:
provider_refund_id=row["provider_refund_id"],
metadata=json.loads(row["metadata"] or "{}"),
created_at=(
datetime.fromisoformat(row["created_at"]) if isinstance(row["created_at"], str) else row["created_at"]
datetime.fromisoformat(row["created_at"])
if isinstance(row["created_at"], str)
else row["created_at"]
),
updated_at=(
datetime.fromisoformat(row["updated_at"]) if isinstance(row["updated_at"], str) else row["updated_at"]
datetime.fromisoformat(row["updated_at"])
if isinstance(row["updated_at"], str)
else row["updated_at"]
),
)
@@ -2105,14 +2193,18 @@ class SubscriptionManager:
reference_id=row["reference_id"],
balance_after=row["balance_after"],
created_at=(
datetime.fromisoformat(row["created_at"]) if isinstance(row["created_at"], str) else row["created_at"]
datetime.fromisoformat(row["created_at"])
if isinstance(row["created_at"], str)
else row["created_at"]
),
metadata=json.loads(row["metadata"] or "{}"),
)
# 全局订阅管理器实例
subscription_manager = None
def get_subscription_manager(db_path: str = "insightflow.db") -> SubscriptionManager:
"""获取订阅管理器实例(单例模式)"""
global subscription_manager