Files
baiyue-logistics-chat/logistics_chat/file_service.py
T
ouyangxq 805675f8db 重构物流客服模块并完善会话接待工作台
- 拆分应用工厂、业务服务与路由,保留原有 HTTP/SSE 和存储入口
- 分离页面资源,重排客服工作台并完善响应式导航、草稿和附件交互
- 整理维护脚本、请求示例和贡献指南,移除启动脚本中的密钥配置
- 上传文件改为仅本地保留,补充隔离的后端与前端回归验证

验证:46 项 Python 测试通过,含 14 个已有子测试;12 个 Node 前端场景通过。
2026-10-29 10:59:29 +08:00

47 lines
1.7 KiB
Python

"""Attachment validation, storage and retention without request parsing."""
import os
import random
import time
from datetime import datetime
from .config import get_setting
def cleanup_uploads():
"""删除 uploads/ 里 7 天前的图片"""
try:
udir = get_setting('UPLOAD_DIR')
if not os.path.isdir(udir):
return
cutoff = time.time() - 7 * 86400
for f in os.listdir(udir):
fp = os.path.join(udir, f)
if os.path.isfile(fp) and os.path.getmtime(fp) < cutoff:
os.remove(fp)
except Exception as e:
print(f'[清理上传文件失败] {e}')
def upload_file(files):
"""上传附件:保存到 uploads 目录,返回文件名与访问地址"""
if 'file' not in files:
return ({'ok': False, 'error': '没有文件'}, 400)
f = files['file']
if not f or not f.filename:
return ({'ok': False, 'error': '文件名为空'}, 400)
ext = os.path.splitext(f.filename)[1].lower()
if ext not in get_setting('ALLOWED_EXT'):
return ({'ok': False, 'error': f'不支持的格式 {ext},仅支持图片/PDF/TXT/CSV'}, 400)
f.seek(0, os.SEEK_END)
size = f.tell()
f.seek(0)
if size > get_setting('MAX_UPLOAD_MB') * 1024 * 1024:
return ({'ok': False, 'error': f"文件超过 {get_setting('MAX_UPLOAD_MB')}MB"}, 400)
os.makedirs(get_setting('UPLOAD_DIR'), exist_ok=True)
safe_name = f"{datetime.now().strftime('%Y%m%d%H%M%S')}_{random.randint(1000, 9999)}{ext}"
f.save(os.path.join(get_setting('UPLOAD_DIR'), safe_name))
is_image = ext in ('.png', '.jpg', '.jpeg', '.gif', '.webp')
return {'ok': True, 'name': f.filename, 'url': f'/uploads/{safe_name}', 'is_image': is_image}