fix: 恢复租户应用订阅的自定义配置功能
All checks were successful
continuous-integration/drone/push Build is passing

定时任务提交(104487f)误删了 custom_configs 相关代码,现恢复:
- backend/app/models/tenant_app.py: 恢复 custom_configs 数据库字段
- backend/app/routers/tenant_apps.py: 恢复 CustomConfigItem、custom_configs 逻辑、get_token API
This commit is contained in:
2026-01-29 17:47:57 +08:00
parent 830361073b
commit c1ba17f809
2 changed files with 44 additions and 0 deletions

View File

@@ -23,6 +23,10 @@ class TenantApp(Base):
# 功能权限 # 功能权限
allowed_tools = Column(Text) # JSON 数组 allowed_tools = Column(Text) # JSON 数组
# 自定义配置JSON 数组)
# [{"key": "industry", "value": "medical_beauty", "remark": "医美行业"}, ...]
custom_configs = Column(Text)
status = Column(SmallInteger, default=1) status = Column(SmallInteger, default=1)
created_at = Column(TIMESTAMP, default=datetime.now) created_at = Column(TIMESTAMP, default=datetime.now)
updated_at = Column(TIMESTAMP, default=datetime.now, onupdate=datetime.now) updated_at = Column(TIMESTAMP, default=datetime.now, onupdate=datetime.now)

View File

@@ -17,6 +17,13 @@ router = APIRouter(prefix="/tenant-apps", tags=["应用配置"])
# Schemas # Schemas
class CustomConfigItem(BaseModel):
"""自定义配置项"""
key: str # 配置键
value: str # 配置值
remark: Optional[str] = None # 备注说明
class TenantAppCreate(BaseModel): class TenantAppCreate(BaseModel):
tenant_id: str tenant_id: str
app_code: str = "tools" app_code: str = "tools"
@@ -25,6 +32,7 @@ class TenantAppCreate(BaseModel):
access_token: Optional[str] = None # 如果不传则自动生成 access_token: Optional[str] = None # 如果不传则自动生成
allowed_origins: Optional[List[str]] = None allowed_origins: Optional[List[str]] = None
allowed_tools: Optional[List[str]] = None allowed_tools: Optional[List[str]] = None
custom_configs: Optional[List[CustomConfigItem]] = None # 自定义配置
class TenantAppUpdate(BaseModel): class TenantAppUpdate(BaseModel):
@@ -33,6 +41,7 @@ class TenantAppUpdate(BaseModel):
access_token: Optional[str] = None access_token: Optional[str] = None
allowed_origins: Optional[List[str]] = None allowed_origins: Optional[List[str]] = None
allowed_tools: Optional[List[str]] = None allowed_tools: Optional[List[str]] = None
custom_configs: Optional[List[CustomConfigItem]] = None # 自定义配置
status: Optional[int] = None status: Optional[int] = None
@@ -111,6 +120,7 @@ async def create_tenant_app(
access_token=access_token, access_token=access_token,
allowed_origins=json.dumps(data.allowed_origins) if data.allowed_origins else None, allowed_origins=json.dumps(data.allowed_origins) if data.allowed_origins else None,
allowed_tools=json.dumps(data.allowed_tools) if data.allowed_tools else None, allowed_tools=json.dumps(data.allowed_tools) if data.allowed_tools else None,
custom_configs=json.dumps([c.model_dump() for c in data.custom_configs], ensure_ascii=False) if data.custom_configs else None,
status=1 status=1
) )
db.add(app) db.add(app)
@@ -139,6 +149,14 @@ async def update_tenant_app(
update_data['allowed_origins'] = json.dumps(update_data['allowed_origins']) if update_data['allowed_origins'] else None update_data['allowed_origins'] = json.dumps(update_data['allowed_origins']) if update_data['allowed_origins'] else None
if 'allowed_tools' in update_data: if 'allowed_tools' in update_data:
update_data['allowed_tools'] = json.dumps(update_data['allowed_tools']) if update_data['allowed_tools'] else None update_data['allowed_tools'] = json.dumps(update_data['allowed_tools']) if update_data['allowed_tools'] else None
if 'custom_configs' in update_data:
if update_data['custom_configs']:
update_data['custom_configs'] = json.dumps(
[c.model_dump() if hasattr(c, 'model_dump') else c for c in update_data['custom_configs']],
ensure_ascii=False
)
else:
update_data['custom_configs'] = None
for key, value in update_data.items(): for key, value in update_data.items():
setattr(app, key, value) setattr(app, key, value)
@@ -164,6 +182,27 @@ async def delete_tenant_app(
return {"success": True} return {"success": True}
@router.get("/{app_id}/token")
async def get_token(
app_id: int,
user: User = Depends(require_operator),
db: Session = Depends(get_db)
):
"""获取真实的 access_token仅管理员可用"""
app = db.query(TenantApp).filter(TenantApp.id == app_id).first()
if not app:
raise HTTPException(status_code=404, detail="应用配置不存在")
# 获取应用的 base_url
app_info = db.query(App).filter(App.app_code == app.app_code).first()
base_url = app_info.base_url if app_info else ""
return {
"access_token": app.access_token,
"base_url": base_url
}
@router.post("/{app_id}/regenerate-token") @router.post("/{app_id}/regenerate-token")
async def regenerate_token( async def regenerate_token(
app_id: int, app_id: int,
@@ -207,6 +246,7 @@ def format_tenant_app(app: TenantApp, mask_secret: bool = True, db: Session = No
"access_token": "******" if mask_secret and app.access_token else app.access_token, "access_token": "******" if mask_secret and app.access_token else app.access_token,
"allowed_origins": json.loads(app.allowed_origins) if app.allowed_origins else [], "allowed_origins": json.loads(app.allowed_origins) if app.allowed_origins else [],
"allowed_tools": json.loads(app.allowed_tools) if app.allowed_tools else [], "allowed_tools": json.loads(app.allowed_tools) if app.allowed_tools else [],
"custom_configs": json.loads(app.custom_configs) if app.custom_configs else [],
"status": app.status, "status": app.status,
"created_at": app.created_at, "created_at": app.created_at,
"updated_at": app.updated_at "updated_at": app.updated_at