添加通过taskId获取文档的接口,支持文件列表查询和参数验证,增强错误处理能力。同时,优化文档生成逻辑,确保生成的文档名称和路径的准确性。

This commit is contained in:
python 2025-12-11 09:30:52 +08:00
parent 3a3b38cd78
commit 4897c96b05
2 changed files with 157 additions and 15 deletions

127
app.py
View File

@ -700,6 +700,133 @@ def generate_document():
return error_response(3001, f"文档生成失败: {str(e)}") return error_response(3001, f"文档生成失败: {str(e)}")
@app.route('/fPolicTask/getDocument', methods=['POST'])
def get_document_by_task():
"""
通过taskId获取文档兼容接口
支持通过taskId查询关联的文件列表或直接使用提供的文件列表
"""
try:
data = request.get_json()
# 验证请求参数
if not data:
return error_response(400, "请求参数不能为空")
task_id = data.get('taskId')
input_data = data.get('inputData', [])
file_list = data.get('fpolicFieldParamFileList', [])
# 如果没有提供file_list尝试通过taskId查询
if not file_list and task_id:
try:
conn = document_service.get_connection()
cursor = conn.cursor(pymysql.cursors.DictCursor)
try:
# 尝试从f_polic_task表查询关联的文件列表
# 注意这里需要根据实际表结构调整SQL
sql = """
SELECT file_id, file_name
FROM f_polic_task_file
WHERE task_id = %s
AND tenant_id = %s
AND state = 1
"""
cursor.execute(sql, (task_id, document_service.tenant_id))
task_files = cursor.fetchall()
if task_files:
file_list = []
for tf in task_files:
file_list.append({
'fileId': tf['file_id'],
'fileName': tf.get('file_name', '')
})
except Exception as e:
# 如果表不存在或查询失败,记录日志但不报错
print(f"[WARN] 无法通过taskId查询文件列表: {str(e)}")
finally:
cursor.close()
conn.close()
except Exception as e:
print(f"[WARN] 查询taskId关联文件时出错: {str(e)}")
# 如果仍然没有file_list返回错误
if not file_list:
return error_response(400, "缺少fpolicFieldParamFileList参数且无法通过taskId查询到关联文件。请提供fpolicFieldParamFileList参数格式: [{'fileId': 文件ID, 'fileName': '文件名'}]")
if not input_data or not isinstance(input_data, list):
return error_response(400, "inputData参数必须是非空数组")
if not file_list or not isinstance(file_list, list):
return error_response(400, "fpolicFieldParamFileList参数必须是非空数组")
# 将input_data转换为字典格式用于生成文档名称
field_data = {}
for item in input_data:
field_code = item.get('fieldCode', '')
field_value = item.get('fieldValue', '')
if field_code:
field_data[field_code] = field_value or ''
# 生成文档ID
document_id = document_service.generate_document_id()
# 处理每个文件
result_file_list = []
first_document_name = None # 用于存储第一个生成的文档名
for file_info in file_list:
file_id = file_info.get('fileId')
file_name = file_info.get('fileName', '')
if not file_id:
return error_response(1001, f"文件 {file_name} 缺少fileId参数")
try:
# 生成文档使用fileId而不是templateCode
result = document_service.generate_document(
file_id=file_id,
input_data=input_data,
file_info=file_info
)
# 使用生成的文档名称(.docx格式而不是原始文件名
generated_file_name = result.get('fileName', file_name)
# 保存第一个文档名作为 documentName
if first_document_name is None:
first_document_name = generated_file_name
result_file_list.append({
'fileId': file_id,
'fileName': generated_file_name, # 使用生成的文档名
'filePath': result['filePath']
})
except Exception as e:
error_msg = str(e)
if '不存在' in error_msg or '模板' in error_msg:
return error_response(1001, error_msg)
elif '生成' in error_msg or '填充' in error_msg:
return error_response(3001, error_msg)
elif '上传' in error_msg or '保存' in error_msg:
return error_response(3002, error_msg)
else:
return error_response(3001, f"文件生成失败: {error_msg}")
# 构建返回数据不包含inputData只返回生成的文档信息
return success_response({
'documentId': document_id,
'documentName': first_document_name or 'generated.docx', # 使用第一个生成的文档名
'fpolicFieldParamFileList': result_file_list
})
except Exception as e:
return error_response(3001, f"文档生成失败: {str(e)}")
if __name__ == '__main__': if __name__ == '__main__':
# 确保static目录存在 # 确保static目录存在
os.makedirs('static', exist_ok=True) os.makedirs('static', exist_ok=True)

View File

@ -134,28 +134,43 @@ class DocumentService:
# 打开模板文档 # 打开模板文档
doc = Document(template_path) doc = Document(template_path)
# 替换占位符 {{field_code}} 为实际值 def replace_placeholder_in_paragraph(paragraph):
for paragraph in doc.paragraphs: """在段落中替换占位符处理跨run的情况"""
# 替换段落文本中的占位符 # 获取段落完整文本
full_text = paragraph.text
if not full_text:
return
# 检查是否有占位符需要替换
has_placeholder = False
replaced_text = full_text
for field_code, field_value in field_data.items(): for field_code, field_value in field_data.items():
placeholder = f"{{{{{field_code}}}}}" placeholder = f"{{{{{field_code}}}}}"
if placeholder in paragraph.text: if placeholder in replaced_text:
# 替换占位符 has_placeholder = True
for run in paragraph.runs: replaced_text = replaced_text.replace(placeholder, field_value or '')
if placeholder in run.text:
run.text = run.text.replace(placeholder, field_value or '') # 如果有替换,更新段落文本
if has_placeholder:
# 清空所有run
paragraph.clear()
# 添加新的run并设置替换后的文本
if replaced_text:
paragraph.add_run(replaced_text)
# 替换段落中的占位符
for paragraph in doc.paragraphs:
replace_placeholder_in_paragraph(paragraph)
# 替换表格中的占位符 # 替换表格中的占位符
for table in doc.tables: for table in doc.tables:
for row in table.rows: for row in table.rows:
for cell in row.cells: for cell in row.cells:
for paragraph in cell.paragraphs: # 检查cell是否有paragraphs属性且不为空
for field_code, field_value in field_data.items(): if hasattr(cell, 'paragraphs') and cell.paragraphs:
placeholder = f"{{{{{field_code}}}}}" for paragraph in cell.paragraphs:
if placeholder in paragraph.text: replace_placeholder_in_paragraph(paragraph)
for run in paragraph.runs:
if placeholder in run.text:
run.text = run.text.replace(placeholder, field_value or '')
# 保存到临时文件 # 保存到临时文件
temp_dir = tempfile.gettempdir() temp_dir = tempfile.gettempdir()