针对于上传图片以及借库还库和出库选单进行更改

This commit is contained in:
dxc
2026-02-09 16:08:47 +08:00
parent eb771ec4f1
commit 50361dba9a
7 changed files with 503 additions and 108 deletions

View File

@ -5,21 +5,18 @@ import uuid
from flask import Blueprint, request, jsonify, send_from_directory
# 定义蓝图
# 注意:在 app/__init__.py 或类似入口文件中,注册此蓝图时 url_prefix 通常应为 '/api/v1/common'
upload_bp = Blueprint('upload', __name__)
# =========================================================
# 配置上传路径 (核心修改:确保路径绝对准确)
# 配置上传路径
# =========================================================
# 向上寻找直到找到 inventory-backend 目录,或者默认为当前文件的上级目录的...上级
# 这种方式比数 dirname 层级更稳健
def get_project_root():
"""获取项目根目录 inventory-backend"""
current_path = os.path.abspath(__file__)
# 循环向上查找,直到找到名为 inventory-backend 的目录
# 如果你的根目录名字不是 inventory-backend,请修改这里的判断逻辑
# 或者直接使用相对路径回退 5 层: api/v1/common -> app -> inventory-backend
# 向上回退直到找到根目录,根据你的目录结构可能需要调整层级
# 假设结构: inventory-backend/app/api/v1/common/upload.py (回退5层)
base = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(current_path)))))
return base
@ -28,7 +25,7 @@ BASE_DIR = get_project_root()
UPLOAD_FOLDER = os.path.join(BASE_DIR, 'uploads')
# 允许上传的文件后缀
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp'}
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif', 'bmp', 'webp', 'pdf', 'doc', 'docx', 'xls', 'xlsx'}
def allowed_file(filename):
@ -47,7 +44,7 @@ def ensure_upload_folder_exists():
# ------------------------------------------------------------------
# 1. 文件上传接口
# URL: /api/v1/common/upload (POST)
# 完整 URL: /api/v1/common/upload (POST)
# ------------------------------------------------------------------
@upload_bp.route('/upload', methods=['POST'])
def upload_file():
@ -63,6 +60,7 @@ def upload_file():
if file and allowed_file(file.filename):
try:
# 获取后缀并生成唯一文件名
ext = file.filename.rsplit('.', 1)[1].lower()
new_filename = f"{uuid.uuid4().hex}.{ext}"
@ -71,8 +69,9 @@ def upload_file():
print(f"💾 [Upload] 文件已保存: {save_path}")
# 生成访问 URL
# 这里的路径必须与 __init__.py 中注册的 url_prefix + 路由匹配
# 生成访问 URL (返回给前端的相对路径)
# 前端展示时通常拼接 baseURL或者直接使用此路径访问
# 这里的 /api/v1/common 需与蓝图注册路径一致
file_url = f"/api/v1/common/files/{new_filename}"
return jsonify({
@ -92,13 +91,13 @@ def upload_file():
# ------------------------------------------------------------------
# 2. 静态文件访问接口 (回显)
# URL: /api/v1/common/files/<filename>
# 完整 URL: /api/v1/common/files/<filename> (GET)
# ------------------------------------------------------------------
@upload_bp.route('/files/<filename>')
@upload_bp.route('/files/<filename>', methods=['GET'])
def uploaded_file(filename):
# 打印日志帮助调试 404 问题
full_path = os.path.join(UPLOAD_FOLDER, filename)
if not os.path.exists(full_path):
# 尝试调试路径问题
print(f"❌ [File Access] 文件未找到: {full_path}")
return jsonify({"code": 404, "msg": "文件不存在"}), 404
@ -107,12 +106,12 @@ def uploaded_file(filename):
# ------------------------------------------------------------------
# 3. 文件删除接口 (同步删除物理文件)
# URL: /api/v1/common/files/<filename> (DELETE)
# 完整 URL: /api/v1/common/files/<filename> (DELETE)
# ------------------------------------------------------------------
@upload_bp.route('/files/<filename>', methods=['DELETE'])
def delete_file(filename):
try:
# 安全处理文件名
# 安全处理文件名 (防止路径遍历)
safe_filename = os.path.basename(filename)
file_path = os.path.join(UPLOAD_FOLDER, safe_filename)
@ -124,7 +123,7 @@ def delete_file(filename):
return jsonify({"code": 200, "msg": "文件已删除"})
else:
print(f"⚠️ [Delete] 文件不存在,无需删除")
# 即使文件不存在也返回成功,保证前端流程继续
# 即使文件不存在也返回成功,保证前端逻辑闭环
return jsonify({"code": 200, "msg": "文件不存在或已删除"})
except Exception as e: