device.vue 9.61 KB
<template>
	<view class="device-page">
		<f-navbar>
			<view slot="left">
				<view style="width: 580rpx"><u--input prefixIcon="search" placeholder="输入设备SN或名称搜索" border="surround" shape="circle" @change="inputChanged"></u--input></view>
			</view>
			<view @click="openSearchDialog" slot="right" class="u-flex">
				<text style="color: #333; font-size: 14px">筛选</text>
				<image style="width: 40rpx; height: 40rpx" src="../../static/shaixuan.png" />
			</view>
		</f-navbar>
		<!-- 公共组件-每个页面必须引入 -->
		<public-module></public-module>
		<view class="org-sty" @click="openOrg">
			<view class="org-item">
				<view class="u-flex" style="margin-top: 26rpx; margin-left: 15rpx"><text style="color: #333; font-size: 15px; margin-left: 14rpx">组织关系</text></view>
				<view style="margin-top: 20rpx; margin-left: 15rpx" class="u-flex" v-if="total">
					<image style="margin-left: 14rpx; width: 30rpx; height: 30rpx" src="../../static/org.png" />
					<text style="margin-left: 10rpx; color: #666; font-size: 12px">设备数 : {{ total }}</text>
				</view>
			</view>
			<view class="org-item">
				<image
					style="
            width: 6px;
            height: 10px;
            float: right;
            margin-right: 34rpx;
            margin-top: 58rpx;
          "
					src="../../static/right-arrow.png"
				/>
			</view>
		</view>
		<mescroll-body ref="mescrollRef" @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback">
			<view class="device-list">
				<view @click="openDeviceDetail(item.id, item.alarmStatus, item.lastOnlineTime, item.tbDeviceId)" class="list-item" v-for="item in list" :key="item.id">
					<view
						class="u-flex item"
						style="
              justify-content: flex-start;
              flex-direction: column;
              align-items: center;
            "
					>
						<view style="width: 450rpx; text-align: left">
							<text style="color: #333; font-size: 15px">{{ item.name }}</text>
						</view>
						<view style="width: 450rpx; text-align: left; margin-top: 10rpx">
							<view style="color: #666; font-size: 15px;display: flex;">
								设备编号:
								<view style="margin-left:16rpx">{{ item.sn }}</view>
							</view>
						</view>
						<view style="width: 450rpx; text-align: left; margin-top: 10rpx">
							<view style="color: #666; font-size: 15px;display: flex;">
								所属组织:
								<view style="margin-left:16rpx">{{ item.organizationDTO.name }}</view>
							</view>
						</view>
					</view>
					<view class="item">
						<view class="u-flex" style="margin-top: -6rpx">
							<image
								style="
                  width: 30rpx;
                  height: 30rpx;
                  margin-top: 5rpx;
                  margin-right: 5rpx;
                "
								:src="item.deviceState === 'ONLINE' ? '../../static/online.png' : item.deviceState === 'INACTIVE' ? '../../static/unonline.png' : '../../static/baojing.png'"
							/>

							<view>
								<text
									style="
                    color: #377dff;
                    font-size: 13px;
                    margin-left: 5rpx;
                    margin-top: 20rpx;
                  "
									:style="{ color: item.deviceState === 'ONLINE' ? '#377DFF' : item.deviceState === 'INACTIVE' ? '#666666' : '#DE4437' }"
								>
									{{ item.deviceState === 'ONLINE' ? '在线' : item.deviceState === 'INACTIVE' ? '待激活' : '离线' }}
								</text>
							</view>
						</view>
					</view>
				</view>
			</view>
		</mescroll-body>
		<!-- 设备筛选 -->
		<u-popup @close="close" closeable bgColor="#fff" :show="show" mode="bottom" :round="20">
			<view>
				<view style="text-align: center; margin-top: 28rpx"><text>筛选条件</text></view>

				<FilterItem :filterList="deviceStatus" title="设备状态" @clickTag="currentIndex => handleClickTag(currentIndex, deviceStatus)"></FilterItem>
				<FilterItem :filterList="alarmStatus" title="告警状态" @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem>
				<FilterItem :filterList="typeStatus" title="设备类型" @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem>
				<view class="u-flex" style="margin-top: 40rpx; margin-left: 55rpx">
					<view style="width: 300rpx"><u-button type="info" shape="circle" text="重置" @click="resetFilter"></u-button></view>
					<view style="width: 300rpx; margin-left: 46rpx"><u-button type="primary" shape="circle" text="确认" @click="confirmFilter"></u-button></view>
				</view>
			</view>
		</u-popup>
		<f-tabbar></f-tabbar>
	</view>
</template>

<script>
import fTabbar from '@/components/module/f-tabbar/f-tabbar';
import fNavbar from '@/components/module/f-navbar/f-navbar';
import FilterItem from './FilterItem.vue';
import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
import { debounce } from '@/plugins/throttle.js';
export default {
	mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
	components: {
		fTabbar,
		fNavbar,
		FilterItem
	},
	data() {
		return {
			downOption: {
				auto: false //是否在初始化后,自动执行downCallback; 默认true
			},
			show: false,
			deviceStatus: [
				{
					checked: true,
					name: '全部',
					type: ''
				},
				{
					checked: false,
					name: '在线',
					type: 'ONLINE'
				},
				{
					checked: false,
					name: '离线',
					type: 'OFFLINE'
				},
				{
					checked: false,
					name: '待激活',
					type: 'INACTIVE'
				}
			],
			alarmStatus: [
				{
					checked: true,
					name: '全部',
					type: ''
				},
				{
					checked: false,
					name: '告警',
					type: '1'
				},
				{
					checked: false,
					name: '正常',
					type: '0'
				}
			],
			typeStatus: [
				{
					checked: true,
					name: '全部',
					type: ''
				},
				{
					checked: false,
					name: '直连设备',
					type: 'DIRECT_CONNECTION'
				},
				{
					checked: false,
					name: '网关设备',
					type: 'GATEWAY'
				},
				{
					checked: false,
					name: '网关子设备',
					type: 'SENSOR'
				}
			],
			total: 0,
			list: [],
			page: {
				num: 0,
				size: 10
			}
		};
	},
	onLoad() {
		// 隐藏原生的tabbar
		uni.hideTabBar();
	},
	onShow() {
		if (this.orgId) {
			this.loadData(1, {
				organizationId: this.orgId
			});
		}
	},
	methods: {
		/*下拉刷新的回调 */
		downCallback() {
			//联网加载数据
			this.list = [];
			this.page.num = 1;
			//联网加载数据
			this.loadData(this.page.num);
		},

		/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
		upCallback() {
			//联网加载数据
			this.page.num += 1;
			this.loadData(this.page.num);
		},

		//获取设备
		loadData(pageNo, params = {}) {
			let httpData = {
				page: pageNo,
				pageSize: 10,
				...params
			};
			uni.$u.http
				.get('/yt/device', {
					params: httpData,
					custom: {
						load: false
					}
				})
				.then(res => {
					this.total = res.total;
					uni.stopPullDownRefresh();
					console.log('获取后端数据', res);
					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
					this.mescroll.endByPage(res.items.length, res.total); //必传参数(当前页的数据个数, 总页数)
					if (pageNo == 1) {
						this.list = res.items;
					} else {
						this.list = this.list.concat(res.items);
					}
				})
				.catch(() => {
					//联网失败, 结束加载
					this.mescroll.endErr();
				});
		},
		openOrg() {
			uni.navigateTo({
				url: './org/org'
			});
		},
		close() {
			this.resetFilter();
			this.show = false;
		},
		openSearchDialog() {
			this.show = true;
		},
		openDeviceDetail(id, alarmStatus, lastOnlineTime, tbDeviceId) {
			uni.navigateTo({
				url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}`
			});
		},
		handleClickTag(currentIndex, list) {
			list.map((item, index) => {
				item.checked = index === currentIndex;
			});
		},
		resetFilter() {
			const { deviceStatus, alarmStatus, typeStatus } = this;
			[deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index === 0)));
		},
		confirmFilter() {
			const deviceState = this.deviceStatus.find(item => item.checked);
			const alarmStatus = this.alarmStatus.find(item => item.checked);
			const deviceType = this.typeStatus.find(item => item.checked);
			this.loadData(1, {
				deviceState: deviceState.type ? deviceState.type : undefined,
				deviceType: deviceType.type ? deviceType.type : undefined,
				alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : undefined
			});
			this.show = false;
		},
		inputChanged: debounce(function(name) {
			this.loadData(1, {
				name
			});
		}, 500)
	}
};
</script>

<style lang="scss" scoped>
.device-page {
	min-height: 100vh;
	background-color: #f8f9fa;
}

.org-sty {
	width: 750rpx;
	height: 150rpx;
	margin-top: 1rpx;
	background-color: #fff;
	display: flex;
	justify-content: space-between;

	.org-item {
		width: 350rpx;
		height: 200rpx;
	}
}

.device-list {
	display: flex;
	flex-direction: column;
	padding-left: 20rpx;

	.list-item {
		width: 713rpx;
		height: 200rpx;
		background-color: #fff;
		margin-top: 24rpx;
		display: flex;
		border-radius: 10px;
		justify-content: space-between;

		.item {
			margin: 30rpx;
		}
	}
}
</style>