|
@@ -1432,4 +1432,247 @@ def query_neo4j_graph(query_requirement):
|
|
|
'success': False,
|
|
|
'message': error_msg,
|
|
|
'data': []
|
|
|
+ }
|
|
|
+
|
|
|
+def talent_get_tags(talent_id):
|
|
|
+ """
|
|
|
+ 根据talent ID获取人才节点关联的标签
|
|
|
+
|
|
|
+ Args:
|
|
|
+ talent_id (int): 人才节点ID
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ dict: 包含人才ID和关联标签的字典,JSON格式
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ # 导入必要的模块
|
|
|
+ from app.services.neo4j_driver import neo4j_driver
|
|
|
+
|
|
|
+ # 准备查询返回数据
|
|
|
+ response_data = {
|
|
|
+ 'code': 200,
|
|
|
+ 'success': True,
|
|
|
+ 'message': '获取人才标签成功',
|
|
|
+ 'data': []
|
|
|
+ }
|
|
|
+
|
|
|
+ # 构建Cypher查询语句,获取人才节点关联的标签
|
|
|
+ cypher_query = """
|
|
|
+ MATCH (t:talent)-[r:BELONGS_TO]->(tag:talent_tag)
|
|
|
+ WHERE id(t) = $talent_id
|
|
|
+ RETURN id(t) as talent_id, tag.name as tag_name
|
|
|
+ """
|
|
|
+
|
|
|
+ # 执行查询
|
|
|
+ with neo4j_driver.get_session() as session:
|
|
|
+ result = session.run(cypher_query, talent_id=int(talent_id))
|
|
|
+ records = list(result)
|
|
|
+
|
|
|
+ # 如果没有查询到标签,返回空数组
|
|
|
+ if not records:
|
|
|
+ response_data['message'] = f'人才ID {talent_id} 没有关联的标签'
|
|
|
+ return response_data
|
|
|
+
|
|
|
+ # 处理查询结果
|
|
|
+ for record in records:
|
|
|
+ talent_tag = {
|
|
|
+ 'talent': record['talent_id'],
|
|
|
+ 'tag': record['tag_name']
|
|
|
+ }
|
|
|
+ response_data['data'].append(talent_tag)
|
|
|
+
|
|
|
+ return response_data
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ error_msg = f"获取人才标签失败: {str(e)}"
|
|
|
+ logging.error(error_msg, exc_info=True)
|
|
|
+
|
|
|
+ return {
|
|
|
+ 'code': 500,
|
|
|
+ 'success': False,
|
|
|
+ 'message': error_msg,
|
|
|
+ 'data': []
|
|
|
+ }
|
|
|
+
|
|
|
+def talent_update_tags(data):
|
|
|
+ """
|
|
|
+ 根据传入的JSON数据为人才节点创建与标签的BELONGS_TO关系
|
|
|
+
|
|
|
+ Args:
|
|
|
+ data (list): 包含talent和tag字段的对象列表
|
|
|
+ 例如: [
|
|
|
+ {"talent": 12345, "tag": "市场营销"},
|
|
|
+ {"talent": 12345, "tag": "酒店管理"}
|
|
|
+ ]
|
|
|
+
|
|
|
+ Returns:
|
|
|
+ dict: 操作结果和状态信息
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ # 导入必要的模块
|
|
|
+ from app.services.neo4j_driver import neo4j_driver
|
|
|
+
|
|
|
+ # 验证输入参数
|
|
|
+ if not isinstance(data, list):
|
|
|
+ return {
|
|
|
+ 'code': 400,
|
|
|
+ 'success': False,
|
|
|
+ 'message': '参数格式错误,需要JSON数组',
|
|
|
+ 'data': None
|
|
|
+ }
|
|
|
+
|
|
|
+ if len(data) == 0:
|
|
|
+ return {
|
|
|
+ 'code': 400,
|
|
|
+ 'success': False,
|
|
|
+ 'message': '数据列表为空',
|
|
|
+ 'data': None
|
|
|
+ }
|
|
|
+
|
|
|
+ # 获取当前时间
|
|
|
+ current_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
|
|
+
|
|
|
+ # 成功和失败计数
|
|
|
+ success_count = 0
|
|
|
+ failed_items = []
|
|
|
+
|
|
|
+ # 按talent分组处理数据
|
|
|
+ talent_tags = {}
|
|
|
+ for item in data:
|
|
|
+ # 验证每个项目的格式
|
|
|
+ if not isinstance(item, dict) or 'talent' not in item or 'tag' not in item:
|
|
|
+ failed_items.append(item)
|
|
|
+ continue
|
|
|
+
|
|
|
+ talent_id = item.get('talent')
|
|
|
+ tag_name = item.get('tag')
|
|
|
+
|
|
|
+ # 验证talent_id和tag_name的值
|
|
|
+ if not talent_id or not tag_name or not isinstance(tag_name, str):
|
|
|
+ failed_items.append(item)
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 按talent_id分组
|
|
|
+ if talent_id not in talent_tags:
|
|
|
+ talent_tags[talent_id] = []
|
|
|
+
|
|
|
+ talent_tags[talent_id].append(tag_name)
|
|
|
+
|
|
|
+ with neo4j_driver.get_session() as session:
|
|
|
+ # 处理每个talent及其标签
|
|
|
+ for talent_id, tags in talent_tags.items():
|
|
|
+ # 首先验证talent节点是否存在
|
|
|
+ check_talent_query = """
|
|
|
+ MATCH (t:talent)
|
|
|
+ WHERE id(t) = $talent_id
|
|
|
+ RETURN t
|
|
|
+ """
|
|
|
+ talent_result = session.run(check_talent_query, talent_id=int(talent_id))
|
|
|
+ if not talent_result.single():
|
|
|
+ # 该talent不存在,记录失败项并继续下一个talent
|
|
|
+ for tag in tags:
|
|
|
+ failed_items.append({'talent': talent_id, 'tag': tag})
|
|
|
+ continue
|
|
|
+
|
|
|
+ # 处理每个标签
|
|
|
+ for tag_name in tags:
|
|
|
+ try:
|
|
|
+ # 1. 查找或创建标签节点
|
|
|
+ # 先查找是否存在该标签
|
|
|
+ find_tag_query = """
|
|
|
+ MATCH (tag:talent_tag)
|
|
|
+ WHERE tag.name = $tag_name
|
|
|
+ RETURN id(tag) as tag_id
|
|
|
+ """
|
|
|
+ tag_result = session.run(find_tag_query, tag_name=tag_name)
|
|
|
+ tag_record = tag_result.single()
|
|
|
+
|
|
|
+ if tag_record:
|
|
|
+ tag_id = tag_record['tag_id']
|
|
|
+ else:
|
|
|
+ # 创建新标签
|
|
|
+ create_tag_query = """
|
|
|
+ CREATE (tag:talent_tag {name: $name, category: $category, updated_at: $updated_at})
|
|
|
+ RETURN id(tag) as tag_id
|
|
|
+ """
|
|
|
+ tag_result = session.run(
|
|
|
+ create_tag_query,
|
|
|
+ name=tag_name,
|
|
|
+ category='talent',
|
|
|
+ updated_at=current_time
|
|
|
+ )
|
|
|
+ tag_record = tag_result.single()
|
|
|
+ tag_id = tag_record['tag_id']
|
|
|
+
|
|
|
+ # 2. 创建人才与标签的BELONGS_TO关系(如果不存在)
|
|
|
+ create_relation_query = """
|
|
|
+ MATCH (t:talent), (tag:talent_tag)
|
|
|
+ WHERE id(t) = $talent_id AND id(tag) = $tag_id
|
|
|
+ MERGE (t)-[r:BELONGS_TO]->(tag)
|
|
|
+ ON CREATE SET r.created_at = $current_time
|
|
|
+ ON MATCH SET r.updated_at = $current_time
|
|
|
+ RETURN r
|
|
|
+ """
|
|
|
+
|
|
|
+ relation_result = session.run(
|
|
|
+ create_relation_query,
|
|
|
+ talent_id=int(talent_id),
|
|
|
+ tag_id=int(tag_id),
|
|
|
+ current_time=current_time
|
|
|
+ )
|
|
|
+
|
|
|
+ if relation_result.single():
|
|
|
+ success_count += 1
|
|
|
+ else:
|
|
|
+ failed_items.append({'talent': talent_id, 'tag': tag_name})
|
|
|
+
|
|
|
+ except Exception as tag_error:
|
|
|
+ logging.error(f"为标签 {tag_name} 创建关系时出错: {str(tag_error)}")
|
|
|
+ failed_items.append({'talent': talent_id, 'tag': tag_name})
|
|
|
+
|
|
|
+ # 返回结果
|
|
|
+ total_items = len(data)
|
|
|
+ if success_count == total_items:
|
|
|
+ return {
|
|
|
+ 'code': 200,
|
|
|
+ 'success': True,
|
|
|
+ 'message': f'成功创建或更新了 {success_count} 个标签关系',
|
|
|
+ 'data': {
|
|
|
+ 'success_count': success_count,
|
|
|
+ 'total_count': total_items,
|
|
|
+ 'failed_items': []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ elif success_count > 0:
|
|
|
+ return {
|
|
|
+ 'code': 206, # Partial Content
|
|
|
+ 'success': True,
|
|
|
+ 'message': f'部分成功: 创建或更新了 {success_count}/{total_items} 个标签关系',
|
|
|
+ 'data': {
|
|
|
+ 'success_count': success_count,
|
|
|
+ 'total_count': total_items,
|
|
|
+ 'failed_items': failed_items
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else:
|
|
|
+ return {
|
|
|
+ 'code': 500,
|
|
|
+ 'success': False,
|
|
|
+ 'message': '无法创建任何标签关系',
|
|
|
+ 'data': {
|
|
|
+ 'success_count': 0,
|
|
|
+ 'total_count': total_items,
|
|
|
+ 'failed_items': failed_items
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ error_msg = f"更新人才标签关系失败: {str(e)}"
|
|
|
+ logging.error(error_msg, exc_info=True)
|
|
|
+
|
|
|
+ return {
|
|
|
+ 'code': 500,
|
|
|
+ 'success': False,
|
|
|
+ 'message': error_msg,
|
|
|
+ 'data': None
|
|
|
}
|