添加clientId字段到全局状态,优化请求参数处理,更新页面路由,调整取水口和灌溉相关界面,增强用户体验。
| | |
| | | form, |
| | | isShowLoding, |
| | | timeout, |
| | | header |
| | | header, |
| | | useParams |
| | | } = _options |
| | | |
| | | // 检查url是否为undefined |
| | | if (!url) { |
| | | console.error('请求URL不能为空'); |
| | | return Promise.reject(new Error('请求URL不能为空')); |
| | | } |
| | | |
| | | const app = getApp() |
| | | // 设置请求头 |
| | | if (form) { |
| | |
| | | myUrl = url; |
| | | } else { |
| | | myUrl = currentBaseUrl + url; |
| | | } |
| | | // 如果 useParams 为 true,拼接查询参数 |
| | | if (useParams && data) { |
| | | const queryString = objToQueryString(data); // 使用上面定义的函数 |
| | | myUrl += `?${queryString}`; // 拼接查询字符串 |
| | | data = {}; // 请求体数据设为空 |
| | | } |
| | | wx.request({ |
| | | url: myUrl, |
| | |
| | | }) |
| | | }) |
| | | } |
| | | |
| | | function objToQueryString(obj) { |
| | | return Object.keys(obj) |
| | | .map(key => { |
| | | // 对键和值进行 URL 编码 |
| | | return `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`; |
| | | }) |
| | | .join('&'); // 将所有键值对用 '&' 连接起来 |
| | | } |
| | | // 封装toast函数 |
| | | function showToast(title, icon = 'none', duration = 2500, mask = false) { |
| | | wx.showToast({ |
| | |
| | | token:"", |
| | | isLoggedIn:false, |
| | | operator:"2025030416200600006", |
| | | clientId:"", |
| | | AppID:"wxbc2b6a00dd904ead" |
| | | } |
| | | }) |
| | |
| | | { |
| | | "pages": [ |
| | | "pages/irrigation/irrigation", |
| | | "pages/createIrrigation/createIrrigation", |
| | | "pages/groupDetail/groupDetail", |
| | | |
| | | "pages/home/home", |
| | | "pages/valveList/valveList", |
| | | "pages/feedback/feedback", |
| | |
| | | "pages/personCharge/personcharge", |
| | | "pages/openCard/openCard", |
| | | "pages/rechargeMoney/rechargMoney", |
| | | "pages/rechargeCard/rechargeCard" |
| | | "pages/rechargeCard/rechargeCard", |
| | | "pages/irrigation/irrigation", |
| | | "pages/createIrrigation/createIrrigation", |
| | | "pages/irrigationDetail/irrigationDetail", |
| | | "pages/groupDetail/groupDetail" |
| | | ], |
| | | "window": { |
| | | "navigationBarTextStyle": "white", |
New file |
| | |
| | | <?xml version="1.0" encoding="UTF-8"?><svg width="24" height="24" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M14 6.67578C8.02198 10.1339 4 16.5973 4 24.0001M14 6.67578V14.0001M14 6.67578H6.67564" stroke="#4090FF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M6.67564 34C10.1337 39.978 16.5972 44 24 44M6.67564 34H14M6.67564 34V41.3244" stroke="#4090FF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M34 41.3244C39.978 37.8663 44 31.4028 44 24M34 41.3244V34M34 41.3244H41.3244" stroke="#4090FF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/><path d="M41.3242 14C37.8661 8.02199 31.4027 4 23.9999 4M41.3242 14H33.9999M41.3242 14V6.67564" stroke="#4090FF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/></svg> |
| | |
| | | <!-- 轮灌组列表 --> |
| | | <view class="group-list {{item.expanded ? 'expanded' : ''}}"> |
| | | <block wx:for="{{item.groups}}" wx:for-item="group" wx:for-index="groupIndex" wx:key="id"> |
| | | <view class="group-item {{group.selected ? 'selected' : ''}}"> |
| | | <view class="group-info" bindtap="navigateToGroupDetail" data-project-index="{{index}}" data-group-index="{{groupIndex}}"> |
| | | <view class="group-item {{group.selected ? 'selected' : ''}}" bindtap="navigateToGroupDetail" data-project-index="{{index}}" data-group-index="{{groupIndex}}"> |
| | | <view class="group-info" > |
| | | <view class="group-name">{{group.name}}</view> |
| | | </view> |
| | | <view class="group-duration"> |
| | |
| | | align-items: center; |
| | | padding: 25rpx 30rpx; |
| | | border-top: 1rpx solid #eee; |
| | | position: relative; |
| | | transition: all 0.3s ease; |
| | | } |
| | | |
| | | .group-item::after { |
| | | content: ''; |
| | | position: absolute; |
| | | right: 15rpx; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 16rpx; |
| | | height: 16rpx; |
| | | border-top: 2rpx solid #999; |
| | | border-right: 2rpx solid #999; |
| | | transform: translateY(-50%) rotate(45deg); |
| | | } |
| | | |
| | | .group-item:active { |
| | | background-color: #e6f7ff; |
| | | } |
| | | |
| | | .group-item.selected { |
| | |
| | | flex: 1; |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .group-name { |
| | | font-size: 26rpx; |
| | | color: #666; |
| | | position: relative; |
| | | padding-left: 10rpx; |
| | | background-color: rgba(24, 144, 255, 0.1); |
| | | padding: 4rpx 20rpx; |
| | | border-radius: 10rpx; |
| | | } |
| | | |
| | | .group-hint { |
| | | font-size: 22rpx; |
| | | color: #1890FF; |
| | | margin-left: 10rpx; |
| | | background-color: rgba(24, 144, 255, 0.1); |
| | | padding: 4rpx 10rpx; |
| | | border-radius: 10rpx; |
| | | } |
| | | |
| | | /* .group-name::before { |
| | | content: ''; |
| | | position: absolute; |
| | | left: 0; |
| | | top: 50%; |
| | | transform: translateY(-50%); |
| | | width: 6rpx; |
| | | height: 6rpx; |
| | | background-color: #1890FF; |
| | | border-radius: 50%; |
| | | } */ |
| | | |
| | | .group-duration { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 20rpx; /* 为右侧箭头留出空间 */ |
| | | } |
| | | |
| | | .duration-input { |
| | |
| | | * 页面的初始数据 |
| | | */ |
| | | data: { |
| | | projectId: '', |
| | | projectName: '', |
| | | groupId: '', |
| | | groupName: '', |
| | | valveList: [ |
| | | // 模拟数据,实际应从API获取 |
| | | { id: '1', name: '阀控器1', status: 'online', location: '位置A' }, |
| | | { id: '2', name: '阀控器2', status: 'offline', location: '位置B' }, |
| | | { id: '3', name: '阀控器3', status: 'online', location: '位置C' }, |
| | | { id: '4', name: '阀控器4', status: 'online', location: '位置D' }, |
| | | { id: '5', name: '阀控器5', status: 'offline', location: '位置E' } |
| | | ], |
| | | loading: false |
| | | groupId: '', |
| | | waterOutletList: [], |
| | | refreshing: false, |
| | | isIrrigating: false // 是否正在灌溉中 |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面加载 |
| | | */ |
| | | onLoad: function (options) { |
| | | console.log('接收到的参数:', options); |
| | | |
| | | if (options) { |
| | | // 直接使用传递的isIrrigating参数,而不是根据status判断 |
| | | const isIrrigating = options.isIrrigating === 'true'; |
| | | console.log('灌溉状态判断:', options.status, '是否正在灌溉:', isIrrigating); |
| | | |
| | | // 处理接收到的参数 |
| | | this.setData({ |
| | | projectId: options.projectId || '', |
| | | projectName: options.projectName || '', |
| | | groupName: options.groupName || '', |
| | | groupId: options.groupId || '', |
| | | groupName: options.groupName || '' |
| | | isIrrigating: isIrrigating |
| | | }); |
| | | |
| | | console.log('设置后的数据:', this.data); |
| | | |
| | | // 设置导航栏标题 |
| | | wx.setNavigationBarTitle({ |
| | | title: this.data.groupName || '轮灌组详情' |
| | | }); |
| | | |
| | | // 获取阀控器列表 |
| | | this.fetchValveList(); |
| | | this.loadWaterOutletData(); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 获取阀控器列表 |
| | | * 加载取水口数据 |
| | | */ |
| | | fetchValveList: function () { |
| | | this.setData({ loading: true }); |
| | | loadWaterOutletData: function() { |
| | | this.setData({ |
| | | refreshing: true |
| | | }); |
| | | |
| | | // 这里应该是实际的API请求 |
| | | // 模拟API请求延迟 |
| | | console.log('加载取水口数据,灌溉状态:', this.data.isIrrigating); |
| | | |
| | | // 模拟数据 |
| | | let mockData = { |
| | | waterOutlets: [] |
| | | }; |
| | | |
| | | // 生成取水口数据,所有取水口都有命令状态 |
| | | mockData.waterOutlets = [ |
| | | { |
| | | id: 1, |
| | | name: '取水口 A-1', |
| | | status: 'online', |
| | | commandStatus: 'sent' // 命令已下发 |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: '取水口 A-2', |
| | | status: 'online', |
| | | commandStatus: 'unsent' // 命令未下发 |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: '取水口 A-3', |
| | | status: 'offline', |
| | | commandStatus: 'unsent' // 命令未下发 |
| | | } |
| | | ]; |
| | | |
| | | // 模拟网络请求延迟 |
| | | setTimeout(() => { |
| | | this.setData({ loading: false }); |
| | | // 实际数据已在data中初始化,这里只是模拟请求完成 |
| | | this.setData({ |
| | | waterOutletList: mockData.waterOutlets, |
| | | refreshing: false |
| | | }); |
| | | console.log('设置取水口数据完成:', this.data.waterOutletList); |
| | | }, 1000); |
| | | |
| | | // 实际API请求示例 |
| | | // 实际项目中应该使用wx.request获取数据 |
| | | // wx.request({ |
| | | // url: 'your-api-url', |
| | | // data: { |
| | | // projectId: this.data.projectId, |
| | | // groupId: this.data.groupId |
| | | // }, |
| | | // url: `https://your-api-url/groups/${this.data.groupId}/waterOutlets`, |
| | | // method: 'GET', |
| | | // success: (res) => { |
| | | // if (res.data && res.data.code === 0) { |
| | | // this.setData({ |
| | | // valveList: res.data, |
| | | // loading: false |
| | | // waterOutletList: res.data.data.waterOutlets, |
| | | // refreshing: false |
| | | // }); |
| | | // }, |
| | | // fail: () => { |
| | | // this.setData({ loading: false }); |
| | | // } else { |
| | | // wx.showToast({ |
| | | // title: '获取数据失败', |
| | | // icon: 'none' |
| | | // }); |
| | | // this.setData({ |
| | | // refreshing: false |
| | | // }); |
| | | // } |
| | | // }, |
| | | // fail: () => { |
| | | // wx.showToast({ |
| | | // title: '网络错误', |
| | | // icon: 'none' |
| | | // }); |
| | | // this.setData({ |
| | | // refreshing: false |
| | | // }); |
| | | // } |
| | | // }); |
| | | }, |
| | | |
| | | /** |
| | | * 下拉刷新处理函数 |
| | | */ |
| | | onRefresh: function() { |
| | | this.loadWaterOutletData(); |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面初次渲染完成 |
| | | */ |
| | | onReady: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面显示 |
| | | */ |
| | | onShow: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面隐藏 |
| | | */ |
| | | onHide: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面卸载 |
| | | */ |
| | | onUnload: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 页面相关事件处理函数--监听用户下拉动作 |
| | | */ |
| | | onPullDownRefresh: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 页面上拉触底事件的处理函数 |
| | | */ |
| | | onReachBottom: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 用户点击右上角分享 |
| | | */ |
| | | onShareAppMessage: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 返回上一页 |
| | | */ |
| | | goBack: function () { |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 阀控器列表 --> |
| | | <!-- 取水口列表 --> |
| | | <view class="valve-list-container"> |
| | | <view class="section-title">取水口阀控器列表</view> |
| | | |
| | | <!-- 加载中 --> |
| | | <!-- 加载中 |
| | | <view class="loading-container" wx:if="{{loading}}"> |
| | | <view class="loading-icon"></view> |
| | | <view class="loading-text">加载中...</view> |
| | | </view> |
| | | </view> --> |
| | | |
| | | <!-- 阀控器列表 --> |
| | | <view class="valve-list" wx:else> |
| | | <block wx:for="{{valveList}}" wx:key="id"> |
| | | <!-- 取水口列表 - 可下拉刷新的scroll-view --> |
| | | <scroll-view |
| | | class="valve-list" |
| | | scroll-y="true" |
| | | refresher-enabled="{{true}}" |
| | | refresher-threshold="50" |
| | | refresher-default-style="black" |
| | | refresher-background="#f2f2f2" |
| | | refresher-triggered="{{refreshing}}" |
| | | bindrefresherrefresh="onRefresh" |
| | | > |
| | | <block wx:for="{{waterOutletList}}" wx:key="id"> |
| | | <view class="valve-item"> |
| | | <view class="valve-info"> |
| | | <view class="valve-name">{{item.name}}</view> |
| | | <view class="valve-location">{{item.location}}</view> |
| | | </view> |
| | | <view class="valve-status {{item.status === 'online' ? 'online' : 'offline'}}"> |
| | | <view class="valve-name"> |
| | | <text>{{item.name}}</text> |
| | | <view class="valve-status-inline {{item.status === 'online' ? 'online' : 'offline'}}"> |
| | | {{item.status === 'online' ? '在线' : '离线'}} |
| | | </view> |
| | | </view> |
| | | </block> |
| | | </view> |
| | | <view class="command-status {{item.commandStatus}}"> |
| | | {{item.commandStatus === 'sent' ? '命令已下发' : '命令未下发'}} |
| | | </view> |
| | | </view> |
| | | </block> |
| | | |
| | | <!-- 空状态 --> |
| | | <view class="empty-state" wx:if="{{!loading && valveList.length === 0}}"> |
| | | <view class="empty-state" wx:if="{{waterOutletList.length === 0}}"> |
| | | <image class="empty-icon" src="/images/empty.svg" mode="aspectFit"></image> |
| | | <view class="empty-text">暂无阀控器数据</view> |
| | | <view class="empty-text">暂无取水口数据</view> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | |
| | | <!-- 底部按钮 --> |
| | | <view class="bottom-button"> |
| | | <button class="back-button" hover-class="back-button-hover" bindtap="goBack">返回</button> |
| | | </view> |
| | | |
| | | </view> |
| | |
| | | .group-detail-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | min-height: 100vh; |
| | | background-color: #f5f5f5; |
| | | height: 100vh; |
| | | background-color: #F5F5F5; |
| | | } |
| | | |
| | | /* 页面标题样式 */ |
| | | .page-header { |
| | | background-color: #1890FF; |
| | | background-color: #FFFFFF; |
| | | padding: 30rpx; |
| | | color: #fff; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .header-content { |
| | |
| | | } |
| | | |
| | | .project-name { |
| | | font-size: 24rpx; |
| | | opacity: 0.8; |
| | | font-size: 28rpx; |
| | | color: #666666; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .group-name { |
| | | font-size: 32rpx; |
| | | font-weight: 500; |
| | | font-size: 36rpx; |
| | | font-weight: bold; |
| | | color: #333333; |
| | | } |
| | | |
| | | /* 阀控器列表容器 */ |
| | | /* 取水口列表容器 */ |
| | | .valve-list-container { |
| | | flex: 1; |
| | | padding: 30rpx; |
| | | padding: 0 30rpx; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .section-title { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | font-weight: 500; |
| | | /* 取水口列表 */ |
| | | .valve-list { |
| | | height: 100%; |
| | | } |
| | | |
| | | /* 取水口项目 */ |
| | | .valve-item { |
| | | background-color: #FFFFFF; |
| | | border-radius: 12rpx; |
| | | padding: 30rpx; |
| | | margin-bottom: 20rpx; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .valve-info { |
| | | flex: 1; |
| | | } |
| | | |
| | | .valve-name { |
| | | font-size: 32rpx; |
| | | font-weight: 500; |
| | | color: #333333; |
| | | display: flex; |
| | | align-items: center; |
| | | flex-wrap: wrap; |
| | | } |
| | | |
| | | .valve-status-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: flex-end; |
| | | } |
| | | |
| | | .valve-status { |
| | | padding: 8rpx 20rpx; |
| | | border-radius: 30rpx; |
| | | font-size: 24rpx; |
| | | font-weight: 500; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .valve-status.online { |
| | | background-color: rgba(82, 196, 26, 0.1); |
| | | color: #52C41A; |
| | | } |
| | | |
| | | .valve-status.offline { |
| | | background-color: rgba(245, 34, 45, 0.1); |
| | | color: #F5222D; |
| | | } |
| | | |
| | | /* 内联状态样式 */ |
| | | .valve-status-inline { |
| | | font-size: 24rpx; |
| | | font-weight: 500; |
| | | padding: 4rpx 12rpx; |
| | | border-radius: 20rpx; |
| | | margin-left: 12rpx; |
| | | display: inline-flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | height: 32rpx; |
| | | line-height: 1; |
| | | } |
| | | |
| | | .valve-status-inline.online { |
| | | background-color: rgba(82, 196, 26, 0.1); |
| | | color: #52C41A; |
| | | } |
| | | |
| | | .valve-status-inline.offline { |
| | | background-color: rgba(245, 34, 45, 0.1); |
| | | color: #F5222D; |
| | | } |
| | | |
| | | /* 命令状态样式 */ |
| | | .command-status { |
| | | padding: 8rpx 20rpx; |
| | | border-radius: 30rpx; |
| | | font-size: 24rpx; |
| | | font-weight: 500; |
| | | text-align: center; |
| | | min-width: 160rpx; |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | height: 40rpx; |
| | | line-height: 1; |
| | | } |
| | | |
| | | .command-status.sent { |
| | | background-color: rgba(82, 196, 26, 0.1); |
| | | color: #52C41A; |
| | | } |
| | | |
| | | .command-status.unsent { |
| | | background-color: rgba(250, 173, 20, 0.1); |
| | | color: #FAAD14; |
| | | } |
| | | |
| | | /* 加载中样式 */ |
| | | .loading-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 60rpx 0; |
| | | align-items: center; |
| | | height: 300rpx; |
| | | } |
| | | |
| | | .loading-icon { |
| | | width: 60rpx; |
| | | height: 60rpx; |
| | | border: 4rpx solid #f3f3f3; |
| | | border-top: 4rpx solid #1890FF; |
| | | width: 80rpx; |
| | | height: 80rpx; |
| | | border: 6rpx solid #f3f3f3; |
| | | border-top: 6rpx solid #3498db; |
| | | border-radius: 50%; |
| | | animation: spin 1s linear infinite; |
| | | margin-bottom: 20rpx; |
| | |
| | | } |
| | | |
| | | .loading-text { |
| | | font-size: 26rpx; |
| | | color: #999; |
| | | } |
| | | |
| | | /* 阀控器列表样式 */ |
| | | .valve-list { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .valve-item { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | padding: 30rpx; |
| | | background-color: #fff; |
| | | margin-bottom: 20rpx; |
| | | border-radius: 8rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .valve-info { |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .valve-name { |
| | | font-size: 28rpx; |
| | | color: #333; |
| | | margin-bottom: 10rpx; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | .valve-location { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | } |
| | | |
| | | .valve-status { |
| | | padding: 8rpx 20rpx; |
| | | border-radius: 30rpx; |
| | | font-size: 24rpx; |
| | | } |
| | | |
| | | .valve-status.online { |
| | | background-color: #e6f7ff; |
| | | color: #1890FF; |
| | | } |
| | | |
| | | .valve-status.offline { |
| | | background-color: #fff1f0; |
| | | color: #f5222d; |
| | | color: #666666; |
| | | } |
| | | |
| | | /* 空状态样式 */ |
| | | .empty-state { |
| | | display: flex; |
| | | flex-direction: column; |
| | | align-items: center; |
| | | justify-content: center; |
| | | padding: 100rpx 0; |
| | | align-items: center; |
| | | height: 400rpx; |
| | | } |
| | | |
| | | .empty-icon { |
| | |
| | | } |
| | | |
| | | .empty-text { |
| | | font-size: 26rpx; |
| | | color: #999; |
| | | font-size: 28rpx; |
| | | color: #999999; |
| | | } |
| | | |
| | | /* 底部按钮样式 */ |
| | |
| | | get, |
| | | post |
| | | } = require('../../api/request.js'); |
| | | const { PROJECT_URLS } = require('../../api/config.js'); |
| | | const { |
| | | PROJECT_URLS |
| | | } = require('../../api/config.js'); |
| | | Page({ |
| | | |
| | | /** |
| | |
| | | waterIntakeName: "", |
| | | image: "/images/ic_head_bg.jpg", |
| | | userPhone: "", |
| | | userName: "请登录", |
| | | userName: "请点击登录", |
| | | scrollViewHeight: 0, |
| | | listData: [], |
| | | isRefreshing: false, |
| | |
| | | lastIntakeName: "", |
| | | showProjectDialog: false, |
| | | selectedProject: '', |
| | | avatarTapCount: 0 |
| | | avatarTapCount: 0, |
| | | isFromLogin: false |
| | | }, |
| | | |
| | | openValve: function (e) { |
| | | const app = getApp(); |
| | | if (app.globalData.isLoggedIn) { |
| | | wx.navigateTo({ |
| | | url: '/pages/waterIntake/waterIntake', |
| | | }) |
| | | } else { |
| | | wx.showToast({ |
| | | title: '请先登录', |
| | | icon: 'error' |
| | | }) |
| | | } |
| | | }, |
| | | calculateScrollViewHeight: function () { |
| | | wx.createSelectorQuery().selectAll('.list-item').boundingClientRect((rects) => { |
| | |
| | | * 生命周期函数--监听页面加载 |
| | | */ |
| | | onLoad(options) { |
| | | // 检查是否已选择项目 |
| | | const { PROJECT_URLS } = require('../../api/config.js'); |
| | | console.log('home页面onLoad开始,参数:', options); |
| | | |
| | | storage.getItem('selectedProject').then((project) => { |
| | | // 检查是否从登录页面返回 |
| | | let fromLogin = false; |
| | | |
| | | // 检查URL参数 |
| | | if (options && options.fromLogin === 'true') { |
| | | console.log('检测到URL参数fromLogin=true'); |
| | | fromLogin = true; |
| | | } |
| | | |
| | | // 检查是否有临时标记 |
| | | try { |
| | | const tempFromLogin = wx.getStorageSync('_temp_from_login'); |
| | | console.log('读取到的临时标记值:', tempFromLogin); |
| | | |
| | | if (tempFromLogin === 'true') { |
| | | console.log('检测到临时fromLogin标记'); |
| | | fromLogin = true; |
| | | |
| | | // 延迟清除临时标记,确保其他地方有足够时间读取 |
| | | setTimeout(() => { |
| | | try { |
| | | wx.removeStorageSync('_temp_from_login'); |
| | | console.log('自动清除临时fromLogin标记'); |
| | | } catch (e) { |
| | | console.error('清除临时标记失败:', e); |
| | | } |
| | | }, 10000); // 延长到10秒 |
| | | } |
| | | } catch (e) { |
| | | console.error('读取临时标记失败:', e); |
| | | } |
| | | |
| | | console.log('home页面加载,fromLogin:', fromLogin, '参数:', options); |
| | | |
| | | // 设置fromLogin标志 |
| | | if (fromLogin) { |
| | | console.log('设置isFromLogin=true'); |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | } |
| | | |
| | | // 延迟执行剩余的初始化过程,以确保临时标记和URL参数能被正确处理 |
| | | setTimeout(() => { |
| | | this.initializePage(options, fromLogin); |
| | | }, 100); |
| | | }, |
| | | |
| | | // 新增的初始化页面辅助函数,分离出onLoad中的逻辑以便延迟执行 |
| | | initializePage(options, fromLogin) { |
| | | // 检查是否已选择项目 |
| | | const { |
| | | PROJECT_URLS |
| | | } = require('../../api/config.js'); |
| | | |
| | | // 确保全局变量存在 |
| | | getApp().globalData = getApp().globalData || {}; |
| | | |
| | | storage.getItemSafe('selectedProject') |
| | | .then((project) => { |
| | | if (project) { |
| | | this.setData({ |
| | | selectedProject: project |
| | | }); |
| | | |
| | | // 确保全局变量存在 |
| | | getApp().globalData = getApp().globalData || {}; |
| | | // 设置 baseUrl |
| | | const baseUrl = PROJECT_URLS[project]; |
| | | getApp().globalData.baseUrl = baseUrl; |
| | |
| | | |
| | | console.log('加载已保存的项目:', project, '域名:', baseUrl, 'tag:', getApp().globalData.tag); |
| | | |
| | | // 检查登录状态 |
| | | if (!getApp().globalData.isLoggedIn) { |
| | | this.checkLoginStatus(); |
| | | return; // 如果未登录,等待跳转到登录页面 |
| | | } |
| | | // 检查sessionId是否存在 |
| | | return storage.getItemSafe('sessionId'); |
| | | } else { |
| | | // 首次进入,显示项目选择弹窗 |
| | | this.setData({ |
| | | showProjectDialog: true |
| | | }); |
| | | return; // 等待用户选择项目 |
| | | return Promise.reject({ |
| | | type: 'project_not_selected', |
| | | message: '未选择项目' |
| | | }); // 终止后续处理 |
| | | } |
| | | }) |
| | | .then(sessionId => { |
| | | if (sessionId) { |
| | | // 如果sessionId存在,设置全局登录状态 |
| | | getApp().globalData.sessionId = sessionId; |
| | | getApp().globalData.isLoggedIn = true; |
| | | |
| | | // 尝试获取clientId |
| | | return storage.getItemSafe('clientId'); |
| | | } else { |
| | | return Promise.reject({ |
| | | type: 'session_not_found', |
| | | message: '未找到sessionId' |
| | | }); |
| | | } |
| | | }) |
| | | .then(clientId => { |
| | | if (clientId) { |
| | | getApp().globalData.clientId = clientId; |
| | | } |
| | | |
| | | //判断本地是否保存sessionId |
| | | // 使用 wx.nextTick 等待页面渲染完成 |
| | | wx.nextTick(() => { |
| | | this.calculateScrollViewHeight(); |
| | | }); |
| | | //当开阀成功后调用刷新 |
| | | console.log("onLoad:" + options.param); |
| | | if (options.param) { |
| | | wx.showToast({ |
| | | title: '开阀成功', |
| | | icon: 'success', |
| | | duration: 3000 |
| | | // 继续初始化页面 |
| | | this.continueInitPage(options); |
| | | }) |
| | | this.getOpenList(); |
| | | .catch(err => { |
| | | // 将错误对象规范化 |
| | | const error = typeof err === 'object' ? err : { |
| | | type: 'unknown', |
| | | message: String(err) |
| | | }; |
| | | console.log('获取存储数据中断:', error.message); |
| | | |
| | | // 如果是从登录页返回或已登录,不再跳转 |
| | | if (fromLogin || getApp().globalData.isLoggedIn) { |
| | | console.log('从登录页返回或已登录,继续初始化页面'); |
| | | this.continueInitPage(options); |
| | | return; |
| | | } |
| | | this.initData(); |
| | | }).catch(err => { |
| | | console.error('Failed to get selectedProject:', err); |
| | | // 出错时也显示项目选择弹窗 |
| | | |
| | | // 处理未选择项目的情况 |
| | | if (error.type === 'project_not_selected') { |
| | | console.log('未选择项目,显示项目选择弹窗'); |
| | | this.setData({ |
| | | showProjectDialog: true |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 处理未找到sessionId的情况 |
| | | if (error.type === 'session_not_found' && this.data.selectedProject) { |
| | | // 检查是否已从登录页返回 |
| | | const isReturning = this.getFromLogin(); |
| | | console.log('未找到sessionId,是否从登录页返回:', isReturning); |
| | | |
| | | // 如果已经是从登录页返回的,不要再跳回去 |
| | | if (isReturning) { |
| | | console.log('已经从登录页返回,不再跳转回去'); |
| | | this.continueInitPage(options); |
| | | return; |
| | | } |
| | | |
| | | console.log('未找到sessionId,跳转到登录页'); |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}` |
| | | }); |
| | | return; |
| | | } |
| | | |
| | | // 其他未知错误,尝试继续初始化页面 |
| | | console.warn('未知错误,尝试继续初始化页面:', error); |
| | | this.continueInitPage(options); |
| | | }); |
| | | }, |
| | | |
| | |
| | | * 生命周期函数--监听页面显示 |
| | | */ |
| | | onShow() { |
| | | console.log('home页面onShow开始'); |
| | | |
| | | // 获取当前页面的参数 |
| | | const pages = getCurrentPages(); |
| | | const currentPage = pages[pages.length - 1]; |
| | | |
| | | let fromLogin = false; |
| | | |
| | | // 检查是否有fromLogin参数 |
| | | if (currentPage && currentPage.options && currentPage.options.fromLogin === 'true') { |
| | | console.log('onShow: 检测到fromLogin参数,设置isFromLogin标记'); |
| | | fromLogin = true; |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | } |
| | | |
| | | // 检查是否有临时标记 |
| | | try { |
| | | const tempFromLogin = wx.getStorageSync('_temp_from_login'); |
| | | console.log('onShow: 读取到的临时标记值:', tempFromLogin); |
| | | |
| | | if (tempFromLogin === 'true') { |
| | | console.log('onShow: 检测到临时fromLogin标记'); |
| | | fromLogin = true; |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | } |
| | | } catch (e) { |
| | | console.error('onShow: 读取临时标记失败:', e); |
| | | } |
| | | |
| | | // 初始化处理 |
| | | if (fromLogin || this.data.isFromLogin) { |
| | | console.log('onShow: 从登录页返回,不进行登录检查'); |
| | | } else { |
| | | console.log('onShow: 正常显示页面'); |
| | | // 延迟检查登录状态,确保能正确识别临时标记 |
| | | setTimeout(() => { |
| | | this.checkLoginStatusIfNeeded(); |
| | | }, 300); |
| | | } |
| | | }, |
| | | |
| | | // 检查登录状态(仅在需要时) |
| | | checkLoginStatusIfNeeded() { |
| | | // 再次确认是否从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('检测到从登录页返回的标记,不进行登录检查'); |
| | | return; |
| | | } |
| | | |
| | | // 再次检查全局登录状态 |
| | | if (getApp().globalData.isLoggedIn) { |
| | | console.log('检测到全局登录状态,不进行登录检查'); |
| | | return; |
| | | } |
| | | |
| | | console.log('执行登录状态检查'); |
| | | this.checkLoginStatus(); |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面隐藏 |
| | | */ |
| | | onHide() { |
| | | |
| | | // 页面隐藏时考虑清理临时标记 |
| | | this.cleanupTempMarkers(); |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面卸载 |
| | | */ |
| | | onUnload() { |
| | | |
| | | // 页面卸载时清理临时标记 |
| | | this.cleanupTempMarkers(); |
| | | }, |
| | | |
| | | /** |
| | |
| | | icon: 'none' |
| | | }) |
| | | }, |
| | | //解绑用户 |
| | | unbind() { |
| | | wx.showModal({ |
| | | title: '解绑确认', |
| | | content: '确定要解绑当前账号吗?', |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | this.unBindPost() |
| | | } |
| | | } |
| | | }); |
| | | }, |
| | | //轮灌 |
| | | irrigation() { |
| | | wx.navigateTo({ |
| | | url: '/pages/irrigation/irrigation', |
| | | }) |
| | | }, |
| | | handleChange(e) { |
| | | const item = e.currentTarget.dataset.item; |
| | | console.log(item); |
| | |
| | | rtuAddr: rtuAddr, |
| | | vcNum: vcNum, //虚拟卡ID |
| | | orderNo: orderNo, |
| | | operator: app.globalData.operator //操作员 |
| | | operator: app.globalData.clientId //操作员 |
| | | }; |
| | | console.log("postCloseValaue" + data); |
| | | post({ |
| | |
| | | */ |
| | | getOpenList() { |
| | | const app = getApp(); |
| | | |
| | | // 检查是否从登录页返回 |
| | | const fromLogin = this.getFromLogin(); |
| | | |
| | | // 检查clientId是否存在 |
| | | if (!app.globalData.clientId) { |
| | | console.log('getOpenList: clientId不存在,不执行API请求'); |
| | | |
| | | // 如果是从登录页返回,就显示空列表而不是错误提示 |
| | | this.setData({ |
| | | listData: [], |
| | | isRefreshing: false, |
| | | isWXRefreshing: false |
| | | }); |
| | | |
| | | // 如果不是从登录页返回且不处于刷新状态,考虑检查登录状态 |
| | | if (!fromLogin && !this.data.isRefreshing && !this.data.isWXRefreshing) { |
| | | console.log('getOpenList: 非刷新状态下检测到无clientId,尝试自动登录'); |
| | | // 延迟调用微信登录,尝试自动恢复会话 |
| | | setTimeout(() => { |
| | | if (!getApp().globalData.clientId && !this.getFromLogin()) { |
| | | this.wxLogin(); |
| | | } |
| | | }, 1000); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | console.log('getOpenList: 开始获取列表数据, clientId:', app.globalData.clientId); |
| | | |
| | | const params = { |
| | | url: 'wx/valve/get', |
| | | data: { |
| | | operator: app.globalData.operator |
| | | operator: app.globalData.clientId |
| | | } |
| | | }; |
| | | |
| | | get(params).then(data => { |
| | | console.log('获取列表数据成功:', data); |
| | | this.setData({ |
| | | listData: data.content, |
| | | isRefreshing: false, // 将triggered属性设置为false,表示下拉刷新已完成 |
| | | isWXRefreshing: false, // 将triggered属性设置为false,表示下拉刷新已完成 |
| | | }) |
| | | }); |
| | | |
| | | // 成功获取数据后刷新UI高度 |
| | | setTimeout(() => { |
| | | this.calculateScrollViewHeight(); |
| | | }, 200); |
| | | }).catch(err => { |
| | | console.error('获取列表数据失败:', err); |
| | | // 错误回调 |
| | | this.setData({ |
| | | isRefreshing: false, // 将triggered属性设置为false,表示下拉刷新已完成 |
| | | isWXRefreshing: false, // 将triggered属性设置为false,表示下拉刷新已完成 |
| | | }) |
| | | }); |
| | | |
| | | // 检查错误类型 |
| | | if (err && err.code === '0003') { |
| | | console.log('会话无效或过期,但不进行跳转'); |
| | | |
| | | // 如果不是从登录页返回,显示错误提示 |
| | | if (!fromLogin) { |
| | | wx.showToast({ |
| | | title: err.msg, |
| | | icon: 'error', |
| | | title: '登录已过期,请刷新重试', |
| | | icon: 'none', |
| | | duration: 3000 |
| | | }) |
| | | }); |
| | | } |
| | | } else { |
| | | // 一般错误,显示错误信息 |
| | | wx.showToast({ |
| | | title: err.msg || '获取列表数据失败', |
| | | icon: 'none', |
| | | duration: 3000 |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | /** |
| | |
| | | }, |
| | | //根据session获取农户信息 |
| | | getUserDataBySession() { |
| | | // 先检查是否从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('getUserDataBySession: 检测到从登录页返回的标记,不执行API请求'); |
| | | return; |
| | | } |
| | | |
| | | const app = getApp(); |
| | | |
| | | // 检查是否有sessionId |
| | | if (!app.globalData.sessionId) { |
| | | console.log('getUserDataBySession: sessionId不存在,不执行API请求'); |
| | | return; |
| | | } |
| | | |
| | | console.log('getUserDataBySession: 开始获取用户数据, sessionId:', app.globalData.sessionId); |
| | | |
| | | const params = { |
| | | url: 'wx/client/simple_info', |
| | | data: { |
| | | sessionId: app.globalData.sessionId |
| | | } |
| | | }; |
| | | |
| | | get(params).then(data => { |
| | | console.log('获取用户数据成功:', data); |
| | | this.setData({ |
| | | userName: data.content.clientName, |
| | | userPhone: this.maskPhoneNumber(data.content.phone) |
| | | }) |
| | | }); |
| | | }).catch(err => { |
| | | // 错误回调 |
| | | console.error('获取用户数据失败:', err); |
| | | // 错误回调,但不进行页面跳转 |
| | | |
| | | // 检查错误类型 |
| | | if (err && err.code === '0003') { |
| | | console.log('会话无效或过期,但不进行跳转'); |
| | | // 不再直接跳转到登录页 |
| | | |
| | | // 清除会话信息 |
| | | app.globalData.sessionId = ''; |
| | | app.globalData.isLoggedIn = false; |
| | | |
| | | // 如果不是从登录页返回,显示错误提示 |
| | | if (!this.getFromLogin()) { |
| | | wx.showToast({ |
| | | title: err.msg, |
| | | icon: 'error', |
| | | title: '登录已过期,请重新登录', |
| | | icon: 'none', |
| | | duration: 3000 |
| | | }) |
| | | }) |
| | | }); |
| | | } |
| | | } else { |
| | | // 其他错误,显示错误信息 |
| | | wx.showToast({ |
| | | title: err.msg || '获取用户信息失败', |
| | | icon: 'none', |
| | | duration: 3000 |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | maskPhoneNumber(phoneNumber) { |
| | | if (phoneNumber.length !== 11) { |
| | |
| | | const data = { |
| | | intakeName: intakeName, //取水口ID |
| | | // vcId: vcId, //虚拟卡ID |
| | | operator: app.globalData.operator, //操作员 |
| | | operator: app.globalData.clientId, //操作员 |
| | | forceOpen: !!isforce // 使用逻辑非操作符 !! 来确保 isForce 是布尔值 |
| | | }; |
| | | post({ |
| | |
| | | //进入界面获取界面数据 |
| | | initData() { |
| | | const app = getApp(); |
| | | console.log("tag>>>>:" +app.globalData.tag) |
| | | console.log("initData开始,tag:", app.globalData.tag); |
| | | |
| | | if (storage.isHasKeySync("userData")) { |
| | | storage.getItem('userData').then((data) => { |
| | | // 首先检查是否从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('initData: 检测到从登录页返回的标记,仅获取基本数据'); |
| | | |
| | | // 即使从登录页返回,也尝试获取开阀列表以显示基本UI |
| | | // 但先检查是否有客户端ID可用 |
| | | if (!app.globalData.clientId) { |
| | | console.log('initData: 从登录页返回且无clientId,尝试从存储恢复'); |
| | | // 尝试从存储恢复clientId |
| | | storage.getItemSafe('clientId') |
| | | .then(clientId => { |
| | | if (clientId) { |
| | | console.log('initData: 从存储恢复clientId成功:', clientId); |
| | | app.globalData.clientId = clientId; |
| | | this.getOpenList(); |
| | | } else { |
| | | console.log('initData: 无法恢复clientId,显示空列表'); |
| | | this.setData({ |
| | | listData: [] |
| | | }); |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error('initData: 恢复clientId失败:', err); |
| | | this.setData({ |
| | | listData: [] |
| | | }); |
| | | }); |
| | | } else { |
| | | this.getOpenList(); |
| | | } |
| | | return; |
| | | } |
| | | |
| | | // 尝试获取用户数据和已开阀记录 |
| | | try { |
| | | // 优先检查全局变量中是否有sessionId |
| | | if (app.globalData.sessionId) { |
| | | console.log('initData: 使用全局sessionId获取数据'); |
| | | this.getUserDataBySession(); |
| | | this.getOpenList(); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否有存储的userData |
| | | const hasUserData = storage.isHasKeySync("userData"); |
| | | console.log('initData: 是否存在userData:', hasUserData); |
| | | |
| | | if (hasUserData) { |
| | | storage.getItemSafe('userData') |
| | | .then((data) => { |
| | | console.log('initData: 成功读取userData'); |
| | | if (data) { |
| | | try { |
| | | let jsonObj = JSON.parse(data); |
| | | app.globalData.sessionId = jsonObj.sessionId; |
| | | app.globalData.tag = jsonObj.tag; |
| | | console.log("userData已加载:", data); |
| | | } catch (e) { |
| | | console.error('userData解析失败:', e); |
| | | } |
| | | } |
| | | // 无论如何都尝试获取用户信息和开阀列表 |
| | | this.getUserDataBySession(); |
| | | this.getOpenList(); |
| | | console.log("userData>>>>>>>" + data) |
| | | }).catch((err) => { |
| | | console.error('Failed to load parameter:', err); |
| | | }); |
| | | }) |
| | | .catch((err) => { |
| | | console.error('加载userData失败:', err); |
| | | |
| | | // 再次检查是否从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('initData:catch: 检测到从登录页返回的标记,只获取开阀列表'); |
| | | this.getOpenList(); |
| | | } else { |
| | | this.getUserDataBySession(); |
| | | this.getOpenList(); |
| | | console.log('Failed to load parameter:false'); |
| | | } |
| | | }); |
| | | } else { |
| | | console.log('未找到userData,直接获取数据'); |
| | | |
| | | // 再次检查是否从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('initData:else: 检测到从登录页返回的标记,只获取开阀列表'); |
| | | this.getOpenList(); |
| | | } else { |
| | | this.getUserDataBySession(); |
| | | this.getOpenList(); |
| | | } |
| | | } |
| | | } catch (e) { |
| | | console.error('initData执行出错:', e); |
| | | |
| | | // 再次检查是否从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('initData:error: 检测到从登录页返回的标记,只获取开阀列表'); |
| | | this.getOpenList(); |
| | | } else { |
| | | // 出错时仍尝试获取数据 |
| | | this.getUserDataBySession(); |
| | | this.getOpenList(); |
| | | } |
| | | } |
| | | }, |
| | | // 处理头像点击 |
| | | handleAvatarTap() { |
| | |
| | | if (!e.detail.visible && !this.data.selectedProject) { |
| | | return; |
| | | } |
| | | this.setData({ showProjectDialog: e.detail.visible }); |
| | | this.setData({ |
| | | showProjectDialog: e.detail.visible |
| | | }); |
| | | }, |
| | | |
| | | // 处理项目选择变化 |
| | |
| | | }); |
| | | return; |
| | | } |
| | | const projectName = this.data.selectedProject === 'JYG' ? '嘉峪关项目' : '民勤项目'; |
| | | |
| | | // 获取当前已选项目和新选择的项目 |
| | | const currentProject = getApp().globalData.selectedProject; |
| | | const newProject = this.data.selectedProject; |
| | | const projectName = newProject === 'JYG' ? '嘉峪关项目' : '民勤项目'; |
| | | |
| | | // 检查是否切换了项目(如果当前项目不同于新选择的项目) |
| | | const isProjectChanged = currentProject && currentProject !== newProject; |
| | | |
| | | // 如果切换了项目,先清除登录状态 |
| | | if (isProjectChanged) { |
| | | console.log(`正在从项目 ${currentProject} 切换到 ${newProject},将清除登录状态`); |
| | | |
| | | // 清除全局登录状态 |
| | | getApp().globalData.sessionId = ''; |
| | | getApp().globalData.clientId = ''; |
| | | getApp().globalData.isLoggedIn = false; |
| | | getApp().globalData.userInfo = null; |
| | | |
| | | // 清除存储中的登录状态 |
| | | try { |
| | | wx.removeStorageSync('sessionId'); |
| | | wx.removeStorageSync('clientId'); |
| | | wx.removeStorageSync('userData'); |
| | | wx.removeStorageSync('isLoggedIn'); |
| | | console.log('已清除登录相关的存储数据'); |
| | | } catch (e) { |
| | | console.error('清除存储数据失败:', e); |
| | | } |
| | | |
| | | // 重置UI显示状态 |
| | | this.setData({ |
| | | userName: "请登录", |
| | | userPhone: "", |
| | | listData: [] |
| | | }); |
| | | } |
| | | |
| | | // 保存项目选择到本地存储 |
| | | storage.setItem('selectedProject', this.data.selectedProject).then(() => { |
| | | storage.setItem('selectedProject', newProject).then(() => { |
| | | // 更新 BASEURL |
| | | const { PROJECT_URLS } = require('../../api/config.js'); |
| | | const baseUrl = PROJECT_URLS[this.data.selectedProject]; |
| | | const { |
| | | PROJECT_URLS |
| | | } = require('../../api/config.js'); |
| | | const baseUrl = PROJECT_URLS[newProject]; |
| | | |
| | | // 直接修改全局变量 |
| | | // 更新全局变量 |
| | | getApp().globalData = getApp().globalData || {}; |
| | | getApp().globalData.baseUrl = baseUrl; |
| | | getApp().globalData.selectedProject = this.data.selectedProject; |
| | | getApp().globalData.selectedProject = newProject; |
| | | |
| | | // 根据项目设置对应的tag |
| | | if (this.data.selectedProject === 'JYG') { |
| | | if (newProject === 'JYG') { |
| | | getApp().globalData.tag = 'ym'; // 嘉峪关项目对应tag为ym |
| | | } else if (this.data.selectedProject === 'MQ') { |
| | | } else if (newProject === 'MQ') { |
| | | getApp().globalData.tag = 'mq'; // 民勤项目对应tag为mq |
| | | } |
| | | |
| | |
| | | showProjectDialog: false |
| | | }); |
| | | |
| | | // 显示切换成功提示 |
| | | wx.showToast({ |
| | | title: `已选择${projectName}`, |
| | | title: isProjectChanged ? `已切换至${projectName},请重新登录` : `已选择${projectName}`, |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }); |
| | | |
| | | // 检查登录状态 |
| | | // setTimeout(() => { |
| | | // this.checkLoginStatus(); |
| | | // }, 500); |
| | | // 如果切换了项目,延迟跳转到登录页面 |
| | | if (isProjectChanged) { |
| | | setTimeout(() => { |
| | | console.log('项目已切换,正在跳转到登录页面'); |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${newProject}`, |
| | | success: () => console.log('成功跳转到登录页'), |
| | | fail: (err) => console.error('跳转到登录页失败:', err) |
| | | }); |
| | | }, 2000); |
| | | } |
| | | }).catch(err => { |
| | | console.error('保存项目选择失败:', err); |
| | | wx.showToast({ |
| | | title: '保存失败,请重试', |
| | | icon: 'success', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | }); |
| | |
| | | checkLoginStatus() { |
| | | const app = getApp(); |
| | | |
| | | // 检查是否已登录 |
| | | if (app.globalData.isLoggedIn && app.globalData.sessionId) { |
| | | // 已登录,重新加载页面 |
| | | wx.reLaunch({ |
| | | url: '/pages/home/home' |
| | | }); |
| | | } else { |
| | | // 尝试从本地存储获取用户信息 |
| | | storage.getItem('userInfo').then(userInfoStr => { |
| | | if (userInfoStr) { |
| | | // 首先,强制再次检查是否从登录页返回 |
| | | try { |
| | | const userInfo = JSON.parse(userInfoStr); |
| | | // 验证用户信息是否有效 |
| | | if (userInfo && userInfo.sessionId) { |
| | | // 恢复登录状态 |
| | | app.globalData.sessionId = userInfo.sessionId; |
| | | app.globalData.token = userInfo.token; |
| | | app.globalData.userInfo = userInfo; |
| | | app.globalData.isLoggedIn = true; |
| | | |
| | | // 已登录,重新加载页面 |
| | | wx.reLaunch({ |
| | | url: '/pages/home/home' |
| | | const tempFromLogin = wx.getStorageSync('_temp_from_login'); |
| | | if (tempFromLogin === 'true') { |
| | | console.log('checkLoginStatus: 检测到临时存储_temp_from_login=true,不执行跳转'); |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | return; |
| | | } |
| | | } catch (e) { |
| | | console.error('解析用户信息失败:', e); |
| | | } |
| | | console.error('checkLoginStatus: 读取临时标记失败:', e); |
| | | } |
| | | |
| | | // 未登录,跳转到登录页面 |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}` |
| | | // 检查是否已登录 |
| | | if (app.globalData.isLoggedIn && app.globalData.sessionId) { |
| | | console.log('已从全局变量检测到登录状态'); |
| | | return; |
| | | } |
| | | |
| | | // 检查本页面是否正在处理返回逻辑 |
| | | const fromLogin = this.getFromLogin(); |
| | | if (fromLogin) { |
| | | console.log('从登录页返回,不再重定向'); |
| | | return; |
| | | } |
| | | |
| | | // 获取当前页面路由和参数 |
| | | const pages = getCurrentPages(); |
| | | const currentPage = pages[pages.length - 1]; |
| | | const currentRoute = currentPage ? currentPage.route : ''; |
| | | const currentOptions = currentPage ? currentPage.options || {} : {}; |
| | | |
| | | console.log('当前页面路由:', currentRoute, '参数:', currentOptions); |
| | | |
| | | // 检查URL参数中是否有fromLogin |
| | | if (currentOptions.fromLogin === 'true') { |
| | | console.log('URL参数中检测到fromLogin=true,不执行跳转'); |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | }).catch(err => { |
| | | console.error('获取用户信息失败:', err); |
| | | // 未登录,跳转到登录页面 |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}` |
| | | return; |
| | | } |
| | | |
| | | // 如果当前已在登录页,不再跳转 |
| | | if (currentRoute === 'pages/login/login') { |
| | | console.log('当前已在登录页,不再跳转'); |
| | | return; |
| | | } |
| | | |
| | | // Promise链处理存储检查 |
| | | Promise.all([ |
| | | storage.getItemSafe('sessionId'), |
| | | storage.getItemSafe('clientId'), |
| | | storage.getItemSafe('isLoggedIn') |
| | | ]) |
| | | .then(([sessionId, clientId, isLoggedIn]) => { |
| | | // 最后一次检查临时标记 |
| | | try { |
| | | const tempFromLogin = wx.getStorageSync('_temp_from_login'); |
| | | if (tempFromLogin === 'true') { |
| | | console.log('Promise内部: 检测到临时存储_temp_from_login=true,不执行跳转'); |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | return; |
| | | } |
| | | } catch (e) {} |
| | | |
| | | if (sessionId) { |
| | | // 从存储中恢复登录状态 |
| | | app.globalData.sessionId = sessionId; |
| | | app.globalData.isLoggedIn = true; |
| | | |
| | | if (clientId) { |
| | | app.globalData.clientId = clientId; |
| | | } |
| | | |
| | | console.log('已从存储恢复登录状态'); |
| | | // 已登录,刷新页面 |
| | | wx.reLaunch({ |
| | | url: '/pages/home/home' |
| | | }); |
| | | } else { |
| | | // 标记当前页面正在处理返回逻辑 |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | |
| | | // 未登录,可能需要跳转到登录页面 |
| | | console.log('未检测到登录状态,可能需要跳转到登录页'); |
| | | |
| | | // 最后再检查一次是否已从登录页返回 |
| | | const finalCheck = this.getFromLogin(); |
| | | if (finalCheck) { |
| | | console.log('最终检查: 已从登录页返回,不再跳转'); |
| | | return; |
| | | } |
| | | |
| | | console.log('确认需要跳转到登录页'); |
| | | |
| | | // 跳转前再次检查登录页面临时标记 |
| | | try { |
| | | wx.setStorageSync('_attempted_login_redirect', 'true'); |
| | | } catch (e) {} |
| | | |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}`, |
| | | success: () => console.log('成功跳转到登录页'), |
| | | fail: (err) => console.error('跳转到登录页失败:', err) |
| | | }); |
| | | } |
| | | }) |
| | | .catch(err => { |
| | | console.error('检查登录状态时出错:', err); |
| | | |
| | | // 标记当前页面正在处理返回逻辑 |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | |
| | | // 再次检查是否已从登录页返回 |
| | | if (this.getFromLogin()) { |
| | | console.log('错误处理: 已从登录页返回,不再跳转'); |
| | | return; |
| | | } |
| | | |
| | | // 出错时也跳转到登录页 |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}`, |
| | | success: () => console.log('错误后成功跳转到登录页'), |
| | | fail: (err) => console.error('错误后跳转到登录页失败:', err) |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | // 辅助函数:检查是否从登录页返回 |
| | | getFromLogin() { |
| | | // 先检查全局变量(作为备用方案) |
| | | if (getApp().globalData && getApp().globalData._tempFromLogin === true) { |
| | | console.log('getFromLogin: 检测到全局变量_tempFromLogin=true'); |
| | | // 设置标志,确保下次检查时能识别 |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | |
| | | // 清除全局标记,防止重复识别 |
| | | setTimeout(() => { |
| | | getApp().globalData._tempFromLogin = false; |
| | | console.log('已清除全局变量_tempFromLogin标记'); |
| | | }, 100); |
| | | |
| | | return true; |
| | | } |
| | | |
| | | // 检查是否有设置fromLogin标志 |
| | | if (this.data.isFromLogin) { |
| | | console.log('getFromLogin: 检测到this.data.isFromLogin=true'); |
| | | return true; |
| | | } |
| | | |
| | | // 检查当前页面的options |
| | | const pages = getCurrentPages(); |
| | | const currentPage = pages[pages.length - 1]; |
| | | if (currentPage && currentPage.options && currentPage.options.fromLogin === 'true') { |
| | | console.log('getFromLogin: 检测到URL参数fromLogin=true'); |
| | | // 设置标志,确保下次检查时能识别 |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | return true; |
| | | } |
| | | |
| | | // 检查临时标记 |
| | | try { |
| | | const tempFromLogin = wx.getStorageSync('_temp_from_login'); |
| | | console.log('getFromLogin: 读取到的临时标记值:', tempFromLogin); |
| | | |
| | | if (tempFromLogin === 'true') { |
| | | console.log('getFromLogin: 检测到临时存储_temp_from_login=true'); |
| | | // 设置标志,确保下次检查时能识别 |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | return true; |
| | | } |
| | | } catch (e) { |
| | | console.error('getFromLogin: 读取临时标记失败:', e); |
| | | } |
| | | |
| | | console.log('getFromLogin: 未检测到从登录页返回的标记'); |
| | | return false; |
| | | }, |
| | | |
| | | // 继续初始化页面 |
| | | continueInitPage(options) { |
| | | console.log('继续初始化页面,options:', options); |
| | | |
| | | // 检查是否从登录页返回 |
| | | let fromLogin = false; |
| | | |
| | | // 从URL参数中检查 |
| | | if (options && options.fromLogin === 'true') { |
| | | console.log('continueInitPage: 从URL参数检测到fromLogin=true'); |
| | | fromLogin = true; |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | } |
| | | |
| | | // 从临时标记中检查 |
| | | try { |
| | | const tempFromLogin = wx.getStorageSync('_temp_from_login'); |
| | | if (tempFromLogin === 'true') { |
| | | console.log('continueInitPage: 检测到临时标记_temp_from_login=true'); |
| | | fromLogin = true; |
| | | this.setData({ |
| | | isFromLogin: true |
| | | }); |
| | | } |
| | | } catch (e) { |
| | | console.error('continueInitPage: 读取临时标记失败:', e); |
| | | } |
| | | |
| | | // 从页面数据中检查 |
| | | if (this.data.isFromLogin) { |
| | | console.log('continueInitPage: 从页面数据中检测到isFromLogin=true'); |
| | | fromLogin = true; |
| | | } |
| | | |
| | | // 判断本地是否保存sessionId |
| | | // 使用 wx.nextTick 等待页面渲染完成 |
| | | wx.nextTick(() => { |
| | | this.calculateScrollViewHeight(); |
| | | }); |
| | | |
| | | // 当开阀成功后调用刷新 |
| | | if (options && options.param) { |
| | | console.log("开阀成功参数:", options.param); |
| | | wx.showToast({ |
| | | title: '开阀成功', |
| | | icon: 'success', |
| | | duration: 3000 |
| | | }); |
| | | this.getOpenList(); |
| | | } |
| | | |
| | | // 初始化数据 |
| | | this.initData(); |
| | | |
| | | // 如果不是从登录页返回,则设置延迟检查登录状态 |
| | | if (!fromLogin) { |
| | | console.log('不是从登录页返回,延迟检查登录状态'); |
| | | setTimeout(() => { |
| | | // 再次检查是否已从登录页返回(可能在初始化过程中状态已变) |
| | | if (this.getFromLogin()) { |
| | | console.log('延迟检查:检测到从登录页返回的标记,不再检查登录状态'); |
| | | return; |
| | | } |
| | | |
| | | // 仅在未登录且不是从登录页返回时检查登录状态 |
| | | if (!getApp().globalData.isLoggedIn) { |
| | | console.log('延迟检查:未登录且不是从登录页返回,执行登录状态检查'); |
| | | this.checkLoginStatus(); |
| | | } |
| | | }, 500); |
| | | } else { |
| | | console.log('从登录页返回,不检查登录状态'); |
| | | } |
| | | }, |
| | | |
| | | // 微信登录 |
| | | wxLogin(){ |
| | | if(!getApp().globalData.isLoggedIn){ |
| | | const that = this; |
| | | wx.showLoading({ |
| | | title: '正在登录请稍候...', |
| | | mask: true |
| | | }); |
| | | |
| | | wx.login({ |
| | | success: function (res) { |
| | | success: (res) => { |
| | | if (res.code) { |
| | | var code = res.code; |
| | | console.log(code); |
| | | // 将code发送到服务器获取openid |
| | | that.codeLogin(code); |
| | | post({ |
| | | url: "wx/client/code_login", |
| | | data: { |
| | | code: res.code |
| | | } |
| | | }).then(response => { |
| | | wx.hideLoading(); |
| | | if (response.code === "0001") { |
| | | if (response.content.client.clientId === "") { |
| | | // 未绑定账号,跳转到登录页面 |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}` |
| | | }); |
| | | } else { |
| | | console.log('登录失败!' + res.errMsg); |
| | | this.setData({ |
| | | userName: response.content.client.clientName, |
| | | userPhone: response.content.client.userPhone |
| | | }) |
| | | // 已有账号,保存数据并初始化 |
| | | const sessionId = response.content.client.sessionId; |
| | | const clientId = response.content.client.clientId; |
| | | |
| | | // 设置全局变量 |
| | | getApp().globalData.sessionId = sessionId; |
| | | getApp().globalData.clientId = clientId; |
| | | getApp().globalData.isLoggedIn = true; |
| | | |
| | | // 设置正确的项目tag |
| | | const tag = this.data.selectedProject === 'JYG' ? 'ym' : 'mq'; |
| | | getApp().globalData.tag = tag; |
| | | |
| | | // 保存到存储 |
| | | storage.setItem("sessionId", sessionId); |
| | | storage.setItem("clientId", clientId); |
| | | storage.setItem("isLoggedIn", "true"); |
| | | |
| | | // 保存userData信息,包含sessionId和tag |
| | | const userData = JSON.stringify({ |
| | | sessionId: sessionId, |
| | | tag: tag, |
| | | project: this.data.selectedProject, |
| | | userName: response.content.client.clientName, |
| | | userPhone: response.content.client.userPhone |
| | | }); |
| | | storage.setItem("userData", userData) |
| | | .then(() => { |
| | | console.log('用户数据保存成功,包含项目信息:', this.data.selectedProject, 'tag:', tag); |
| | | this.initData(); |
| | | }) |
| | | .catch(err => { |
| | | console.warn('保存userData失败,但继续初始化:', err); |
| | | this.initData(); |
| | | }); |
| | | |
| | | } |
| | | } else { |
| | | wx.showToast({ |
| | | title: '登录失败', |
| | | icon: 'error', |
| | | duration: 2000 |
| | | }); |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}` |
| | | }); |
| | | } |
| | | }).catch(error => { |
| | | wx.hideLoading(); |
| | | console.error('登录请求失败:', error); |
| | | wx.showToast({ |
| | | title: '登录失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | wx.redirectTo({ |
| | | url: `/pages/login/login?project=${this.data.selectedProject}` |
| | | }); |
| | | }); |
| | | } else { |
| | | wx.hideLoading(); |
| | | console.log('登录失败!' + res.errMsg); |
| | | wx.showToast({ |
| | | title: '微信登录失败', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }, |
| | | fail: (err) => { |
| | | wx.hideLoading(); |
| | | console.error('微信登录API调用失败:', err); |
| | | wx.showToast({ |
| | | title: '登录失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }); |
| | | } |
| | | }, |
| | | //微信code登录 |
| | | codeLogin(codeData) { |
| | | |
| | | // 辅助函数:清理临时标记 |
| | | cleanupTempMarkers() { |
| | | // 只有在isFromLogin为true时才进行清理 |
| | | if (this.data.isFromLogin) { |
| | | console.log('清理临时标记'); |
| | | |
| | | // 清理存储标记 |
| | | try { |
| | | wx.removeStorageSync('_temp_from_login'); |
| | | } catch (e) { |
| | | console.error('清理存储标记失败:', e); |
| | | } |
| | | |
| | | // 清理全局变量标记 |
| | | if (getApp().globalData) { |
| | | getApp().globalData._tempFromLogin = false; |
| | | } |
| | | |
| | | // 重设isFromLogin为false,但添加延迟,避免影响当前页面的返回逻辑 |
| | | setTimeout(() => { |
| | | this.setData({ |
| | | isFromLogin: false |
| | | }); |
| | | console.log('重置isFromLogin=false'); |
| | | }, 5000); |
| | | } |
| | | }, //确认解绑 |
| | | unBindPost() { |
| | | this.setData({ |
| | | showUnBind: false |
| | | }) |
| | | wx.showLoading({ |
| | | title: '正在登录请稍候...', // 加载提示文字 |
| | | title: '正在解绑请稍候...', // 加载提示文字 |
| | | mask: true // 是否显示透明蒙层,防止触摸穿透,默认为 false |
| | | }); |
| | | const data = { |
| | | code: codeData, //临时登录凭证 |
| | | sessionId: getApp().globalData.sessionId //取水口ID |
| | | }; |
| | | post({ |
| | | url: "wx/client/code_login", |
| | | url: 'wx/client/unbind', |
| | | data: data, |
| | | useParams: true |
| | | }).then(response => { |
| | | // 处理成功响应 |
| | | console.log('请求成功:', response); |
| | | // 加载完成后隐藏加载动画 |
| | | wx.hideLoading(); |
| | | if (response.code === "0001") { |
| | | //假如为空则跳转到绑定界面 |
| | | if (response.content.client.clientId === "") { |
| | | wx.navigateTo({ |
| | | url: '/pages/login/login' |
| | | }) |
| | | } else { |
| | | //缓存在本地 |
| | | this.setData({ |
| | | isLogin: true |
| | | }) |
| | | getApp().globalData.sessionId = response.content.client.sessionId |
| | | storage.setItem("sessionId", response.content.client.sessionId) |
| | | getApp().globalData.clientId = response.content.client.clientId |
| | | storage.setItem("clientId", response.content.client.clientId) |
| | | this.initData(); |
| | | } |
| | | } else { |
| | | const app = getApp(); |
| | | |
| | | // 清除全局登录状态 |
| | | app.globalData.sessionId = ''; |
| | | app.globalData.clientId = ''; |
| | | app.globalData.isLoggedIn = false; |
| | | app.globalData.userInfo = null; |
| | | |
| | | // 清除存储中的登录状态 |
| | | const storage = require('../../utils/storage.js'); |
| | | storage.removeItem('sessionId') |
| | | .then(() => storage.removeItem('clientId')) |
| | | .then(() => storage.removeItem('userData')) |
| | | .then(() => storage.removeItem('isLoggedIn')) |
| | | .then(() => { |
| | | wx.showToast({ |
| | | title: 'title', |
| | | icon: 'error', |
| | | title: '解绑成功', |
| | | icon: 'success', |
| | | duration: 2000 |
| | | }); |
| | | |
| | | // 重置UI显示状态 |
| | | this.setData({ |
| | | userName: "请点击登录", |
| | | userPhone: "", |
| | | listData: [] |
| | | }); |
| | | }) |
| | | } |
| | | .catch(err => { |
| | | console.error('解绑过程中出错:', err); |
| | | wx.showToast({ |
| | | title: '解绑失败,请重试', |
| | | icon: 'none', |
| | | duration: 2000 |
| | | }); |
| | | }); |
| | | }).catch(error => { |
| | | // 加载完成后隐藏加载动画 |
| | | wx.hideLoading(); |
| | | // 处理错误响应 |
| | | console.error('请求失败:', error); |
| | | wx.showToast({ |
| | | title: '解绑失败', |
| | | icon: 'error', |
| | | duration: 3000 |
| | | }) |
| | | }); |
| | | }, |
| | | }) |
| | |
| | | <text class="head-bottom">{{userPhone}}</text> |
| | | </view> |
| | | <view class="head-button-wrapper"> |
| | | <text class="unbind" bind:tap="feedBack">解绑</text> |
| | | <text class="unbind" bind:tap="unbind">解绑</text> |
| | | <text class="head-bottom" bind:tap="feedBack">联系客服</text> |
| | | </view> |
| | | <view class="scen-view" bind:tap="scenCode"> |
| | |
| | | <image src="/images/record.svg" /> |
| | | <text>开关阀记录</text> |
| | | </view> |
| | | <view class="center-view" bind:tap="feedBack"> |
| | | <image src="/images/question.svg" /> |
| | | <view class="center-view" bind:tap="irrigation"> |
| | | <image src="/images/irrigation.svg" /> |
| | | <text>轮灌</text> |
| | | </view> |
| | | </view> |
| | |
| | | }, |
| | | |
| | | /** |
| | | * 点击列表项 |
| | | */ |
| | | onItemTap: function (e) { |
| | | const id = e.currentTarget.dataset.id; |
| | | const status = e.currentTarget.dataset.status; |
| | | |
| | | // 导航到灌溉详情页面,并传递参数 |
| | | wx.navigateTo({ |
| | | url: `/pages/irrigationDetail/irrigationDetail?id=${id}&fromList=true` |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | | * 点击发布按钮 |
| | | */ |
| | | onPublish: function (e) { |
| | |
| | | }, |
| | | |
| | | /** |
| | | * 阻止事件冒泡 |
| | | */ |
| | | stopPropagation: function (e) { |
| | | // 阻止事件冒泡 |
| | | return false; |
| | | }, |
| | | |
| | | /** |
| | | * 开始下拉刷新 |
| | | */ |
| | | startPullDownRefresh: function() { |
| | |
| | | <view class="scroll-bg"> |
| | | <block wx:if="{{currentList.length > 0}}"> |
| | | <!-- 统一显示所有列表项,不再按状态分组 --> |
| | | <view class="list-item" wx:for="{{currentList}}" wx:key="id"> |
| | | <view class="list-item" wx:for="{{currentList}}" wx:key="id" bindtap="onItemTap" data-id="{{item.id}}" data-status="{{item.status}}"> |
| | | <view class="item-header"> |
| | | <view class="info-row title-row"> |
| | | <view class="info-label">编号:</view> |
| | |
| | | </view> |
| | | </block> |
| | | </view> |
| | | <view class="item-actions"> |
| | | <view class="item-actions" catchtap="stopPropagation"> |
| | | <!-- 根据状态显示不同的按钮 --> |
| | | <block wx:if="{{item.status === '未发布'}}"> |
| | | <button class="action-button publish-button" hover-class="publish-button-hover" bindtap="onPublish" data-id="{{item.id}}">发布</button> |
New file |
| | |
| | | Page({ |
| | | /** |
| | | * 页面的初始数据 |
| | | */ |
| | | data: { |
| | | planCode: '', |
| | | startTime: '', |
| | | projects: [], |
| | | isRefreshing: false, // 下拉刷新状态 |
| | | planId: '' // 保存计划ID |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面加载 |
| | | */ |
| | | onLoad: function (options) { |
| | | if (options.id) { |
| | | this.setData({ |
| | | planId: options.id |
| | | }); |
| | | // 从列表页面进入时,所有项目默认收起 |
| | | const fromListPage = options.fromList === 'true'; |
| | | this.loadIrrigationDetail(options.id, !fromListPage); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 加载灌溉计划详情 |
| | | * @param {string} id 灌溉计划ID |
| | | * @param {boolean} isFirstLoad 是否首次加载 |
| | | */ |
| | | loadIrrigationDetail: function (id, isFirstLoad = false) { |
| | | // 开始加载,设置刷新状态 |
| | | this.setData({ |
| | | isRefreshing: true |
| | | }); |
| | | |
| | | // 保存当前项目的展开状态 |
| | | const currentExpandStates = {}; |
| | | if (!isFirstLoad && this.data.projects.length > 0) { |
| | | this.data.projects.forEach((project, index) => { |
| | | currentExpandStates[project.id] = project.expanded; |
| | | }); |
| | | } |
| | | |
| | | // 这里应该是从API获取数据 |
| | | // 以下是模拟数据 |
| | | const mockData = { |
| | | planCode: 'IRG20240317001', |
| | | startTime: '2024-03-17 08:00', |
| | | projects: [ |
| | | { |
| | | id: 1, |
| | | name: '项目A', |
| | | expanded: isFirstLoad ? true : false, // 仅在非列表页进入且首次加载时展开第一个项目 |
| | | groups: [ |
| | | { |
| | | id: 1, |
| | | name: '轮灌组A-1', |
| | | status: 'irrigated', // 已灌溉 |
| | | statusText: '已灌溉', |
| | | startTime: '2024-03-17 08:00', |
| | | endTime: '2024-03-17 09:30', |
| | | duration: 90 |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: '轮灌组A-2', |
| | | status: 'irrigating', // 正在灌溉 |
| | | statusText: '正在灌溉', |
| | | startTime: '2024-03-17 09:30', |
| | | endTime: '2024-03-17 11:00', |
| | | duration: 90 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | id: 2, |
| | | name: '项目B', |
| | | expanded: false, |
| | | groups: [ |
| | | { |
| | | id: 3, |
| | | name: '轮灌组B-1', |
| | | status: 'waiting', // 未灌溉 |
| | | statusText: '未灌溉', |
| | | startTime: '2024-03-17 11:00', |
| | | endTime: '2024-03-17 12:30', |
| | | duration: 90 |
| | | }, |
| | | { |
| | | id: 4, |
| | | name: '轮灌组B-2', |
| | | status: 'waiting', // 未灌溉 |
| | | statusText: '未灌溉', |
| | | startTime: '2024-03-17 12:30', |
| | | endTime: '2024-03-17 14:00', |
| | | duration: 90 |
| | | } |
| | | ] |
| | | }, |
| | | { |
| | | id: 3, |
| | | name: '项目C', |
| | | expanded: false, |
| | | groups: [ |
| | | { |
| | | id: 5, |
| | | name: '轮灌组C-1', |
| | | status: 'waiting', // 未灌溉 |
| | | statusText: '未灌溉', |
| | | startTime: '2024-03-17 14:00', |
| | | endTime: '2024-03-17 15:30', |
| | | duration: 90 |
| | | } |
| | | ] |
| | | } |
| | | ] |
| | | }; |
| | | |
| | | // 计算每个项目的总灌溉时长 |
| | | mockData.projects = this.calculateProjectTotalDuration(mockData.projects); |
| | | |
| | | // 如果不是首次加载,恢复项目的展开状态 |
| | | if (!isFirstLoad) { |
| | | mockData.projects.forEach(project => { |
| | | if (currentExpandStates[project.id] !== undefined) { |
| | | project.expanded = currentExpandStates[project.id]; |
| | | } |
| | | }); |
| | | } |
| | | |
| | | // 模拟网络请求延迟 |
| | | setTimeout(() => { |
| | | // 设置页面数据 |
| | | this.setData({ |
| | | planCode: mockData.planCode, |
| | | startTime: mockData.startTime, |
| | | projects: mockData.projects, |
| | | isRefreshing: false // 结束刷新状态 |
| | | }); |
| | | }, 1000); |
| | | |
| | | // 实际项目中应该使用wx.request获取数据 |
| | | // wx.request({ |
| | | // url: 'https://your-api-url/irrigation/' + id, |
| | | // method: 'GET', |
| | | // success: (res) => { |
| | | // if (res.data && res.data.code === 0) { |
| | | // // 获取新数据 |
| | | // let projects = res.data.data.projects; |
| | | // |
| | | // // 如果是首次加载,设置默认展开状态 |
| | | // if (isFirstLoad) { |
| | | // projects = projects.map((project, index) => { |
| | | // return { |
| | | // ...project, |
| | | // expanded: index === 0 // 默认只展开第一个项目 |
| | | // }; |
| | | // }); |
| | | // } else { |
| | | // // 如果不是首次加载,恢复项目的展开状态 |
| | | // projects = projects.map(project => { |
| | | // return { |
| | | // ...project, |
| | | // expanded: currentExpandStates[project.id] !== undefined |
| | | // ? currentExpandStates[project.id] |
| | | // : false |
| | | // }; |
| | | // }); |
| | | // } |
| | | // |
| | | // // 计算每个项目的总灌溉时长 |
| | | // projects = this.calculateProjectTotalDuration(projects); |
| | | // |
| | | // this.setData({ |
| | | // planCode: res.data.data.planCode, |
| | | // startTime: res.data.data.startTime, |
| | | // projects: projects, |
| | | // isRefreshing: false // 结束刷新状态 |
| | | // }); |
| | | // } else { |
| | | // wx.showToast({ |
| | | // title: '获取数据失败', |
| | | // icon: 'none' |
| | | // }); |
| | | // this.setData({ |
| | | // isRefreshing: false // 结束刷新状态 |
| | | // }); |
| | | // } |
| | | // }, |
| | | // fail: () => { |
| | | // wx.showToast({ |
| | | // title: '网络错误', |
| | | // icon: 'none' |
| | | // }); |
| | | // this.setData({ |
| | | // isRefreshing: false // 结束刷新状态 |
| | | // }); |
| | | // } |
| | | // }); |
| | | }, |
| | | |
| | | /** |
| | | * 计算每个项目的总灌溉时长 |
| | | */ |
| | | calculateProjectTotalDuration: function(projects) { |
| | | return projects.map(project => { |
| | | // 计算项目下所有轮灌组的总时长 |
| | | const totalDuration = project.groups.reduce((total, group) => { |
| | | return total + (group.duration || 0); |
| | | }, 0); |
| | | |
| | | return { |
| | | ...project, |
| | | totalDuration: totalDuration |
| | | }; |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | | * 切换项目展开/收起状态 |
| | | */ |
| | | toggleProject: function (e) { |
| | | const index = e.currentTarget.dataset.index; |
| | | const expanded = this.data.projects[index].expanded; |
| | | |
| | | // 更新项目的展开状态 |
| | | const key = `projects[${index}].expanded`; |
| | | this.setData({ |
| | | [key]: !expanded |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | | * 导航到轮灌组详情页面 |
| | | */ |
| | | navigateToGroupDetail: function (e) { |
| | | const projectName = e.currentTarget.dataset.projectName; |
| | | const groupName = e.currentTarget.dataset.groupName; |
| | | const groupId = e.currentTarget.dataset.groupId; |
| | | const status = e.currentTarget.dataset.status; |
| | | |
| | | console.log('跳转到组详情页面,原始状态:', status); |
| | | |
| | | // 导航到组详情页面,并传递参数 |
| | | // 注意:需要将status转换为isIrrigating参数,以便在组详情页面正确显示命令状态 |
| | | wx.navigateTo({ |
| | | url: `/pages/groupDetail/groupDetail?projectName=${projectName}&groupName=${groupName}&groupId=${groupId}&status=${status}&isIrrigating=${status === 'irrigating' ? 'true' : 'false'}` |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面初次渲染完成 |
| | | */ |
| | | onReady: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面显示 |
| | | */ |
| | | onShow: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面隐藏 |
| | | */ |
| | | onHide: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 生命周期函数--监听页面卸载 |
| | | */ |
| | | onUnload: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 下拉刷新处理函数 |
| | | */ |
| | | onPullDownRefresh: function () { |
| | | // 重新加载数据,但保持展开状态 |
| | | if (this.data.planId) { |
| | | this.loadIrrigationDetail(this.data.planId, false); |
| | | } else { |
| | | this.setData({ |
| | | isRefreshing: false |
| | | }); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | | * 页面上拉触底事件的处理函数 |
| | | */ |
| | | onReachBottom: function () { |
| | | |
| | | }, |
| | | |
| | | /** |
| | | * 用户点击右上角分享 |
| | | */ |
| | | onShareAppMessage: function () { |
| | | |
| | | } |
| | | }) |
New file |
| | |
| | | { |
| | | "usingComponents": {}, |
| | | "navigationBarTitleText": "轮灌详情" |
| | | } |
New file |
| | |
| | | <view class="irrigation-detail-container"> |
| | | <!-- 顶部信息区域 --> |
| | | <view class="header-section"> |
| | | <view class="plan-info"> |
| | | <view class="plan-code"> |
| | | <text class="label">计划编号:</text> |
| | | <text class="value">{{planCode}}</text> |
| | | </view> |
| | | <image class="status-icon" src="/images/progress.svg" mode="aspectFit"></image> |
| | | </view> |
| | | |
| | | <!-- 灌溉时间信息 --> |
| | | <view class="time-info"> |
| | | <text class="label">灌溉开始时间:</text> |
| | | <text class="value">{{startTime}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 项目和轮灌组列表 --> |
| | | <scroll-view |
| | | scroll-y="true" |
| | | class="project-list" |
| | | refresher-enabled="{{true}}" |
| | | refresher-threshold="50" |
| | | refresher-triggered="{{isRefreshing}}" |
| | | bindrefresherrefresh="onPullDownRefresh"> |
| | | <view class="scroll-content"> |
| | | <block wx:for="{{projects}}" wx:key="id" wx:for-item="project" wx:for-index="projectIndex"> |
| | | <!-- 项目信息 --> |
| | | <view class="project-item {{project.expanded ? 'expanded' : 'collapsed'}}"> |
| | | <view class="project-header" bindtap="toggleProject" data-index="{{projectIndex}}"> |
| | | <image class="toggle-icon {{project.expanded ? 'expanded' : ''}}" src="/images/arrow-down.svg" mode="aspectFit"></image> |
| | | <view class="project-info"> |
| | | <view class="project-name">{{project.name}}</view> |
| | | <view class="project-duration">总灌溉时长: {{project.totalDuration || 0}}分钟</view> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 轮灌组列表 --> |
| | | <view class="group-list {{project.expanded ? 'expanded' : 'collapsed'}}"> |
| | | <block wx:for="{{project.groups}}" wx:key="id" wx:for-item="group"> |
| | | <view class="group-item {{group.status}}" bindtap="navigateToGroupDetail" data-project-name="{{project.name}}" data-group-name="{{group.name}}" data-group-id="{{group.id}}" data-status="{{group.status}}"> |
| | | <!-- 轮灌组状态标识 --> |
| | | <view class="group-status-indicator"> |
| | | <view class="status-dot"></view> |
| | | <text class="status-text">{{group.statusText}}</text> |
| | | </view> |
| | | |
| | | <!-- 轮灌组信息 --> |
| | | <view class="group-info"> |
| | | <view class="group-name">{{group.name}}</view> |
| | | <view class="group-time-info"> |
| | | <view class="time-row"> |
| | | <text class="time-label">开始时间:</text> |
| | | <text class="time-value">{{group.startTime}}</text> |
| | | </view> |
| | | <view class="time-row"> |
| | | <text class="time-label">结束时间:</text> |
| | | <text class="time-value">{{group.endTime}}</text> |
| | | </view> |
| | | <view class="time-row"> |
| | | <text class="time-label">灌溉时长:</text> |
| | | <text class="time-value">{{group.duration}}分钟</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </block> |
| | | </view> |
| | | </view> |
| | | </block> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
New file |
| | |
| | | .irrigation-detail-container { |
| | | display: flex; |
| | | flex-direction: column; |
| | | height: 100vh; |
| | | background-color: #F5F5F5; |
| | | } |
| | | |
| | | /* 顶部信息区域样式 */ |
| | | .header-section { |
| | | background-color: #FFFFFF; |
| | | padding: 20rpx 30rpx; |
| | | margin-bottom: 20rpx; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .plan-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .plan-code { |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | |
| | | .status-icon { |
| | | width: 68rpx; |
| | | height: 68rpx; |
| | | } |
| | | |
| | | .time-info { |
| | | display: flex; |
| | | align-items: center; |
| | | padding: 10rpx 0; |
| | | } |
| | | |
| | | .label { |
| | | color: #666666; |
| | | font-size: 28rpx; |
| | | margin-right: 10rpx; |
| | | } |
| | | |
| | | .value { |
| | | color: #333333; |
| | | font-size: 28rpx; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 项目列表样式 */ |
| | | .project-list { |
| | | flex: 1; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .scroll-content { |
| | | padding: 0 30rpx 30rpx 30rpx; |
| | | } |
| | | |
| | | .project-item { |
| | | margin-bottom: 30rpx; |
| | | border-radius: 12rpx; |
| | | overflow: hidden; |
| | | box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .project-header { |
| | | background-color: #FFFFFF; |
| | | padding: 20rpx 30rpx; |
| | | margin-bottom: 0; |
| | | display: flex; |
| | | align-items: flex-start; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | /* 所有项目标题都有圆角 */ |
| | | .project-item .project-header { |
| | | border-radius: 12rpx; |
| | | } |
| | | |
| | | /* 展开状态的项目标题只有顶部圆角 */ |
| | | .project-item.expanded .project-header { |
| | | border-radius: 12rpx 12rpx 0 0; |
| | | } |
| | | |
| | | .toggle-icon { |
| | | width: 32rpx; |
| | | height: 32rpx; |
| | | margin-right: 16rpx; |
| | | transition: transform 0.3s ease; |
| | | flex-shrink: 0; |
| | | margin-top: 6rpx; |
| | | } |
| | | |
| | | .toggle-icon.expanded { |
| | | transform: rotate(180deg); |
| | | } |
| | | |
| | | .project-info { |
| | | flex: 1; |
| | | width: calc(100% - 48rpx); |
| | | } |
| | | |
| | | .project-name { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | color: #333333; |
| | | word-break: break-all; |
| | | } |
| | | |
| | | .project-duration { |
| | | font-size: 26rpx; |
| | | color: #666666; |
| | | margin-top: 10rpx; |
| | | } |
| | | |
| | | /* 轮灌组列表样式 */ |
| | | .group-list { |
| | | background-color: #FFFFFF; |
| | | border-radius: 0 0 12rpx 12rpx; |
| | | padding: 0 20rpx; |
| | | overflow: hidden; |
| | | max-height: 0; |
| | | transition: all 0.3s ease-in-out; |
| | | width: 100%; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .group-list.expanded { |
| | | max-height: 2000rpx; /* 足够大的高度以容纳内容 */ |
| | | padding: 0 20rpx 20rpx 20rpx; |
| | | } |
| | | |
| | | .group-list.collapsed { |
| | | max-height: 0; |
| | | padding-top: 0; |
| | | padding-bottom: 0; |
| | | } |
| | | |
| | | .group-item { |
| | | border-radius: 8rpx; |
| | | margin-top: 20rpx; |
| | | padding: 20rpx; |
| | | background-color: #F9F9F9; |
| | | position: relative; |
| | | } |
| | | |
| | | /* 轮灌组状态样式 */ |
| | | .group-status-indicator { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .status-dot { |
| | | width: 16rpx; |
| | | height: 16rpx; |
| | | border-radius: 50%; |
| | | margin-right: 10rpx; |
| | | } |
| | | |
| | | .status-text { |
| | | font-size: 26rpx; |
| | | font-weight: 500; |
| | | } |
| | | |
| | | /* 已灌溉状态 */ |
| | | .irrigated .status-dot { |
| | | background-color: #52C41A; |
| | | } |
| | | |
| | | .irrigated .status-text { |
| | | color: #52C41A; |
| | | } |
| | | |
| | | /* 正在灌溉状态 */ |
| | | .irrigating .status-dot { |
| | | background-color: #D43030; |
| | | } |
| | | |
| | | .irrigating .status-text { |
| | | color: #D43030; |
| | | } |
| | | |
| | | /* 未灌溉状态 */ |
| | | .waiting .status-dot { |
| | | background-color: #FAAD14; |
| | | } |
| | | |
| | | .waiting .status-text { |
| | | color: #FAAD14; |
| | | } |
| | | |
| | | /* 轮灌组信息样式 */ |
| | | .group-info { |
| | | padding-left: 26rpx; |
| | | } |
| | | |
| | | .group-name { |
| | | font-size: 30rpx; |
| | | font-weight: bold; |
| | | color: #333333; |
| | | margin-bottom: 20rpx; |
| | | } |
| | | |
| | | .group-time-info { |
| | | background-color: #FFFFFF; |
| | | border-radius: 8rpx; |
| | | padding: 20rpx; |
| | | } |
| | | |
| | | .time-row { |
| | | display: flex; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .time-row:last-child { |
| | | margin-bottom: 0; |
| | | } |
| | | |
| | | .time-label { |
| | | color: #666666; |
| | | font-size: 26rpx; |
| | | width: 150rpx; |
| | | } |
| | | |
| | | .time-value { |
| | | color: #333333; |
| | | font-size: 26rpx; |
| | | } |
| | |
| | | countDown: 60, |
| | | projectName: '嘉峪关项目', // 默认项目名称 |
| | | selectedProject: 'JYG', // 默认项目代码 |
| | | showErrorDialog: false |
| | | showErrorDialog: false, |
| | | fromBack: false, // 标记是否是从返回按钮返回的 |
| | | manualNavigate: false // 标记是否是通过编程方式导航的 |
| | | }, |
| | | |
| | | /** |
| | |
| | | return; |
| | | } |
| | | |
| | | // 开始倒计时 |
| | | this.startCountDown(); |
| | | |
| | | |
| | | // 发送验证码请求 |
| | | this.postCode(); |
| | |
| | | title: '登录中...', |
| | | mask: true |
| | | }); |
| | | |
| | | // 标记为手动导航,确保不会触发返回逻辑 |
| | | console.log('登录按钮点击,设置manualNavigate=true'); |
| | | this.setData({ |
| | | manualNavigate: true |
| | | }); |
| | | |
| | | this.wsLogin(); |
| | | |
| | | |
| | | // 发送登录请求 |
| | | post('/api/loginByCode', { |
| | | phone: phone, |
| | | code: verificationCode, |
| | | projectCode: this.data.selectedProject |
| | | }).then(res => { |
| | | wx.hideLoading(); |
| | | |
| | | if (res.code === 0 && res.data) { |
| | | // 保存用户信息和token |
| | | storage.setUserInfo(res.data); |
| | | storage.setToken(res.data.token); |
| | | |
| | | // 跳转到首页 |
| | | wx.switchTab({ |
| | | url: '/pages/index/index' |
| | | }); |
| | | } else { |
| | | wx.showToast({ |
| | | title: res.msg || '登录失败,请重试', |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | wx.hideLoading(); |
| | | console.error('登录失败', err); |
| | | wx.showToast({ |
| | | title: '网络异常,请重试', |
| | | icon: 'none' |
| | | }); |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | |
| | | * 生命周期函数--监听页面加载 |
| | | */ |
| | | onLoad: function (options) { |
| | | // 获取选择的项目 |
| | | if (options.project) { |
| | | console.log('login页面加载,options:', options); |
| | | |
| | | // 设置页面数据 |
| | | this.setData({ |
| | | selectedProject: options.project, |
| | | projectName: options.project === 'JYG' ? '嘉峪关项目' : '民勤项目' |
| | | fromBack: false, // 标记是否是从返回按钮返回的 |
| | | manualNavigate: false // 标记是否是通过编程方式导航的 |
| | | }); |
| | | } else { |
| | | // 尝试从本地存储获取已选择的项目 |
| | | storage.getItem('selectedProject').then(project => { |
| | | if (project) { |
| | | |
| | | // 获取选择的项目 - 优先使用URL参数 |
| | | if (options && options.project) { |
| | | const project = options.project; |
| | | const projectName = project === 'JYG' ? '嘉峪关项目' : '民勤项目'; |
| | | |
| | | console.log(`从URL参数获取项目信息: ${project} (${projectName})`); |
| | | |
| | | this.setData({ |
| | | selectedProject: project, |
| | | projectName: project === 'JYG' ? '嘉峪关项目' : '民勤项目' |
| | | projectName: projectName |
| | | }); |
| | | |
| | | // 同步更新全局项目设置 |
| | | if (getApp().globalData) { |
| | | getApp().globalData.selectedProject = project; |
| | | |
| | | // 设置对应的tag |
| | | if (project === 'JYG') { |
| | | getApp().globalData.tag = 'ym'; |
| | | } else if (project === 'MQ') { |
| | | getApp().globalData.tag = 'mq'; |
| | | } |
| | | |
| | | // 更新 BASEURL |
| | | try { |
| | | const { PROJECT_URLS } = require('../../api/config.js'); |
| | | getApp().globalData.baseUrl = PROJECT_URLS[project]; |
| | | } catch (e) { |
| | | console.error('设置baseUrl失败:', e); |
| | | } |
| | | } |
| | | |
| | | // 保存项目选择到本地存储,确保项目信息一致 |
| | | storage.setItem('selectedProject', project) |
| | | .then(() => console.log('成功保存项目选择到存储')) |
| | | .catch(err => console.error('保存项目选择到存储失败:', err)); |
| | | } else { |
| | | // 从本地存储获取已选择的项目 |
| | | storage.getItemSafe('selectedProject').then(project => { |
| | | if (project) { |
| | | const projectName = project === 'JYG' ? '嘉峪关项目' : '民勤项目'; |
| | | console.log(`从存储获取项目信息: ${project} (${projectName})`); |
| | | |
| | | this.setData({ |
| | | selectedProject: project, |
| | | projectName: projectName |
| | | }); |
| | | } else { |
| | | console.log('未找到已选择的项目,使用默认项目'); |
| | | } |
| | | }).catch(err => { |
| | | console.error('获取已选择项目失败:', err); |
| | |
| | | * 生命周期函数--监听页面隐藏 |
| | | */ |
| | | onHide() { |
| | | // 如果不是通过编程方式导航,则可能是点击了返回按钮 |
| | | // 注意:在某些情况下,微信可能会直接调用onUnload而跳过onHide |
| | | if (!this.data.manualNavigate) { |
| | | console.log('页面隐藏,可能是点击了返回按钮'); |
| | | this.setData({ |
| | | fromBack: true |
| | | }); |
| | | |
| | | // 如果页面隐藏但未登录,记录一个时间戳,帮助识别是否是返回操作 |
| | | if (!getApp().globalData.isLoggedIn) { |
| | | this.hideTimestamp = Date.now(); |
| | | } |
| | | } else { |
| | | console.log('页面隐藏,是通过代码导航的'); |
| | | } |
| | | }, |
| | | |
| | | /** |
| | |
| | | clearInterval(this.countDownTimer); |
| | | this.countDownTimer = null; |
| | | } |
| | | |
| | | // 记录退出登录页面的情况 |
| | | console.log('登录页面卸载,fromBack:', this.data.fromBack, 'manualNavigate:', this.data.manualNavigate, '登录状态:', !!getApp().globalData.isLoggedIn); |
| | | |
| | | // 如果是登录成功,不执行返回逻辑 |
| | | if (getApp().globalData.isLoggedIn) { |
| | | console.log('用户已登录,无需执行返回逻辑'); |
| | | return; |
| | | } |
| | | |
| | | // 检查是否是通过编程方式明确设置了导航 |
| | | // 如果没有明确设置,就假定是返回操作 |
| | | if (!this.data.manualNavigate) { |
| | | console.log('页面卸载时未设置manualNavigate,假定是返回按钮操作'); |
| | | |
| | | // 立即写入临时标记,以便首页检测到 |
| | | try { |
| | | // 多种方式确保写入成功 |
| | | wx.setStorageSync('_temp_from_login', 'true'); |
| | | console.log('立即写入_temp_from_login标记为true'); |
| | | |
| | | // 创建一个全局对象,作为备用方案 |
| | | if (!getApp().globalData) { |
| | | getApp().globalData = {}; |
| | | } |
| | | getApp().globalData._tempFromLogin = true; |
| | | console.log('同时设置全局变量_tempFromLogin=true'); |
| | | |
| | | // 检查写入是否成功 |
| | | const check = wx.getStorageSync('_temp_from_login'); |
| | | console.log('检查临时标记是否写入成功:', check); |
| | | } catch (e) { |
| | | console.error('写入标记失败:', e); |
| | | // 备用方式写入 |
| | | wx.setStorage({ |
| | | key: '_temp_from_login', |
| | | data: 'true' |
| | | }); |
| | | } |
| | | |
| | | // 尝试使用wx.navigateBack返回上一页(如果可行) |
| | | const pages = getCurrentPages(); |
| | | if (pages.length > 1) { |
| | | console.log('检测到有上一页,使用navigateBack返回'); |
| | | wx.navigateBack({ |
| | | delta: 1, |
| | | success: () => console.log('navigateBack成功'), |
| | | fail: (err) => { |
| | | console.error('navigateBack失败:', err); |
| | | // 如果navigateBack失败,尝试reLaunch |
| | | this.backupReturnToHome(); |
| | | } |
| | | }); |
| | | } else { |
| | | console.log('无上一页,使用备用返回方式'); |
| | | // 没有上一页,使用备用方法 |
| | | this.backupReturnToHome(); |
| | | } |
| | | } else { |
| | | console.log('通过编程方式离开登录页面'); |
| | | } |
| | | }, |
| | | |
| | | // 备用的返回首页方法 |
| | | backupReturnToHome() { |
| | | console.log('使用备用方法返回首页'); |
| | | |
| | | // 尝试使用switchTab(如果首页在tabBar中) |
| | | const useReLaunch = () => { |
| | | console.log('使用reLaunch返回首页'); |
| | | wx.reLaunch({ |
| | | url: '/pages/home/home?fromLogin=true', |
| | | success: () => console.log('reLaunch成功返回首页'), |
| | | fail: (err) => { |
| | | console.error('reLaunch返回首页失败:', err); |
| | | // 最后的备用方案:使用redirectTo |
| | | setTimeout(() => { |
| | | console.log('延迟使用redirectTo尝试返回首页'); |
| | | wx.redirectTo({ |
| | | url: '/pages/home/home?fromLogin=true', |
| | | success: () => console.log('redirectTo成功返回首页'), |
| | | fail: (err) => console.error('所有返回方法都失败:', err) |
| | | }); |
| | | }, 100); |
| | | } |
| | | }); |
| | | }; |
| | | |
| | | // 先尝试使用switchTab(某些版本可能将首页设置为tabBar) |
| | | wx.switchTab({ |
| | | url: '/pages/home/home', |
| | | success: () => console.log('switchTab成功返回首页'), |
| | | fail: (err) => { |
| | | console.log('switchTab失败(可能首页不在tabBar中):', err); |
| | | useReLaunch(); |
| | | } |
| | | }); |
| | | }, |
| | | |
| | | /** |
| | |
| | | this.setData({ |
| | | codeSent: true, |
| | | }); |
| | | // 启动倒计时 |
| | | this.startCountdown(); |
| | | // 开始倒计时 |
| | | this.startCountDown(); |
| | | }) |
| | | .catch((error) => { |
| | | wx.showToast({ |
| | |
| | | }); |
| | | }, |
| | | wsLogin() { |
| | | // 标记为手动导航 |
| | | console.log('wsLogin调用,设置manualNavigate=true'); |
| | | this.setData({ |
| | | manualNavigate: true |
| | | }); |
| | | |
| | | wx.login({ |
| | | success: res => { |
| | | if (res.code) { |
| | | console.log('登录成功,获取到的code:', res.code); |
| | | console.log('微信登录成功,获取到的code:', res.code); |
| | | // 发送 res.code 到后台服务器换取 openId, sessionKey, unionId |
| | | this.verify(res.code) |
| | | } else { |
| | | console.log('登录失败!' + res.errMsg); |
| | | console.log('微信登录失败!' + res.errMsg); |
| | | // 登录失败时重置状态 |
| | | this.setData({ |
| | | manualNavigate: false |
| | | }); |
| | | } |
| | | }, |
| | | fail: err => { |
| | | console.error('微信登录API调用失败:', err); |
| | | // 登录失败,重置导航标记 |
| | | this.setData({ |
| | | manualNavigate: false |
| | | }); |
| | | } |
| | | }); |
| | | }, |
| | | //用户绑定 |
| | | verify(wxCode) { |
| | | console.log('verify调用,确认manualNavigate=', this.data.manualNavigate); |
| | | |
| | | const params = { |
| | | url: 'wx/client/verify', |
| | | data: { |
| | |
| | | code: wxCode |
| | | } |
| | | }; |
| | | |
| | | post(params) |
| | | .then((data) => { |
| | | wx.hideLoading(); |
| | | getApp().globalData.sessionId = String(data.content.sessionId) |
| | | storage.setItem("sessionId", String(data.content.sessionId)) |
| | | getApp().globalData.clientId = String(data.content.clientId) |
| | | storage.setItem("clientId", String(data.content.clientId)) |
| | | |
| | | console.log('验证成功,准备保存用户数据'); |
| | | |
| | | // 确保全局对象已初始化 |
| | | if (!getApp().globalData) { |
| | | getApp().globalData = {}; |
| | | } |
| | | |
| | | // 保存会话ID和客户端ID |
| | | getApp().globalData.sessionId = String(data.content.sessionId); |
| | | storage.setItem("sessionId", String(data.content.sessionId)); |
| | | getApp().globalData.clientId = String(data.content.clientId); |
| | | storage.setItem("clientId", String(data.content.clientId)); |
| | | |
| | | // 设置当前项目的tag |
| | | const tag = this.data.selectedProject === 'JYG' ? 'ym' : 'mq'; |
| | | getApp().globalData.tag = tag; |
| | | |
| | | // 保存用户信息 |
| | | const userInfo = { |
| | | sessionId: String(data.content.sessionId), |
| | | clientId: String(data.content.clientId), |
| | | phone: this.data.phone, |
| | | token: data.content.token || '', |
| | | project: this.data.selectedProject, |
| | | tag: tag |
| | | }; |
| | | |
| | | // 保存到全局变量 |
| | | getApp().globalData.userInfo = userInfo; |
| | | getApp().globalData.isLoggedIn = true; |
| | | |
| | | // 保存到本地存储 |
| | | storage.setItem("userInfo", JSON.stringify(userInfo)) |
| | | .then(() => { |
| | | console.log('用户信息保存成功'); |
| | | return storage.setItem("isLoggedIn", "true"); |
| | | }) |
| | | .then(() => { |
| | | // 保存userData信息,包含sessionId和tag |
| | | const userData = JSON.stringify({ |
| | | sessionId: String(data.content.sessionId), |
| | | tag: tag |
| | | }); |
| | | return storage.setItem("userData", userData); |
| | | }) |
| | | .then(() => { |
| | | console.log('登录状态和项目信息保存成功'); |
| | | this.bindSuccess(); |
| | | }) |
| | | .catch(err => { |
| | | console.warn('保存用户信息过程中出错,但不影响继续操作:', err); |
| | | this.bindSuccess(); |
| | | }); |
| | | }) |
| | | .catch((error) => { |
| | | wx.hideLoading(); |
| | | console.error('验证请求失败:', error); |
| | | |
| | | // 验证失败,需要重置导航标记 |
| | | console.log('验证失败,重置manualNavigate=false'); |
| | | this.setData({ |
| | | manualNavigate: false |
| | | }); |
| | | |
| | | wx.showToast({ |
| | | title: error.msg, |
| | | title: error.msg || '验证失败', |
| | | icon: 'error', |
| | | duration: 3000, |
| | | }); |
| | | console.error('Failed to add item:', error); |
| | | }); |
| | | }, |
| | | bindSuccess: function () { |
| | | if (!this.data.isButtonEnabled) return; |
| | | // 设置标记,表示通过编程方式导航 |
| | | console.log('绑定成功,最终确认manualNavigate=true'); |
| | | this.setData({ |
| | | manualNavigate: true, |
| | | fromBack: false // 确保不会被识别为返回操作 |
| | | }); |
| | | |
| | | // 设置全局登录状态 |
| | | getApp().globalData.isLoggedIn = true; |
| | | |
| | | // 确保清除临时标记 |
| | | try { |
| | | wx.removeStorageSync('_temp_from_login'); |
| | | } catch(e) { |
| | | console.warn('清除临时标记失败', e); |
| | | } |
| | | |
| | | wx.showToast({ |
| | | title: '绑定成功', |
| | | icon: 'success' |
| | | icon: 'success', |
| | | duration: 1500, |
| | | mask: true, |
| | | success: () => { |
| | | // 延迟跳转,确保Toast显示完成 |
| | | setTimeout(() => { |
| | | console.log('登录成功,准备跳转到首页'); |
| | | // 跳转到首页,使用reLaunch而不是redirectTo |
| | | wx.reLaunch({ |
| | | url: '/pages/home/home' |
| | | }); |
| | | // 跳转到 TabBar 页面 |
| | | wx.redirectTo({ |
| | | url: '/pages/home/home' // 这里填写你想要跳转的 TabBar 页面路径 |
| | | }, 1500); |
| | | } |
| | | }); |
| | | }, |
| | | }) |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <view class="project-info"> |
| | | <view class="project-info {{selectedProject === 'MQ' ? 'mq' : 'jyg'}}"> |
| | | <text>当前项目: {{projectName}}</text> |
| | | </view> |
| | | |
| | |
| | | bottom: 40rpx; |
| | | width: 100%; |
| | | text-align: center; |
| | | font-size: 28rpx; |
| | | color: #999; |
| | | font-size: 32rpx; |
| | | padding: 16rpx 0; |
| | | background-color: rgba(255, 255, 255, 0.8); |
| | | backdrop-filter: blur(5px); |
| | | box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1); |
| | | } |
| | | |
| | | .project-info text { |
| | | display: inline-block; |
| | | padding: 8rpx 24rpx; |
| | | color: #fff; |
| | | border-radius: 30rpx; |
| | | font-weight: 500; |
| | | box-shadow: 0 4rpx 8rpx rgba(0, 0, 0, 0.2); |
| | | background: linear-gradient(45deg, #1890FF, #36a9fc); |
| | | } |
| | | |
| | | .project-info.mq text { |
| | | background: linear-gradient(45deg, #18c063, #36d486); |
| | | } |
| | | |
| | | image { |
| | |
| | | const data = { |
| | | intakeId: intakeId, //取水口ID |
| | | // vcId: vcId, //虚拟卡ID |
| | | operator: app.globalData.operator, //操作员 |
| | | operator: app.globalData.clientId, //操作员 |
| | | forceOpen: !!isforce // 使用逻辑非操作符 !! 来确保 isForce 是布尔值 |
| | | }; |
| | | post({ |
| | |
| | | get({ |
| | | url: 'wx/intake/used_intakes', |
| | | data: { |
| | | operatorId: getApp().globalData.operator |
| | | operatorId: getApp().globalData.clientId |
| | | } |
| | | }) |
| | | .then((data) => { |
| | |
| | | const setItem = (key, data) => { |
| | | return new Promise((resolve, reject) => { |
| | | if (!key) { |
| | | reject(new Error('存储键不能为空')); |
| | | return; |
| | | } |
| | | |
| | | wx.setStorage({ |
| | | key: key, |
| | | data: data, |
| | | success: resolve, |
| | | fail: reject |
| | | fail: (err) => { |
| | | console.error(`设置存储项 ${key} 失败:`, err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const getItem = (key) => { |
| | | return new Promise((resolve, reject) => { |
| | | if (!key) { |
| | | reject(new Error('存储键不能为空')); |
| | | return; |
| | | } |
| | | |
| | | wx.getStorage({ |
| | | key: key, |
| | | success: (res) => resolve(res.data), |
| | | fail: reject |
| | | fail: (err) => { |
| | | console.error(`获取存储项 ${key} 失败:`, err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | // 安全获取存储项,失败时返回默认值而不是拒绝Promise |
| | | const getItemSafe = (key, defaultValue = null) => { |
| | | return new Promise((resolve) => { |
| | | if (!key) { |
| | | resolve(defaultValue); |
| | | return; |
| | | } |
| | | |
| | | wx.getStorage({ |
| | | key: key, |
| | | success: (res) => resolve(res.data), |
| | | fail: (err) => { |
| | | // 在开发环境下记录警告,但不作为错误处理 |
| | | // 数据不存在是正常情况,不需要作为警告输出 |
| | | if (err.errMsg !== "getStorage:fail data not found") { |
| | | console.warn(`安全获取存储项 ${key} 失败:`, err); |
| | | } else { |
| | | console.log(`存储项 ${key} 不存在,返回默认值`); |
| | | } |
| | | resolve(defaultValue); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | const removeItem = (key) => { |
| | | return new Promise((resolve, reject) => { |
| | | if (!key) { |
| | | reject(new Error('存储键不能为空')); |
| | | return; |
| | | } |
| | | |
| | | wx.removeStorage({ |
| | | key: key, |
| | | success: resolve, |
| | | fail: reject |
| | | fail: (err) => { |
| | | console.error(`删除存储项 ${key} 失败:`, err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | |
| | | return new Promise((resolve, reject) => { |
| | | wx.clearStorage({ |
| | | success: resolve, |
| | | fail: reject |
| | | fail: (err) => { |
| | | console.error('清除存储失败:', err); |
| | | reject(err); |
| | | } |
| | | }); |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 判断本地是否保存了某个key |
| | | * @param {} key |
| | | * @param {String} key 存储键 |
| | | * @returns {Boolean} 是否存在该键 |
| | | */ |
| | | const isHasKeySync= (key) => { |
| | | if (!key) return false; |
| | | |
| | | try { |
| | | const res = wx.getStorageInfoSync(); |
| | | return res.keys.includes(key); |
| | | } catch (e) { |
| | | console.error('Failed to get storage info:', e); |
| | | console.error('获取存储信息失败:', e); |
| | | return false; |
| | | } |
| | | }; |
| | |
| | | module.exports = { |
| | | setItem, |
| | | getItem, |
| | | getItemSafe, |
| | | removeItem, |
| | | clear, |
| | | isHasKeySync |