from flask import jsonify, request, make_response, Blueprint, current_app, send_file from app.api.data_parse import bp from app.core.data_parse.parse import parse_data, process_business_card, update_business_card, get_business_cards, update_business_card_status, get_business_card_image_from_minio from app.config.config import DevelopmentConfig, ProductionConfig import logging import boto3 from botocore.config import Config from botocore.exceptions import ClientError from io import BytesIO import base64 import os import urllib.parse from minio import Minio # Define logger logger = logging.getLogger(__name__) # For failure responses def failed(message, code=500): return { 'success': False, 'message': message, 'data': None }, code # 根据环境选择配置 if os.environ.get('FLASK_ENV') == 'production': config = ProductionConfig() else: config = DevelopmentConfig() # 使用配置变量 minio_url = f"{'https' if config.MINIO_SECURE else 'http'}://{config.MINIO_HOST}" minio_access_key = config.MINIO_USER minio_secret_key = config.MINIO_PASSWORD minio_bucket = config.MINIO_BUCKET use_ssl = config.MINIO_SECURE def get_minio_client(): """获取 MinIO 客户端实例""" return Minio( '192.168.3.143:9000', access_key=config.MINIO_USER, secret_key=config.MINIO_PASSWORD, secure=config.MINIO_SECURE ) # 测试用的解析数据接口。没有实际使用。 @bp.route('/parse', methods=['POST']) def parse(): """ 解析数据的接口 """ try: data = request.get_json() if not data: return jsonify({'error': 'No data provided'}), 400 result = parse_data(data) return jsonify(result), 200 except Exception as e: return jsonify({'error': str(e)}), 500 # 名片解析接口 @bp.route('/business-card-parse', methods=['POST']) def parse_business_card_route(): """ 处理名片图片并提取信息的API接口 请求参数: - image: 名片图片文件 (multipart/form-data) 返回: - JSON: 包含提取的名片信息和处理状态 """ # 检查是否上传了文件 if 'image' not in request.files: return jsonify({ 'success': False, 'message': '未上传图片', 'data': None }), 400 image_file = request.files['image'] # 检查文件是否为空 if image_file.filename == '': return jsonify({ 'success': False, 'message': '未选择文件', 'data': None }), 400 # 检查文件类型是否为图片 if not image_file.content_type.startswith('image/'): return jsonify({ 'success': False, 'message': '上传的文件不是图片', 'data': None }), 400 # 处理名片图片 result = process_business_card(image_file) if result['success']: return jsonify(result), 200 else: return jsonify(result), 500 # 更新名片信息接口 @bp.route('/business-cards/', methods=['PUT']) def update_business_card_route(card_id): """ 更新名片信息的API接口 路径参数: - card_id: 名片记录ID 请求参数: - JSON格式的名片信息 返回: - JSON: 包含更新后的名片信息和处理状态 """ # 获取请求数据 data = request.json if not data: return jsonify({ 'success': False, 'message': '请求数据为空', 'data': None }), 400 # 调用业务逻辑函数处理更新 result = update_business_card(card_id, data) # 根据处理结果设置HTTP状态码 status_code = 200 if result['success'] else 500 if 'not found' in result.get('message', '').lower() or '未找到' in result.get('message', ''): status_code = 404 return jsonify(result), status_code # 获取所有名片记录的API接口 @bp.route('/get-business-cards', methods=['GET']) def get_business_cards_route(): """ 获取所有名片记录的API接口 返回: - JSON: 包含名片记录列表和处理状态 """ # 调用业务逻辑函数获取名片列表 result = get_business_cards() # 根据处理结果设置HTTP状态码 status_code = 200 if result['success'] else 500 return jsonify(result), status_code @bp.route('/update-business-cards//status', methods=['PUT']) def update_business_card_status_route(card_id): """ 更新名片状态的API接口 路径参数: - card_id: 名片记录ID 请求参数: - JSON格式,包含status字段 返回: - JSON: 包含更新后的名片信息和处理状态 """ # 获取请求数据 data = request.json if not data or 'status' not in data: return jsonify({ 'success': False, 'message': '请求数据为空或缺少status字段', 'data': None }), 400 status = data['status'] # 调用业务逻辑函数处理状态更新 result = update_business_card_status(card_id, status) # 根据处理结果设置HTTP状态码 status_code = 200 if result['success'] else 500 if 'not found' in result.get('message', '').lower() or '未找到' in result.get('message', ''): status_code = 404 return jsonify(result), status_code # 从MinIO获取名片图片的API接口 @bp.route('/business-cards/image/', methods=['GET']) def get_business_card_image(image_path): """ 从MinIO获取名片图片的API接口 路径参数: - image_path: MinIO中的图片路径 返回: - 图片数据流 """ try: # 记录下载请求信息,便于调试 logger.info(f"获取名片图片请求: {image_path}") # 获取 MinIO 客户端 minio_client = get_minio_client() if not minio_client: return jsonify(failed("MinIO客户端初始化失败")), 500 try: # 使用正确的MinIO客户端方法 data = minio_client.get_object(minio_bucket, image_path) # 创建内存文件流 file_stream = BytesIO(data.read()) # 获取文件名 file_name = image_path.split('/')[-1] # 返回文件 return send_file( file_stream, as_attachment=False, # 设置为False,让浏览器直接显示图片 download_name=file_name, mimetype='image/jpeg' # 根据实际图片类型设置 ) except Exception as e: logger.error(f"MinIO获取文件失败: {str(e)}") return jsonify(failed(f"文件获取失败: {str(e)}")), 404 except Exception as e: logger.error(f"文件下载失败: {str(e)}") return jsonify(failed(str(e))), 500 finally: # 确保关闭数据流 if 'data' in locals(): data.close()