Переглянути джерело

人才标签优化。 人才标注优化。人才检索优化。

maxiaolong 2 днів тому
батько
коміт
37ba05c665
3 змінених файлів з 189 додано та 31 видалено
  1. 27 1
      app/api/data_parse/routes.py
  2. 83 28
      app/core/data_parse/parse.py
  3. 79 2
      data_parse_api_docs.md

+ 27 - 1
app/api/data_parse/routes.py

@@ -1,6 +1,6 @@
 from flask import jsonify, request, make_response, Blueprint, current_app, send_file
 from app.api.data_parse import bp
-from app.core.data_parse.parse import parse_data, process_business_card, update_business_card, get_business_cards, update_business_card_status, create_talent_tag, get_talent_tag_list, update_talent_tag, delete_talent_tag, query_neo4j_graph, talent_get_tags, talent_update_tags
+from app.core.data_parse.parse import parse_data, process_business_card, update_business_card, get_business_cards, update_business_card_status, create_talent_tag, get_talent_tag_list, update_talent_tag, delete_talent_tag, query_neo4j_graph, talent_get_tags, talent_update_tags, get_business_card
 from app.config.config import DevelopmentConfig, ProductionConfig
 import logging
 import boto3
@@ -604,3 +604,29 @@ def test_minio_connection_route():
             }
         }), 500
 
+# 获取单个名片记录的API接口
+@bp.route('/get-business-card/<int:card_id>', methods=['GET'])
+def get_business_card_route(card_id):
+    """
+    获取单个名片记录的API接口
+    
+    路径参数:
+        - card_id: 名片记录ID
+        
+    返回:
+        - JSON: 包含名片记录信息和处理状态
+    """
+    # 调用业务逻辑函数获取名片记录
+    result = get_business_card(card_id)
+    
+    # 根据处理结果设置HTTP状态码
+    if not result['success']:
+        if result['code'] == 404:
+            status_code = 404
+        else:
+            status_code = 500
+    else:
+        status_code = 200
+    
+    return jsonify(result), status_code
+

+ 83 - 28
app/core/data_parse/parse.py

@@ -985,6 +985,15 @@ def create_talent_tag(tag_data):
     try:
         from app.services.neo4j_driver import neo4j_driver
         
+        # 验证必要参数存在
+        if not tag_data or 'name' not in tag_data or not tag_data['name']:
+            return {
+                'code': 400,
+                'success': False,
+                'message': '标签名称为必填项',
+                'data': None
+            }
+        
         # 准备节点属性
         tag_properties = {
             'name': tag_data.get('name'),
@@ -1327,38 +1336,33 @@ def query_neo4j_graph(query_requirement):
            属性: pg_id(PostgreSQL数据库ID), name_zh(中文姓名), name_en(英文姓名), 
                 mobile(手机号码), email(电子邮箱), updated_at(更新时间)
         
-        2. hotel - 酒店节点
-           属性: hotel_zh(酒店中文名称), hotel_en(酒店英文名称), updated_at(更新时间)
-           
-        3. talent_tag - 人才标签节点
-           属性: name(标签名称), category(标签分类), en_name(英文名称)
-           
-        4. hotel_tag - 酒店标签节点
-           属性: name(标签名称), category(标签分类), en_name(英文名称)
-           
-        5. brand_group - 品牌集团节点
-           属性: name(集团名称), en_name(英文名称)
-        
+        2. data_label - 人才标签节点
+                      
         ### 关系
-        1. WORKS_FOR - 工作关系,人才在酒店工作
-           (talent)-[WORKS_FOR]->(hotel)
-           属性: title_zh(中文职位), title_en(英文职位), updated_at(更新时间)
-           
-        2. BELONGS_TO - 从属关系
-           (talent)-[BELONGS_TO]->(talent_tag) - 人才属于某标签
-           (hotel)-[BELONGS_TO]->(hotel_tag) - 酒店属于某标签
-           (hotel)-[BELONGS_TO]->(brand_group) - 酒店属于某品牌集团
+        BELONGS_TO - 从属关系
+           (talent)-[BELONGS_TO]->(data_label) - 人才属于某标签
         
         ## 查询需求
-        {query_requirement}
+        {query_requirement}。从查询需求中提取出需要查询的标签。用MATCH和WHERE语句描述。
+        只用一个MATCH语句,描述(t:talent)-[:BELONGS_TO]->(dl:data_label)关系。
+        WHERE语句可以包含多个标签,用AND连接。
         
         ## 输出要求
         1. 只输出有效的Cypher查询语句,不要包含任何解释或注释
-        2. 确保查询结果包含有意义的列名
-        3. 根据需要使用适当的过滤、排序、聚合和限制
-        4. 尽量利用图数据库的特性来优化查询效率
+        2. 确保return语句中包含talent节点属性
+        3. 尽量利用图数据库的特性来优化查询效率
         
         注意:请直接返回Cypher查询语句,无需任何其他文本。
+
+        例如:
+        查找需求为:查找有新开酒店经验和五星级酒店经验,担任总经理的人。
+        
+        生成的Cypher查询语句为:
+        MATCH (t:talent)-[:BELONGS_TO]->(dl:data_label)  
+        WHERE dl.name IN ['新开酒店经验', '五星级酒店', '总经理']  
+        WITH t, COLLECT(DISTINCT dl.name) AS labels  
+        WHERE size(labels) = 3  
+        RETURN t.pg_id as pg_id, t.name_zh as name_zh, t.name_en as name_en, t.mobile as mobile, t.email as email, t.updated_at as updated_at
         """
         
         # 调用Deepseek API生成Cypher脚本
@@ -1574,6 +1578,17 @@ def talent_update_tags(data):
                         failed_items.append({'talent_pg_id': talent_id, 'tag': tag})
                     continue
                 
+                # 首先清除所有现有的BELONGS_TO关系
+                clear_relations_query = """
+                MATCH (t:talent)-[r:BELONGS_TO]->(:data_label)
+                WHERE t.pg_id = $talent_id
+                DELETE r
+                RETURN count(r) as deleted_count
+                """
+                clear_result = session.run(clear_relations_query, talent_id=int(talent_id))
+                deleted_count = clear_result.single()['deleted_count']
+                logging.info(f"已删除talent_id={talent_id}的{deleted_count}个已有标签关系")
+                
                 # 处理每个标签
                 for tag_name in tags:
                     try:
@@ -1604,13 +1619,12 @@ def talent_update_tags(data):
                             tag_record = tag_result.single()
                             tag_id = tag_record['tag_id']
                         
-                        # 2. 创建人才与标签的BELONGS_TO关系(如果不存在)
+                        # 2. 创建人才与标签的BELONGS_TO关系
                         create_relation_query = """
                         MATCH (t:talent), (tag:data_label)
                         WHERE t.pg_id = $talent_id AND tag.name = $tag_name
-                        MERGE (t)-[r:BELONGS_TO]->(tag)
-                        ON CREATE SET r.created_at = $current_time
-                        ON MATCH SET r.updated_at = $current_time
+                        CREATE (t)-[r:BELONGS_TO]->(tag)
+                        SET r.created_at = $current_time
                         RETURN r
                         """
                         
@@ -1670,6 +1684,47 @@ def talent_update_tags(data):
         error_msg = f"更新人才标签关系失败: {str(e)}"
         logging.error(error_msg, exc_info=True)
         
+        return {
+            'code': 500,
+            'success': False,
+            'message': error_msg,
+            'data': None
+        }
+
+def get_business_card(card_id):
+    """
+    根据ID从PostgreSQL数据库中获取名片记录
+    
+    Args:
+        card_id (int): 名片记录ID
+        
+    Returns:
+        dict: 包含操作结果和名片信息的字典
+    """
+    try:
+        # 查询指定ID的名片记录
+        card = BusinessCard.query.get(card_id)
+        
+        if not card:
+            return {
+                'code': 404,
+                'success': False,
+                'message': f'未找到ID为{card_id}的名片记录',
+                'data': None
+            }
+        
+        # 将记录转换为字典格式返回
+        return {
+            'code': 200,
+            'success': True,
+            'message': '获取名片记录成功',
+            'data': card.to_dict()
+        }
+    
+    except Exception as e:
+        error_msg = f"获取名片记录失败: {str(e)}"
+        logging.error(error_msg, exc_info=True)
+        
         return {
             'code': 500,
             'success': False,

+ 79 - 2
data_parse_api_docs.md

@@ -205,7 +205,84 @@ Content-Type: multipart/form-data
 |---------|---------|-------------------|
 | 500     | 服务器内部错误 | 获取名片列表失败: {错误信息}  |
 
-### 2.4 更新名片状态
+### 2.4 获取单个名片记录
+
+**接口地址**:`/get-business-card/<int:card_id>`
+
+**请求方法**:GET
+
+**功能描述**:根据ID获取单个名片的详细信息。
+
+**路径参数**:
+
+| 参数名      | 参数类型 | 描述    |
+|----------|------|-------|
+| card_id  | int  | 名片记录ID |
+
+**请求参数**:无
+
+**返回结果**:
+
+成功时返回:
+
+```json
+{
+  "code": 200,
+  "success": true,
+  "message": "获取名片记录成功",
+  "data": {
+    "id": 1,
+    "name_zh": "张三",
+    "name_en": "Zhang San",
+    "title_zh": "项目经理",
+    "title_en": "Project Manager",
+    "mobile": "13800138000",
+    "phone": "010-12345678",
+    "email": "zhangsan@example.com",
+    "hotel_zh": "某酒店",
+    "hotel_en": "Some Hotel",
+    "address_zh": "北京市朝阳区某街某号",
+    "address_en": "Some Street, Chaoyang District, Beijing",
+    "postal_code_zh": "100000",
+    "postal_code_en": "100000",
+    "brand_zh": "某品牌",
+    "brand_en": "Some Brand",
+    "affiliation_zh": "某集团",
+    "affiliation_en": "Some Group",
+    "image_path": "unique-filename.jpg",
+    "career_path": [],
+    "brand_group": "",
+    "created_at": "2023-01-01 12:00:00",
+    "updated_at": null,
+    "updated_by": "system",
+    "status": "active"
+  }
+}
+```
+
+**错误码**:
+
+| HTTP 状态码 | 错误描述    | 错误消息                    |
+|---------|---------|-------------------------|
+| 404     | 资源不存在   | 未找到ID为{card_id}的名片记录    |
+| 500     | 服务器内部错误 | 获取名片记录失败: {错误信息}        |
+
+**使用示例**:
+
+```bash
+# 使用curl获取ID为1的名片记录
+curl -X GET http://localhost:5500/api/data_parse/get-business-card/1
+```
+
+**使用说明**:
+
+1. 该接口用于查询单个名片的详细信息,支持前端应用展示名片详情页面。
+2. 接口返回的数据结构与更新接口一致,包含名片的所有字段信息。
+3. 如需同时获取该名片关联的标签信息,可以配合`/talent-get-tags/{talent_id}`接口使用。
+4. 对于不存在的名片ID,接口将返回404状态码。
+5. 接口支持前端分页应用,可先使用列表接口获取所有名片ID,再通过此接口获取详细信息。
+
+### 2.5 更新名片状态
 
 **接口地址**:`/update-business-cards/<int:card_id>/status`
 
@@ -250,7 +327,7 @@ Content-Type: multipart/form-data
 | 404     | 资源不存在   | 未找到ID为{card_id}的名片记录          |
 | 500     | 服务器内部错误 | 更新名片状态失败: {错误信息}              |
 
-### 2.5 获取名片图片
+### 2.6 获取名片图片
 
 **接口地址**:`/business-cards/image/<path:image_path>`