refactor(services): 服务层适配用户隔离配置

- chat_service 从 department_id 改为 uid
- 优化 agent_config 解析和验证逻辑
- 更新 filesystem_service 和 workspace_service
This commit is contained in:
Wenjie Zhang 2026-05-18 09:40:46 +08:00
parent 4181604a71
commit 9fd2ebd69c
4 changed files with 19 additions and 30 deletions

View File

@ -68,7 +68,7 @@ async def create_agent_run_view(
config_repo = AgentConfigRepository(db) config_repo = AgentConfigRepository(db)
config_item = await config_repo.get_by_id(config_id=int(agent_config_id)) config_item = await config_repo.get_by_id(config_id=int(agent_config_id))
if config_item is None: if config_item is None or config_item.uid != str(current_uid):
raise HTTPException(status_code=404, detail="配置不存在") raise HTTPException(status_code=404, detail="配置不存在")
agent_id = config_item.agent_id agent_id = config_item.agent_id

View File

@ -419,11 +419,11 @@ def _extract_ai_message(messages: list[Any] | None) -> AIMessage | None:
async def get_agent_config_by_id(db, user: User, agent_config_id: int): async def get_agent_config_by_id(db, user: User, agent_config_id: int):
"""按配置 ID 解析 AgentConfig 记录。""" """按配置 ID 解析 AgentConfig 记录。"""
department_id = user.department_id uid = str(user.uid)
agent_config_repo = AgentConfigRepository(db) agent_config_repo = AgentConfigRepository(db)
config_item = await agent_config_repo.get_by_id(config_id=int(agent_config_id)) config_item = await agent_config_repo.get_by_id(config_id=int(agent_config_id))
if config_item is None or config_item.department_id != department_id: if config_item is None or config_item.uid != uid:
raise ValueError("配置不存在") raise ValueError("配置不存在")
return config_item return config_item
@ -431,7 +431,7 @@ async def get_agent_config_by_id(db, user: User, agent_config_id: int):
async def _resolve_agent_config(db, agent_id: str, user: User, agent_config_id): async def _resolve_agent_config(db, agent_id: str, user: User, agent_config_id):
"""解析 agent_config返回 agent_config""" """解析 agent_config返回 agent_config"""
department_id = user.department_id uid = str(user.uid)
agent_config_repo = AgentConfigRepository(db) agent_config_repo = AgentConfigRepository(db)
config_item = None config_item = None
@ -441,9 +441,7 @@ async def _resolve_agent_config(db, agent_id: str, user: User, agent_config_id):
config_item = None config_item = None
if config_item is None: if config_item is None:
config_item = await agent_config_repo.get_or_create_default( config_item = await agent_config_repo.get_or_create_default(uid=uid, agent_id=agent_id, created_by=uid)
department_id=department_id, agent_id=agent_id, created_by=str(user.id)
)
return (config_item.config_json or {}).get("context", {}) return (config_item.config_json or {}).get("context", {})
@ -479,7 +477,6 @@ async def _ensure_thread_bound_agent_config(
agent_config_repo: AgentConfigRepository, agent_config_repo: AgentConfigRepository,
thread_id: str, thread_id: str,
uid: str, uid: str,
department_id: int,
agent_id: str, agent_id: str,
agent_config_id: int, agent_config_id: int,
) -> None: ) -> None:
@ -502,13 +499,21 @@ async def _ensure_thread_bound_agent_config(
f"switching to default config for agent {agent_id}" f"switching to default config for agent {agent_id}"
) )
default_config = await agent_config_repo.get_or_create_default( default_config = await agent_config_repo.get_or_create_default(
department_id=department_id, uid=uid,
agent_id=agent_id, agent_id=agent_id,
created_by=uid, created_by=uid,
) )
await conv_repo.bind_agent_config(thread_id, default_config.id) await conv_repo.bind_agent_config(thread_id, default_config.id)
else: else:
await conv_repo.bind_agent_config(thread_id, agent_config_id) if config_item.uid != uid or config_item.agent_id != agent_id:
default_config = await agent_config_repo.get_or_create_default(
uid=uid,
agent_id=agent_id,
created_by=uid,
)
await conv_repo.bind_agent_config(thread_id, default_config.id)
else:
await conv_repo.bind_agent_config(thread_id, agent_config_id)
async def agent_chat( async def agent_chat(
@ -544,14 +549,6 @@ async def agent_chat(
"request_id": meta.get("request_id"), "request_id": meta.get("request_id"),
} }
if not current_user.department_id:
return {
"status": "error",
"error_type": "invalid_config",
"error_message": "当前用户未绑定部门",
"request_id": meta.get("request_id"),
}
uid = str(current_user.uid) uid = str(current_user.uid)
meta = dict(meta or {}) meta = dict(meta or {})
if "request_id" not in meta or not meta.get("request_id"): if "request_id" not in meta or not meta.get("request_id"):
@ -618,7 +615,6 @@ async def agent_chat(
agent_config_repo=agent_config_repo, agent_config_repo=agent_config_repo,
thread_id=thread_id, thread_id=thread_id,
uid=uid, uid=uid,
department_id=current_user.department_id,
agent_id=agent_id, agent_id=agent_id,
agent_config_id=agent_config_id, agent_config_id=agent_config_id,
) )
@ -767,10 +763,6 @@ async def stream_agent_chat(
) )
return return
if not current_user.department_id:
yield make_chunk(status="error", error_type="invalid_config", error_message="当前用户未绑定部门", meta=meta)
return
meta = dict(meta or {}) meta = dict(meta or {})
if "request_id" not in meta or not meta.get("request_id"): if "request_id" not in meta or not meta.get("request_id"):
logger.warning("请求缺少 request_id已自动生成一个新的 request_id") logger.warning("请求缺少 request_id已自动生成一个新的 request_id")
@ -837,7 +829,6 @@ async def stream_agent_chat(
agent_config_repo=agent_config_repo, agent_config_repo=agent_config_repo,
thread_id=thread_id, thread_id=thread_id,
uid=uid, uid=uid,
department_id=current_user.department_id,
agent_id=agent_id, agent_id=agent_id,
agent_config_id=agent_config_id, agent_config_id=agent_config_id,
) )

View File

@ -30,16 +30,14 @@ async def _resolve_filesystem_context(
config_item = None config_item = None
if agent_config_id is not None: if agent_config_id is not None:
config_item = await repo.get_by_id(config_id=int(agent_config_id)) config_item = await repo.get_by_id(config_id=int(agent_config_id))
if config_item is not None and ( if config_item is not None and (config_item.uid != str(user.uid) or config_item.agent_id != agent_id):
config_item.department_id != user.department_id or config_item.agent_id != agent_id
):
config_item = None config_item = None
if config_item is None: if config_item is None:
config_item = await repo.get_or_create_default( config_item = await repo.get_or_create_default(
department_id=user.department_id, uid=str(user.uid),
agent_id=agent_id, agent_id=agent_id,
created_by=str(user.id), created_by=str(user.uid),
) )
context.update_from_dict((config_item.config_json or {}).get("context", {})) context.update_from_dict((config_item.config_json or {}).get("context", {}))

View File

@ -24,7 +24,7 @@ MAX_WORKSPACE_UPLOAD_SIZE_BYTES = 100 * 1024 * 1024
def _workspace_root(user: User) -> Path: def _workspace_root(user: User) -> Path:
try: try:
user_data_root = _global_user_data_dir(str(user.id)).resolve() user_data_root = _global_user_data_dir(str(user.uid)).resolve()
root = user_data_root / WORKSPACE_DIR_NAME root = user_data_root / WORKSPACE_DIR_NAME
except ValueError as exc: except ValueError as exc:
raise HTTPException(status_code=403, detail="Access denied") from exc raise HTTPException(status_code=403, detail="Access denied") from exc