feat:新增登录验证

This commit is contained in:
吉浩茹
2025-10-31 18:24:56 +08:00
parent 2b5dff94af
commit 20a3fe0b51
4 changed files with 250 additions and 123 deletions

View File

@ -7,68 +7,68 @@
<!-- 内容区域 -->
<view class="tabbar-content">
<!-- 环境参数详情 -->
<view class="parameter-details">
<!-- 温度卡片 -->
<view class="detail-card temperature-detail-card">
<view class="detail-header">
<view class="detail-icon-container">
<view class="detail-icon temperature-icon">🌡</view>
<text class="detail-label">温度</text>
</view>
<view class="detail-value-container">
<text class="detail-value">{{ temperature }}°C</text>
<view class="detail-status" :class="temperature > 0 ? 'active' : 'inactive'"></view>
</view>
</view>
<view class="detail-progress-bar">
<view class="detail-progress-fill temperature-progress" :style="{ width: temperatureProgress + '%' }"></view>
</view>
<!-- <view class="detail-range">
<text class="detail-range-text">{{ 0 }}°C - {{ 100 }}°C</text>
</view> -->
<!-- 环境参数详情 -->
<view class="parameter-details">
<!-- 温度卡片 -->
<view class="detail-card temperature-detail-card" @click="navigateToParameterRecord">
<view class="detail-header">
<view class="detail-icon-container">
<view class="detail-icon temperature-icon">🌡</view>
<text class="detail-label">温度</text>
</view>
<!-- 湿度卡片 -->
<view class="detail-card humidity-detail-card">
<view class="detail-header">
<view class="detail-icon-container">
<view class="detail-icon humidity-icon">💧</view>
<text class="detail-label">湿度</text>
</view>
<view class="detail-value-container">
<text class="detail-value">{{ humidity }}%</text>
<view class="detail-status" :class="humidity > 0 ? 'active' : 'inactive'"></view>
</view>
</view>
<view class="detail-progress-bar">
<view class="detail-progress-fill humidity-progress" :style="{ width: humidityProgress + '%' }"></view>
</view>
<!-- <view class="detail-range">
<text class="detail-range-text">{{ 0 }}% - {{ 100 }}%</text>
</view> -->
</view>
<!-- 洁净度卡片 -->
<view class="detail-card cleanliness-detail-card">
<view class="detail-header">
<view class="detail-icon-container">
<view class="detail-icon cleanliness-icon"></view>
<text class="detail-label">洁净度</text>
</view>
<view class="detail-value-container">
<text class="detail-value">{{ cleanliness > 0 ? cleanliness + 'μg/m³' : '-μg/m³' }}</text>
<view class="detail-status" :class="cleanliness > 0 ? 'active' : 'inactive'"></view>
</view>
</view>
<view class="detail-progress-bar">
<view class="detail-progress-fill cleanliness-progress" :style="{ width: cleanlinessProgress + '%' }"></view>
</view>
<!-- <view class="detail-range">
<text class="detail-range-text">{{ 0 }}% - {{ 100 }}%</text>
</view> -->
<view class="detail-value-container">
<text class="detail-value">{{ temperature }}°C</text>
<view class="detail-status" :class="temperature > 0 ? 'active' : 'inactive'"></view>
</view>
</view>
<view class="detail-progress-bar">
<view class="detail-progress-fill temperature-progress" :style="{ width: temperatureProgress + '%' }"></view>
</view>
<!-- <view class="detail-range">
<text class="detail-range-text">{{ 0 }}°C - {{ 100 }}°C</text>
</view> -->
</view>
<!-- 湿度卡片 -->
<view class="detail-card humidity-detail-card" @click="navigateToParameterRecord">
<view class="detail-header">
<view class="detail-icon-container">
<view class="detail-icon humidity-icon">💧</view>
<text class="detail-label">湿度</text>
</view>
<view class="detail-value-container">
<text class="detail-value">{{ humidity }}%</text>
<view class="detail-status" :class="humidity > 0 ? 'active' : 'inactive'"></view>
</view>
</view>
<view class="detail-progress-bar">
<view class="detail-progress-fill humidity-progress" :style="{ width: humidityProgress + '%' }"></view>
</view>
<!-- <view class="detail-range">
<text class="detail-range-text">{{ 0 }}% - {{ 100 }}%</text>
</view> -->
</view>
<!-- 洁净度卡片 -->
<view class="detail-card cleanliness-detail-card" @click="navigateToParameterRecord">
<view class="detail-header">
<view class="detail-icon-container">
<view class="detail-icon cleanliness-icon"></view>
<text class="detail-label">洁净度</text>
</view>
<view class="detail-value-container">
<text class="detail-value">{{ cleanliness > 0 ? cleanliness + 'μg/m³' : '-μg/m³' }}</text>
<view class="detail-status" :class="cleanliness > 0 ? 'active' : 'inactive'"></view>
</view>
</view>
<view class="detail-progress-bar">
<view class="detail-progress-fill cleanliness-progress" :style="{ width: cleanlinessProgress + '%' }"></view>
</view>
<!-- <view class="detail-range">
<text class="detail-range-text">{{ 0 }}% - {{ 100 }}%</text>
</view> -->
</view>
</view>
<!-- 空调设置 -->
<view class="air-conditioner-settings">
@ -385,6 +385,13 @@ export default {
this.loadWsdSettings()
// 注意:定时器在 onShow 中启动,避免重复启动
},
navigateToParameterRecord() {
try {
uni.switchTab({ url: '/pages/parameter/index' })
} catch (e) {
uni.showToast({ title: '页面跳转失败', icon: 'none' })
}
},
// 首次进入系统时创建启动事件
async createStartupEventIfNeeded() {
// 检查是否已经创建过启动事件

View File

@ -16,15 +16,32 @@
<text class="title-text">上动物联</text>
</view>
</view>
<!-- 下部区域按钮和版本号 -->
<view class="bottom-section">
<!-- 进入系统按钮 -->
<!-- 登录表单账号密码 -->
<view class="form-section">
<!-- <view class="form-item">
<text class="form-label">账号</text>
<input class="form-input" v-model="username" placeholder="请输入账号" placeholder-class="placeholder" confirm-type="next" />
</view> -->
<view class="form-item">
<text class="form-label">密码</text>
<input class="form-input" v-model="password" password placeholder="请输入密码" placeholder-class="placeholder" confirm-type="done" />
</view>
<view class="action-container">
<button class="enter-button" @click="navigateToTabBar">
<text class="button-text">进入系统 </text>
</button>
</view>
</view>
<!-- 下部区域按钮和版本号 -->
<view class="bottom-section">
<!-- 进入系统按钮 -->
<!-- <view class="action-container">
<button class="enter-button" @click="navigateToTabBar">
<text class="button-text">进入系统 </text>
</button>
</view> -->
<!-- 版本号 -->
<view class="version-container">
@ -37,84 +54,141 @@
<script>
import { manualReconnect } from '@/utils/sendMqtt.js'
import { authApi } from '@/utils/api.js'
export default {
data() {
return {
title: 'Hello',
username: '',
password: '',
}
},
computed: {
canLogin() {
// return this.username && this.username.trim().length > 0 && this.password && this.password.trim().length > 0
return this.password && this.password.trim().length > 0
}
},
onLoad() {},
methods: {
navigateToTabBar() {
console.log('🔧 用户点击进入系统开始MQTT重连...')
// 立即显示连接提示
uni.showLoading({
title: '正在连接MQTT...',
// mask: true
})
// 调用MQTT重连函数
async navigateToTabBar() {
if (!this.canLogin) {
uni.showToast({
title: '请输入密码',
icon: 'none',
duration: 1200
})
return
}
console.log('🔒 开始登录...')
// 先登录
try {
manualReconnect()
console.log('✅ MQTT重连函数已调用')
// 延迟跳转给MQTT连接一些时间
setTimeout(() => {
// 更新loading文本
uni.showLoading({ title: '正在登录...' })
const loginRes = await authApi.login({
username: this.username || 'admin',
password: this.password
})
console.log('🔒 登录结果:', loginRes)
if (loginRes.success) {
// 可选:如果返回 token保存以备后续请求使用
if (loginRes && loginRes.token) {
const token = loginRes.token;
try {
uni.setStorageSync('auth_token', token)
} catch (e) {}
}
uni.hideLoading()
uni.showToast({ title: '登录成功', icon: 'success', duration: 800 })
// 立即显示连接提示
uni.showLoading({
title: '正在跳转系统...',
title: '正在连接MQTT...',
// mask: true
})
uni.hideLoading()
// 跳转到tabbar的第一个页面环境参数页面
uni.switchTab({
url: '/pages/environment/index',
success: () => {
console.log('✅ 成功跳转到环境参数页面')
uni.showToast({
title: '系统连接成功',
icon: 'success',
duration: 1000
// 调用MQTT重连函数
try {
manualReconnect()
console.log('✅ MQTT重连函数已调用')
// 延迟跳转给MQTT连接一些时间
setTimeout(() => {
// 更新loading文本
uni.showLoading({
title: '正在跳转系统...',
// mask: true
})
},
fail: (err) => {
console.error('❌ 跳转到tabbar失败:', err);
// 如果失败尝试使用redirectTo
uni.redirectTo({
uni.hideLoading()
// 跳转到tabbar的第一个页面环境参数页面
uni.switchTab({
url: '/pages/environment/index',
success: () => {
console.log('✅ 使用redirectTo成功跳转')
console.log('✅ 成功跳转到环境参数页面')
uni.showToast({
title: '系统连接成功',
icon: 'success',
duration: 1000
})
},
fail: (redirectErr) => {
console.error('❌ redirectTo也失败:', redirectErr)
uni.showToast({
title: '页面跳转失败',
icon: 'error',
duration: 1000
})
fail: (err) => {
console.error('❌ 跳转到tabbar失败:', err);
// 如果失败尝试使用redirectTo
uni.redirectTo({
url: '/pages/environment/index',
success: () => {
console.log('✅ 使用redirectTo成功跳转')
uni.showToast({
title: '系统连接成功',
icon: 'success',
duration: 1000
})
},
fail: (redirectErr) => {
console.error('❌ redirectTo也失败:', redirectErr)
uni.showToast({
title: '页面跳转失败',
icon: 'error',
duration: 1000
})
}
});
}
});
}
})
}, 300) // 1秒后开始跳转
} catch (error) {
console.error('❌ MQTT重连失败:', error)
uni.hideLoading()
uni.showToast({
title: 'MQTT连接失败',
icon: 'error',
duration: 1000
})
}
} else {
uni.hideLoading()
uni.showToast({
title: loginRes?.message || '登录失败',
icon: 'none',
duration: 1500
})
}, 300) // 1秒后开始跳转
} catch (error) {
console.error('❌ MQTT重连失败:', error)
return
}
} catch (e) {
uni.hideLoading()
uni.showToast({
title: 'MQTT连接失败',
icon: 'error',
duration: 1000
title: e?.message || '登录失败',
icon: 'none',
duration: 1500
})
return
}
console.log('🔧 用户点击进入系统开始MQTT重连...')
}
},
}
@ -193,6 +267,7 @@ export default {
/* 进入系统按钮 */
.action-container {
margin-bottom: 40rpx;
margin-top: 40px;
}
.enter-button {
@ -210,6 +285,42 @@ export default {
font-weight: 500;
}
/* 表单样式 */
.form-section {
width: 100%;
max-width: 640rpx;
margin-top: 40rpx;
}
.form-item {
display: flex;
align-items: center;
background: #f7f8fa;
border-radius: 12rpx;
padding: 20rpx 24rpx;
margin-bottom: 24rpx;
}
.form-label {
width: 120rpx;
font-size: 28rpx;
color: #333333;
}
.form-input {
flex: 1;
font-size: 28rpx;
color: #111111;
}
.placeholder {
color: #999999;
}
.enter-button:disabled {
opacity: 0.5;
}
/* 版本号 */
.version-text {

View File

@ -5,6 +5,15 @@
import httpService from './http.js'
// 认证接口
export const authApi = {
// 登录
login(data) {
// 约定字段username、password
return httpService.post('/api/auth/login', data)
}
}
// 数据历史接口
export const dataHistoryApi = {
// 获取历史数据

View File

@ -282,11 +282,11 @@ const sendMqttData = (data) => {
});
} else {
console.log('✅ MQTT数据发送成功');
uni.showToast({
title: '数据发送成功',
icon: 'success',
duration: 1500
});
// uni.showToast({
// title: '数据发送成功',
// icon: 'success',
// duration: 1500
// });
}
});
@ -334,11 +334,11 @@ const sendMqttDataRecall = (data) => {
duration: 2000
});
} else {
uni.showToast({
title: '数据发送成功',
icon: 'success',
duration: 1500
});
// uni.showToast({
// title: '数据发送成功',
// icon: 'success',
// duration: 1500
// });
}
});