routes.py 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. from flask import jsonify, request, make_response, Blueprint, current_app, send_file
  2. from app.api.data_parse import bp
  3. 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
  4. from app.config.config import DevelopmentConfig, ProductionConfig
  5. import logging
  6. import boto3
  7. from botocore.config import Config
  8. from botocore.exceptions import ClientError
  9. from io import BytesIO
  10. import base64
  11. import os
  12. import urllib.parse
  13. from minio import Minio
  14. # Define logger
  15. logger = logging.getLogger(__name__)
  16. # For failure responses
  17. def failed(message, code=500):
  18. return {
  19. 'success': False,
  20. 'message': message,
  21. 'data': None
  22. }, code
  23. # 根据环境选择配置
  24. if os.environ.get('FLASK_ENV') == 'production':
  25. config = ProductionConfig()
  26. else:
  27. config = DevelopmentConfig()
  28. # 使用配置变量
  29. minio_url = f"{'https' if config.MINIO_SECURE else 'http'}://{config.MINIO_HOST}"
  30. minio_access_key = config.MINIO_USER
  31. minio_secret_key = config.MINIO_PASSWORD
  32. minio_bucket = config.MINIO_BUCKET
  33. use_ssl = config.MINIO_SECURE
  34. def get_minio_client():
  35. """获取 MinIO 客户端实例"""
  36. return Minio(
  37. '192.168.3.143:9000',
  38. access_key=config.MINIO_USER,
  39. secret_key=config.MINIO_PASSWORD,
  40. secure=config.MINIO_SECURE
  41. )
  42. # 测试用的解析数据接口。没有实际使用。
  43. @bp.route('/parse', methods=['POST'])
  44. def parse():
  45. """
  46. 解析数据的接口
  47. """
  48. try:
  49. data = request.get_json()
  50. if not data:
  51. return jsonify({'error': 'No data provided'}), 400
  52. result = parse_data(data)
  53. return jsonify(result), 200
  54. except Exception as e:
  55. return jsonify({'error': str(e)}), 500
  56. # 名片解析接口
  57. @bp.route('/business-card-parse', methods=['POST'])
  58. def parse_business_card_route():
  59. """
  60. 处理名片图片并提取信息的API接口
  61. 请求参数:
  62. - image: 名片图片文件 (multipart/form-data)
  63. 返回:
  64. - JSON: 包含提取的名片信息和处理状态
  65. """
  66. # 检查是否上传了文件
  67. if 'image' not in request.files:
  68. return jsonify({
  69. 'success': False,
  70. 'message': '未上传图片',
  71. 'data': None
  72. }), 400
  73. image_file = request.files['image']
  74. # 检查文件是否为空
  75. if image_file.filename == '':
  76. return jsonify({
  77. 'success': False,
  78. 'message': '未选择文件',
  79. 'data': None
  80. }), 400
  81. # 检查文件类型是否为图片
  82. if not image_file.content_type.startswith('image/'):
  83. return jsonify({
  84. 'success': False,
  85. 'message': '上传的文件不是图片',
  86. 'data': None
  87. }), 400
  88. # 处理名片图片
  89. result = process_business_card(image_file)
  90. if result['success']:
  91. return jsonify(result), 200
  92. else:
  93. return jsonify(result), 500
  94. # 更新名片信息接口
  95. @bp.route('/business-cards/<int:card_id>', methods=['PUT'])
  96. def update_business_card_route(card_id):
  97. """
  98. 更新名片信息的API接口
  99. 路径参数:
  100. - card_id: 名片记录ID
  101. 请求参数:
  102. - JSON格式的名片信息
  103. 返回:
  104. - JSON: 包含更新后的名片信息和处理状态
  105. """
  106. # 获取请求数据
  107. data = request.json
  108. if not data:
  109. return jsonify({
  110. 'success': False,
  111. 'message': '请求数据为空',
  112. 'data': None
  113. }), 400
  114. # 调用业务逻辑函数处理更新
  115. result = update_business_card(card_id, data)
  116. # 根据处理结果设置HTTP状态码
  117. status_code = 200 if result['success'] else 500
  118. if 'not found' in result.get('message', '').lower() or '未找到' in result.get('message', ''):
  119. status_code = 404
  120. return jsonify(result), status_code
  121. # 获取所有名片记录的API接口
  122. @bp.route('/get-business-cards', methods=['GET'])
  123. def get_business_cards_route():
  124. """
  125. 获取所有名片记录的API接口
  126. 返回:
  127. - JSON: 包含名片记录列表和处理状态
  128. """
  129. # 调用业务逻辑函数获取名片列表
  130. result = get_business_cards()
  131. # 根据处理结果设置HTTP状态码
  132. status_code = 200 if result['success'] else 500
  133. return jsonify(result), status_code
  134. @bp.route('/update-business-cards/<int:card_id>/status', methods=['PUT'])
  135. def update_business_card_status_route(card_id):
  136. """
  137. 更新名片状态的API接口
  138. 路径参数:
  139. - card_id: 名片记录ID
  140. 请求参数:
  141. - JSON格式,包含status字段
  142. 返回:
  143. - JSON: 包含更新后的名片信息和处理状态
  144. """
  145. # 获取请求数据
  146. data = request.json
  147. if not data or 'status' not in data:
  148. return jsonify({
  149. 'success': False,
  150. 'message': '请求数据为空或缺少status字段',
  151. 'data': None
  152. }), 400
  153. status = data['status']
  154. # 调用业务逻辑函数处理状态更新
  155. result = update_business_card_status(card_id, status)
  156. # 根据处理结果设置HTTP状态码
  157. status_code = 200 if result['success'] else 500
  158. if 'not found' in result.get('message', '').lower() or '未找到' in result.get('message', ''):
  159. status_code = 404
  160. return jsonify(result), status_code
  161. # 从MinIO获取名片图片的API接口
  162. @bp.route('/business-cards/image/<path:image_path>', methods=['GET'])
  163. def get_business_card_image(image_path):
  164. """
  165. 从MinIO获取名片图片的API接口
  166. 路径参数:
  167. - image_path: MinIO中的图片路径
  168. 返回:
  169. - 图片数据流
  170. """
  171. try:
  172. # 记录下载请求信息,便于调试
  173. logger.info(f"获取名片图片请求: {image_path}")
  174. # 获取 MinIO 客户端
  175. minio_client = get_minio_client()
  176. if not minio_client:
  177. return jsonify(failed("MinIO客户端初始化失败")), 500
  178. try:
  179. # 使用正确的MinIO客户端方法
  180. data = minio_client.get_object(minio_bucket, image_path)
  181. # 创建内存文件流
  182. file_stream = BytesIO(data.read())
  183. # 获取文件名
  184. file_name = image_path.split('/')[-1]
  185. # 返回文件
  186. return send_file(
  187. file_stream,
  188. as_attachment=False, # 设置为False,让浏览器直接显示图片
  189. download_name=file_name,
  190. mimetype='image/jpeg' # 根据实际图片类型设置
  191. )
  192. except Exception as e:
  193. logger.error(f"MinIO获取文件失败: {str(e)}")
  194. return jsonify(failed(f"文件获取失败: {str(e)}")), 404
  195. except Exception as e:
  196. logger.error(f"文件下载失败: {str(e)}")
  197. return jsonify(failed(str(e))), 500
  198. finally:
  199. # 确保关闭数据流
  200. if 'data' in locals():
  201. data.close()