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