diff --git a/backend/app.py b/backend/app.py index 2a5e590a..66dfca7f 100644 --- a/backend/app.py +++ b/backend/app.py @@ -242,81 +242,61 @@ def api_health_check(): @app.route('/api/auth/login', methods=['POST']) def login(): """用户登录""" - max_retries = 3 - retry_delay = 1 # 1秒延迟 - - for attempt in range(max_retries): - try: - data = flask_request.get_json() - username = data.get('username') - password = data.get('password') - if not username or not password: - return jsonify({ - 'success': False, - 'message': '用户名或密码不能为空' - }), 400 + try: + data = flask_request.get_json() + username = data.get('username') + password = data.get('password') + if not username or not password: + return jsonify({ + 'success': False, + 'message': '用户名或密码不能为空' + }), 400 - # 使用数据库验证用户 - user = db_manager.authenticate_user(username, password) - - if user: - # 检查用户是否已激活 - if not user['is_active']: - return jsonify({ - 'success': False, - 'message': '账户未激活,请联系管理员审核' - }), 403 - - # 构建用户数据 - user_data = { - 'id': user['id'], - 'username': user['username'], - 'name': user['name'], - 'role': 'admin' if user['user_type'] == 'admin' else 'user', - 'user_type': user['user_type'], - 'avatar': '' - } - - # 生成token(实际项目中应使用JWT等安全token) - token = f"token_{username}_{int(time.time())}" - - logger.info(f'用户 {username} 登录成功') - - return jsonify({ - 'success': True, - 'data': { - 'token': token, - 'user': user_data - }, - 'message': '登录成功' - }) - else: - logger.warning(f'用户 {username} 登录失败:用户名或密码错误') + # 使用数据库验证用户 + user = db_manager.authenticate_user(username, password) + + if user: + # 检查用户是否已激活 + if not user['is_active']: return jsonify({ 'success': False, - 'message': '用户名或密码错误' - }), 401 - - except Exception as e: - logger.error(f'登录失败 (尝试 {attempt + 1}/{max_retries}): {e}') + 'message': '账户未激活,请联系管理员审核' + }), 403 - # 如果是最后一次尝试,直接返回错误 - if attempt == max_retries - 1: - logger.error(f'登录失败,已达到最大重试次数 ({max_retries})') - return jsonify({ - 'success': False, - 'message': '系统异常,请稍后重试' - }), 500 + # 构建用户数据 + user_data = { + 'id': user['id'], + 'username': user['username'], + 'name': user['name'], + 'role': 'admin' if user['user_type'] == 'admin' else 'user', + 'user_type': user['user_type'], + 'avatar': '' + } - # 延迟后重试 - logger.info(f'等待 {retry_delay} 秒后重试...') - time.sleep(retry_delay) - - # 理论上不会执行到这里,但为了安全起见 - return jsonify({ - 'success': False, - 'message': '系统异常,请稍后重试' - }), 500 + # 生成token(实际项目中应使用JWT等安全token) + token = f"token_{username}_{int(time.time())}" + + logger.info(f'用户 {username} 登录成功') + + return jsonify({ + 'success': True, + 'data': { + 'token': token, + 'user': user_data + }, + 'message': '登录成功' + }) + else: + logger.warning(f'用户 {username} 登录失败:用户名或密码错误') + return jsonify({ + 'success': False, + 'message': '用户名或密码错误' + }), 401 + + except Exception as e: + logger.error(f'登录失败: {e}') + return jsonify({'success': False, 'message': '登录失败'}), 500 + @app.route('/api/auth/register', methods=['POST']) def register(): diff --git a/backend/devices/camera_manager.py b/backend/devices/camera_manager.py index 1b8c4dc9..43926695 100644 --- a/backend/devices/camera_manager.py +++ b/backend/devices/camera_manager.py @@ -64,7 +64,7 @@ class CameraManager(BaseDevice): self.backend_name = backend_name # 额外可调的降采样宽度(不改变外部配置语义,仅内部优化传输) - self._tx_max_width = int(config.get('tx_max_width', 640)) + self._tx_max_width = int(config.get('tx_max_width', 1920)) # 流控制 self.streaming_thread = None @@ -862,7 +862,7 @@ class CameraManager(BaseDevice): self.fps = config.get('fps', 30) self.buffer_size = config.get('buffer_size', 1) self.fourcc = config.get('fourcc', 'MJPG') - self._tx_max_width = int(config.get('tx_max_width', 640)) + self._tx_max_width = int(config.get('tx_max_width', 1920)) # 新增:动态更新重连/阈值配置 self.max_reconnect_attempts = int(config.get('max_reconnect_attempts', self.max_reconnect_attempts)) self.reconnect_delay = float(config.get('reconnect_delay', self.reconnect_delay)) diff --git a/frontend/src/renderer/src/views/Detection.vue b/frontend/src/renderer/src/views/Detection.vue index 455efd6e..30a80595 100644 --- a/frontend/src/renderer/src/views/Detection.vue +++ b/frontend/src/renderer/src/views/Detection.vue @@ -565,7 +565,7 @@
+ width: 100%;height: 100vh;z-index: 9999;background: red;border: 2px solid #b0b0b0"> diff --git a/frontend/src/renderer/src/views/Login.vue b/frontend/src/renderer/src/views/Login.vue index 67aed137..f1229753 100644 --- a/frontend/src/renderer/src/views/Login.vue +++ b/frontend/src/renderer/src/views/Login.vue @@ -56,7 +56,7 @@
- + 注册
@@ -217,7 +217,7 @@ import { useAuthStore } from '../stores' import { User, Lock, View, Hide, Phone } from '@element-plus/icons-vue' import bg from '@/assets/bg.png' -import { getBackendUrl } from '../services/api.js' +import { getBackendUrl,systemAPI } from '../services/api.js' const BACKEND_URL = getBackendUrl() const router = useRouter() const authStore = useAuthStore() @@ -415,6 +415,7 @@ const handleRegisterSubmit = async () => { // 登录处理 const handleLogin = async () => { + isLoading.value = true // 验证用户名 if (!form.value.account) { showError('请输入登录账号!') @@ -427,8 +428,34 @@ const handleLogin = async () => { return } - try { - isLoading.value = true + // 网络访问测试(最多重试3次,每次延迟2秒) + let healthOk = false + for (let attempt = 1; attempt <= 3; attempt++) { + try { + const result = await systemAPI.health() + if (result && result.status === 'healthy') { + healthOk = true + break + } else { + // 后台返回非 healthy 状态 + if (attempt === 3) { + showError('后台服务异常,请稍后重试!') + return + } + await new Promise(resolve => setTimeout(resolve, 2000)) + } + } catch (error) { + // 捕获异常,等待后重试 + if (attempt === 3) { + showError('网络访问失败,请检查连接后重试!') + isLoading.value = false + return + } + await new Promise(resolve => setTimeout(resolve, 2000)) + } + } + + try { const result = await authStore.login({ username: form.value.account, password: form.value.password @@ -455,6 +482,7 @@ const handleLogin = async () => { } } catch (error) { showError('登录失败,请检查网络连接后重试!') + isLoading.value = false } finally { isLoading.value = false }