# -*- coding: utf-8 -*- """ 飞书同步蓝图 处理飞书多维表格与工单系统的同步 """ from flask import Blueprint, request, jsonify from src.integrations.feishu_client import FeishuClient from src.integrations.workorder_sync import WorkOrderSyncService from src.integrations.config_manager import config_manager import logging logger = logging.getLogger(__name__) feishu_sync_bp = Blueprint('feishu_sync', __name__, url_prefix='/api/feishu-sync') # 全局同步服务实例 sync_service = None def get_sync_service(): """获取同步服务实例""" global sync_service if sync_service is None: # 从配置管理器读取飞书配置 feishu_config = config_manager.get_feishu_config() if not all([feishu_config.get("app_id"), feishu_config.get("app_secret"), feishu_config.get("app_token"), feishu_config.get("table_id")]): raise Exception("飞书配置不完整,请先配置飞书应用信息") feishu_client = FeishuClient(feishu_config["app_id"], feishu_config["app_secret"]) sync_service = WorkOrderSyncService(feishu_client, feishu_config["app_token"], feishu_config["table_id"]) return sync_service @feishu_sync_bp.route('/config', methods=['GET', 'POST']) def manage_config(): """管理飞书同步配置""" if request.method == 'GET': # 返回当前配置 try: config_summary = config_manager.get_config_summary() return jsonify({ "success": True, "config": config_summary }) except Exception as e: logger.error(f"获取配置失败: {e}") return jsonify({"error": str(e)}), 500 elif request.method == 'POST': # 更新配置 try: data = request.get_json() app_id = data.get('app_id') app_secret = data.get('app_secret') app_token = data.get('app_token') table_id = data.get('table_id') if not all([app_id, app_secret, app_token, table_id]): return jsonify({"error": "缺少必要配置参数"}), 400 # 更新配置管理器 success = config_manager.update_feishu_config( app_id=app_id, app_secret=app_secret, app_token=app_token, table_id=table_id ) if success: # 重新初始化同步服务 global sync_service sync_service = None # 强制重新创建 return jsonify({ "success": True, "message": "配置更新成功" }) else: return jsonify({"error": "配置更新失败"}), 500 except Exception as e: logger.error(f"更新飞书配置失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/sync-from-feishu', methods=['POST']) def sync_from_feishu(): """从飞书同步数据到本地""" try: data = request.get_json() or {} generate_ai = data.get('generate_ai_suggestions', True) limit = data.get('limit', 10) sync_service = get_sync_service() result = sync_service.sync_from_feishu(generate_ai_suggestions=generate_ai, limit=limit) if result.get("success"): message = f"同步完成:创建 {result['created_count']} 条,更新 {result['updated_count']} 条" if result.get('ai_suggestions_generated'): message += ",AI建议已生成并更新到飞书表格" return jsonify({ "success": True, "message": message, "details": result }) else: return jsonify({"error": result.get("error")}), 500 except Exception as e: logger.error(f"从飞书同步失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/sync-to-feishu/', methods=['POST']) def sync_to_feishu(workorder_id): """将本地工单同步到飞书""" try: sync_service = get_sync_service() result = sync_service.sync_to_feishu(workorder_id) if result.get("success"): return jsonify({ "success": True, "message": "同步到飞书成功" }) else: return jsonify({"error": result.get("error")}), 500 except Exception as e: logger.error(f"同步到飞书失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/status') def get_sync_status(): """获取同步状态""" try: sync_service = get_sync_service() status = sync_service.get_sync_status() return jsonify({ "success": True, "status": status }) except Exception as e: logger.error(f"获取同步状态失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/test-connection') def test_connection(): """测试飞书连接""" try: # 使用配置管理器测试连接 result = config_manager.test_feishu_connection() if result.get("success"): # 如果连接成功,尝试获取表格字段信息 try: sync_service = get_sync_service() # 使用新的测试连接方法 connection_test = sync_service.feishu_client.test_connection() if not connection_test.get("success"): return jsonify({ "success": False, "message": f"飞书连接测试失败: {connection_test.get('message')}" }), 400 fields_info = sync_service.feishu_client.get_table_fields( sync_service.app_token, sync_service.table_id ) if fields_info.get("code") == 0: result["fields"] = fields_info.get("data", {}).get("items", []) except Exception as e: logger.warning(f"获取表格字段信息失败: {e}") return jsonify(result) except Exception as e: logger.error(f"测试飞书连接失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/create-workorder', methods=['POST']) def create_workorder_from_feishu(): """从飞书记录创建工单""" try: data = request.get_json() record_id = data.get('record_id') if not record_id: return jsonify({"success": False, "message": "缺少记录ID"}), 400 sync_service = get_sync_service() result = sync_service.create_workorder_from_feishu_record(record_id) if result.get("success"): return jsonify(result) else: return jsonify(result), 400 except Exception as e: logger.error(f"创建工单失败: {e}") return jsonify({"success": False, "message": str(e)}), 500 @feishu_sync_bp.route('/preview-feishu-data') def preview_feishu_data(): """预览飞书数据""" try: sync_service = get_sync_service() # 获取前10条记录进行预览 records = sync_service.feishu_client.get_table_records( sync_service.app_token, sync_service.table_id, page_size=10 ) if records.get("code") == 0: items = records.get("data", {}).get("items", []) preview_data = [] for record in items: parsed_fields = sync_service.feishu_client.parse_record_fields(record) preview_data.append({ "record_id": record.get("record_id"), "fields": parsed_fields }) return jsonify({ "success": True, "preview_data": preview_data, "total_count": len(preview_data) }) else: return jsonify({ "success": False, "error": records.get("msg", "获取数据失败") }), 500 except Exception as e: logger.error(f"预览飞书数据失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/config/export', methods=['GET']) def export_config(): """导出配置""" try: config_json = config_manager.export_config() return jsonify({ "success": True, "config": config_json }) except Exception as e: logger.error(f"导出配置失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/config/import', methods=['POST']) def import_config(): """导入配置""" try: data = request.get_json() config_json = data.get('config') if not config_json: return jsonify({"error": "缺少配置数据"}), 400 success = config_manager.import_config(config_json) if success: # 重新初始化同步服务 global sync_service sync_service = None return jsonify({ "success": True, "message": "配置导入成功" }) else: return jsonify({"error": "配置导入失败"}), 500 except Exception as e: logger.error(f"导入配置失败: {e}") return jsonify({"error": str(e)}), 500 @feishu_sync_bp.route('/config/reset', methods=['POST']) def reset_config(): """重置配置""" try: success = config_manager.reset_config() if success: # 重新初始化同步服务 global sync_service sync_service = None return jsonify({ "success": True, "message": "配置重置成功" }) else: return jsonify({"error": "配置重置失败"}), 500 except Exception as e: logger.error(f"重置配置失败: {e}") return jsonify({"error": str(e)}), 500