ai-business-write/技术文档/模板字段关联查询说明.md

16 KiB
Raw Permalink Blame History

模板字段关联查询说明

一、概述

本文档说明如何通过查询 f_polic_file_config 表获取每个模板关联的输入和输出字段。系统已重新建立了模板和字段的关联关系,不再依赖 input_datatemplate_code 字段。

二、表结构关系

2.1 相关表说明

  1. f_polic_file_config - 文件模板配置表

    • id: 文件配置ID主键
    • name: 模板名称(如:"初步核实审批表"
    • tenant_id: 租户ID固定值615873064429507639
    • state: 状态0=未启用1=启用)
  2. f_polic_field - 字段定义表

    • id: 字段ID主键
    • name: 字段名称(中文显示名)
    • filed_code: 字段编码(注意:表中字段名拼写为 filed_code
    • field_type: 字段类型1=输入字段2=输出字段)
    • tenant_id: 租户ID
  3. f_polic_file_field - 文件和字段关联表

    • file_id: 文件配置ID关联 f_polic_file_config.id
    • filed_id: 字段ID关联 f_polic_field.id
    • tenant_id: 租户ID
    • state: 状态0=未启用1=启用)

2.2 关联关系

f_polic_file_config (模板)
    ↓ (通过 file_id)
f_polic_file_field (关联表)
    ↓ (通过 filed_id)
f_polic_field (字段)

三、查询方式

3.1 根据模板名称查询字段

场景:已知模板名称,查询该模板关联的所有字段(包括输入和输出字段)

SELECT 
    fc.id AS template_id,
    fc.name AS template_name,
    f.id AS field_id,
    f.name AS field_name,
    f.filed_code AS field_code,
    f.field_type,
    CASE 
        WHEN f.field_type = 1 THEN '输入字段'
        WHEN f.field_type = 2 THEN '输出字段'
        ELSE '未知'
    END AS field_type_name
FROM f_polic_file_config fc
INNER JOIN f_polic_file_field fff ON fc.id = fff.file_id
INNER JOIN f_polic_field f ON fff.filed_id = f.id
WHERE fc.tenant_id = 615873064429507639
  AND fc.name = '初步核实审批表'
  AND fc.state = 1
  AND fff.state = 1
  AND f.state = 1
ORDER BY f.field_type, f.name;

3.2 根据模板ID查询字段

场景已知模板ID查询该模板关联的所有字段

SELECT 
    f.id AS field_id,
    f.name AS field_name,
    f.filed_code AS field_code,
    f.field_type,
    CASE 
        WHEN f.field_type = 1 THEN '输入字段'
        WHEN f.field_type = 2 THEN '输出字段'
        ELSE '未知'
    END AS field_type_name
FROM f_polic_file_field fff
INNER JOIN f_polic_field f ON fff.filed_id = f.id
WHERE fff.file_id = ?  -- 替换为实际的模板ID
  AND fff.tenant_id = 615873064429507639
  AND fff.state = 1
  AND f.state = 1
ORDER BY f.field_type, f.name;

3.3 分别查询输入字段和输出字段

场景:需要分别获取输入字段和输出字段列表

查询输入字段field_type = 1

SELECT 
    f.id AS field_id,
    f.name AS field_name,
    f.filed_code AS field_code
FROM f_polic_file_config fc
INNER JOIN f_polic_file_field fff ON fc.id = fff.file_id
INNER JOIN f_polic_field f ON fff.filed_id = f.id
WHERE fc.tenant_id = 615873064429507639
  AND fc.name = '初步核实审批表'
  AND fc.state = 1
  AND fff.state = 1
  AND f.state = 1
  AND f.field_type = 1  -- 输入字段
ORDER BY f.name;

查询输出字段field_type = 2

SELECT 
    f.id AS field_id,
    f.name AS field_name,
    f.filed_code AS field_code
FROM f_polic_file_config fc
INNER JOIN f_polic_file_field fff ON fc.id = fff.file_id
INNER JOIN f_polic_field f ON fff.filed_id = f.id
WHERE fc.tenant_id = 615873064429507639
  AND fc.name = '初步核实审批表'
  AND fc.state = 1
  AND fff.state = 1
  AND f.state = 1
  AND f.field_type = 2  -- 输出字段
ORDER BY f.name;

3.4 查询所有模板及其字段统计

场景:获取所有模板及其关联的字段数量统计

SELECT 
    fc.id AS template_id,
    fc.name AS template_name,
    COUNT(DISTINCT CASE WHEN f.field_type = 1 THEN f.id END) AS input_field_count,
    COUNT(DISTINCT CASE WHEN f.field_type = 2 THEN f.id END) AS output_field_count,
    COUNT(DISTINCT f.id) AS total_field_count
FROM f_polic_file_config fc
LEFT JOIN f_polic_file_field fff ON fc.id = fff.file_id AND fff.state = 1
LEFT JOIN f_polic_field f ON fff.filed_id = f.id AND f.state = 1
WHERE fc.tenant_id = 615873064429507639
  AND fc.state = 1
GROUP BY fc.id, fc.name
ORDER BY fc.name;

3.5 查询特定模板的完整字段信息JSON格式

场景:前端需要获取模板的完整字段信息,包括输入和输出字段的详细信息

SELECT 
    fc.id AS template_id,
    fc.name AS template_name,
    JSON_OBJECT(
        'input_fields', JSON_ARRAYAGG(
            CASE 
                WHEN f.field_type = 1 THEN JSON_OBJECT(
                    'id', f.id,
                    'name', f.name,
                    'field_code', f.filed_code
                )
            END
        ),
        'output_fields', JSON_ARRAYAGG(
            CASE 
                WHEN f.field_type = 2 THEN JSON_OBJECT(
                    'id', f.id,
                    'name', f.name,
                    'field_code', f.filed_code
                )
            END
        )
    ) AS fields_info
FROM f_polic_file_config fc
LEFT JOIN f_polic_file_field fff ON fc.id = fff.file_id AND fff.state = 1
LEFT JOIN f_polic_field f ON fff.filed_id = f.id AND f.state = 1
WHERE fc.tenant_id = 615873064429507639
  AND fc.name = '初步核实审批表'
  AND fc.state = 1
GROUP BY fc.id, fc.name;

四、Python代码示例

4.1 根据模板名称获取字段

import pymysql

# 数据库配置
DB_CONFIG = {
    'host': '152.136.177.240',
    'port': 5012,
    'user': 'finyx',
    'password': '6QsGK6MpePZDE57Z',
    'database': 'finyx',
    'charset': 'utf8mb4'
}

TENANT_ID = 615873064429507639

def get_template_fields_by_name(template_name: str):
    """
    根据模板名称获取关联的字段
    
    Args:
        template_name: 模板名称,如 '初步核实审批表'
    
    Returns:
        dict: 包含 input_fields 和 output_fields 的字典
    """
    conn = pymysql.connect(**DB_CONFIG)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    try:
        sql = """
            SELECT 
                f.id,
                f.name,
                f.filed_code AS field_code,
                f.field_type
            FROM f_polic_file_config fc
            INNER JOIN f_polic_file_field fff ON fc.id = fff.file_id
            INNER JOIN f_polic_field f ON fff.filed_id = f.id
            WHERE fc.tenant_id = %s
              AND fc.name = %s
              AND fc.state = 1
              AND fff.state = 1
              AND f.state = 1
            ORDER BY f.field_type, f.name
        """
        cursor.execute(sql, (TENANT_ID, template_name))
        fields = cursor.fetchall()
        
        # 分类为输入字段和输出字段
        result = {
            'template_name': template_name,
            'input_fields': [],
            'output_fields': []
        }
        
        for field in fields:
            field_info = {
                'id': field['id'],
                'name': field['name'],
                'field_code': field['field_code'],
                'field_type': field['field_type']
            }
            
            if field['field_type'] == 1:
                result['input_fields'].append(field_info)
            elif field['field_type'] == 2:
                result['output_fields'].append(field_info)
        
        return result
        
    finally:
        cursor.close()
        conn.close()

# 使用示例
if __name__ == '__main__':
    result = get_template_fields_by_name('初步核实审批表')
    print(f"模板: {result['template_name']}")
    print(f"输入字段数量: {len(result['input_fields'])}")
    print(f"输出字段数量: {len(result['output_fields'])}")
    print("\n输入字段:")
    for field in result['input_fields']:
        print(f"  - {field['name']} ({field['field_code']})")
    print("\n输出字段:")
    for field in result['output_fields']:
        print(f"  - {field['name']} ({field['field_code']})")

4.2 根据模板ID获取字段

def get_template_fields_by_id(template_id: int):
    """
    根据模板ID获取关联的字段
    
    Args:
        template_id: 模板ID
    
    Returns:
        dict: 包含 input_fields 和 output_fields 的字典
    """
    conn = pymysql.connect(**DB_CONFIG)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    try:
        # 先获取模板名称
        sql_template = """
            SELECT id, name
            FROM f_polic_file_config
            WHERE id = %s AND tenant_id = %s AND state = 1
        """
        cursor.execute(sql_template, (template_id, TENANT_ID))
        template = cursor.fetchone()
        
        if not template:
            return None
        
        # 获取字段
        sql_fields = """
            SELECT 
                f.id,
                f.name,
                f.filed_code AS field_code,
                f.field_type
            FROM f_polic_file_field fff
            INNER JOIN f_polic_field f ON fff.filed_id = f.id
            WHERE fff.file_id = %s
              AND fff.tenant_id = %s
              AND fff.state = 1
              AND f.state = 1
            ORDER BY f.field_type, f.name
        """
        cursor.execute(sql_fields, (template_id, TENANT_ID))
        fields = cursor.fetchall()
        
        result = {
            'template_id': template['id'],
            'template_name': template['name'],
            'input_fields': [],
            'output_fields': []
        }
        
        for field in fields:
            field_info = {
                'id': field['id'],
                'name': field['name'],
                'field_code': field['field_code'],
                'field_type': field['field_type']
            }
            
            if field['field_type'] == 1:
                result['input_fields'].append(field_info)
            elif field['field_type'] == 2:
                result['output_fields'].append(field_info)
        
        return result
        
    finally:
        cursor.close()
        conn.close()

4.3 获取所有模板及其字段统计

def get_all_templates_with_field_stats():
    """
    获取所有模板及其字段统计信息
    
    Returns:
        list: 模板列表,每个模板包含字段统计
    """
    conn = pymysql.connect(**DB_CONFIG)
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    
    try:
        sql = """
            SELECT 
                fc.id AS template_id,
                fc.name AS template_name,
                COUNT(DISTINCT CASE WHEN f.field_type = 1 THEN f.id END) AS input_field_count,
                COUNT(DISTINCT CASE WHEN f.field_type = 2 THEN f.id END) AS output_field_count,
                COUNT(DISTINCT f.id) AS total_field_count
            FROM f_polic_file_config fc
            LEFT JOIN f_polic_file_field fff ON fc.id = fff.file_id AND fff.state = 1
            LEFT JOIN f_polic_field f ON fff.filed_id = f.id AND f.state = 1
            WHERE fc.tenant_id = %s
              AND fc.state = 1
            GROUP BY fc.id, fc.name
            ORDER BY fc.name
        """
        cursor.execute(sql, (TENANT_ID,))
        templates = cursor.fetchall()
        
        return [
            {
                'template_id': t['template_id'],
                'template_name': t['template_name'],
                'input_field_count': t['input_field_count'] or 0,
                'output_field_count': t['output_field_count'] or 0,
                'total_field_count': t['total_field_count'] or 0
            }
            for t in templates
        ]
        
    finally:
        cursor.close()
        conn.close()

# 使用示例
if __name__ == '__main__':
    templates = get_all_templates_with_field_stats()
    print("所有模板及其字段统计:")
    for template in templates:
        print(f"\n模板: {template['template_name']} (ID: {template['template_id']})")
        print(f"  输入字段: {template['input_field_count']} 个")
        print(f"  输出字段: {template['output_field_count']} 个")
        print(f"  总字段数: {template['total_field_count']} 个")

五、常见查询场景

5.1 前端展示模板列表

需求:前端需要展示所有模板,并显示每个模板的字段数量

SELECT 
    fc.id,
    fc.name,
    COUNT(DISTINCT CASE WHEN f.field_type = 1 THEN f.id END) AS input_count,
    COUNT(DISTINCT CASE WHEN f.field_type = 2 THEN f.id END) AS output_count
FROM f_polic_file_config fc
LEFT JOIN f_polic_file_field fff ON fc.id = fff.file_id AND fff.state = 1
LEFT JOIN f_polic_field f ON fff.filed_id = f.id AND f.state = 1
WHERE fc.tenant_id = 615873064429507639
  AND fc.state = 1
GROUP BY fc.id, fc.name
ORDER BY fc.name;

5.2 验证模板字段完整性

需求:检查某个模板是否有关联字段

SELECT 
    fc.id,
    fc.name,
    CASE 
        WHEN COUNT(f.id) > 0 THEN '有字段关联'
        ELSE '无字段关联'
    END AS status,
    COUNT(f.id) AS field_count
FROM f_polic_file_config fc
LEFT JOIN f_polic_file_field fff ON fc.id = fff.file_id AND fff.state = 1
LEFT JOIN f_polic_field f ON fff.filed_id = f.id AND f.state = 1
WHERE fc.tenant_id = 615873064429507639
  AND fc.name = '初步核实审批表'
  AND fc.state = 1
GROUP BY fc.id, fc.name;

5.3 查找使用特定字段的所有模板

需求:查找哪些模板使用了某个字段(如 target_name

SELECT 
    fc.id AS template_id,
    fc.name AS template_name
FROM f_polic_file_config fc
INNER JOIN f_polic_file_field fff ON fc.id = fff.file_id
INNER JOIN f_polic_field f ON fff.filed_id = f.id
WHERE fc.tenant_id = 615873064429507639
  AND f.tenant_id = 615873064429507639
  AND f.filed_code = 'target_name'
  AND fc.state = 1
  AND fff.state = 1
  AND f.state = 1
ORDER BY fc.name;

六、注意事项

  1. 租户ID所有查询都需要使用固定的租户ID615873064429507639

  2. 状态过滤:建议始终过滤 state = 1 的记录,确保只获取启用的模板和字段

  3. 字段名拼写:注意 f_polic_field 表中的字段编码字段名是 filed_code(不是 field_code),这是历史遗留问题

  4. 字段类型

    • field_type = 1输入字段用于AI解析的原始数据
    • field_type = 2输出字段AI解析后生成的结构化数据用于填充模板
  5. 关联表状态f_polic_file_field 表也有 state 字段,需要过滤 fff.state = 1

  6. 性能优化:如果经常查询,建议在以下字段上创建索引:

    • f_polic_file_config.tenant_id
    • f_polic_file_config.name
    • f_polic_file_field.file_id
    • f_polic_file_field.filed_id
    • f_polic_field.filed_code

七、示例数据

7.1 初步核实审批表字段示例

输入字段2个

  • clue_info - 线索信息
  • target_basic_info_clue - 被核查人员工作基本情况线索

输出字段14个

  • target_name - 被核查人姓名
  • target_organization_and_position - 被核查人员单位及职务
  • target_organization - 被核查人员单位
  • target_position - 被核查人员职务
  • target_gender - 被核查人员性别
  • target_date_of_birth - 被核查人员出生年月
  • target_age - 被核查人员年龄
  • target_education_level - 被核查人员文化程度
  • target_political_status - 被核查人员政治面貌
  • target_professional_rank - 被核查人员职级
  • clue_source - 线索来源
  • target_issue_description - 主要问题线索
  • department_opinion - 初步核实审批表承办部门意见
  • filler_name - 初步核实审批表填表人

八、总结

通过 f_polic_file_field 关联表,可以方便地查询每个模板关联的输入和输出字段。这种方式比之前依赖 input_datatemplate_code 字段更加规范、可靠,也更容易维护和扩展。

其他研发人员可以根据上述SQL示例和Python代码在自己的模块中实现模板字段的查询功能。