diff --git a/back/app.py b/back/app.py index 1d9b013..620063c 100644 --- a/back/app.py +++ b/back/app.py @@ -92,20 +92,7 @@ def create_app(): app.get_db = get_db # 启用 CORS(跨域支持) - CORS(app, - resources={r"/*": { - "origins": [ - "http://localhost:8080", - "http://127.0.0.1:8080", - "http://[::1]:8080", - "http://localhost:5173", - "http://127.0.0.1:5173", - "http://[::1]:5173" - ], - "supports_credentials": True, - "allow_headers": ["Content-Type", "Authorization"], - "methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"] - }}) + CORS(app, resources={r"/*": {"origins": "*"}}) # 允许所有来源,或指定局域网IP # 注册蓝图 from blueprints.login import bp as login_bp @@ -165,4 +152,4 @@ def create_app(): if __name__ == '__main__': app = create_app() - app.run(debug=True) \ No newline at end of file + app.run(host='0.0.0.0', port=5000, debug=True) \ No newline at end of file diff --git a/back/blueprints/login.py b/back/blueprints/login.py index 4912ced..bdf0f80 100644 --- a/back/blueprints/login.py +++ b/back/blueprints/login.py @@ -13,77 +13,40 @@ from cryptography.hazmat.primitives import serialization bp = Blueprint('auth', __name__, url_prefix='/auth') logger = logging.getLogger(__name__) - -# 添加 CORS 头 -FRONTEND_ORIGINS = { - "http://localhost:8080", - "http://127.0.0.1:8080", - "http://[::1]:8080", - "http://localhost:5173", - "http://127.0.0.1:5173", - "http://[::1]:5173" -} +# 允许所有局域网IP或指定前端源 +FRONTEND_ORIGINS = {"*"} # 使用通配符表示接受所有来源,或指定具体的局域网IP如{"http://192.168.x.x:8080"} def add_cors_headers(response): origin = request.headers.get('Origin') - if origin in FRONTEND_ORIGINS: - response.headers['Access-Control-Allow-Origin'] = origin + if origin in FRONTEND_ORIGINS or "*" in FRONTEND_ORIGINS: + response.headers['Access-Control-Allow-Origin'] = origin if origin else '*' response.headers['Access-Control-Allow-Credentials'] = 'true' response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS' return response - - -# 辅助函数:创建JWT令牌 def create_jwt_token(payload, secret_key, algorithm="HS256", expires_in=7200): - # 添加过期时间 payload_with_exp = payload.copy() payload_with_exp["exp"] = int((datetime.datetime.utcnow() + datetime.timedelta(seconds=expires_in)).timestamp()) - # JWT头部 header = {"alg": algorithm, "typ": "JWT"} - - # 编码头部和载荷 encoded_header = base64.urlsafe_b64encode(json.dumps(header).encode('utf-8')).rstrip(b'=').decode('utf-8') - encoded_payload = base64.urlsafe_b64encode(json.dumps(payload_with_exp).encode('utf-8')).rstrip(b'=').decode( - 'utf-8') - - # 组合头部和载荷 + encoded_payload = base64.urlsafe_b64encode(json.dumps(payload_with_exp).encode('utf-8')).rstrip(b'=').decode('utf-8') message = f"{encoded_header}.{encoded_payload}" - # 创建签名 if algorithm == "HS256": - # 使用HMAC-SHA256创建签名 - signature = hmac.new( - secret_key.encode('utf-8'), - message.encode('utf-8'), - hashlib.sha256 - ).digest() + signature = hmac.new(secret_key.encode('utf-8'), message.encode('utf-8'), hashlib.sha256).digest() encoded_signature = base64.urlsafe_b64encode(signature).rstrip(b'=').decode('utf-8') elif algorithm == "RS256": - # 使用RSA-SHA256创建签名 (生产环境中应妥善管理私钥) - private_key = serialization.load_pem_private_key( - secret_key.encode('utf-8'), - password=None - ) - signature = private_key.sign( - message.encode('utf-8'), - padding.PSS( - mgf=padding.MGF1(hashes.SHA256()), - salt_length=padding.PSS.MAX_LENGTH - ), - hashes.SHA256() - ) + private_key = serialization.load_pem_private_key(secret_key.encode('utf-8'), password=None) + signature = private_key.sign(message.encode('utf-8'), padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.MAX_LENGTH), hashes.SHA256()) encoded_signature = base64.urlsafe_b64encode(signature).rstrip(b'=').decode('utf-8') else: raise ValueError(f"不支持的算法: {algorithm}") - # 组合JWT jwt_token = f"{encoded_header}.{encoded_payload}.{encoded_signature}" return jwt_token - @bp.route('/login', methods=['POST', 'OPTIONS']) def login(): if request.method == "OPTIONS": @@ -99,11 +62,8 @@ def login(): response = jsonify({'message': '缺少必要字段'}) return add_cors_headers(response), 400 - # 获取数据库连接 db = current_app.get_db() cursor = db.cursor() - - # 查询用户(注意:生产环境应使用参数化查询防止SQL注入) cursor.execute("SELECT * FROM user WHERE username = ?", (username,)) user_row = cursor.fetchone() @@ -112,40 +72,29 @@ def login(): response = jsonify({'message': '用户不存在'}) return add_cors_headers(response), 401 - # 将元组结果转换为字典(如果需要) if isinstance(user_row, tuple): user_dict = dict(zip([column[0] for column in cursor.description], user_row)) else: user_dict = user_row - # 明文密码比对(⚠️ 不推荐用于生产环境) if password != user_dict['password']: logger.warning(f"密码错误: {username}") response = jsonify({'message': '密码错误'}) return add_cors_headers(response), 401 - # 检查用户状态 if user_dict['status'] != 'Active': logger.warning(f"用户已禁用: {username}") response = jsonify({'message': '用户已禁用'}) return add_cors_headers(response), 403 - # 判断是否为管理员(基于permission_level字段) is_admin = user_dict['permission_level'] == 'Admin' + secret_key = os.getenv('SECRET_KEY', '默认密钥') # 生产环境建议使用环境变量设置 - # 构建 JWT Token - secret_key = os.getenv('SECRET_KEY', '默认密钥') # 建议设置环境变量 - - # 使用我们自己的函数创建JWT token = create_jwt_token( - { - 'user_id': user_dict['id'], - 'username': user_dict['username'], - 'is_admin': is_admin, - }, + {'user_id': user_dict['id'], 'username': user_dict['username'], 'is_admin': is_admin}, secret_key, algorithm="HS256", - expires_in=2 * 60 * 60 # 2小时 + expires_in=2 * 60 * 60 ) response_data = jsonify({ @@ -153,19 +102,18 @@ def login(): 'message': '登录成功', 'username': user_dict['username'], 'is_admin': is_admin, - 'user_id': user_dict['id'] # 可选:返回用户ID + 'user_id': user_dict['id'] }) response = add_cors_headers(response_data) - # 设置 Cookie(注意:生产环境应启用 secure=True) response.set_cookie( 'token', value=token, - max_age=2 * 60 * 60, # 2小时 + max_age=2 * 60 * 60, httponly=True, - samesite='None', - secure=False # 开发环境使用False,生产环境使用True + samesite='None', # 注意:开发环境下可以设为None,生产环境推荐使用'Lax'或'Strict' + secure=False # 开发环境使用False,生产环境应设为True ) logger.info(f"用户登录成功: {username}") @@ -174,4 +122,4 @@ def login(): except Exception as e: logger.error(f"登录过程发生错误: {str(e)}", exc_info=True) response = jsonify({'message': '服务器内部错误'}) - return add_cors_headers(response), 500 + return add_cors_headers(response), 500 \ No newline at end of file diff --git a/back/blueprints/register.py b/back/blueprints/register.py index b792e06..d0b4f21 100644 --- a/back/blueprints/register.py +++ b/back/blueprints/register.py @@ -3,37 +3,37 @@ import logging bp = Blueprint('register', __name__) logger = logging.getLogger(__name__) -FRONTEND_ORIGINS = [ - "http://localhost:8080", - "http://127.0.0.1:8080", - "http://[::1]:8080", - "http://localhost:5173", - "http://127.0.0.1:5173", - "http://[::1]:5173" -] + +# 支持所有局域网设备访问(或指定 IP) +FRONTEND_ORIGINS = ["*"] # 也可以替换为具体的 IP 地址列表 + +def add_cors_headers(response): + origin = request.headers.get('Origin') + if origin in FRONTEND_ORIGINS or "*" in FRONTEND_ORIGINS: + response.headers['Access-Control-Allow-Origin'] = origin if origin else '*' + response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' + response.headers['Access-Control-Allow-Methods'] = 'POST, OPTIONS' + response.headers['Access-Control-Allow-Credentials'] = 'true' + return response @bp.route('/register', methods=['POST', 'OPTIONS']) def register(): if request.method == 'OPTIONS': - origin = request.headers.get('Origin') - if origin in FRONTEND_ORIGINS: - response = jsonify() - response.headers.add('Access-Control-Allow-Origin', origin) - response.headers.add('Access-Control-Allow-Headers', 'Content-Type, Authorization') - response.headers.add('Access-Control-Allow-Methods', 'POST, OPTIONS') - response.headers.add('Access-Control-Allow-Credentials', 'true') - return response, 200 + response = jsonify() + return add_cors_headers(response), 200 try: logger.info("收到注册请求") data = request.get_json() if not data: - return jsonify({'message': '请求数据为空'}), 400 + response = jsonify({'message': '请求数据为空'}) + return add_cors_headers(response), 400 username = data.get('username') password = data.get('password') if not all([username, password]): - return jsonify({'message': '缺少用户名或密码'}), 400 + response = jsonify({'message': '缺少用户名或密码'}) + return add_cors_headers(response), 400 db = current_app.get_db() cursor = db.cursor() @@ -41,7 +41,8 @@ def register(): # 检查用户名是否已存在 cursor.execute("SELECT id FROM user WHERE username = ?", (username,)) if cursor.fetchone(): - return jsonify({'message': '用户名已存在'}), 400 + response = jsonify({'message': '用户名已存在'}) + return add_cors_headers(response), 400 # 插入数据时包含 permission_level(默认设为 Operator) cursor.execute( @@ -51,9 +52,11 @@ def register(): db.commit() logger.info(f"用户 {username} 注册成功") - return jsonify({'message': '注册成功'}), 201 + response = jsonify({'message': '注册成功'}) + return add_cors_headers(response), 201 except Exception as e: logger.error(f"服务器内部错误: {str(e)}", exc_info=True) db.rollback() - return jsonify({'message': '服务器内部错误'}), 500 \ No newline at end of file + response = jsonify({'message': '服务器内部错误'}) + return add_cors_headers(response), 500 \ No newline at end of file diff --git a/platform/.env.development b/platform/.env.development new file mode 100644 index 0000000..ead2094 --- /dev/null +++ b/platform/.env.development @@ -0,0 +1 @@ +VITE_API_BASE_URL=http://localhost:5000 \ No newline at end of file diff --git a/platform/.env.production b/platform/.env.production new file mode 100644 index 0000000..50f53bf --- /dev/null +++ b/platform/.env.production @@ -0,0 +1 @@ +VITE_API_BASE_URL=https://your-production-domain.com/api \ No newline at end of file diff --git a/platform/src/components/dashboard/StatCards.vue b/platform/src/components/dashboard/StatCards.vue index d3826ba..f416ae0 100644 --- a/platform/src/components/dashboard/StatCards.vue +++ b/platform/src/components/dashboard/StatCards.vue @@ -62,7 +62,7 @@ import StatCardItem from './StatCardItem.vue'; // 总用户数 const totalUsers = ref(0); - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 设备相关 const devices = ref([]); const totalDevicesCount = computed(() => devices.value?.length || 0); // 计算设备总数 @@ -77,7 +77,7 @@ const repairDevicesCount = ref(0); // 初始化为0 // 获取用户总数 const fetchTotalUsers = async () => { try { - const response = await axios.get('http://localhost:5000/personnel/users'); + const response = await axios.get(`${apiUrl}/personnel/users`); totalUsers.value = response.data.data.length; } catch (error) { console.error('获取用户总数失败:', error); @@ -88,7 +88,7 @@ const fetchTotalUsers = async () => { // 获取设备列表 const fetchDevices = async () => { try { - const response = await axios.get('http://localhost:5000/api/device/list'); + const response = await axios.get(`${apiUrl}/api/device/list`); if (response.data.success) { devices.value = response.data.data; } @@ -101,7 +101,7 @@ const fetchDevices = async () => { const fetchDeviceATemperature = async () => { try { isTemperatureLoading.value = true; - const response = await axios.get('http://localhost:5000/temperature/daily/average', { + const response = await axios.get(`${apiUrl}/temperature/daily/average`, { params: { deviceId: 1, date: '2025-05-27' } }); @@ -120,9 +120,9 @@ const fetchDeviceATemperature = async () => { }; // 获取故障设备数 -const fetchRepairDevicesCount = async () => { +const fetchRepairDevicesCount = async () => { `${apiUrl}/dashboard` try { - const response = await axios.get('http://localhost:5000/dashboard'); + const response = await axios.get(`${apiUrl}/dashboard`); repairDevicesCount.value = response.data.todayFaults || 0; } catch (error) { console.error('获取维修设备数失败:', error); diff --git a/platform/src/components/features/monitoring/TemperatureMonitor.vue b/platform/src/components/features/monitoring/TemperatureMonitor.vue index 0405e05..55bcba6 100644 --- a/platform/src/components/features/monitoring/TemperatureMonitor.vue +++ b/platform/src/components/features/monitoring/TemperatureMonitor.vue @@ -53,6 +53,7 @@ import * as echarts from 'echarts'; const deviceId = ref('TEMP-001'); const lastUpdateTime = ref('刚刚更新'); const isLoading = ref(false); +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 图表相关变量 const chartContainer = ref(null); @@ -103,7 +104,7 @@ const fetchData = async () => { try { const [startTime, endTime] = getTimeRange(); - const response = await axios.get('http://localhost:5000/api/weather/data', { + const response = await axios.get(`${apiUrl}/api/weather/data`, { params: { start_time: startTime, end_time: endTime } }); diff --git a/platform/src/components/gu3.vue b/platform/src/components/gu3.vue index 36b13a1..c686dd1 100644 --- a/platform/src/components/gu3.vue +++ b/platform/src/components/gu3.vue @@ -48,7 +48,7 @@ import Gu4 from "../components3/gu4.vue"; import Gu5 from "../components3/gu5.vue"; import Gu6 from "../components3/gu6.vue"; import Askai from "../components1/askai.vue"; - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL export default { name: 'FaultManagementDashboard', components: {Askai, Gu6, Gu5, Gu4 }, @@ -77,7 +77,7 @@ export default { this.isLoading = true; // 显示加载状态 try { // 调用后端故障仪表盘接口(需与后端API路径一致) - const response = await axios.get('http://localhost:5000/dashboard'); + const response = await axios.get(`${apiUrl}/dashboard`); const {todayFaults, increase, monthlyFaults, limit} = response.data; // 更新数据到组件状态 diff --git a/platform/src/components/login.vue b/platform/src/components/login.vue index 0b8ef03..df843c1 100644 --- a/platform/src/components/login.vue +++ b/platform/src/components/login.vue @@ -8,7 +8,7 @@ const username = ref(''); const password = ref(''); const rememberMe = ref(false); const errorMessage = ref(''); - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 跳转到注册页面 const register = () => { router.push('/register'); @@ -17,7 +17,7 @@ const register = () => { // 登录功能 const login = async () => { try { - const response = await axios.post('http://localhost:5000/auth/login', { + const response = await axios.post(`${apiUrl}/auth/login`, { username: username.value, password: password.value }, { diff --git a/platform/src/components/pople5.vue b/platform/src/components/pople5.vue index 10a6e73..6a81690 100644 --- a/platform/src/components/pople5.vue +++ b/platform/src/components/pople5.vue @@ -356,6 +356,7 @@ const emailError = ref(''); const phoneError = ref(''); const showDeleteConfirm = ref(''); const isLogsLoaded = ref(false); +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 统一错误处理函数 const handleError = (error, message = '操作失败') => { @@ -557,7 +558,7 @@ onMounted(() => { // 获取用户数据 const fetchUsers = async () => { try { - const response = await axios.get('http://localhost:5000/personnel/users', { + const response = await axios.get(`${apiUrl}/personnel/users`, { headers: { Authorization: `Bearer ${userInfo.token}` } @@ -589,7 +590,7 @@ const fetchUsers = async () => { // 获取日志数据 const fetchLogs = async () => { try { - const response = await axios.get(`http://localhost:5000/personnel/logs`, { + const response = await axios.get(`${apiUrl}/personnel/logs`, { headers: { Authorization: `Bearer ${userInfo.token}` } @@ -650,7 +651,7 @@ const handleAddUser = async () => { }; try { - const response = await axios.post('http://localhost:5000/personnel/users', requestData, { + const response = await axios.post(`${apiUrl}/personnel/users`, requestData, { headers: { Authorization: `Bearer ${userInfo.token}` } @@ -737,7 +738,7 @@ const handleEditUser = async () => { try { const response = await axios.put( - `http://localhost:5000/personnel/users/${editingUser.value.username}`, + `${apiUrl}/personnel/users/${editingUser.value.username}`, payload, { headers: { @@ -779,7 +780,7 @@ const deleteUser = async (username) => { if (!confirm(`确定要删除用户 ${username} 吗?此操作不可撤销。`)) return; try { - const response = await axios.delete(`http://localhost:5000/personnel/users/${username}`, { + const response = await axios.delete(`${apiUrl}/personnel/users/${username}`, { headers: { Authorization: `Bearer ${userInfo.token}` } diff --git a/platform/src/components/register.vue b/platform/src/components/register.vue index e44eca0..eb1bd38 100644 --- a/platform/src/components/register.vue +++ b/platform/src/components/register.vue @@ -9,7 +9,7 @@ const username = ref('') const password = ref('') const verificationCode = ref('') const errorMessage = ref('') - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL let countdownInterval: number | undefined; const login = () => { @@ -23,7 +23,7 @@ const sendVerificationCode = async () => { } try { - await axios.post('http://localhost:5000/captcha/email', { + await axios.post(`${apiUrl}/captcha/email`, { email: username.value }) @@ -69,7 +69,7 @@ const register = async () => { } try { - const response = await axios.post('http://localhost:5000/register', { + const response = await axios.post(`${apiUrl}/register`, { username: username.value, password: password.value, code: verificationCode.value diff --git a/platform/src/components/she4.vue b/platform/src/components/she4.vue index 1625e7f..6f9642e 100644 --- a/platform/src/components/she4.vue +++ b/platform/src/components/she4.vue @@ -241,8 +241,8 @@ import { ElMessage, ElMessageBox } from 'element-plus'; import axios from 'axios'; import Askai from "../components1/askai.vue"; -// 配置后端基础URL -axios.defaults.baseURL = 'http://localhost:5000'; +// ✅ 使用环境变量来配置基础URL +const API_BASE_URL = import.meta.env.VITE_API_BASE_URL; // 状态管理 const isLoading = ref(false); @@ -280,8 +280,7 @@ const editFormRules = { const fetchDevices = async (page = 1, size = 10) => { isLoading.value = true; try { - // 使用相对路径,自动拼接baseURL - const response = await axios.get('http://localhost:5000/api/device/list', { params: { page, size } }); + const response = await axios.get(`${API_BASE_URL}/api/device/list`, { params: { page, size } }); if (response.data.success) { devices.value = response.data.data; totalDevices.value = response.data.total; @@ -299,8 +298,7 @@ const fetchDevices = async (page = 1, size = 10) => { // 新增设备 const handleAddDevice = async () => { try { - // 使用相对路径 - const response = await axios.post('http://localhost:5000/api/device', newDevice.value); + const response = await axios.post(`${API_BASE_URL}/api/device`, newDevice.value); if (response.data.success) { ElMessage.success('设备新增成功'); showAddModal.value = false; @@ -318,8 +316,7 @@ const handleAddDevice = async () => { // 编辑设备 const handleEditDevice = async () => { try { - // 使用相对路径 - const response = await axios.put(`http://localhost:5000/api/device/${editingDevice.value.id}`, editingDevice.value); + const response = await axios.put(`${API_BASE_URL}/api/device/${editingDevice.value.id}`, editingDevice.value); if (response.data.success) { ElMessage.success('设备编辑成功'); showEditModal.value = false; @@ -338,8 +335,7 @@ const handleDelete = async (id) => { await ElMessageBox.confirm('确认删除该设备?', '警告', { type: 'warning' }).then(async () => { - // 使用相对路径 - const response = await axios.delete(`http://localhost:5000/api/device/${id}`); + const response = await axios.delete(`${API_BASE_URL}/api/device/${id}`); if (response.data.success) { ElMessage.success('设备删除成功'); fetchDevices(); diff --git a/platform/src/components/shu2.vue b/platform/src/components/shu2.vue index 50b9238..c217384 100644 --- a/platform/src/components/shu2.vue +++ b/platform/src/components/shu2.vue @@ -14,6 +14,7 @@ import { ElMessageBox, ElNotification, ElDialog, ElMessage } from 'element-plus' import axios from 'axios'; import html2canvas from 'html2canvas'; import jsPDF from 'jspdf'; +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL const drawerVisible = ref(false); const drawerVisibleHumidity = ref(false); @@ -126,7 +127,7 @@ const fetchDeviceATemperature = async () => { // Simulate getting humidity data const fetchPhData = async () => { try { - const response = await axios.get('http://localhost:5000/ph_data/get_ph_data'); + const response = await axios.get(`${apiUrl}/ph_data/get_ph_data`); if (response.data.data.length > 0) { const avgPh = response.data.data.reduce((sum: number, item: { ph: number }) => sum + item.ph, 0) / response.data.data.length; currentPh.value = avgPh.toFixed(2); @@ -138,7 +139,7 @@ const fetchPhData = async () => { const fetchHumidityData = async () => { try { - const response = await axios.get('http://localhost:5000/moisture'); + const response = await axios.get(`${apiUrl}/moisture`); if (Array.isArray(response.data) && response.data.length > 0) { const avg = response.data.reduce((sum: number, item: { moisture: number }) => sum + item.moisture, 0) / response.data.length; currentHumidity.value = `${Math.round(avg)}%`; diff --git a/platform/src/components1/PrecipitationChart.vue b/platform/src/components1/PrecipitationChart.vue index d03c68b..d973a19 100644 --- a/platform/src/components1/PrecipitationChart.vue +++ b/platform/src/components1/PrecipitationChart.vue @@ -32,7 +32,7 @@ import { ref, onMounted, onBeforeUnmount, watch, nextTick } from 'vue'; import axios from 'axios'; import * as echarts from 'echarts'; - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL const chartContainer = ref(null); const selectedRange = ref('today'); const selectedDevice = ref(1); @@ -82,7 +82,7 @@ const fetchData = async () => { try { const [startTime, endTime] = getTimeRange(); - const response = await axios.get('http://localhost:5000/api/weather/data', { + const response = await axios.get(`${apiUrl}/api/weather/data`, { params: { start_time: startTime, end_time: endTime } }); diff --git a/platform/src/components1/askai.vue b/platform/src/components1/askai.vue index 66228d2..47d744c 100644 --- a/platform/src/components1/askai.vue +++ b/platform/src/components1/askai.vue @@ -155,9 +155,10 @@ export default { const uploadType = ref<'document' | 'image' | null>(null); const uploadedFileName = ref(''); const isFileInterpretation = ref(false); + const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // API配置 - const API_BASE_URL = ref('http://localhost:5000/aiask'); + const API_BASE_URL = ref(`${apiUrl}/aiask`); const userId = ref('user_' + Math.random().toString(36).substr(2, 9)); // 轮询状态 diff --git a/platform/src/components1/home1.vue b/platform/src/components1/home1.vue index 0c64ef2..993a363 100644 --- a/platform/src/components1/home1.vue +++ b/platform/src/components1/home1.vue @@ -18,7 +18,7 @@ import c6 from '../assets/c6.jpg'; // Array of available avatar images const avatarImages = [c1, c2, c3, c4, c5, c6]; - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // Function to get a random avatar const getRandomAvatar = () => { const randomIndex = Math.floor(Math.random() * avatarImages.length); @@ -43,7 +43,7 @@ let timeUpdateTimer: ReturnType | null = null; onMounted(async () => { try { // 调用后端接口获取维修设备数(假设接口为/get-repair-count) - const response = await axios.get('http://localhost:5000/dashboard'); // 示例接口 + const response = await axios.get(`${apiUrl}/dashboard`); // 示例接口 const { todayFaults } = response.data; // 更新响应式变量 @@ -85,7 +85,7 @@ const totalUsers = ref(0); // 在组件挂载时获取用户总数 onMounted(async () => { try { - const response = await axios.get('http://localhost:5000/personnel/users'); + const response = await axios.get(`${apiUrl}/personnel/users`); totalUsers.value = response.data.data.length; // 假设返回的数据结构中有data数组 } catch (error) { console.error('获取用户总数失败:', error); @@ -98,7 +98,7 @@ const devices = ref([]); // 确保已有这个声明 // 获取设备列表 const fetchDevices = async () => { try { - const response = await axios.get('http://localhost:5000/api/device/list'); + const response = await axios.get(`${apiUrl}/api/device/list`); if (response.data.success) { devices.value = response.data.data; } @@ -126,7 +126,7 @@ const fetchDeviceATemperature = async () => { temperatureError.value = ''; // 调用优化后的温度API - const response = await axios.get('http://localhost:5000/temperature/daily/average', { + const response = await axios.get(`${apiUrl}/temperature/daily/average`, { params: { deviceId: 1, date: '2025-05-27' diff --git a/platform/src/components2/ph.vue b/platform/src/components2/ph.vue index 200c0cd..4f462f1 100644 --- a/platform/src/components2/ph.vue +++ b/platform/src/components2/ph.vue @@ -40,11 +40,11 @@ const timeRanges = ref([]); const data = ref([]); const loading = ref(false); const error = ref(''); - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 获取时间范围选项 const fetchMetadata = async () => { try { - const response = await axios.get('http://localhost:5000/ph_data/get_time_ranges'); + const response = await axios.get(`${apiUrl}/ph_data/get_time_ranges`); timeRanges.value = response.data.time_ranges; } catch (err) { console.error('获取时间范围失败:', err); @@ -58,7 +58,7 @@ const fetchData = async () => { error.value = ''; try { - const response = await axios.get('http://localhost:5000/ph_data/get_ph_data', { + const response = await axios.get(`${apiUrl}/ph_data/get_ph_data`, { params: { time_range: selectedTimeRange.value } diff --git a/platform/src/components2/ph3.vue b/platform/src/components2/ph3.vue index 6a02b45..74fe0f1 100644 --- a/platform/src/components2/ph3.vue +++ b/platform/src/components2/ph3.vue @@ -411,12 +411,12 @@ const acidThreshold = ref(5.5) const alkaliThreshold = ref(8.5) const previousAcidThreshold = ref(5.5) const previousAlkaliThreshold = ref(8.5) - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 获取当前pH值数据 const fetchPhData = async () => { try { // 调用后端API获取5月27日的pH数据(假设后端接口已正确实现) - const response = await axios.get('http://localhost:5000/ph_data/get_ph_data', { + const response = await axios.get(`${apiUrl}/ph_data/get_ph_data`, { params: { time_range: 'today', sample_method: 'fixed' diff --git a/platform/src/components2/ph4.vue b/platform/src/components2/ph4.vue index 4744f7f..aa53288 100644 --- a/platform/src/components2/ph4.vue +++ b/platform/src/components2/ph4.vue @@ -341,11 +341,11 @@ const renderChart = (data) => { chart.setOption(option); }; - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 获取初始数据 const fetchPhData = async () => { try { - const response = await axios.get('http://localhost:5000/api/ph_data/get_ph_today'); + const response = await axios.get(`${apiUrl}/api/ph_data/get_ph_today`); chartData.value = response.data.data; if (chartData.value.length === 0) { diff --git a/platform/src/components2/shidu4.vue b/platform/src/components2/shidu4.vue index adcebcb..c25c856 100644 --- a/platform/src/components2/shidu4.vue +++ b/platform/src/components2/shidu4.vue @@ -35,7 +35,7 @@ const humidityData = ref([]); const locations = ref(['设备1', '设备2', '设备3', '设备4', '设备5', '设备6', '设备7']); const timeRange = ref('current'); -const API_URL = 'http://localhost:5000/api/device-sd'; +const API_URL = `${import.meta.env.VITE_API_BASE_URL}/api/device-sd`; const handleTimeRangeChange = () => { fetchData(timeRange.value); diff --git a/platform/src/components2/wendu2.vue b/platform/src/components2/wendu2.vue index a1c7066..e0c8ec2 100644 --- a/platform/src/components2/wendu2.vue +++ b/platform/src/components2/wendu2.vue @@ -120,12 +120,12 @@ const option = ref({ } ] }); - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 获取设备列表 const fetchDevices = async () => { try { loading.value = true; - const response = await axios.get('http://localhost:5000/api/devices'); + const response = await axios.get(`${apiUrl}/api/devices`); if (response.data.code === 200) { deviceList.value = response.data.data; if (Object.keys(response.data.data).length > 0) { diff --git a/platform/src/components2/wendu4.vue b/platform/src/components2/wendu4.vue index ba4c76d..f387565 100644 --- a/platform/src/components2/wendu4.vue +++ b/platform/src/components2/wendu4.vue @@ -224,7 +224,7 @@ const checkAndTriggerWarning = () => { }, 5000); } }; - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL const getCurrentTime = () => { const now = new Date(); const minutes = now.getMinutes(); @@ -236,7 +236,7 @@ const getCurrentTime = () => { const fetchDevices = async () => { try { - const response = await axios.get('http://localhost:5000/api/chou1/devices'); + const response = await axios.get(`${apiUrl}/api/chou1/devices`); if (response.data.code === 200) { return response.data.data; } @@ -255,7 +255,7 @@ const fetchLatestActualSensorData = async (deviceId: string) => { hasData.value = false; const response = await axios.get( - `http://localhost:5000/api/sensor/device/${deviceId}/latest` + `${apiUrl}/api/sensor/device/${deviceId}/latest` ); if (response.data.code === 200) { @@ -278,7 +278,7 @@ const fetchLatestActualSensorData = async (deviceId: string) => { const fetchLatestTemperaturePrediction = async () => { try { - const response = await axios.get('http://localhost:5000/api/prediction/temperature/latest'); + const response = await axios.get(`${apiUrl}/api/prediction/temperature/latest`); if (response.data.code === 200) { return response.data.data as number; } diff --git a/platform/src/components3/gu4.vue b/platform/src/components3/gu4.vue index 32407fb..f3db6eb 100644 --- a/platform/src/components3/gu4.vue +++ b/platform/src/components3/gu4.vue @@ -85,11 +85,11 @@ const initChart = () => { const handleResize = () => { chartInstance?.resize(); }; - +const apiUrl = import.meta.env.VITE_API_BASE_URL // 动态获取API基础URL // 获取故障类型数据 const fetchFaultData = async () => { try { - const response = await axios.get('http://localhost:5000/fault-types'); + const response = await axios.get(`${apiUrl}/fault-types`); if (response.data.success) { faultData.value = response.data.data; } diff --git a/platform/src/components3/gu6.vue b/platform/src/components3/gu6.vue index 7a1a538..5e4773b 100644 --- a/platform/src/components3/gu6.vue +++ b/platform/src/components3/gu6.vue @@ -97,6 +97,8 @@