修复生成文件路径问题
This commit is contained in:
50
main.py
50
main.py
@ -15,13 +15,15 @@ from fastapi.middleware.cors import CORSMiddleware
|
|||||||
from fastapi.responses import FileResponse
|
from fastapi.responses import FileResponse
|
||||||
from pydantic import BaseModel, HttpUrl
|
from pydantic import BaseModel, HttpUrl
|
||||||
|
|
||||||
|
# 只导入AI_Agent的统一入口方法(不再导入多个内部方法)
|
||||||
from AI_Agent import generate_tender_from_input
|
from AI_Agent import generate_tender_from_input
|
||||||
from config import DetectionResponse
|
from config import DetectionResponse
|
||||||
from process import detect_large_image_from_url
|
from process import detect_large_image_from_url
|
||||||
|
|
||||||
# 配置文件存储路径
|
# 配置文件存储路径(使用绝对路径确保一致性)
|
||||||
UPLOAD_DIR = Path("uploaded_files")
|
BASE_DIR = Path(__file__).parent.resolve() # 项目根目录绝对路径
|
||||||
OUTPUT_DIR = Path("generated_tenders")
|
UPLOAD_DIR = BASE_DIR / "uploaded_files"
|
||||||
|
OUTPUT_DIR = BASE_DIR / "generated_tenders"
|
||||||
UPLOAD_DIR.mkdir(exist_ok=True)
|
UPLOAD_DIR.mkdir(exist_ok=True)
|
||||||
OUTPUT_DIR.mkdir(exist_ok=True)
|
OUTPUT_DIR.mkdir(exist_ok=True)
|
||||||
|
|
||||||
@ -147,9 +149,11 @@ async def get_supported_types():
|
|||||||
async def generate_tender_file(file: UploadFile = File(...)):
|
async def generate_tender_file(file: UploadFile = File(...)):
|
||||||
"""
|
"""
|
||||||
上传招标文件(Word格式),生成投标文件
|
上传招标文件(Word格式),生成投标文件
|
||||||
|
|
||||||
支持的文件格式:.docx
|
支持的文件格式:.docx
|
||||||
返回生成文件的相对路径,用于下载接口
|
返回生成文件的相对路径,用于下载接口
|
||||||
"""
|
"""
|
||||||
|
# 初始化upload_path变量,避免UnboundLocalError
|
||||||
upload_path = None
|
upload_path = None
|
||||||
|
|
||||||
# 验证文件类型
|
# 验证文件类型
|
||||||
@ -172,15 +176,16 @@ async def generate_tender_file(file: UploadFile = File(...)):
|
|||||||
|
|
||||||
print(f"已接收上传文件:{upload_path}")
|
print(f"已接收上传文件:{upload_path}")
|
||||||
|
|
||||||
# 生成输出文件名和路径
|
# 生成输出文件名和路径(使用绝对路径)
|
||||||
output_filename = f"投标文件_生成版_{timestamp}.docx"
|
output_filename = f"投标文件_生成版_{timestamp}.docx"
|
||||||
output_path = OUTPUT_DIR / output_filename
|
output_path = OUTPUT_DIR / output_filename
|
||||||
|
output_path_abs = str(output_path.resolve()) # 绝对路径
|
||||||
|
|
||||||
# 调用AI_Agent的统一入口方法(仅这一个调用)
|
# 调用AI_Agent的统一入口方法(仅这一个调用)
|
||||||
print("开始生成投标文件...")
|
print("开始生成投标文件...")
|
||||||
generate_success = generate_tender_from_input(
|
generate_success = generate_tender_from_input(
|
||||||
input_word_path=str(upload_path),
|
input_word_path=str(upload_path.resolve()), # 传入绝对路径
|
||||||
output_word_path=str(output_path)
|
output_word_path=output_path_abs
|
||||||
)
|
)
|
||||||
|
|
||||||
if not generate_success:
|
if not generate_success:
|
||||||
@ -193,10 +198,19 @@ async def generate_tender_file(file: UploadFile = File(...)):
|
|||||||
# 计算文件大小
|
# 计算文件大小
|
||||||
file_size = output_path.stat().st_size
|
file_size = output_path.stat().st_size
|
||||||
|
|
||||||
# 构建相对路径(相对于项目根目录)
|
# 修复:使用os.path.relpath计算相对路径,更灵活
|
||||||
relative_path = str(output_path.relative_to(Path.cwd()))
|
try:
|
||||||
|
# 计算相对于项目根目录的相对路径
|
||||||
|
relative_path = os.path.relpath(output_path_abs, str(BASE_DIR))
|
||||||
|
# 统一路径分隔符为 '/',避免Windows和Linux差异
|
||||||
|
relative_path = relative_path.replace(os.sep, '/')
|
||||||
|
except Exception as e:
|
||||||
|
# 异常情况下直接返回文件名(降级方案)
|
||||||
|
relative_path = output_filename
|
||||||
|
print(f"计算相对路径失败,使用降级方案:{e}")
|
||||||
|
|
||||||
print(f"投标文件生成成功:{output_path}")
|
print(f"投标文件生成成功:{output_path_abs}")
|
||||||
|
print(f"相对路径:{relative_path}")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"status": "success",
|
"status": "success",
|
||||||
@ -229,12 +243,17 @@ async def generate_tender_file(file: UploadFile = File(...)):
|
|||||||
async def download_generated_file(relative_path: str):
|
async def download_generated_file(relative_path: str):
|
||||||
"""
|
"""
|
||||||
根据相对路径下载生成的投标文件
|
根据相对路径下载生成的投标文件
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
relative_path: 生成文件的相对路径(从/generate_tender接口获取)
|
relative_path: 生成文件的相对路径(从/generate_tender接口获取)
|
||||||
"""
|
"""
|
||||||
# 解析绝对路径,防止路径穿越攻击
|
|
||||||
try:
|
try:
|
||||||
abs_path = Path(relative_path).resolve()
|
# 修复:将相对路径转换为绝对路径
|
||||||
|
# 统一路径分隔符
|
||||||
|
relative_path = relative_path.replace('/', os.sep)
|
||||||
|
# 拼接项目根目录得到绝对路径
|
||||||
|
abs_path = BASE_DIR / relative_path
|
||||||
|
abs_path = abs_path.resolve() # 解析完整路径
|
||||||
|
|
||||||
# 验证路径是否在允许的输出目录内
|
# 验证路径是否在允许的输出目录内
|
||||||
if not abs_path.is_relative_to(OUTPUT_DIR.resolve()):
|
if not abs_path.is_relative_to(OUTPUT_DIR.resolve()):
|
||||||
@ -271,9 +290,16 @@ async def list_generated_files():
|
|||||||
"""列出所有生成的投标文件(可选接口)"""
|
"""列出所有生成的投标文件(可选接口)"""
|
||||||
files = []
|
files = []
|
||||||
for file in OUTPUT_DIR.glob("*.docx"):
|
for file in OUTPUT_DIR.glob("*.docx"):
|
||||||
|
# 计算相对路径
|
||||||
|
try:
|
||||||
|
relative_path = os.path.relpath(str(file.resolve()), str(BASE_DIR))
|
||||||
|
relative_path = relative_path.replace(os.sep, '/')
|
||||||
|
except:
|
||||||
|
relative_path = file.name
|
||||||
|
|
||||||
files.append({
|
files.append({
|
||||||
"file_name": file.name,
|
"file_name": file.name,
|
||||||
"relative_path": str(file.relative_to(Path.cwd())),
|
"relative_path": relative_path,
|
||||||
"file_size": file.stat().st_size,
|
"file_size": file.stat().st_size,
|
||||||
"created_time": file.stat().st_ctime
|
"created_time": file.stat().st_ctime
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user