environment = environ[‘wsgi.websocket‘] KeyError: ‘wsgi.websocket‘

本文详细描述了如何在Nginx配置中设置代理,包括转发请求头和连接升级,同时提到了`wsgi.websocket`引发的KeyError问题,暗示可能是在处理WebSocket时遇到的问题。
   location / {
                   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

                   proxy_set_header Host $http_host;

                   proxy_redirect off;

                   proxy_pass http://127.0.0.1:8082/;
                   proxy_http_version 1.1;
                   proxy_set_header Upgrade $http_upgrade;
                   proxy_set_header Connection "upgrade";
                    }

在这里插入图片描述
Key error: wsgi.websocket

# E:\AI_System\web_ui\server.py (修复KeyError完整版) import sys import os import time import logging import json import traceback import threading import platform import psutil import datetime from pathlib import Path from functools import wraps from concurrent.futures import ThreadPoolExecutor import logging.handlers # ========== 关键修复1: 最先执行eventlet猴子补丁 ========== try: import eventlet eventlet.monkey_patch() # 必须在所有导入之前执行 print("✅ Eventlet monkey patch applied at startup") except ImportError: print("⚠️ Eventlet not installed, using threading mode") pass # 修复1:更新依赖包列表 REQUIRED_PACKAGES = [ 'flask', 'flask_socketio', 'flask_limiter', 'psutil', 'eventlet', 'waitress' ] def check_dependencies(): """增强依赖检查功能""" missing = [] for package in REQUIRED_PACKAGES: try: __import__(package) except ImportError: missing.append(package) if missing: print(f"❌ 缺少必要的依赖包: {', '.join(missing)}") print("请运行以下命令安装依赖:") print(f"pip install {' '.join(missing)}") sys.exit(1) if __name__ == '__main__': check_dependencies() # 在启动前检查依赖 # 现在导入其他模块 from flask import Flask, jsonify, request, render_template from flask_socketio import SocketIO, emit from flask_limiter import Limiter from flask_limiter.util import get_remote_address # ========== 配置系统 ========== class SystemConfig: def __init__(self): self.BASE_DIR = Path(__file__).resolve().parent.parent self.HOST = '0.0.0.0' self.PORT = 5000 self.LOG_LEVEL = 'DEBUG' self.SECRET_KEY = os.getenv('SECRET_KEY', 'your_secret_key_here') self.DEBUG = True self.USE_GPU = False self.DEFAULT_MODEL = 'gpt-3.5-turbo' self.MAX_WORKERS = 4 # 目录配置 self.LOG_DIR = self.BASE_DIR / 'logs' self.LOG_DIR.mkdir(parents=True, exist_ok=True) self.CONFIG_DIR = self.BASE_DIR / 'config' self.CONFIG_DIR.mkdir(parents=True, exist_ok=True) self.AGENT_PATH = self.BASE_DIR / 'agent' self.MODEL_CACHE_DIR = self.BASE_DIR / 'model_cache' self.MODEL_CACHE_DIR.mkdir(parents=True, exist_ok=True) self.TEMPLATE_DIR = self.BASE_DIR / 'web_ui' / 'templates' def __str__(self): return f"SystemConfig(HOST={self.HOST}, PORT={self.PORT})" config = SystemConfig() # ========== 全局协调器 ========== coordinator = None executor = ThreadPoolExecutor(max_workers=config.MAX_WORKERS) def register_coordinator(coord): global coordinator coordinator = coord if coordinator and hasattr(coordinator, 'connect_to_ui'): coordinator.connect_to_ui(update_ui) def update_ui(event): if 'socketio' in globals(): socketio.emit('system_event', event) # ========== 线程安全装饰器 ========== def synchronized(lock): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): with lock: return func(*args, **kwargs) return wrapper return decorator # ========== 日志系统 ========== def setup_logger(): """优化日志配置""" logger = logging.getLogger('WebServer') logger.setLevel(getattr(logging, config.LOG_LEVEL.upper(), logging.DEBUG)) # 清除所有现有处理器 for handler in logger.handlers[:]: logger.removeHandler(handler) # 日志格式 log_formatter = logging.Formatter( '%(asctime)s [%(levelname)s] %(name)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # 文件日志处理器 (每天轮换,保留30天) file_handler = logging.handlers.TimedRotatingFileHandler( config.LOG_DIR / 'web_server.log', when='midnight', backupCount=30, encoding='utf-8' ) file_handler.setFormatter(log_formatter) logger.addHandler(file_handler) # 控制台日志处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(log_formatter) logger.addHandler(console_handler) # 设置Flask和SocketIO日志 flask_logger = logging.getLogger('werkzeug') flask_logger.setLevel(logging.WARNING) socketio_logger = logging.getLogger('engineio') socketio_logger.setLevel(logging.WARNING) return logger logger = setup_logger() # ========== 环境管理器 ========== class EnvironmentManager: """独立的环境管理器类""" def __init__(self, config): self.config = config self.state = { 'temperature': 22.5, 'humidity': 45.0, 'light_level': 75, 'objects': [], 'last_updated': datetime.datetime.now().isoformat() } self.healthy = True self.lock = threading.Lock() @synchronized(threading.Lock()) def start(self): logger.info("环境管理器已启动") @synchronized(threading.Lock()) def get_state(self): # 更新模拟数据 self.state['temperature'] = round(20 + 5 * (time.time() % 10) / 10, 1) self.state['humidity'] = round(40 + 10 * (time.time() % 10) / 10, 1) self.state['light_level'] = round(70 + 10 * (time.time() % 10) / 10, 1) self.state['last_updated'] = datetime.datetime.now().isoformat() return self.state @synchronized(threading.Lock()) def execute_action(self, action, params): logger.info(f"执行环境动作: {action} 参数: {params}") if action == "adjust_temperature": self.state['temperature'] = params.get('value', 22.0) return True elif action == "adjust_light": self.state['light_level'] = params.get('level', 70) return True return False def is_healthy(self): return self.healthy # ========== 系统初始化 ========== class SystemInitializer: def __init__(self): self.base_dir = Path(__file__).resolve().parent.parent self.ai_c极 = None self.hardware_manager = None self.life_scheduler = None self.ai_agent = None self.start_time = time.time() self.environment_manager = None self.life_lock = threading.Lock() def initialize_system_paths(self): sys.path.insert(0, str(self.base_dir)) logger.info(f"项目根目录: {self.base_dir}") sub_dirs = ['agent', 'core', 'utils', 'config', 'cognitive_arch', 'environment'] for sub_dir in sub_dirs: full_path = self.base_dir / sub_dir if full_path.exists(): sys.path.insert(0, str(full_path)) logger.info(f"添加路径: {full_path}") else: logger.warning(f"目录不存在: {full_path} - 已跳过") def initialize_environment_manager(self): try: env_config = {'update_interval': 1.0, 'spatial': {'grid_size': 1.0}} self.environment_manager = EnvironmentManager(env_config) self.environment_manager.start() logger.info("✅ 环境管理器初始化成功") return self.environment_manager except Exception as e: logger.error(f"❌ 环境管理器初始化失败: {str(e)}") logger.warning("⚠️ 环境交互功能将不可用") return None def initialize_ai_core(self): logger.info("✅ 模拟AI核心初始化") self.ai_core = type('AICore', (), { 'status': 'running', 'get_state': lambda: {"status": "running", "model": "gpt-3.5-turbo"} })() def initialize_hardware_manager(self): logger.info("✅ 模拟硬件管理器初始化") self.hardware_manager = type('HardwareManager', (), { 'get_status': lambda: { "cpu_usage": psutil.cpu_percent(), "memory_usage": psutil.virtual_memory().percent, "gpu_usage": 0 } })() @synchronized(lock=threading.Lock()) def initialize_life_scheduler(self): logger.info("✅ 模拟生活调度器初始化") self.life_scheduler = type('LifeScheduler', (), { 'get_status': lambda: { "current_activity": "thinking", "next_activity": "learning", "energy": 85 } })() @synchronized(lock=threading.Lock()) def initialize_ai_agent(self): logger.info("✅ 模拟AI智能体初始化") self.ai_agent = type('AIAgent', (), { 'process_input': lambda self, input, user_id: f"你好{user_id},我收到了你的消息: '{input}'" })() def start_evolution_monitor(self): logger.info("✅ 模拟进化监视器启动") def initialize_all(self): logger.info("=" * 50) logger.info("🚀 开始初始化AI系统") logger.info("=" * 50) self.initialize_system_paths() self.initialize_ai_core() self.initialize_hardware_manager() self.initialize_life_scheduler() self.initialize_ai_agent() self.initialize_environment_manager() self.start_evolution_monitor() logger.info("✅ 所有系统组件初始化完成") return { "ai_core": self.ai_core, "hardware_manager": self.hardware_manager, "life_scheduler": self.life_scheduler, "ai_agent": self.ai_agent, "environment_manager": self.environment_manager } # ========== 环境交互路由 ========== def register_environment_routes(app): @app.route('/environment') def environment_view(): return render_template('environment_view.html') @app.route('/api/environment/state', methods=['GET']) @app.config['LIMITER'].limit("10 per minute") def get_environment_state(): env_manager = app.config['SYSTEM_COMPONENTS'].get('environment_manager') if not env_manager: return jsonify({"success": False, "error": "环境管理器未初始化"}), 503 try: state = env_manager.get_state() return jsonify(state) except Exception as e: app.logger.error(f"获取环境状态失败: {traceback.format_exc()}") return jsonify({"success": False, "error": str(e)}), 500 @app.route('/api/environment/action', methods=['POST']) @app.config['极IMITER'].limit("5 per minute") def execute_environment_action(): env_manager = app.config['SYSTEM_COMPONENTS'].get('environment_manager') if not env_manager: return jsonify({"success": False, "error": "环境管理器未初始化"}), 503 try: data = request.json action = data.get('action') params = data.get('params', {}) if not action: return jsonify({"success": False, "error": "缺少动作参数"}), 400 success = env_manager.execute_action(action, params) return jsonify({"success": success, "action": action}) except Exception as e: app.logger.error(f"执行环境动作失败: {traceback.format_exc()}") return jsonify({"success": False, "error": str(e)}), 500 # ========== 路由注册 ========== def register_routes(app): # 添加根路由 - 关键修复 @app.route('/') def home(): """根路由显示欢迎页面""" # 使用f-string避免format()方法的问题 current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f""" <!DOCTYPE html> <html> <head> <title>AI系统控制中心</title> <style> body {{ font-family: Arial, sans-serif; margin: 40px; background-color: #f5f8fa; }} .container {{ max-width: 800px; margin: 0 auto; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }} h1 {{ color: #2c3e50; text-align: center; margin-bottom: 30px; }} .status {{ background: #f8f9fa; padding: 20px; border-radius: 8px; margin-top: 30px; border-left: 4px solid #3498db; }} .links {{ margin-top: 20px; display: flex; justify-content: center; flex-wrap: wrap; gap: 15px; }} .links a {{ display: inline-block; padding: 12px 25px; background: #3498db; color: white; text-decoration: none; border-radius: 4px; transition: all 0.3s ease; text-align: center; min-width: 150px; }} .links a:hover {{ background: #2980b9; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); }} .footer {{ text-align: center; margin-top: 30px; color: #7f8c8d; font-size: 0.9em; }} </style> </head> <body> <div class="container"> <h1>🤖 AI系统控制中心</h1> <p>欢迎访问AI系统控制面板,请选择以下功能:</p> <div class="links"> <a href="/environment">🌍 环境监控</a> <a href="/life/dashboard">📅 生活调度</a> <a href="/status">📊 系统状态</a> <a href="/health">🩺 健康检查</a> <a href="/chat">💬 聊天交互</a> </div> <div class="status"> <h3>系统状态</h3> <p>✅ 服务器已启动,运行正常</p> <p>🕒 启动时间: {current_time}</p> <p>📍 服务器地址: http://{request.host}</p> </div> <div class="footer"> <p>AI系统控制中心 v1.0 | 技术支持: support@ai-system.com</p> </div> </div> </body> </html> """ register_environment_routes(app) # 健康检查路由 @app.route('/health') def health_check(): return jsonify({"status": "healthy", "timestamp": datetime.datetime.now().isoformat()}) # 系统状态路由 @app.route('/status') @app.config['LIMITER'].exempt def status(): components = app.config['SYSTEM_COMPONENTS'] system_info = { "uptime": time.time() - app.config['START_TIME'], "ai_core_status": components['ai_core'].status if components['ai_core'] else "uninitialized", "hardware_status": components['hardware_manager'].get_status() if components[ 'hardware_manager'] else "uninitialized", "life_scheduler_status": components['life_scheduler'].get_status() if components[ 'life_scheduler'] else "uninitialized", "environment_status": components['environment_manager'].is_healthy() if components[ 'environment_manager'] else "uninitialized", "platform": platform.platform(), "python_version": sys.version, "memory_usage": psutil.virtual_memory().percent, "cpu_usage": psutil.cpu_percent(), "thread_count": threading.active_count(), "process_id": os.getpid() } return jsonify(system_info) # 核心系统路由 @app.route('/api/core/state') @app.config['LIMITER'].limit("10 per minute") def get_core_state(): ai_core = app.config['SYSTEM_COMPONENTS'].get('ai_core') if not ai_core: return jsonify({"error": "AI核心未初始化"}), 503 return jsonify(ai_core.get_state()) # 生活系统路由 @app.route('/life/dashboard') def life_dashboard(): return render_template('life_dashboard.html') @app.route('/api/life/status') @app.config['LIMITER'].limit("10 per minute") def get_life_status(): life_scheduler = app.config['SYSTEM_COMPONENTS'].get('life_scheduler') if not life_scheduler: return jsonify({"error": "生活调度器未初始化"}), 503 status = life_scheduler.get_status() return jsonify(status) # 聊天路由 - 添加GET方法支持 @app.route('/chat', methods=['GET']) def chat_interface(): """聊天界面""" return render_template('chat.html') @app.route('/api/chat', methods=['POST']) @app.config['LIMITER'].limit("30 per minute") def chat_handler(): """处理聊天请求的API端点""" components = app.config['SYSTEM_COMPONENTS'] if not components['ai_agent']: return jsonify({"error": "Agent未初始化"}), 503 try: data = request.get_json() user_input = data.get('message', '') user_id = data.get('user_id', 'default') if not user_input: return jsonify({"error": "消息内容不能为空"}), 400 app.logger.info(f"聊天请求: 用户={user_id}, 内容长度={len(user_input)}") # 使用线程池异步处理 future = executor.submit(components['ai_agent'].process_input, user_input, user_id) response = future.result(timeout=10) # 10秒超时 return jsonify({"response": response}) except TimeoutError: return jsonify({"error": "处理超时"}), 504 except Exception as e: app.logger.error(f"聊天处理失败: {traceback.format_exc()}") return jsonify({"error": "聊天处理失败", "details": str(e)}), 500 # 404处理 @app.route('/<path:path>') def catch_all(path): return jsonify({"error": "路由不存在", "path": path}), 404 def register_error_handlers(app): @app.errorhandler(404) def not_found_error(error): return jsonify({"error": "资源未找到", "message": str(error)}), 404 @app.errorhandler(500) def internal_error(error): app.logger.error(f"服务器内部错误: {str(error)}") return jsonify({"error": "服务器内部错误", "message": "请查看日志获取详细信息"}), 500 # ========== WebSocket处理 ========== def setup_websocket_handlers(socketio): @socketio.on('connect') def handle_connect(): logger.info('客户端已连接') socketio.emit('system_status', {'status': 'ready'}) @socketio.on('disconnect') def handle_disconnect(): logger.info('客户端已断开连接') @socketio.on('user_message') def handle_user_message(data): user_id = data.get('user_id', 'guest') message = data.get('message', '') logger.info(f"收到来自 {user_id} 的消息: {message}") # 使用线程池处理消息 def process_message(): try: global coordinator if coordinator: return coordinator.process_message(message) else: return f"已收到您的消息: {message}" except Exception as e: logger.error(f"消息处理失败: {str(e)}") return "处理消息时出错" future = executor.submit(process_message) try: response = future.result(timeout=10) socketio.emit('agent_response', { 'user_id': user_id, 'response': response }) except TimeoutError: socketio.emit('agent_response', { 'user_id': user_id, 'response': "处理超时,请重试" }) # ========== 生产环境启动器 ========== def run_production_server(app): try: from waitress import serve logger.info(f"🚀 生产服务器启动: http://{config.HOST}:{config.PORT}") logger.warning("⚠️ 当前运行在生产模式 (Waitress WSGI服务器)") serve(app, host=config.HOST, port=config.PORT, threads=8) except ImportError: logger.error("❌ 缺少生产环境依赖: waitress") logger.info("请运行: pip install waitress") sys.exit(1) # ========== Flask应用工厂 ========== def create_app(): app = Flask( __name__, template_folder=str(config.TEMPLATE_DIR), static_folder='static', static_url_path='/static' ) app.secret_key = config.SECRET_KEY # 初始化限流器 limiter = Limiter( get_remote_address, app=app, default_limits=["200 per day", "50 per hour"], storage_uri="memory://" ) app.config['LIMITER'] = limiter system_initializer = SystemInitializer() components = system_initializer.initialize_all() app.config['SYSTEM_COMPONENTS'] = components app.config['START_TIME'] = system_initializer.start_time app.config['BASE_DIR'] = system_initializer.base_dir # 配置SocketIO async_mode = 'threading' try: import eventlet async_mode = 'eventlet' logger.info("✅ 使用eventlet异步模式") except ImportError: logger.warning("⚠️ eventlet未安装,使用threadi 哥 你给我发完整版吧 改来改去我会烦 也改不明白
08-12
前端代码:// pages/order-detail/order-detail.js Page({ data: { activeIndex: 0, // 当前选中的状态索引 statusList: ['新订单', '备货中', '待配送', '配送中', '已完成', '已取消'], // 订单状态列表 showActionSheet: false, // 是否显示操作面板 currentOrderId: null, // 当前操作的订单ID cancelOrderCount: 0, // 取消订单次数 lastCancelDate: null, // 最后一次取消订单的日期 searchText: '', // 搜索关键字 orders: [], // 所有订单数据 filteredOrders: [], // 筛选后的订单数据 isLoading: false, // 是否正在加载数据 page: 1, // 当前页码 pageSize: 10, // 每页大小 hasMore: true ,// 是否还有更多数据 socketOpen: false, // WebSocket 是否已打开 socketTask: null, // WebSocket 实例 }, // onLoad() { // this.loadOrders(); // 加载订单数据 // this.loadCancelInfo(); // 加载取消订单信息 // }, onReachBottom() { if (this.data.hasMore && !this.data.isLoading) { this.setData({ page: this.data.page + 1 }, () => { this.loadOrders(); }); } }, loadCancelInfo() { const cancelInfo = wx.getStorageSync('cancelOrderInfo') || {}; this.setData({ cancelOrderCount: cancelInfo.count || 0, lastCancelDate: cancelInfo.date || null }); }, onLoad() { this.loadOrders(); // 加载订单数据 this.initWebSocket(); // 初始化 WebSocket }, onUnload() { this.closeWebSocket(); // 页面卸载时关闭 WebSocket }, // 初始化 WebSocket initWebSocket() { const that = this; const socketTask = wx.connectSocket({ url: 'ws://127.0.0.1:8000/ws/orders/', // 替换为实际的 WebSocket URL header: { 'Authorization': 'Bearer ' + wx.getStorageSync('token') } }); socketTask.onOpen(() => { console.log('WebSocket 已连接'); that.setData({ socketOpen: true }); }); socketTask.onMessage((res) => { console.log('收到新订单:', res.data); const newOrder = JSON.parse(res.data); // 更新本地订单数据 that.setData({ orders: [newOrder, ...that.data.orders], filteredOrders: [newOrder, ...that.data.filteredOrders] }); // 提示用户有新订单 wx.showToast({ title: '有新订单', icon: 'success' }); }); socketTask.onError((err) => { console.error('WebSocket 连接错误:', err); that.setData({ socketOpen: false }); }); socketTask.onClose(() => { console.log('WebSocket 已关闭'); that.setData({ socketOpen: false }); }); this.setData({ socketTask }); }, // 关闭 WebSocket closeWebSocket() { const { socketTask } = this.data; if (socketTask) { socketTask.close(); } }, async loadOrders() { if (this.data.isLoading || !this.data.hasMore) return; this.setData({ isLoading: true }); try { const { statusList, activeIndex, searchText, page, pageSize } = this.data; const currentStatus = statusList[activeIndex]; const user = wx.getStorageSync('userInfo'); const shopId = user.id; // 确保已存储shopId const res = await new Promise((resolve, reject) => { wx.request({ url: 'http://127.0.0.1:8000/api/gouw/merchant/orders/', method: 'GET', header: { 'Authorization': 'Bearer ' + wx.getStorageSync('token'), 'Content-Type': 'application/json' }, data: { shop_id: shopId, status: currentStatus, search: searchText, page: page, page_size: pageSize }, success: (res) => { if (res.statusCode === 200) { resolve(res.data); } else { reject(new Error(`HTTP ${res.statusCode}: ${res.data?.message || '请求失败'}`)); } }, fail: (err) => { reject(new Error('网络请求失败')); } }); }); console.log('API响应数据:', JSON.stringify(res, null, 2)); if (res.code === 200) { const newOrders = res.data.orders.map(order => ({ id: order.orderId, orderId: order.orderNo, customerName: order.customerName, customerPhone: order.customerPhone, status: order.status, statusCode: order.statusCode, createTime: order.createTime, totalAmount: order.totalAmount, products: order.products, deliveryFee: order.deliveryFee })); this.setData({ orders: page === 1 ? newOrders : [...this.data.orders, ...newOrders], filteredOrders: page === 1 ? newOrders : [...this.data.orders, ...newOrders], hasMore: page < res.data.pagination.totalPages, isLoading: false }); } else { throw new Error(res.message || '加载订单失败'); } } catch (err) { console.error('加载订单错误:', err.message, err); wx.showToast({ title: err.message || '加载订单失败', icon: 'none', duration: 2000 }); this.setData({ isLoading: false }); } }, // 加载订单数据 // async loadOrders() { // try { // const user = wx.getStorageSync('userInfo'); // const shopId = user.id; // const res = await new Promise((resolve, reject) => { // wx.request({ // url: 'http://127.0.0.1:8000/api/gouw/merchant/orders/', // method: 'GET', // header: { // 'Authorization': 'Bearer ' + wx.getStorageSync('token'), // 'Content-Type': 'application/json' // }, // data: { // shop_id: shopId, // status: '新订单', // page: 1, // page_size: 10 // }, // success: (res) => { // if (res.statusCode === 200) { // resolve(res.data); // } else { // reject(new Error(`HTTP ${res.statusCode}: ${res.data?.message || '请求失败'}`)); // } // }, // fail: (err) => { // reject(new Error('网络请求失败')); // } // }); // }); // if (res.code === 200) { // const orders = res.data.orders.map(order => ({ // id: order.orderId, // orderId: order.orderNo, // customerName: order.customerName, // customerPhone: order.customerPhone, // status: order.status, // statusCode: order.statusCode, // createTime: order.createTime, // totalAmount: order.totalAmount, // products: order.products, // deliveryFee: order.deliveryFee // })); // this.setData({ // orders, // filteredOrders: orders // }); // } // } catch (err) { // console.error('加载订单错误:', err.message); // } // }, // 切换订单状态 switchStatus(e) { const index = e.currentTarget.dataset.index; this.setData({ activeIndex: index, searchText: '', page: 1, hasMore: true }, () => { this.loadOrders(); }); }, filterOrders() { const { activeIndex, statusList, orders, searchText } = this.data; const currentStatus = statusList[activeIndex]; let filtered = orders.filter(order => { if (currentStatus !== '全部' && order.status !== currentStatus) { return false; } if (searchText && !order.orderId.includes(searchText) && !order.customerName.includes(searchText) && !order.customerPhone.includes(searchText)) { return false; } return true; }); filtered.sort((a, b) => new Date(b.createTime) - new Date(a.createTime)); this.setData({ filteredOrders: filtered }); }, handleSearchInput(e) { this.setData({ searchText: e.detail.value }); }, handleSearch() { this.setData({ page: 1, hasMore: true }, () => { this.loadOrders(); }); }, showActionSheet(e) { const orderId = e.currentTarget.dataset.orderid; this.setData({ showActionSheet: true, currentOrderId: orderId }); }, hideActionSheet() { this.setData({ showActionSheet: false, currentOrderId: null }); }, handleCancelOrder(e) { const orderId = e.currentTarget.dataset.orderid; const today = new Date().toDateString(); if (this.data.lastCancelDate === today && this.data.cancelOrderCount >= 3) { wx.showModal({ title: '提示', content: '当天取消接单次数已经用完,如需继续,请点击申诉', showCancel: false }); this.hideActionSheet(); return; } let newCount = this.data.cancelOrderCount; let newDate = this.data.lastCancelDate; if (newDate !== today) { newCount = 0; newDate = today; } newCount++; this.setData({ cancelOrderCount: newCount, lastCancelDate: newDate }); wx.setStorageSync('cancelOrderInfo', { count: newCount, date: newDate }); this.updateOrderStatus(orderId, '已取消'); wx.showToast({ title: '订单已取消', icon: 'success' }); this.hideActionSheet(); }, handleAppeal(e) { const orderId = e.currentTarget.dataset.orderid; this.hideActionSheet(); wx.navigateTo({ url: `/pages/appeal/appeal?orderId=${orderId}`, success: () => { console.log('跳转到申诉页面'); }, fail: (err) => { console.error('跳转失败:', err); wx.showToast({ title: '跳转失败,请重试', icon: 'none' }); } }); }, handleAcceptOrder(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, '备货中'); wx.showToast({ title: '接单成功', icon: 'success' }); }, handleReadyForDelivery(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, '待配送'); wx.showToast({ title: '备货完成', icon: 'success' }); }, handleStartDelivery(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, '配送中'); wx.showToast({ title: '开始配送', icon: 'success' }); }, handleCompleteDelivery(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, '已完成'); wx.showToast({ title: '配送完成', icon: 'success' }); }, // 更新订单状态 async updateOrderStatus(orderId, newStatus) { const token = wx.getStorageSync('token'); if (!token) { wx.showToast({ title: '未登录,请重新登录', icon: 'none' }); return; } wx.showLoading({ title: '处理中...', mask: true }); try { const res = await new Promise((resolve, reject) => { wx.request({ url: 'http://127.0.0.1:8000/api/gouw/update-order-status/', method: 'POST', header: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }, data: { order_no: orderId, status: newStatus }, success: (res) => { if (res.statusCode === 200 && res.data.code === 200) { resolve(res.data); } else { reject(new Error(res.data?.message || '更新失败')); } }, fail: (err) => { reject(new Error('网络请求失败')); } }); }); wx.hideLoading(); wx.showToast({ title: '操作成功', icon: 'success' }); // 从本地数据中移除已处理的订单 // 核心修改:更新本地订单状态并重新过滤 const updatedOrders = this.data.orders.map(order => { if (order.orderId === orderId) { return { ...order, status: newStatus }; } return order; }); this.setData({ // 从完整订单列表移除 orders: this.data.orders.filter(order => order.orderId !== orderId), // 从当前视图列表直接移除 filteredOrders: this.data.filteredOrders.filter(order => order.orderId !== orderId) }); wx.hideLoading(); wx.showToast({ title: '操作成功', icon: 'success' }); // this.loadOrders(); // 如果需要重新加载数据,可以调用 this.loadOrders(); } catch (err) { console.error('更新订单状态失败:', err.message); wx.hideLoading(); wx.showToast({ title: err.message || '操作失败,请重试', icon: 'none' }); } }, // 辅助方法:匹配搜索条件 matchSearchCriteria(order) { const searchText = this.data.searchText.toLowerCase(); return !searchText || order.orderId.toLowerCase().includes(searchText) || order.customerName.toLowerCase().includes(searchText) || order.customerPhone.includes(searchText); }, sj_mb(e) { wx.navigateTo({ url: "/pages/gr_xx/gr_xx", success: () => { console.log('成功跳转到商家信息页面'); }, fail: (err) => { console.error('跳转失败:', err); wx.showToast({ title: '跳转失败,请重试', icon: 'none' }); } }); }, dp_zt(e) { wx.navigateTo({ url: "/pages/dp_zt/dp_zt", success: () => { console.log('成功跳转到商家信息页面'); }, fail: (err) => { console.error('跳转失败:', err); wx.showToast({ title: '跳转失败,请重试', icon: 'none' }); } }); }, tk_dd(e) { wx.navigateTo({ url: "/pages/tk_dd/tk_dd", success: () => { console.log('成功跳转到退款订单页面'); }, fail: (err) => { console.error('跳转失败:', err); wx.showToast({ title: '跳转失败,请重试', icon: 'none' }); } }); } }); 后端代码:""" ASGI config for DjangoProject1 project. It exposes the ASGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/5.1/howto/deployment/asgi/ """ # import os # # from django.core.asgi import get_asgi_application # # os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoProject1.settings') # # application = get_asgi_application() # DjangoProject1/asgi.py # DjangoProject1/asgi.py # DjangoProject1/asgi.py import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from .routing import application # 直接导入主路由配置 os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoProject1.settings') application = application # DjangoProject1/routing.py from django.urls import re_path from channels.routing import ProtocolTypeRouter, URLRouter from gouw.routing import websocket_urlpatterns as gouw_routes # 直接导入子路由 application = ProtocolTypeRouter({ "websocket": URLRouter([ re_path(r'^ws/', URLRouter(gouw_routes)), # 确保路径匹配 ]) }) # gouw/consumers.py import json from channels.generic.websocket import AsyncWebsocketConsumer class OrderConsumer(AsyncWebsocketConsumer): async def connect(self): # 接受 WebSocket 连接 await self.accept() async def disconnect(self, close_code): # 处理连接断开 pass async def receive(self, text_data): # 接收消息 text_data_json = json.loads(text_data) message = text_data_json['message'] # 发送消息回客户端 await self.send(text_data=json.dumps({ 'message': message })) # gouw/routing.py from django.urls import path from .consumers import OrderConsumer websocket_urlpatterns = [ path('orders/', OrderConsumer.as_asgi()), # 保持简单路由列表 ] """ Django settings for DjangoProject1 project. Generated by 'django-admin startproject' using Django 5.1.6. For more information on this file, see https://docs.djangoproject.com/en/5.1/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/5.1/ref/settings/ """ import os from datetime import timedelta from pathlib import Path # import AES # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-7f5y$m$)-y81w5h0q*o12ohp$douez_97h-x_!daldl@9%7kvr' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ # 通用 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework_simplejwt', # 新增 # 功能 'rest_framework', 'corsheaders', 'django_filters', 'rest_framework.authtoken', 'channels', # app 'swiper', 'search', # 正确的应用名称 'merchant', # 正确的应用名称 'shop', "product", "gouw", "xiad", "zhif", "dd", 'wod_denglu', "dingd", ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] # ASGI_APPLICATION = "DjangoProject1.asgi.application" # 确保存在 ASGI_APPLICATION = 'DjangoProject1.routing.application' # ASGI_APPLICATION = "DjangoProject1.asgi.application" CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer", }, } TIME_ZONE = 'Asia/Shanghai' # 确保时区正确 USE_TZ = True CORS_ALLOW_ALL_ORIGINS = True ROOT_URLCONF = 'DjangoProject1.urls' # TEMPLATES = [ # { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # 'BACKEND': 'django.template.backends.django.DjangoTemplates', # 'DIRS': [BASE_DIR / 'templates'] # , # 'APP_DIRS': True, # 'OPTIONS': { # 'context_processors': [ # 'django.template.context_processors.debug', # 'django.template.context_processors.request', # 'django.contrib.auth.context_processors.auth', # 'django.contrib.messages.context_processors.messages', # ], # }, # }, # ] CORS_ALLOWED_ORIGINS = [ 'http://127.0.0.1:8000', # 替换为实际的前端地址 ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'DjangoProject1.wsgi.application' CORS_ORIGIN_ALLOW_ALL = True # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':"db_44", 'USER': 'root', 'PASSWORD': '123456', 'HOST': 'localhost', 'PORT': '3306', 'charset': 'utf8mb4', } } # Password validation # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] CORS_ALLOW_CREDENTIALS = True # DRF配置 REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 20, 'ORDERING_PARAM': 'ordering', 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.authentication.BasicAuthentication', # 'rest_framework.authentication.SessionAuthentication', ], # "DEFAULT_AUTHENTICATION_CLASSES": ( # 'rest_framework.permissions.IsAuthenticated', # ), # "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), # # 'DEFAULT_AUTHENTICATION_CLASSES': [ # 'rest_framework.authentication.TokenAuthentication', # ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', # 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', # 'rest_framework_simplejwt.authentication.JWTAuthentication', # 替换原来的 JWT 认证 # #Token认证 # 'rest_framework.authentication.TokenAuthentication', # 'rest_framework.authentication.BasicAuthentication', ), 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler', } AUTH_USER_MODEL = 'wod_denglu.User' # AUTH_USER_MODEL = None # 替换为实际应用名 # 配置文件上传路径 MEDIA_ROOT = os.path.join(BASE_DIR, "media") MEDIA_URL = "/media/" # 在settings.py 中启用调试模式 DEBUG = True # Internationalization # https://docs.djangoproject.com/en/5.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.1/howto/static-files/ STATIC_URL = 'static/' # Default primary key field type # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # # # LOGGING = { # 'version': 1, # 'disable_existing_loggers': False, # 'handlers': { # 'console': { # 'level': 'DEBUG', # 'class': 'logging.StreamHandler', # }, # }, # 'loggers': { # 'django': { # 'handlers': ['console'], # 'level': 'DEBUG', # }, # }, # } # 允许所有域名(开发环境临时方案) CORS_ORIGIN_ALLOW_ALL = True # 配置允许的请求头 CORS_ALLOW_HEADERS = [ 'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ] # 配置允许的HTTP方法 CORS_ALLOW_METHODS = [ 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' ] # # # 增强型JWT配置 # JWT_SETTINGS = { # 'SECRET_KEY': os.getenv('JWT_SECRET'), # 32位随机字符串 # 'ALGORITHM': 'HS256', # 'ACCESS_TOKEN_LIFETIME': timedelta(hours=2), # 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), # 'AUTH_HEADER_PREFIX': 'Bearer' # } # # 微信配置 # WECHAT = { # 'APP_ID': os.environ.get('WECHAT_APP_ID'), # 'APP_SECRET': os.environ.get('WECHAT_APP_SECRET'), # 'LOGIN_URL': 'https://api.weixin.qq.com/sns/jscode2session' # } # # # AES加密配置(用于手机号解密) # AES_SETTINGS = { # 'MODE': AES.MODE_CBC, # 'BLOCK_SIZE': 32, # 'PADDING': '\0' # } # 微信配置 WX_APPID= 'wx5bb48b2fd7ec3e54' WX_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200' WX_MCHID = '1230004567' # 新增 WX_API_KEY = 'aBcDeFgHiJkLmNoPqRsTuVwXyZ' # 新增 WX_NOTIFY_URL = 'http:/http://127.0.0.1:8000/api/zhif/wx-notify/' WECHAT_APPID = 'wx5bb48b2fd7ec3e54' WECHAT_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200' WECHAT_APP_ID = 'wx5bb48b2fd7ec3e54' WECHAT_APP_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200' WECHAT_MINI_PROGRAM = { 'APPID': 'wx5bb48b2fd7ec3e54', 'SECRET': '6ba10b53c9bdf24aaa0f026f147e0200' } WECHAT_TOKEN = "90_RzkT6EObTjmOA4E0O2ouANm7iYvTauxbwnTFkcTEu-3ggitiQnpzpvHE6-JUfbGThiqvmOdHBF4TEE3rf9GE_1MvDoBzhPEIj24OWmT0ulQkJ4iq95JweKmIBa8OQZfAGASUD" # 默认头像配置 DEFAULT_AVATAR_URL = 'https://tse2-mm.cn.bing.net/th/id/OIP-C.1eW3_u1T8He1QmfKH_ctngAAAA?rs=1&pid=ImgDetMain' # JWT配置 JWT_EXPIRATION_DAYS = 7 SIMPLE_JWT = { # 'AUTH_TOKEN_CLASSES': ('shop.auth.ShopJWTAuthentication',), # # 'TOKEN_USER_CLASS': 'shop.models.Shop', # 'USER_ID_FIELD': 'id', # 'USER_ID_CLAIM': 'user_id', 'USER_AUTHENTICATION_RULE': 'shop.auth.allow_all_users', # 新增规则 # 添加商家用户类型支持 'TOKEN_USER_CLASSES': ( 'wod_denglu.models.User', 'shop.models.Shop' ), # 'AUTH_TOKEN_CLASSES': ('shop.auth.ShopJWTAuthentication',), # 'USER_ID_FIELD': 'uuid', # 使用唯一标识字段 'TOKEN_USER_CLASS': 'wod_denglu.models.User', # 主用户类 'TOKEN_OBTAIN_SERIALIZER': 'wod_denglu.serializers.CustomTokenObtainPairSerializer', # 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', 'ACCESS_TOKEN_LIFETIME': timedelta(days=7), # 按需配置有效期 'REFRESH_TOKEN_LIFETIME': timedelta(days=30), 'ROTATE_REFRESH_TOKENS': False, 'BLACKLIST_AFTER_ROTATION': True, # 调试专用配置 'VERIFYING_KEY': None, 'AUDIENCE': None, 'ISSUER': None, 'JWK_URL': None, 'LEEWAY': 0, 'AUTH_HEADER_TYPES': ('Bearer',), 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION', 'USER_ID_FIELD': 'id', # 确保与用户模型匹配 'USER_ID_CLAIM': 'user_id', # 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken','shop.auth.ShopJWTAuthentication'), 'TOKEN_TYPE_CLAIM': 'token_type', # 开启详细错误 'SHOW_AUTHENTICATION_ERRORS': True, 'SIGNING_KEY': '6ba10b53c9bdf24aaa0f026f147e0200', # 替换为强密钥 } # 安全配置 SECRET_KEY = '6ba10b53c9bdf24aaa0f026f147e0200' # AUTHENTICATION_BACKENDS = [ # 'django.contrib.auth.backends.ModelBackend', # 'shop.backends.ShopBackend', # 如果你使用自定义后端 # ] # # 指定自定义用户模型 # AUTH_USER_MODEL = 'shop.Shop' # 根据应用名调整 # 配置认证后端 AUTHENTICATION_BACKENDS = [ 'shop.backends.ShopAuthBackend', # 商家认证 'wod_denglu.backends.CustomerAuthBackend', # 消费者认证 'django.contrib.auth.backends.ModelBackend', ] # JWT配置 # SIMPLE_JWT = { # 'USER_ID_FIELD': 'id', # 'USER_ID_CLAIM': 'user_id', # 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), # } # # # 认证后端配置 # AUTHENTICATION_BACKENDS = [ # 'django.contrib.auth.backends.ModelBackend', # 'shop.backends.ShopBackend', # ] # # # 用户模型配置 # AUTH_USER_MODEL = 'shop.Shop' # # # JWT配置 # SIMPLE_JWT = { # 'ACCESS_TOKEN_LIFETIME': timedelta(days=1), # 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), # 'ROTATE_REFRESH_TOKENS': False, # 'BLACKLIST_AFTER_ROTATION': True, # 'ALGORITHM': 'HS256', # 'SIGNING_KEY': SECRET_KEY, # 'VERIFYING_KEY': None, # 'AUTH_HEADER_TYPES': ('Bearer',), # 'USER_ID_FIELD': 'id', # 'USER_ID_CLAIM': 'user_id', # 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), # } DATA_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10MB FILE_UPLOAD_MAX_MEMORY_SIZE = 2 * 1024 * 1024 # 2MB FILE_UPLOAD_PERMISSIONS = 0o644 # LOGGING = { # 'version': 1, # 'disable_existing_loggers': False, # 'handlers': { # 'file': { # 'level': 'DEBUG', # 'class': 'logging.FileHandler', # 'filename': 'debug.log', # }, # 'console': { # 'level': 'DEBUG', # 'class': 'logging.StreamHandler', # }, # }, # 'loggers': { # 'django': { # 'handlers': ['file', 'console'], # 'level': 'DEBUG', # 'propagate': True, # }, # }, # } 前端报错:WebSocket connection to 'ws://127.0.0.1:8000/ws/orders/' failed: (env: Windows,mp,1.06.2409140; lib: 3.8.4) initWebSocket @ index.js:55 onLoad @ index.js:46 (anonymous) @ index.js:536 (anonymous) @ index.js:536 (anonymous) @ VM2437:617 index.js:85 WebSocket 连接错误: {errMsg: "未完成的操作"}(env: Windows,mp,1.06.2409140; lib: 3.8.4) 后端报错:Not Found: /ws/orders/ [16/May/2025 19:09:48] "GET /ws/orders/ HTTP/1.1" 404 4239
05-17
# E:\AI_System\web_ui\server.py (完整可运行版) import sys import os import time import logging import json import traceback import threading import platform import psutil import datetime from pathlib import Path from functools import wraps from concurrent.futures import ThreadPoolExecutor import logging.handlers # ========== 关键修复1: 最先执行eventlet猴子补丁 ========== try: import eventlet eventlet.monkey_patch() # 必须在所有导入之前执行 print("✅ Eventlet monkey patch applied at startup") except ImportError: print("⚠️ Eventlet not installed, using threading mode") pass # 修复1:更新依赖包列表 REQUIRED_PACKAGES = [ 'flask', 'flask_socketio', 'flask_limiter', 'psutil', 'waitress' ] def check_dependencies(): """增强依赖检查功能""" missing = [] for package in REQUIRED_PACKAGES: try: __import__(package) except ImportError: missing.append(package) if missing: print(f"❌ 缺少必要的依赖包: {', '.join(missing)}") print("请运行以下命令安装依赖:") print(f"pip install {' '.join(missing)}") sys.exit(1) if __name__ == '__main__': check_dependencies() # 在启动前检查依赖 # 现在导入其他模块 from flask import Flask, jsonify, request, render_template, send_from_directory from flask_socketio import SocketIO, emit from flask_limiter import Limiter from flask_limiter.util import get_remote_address # ========== 配置系统 ========== class SystemConfig: def __init__(self): self.BASE_DIR = Path(__file__).resolve().parent.parent self.HOST = '0.0.0.0' self.PORT = 5000 self.LOG_LEVEL = 'DEBUG' self.SECRET_KEY = os.getenv('SECRET_KEY', 'your_secret_key_here') self.DEBUG = True self.USE_GPU = False self.DEFAULT_MODEL = 'gpt-3.5-turbo' self.MAX_WORKERS = 4 # 目录配置 self.LOG_DIR = self.BASE_DIR / 'logs' self.LOG_DIR.mkdir(parents=True, exist_ok=True) self.CONFIG_DIR = self.BASE_DIR / 'config' self.CONFIG_DIR.mkdir(parents=True, exist_ok=True) self.AGENT_PATH = self.BASE_DIR / 'agent' self.MODEL_CACHE_DIR = self.BASE_DIR / 'model_cache' self.MODEL_CACHE_DIR.mkdir(parents=True, exist_ok=True) self.TEMPLATE_DIR = self.BASE_DIR / 'web_ui' / 'templates' self.STATIC_DIR = self.BASE_DIR / 'web_ui' / 'static' def __str__(self): return f"SystemConfig(HOST={self.HOST}, PORT={self.PORT})" config = SystemConfig() # ========== 全局协调器 ========== coordinator = None executor = ThreadPoolExecutor(max_workers=config.MAX_WORKERS) def register_coordinator(coord): global coordinator coordinator = coord if coordinator and hasattr(coordinator, 'connect_to_ui'): coordinator.connect_to_ui(update_ui) def update_ui(event): if 'socketio' in globals(): socketio.emit('system_event', event) # ========== 线程安全装饰器 ========== def synchronized(lock): def decorator(func): @wraps(func) def wrapper(*args, **kwargs): with lock: return func(*args, **kwargs) return wrapper return decorator # ========== 日志系统 ========== def setup_logger(): """优化日志配置""" logger = logging.getLogger('WebServer') logger.setLevel(getattr(logging, config.LOG_LEVEL.upper(), logging.DEBUG)) # 清除所有现有处理器 for handler in logger.handlers[:]: logger.removeHandler(handler) # 日志格式 log_formatter = logging.Formatter( '%(asctime)s [%(levelname)s] %(name)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) # 文件日志处理器 (每天轮换,保留30天) file_handler = logging.handlers.TimedRotatingFileHandler( config.LOG_DIR / 'web_server.log', when='midnight', backupCount=30, encoding='utf-8' ) file_handler.setFormatter(log_formatter) logger.addHandler(file_handler) # 控制台日志处理器 console_handler = logging.StreamHandler() console_handler.setFormatter(log_formatter) logger.addHandler(console_handler) # 设置Flask和SocketIO日志 flask_logger = logging.getLogger('werkzeug') flask_logger.setLevel(logging.WARNING) socketio_logger = logging.getLogger('engineio') socketio_logger.setLevel(logging.WARNING) return logger logger = setup_logger() # ========== 环境管理器 ========== class EnvironmentManager: """独立的环境管理器类""" def __init__(self, config): self.config = config self.state = { 'temperature': 22.5, 'humidity': 45.0, 'light_level': 75, 'objects': [], 'last_updated': datetime.datetime.now().isoformat() } self.healthy = True self.lock = threading.Lock() @synchronized(threading.Lock()) def start(self): logger.info("环境管理器已启动") @synchronized(threading.Lock()) def get_state(self): # 更新模拟数据 self.state['temperature'] = round(20 + 5 * (time.time() % 10) / 10, 1) self.state['humidity'] = round(40 + 10 * (time.time() % 10) / 10, 1) self.state['light_level'] = round(70 + 10 * (time.time() % 10) / 10, 1) self.state['last_updated'] = datetime.datetime.now().isoformat() return self.state @synchronized(threading.Lock()) def execute_action(self, action, params): logger.info(f"执行环境动作: {action} 参数: {params}") if action == "adjust_temperature": self.state['temperature'] = params.get('value', 22.0) return True elif action == "adjust_light": self.state['light_level'] = params.get('level', 70) return True return False def is_healthy(self): return self.healthy # ========== 系统初始化 ========== class SystemInitializer: def __init__(self): self.base_dir = Path(__file__).resolve().parent.parent self.ai_core = None self.hardware_manager = None self.life_scheduler = None self.ai_agent = None self.start_time = time.time() self.environment_manager = None self.life_lock = threading.Lock() def initialize_system_paths(self): sys.path.insert(0, str(self.base_dir)) logger.info(f"项目根目录: {self.base_dir}") sub_dirs = ['agent', 'core', 'utils', 'config', 'cognitive_arch', 'environment'] for sub_dir in sub_dirs: full_path = self.base_dir / sub_dir if full_path.exists(): sys.path.insert(0, str(full_path)) logger.info(f"添加路径: {full_path}") else: logger.warning(f"目录不存在: {full_path} - 已跳过") def initialize_environment_manager(self): try: env_config = {'update_interval': 1.0, 'spatial': {'grid_size': 1.0}} self.environment_manager = EnvironmentManager(env_config) self.environment_manager.start() logger.info("✅ 环境管理器初始化成功") return self.environment_manager except Exception as e: logger.error(f"❌ 环境管理器初始化失败: {str(e)}") logger.warning("⚠️ 环境交互功能将不可用") return None def initialize_ai_core(self): logger.info("✅ 模拟AI核心初始化") self.ai_core = type('AICore', (), { 'status': 'running', 'get_state': lambda: {"status": "running", "model": "gpt-3.5-turbo"} })() def initialize_hardware_manager(self): logger.info("✅ 模拟硬件管理器初始化") self.hardware_manager = type('HardwareManager', (), { 'get_status': lambda: { "cpu_usage": psutil.cpu_percent(), "memory_usage": psutil.virtual_memory().percent, "gpu_usage": 0 } })() @synchronized(lock=threading.Lock()) def initialize_life_scheduler(self): logger.info("✅ 模拟生活调度器初始化") self.life_scheduler = type('LifeScheduler', (), { 'get_status': lambda: { "current_activity": "thinking", "next_activity": "learning", "energy": 85 } })() @synchronized(lock=threading.Lock()) def initialize_ai_agent(self): logger.info("✅ 模拟AI智能体初始化") self.ai_agent = type('AIAgent', (), { 'process_input': lambda self, input, user_id: f"你好{user_id},我收到了你的消息: '{input}'" })() def start_evolution_monitor(self): logger.info("✅ 模拟进化监视器启动") def initialize_all(self): logger.info("=" * 50) logger.info("🚀 开始初始化AI系统") logger.info("=" * 50) self.initialize_system_paths() self.initialize_ai_core() self.initialize_hardware_manager() self.initialize_life_scheduler() self.initialize_ai_agent() self.initialize_environment_manager() self.start_evolution_monitor() logger.info("✅ 所有系统组件初始化完成") return { "ai_core": self.ai_core, "hardware_manager": self.hardware_manager, "life_scheduler": self.life_scheduler, "ai_agent": self.ai_agent, "environment_manager": self.environment_manager } # ========== 环境交互路由 ========== def register_environment_routes(app): @app.route('/environment') def environment_view(): return render_template('environment_view.html') @app.route('/api/environment/state', methods=['GET']) @app.config['LIMITER'].limit("10 per minute") def get_environment_state(): env_manager = app.config['SYSTEM_COMPONENTS'].get('environment_manager') if not env_manager: return jsonify({"success": False, "error": "环境管理器未初始化"}), 503 try: state = env_manager.get_state() return jsonify(state) except Exception as e: app.logger.error(f"获取环境状态失败: {traceback.format_exc()}") return jsonify({"success": False, "error": str(e)}), 500 @app.route('/api/environment/action', methods=['POST']) @app.config['LIMITER'].limit("5 per minute") def execute_environment_action(): env_manager = app.config['SYSTEM_COMPONENTS'].get('environment_manager') if not env_manager: return jsonify({"success": False, "error": "环境管理器未初始化"}), 503 try: data = request.json action = data.get('action') params = data.get('params', {}) if not action: return jsonify({"success": False, "error": "缺少动作参数"}), 400 success = env_manager.execute_action(action, params) return jsonify({"success": success, "action": action}) except Exception as e: app.logger.error(f"执行环境动作失败: {traceback.format_exc()}") return jsonify({"success": False, "error": str(e)}), 500 # ========== 路由注册 ========== def register_routes(app): # 添加根路由 - 关键修复 @app.route('/') def home(): """根路由显示欢迎页面""" current_time = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") return f""" <!DOCTYPE html> <html> <head> <title>AI系统控制中心</title> <style> body {{ font-family: Arial, sans-serif; margin: 40px; background-color: #f5f8fa; }} .container {{ max-width: 800px; margin: 0 auto; padding: 20px; background: white; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }} h1 {{ color: #2c3e50; text-align: center; margin-bottom: 30px; }} .status {{ background: #f8f9fa; padding: 20px; border-radius: 8px; margin-top: 30px; border-left: 4px solid #3498db; }} .links {{ margin-top: 20px; display: flex; justify-content: center; flex-wrap: wrap; gap: 15px; }} .links a {{ display: inline-block; padding: 12px 25px; background: #3498db; color: white; text-decoration: none; border-radius: 4px; transition: all 0.3s ease; text-align: center; min-width: 150px; }} .links a:hover {{ background: #2980b9; transform: translateY(-2px); box-shadow: 0 4px 8px rgba(0,0,0,0.1); }} .footer {{ text-align: center; margin-top: 30px; color: #7f8c8d; font-size: 0.9em; }} </style> </head> <body> <div class="container"> <h1>🤖 AI系统控制中心</h1> <p>欢迎访问AI系统控制面板,请选择以下功能:</p> <div class="links"> <a href="/environment">🌍 环境监控</a> <a href="/life/dashboard">📅 生活调度</a> <a href="/status">📊 系统状态</a> <a href="/health">🩺 健康检查</a> <a href="/chat">💬 聊天交互</a> </div> <div class="status"> <h3>系统状态</h3> <p>✅ 服务器已启动,运行正常</p> <p>🕒 启动时间: {current_time}</p> <p>📍 服务器地址: http://{request.host}</p> </div> <div class="footer"> <p>AI系统控制中心 v1.0 | 技术支持: support@ai-system.com</p> </div> </div> </body> </html> """ register_environment_routes(app) # 静态文件路由 @app.route('/static/<path:filename>') def static_files(filename): return send_from_directory(app.static_folder, filename) # 健康检查路由 @app.route('/health') def health_check(): return jsonify({"status": "healthy", "timestamp": datetime.datetime.now().isoformat()}) # 系统状态路由 @app.route('/status') @app.config['LIMITER'].exempt def status(): components = app.config['SYSTEM_COMPONENTS'] system_info = { "uptime": time.time() - app.config['START_TIME'], "ai_core_status": components['ai_core'].status if components['ai_core'] else "uninitialized", "hardware_status": components['hardware_manager'].get_status() if components[ 'hardware_manager'] else "uninitialized", "life_scheduler_status": components['life_scheduler'].get_status() if components[ 'life_scheduler'] else "uninitialized", "environment_status": components['environment_manager'].is_healthy() if components[ 'environment_manager'] else "uninitialized", "platform": platform.platform(), "python_version": sys.version, "memory_usage": psutil.virtual_memory().percent, "cpu_usage": psutil.cpu_percent(), "thread_count": threading.active_count(), "process_id": os.getpid() } return jsonify(system_info) # 核心系统路由 @app.route('/api/core/state') @app.config['LIMITER'].limit("10 per minute") def get_core_state(): ai_core = app.config['SYSTEM_COMPONENTS'].get('ai_core') if not ai_core: return jsonify({"error": "AI核心未初始化"}), 503 return jsonify(ai_core.get_state()) # 生活系统路由 @app.route('/life/dashboard') def life_dashboard(): return render_template('life_dashboard.html') @app.route('/api/life/status') @app.config['LIMITER'].limit("10 per minute") def get_life_status(): life_scheduler = app.config['SYSTEM_COMPONENTS'].get('life_scheduler') if not life_scheduler: return jsonify({"error": "生活调度器未初始化"}), 503 status = life_scheduler.get_status() return jsonify(status) # 聊天路由 @app.route('/chat', methods=['GET']) def chat_interface(): """聊天界面""" return render_template('chat.html') @app.route('/api/chat', methods=['POST']) @app.config['LIMITER'].limit("30 per minute") def chat_handler(): """处理聊天请求的API端点""" components = app.config['SYSTEM_COMPONENTS'] if not components['ai_agent']: return jsonify({"error": "Agent未初始化"}), 503 try: data = request.get_json() user_input = data.get('message', '') user_id = data.get('user_id', 'default') if not user_input: return jsonify({"error": "消息内容不能为空"}), 400 app.logger.info(f"聊天请求: 用户={user_id}, 内容长度={len(user_input)}") # 使用线程池异步处理 future = executor.submit(components['ai_agent'].process_input, user_input, user_id) response = future.result(timeout=10) # 10秒超时 return jsonify({"response": response}) except TimeoutError: return jsonify({"error": "处理超时"}), 504 except Exception as e: app.logger.error(f"聊天处理失败: {traceback.format_exc()}") return jsonify({"error": "聊天处理失败", "details": str(e)}), 500 # 404处理 @app.route('/<path:path>') def catch_all(path): return jsonify({"error": "路由不存在", "path": path}), 404 def register_error_handlers(app): @app.errorhandler(404) def not_found_error(error): return jsonify({"error": "资源未找到", "message": str(error)}), 404 @app.errorhandler(500) def internal_error(error): app.logger.error(f"服务器内部错误: {str(error)}") return jsonify({"error": "服务器内部错误", "message": "请查看日志获取详细信息"}), 500 # ========== WebSocket处理 ========== def setup_websocket_handlers(socketio): @socketio.on('connect') def handle_connect(): logger.info('客户端已连接') socketio.emit('system_status', {'status': 'ready'}) @socketio.on('disconnect') def handle_disconnect(): logger.info('客户端已断开连接') @socketio.on('user_message') def handle_user_message(data): user_id = data.get('user_id', 'guest') message = data.get('message', '') logger.info(f"收到来自 {user_id} 的消息: {message}") # 使用线程池处理消息 def process_message(): try: global coordinator if coordinator: return coordinator.process_message(message) else: return f"已收到您的消息: {message}" except Exception as e: logger.error(f"消息处理失败: {str(e)}") return "处理消息时出错" future = executor.submit(process_message) try: response = future.result(timeout=10) socketio.emit('agent_response', { 'user_id': user_id, 'response': response }) except TimeoutError: socketio.emit('agent_response', { 'user_id': user_id, 'response': "处理超时,请重试" }) # ========== 生产环境启动器 ========== def run_production_server(app): try: from waitress import serve logger.info(f"🚀 生产服务器启动: http://{config.HOST}:{config.PORT}") logger.warning("⚠️ 当前运行在生产模式 (Waitress WSGI服务器)") serve(app, host=config.HOST, port=config.PORT, threads=8) except ImportError: logger.error("❌ 缺少生产环境依赖: waitress") logger.info("请运行: pip install waitress") sys.exit(1) # ========== Flask应用工厂 ========== def create_app(): app = Flask( __name__, template_folder=str(config.TEMPLATE_DIR), static_folder=str(config.STATIC_DIR), static_url_path='/static' ) app.secret_key = config.SECRET_KEY # 初始化限流器 limiter = Limiter( get_remote_address, app=app, default_limits=["200 per day", "50 per hour"], storage_uri="memory://" ) app.config['LIMITER'] = limiter system_initializer = SystemInitializer() components = system_initializer.initialize_all() app.config['SYSTEM_COMPONENTS'] = components app.config['START_TIME'] = system_initializer.start_time app.config['BASE_DIR'] = system_initializer.base_dir # 配置SocketIO async_mode = 'threading' try: import eventlet async_mode = 'eventlet' logger.info("✅ 使用eventlet异步模式") except ImportError: logger.warning("⚠️ eventlet未安装,使用threading模式") pass # 注册路由和错误处理 register_routes(app) register_error_handlers(app) # 创建SocketIO实例 socketio = SocketIO(app, async_mode=async_mode, logger=False, engineio_logger=False) setup_websocket_handlers(socketio) app.config['SOCKETIO'] = socketio return app, socketio # ========== 主程序入口 ========== if __name__ == '__main__': app, socketio = create_app() # 启动服务器 if os.environ.get('ENV') == 'production': run_production_server(app) else: logger.info(f"🚀 开发服务器启动: http://{config.HOST}:{config.PORT}") socketio.run( app, host=config.HOST, port=config.PORT, debug=config.DEBUG, use_reloader=False ) # E:\AI_System\agent\autonomous_agent.py import os import sys import time import logging import importlib import traceback import psutil import platform import threading import json from pathlib import Path from dotenv import load_dotenv from typing import Dict, Any, Optional, List, Callable from concurrent.futures import ThreadPoolExecutor from ..core.config import system_config # 使用绝对导入 - 确保路径正确 sys.path.insert(0, str(Path(__file__).resolve().parent.parent)) from core.config import system_config from core.exceptions import DependencyError, SubsystemFailure from core.dependency_manager import DependencyManager from core.metrics import PerformanceMetrics, MetricsCollector # 全局线程池 executor = ThreadPoolExecutor(max_workers=4) class AutonomousAgent: def __init__(self): """自主智能体核心类,负责协调所有子系统""" self.logger = self._setup_logger() self.logger.info("🔁 初始化自主智能体核心模块...") self._running = False # 运行状态标志 self._background_thread = None # 后台线程 # 初始化状态跟踪 self.initialization_steps = [] self._last_env_check = 0 self._initialization_time = time.time() self.subsystem_status = {} # 子系统熔断状态 self.metrics = MetricsCollector() # 性能监控 self._status_lock = threading.Lock() # 状态锁 # 依赖管理器 self.dependency_manager = DependencyManager() try: # 记录初始化步骤 self._record_step("加载环境变量") load_dotenv() self._record_step("验证环境") self.verify_environment() self._record_step("初始化核心组件") self._initialize_core_components() self._record_step("初始化子系统") self._initialize_subsystems() self.logger.info(f"✅ 自主智能体初始化完成 (耗时: {time.time() - self._initialization_time:.2f}秒)") self.logger.info(f"初始化步骤: {', '.join(self.initialization_steps)}") # 启动后台任务线程 self._start_background_tasks() except Exception as e: self.logger.exception(f"❌ 智能体初始化失败: {str(e)}") self.logger.error(f"堆栈跟踪:\n{traceback.format_exc()}") raise RuntimeError(f"智能体初始化失败: {str(e)}") from e def _start_background_tasks(self): """启动后台任务线程""" if self._running: self.logger.warning("后台任务已在运行") return self._running = True self._background_thread = threading.Thread( target=self._background_task_loop, daemon=True, name="AutonomousAgentBackgroundTasks" ) self._background_thread.start() self.logger.info("✅ 后台任务线程已启动") def _background_task_loop(self): """后台任务循环""" while self._running: try: start_time = time.time() self.run_periodic_tasks() # 动态调整睡眠时间 task_time = time.time() - start_time sleep_time = max(0.1, 10 - task_time) # 确保至少10秒间隔 time.sleep(sleep_time) except Exception as e: self.logger.error(f"后台任务错误: {str(e)}") self.metrics.record_error('background_task') time.sleep(30) def _record_step(self, step_name: str): """记录初始化步骤""" self.initialization_steps.append(step_name) self.logger.info(f"⏳ 步骤 {len(self.initialization_steps)}: {step_name}") def verify_environment(self): """验证运行环境是否满足要求""" missing = [] warnings = [] # 检查必需模块 required_modules = [ 'os', 'sys', 'logging', 'dotenv', 'flask', 'werkzeug', 'numpy', 'transformers', 'torch', 'psutil' ] for mod in required_modules: try: importlib.import_module(mod) except ImportError: missing.append(mod) # 检查配置文件 if not hasattr(system_config, 'CONFIG_PATH') or not os.path.exists(system_config.CONFIG_PATH): self.logger.error(f"❌ 配置文件缺失: {system_config.CONFIG_PATH}") warnings.append(f"配置文件缺失: {system_config.CONFIG_PATH}") # 检查模型目录 - 如果不存在则创建 model_dir = Path(system_config.MODEL_CACHE_DIR) if not model_dir.exists(): model_dir.mkdir(parents=True, exist_ok=True) self.logger.warning(f"⚠️ 创建模型缓存目录: {model_dir}") # 检查日志目录 - 如果不存在则创建 log_dir = Path(system_config.LOG_DIR) if not log_dir.exists(): log_dir.mkdir(parents=True, exist_ok=True) self.logger.warning(f"⚠️ 创建日志目录: {log_dir}") # 处理警告 for warning in warnings: self.logger.warning(warning) # 处理缺失项 if missing: error_msg = f"环境验证失败,缺失: {', '.join(missing)}" self.logger.error(error_msg) self.dependency_manager.record_missing_dependencies(missing) raise DependencyError(error_msg) self.logger.info("✅ 环境验证通过") def _setup_logger(self) -> logging.Logger: """配置日志记录器""" logger = logging.getLogger('AutonomousAgent') logger.setLevel(system_config.LOG_LEVEL) # 创建控制台处理器 console_handler = logging.StreamHandler() console_handler.setLevel(system_config.LOG_LEVEL) # 创建文件处理器 log_file = Path(system_config.LOG_DIR) / 'autonomous_agent.log' file_handler = logging.FileHandler(log_file, encoding='utf-8') file_handler.setLevel(system_config.LOG_LEVEL) # 创建格式化器 formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) # 添加处理器 logger.addHandler(console_handler) logger.addHandler(file_handler) logger.propagate = False return logger def _initialize_core_components(self): """初始化不依赖其他组件的核心组件""" # 获取项目根目录 base_dir = Path(__file__).resolve().parent.parent # 环境相关组件 - 使用回退实现 self.environment = self._create_fallback_environment(base_dir) self.logger.info("✅ 环境接口初始化完成") # 记录环境状态 self._log_environment_status() # 初始化状态持久化 self._load_subsystem_status() def _create_fallback_environment(self, base_dir: Path): """创建回退的环境实现""" class FallbackEnvironment: def __init__(self, base_dir): self.base_dir = base_dir self.status_file = base_dir / 'environment_status.json' def get_system_info(self): try: # 尝试从文件加载状态 if self.status_file.exists(): with open(self.status_file, 'r') as f: return json.load(f) except: pass # 创建新状态 status = { "os": platform.system(), "os_version": platform.version(), "cpu": platform.processor(), "cpu_cores": psutil.cpu_count(logical=False), "memory_total": round(psutil.virtual_memory().total / (1024 ** 3), 1), "memory_used": round(psutil.virtual_memory().used / (1024 ** 3), 1), "disk_total": round(psutil.disk_usage('/').total / (1024 ** 3), 1), "disk_used": round(psutil.disk_usage('/').used / (1024 ** 3), 1), "timestamp": time.time() } # 保存状态 try: with open(self.status_file, 'w') as f: json.dump(status, f) except: pass return status return FallbackEnvironment(base_dir) def _log_environment_status(self): """记录环境状态信息""" try: env_status = self.environment.get_system_info() or {} self.logger.info( f"📊 系统状态: OS={env_status.get('os', '未知')} {env_status.get('os_version', '')}, " f"CPU={env_status.get('cpu', '未知')} ({env_status.get('cpu_cores', 0)}核), " f"内存={env_status.get('memory_used', 0)}/{env_status.get('memory_total', 0)}GB, " f"磁盘={env_status.get('disk_used', 0)}/{env_status.get('disk_total', 0)}GB" ) except Exception as e: self.logger.error(f"环境状态获取失败: {str(e)}") self.metrics.record_error('environment_status') def _initialize_subsystems(self): """初始化所有子系统 - 使用动态导入并添加详细错误处理""" # 定义子系统初始化顺序 - 使用更简单的回退实现 subsystems = [ ('健康系统', self._create_fallback_health_system, {}), ('模型管理器', self._create_fallback_model_manager, {}), ('记忆系统', self._create_fallback_memory_system, {}), ('情感系统', self._create_fallback_affective_system, {}), ('认知架构', self._create_fallback_cognitive_architecture, {}), ('通信系统', self._create_fallback_communication_system, {}) ] # 注册子系统依赖关系 self.dependency_manager.register_dependency('通信系统', ['认知架构']) self.dependency_manager.register_dependency('情感系统', ['健康系统', '记忆系统']) self.dependency_manager.register_dependency('认知架构', ['记忆系统']) # 初始化子系统 for name, creator_func, kwargs in subsystems: try: # 检查依赖是否满足 missing_deps = self.dependency_manager.check_dependencies(name) if missing_deps: self.logger.warning(f"⚠️ 子系统 {name} 缺少依赖: {', '.join(missing_deps)}") # 尝试自动安装缺失依赖 self.dependency_manager.install_missing_dependencies(missing_deps) # 创建实例 instance = creator_func(**kwargs) setattr(self, name.lower().replace(' ', '_'), instance) self.logger.info(f"✅ {name}初始化完成") # 标记子系统为活跃状态 with self._status_lock: self.subsystem_status[name] = { 'active': True, 'error_count': 0, 'last_active': time.time(), 'last_recovery_attempt': 0 } except Exception as e: self.logger.error(f"❌ {name}初始化失败: {str(e)}") with self._status_lock: self.subsystem_status[name] = { 'active': False, 'error': str(e), 'error_count': 1, 'last_error': time.time() } # 记录指标 self.metrics.record_error(f'subsystem_init_{name.lower()}') # 保存子系统状态 self._save_subsystem_status() # 各子系统回退实现保持不变... def process_input(self, user_input: str, user_id: str = "default") -> Dict[str, Any]: """处理用户输入(通过通信系统)""" # 检查通信系统是否活跃 with self._status_lock: comm_status = self.subsystem_status.get('通信系统', {}) active = comm_status.get('active', False) if not active: self.logger.error("通信系统未激活,使用回退处理") self.metrics.record_error('communication_system_inactive') return {"response": "系统正在维护中,请稍后再试"} try: # 使用性能监控 with PerformanceMetrics() as pm: # 使用线程池异步处理 future = executor.submit( self.communication_system.process_input, user_input, user_id ) response = future.result(timeout=10) # 10秒超时 # 记录性能指标 self.metrics.record_latency('process_input', pm.duration) self.metrics.record_success('process_input') self.logger.info(f"📥 处理输入: '{user_input[:30]}...' → 耗时: {pm.duration:.2f}秒") return response except TimeoutError: self.logger.warning("处理输入超时") self.metrics.record_timeout('process_input') return {"error": "处理超时,请重试"} except Exception as e: # 更新错误计数 with self._status_lock: comm_status = self.subsystem_status.get('通信系统', {}) comm_status['error_count'] = comm_status.get('error_count', 0) + 1 comm_status['last_error'] = time.time() # 检查熔断条件 if comm_status['error_count'] >= 5: # 临时阈值 comm_status['active'] = False self.logger.critical(f"🚨 通信系统因连续错误被熔断!") self.metrics.record_event('circuit_breaker', '通信系统') self.logger.error(f"处理输入失败: {str(e)}") self.metrics.record_error('process_input') return {"error": "处理失败,请稍后再试"} def run_periodic_tasks(self): """运行周期性任务""" task_start = time.time() tasks_executed = 0 tasks_failed = 0 # 定义任务列表 tasks = [ ('健康系统更新', lambda: self.health_system.update()), ('情感系统更新', lambda: self.affective_system.grow()), ('记忆系统维护', lambda: self.memory_system.consolidate_memories()), ('环境监控', self._monitor_environment), ('子系统心跳检查', self._check_subsystem_heartbeats), ('子系统恢复', self._recover_failed_subsystems) ] # 执行任务 for name, task_func in tasks: try: if name == '环境监控' or self._is_subsystem_active(name.split()[0]): task_func() tasks_executed += 1 except Exception as e: tasks_failed += 1 subsystem_name = name.split()[0] self.logger.error(f"{name}失败: {str(e)}", exc_info=True) self._handle_subsystem_error(subsystem_name, e) self.metrics.record_error(f'periodic_{subsystem_name.lower()}') # 记录任务执行情况 if tasks_executed > 0: task_time = time.time() - task_start self.logger.debug(f"⏱️ 执行 {tasks_executed} 项周期性任务 ({tasks_failed}失败), 耗时: {task_time:.3f}秒") self.metrics.record_latency('periodic_tasks', task_time) self.metrics.record_value('periodic_tasks_count', tasks_executed) self.metrics.record_value('periodic_tasks_failed', tasks_failed) def _is_subsystem_active(self, name: str) -> bool: """检查子系统是否活跃""" with self._status_lock: status = self.subsystem_status.get(name, {}) return status.get('active', False) def _handle_subsystem_error(self, name: str, error: Exception): """处理子系统错误""" with self._status_lock: status = self.subsystem_status.get(name, {}) status['error_count'] = status.get('error_count', 0) + 1 status['last_error'] = time.time() # 检查熔断条件 if status['error_count'] >= 5: # 临时阈值 status['active'] = False self.logger.critical(f"🚨 子系统 {name} 因连续错误被熔断!") self.metrics.record_event('circuit_breaker', name) def _check_subsystem_heartbeats(self): """检查子系统心跳""" for name in list(self.subsystem_status.keys()): with self._status_lock: status = self.subsystem_status.get(name, {}) if not status.get('active', False): continue # 跳过已熔断的 subsystem = getattr(self, name.lower().replace(' ', '_'), None) if subsystem and hasattr(subsystem, 'check_heartbeat'): try: if not subsystem.check_heartbeat(): self.logger.warning(f"⚠️ 子系统 {name} 心跳检测失败") self._handle_subsystem_error(name, RuntimeError("心跳检测失败")) else: # 更新最后活跃时间 with self._status_lock: status['last_active'] = time.time() except Exception as e: self.logger.error(f"子系统 {name} 心跳检查异常: {str(e)}") self._handle_subsystem_error(name, e) self.metrics.record_error(f'heartbeat_{name.lower()}') def _recover_failed_subsystems(self): """尝试恢复失败的子系统""" for name in list(self.subsystem_status.keys()): with self._status_lock: status = self.subsystem_status.get(name, {}) if status.get('active', False): continue # 跳过活跃的 # 检查恢复条件:错误后至少等待5分钟 last_error = status.get('last_error', 0) if time.time() - last_error < 300: continue # 检查上次恢复尝试时间 last_attempt = status.get('last_recovery_attempt', 0) if time.time() - last_attempt < 600: # 每10分钟尝试一次 continue self.logger.info(f"🔄 尝试恢复子系统: {name}") status['last_recovery_attempt'] = time.time() try: # 尝试重新初始化子系统 # 这里需要根据子系统名称调用相应的初始化方法 # 简化实现:直接重置状态 subsystem = self._reinitialize_subsystem(name) setattr(self, name.lower().replace(' ', '_'), subsystem) with self._status_lock: status['active'] = True status['error_count'] = 0 status['last_error'] = 0 self.logger.info(f"✅ 子系统 {name} 恢复成功") self.metrics.record_event('subsystem_recovered', name) except Exception as e: with self._status_lock: status['active'] = False status['error_count'] += 1 status['last_error'] = time.time() self.logger.error(f"子系统 {name} 恢复失败: {str(e)}") self.metrics.record_error(f'recovery_{name.lower()}') def _reinitialize_subsystem(self, name: str) -> Any: """重新初始化子系统""" # 根据名称选择初始化方法 creators = { '健康系统': self._create_fallback_health_system, '模型管理器': self._create_fallback_model_manager, '记忆系统': self._create_fallback_memory_system, '情感系统': self._create_fallback_affective_system, '认知架构': self._create_fallback_cognitive_architecture, '通信系统': self._create_fallback_communication_system } if name in creators: return creators[name]() else: raise SubsystemFailure(f"未知子系统: {name}") def _monitor_environment(self): """监控环境状态""" try: self.logger.info("🔍 开始环境监控...") env_status = self.environment.get_system_info() or {} # 获取CPU和内存使用情况 env_status['cpu_usage'] = psutil.cpu_percent() env_status['memory_usage'] = psutil.virtual_memory().percent env_status['disk_usage'] = psutil.disk_usage('/').percent # 记录到日志 self.logger.info( f"📊 环境监控: CPU={env_status['cpu_usage']}%, " f"内存={env_status['memory_usage']}%, " f"磁盘={env_status['disk_usage']}%" ) # 记录到健康系统 if hasattr(self, 'health_system'): self.health_system.record_environment_status(env_status) # 记录指标 self.metrics.record_value('cpu_usage', env_status['cpu_usage']) self.metrics.record_value('memory_usage', env_status['memory_usage']) self.metrics.record_value('disk_usage', env_status['disk_usage']) except Exception as e: self.logger.error(f"环境监控失败: {str(e)}", exc_info=True) self.metrics.record_error('environment_monitoring') def _save_subsystem_status(self): """保存子系统状态到文件""" status_file = Path(system_config.CONFIG_DIR) / 'subsystem_status.json' try: with self._status_lock: data = { 'timestamp': time.time(), 'status': self.subsystem_status } with open(status_file, 'w') as f: json.dump(data, f, indent=2) except Exception as e: self.logger.error(f"保存子系统状态失败: {str(e)}") def _load_subsystem_status(self): """从文件加载子系统状态""" status_file = Path(system_config.CONFIG_DIR) / 'subsystem_status.json' if status_file.exists(): try: with open(status_file, 'r') as f: data = json.load(f) # 只加载24小时内的状态 if time.time() - data.get('timestamp', 0) < 86400: with self._status_lock: self.subsystem_status = data.get('status', {}) self.logger.info("加载子系统状态缓存") except Exception as e: self.logger.error(f"加载子系统状态失败: {str(e)}") def get_status(self) -> Dict[str, Any]: """获取智能体状态报告""" with self._status_lock: status_data = { "uptime": time.time() - self._initialization_time, "subsystems": { name: info.get('active', False) for name, info in self.subsystem_status.items() }, "circuit_breaker": { name: { "active": info.get('active', False), "error_count": info.get('error_count', 0), "last_error": info.get('last_error', 0) } for name, info in self.subsystem_status.items() }, "metrics": self.metrics.get_metrics(), "environment": self.environment.get_system_info() if hasattr(self, 'environment') else {} } # 添加子系统状态 for name in ['健康系统', '情感系统', '记忆系统', '模型管理器', '认知架构', '通信系统']: attr_name = name.lower().replace(' ', '_') if hasattr(self, attr_name) and hasattr(getattr(self, attr_name), 'get_status'): status_data[name] = getattr(self, attr_name).get_status() return status_data def shutdown(self): """关闭智能体""" self.logger.info("🛑 正在关闭智能体...") self._running = False # 停止线程池 executor.shutdown(wait=False) # 保存状态 self._save_subsystem_status() # 等待后台线程 if self._background_thread and self._background_thread.is_alive(): self._background_thread.join(timeout=5.0) if self._background_thread.is_alive(): self.logger.warning("后台线程未正常退出") self.logger.info("✅ 智能体已关闭") 你看看怎么修改 主要是哪个模块没启动 哪里有问题 我需要知道 你理解吗?
08-13
请优化以下前后端代码,我手动修改数据库内容,后端未同步到前端。前端代码:// pages/order-detail/order-detail.js Page({ data: { activeIndex: 0, // 当前选中的状态索引 statusList: [‘新订单’, ‘备货中’, ‘待配送’, ‘配送中’, ‘已完成’, ‘已取消’], // 订单状态列表 showActionSheet: false, // 是否显示操作面板 currentOrderId: null, // 当前操作的订单ID cancelOrderCount: 0, // 取消订单次数 lastCancelDate: null, // 最后一次取消订单的日期 searchText: ‘’, // 搜索关键字 orders: [], // 所有订单数据 filteredOrders: [], // 筛选后的订单数据 isLoading: false, // 是否正在加载数据 page: 1, // 当前页码 pageSize: 10, // 每页大小 hasMore: true ,// 是否还有更多数据 socketOpen: false, // WebSocket 是否已打开 socketTask: null, // WebSocket 实例 socketRetryCount: 0, // WebSocket 重试次数 }, // onLoad() { // this.loadOrders(); // 加载订单数据 // this.loadCancelInfo(); // 加载取消订单信息 // }, onReachBottom() { if (this.data.hasMore && !this.data.isLoading) { this.setData({ page: this.data.page + 1 }, () => { this.loadOrders(); }); } }, loadCancelInfo() { const cancelInfo = wx.getStorageSync(‘cancelOrderInfo’) || {}; this.setData({ cancelOrderCount: cancelInfo.count || 0, lastCancelDate: cancelInfo.date || null }); }, onLoad() { this.loadOrders(); // 加载订单数据 this.initWebSocket(); // 初始化 WebSocket }, onUnload() { this.closeWebSocket(); // 页面卸载时关闭 WebSocket }, // 初始化 WebSocket // 修改后的 initWebSocket 方法 // 修改后的 initWebSocket 方法 initWebSocket() { const that = this; // 先关闭现有连接 this.closeWebSocket(); // 检查是否超过最大重试次数 if (this.data.socketRetryCount >= 5) { console.log(‘已达到最大重连次数,停止尝试’); wx.showToast({ title:网络连接不稳定,请检查网络后重试’, icon: ‘none’ }); return; } const socketTask = wx.connectSocket({ url: ‘ws://127.0.0.1:8001/ws/orders/’, header: { ‘Authorization’: 'Bearer ’ + wx.getStorageSync(‘token’) }, success: () => { console.log(‘WebSocket连接初始化成功’); }, fail: (err) => { console.error(‘WebSocket连接初始化失败:’, err); that.handleSocketError(); } }); socketTask.onOpen(() => { console.log(‘WebSocket已连接’); // 发送加入组请求(使用统一组名) socketTask.send({ data: JSON.stringify({ type: "join_group", group: "order_updates" }) }); // 启动心跳 that.heartbeatInterval = setInterval(() => { if (that.data.socketOpen && socketTask) { console.log('发送消息:', JSON.stringify({ type: 'heartbeat' })); socketTask.send({ data: JSON.stringify({ type: 'heartbeat' }), success: () => console.log('心跳发送成功'), fail: (err) => { console.log('心跳发送失败', err); that.handleSocketError(); } }); } }, 25000); }); socketTask.onMessage((res) => { try { const message = JSON.parse(res.data); console.log(‘收到消息:’, message); switch (message.type) { case 'order_update': this.handleOrderUpdate(message.data); break; case 'heartbeat_ack': console.log('心跳响应:', message.timestamp); break; case 'system': console.log('系统消息:', message.message); break; case 'error': console.error('服务器返回错误:', message); wx.showToast({ title: message.message || '服务器错误', icon: 'none' }); break; default: console.warn('未知消息类型:', message.type); } } catch (e) { console.error(‘消息处理错误:’, e); } }); socketTask.onError((err) => { console.error(‘WebSocket错误:’, err); that.handleSocketError(); }); socketTask.onClose(() => { console.log(‘WebSocket关闭’); that.handleSocketClose(); }); this.setData({ socketTask, socketOpen: true }); }, handleSocketError() { this.setData({ socketOpen: false }); clearInterval(this.heartbeatInterval); // 增加重连延迟 setTimeout(() => { this.setData(prev => ({ socketRetryCount: prev.socketRetryCount + 1 })); console.log(尝试第 ${this.data.socketRetryCount} 次重连...); this.initWebSocket(); }, 5000); // 5秒后重连 }, handleSocketClose() { this.setData({ socketOpen: false }); clearInterval(this.heartbeatInterval); if (!this.data.isManualClose) { this.handleSocketError(); } }, closeWebSocket() { if (this.data.socketTask) { this.setData({ isManualClose: true }); this.data.socketTask.close(); this.setData({ socketTask: null }); } clearInterval(this.heartbeatInterval); }, handleOrderUpdate(data) { console.log(‘处理订单更新:’, data); const { id, orderNo, status } = data; // 更新本地订单状态 const updatedOrders = this.data.orders.map(order => { if (order.orderId === orderNo) { return { …order, status }; } return order; }); this.setData({ orders: updatedOrders, filteredOrders: this.filterOrders(updatedOrders) }); }, filterOrders(orders = this.data.orders) { const { activeIndex, statusList, searchText } = this.data; const currentStatus = statusList[activeIndex]; let filtered = orders.filter(order => { if (currentStatus !== ‘全部’ && order.status !== currentStatus) { return false; } if (searchText && !order.orderId.includes(searchText) && !order.customerName.includes(searchText) && !order.customerPhone.includes(searchText)) { return false; } return true; }); filtered.sort((a, b) => new Date(b.createTime) - new Date(a.createTime)); return filtered; }, async loadOrders() { if (this.data.isLoading || !this.data.hasMore) return; this.setData({ isLoading: true }); try { const { statusList, activeIndex, searchText, page, pageSize } = this.data; const currentStatus = statusList[activeIndex]; const user = wx.getStorageSync('userInfo'); const shopId = user.id; // 确保已存储shopId const res = await new Promise((resolve, reject) => { wx.request({ url: 'http://127.0.0.1:8000/api/gouw/merchant/orders/', method: 'GET', header: { 'Authorization': 'Bearer ' + wx.getStorageSync('token'), 'Content-Type': 'application/json' }, data: { shop_id: shopId, status: currentStatus, search: searchText, page: page, page_size: pageSize }, success: (res) => { if (res.statusCode === 200) { resolve(res.data); } else { reject(new Error(`HTTP ${res.statusCode}: ${res.data?.message || '请求失败'}`)); } }, fail: (err) => { reject(new Error('网络请求失败')); } }); }); console.log('API响应数据:', JSON.stringify(res, null, 2)); if (res.code === 200) { const newOrders = res.data.orders.map(order => ({ id: order.orderId, orderId: order.orderNo, customerName: order.customerName, customerPhone: order.customerPhone, status: order.status, statusCode: order.statusCode, createTime: order.createTime, totalAmount: order.totalAmount, products: order.products, deliveryFee: order.deliveryFee })); this.setData({ orders: page === 1 ? newOrders : [...this.data.orders, ...newOrders], filteredOrders: page === 1 ? newOrders : [...this.data.orders, ...newOrders], hasMore: page < res.data.pagination.totalPages, isLoading: false }); } else { throw new Error(res.message || '加载订单失败'); } } catch (err) { console.error('加载订单错误:', err.message, err); wx.showToast({ title: err.message || '加载订单失败', icon: 'none', duration: 2000 }); this.setData({ isLoading: false }); } }, // 加载订单数据 // async loadOrders() { // try { // const user = wx.getStorageSync(‘userInfo’); // const shopId = user.id; // const res = await new Promise((resolve, reject) => { // wx.request({ // url: ‘http://127.0.0.1:8000/api/gouw/merchant/orders/’, // method: ‘GET’, // header: { // ‘Authorization’: 'Bearer ’ + wx.getStorageSync(‘token’), // ‘Content-Type’: ‘application/json’ // }, // data: { // shop_id: shopId, // status: ‘新订单’, // page: 1, // page_size: 10 // }, // success: (res) => { // if (res.statusCode === 200) { // resolve(res.data); // } else { // reject(new Error(HTTP ${res.statusCode}: ${res.data?.message || '请求失败'})); // } // }, // fail: (err) => { // reject(new Error(‘网络请求失败’)); // } // }); // }); // if (res.code === 200) { // const orders = res.data.orders.map(order => ({ // id: order.orderId, // orderId: order.orderNo, // customerName: order.customerName, // customerPhone: order.customerPhone, // status: order.status, // statusCode: order.statusCode, // createTime: order.createTime, // totalAmount: order.totalAmount, // products: order.products, // deliveryFee: order.deliveryFee // })); // this.setData({ // orders, // filteredOrders: orders // }); // } // } catch (err) { // console.error(‘加载订单错误:’, err.message); // } // }, // 切换订单状态 switchStatus(e) { const index = e.currentTarget.dataset.index; this.setData({ activeIndex: index, searchText: '', page: 1, hasMore: true }, () => { this.loadOrders(); }); }, // filterOrders() { // const { activeIndex, statusList, orders, searchText } = this.data; // const currentStatus = statusList[activeIndex]; // let filtered = orders.filter(order => { // if (currentStatus !== ‘全部’ && order.status !== currentStatus) { // return false; // } // if (searchText && !order.orderId.includes(searchText) && // !order.customerName.includes(searchText) && // !order.customerPhone.includes(searchText)) { // return false; // } // return true; // }); // filtered.sort((a, b) => new Date(b.createTime) - new Date(a.createTime)); // this.setData({ filteredOrders: filtered }); // }, handleSearchInput(e) { this.setData({ searchText: e.detail.value }); }, handleSearch() { this.setData({ page: 1, hasMore: true }, () => { this.loadOrders(); }); }, showActionSheet(e) { const orderId = e.currentTarget.dataset.orderid; this.setData({ showActionSheet: true, currentOrderId: orderId }); }, hideActionSheet() { this.setData({ showActionSheet: false, currentOrderId: null }); }, handleCancelOrder(e) { const orderId = e.currentTarget.dataset.orderid; const today = new Date().toDateString(); if (this.data.lastCancelDate === today && this.data.cancelOrderCount >= 3) { wx.showModal({ title: '提示', content: '当天取消接单次数已经用完,如需继续,请点击申诉', showCancel: false }); this.hideActionSheet(); return; } let newCount = this.data.cancelOrderCount; let newDate = this.data.lastCancelDate; if (newDate !== today) { newCount = 0; newDate = today; } newCount++; this.setData({ cancelOrderCount: newCount, lastCancelDate: newDate }); wx.setStorageSync('cancelOrderInfo', { count: newCount, date: newDate }); this.updateOrderStatus(orderId, '已取消'); wx.showToast({ title: '订单已取消', icon: 'success' }); this.hideActionSheet(); }, handleAppeal(e) { const orderId = e.currentTarget.dataset.orderid; this.hideActionSheet(); wx.navigateTo({ url: `/pages/appeal/appeal?orderId=${orderId}`, success: () => { console.log('跳转到申诉页面'); }, fail: (err) => { console.error('跳转失败:', err); wx.showToast({ title: '跳转失败,请重试', icon: 'none' }); } }); }, handleAcceptOrder(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, ‘备货中’); wx.showToast({ title: ‘接单成功’, icon: ‘success’ }); }, handleReadyForDelivery(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, ‘待配送’); wx.showToast({ title: ‘备货完成’, icon: ‘success’ }); }, handleStartDelivery(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, ‘配送中’); wx.showToast({ title: ‘开始配送’, icon: ‘success’ }); }, handleCompleteDelivery(e) { const orderId = e.currentTarget.dataset.orderid; this.updateOrderStatus(orderId, ‘已完成’); wx.showToast({ title: ‘配送完成’, icon: ‘success’ }); }, // 更新订单状态 async updateOrderStatus(orderId, newStatus) { const token = wx.getStorageSync(‘token’); if (!token) { wx.showToast({ title: ‘未登录,请重新登录’, icon: ‘none’ }); return; } wx.showLoading({ title: '处理中...', mask: true }); try { const res = await new Promise((resolve, reject) => { wx.request({ url: 'http://127.0.0.1:8000/api/gouw/update-order-status/', method: 'POST', header: { 'Authorization': 'Bearer ' + token, 'Content-Type': 'application/json' }, data: { order_no: orderId, status: newStatus }, success: (res) => { if (res.statusCode === 200 && res.data.code === 200) { resolve(res.data); } else { reject(new Error(res.data?.message || '更新失败')); } }, fail: (err) => { reject(new Error('网络请求失败')); } }); }); wx.hideLoading(); wx.showToast({ title: '操作成功', icon: 'success' }); // 从本地数据中移除已处理的订单 // 核心修改:更新本地订单状态并重新过滤 const updatedOrders = this.data.orders.map(order => { if (order.orderId === orderId) { return { ...order, status: newStatus }; } return order; }); this.setData({ // 从完整订单列表移除 orders: this.data.orders.filter(order => order.orderId !== orderId), // 从当前视图列表直接移除 filteredOrders: this.data.filteredOrders.filter(order => order.orderId !== orderId) }); wx.hideLoading(); wx.showToast({ title: '操作成功', icon: 'success' }); // this.loadOrders(); // 如果需要重新加载数据,可以调用 this.loadOrders(); } catch (err) { console.error('更新订单状态失败:', err.message); wx.hideLoading(); wx.showToast({ title: err.message || '操作失败,请重试', icon: 'none' }); } }, // 辅助方法:匹配搜索条件 matchSearchCriteria(order) { const searchText = this.data.searchText.toLowerCase(); return !searchText || order.orderId.toLowerCase().includes(searchText) || order.customerName.toLowerCase().includes(searchText) || order.customerPhone.includes(searchText); }, sj_mb(e) { wx.navigateTo({ url: “/pages/gr_xx/gr_xx”, success: () => { console.log(‘成功跳转到商家信息页面’); }, fail: (err) => { console.error(‘跳转失败:’, err); wx.showToast({ title: ‘跳转失败,请重试’, icon: ‘none’ }); } }); }, dp_zt(e) { wx.navigateTo({ url: “/pages/dp_zt/dp_zt”, success: () => { console.log(‘成功跳转到商家信息页面’); }, fail: (err) => { console.error(‘跳转失败:’, err); wx.showToast({ title: ‘跳转失败,请重试’, icon: ‘none’ }); } }); }, tk_dd(e) { wx.navigateTo({ url: “/pages/tk_dd/tk_dd”, success: () => { console.log(‘成功跳转到退款订单页面’); }, fail: (err) => { console.error(‘跳转失败:’, err); wx.showToast({ title: ‘跳转失败,请重试’, icon: ‘none’ }); } }); } }); 前端运行日志:WebSocket已连接 index.js:116 收到消息: {type: “system”, message: “连接成功”, timestamp: “2025-05-18T15:12:08.829969”} index.js:126 系统消息: 连接成功 index.js:149 WebSocket关闭 index.js? [sm]:166 尝试第 0 次重连… index.js? [sm]:78 WebSocket连接初始化成功 index.js? [sm]:87 WebSocket已连接 index.js? [sm]:116 收到消息: {type: “system”, message: “连接成功”, timestamp: “2025-05-18T15:12:13.772510”} index.js? [sm]:126 系统消息: 连接成功 index.js:166 尝试第 0 次重连… index.js:78 WebSocket连接初始化成功 index.js:87 WebSocket已连接 index.js:116 收到消息: {type: “system”, message: “连接成功”, timestamp: “2025-05-18T15:12:14.184758”} index.js:126 系统消息: 连接成功 index.js? [sm]:149 WebSocket关闭 index.js:149 WebSocket关闭 [worker] reportRealtimeAction:fail not support U @ WAWorker.js:1 invoke @ WAWorker.js:1 invoke @ WAWorker.js:1 G @ WAWorker.js:1 (anonymous) @ WAWorker.js:1 $e @ WAWorker.js:1 Z @ WAWorker.js:1 p @ WAWorker.js:1 (anonymous) @ WAWorker.js:1 (anonymous) @ WAWorker.js:1 setTimeout (async) globalThis.setTimeout @ WAWorker.js:1 Y @ WAWorker.js:1 Re @ WAWorker.js:1 (anonymous) @ WAWorker.js:1 r @ WAWorker.js:1 s @ WAWorker.js:1 callAndRemove @ WAWorker.js:1 invokeCallbackHandler @ WAWorker.js:1 eval @ VM16:1 后端代码:# DjangoProject1/asgi.py import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter from channels.auth import AuthMiddlewareStack from gouw.routing import websocket_urlpatterns os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'DjangoProject1.settings') application = ProtocolTypeRouter({ "http": get_asgi_application(), "websocket": AuthMiddlewareStack( URLRouter( websocket_urlpatterns ) ), }) # DjangoProject1/routing.py from django.urls import re_path, path from channels.routing import ProtocolTypeRouter, URLRouter from gouw.routing import websocket_urlpatterns as gouw_websockets application = ProtocolTypeRouter({ "websocket": URLRouter([ *gouw_websockets, # 将 gouw 的 WebSocket 路由引入 ]), }) # gouw/apps.py from django.apps import AppConfig class GouwConfig(AppConfig): name = 'gouw' def ready(self): # 确保信号被加载 import gouw.signals # 这行必须执行 print("信号已加载!") # 添加这行用于调试 # gouw/consumers.py from channels.generic.websocket import AsyncWebsocketConsumer import json from datetime import datetime import logging from asgiref.sync import async_to_sync from channels.layers import get_channel_layer logger = logging.getLogger(__name__) # 常量定义 ORDER_GROUP_NAME = "order_updates" # 统一定义组名 def broadcast_order_update(order_data): """广播订单更新到所有客户端""" try: channel_layer = get_channel_layer() async_to_sync(channel_layer.group_send)( ORDER_GROUP_NAME, { "type": "order.update", # 注意这里使用点号 "data": { # 添加data层保持结构一致 "id": order_data["id"], "orderNo": order_data["order_no"], "status": order_data["status"] } } ) logger.info(f"广播成功: {order_data}") except Exception as e: logger.error(f"广播失败: {str(e)}") class OrderConsumer(AsyncWebsocketConsumer): groups = [ORDER_GROUP_NAME] # 添加这行确保组名一致 async def connect(self): """开放连接(带基本验证)""" try: await self.accept() logger.info(f"新客户端连接: {self.channel_name}") await self.send(text_data=json.dumps({ "type": "system", "message": "连接成功", "timestamp": datetime.now().isoformat() })) except Exception as e: logger.error(f"连接处理错误: {str(e)}") await self.close(code=4001) async def disconnect(self, close_code): """断开连接处理""" try: await self.channel_layer.group_discard( ORDER_GROUP_NAME, self.channel_name ) logger.info(f"客户端断开: {close_code}") except Exception as e: logger.error(f"断开连接错误: {str(e)}") async def receive(self, text_data=None, bytes_data=None): """消息处理(带错误保护)""" try: data = json.loads(text_data) logger.debug(f"收到消息: {data}") # 加入组处理 if data.get("type") == "join_group": group_name = data.get("group") if group_name: await self.channel_layer.group_add( group_name, self.channel_name ) await self.send(text_data=json.dumps({ "type": "system", "message": f"成功加入组: {group_name}" })) else: await self.send(text_data=json.dumps({ "type": "error", "code": 4003, "message": "缺少必要字段: group" })) return # 心跳处理 if data.get("type") == "heartbeat": await self.send(text_data=json.dumps({ "type": "heartbeat_ack", "timestamp": datetime.now().isoformat() })) return # 处理其他消息类型 message_type = data.get("type", "unknown") if message_type == "order_update": order_id = data.get("id") order_status = data.get("status") logger.info(f"收到订单更新: ID={order_id}, 状态={order_status}") else: await self.send(text_data=json.dumps({ "type": "error", "code": 4002, "message": f"未知的消息类型: {message_type}" })) except json.JSONDecodeError as e: logger.error(f"消息解析失败: {str(e)}") await self.send(text_data=json.dumps({ "type": "error", "code": 4001, "message": "无效的JSON格式" })) except KeyError as e: logger.error(f"缺少必要字段: {str(e)}") await self.send(text_data=json.dumps({ "type": "error", "code": 4003, "message": f"缺少必要字段: {str(e)}" })) except Exception as e: logger.error(f"消息处理异常: {str(e)}") await self.send(text_data=json.dumps({ "type": "error", "code": 5000, "message": "服务器内部错误" })) async def order_update(self, event): """处理订单更新广播""" await self.send(text_data=json.dumps({ "type": "order_update", "data": { "id": event["data"]["id"], "orderNo": event["data"]["orderNo"], "status": event["data"]["status"] } })) # gouw/routing.py from django.urls import re_path from .consumers import OrderConsumer websocket_urlpatterns = [ re_path(r'ws/orders/$', OrderConsumer.as_asgi()), ] # # signals.py # from django.db.models.signals import post_save, post_delete # from django.dispatch import receiver # from .models import Order # from .consumers import broadcast_order_update # import logging # logger = logging.getLogger(__name__) # @receiver(post_save, sender=Order) # def order_updated(sender, instance, created, **kwargs): # print(f"订单更新信号触发!订单ID: {instance.id}") # 调试日志 # try: # # # 构建标准化消息数据 # order_data = { # "id": instance.id, # "order_no": instance.order_no, # "status": instance.status, # # "statusCode": instance.status, # "createTime": instance.create_time.isoformat(), # "totalAmount": float(instance.total_amount), # # "customerName": instance.customername, # # "customerPhone": instance.customerPhone, # # "products": [ # # { # # "name": item.product.name, # # "quantity": item.quantity, # # "price": float(item.price) # # } for item in instance.items.all() # # ] # } # # # 强制广播消息 # broadcast_order_update(order_data) # print(f"广播订单更新: {instance.id} 状态: {instance.status}") # # except Exception as e: # print(f"订单更新信号处理错误: {str(e)}") # # @receiver(post_save, sender=Order) # def order_updated(sender, instance, **kwargs): # broadcast_order_update({ # "id": instance.id, # "order_no": instance.order_no, # 使用下划线命名 # "status": instance.status # }) # @receiver(post_save, sender=Order) # def handle_order_update(sender, instance, **kwargs): # try: # broadcast_order_update({ # "id": instance.id, # "order_no": instance.order_no, # 使用下划线命名 # "status": instance.status # }) # logger.info(f"信号处理完成 - 订单ID: {instance.id} 状态: {instance.status}") # except Exception as e: # logger.error(f"信号处理错误: {str(e)}") from django.db.models.signals import post_save from django.dispatch import receiver from .models import Order from .consumers import broadcast_order_update import logging logger = logging.getLogger(__name__) @receiver(post_save, sender=Order) def handle_order_update(sender, instance, **kwargs): """统一处理订单更新信号""" try: logger.info(f"订单更新信号触发 - 订单ID: {instance.id} 状态: {instance.status}") # 构建标准化消息数据 order_data = { "id": instance.id, "order_no": instance.order_no, "status": instance.status } # 广播消息 broadcast_order_update(order_data) logger.info(f"广播订单更新成功 - 订单ID: {instance.id}") except Exception as e: logger.error(f"订单更新信号处理错误: {str(e)}", exc_info=True) """ Django settings for DjangoProject1 project. Generated by 'django-admin startproject' using Django 5.1.6. For more information on this file, see https://docs.djangoproject.com/en/5.1/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/5.1/ref/settings/ """ import os from datetime import timedelta from pathlib import Path # import AES # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/5.1/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'django-insecure-7f5y$m$)-y81w5h0q*o12ohp$douez_97h-x_!daldl@9%7kvr' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ # 通用 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework_simplejwt', # 新增 # 功能 'rest_framework', 'corsheaders', 'django_filters', 'rest_framework.authtoken', 'channels', # app 'swiper', 'search', # 正确的应用名称 'merchant', # 正确的应用名称 'shop', "product", # "gouw", 'gouw.apps.GouwConfig', "xiad", "zhif", "dd", 'wod_denglu', "dingd", ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] # ASGI_APPLICATION = "DjangoProject1.asgi.application" # 确保存在 # ASGI_APPLICATION = 'DjangoProject1.routing.application' ASGI_APPLICATION = "DjangoProject1.asgi.application" CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("127.0.0.1", 6379)], "channel_capacity": { "http.request": 200, "websocket.send*": 200, } }, }, } # 信号配置 SIGNAL_HANDLERS = True TIME_ZONE = 'Asia/Shanghai' # 确保时区正确 USE_TZ = True CORS_ALLOW_ALL_ORIGINS = True ROOT_URLCONF = 'DjangoProject1.urls' # TEMPLATES = [ # { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # 'BACKEND': 'django.template.backends.django.DjangoTemplates', # 'DIRS': [BASE_DIR / 'templates'] # , # 'APP_DIRS': True, # 'OPTIONS': { # 'context_processors': [ # 'django.template.context_processors.debug', # 'django.template.context_processors.request', # 'django.contrib.auth.context_processors.auth', # 'django.contrib.messages.context_processors.messages', # ], # }, # }, # ] CORS_ALLOWED_ORIGINS = [ 'http://127.0.0.1:8000', # 替换为实际的前端地址 ] TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'DjangoProject1.wsgi.application' CORS_ORIGIN_ALLOW_ALL = True # Database # https://docs.djangoproject.com/en/5.1/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME':"db_44", 'USER': 'root', 'PASSWORD': '123456', 'HOST': 'localhost', 'PORT': '3306', 'charset': 'utf8mb4', } } # Password validation # https://docs.djangoproject.com/en/5.1/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', }, { 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', }, { 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', }, { 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', }, ] CORS_ALLOW_CREDENTIALS = True # DRF配置 REST_FRAMEWORK = { 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', 'PAGE_SIZE': 20, 'ORDERING_PARAM': 'ordering', 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', 'rest_framework.authentication.BasicAuthentication', # 'rest_framework.authentication.SessionAuthentication', ], # "DEFAULT_AUTHENTICATION_CLASSES": ( # 'rest_framework.permissions.IsAuthenticated', # ), # "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), # # 'DEFAULT_AUTHENTICATION_CLASSES': [ # 'rest_framework.authentication.TokenAuthentication', # ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', # 'rest_framework.permissions.IsAuthenticated', ], 'DEFAULT_AUTHENTICATION_CLASSES': ( 'rest_framework_simplejwt.authentication.JWTAuthentication', # 'rest_framework_simplejwt.authentication.JWTAuthentication', # 替换原来的 JWT 认证 # #Token认证 # 'rest_framework.authentication.TokenAuthentication', # 'rest_framework.authentication.BasicAuthentication', ), 'EXCEPTION_HANDLER': 'rest_framework.views.exception_handler', } AUTH_USER_MODEL = 'wod_denglu.User' # AUTH_USER_MODEL = None # 替换为实际应用名 # 配置文件上传路径 MEDIA_ROOT = os.path.join(BASE_DIR, "media") MEDIA_URL = "/media/" # 在settings.py 中启用调试模式 DEBUG = True # Internationalization # https://docs.djangoproject.com/en/5.1/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/5.1/howto/static-files/ STATIC_URL = 'static/' # Default primary key field type # https://docs.djangoproject.com/en/5.1/ref/settings/#default-auto-field DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField' # # # # 日志配置 LOGGING = { 'version': 1, 'handlers': { 'console': { 'class': 'logging.StreamHandler', }, }, 'loggers': { 'gouw': { 'handlers': ['console'], 'level': 'DEBUG', }, }, } # 允许所有域名(开发环境临时方案) CORS_ORIGIN_ALLOW_ALL = True # 配置允许的请求头 CORS_ALLOW_HEADERS = [ 'accept', 'accept-encoding', 'authorization', 'content-type', 'dnt', 'origin', 'user-agent', 'x-csrftoken', 'x-requested-with', ] # 配置允许的HTTP方法 CORS_ALLOW_METHODS = [ 'GET', 'POST', 'PUT', 'DELETE', 'OPTIONS' ] # # # 增强型JWT配置 # JWT_SETTINGS = { # 'SECRET_KEY': os.getenv('JWT_SECRET'), # 32位随机字符串 # 'ALGORITHM': 'HS256', # 'ACCESS_TOKEN_LIFETIME': timedelta(hours=2), # 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), # 'AUTH_HEADER_PREFIX': 'Bearer' # } # # 微信配置 # WECHAT = { # 'APP_ID': os.environ.get('WECHAT_APP_ID'), # 'APP_SECRET': os.environ.get('WECHAT_APP_SECRET'), # 'LOGIN_URL': 'https://api.weixin.qq.com/sns/jscode2session' # } # # # AES加密配置(用于手机号解密) # AES_SETTINGS = { # 'MODE': AES.MODE_CBC, # 'BLOCK_SIZE': 32, # 'PADDING': '\0' # } # 微信配置 WX_APPID= 'wx5bb48b2fd7ec3e54' WX_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200' WX_MCHID = '1230004567' # 新增 WX_API_KEY = 'aBcDeFgHiJkLmNoPqRsTuVwXyZ' # 新增 WX_NOTIFY_URL = 'http:/http://127.0.0.1:8000/api/zhif/wx-notify/' WECHAT_APPID = 'wx5bb48b2fd7ec3e54' WECHAT_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200' WECHAT_APP_ID = 'wx5bb48b2fd7ec3e54' WECHAT_APP_SECRET = '6ba10b53c9bdf24aaa0f026f147e0200' WECHAT_MINI_PROGRAM = { 'APPID': 'wx5bb48b2fd7ec3e54', 'SECRET': '6ba10b53c9bdf24aaa0f026f147e0200' } WECHAT_TOKEN = "90_RzkT6EObTjmOA4E0O2ouANm7iYvTauxbwnTFkcTEu-3ggitiQnpzpvHE6-JUfbGThiqvmOdHBF4TEE3rf9GE_1MvDoBzhPEIj24OWmT0ulQkJ4iq95JweKmIBa8OQZfAGASUD" # 默认头像配置 DEFAULT_AVATAR_URL = 'https://tse2-mm.cn.bing.net/th/id/OIP-C.1eW3_u1T8He1QmfKH_ctngAAAA?rs=1&pid=ImgDetMain' # JWT配置 JWT_EXPIRATION_DAYS = 7 SIMPLE_JWT = { # 'AUTH_TOKEN_CLASSES': ('shop.auth.ShopJWTAuthentication',), # # 'TOKEN_USER_CLASS': 'shop.models.Shop', # 'USER_ID_FIELD': 'id', # 'USER_ID_CLAIM': 'user_id', 'USER_AUTHENTICATION_RULE': 'shop.auth.allow_all_users', # 新增规则 # 添加商家用户类型支持 'TOKEN_USER_CLASSES': ( 'wod_denglu.models.User', 'shop.models.Shop' ), # 'AUTH_TOKEN_CLASSES': ('shop.auth.ShopJWTAuthentication',), # 'USER_ID_FIELD': 'uuid', # 使用唯一标识字段 'TOKEN_USER_CLASS': 'wod_denglu.models.User', # 主用户类 'TOKEN_OBTAIN_SERIALIZER': 'wod_denglu.serializers.CustomTokenObtainPairSerializer', # 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', 'ACCESS_TOKEN_LIFETIME': timedelta(days=7), # 按需配置有效期 'REFRESH_TOKEN_LIFETIME': timedelta(days=30), 'ROTATE_REFRESH_TOKENS': False, 'BLACKLIST_AFTER_ROTATION': True, # 调试专用配置 'VERIFYING_KEY': None, 'AUDIENCE': None, 'ISSUER': None, 'JWK_URL': None, 'LEEWAY': 0, 'AUTH_HEADER_TYPES': ('Bearer',), 'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION', 'USER_ID_FIELD': 'id', # 确保与用户模型匹配 'USER_ID_CLAIM': 'user_id', # 'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule', 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken','shop.auth.ShopJWTAuthentication'), 'TOKEN_TYPE_CLAIM': 'token_type', # 开启详细错误 'SHOW_AUTHENTICATION_ERRORS': True, 'SIGNING_KEY': '6ba10b53c9bdf24aaa0f026f147e0200', # 替换为强密钥 } # 安全配置 SECRET_KEY = '6ba10b53c9bdf24aaa0f026f147e0200' # AUTHENTICATION_BACKENDS = [ # 'django.contrib.auth.backends.ModelBackend', # 'shop.backends.ShopBackend', # 如果你使用自定义后端 # ] # # 指定自定义用户模型 # AUTH_USER_MODEL = 'shop.Shop' # 根据应用名调整 # 配置认证后端 AUTHENTICATION_BACKENDS = [ 'shop.backends.ShopAuthBackend', # 商家认证 'wod_denglu.backends.CustomerAuthBackend', # 消费者认证 'django.contrib.auth.backends.ModelBackend', ] # JWT配置 # SIMPLE_JWT = { # 'USER_ID_FIELD': 'id', # 'USER_ID_CLAIM': 'user_id', # 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), # } # # # 认证后端配置 # AUTHENTICATION_BACKENDS = [ # 'django.contrib.auth.backends.ModelBackend', # 'shop.backends.ShopBackend', # ] # # # 用户模型配置 # AUTH_USER_MODEL = 'shop.Shop' # # # JWT配置 # SIMPLE_JWT = { # 'ACCESS_TOKEN_LIFETIME': timedelta(days=1), # 'REFRESH_TOKEN_LIFETIME': timedelta(days=7), # 'ROTATE_REFRESH_TOKENS': False, # 'BLACKLIST_AFTER_ROTATION': True, # 'ALGORITHM': 'HS256', # 'SIGNING_KEY': SECRET_KEY, # 'VERIFYING_KEY': None, # 'AUTH_HEADER_TYPES': ('Bearer',), # 'USER_ID_FIELD': 'id', # 'USER_ID_CLAIM': 'user_id', # 'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',), # } DATA_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10MB FILE_UPLOAD_MAX_MEMORY_SIZE = 2 * 1024 * 1024 # 2MB FILE_UPLOAD_PERMISSIONS = 0o644 # LOGGING = { # 'version': 1, # 'disable_existing_loggers': False, # 'handlers': { # 'file': { # 'level': 'DEBUG', # 'class': 'logging.FileHandler', # 'filename': 'debug.log', # }, # 'console': { # 'level': 'DEBUG', # 'class': 'logging.StreamHandler', # }, # }, # 'loggers': { # 'django': { # 'handlers': ['file', 'console'], # 'level': 'DEBUG', # 'propagate': True, # }, # }, # } 后端:(.venv) PS D:\ajango后端项目\DjangoProject1> daphne -p 8001 DjangoProject1.asgi:application 信号已加载! 127.0.0.1:64486 - - [18/May/2025:15:12:08] "WSCONNECTING /ws/orders/" - - 127.0.0.1:64486 - - [18/May/2025:15:12:08] "WSCONNECT /ws/orders/" - - 新客户端连接: specific.214396818bd94fb9a6c1eead947f0c54!2d9cb14738ae43b0aa0c3b9b1de9101f 2025-05-18 15:12:08,828 INFO 新客户端连接: specific.214396818bd94fb9a6c1eead947f0c54!2d9cb14738ae43b0aa0c3b9b1de9101f 127.0.0.1:64486 - - [18/May/2025:15:12:09] "WSDISCONNECT /ws/orders/" - - 127.0.0.1:51483 - - [18/May/2025:15:12:13] "WSCONNECTING /ws/orders/" - - 127.0.0.1:51483 - - [18/May/2025:15:12:13] "WSCONNECT /ws/orders/" - - 新客户端连接: specific.214396818bd94fb9a6c1eead947f0c54!28560ecf1ac54d55833d143161e19e72 2025-05-18 15:12:13,772 INFO 新客户端连接: specific.214396818bd94fb9a6c1eead947f0c54!28560ecf1ac54d55833d143161e19e72 127.0.0.1:54431 - - [18/May/2025:15:12:14] "WSCONNECTING /ws/orders/" - - 127.0.0.1:54431 - - [18/May/2025:15:12:14] "WSCONNECT /ws/orders/" - - 新客户端连接: specific.214396818bd94fb9a6c1eead947f0c54!499cf5873e334b06bcbd90d97b2329f0 2025-05-18 15:12:14,183 INFO 新客户端连接: specific.214396818bd94fb9a6c1eead947f0c54!499cf5873e334b06bcbd90d97b2329f0 127.0.0.1:51483 - - [18/May/2025:15:12:14] "WSDISCONNECT /ws/orders/" - - 127.0.0.1:54431 - - [18/May/2025:15:12:14] "WSDISCONNECT /ws/orders/" - -
05-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cocktail_py

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值