Files
assist/src/web/blueprints/tenants.py

133 lines
4.6 KiB
Python
Raw Normal View History

# -*- coding: utf-8 -*-
"""
租户管理蓝图
处理租户 CRUD API 路由
"""
import json
import logging
from flask import Blueprint, request, jsonify
from src.core.database import db_manager
from src.core.models import Tenant, DEFAULT_TENANT
logger = logging.getLogger(__name__)
tenants_bp = Blueprint('tenants', __name__, url_prefix='/api/tenants')
def _ensure_default_tenant():
"""确保 default 租户存在"""
try:
with db_manager.get_session() as session:
existing = session.query(Tenant).filter(Tenant.tenant_id == DEFAULT_TENANT).first()
if not existing:
session.add(Tenant(
tenant_id=DEFAULT_TENANT,
name="默认租户",
description="系统默认租户"
))
session.commit()
except Exception as e:
logger.error(f"确保默认租户失败: {e}")
@tenants_bp.route('', methods=['GET'])
def list_tenants():
"""获取所有租户列表"""
try:
with db_manager.get_session() as session:
tenants = session.query(Tenant).order_by(Tenant.created_at).all()
return jsonify([t.to_dict() for t in tenants])
except Exception as e:
logger.error(f"获取租户列表失败: {e}")
return jsonify({"error": str(e)}), 500
@tenants_bp.route('', methods=['POST'])
def create_tenant():
"""创建新租户"""
try:
data = request.get_json()
if not data or not data.get('tenant_id') or not data.get('name'):
return jsonify({"error": "tenant_id 和 name 为必填项"}), 400
tenant_id = data['tenant_id'].strip()
name = data['name'].strip()
if not tenant_id or not name:
return jsonify({"error": "tenant_id 和 name 不能为空"}), 400
with db_manager.get_session() as session:
existing = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).first()
if existing:
return jsonify({"error": f"租户 '{tenant_id}' 已存在"}), 409
tenant = Tenant(
tenant_id=tenant_id,
name=name,
description=data.get('description', ''),
config=json.dumps(data.get('config', {}))
)
session.add(tenant)
session.commit()
# 重新查询以获取完整数据
tenant = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).first()
return jsonify({"success": True, "tenant": tenant.to_dict()}), 201
except Exception as e:
logger.error(f"创建租户失败: {e}")
return jsonify({"error": str(e)}), 500
@tenants_bp.route('/<tenant_id>', methods=['PUT'])
def update_tenant(tenant_id):
"""更新租户信息(重命名等)"""
try:
data = request.get_json()
if not data:
return jsonify({"error": "请求体不能为空"}), 400
with db_manager.get_session() as session:
tenant = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).first()
if not tenant:
return jsonify({"error": f"租户 '{tenant_id}' 不存在"}), 404
if 'name' in data:
tenant.name = data['name'].strip()
if 'description' in data:
tenant.description = data['description']
if 'config' in data:
tenant.config = json.dumps(data['config'])
if 'is_active' in data:
tenant.is_active = data['is_active']
session.commit()
tenant = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).first()
return jsonify({"success": True, "tenant": tenant.to_dict()})
except Exception as e:
logger.error(f"更新租户失败: {e}")
return jsonify({"error": str(e)}), 500
@tenants_bp.route('/<tenant_id>', methods=['DELETE'])
def delete_tenant(tenant_id):
"""删除租户(不允许删除 default"""
try:
if tenant_id == DEFAULT_TENANT:
return jsonify({"error": "不能删除默认租户"}), 403
with db_manager.get_session() as session:
tenant = session.query(Tenant).filter(Tenant.tenant_id == tenant_id).first()
if not tenant:
return jsonify({"error": f"租户 '{tenant_id}' 不存在"}), 404
session.delete(tenant)
session.commit()
return jsonify({"success": True, "message": f"租户 '{tenant_id}' 已删除"})
except Exception as e:
logger.error(f"删除租户失败: {e}")
return jsonify({"error": str(e)}), 500