Merge pull request #686 from SuanmoSuanyangTechnology/feature/user-alias
Feature/user alias
This commit is contained in:
71
api/app/repositories/end_user_info_repository.py
Normal file
71
api/app/repositories/end_user_info_repository.py
Normal file
@@ -0,0 +1,71 @@
|
||||
"""
|
||||
终端用户信息仓储层
|
||||
"""
|
||||
import uuid
|
||||
from typing import List, Optional
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.models.end_user_info_model import EndUserInfo
|
||||
from app.core.logging_config import get_logger
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
class EndUserInfoRepository:
|
||||
"""终端用户信息仓储类"""
|
||||
|
||||
def __init__(self, db: Session):
|
||||
self.db = db
|
||||
|
||||
def create(self, end_user_id: uuid.UUID, other_name: str, aliases: List[str] = None, meta_data: dict = None) -> EndUserInfo:
|
||||
"""创建终端用户信息"""
|
||||
end_user_info = EndUserInfo(
|
||||
end_user_id=end_user_id,
|
||||
other_name=other_name,
|
||||
aliases=aliases or [],
|
||||
meta_data=meta_data
|
||||
)
|
||||
self.db.add(end_user_info)
|
||||
self.db.commit()
|
||||
self.db.refresh(end_user_info)
|
||||
logger.info(f"创建终端用户信息: end_user_id={end_user_id}, aliases={aliases}")
|
||||
return end_user_info
|
||||
|
||||
def get_by_id(self, info_id: uuid.UUID) -> Optional[EndUserInfo]:
|
||||
"""根据ID获取用户信息"""
|
||||
return self.db.query(EndUserInfo).filter(EndUserInfo.id == info_id).first()
|
||||
|
||||
|
||||
def get_by_end_user_id(self, end_user_id: uuid.UUID) -> Optional[EndUserInfo]:
|
||||
"""获取用户的信息记录"""
|
||||
return self.db.query(EndUserInfo).filter(EndUserInfo.end_user_id == end_user_id).first()
|
||||
|
||||
def update(self, info_id: uuid.UUID, aliases: List[str] = None, meta_data: dict = None) -> Optional[EndUserInfo]:
|
||||
"""更新用户信息"""
|
||||
end_user_info = self.get_by_id(info_id)
|
||||
if end_user_info:
|
||||
if aliases is not None:
|
||||
end_user_info.aliases = aliases
|
||||
if meta_data is not None:
|
||||
end_user_info.meta_data = meta_data
|
||||
self.db.commit()
|
||||
self.db.refresh(end_user_info)
|
||||
logger.info(f"更新终端用户信息: info_id={info_id}")
|
||||
return end_user_info
|
||||
|
||||
def delete(self, info_id: uuid.UUID) -> bool:
|
||||
"""删除用户信息"""
|
||||
end_user_info = self.get_by_id(info_id)
|
||||
if end_user_info:
|
||||
self.db.delete(end_user_info)
|
||||
self.db.commit()
|
||||
logger.info(f"删除终端用户信息: info_id={info_id}")
|
||||
return True
|
||||
return False
|
||||
|
||||
def delete_by_end_user_id(self, end_user_id: uuid.UUID) -> int:
|
||||
"""删除用户的所有信息记录"""
|
||||
count = self.db.query(EndUserInfo).filter(EndUserInfo.end_user_id == end_user_id).delete()
|
||||
self.db.commit()
|
||||
logger.info(f"删除用户所有信息记录: end_user_id={end_user_id}, count={count}")
|
||||
return count
|
||||
@@ -7,6 +7,7 @@ from sqlalchemy.orm import Session
|
||||
from app.core.logging_config import get_db_logger
|
||||
from app.models.app_model import App
|
||||
from app.models.end_user_model import EndUser
|
||||
from app.models.end_user_info_model import EndUserInfo
|
||||
from app.models.workspace_model import Workspace
|
||||
|
||||
# 获取数据库专用日志器
|
||||
@@ -70,7 +71,8 @@ class EndUserRepository:
|
||||
app_id: uuid.UUID,
|
||||
workspace_id: uuid.UUID,
|
||||
other_id: str,
|
||||
original_user_id: Optional[str] = None
|
||||
original_user_id: Optional[str] = None,
|
||||
other_name: Optional[str] = None
|
||||
) -> EndUser:
|
||||
"""获取或创建终端用户
|
||||
|
||||
@@ -79,6 +81,7 @@ class EndUserRepository:
|
||||
workspace_id: 工作空间ID
|
||||
other_id: 第三方ID
|
||||
original_user_id: 原始用户ID (存储到 other_id)
|
||||
other_name: 用户名称(用于创建 EndUserInfo)
|
||||
"""
|
||||
try:
|
||||
# 尝试查找现有用户
|
||||
@@ -106,10 +109,22 @@ class EndUserRepository:
|
||||
other_id=other_id
|
||||
)
|
||||
self.db.add(end_user)
|
||||
self.db.flush() # 刷新以获取 end_user.id,但不提交事务
|
||||
|
||||
# 创建对应的 EndUserInfo 记录
|
||||
end_user_info = EndUserInfo(
|
||||
end_user_id=end_user.id,
|
||||
other_name=other_name or "", # 如果没有提供 other_name,使用空字符串
|
||||
aliases=[],
|
||||
meta_data={}
|
||||
)
|
||||
self.db.add(end_user_info)
|
||||
|
||||
# 一起提交
|
||||
self.db.commit()
|
||||
self.db.refresh(end_user)
|
||||
|
||||
db_logger.info(f"创建新终端用户: (other_id: {other_id}) for workspace {workspace_id}")
|
||||
db_logger.info(f"创建新终端用户及其信息: (other_id: {other_id}) for workspace {workspace_id}")
|
||||
return end_user
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -336,6 +336,48 @@ ORDER BY score DESC
|
||||
LIMIT $limit
|
||||
"""
|
||||
|
||||
SEARCH_ENTITIES_BY_NAME_OR_ALIAS = """
|
||||
CALL db.index.fulltext.queryNodes("entitiesFulltext", $q) YIELD node AS e, score
|
||||
WHERE ($end_user_id IS NULL OR e.end_user_id = $end_user_id)
|
||||
WITH e, score
|
||||
UNION
|
||||
MATCH (e:ExtractedEntity)
|
||||
WHERE ($end_user_id IS NULL OR e.end_user_id = $end_user_id)
|
||||
AND e.aliases IS NOT NULL
|
||||
AND ANY(alias IN e.aliases WHERE toLower(alias) CONTAINS toLower($q))
|
||||
WITH e,
|
||||
CASE
|
||||
WHEN ANY(alias IN e.aliases WHERE toLower(alias) = toLower($q)) THEN 1.0
|
||||
WHEN ANY(alias IN e.aliases WHERE toLower(alias) STARTS WITH toLower($q)) THEN 0.9
|
||||
ELSE 0.8
|
||||
END AS score
|
||||
WITH DISTINCT e, MAX(score) AS score
|
||||
OPTIONAL MATCH (s:Statement)-[:REFERENCES_ENTITY]->(e)
|
||||
OPTIONAL MATCH (c:Chunk)-[:CONTAINS]->(s)
|
||||
RETURN e.id AS id,
|
||||
e.name AS name,
|
||||
e.end_user_id AS end_user_id,
|
||||
e.entity_type AS entity_type,
|
||||
e.created_at AS created_at,
|
||||
e.expired_at AS expired_at,
|
||||
e.entity_idx AS entity_idx,
|
||||
e.statement_id AS statement_id,
|
||||
e.description AS description,
|
||||
e.aliases AS aliases,
|
||||
e.name_embedding AS name_embedding,
|
||||
e.connect_strength AS connect_strength,
|
||||
collect(DISTINCT s.id) AS statement_ids,
|
||||
collect(DISTINCT c.id) AS chunk_ids,
|
||||
COALESCE(e.activation_value, e.importance_score, 0.5) AS activation_value,
|
||||
COALESCE(e.importance_score, 0.5) AS importance_score,
|
||||
e.last_access_time AS last_access_time,
|
||||
COALESCE(e.access_count, 0) AS access_count,
|
||||
score
|
||||
ORDER BY score DESC
|
||||
LIMIT $limit
|
||||
"""
|
||||
|
||||
|
||||
SEARCH_CHUNKS_BY_CONTENT = """
|
||||
CALL db.index.fulltext.queryNodes("chunksFulltext", $q) YIELD node AS c, score
|
||||
WHERE ($end_user_id IS NULL OR c.end_user_id = $end_user_id)
|
||||
|
||||
@@ -13,6 +13,7 @@ from app.repositories.neo4j.cypher_queries import (
|
||||
SEARCH_COMMUNITIES_BY_KEYWORD,
|
||||
SEARCH_DIALOGUE_BY_DIALOG_ID,
|
||||
SEARCH_ENTITIES_BY_NAME,
|
||||
SEARCH_ENTITIES_BY_NAME_OR_ALIAS,
|
||||
SEARCH_MEMORY_SUMMARIES_BY_KEYWORD,
|
||||
SEARCH_STATEMENTS_BY_CREATED_AT,
|
||||
SEARCH_STATEMENTS_BY_KEYWORD,
|
||||
@@ -264,7 +265,7 @@ async def search_graph(
|
||||
|
||||
if "entities" in include:
|
||||
tasks.append(connector.execute_query(
|
||||
SEARCH_ENTITIES_BY_NAME,
|
||||
SEARCH_ENTITIES_BY_NAME_OR_ALIAS,
|
||||
q=q,
|
||||
end_user_id=end_user_id,
|
||||
limit=limit,
|
||||
|
||||
Reference in New Issue
Block a user