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

531 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 模板字段关联查询说明
## 一、概述
本文档说明如何通过查询 `f_polic_file_config` 表获取每个模板关联的输入和输出字段。系统已重新建立了模板和字段的关联关系,不再依赖 `input_data``template_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 根据模板名称查询字段
**场景**:已知模板名称,查询该模板关联的所有字段(包括输入和输出字段)
```sql
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查询该模板关联的所有字段
```sql
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
```sql
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
```sql
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 查询所有模板及其字段统计
**场景**:获取所有模板及其关联的字段数量统计
```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 = 615873064429507639
AND fc.state = 1
GROUP BY fc.id, fc.name
ORDER BY fc.name;
```
### 3.5 查询特定模板的完整字段信息JSON格式
**场景**:前端需要获取模板的完整字段信息,包括输入和输出字段的详细信息
```sql
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 根据模板名称获取字段
```python
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获取字段
```python
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 获取所有模板及其字段统计
```python
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 前端展示模板列表
**需求**:前端需要展示所有模板,并显示每个模板的字段数量
```sql
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 验证模板字段完整性
**需求**:检查某个模板是否有关联字段
```sql
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`
```sql
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**所有查询都需要使用固定的租户ID`615873064429507639`
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_data``template_code` 字段更加规范、可靠,也更容易维护和扩展。
其他研发人员可以根据上述SQL示例和Python代码在自己的模块中实现模板字段的查询功能。