- 后端: App 模型添加 config_schema 字段,支持配置项定义 - 后端: apps API 支持 config_schema 的增删改查 - 前端: 应用管理页面支持定义配置项(text/radio/select/switch类型) - 前端: 租户订阅页面根据应用 schema 动态渲染对应表单控件 - 支持设置选项、默认值、必填等属性
This commit is contained in:
@@ -18,6 +18,11 @@ class App(Base):
|
||||
# [{"code": "brainstorm", "name": "头脑风暴", "path": "/brainstorm"}, ...]
|
||||
tools = Column(Text)
|
||||
|
||||
# 配置项定义(JSON 数组)- 定义租户可配置的参数
|
||||
# [{"key": "industry", "label": "行业类型", "type": "radio", "options": [...], "default": "...", "required": false}, ...]
|
||||
# type: text(文本) | radio(单选) | select(下拉多选) | switch(开关)
|
||||
config_schema = Column(Text)
|
||||
|
||||
# 是否需要企微JS-SDK
|
||||
require_jssdk = Column(SmallInteger, default=0) # 0-不需要 1-需要
|
||||
|
||||
|
||||
@@ -23,6 +23,18 @@ class ToolItem(BaseModel):
|
||||
path: str
|
||||
|
||||
|
||||
class ConfigSchemaItem(BaseModel):
|
||||
"""配置项定义"""
|
||||
key: str # 配置键
|
||||
label: str # 显示标签
|
||||
type: str # text | radio | select | switch
|
||||
options: Optional[List[str]] = None # radio/select 的选项值
|
||||
option_labels: Optional[dict] = None # 选项显示名称 {"value": "显示名"}
|
||||
default: Optional[str] = None # 默认值
|
||||
placeholder: Optional[str] = None # 输入提示(text类型)
|
||||
required: bool = False # 是否必填
|
||||
|
||||
|
||||
class AppCreate(BaseModel):
|
||||
"""创建应用"""
|
||||
app_code: str
|
||||
@@ -30,6 +42,7 @@ class AppCreate(BaseModel):
|
||||
base_url: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
tools: Optional[List[ToolItem]] = None
|
||||
config_schema: Optional[List[ConfigSchemaItem]] = None
|
||||
require_jssdk: bool = False
|
||||
|
||||
|
||||
@@ -39,6 +52,7 @@ class AppUpdate(BaseModel):
|
||||
base_url: Optional[str] = None
|
||||
description: Optional[str] = None
|
||||
tools: Optional[List[ToolItem]] = None
|
||||
config_schema: Optional[List[ConfigSchemaItem]] = None
|
||||
require_jssdk: Optional[bool] = None
|
||||
status: Optional[int] = None
|
||||
|
||||
@@ -119,6 +133,7 @@ async def create_app(
|
||||
base_url=data.base_url,
|
||||
description=data.description,
|
||||
tools=json.dumps([t.model_dump() for t in data.tools], ensure_ascii=False) if data.tools else None,
|
||||
config_schema=json.dumps([c.model_dump() for c in data.config_schema], ensure_ascii=False) if data.config_schema else None,
|
||||
require_jssdk=1 if data.require_jssdk else 0,
|
||||
status=1
|
||||
)
|
||||
@@ -150,6 +165,13 @@ async def update_app(
|
||||
else:
|
||||
update_data['tools'] = None
|
||||
|
||||
# 处理 config_schema JSON
|
||||
if 'config_schema' in update_data:
|
||||
if update_data['config_schema']:
|
||||
update_data['config_schema'] = json.dumps([c.model_dump() if hasattr(c, 'model_dump') else c for c in update_data['config_schema']], ensure_ascii=False)
|
||||
else:
|
||||
update_data['config_schema'] = None
|
||||
|
||||
# 处理 require_jssdk
|
||||
if 'require_jssdk' in update_data:
|
||||
update_data['require_jssdk'] = 1 if update_data['require_jssdk'] else 0
|
||||
@@ -259,6 +281,21 @@ async def get_app_tools(
|
||||
return tools
|
||||
|
||||
|
||||
@router.get("/{app_code}/config-schema")
|
||||
async def get_app_config_schema(
|
||||
app_code: str,
|
||||
user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""获取应用的配置项定义(用于租户订阅时渲染表单)"""
|
||||
app = db.query(App).filter(App.app_code == app_code).first()
|
||||
if not app:
|
||||
raise HTTPException(status_code=404, detail="应用不存在")
|
||||
|
||||
config_schema = json.loads(app.config_schema) if app.config_schema else []
|
||||
return config_schema
|
||||
|
||||
|
||||
def format_app(app: App) -> dict:
|
||||
"""格式化应用数据"""
|
||||
return {
|
||||
@@ -268,6 +305,7 @@ def format_app(app: App) -> dict:
|
||||
"base_url": app.base_url,
|
||||
"description": app.description,
|
||||
"tools": json.loads(app.tools) if app.tools else [],
|
||||
"config_schema": json.loads(app.config_schema) if app.config_schema else [],
|
||||
"require_jssdk": bool(app.require_jssdk),
|
||||
"status": app.status,
|
||||
"created_at": app.created_at,
|
||||
|
||||
Reference in New Issue
Block a user