fix(admin): 行业选择500修复 + 管理员切换订阅计划
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- fix(industry): list_industries SQL参数编号错位 — count查询和items查询 共用WHERE子句但参数从$3开始,sqlx bind按$1/$2顺序绑定导致500 - feat(billing): 新增 PUT /admin/accounts/:id/subscription 端点 (super_admin) 验证目标计划 → 取消当前订阅 → 创建新订阅(30天) → 同步配额 - feat(admin-v2): Accounts.tsx 编辑弹窗新增「订阅计划」选择区 显示所有活跃计划,保存时调用admin switch plan API
This commit is contained in:
@@ -7,6 +7,7 @@ use axum::{
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::auth::types::AuthContext;
|
||||
use crate::auth::handlers::{log_operation, check_permission};
|
||||
use crate::error::{SaasError, SaasResult};
|
||||
use crate::state::AppState;
|
||||
use super::service;
|
||||
@@ -115,6 +116,41 @@ pub async fn increment_usage_dimension(
|
||||
})))
|
||||
}
|
||||
|
||||
/// POST /api/v1/billing/payments — 创建支付订单
|
||||
|
||||
/// PUT /api/v1/admin/accounts/:id/subscription — 管理员切换用户订阅计划(仅 super_admin)
|
||||
pub async fn admin_switch_subscription(
|
||||
State(state): State<AppState>,
|
||||
Extension(ctx): Extension<AuthContext>,
|
||||
Path(account_id): Path<String>,
|
||||
Json(req): Json<AdminSwitchPlanRequest>,
|
||||
) -> SaasResult<Json<serde_json::Value>> {
|
||||
// 仅 super_admin 可操作
|
||||
check_permission(&ctx, "admin:full")?;
|
||||
|
||||
// 验证 plan_id 非空
|
||||
if req.plan_id.trim().is_empty() {
|
||||
return Err(SaasError::InvalidInput("plan_id 不能为空".into()));
|
||||
}
|
||||
|
||||
let sub = service::admin_switch_plan(&state.db, &account_id, &req.plan_id).await?;
|
||||
|
||||
log_operation(
|
||||
&state.db,
|
||||
&ctx.account_id,
|
||||
"billing.admin_switch_plan",
|
||||
"account",
|
||||
&account_id,
|
||||
Some(serde_json::json!({ "plan_id": req.plan_id })),
|
||||
None,
|
||||
).await.ok(); // 日志失败不影响主流程
|
||||
|
||||
Ok(Json(serde_json::json!({
|
||||
"success": true,
|
||||
"subscription": sub,
|
||||
})))
|
||||
}
|
||||
|
||||
/// POST /api/v1/billing/payments — 创建支付订单
|
||||
pub async fn create_payment(
|
||||
State(state): State<AppState>,
|
||||
|
||||
Reference in New Issue
Block a user