提交 8f0c58fd 作者: 宇宙超人

设备列表页面

上级 8d25a329
import { otherHttp } from '/@/utils/http/axios'
import { postFormData } from '/@/utils/http/formDataRequest'
enum Api {
zoneList = '/online/cgform/api/getData/01fd687ecb164aea914e92047e144d66', // 功能菜单数据
......@@ -9,6 +10,9 @@ enum Api {
commonToolsList = '/online/cgform/api/getData/3a7fbb877f304b7d83935caa454859c4', // 常用工具数据
getFarmBaseList = '/farmbase/getFarmBaseList',
}
export function queryByType(data = {}) {
return postFormData('/device/queryByType', data).then((res) => res.data)
}
/**
* 删除设备
* @param id
......
......@@ -12,17 +12,20 @@ const pageData = reactive({
param: {
deviceName: '',
deviceType: '', // 添加设备类型筛选
farmBaseId: '', //基地id
},
list: [],
selectedCategory: 'all',
selectedDevice: {},
})
// 摄像头设备的分类标签
const cameraCategories = computed(() => {
const dictList = dictStore.getDictList.deviceType?.map((item) => ({
id: item.value,
name: item.text,
})) || []
const dictList =
dictStore.getDictList.deviceType?.map((item) => ({
id: item.value,
name: item.text,
})) || []
return [{ id: 'all', name: '全部' }, ...dictList]
})
......@@ -30,25 +33,33 @@ onLoad((options) => {
// 获取设备类型参数
if (options.deviceType) {
deviceType.value = options.deviceType
pageData.selectedCategory = options.deviceType
pageData.param.deviceType = options.deviceType
pageData.param.farmBaseId = options.farmBaseId
}
getList()
})
// 判断是否为摄像头设备
const isCameraDevice = computed(() => {
return deviceType.value === '1'
return deviceType.value == '1'
})
// 获取设备列表
function getList() {
// TODO: API请求留空,后续实现
// NongchangAPI.getDeviceList(pageData.param)
// .then((res) => {
// pageData.list = res.records || []
// })
// .catch(() => {
// pageData.list = []
// })
const formData = {
deviceName: pageData.param.deviceName,
deviceType: pageData.param.deviceType,
farmBaseId: pageData.param.farmBaseId,
}
NongchangAPI.queryByType(formData)
.then((res) => {
pageData.list = res.result || []
if (res.result.length > 0) handleDeviceClick(res.result[0])
})
.catch(() => {
pageData.list = []
})
}
function handleSearch() {
......@@ -87,131 +98,129 @@ function getStatusClass(status) {
// 分类标签点击
function handleCategoryClick(category) {
pageData.selectedCategory = category.id
// TODO: 根据分类筛选设备
if (category.id === 'all') {
pageData.param.deviceType = ''
} else {
pageData.param.deviceType = category.id
}
getList()
}
// 设备卡片点击
function handleDeviceClick(device) {
pageData.selectedDevice = device
deviceType.value = device.deviceType
}
</script>
<template>
<view class="codefun-flex-col page">
<!-- 摄像头设备布局 -->
<view v-if="isCameraDevice" class="camera-layout">
<!-- 搜索框 -->
<view class="codefun-flex-col group_3">
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input
v-model="pageData.param.deviceName"
placeholder="请输入设备名称搜索"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
<!-- 顶部占位区域 - 根据设备类型显示 -->
<!-- 摄像头设备 - 视频占位区域 -->
<view v-if="isCameraDevice" class="video-placeholder-top">
<view class="video-overlay">
<view class="video-info">
<text class="video-location">{{ pageData.selectedDevice.deviceName }}</text>
<!-- <text class="video-time">2022年11月01日 星期二 14:53:24</text> -->
</view>
<image class="fullscreen-icon" src="/static/images/device/fullscreen.png" mode="aspectFit" />
</view>
</view>
<!-- 分类标签 -->
<view class="category-tabs">
<view
v-for="category in cameraCategories"
:key="category.id"
class="category-tab"
:class="{ active: pageData.selectedCategory === category.id }"
@click="handleCategoryClick(category)"
>
{{ category.name }}
</view>
<!-- 其他设备 - 设备信息卡片 -->
<view v-else class="device-info-card">
<view class="device-header">
<view class="device-icon">
<image class="icon-img" src="/static/images/device/location-icon.png" mode="aspectFit" />
</view>
<!-- 摄像头设备列表 -->
<view class="camera-grid">
<view v-for="(item, index) in pageData.list" :key="index" class="camera-card" @click="() => {}">
<!-- 视频占位区域 -->
<view class="video-placeholder">
<view class="video-title">{{ item.deviceName }}</view>
<image class="play-icon" src="/static/images/device/play-icon.png" mode="aspectFit" />
</view>
<!-- 设备信息 -->
<view class="camera-info">
<view class="info-row">
<text class="info-label">设备类型:</text>
<text class="info-value">{{ item.deviceType_dictText || '未知' }}</text>
</view>
<view class="info-row">
<text class="info-label">设备编号:</text>
<text class="info-value">{{ item.deviceIdentifier }}</text>
</view>
</view>
<view class="device-title-group">
<view class="device-title">{{ pageData.selectedDevice.deviceName }}</view>
<view class="device-badges">
<text class="badge badge-green" v-if="pageData.selectedDevice.isOnline == 1">在线</text>
<text class="badge badge-gray" v-else>离线</text>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="pageData.list.length === 0">
<text>暂无设备数据</text>
</view>
<view class="device-stats">
<view class="stat-item">
<text class="stat-label">设备ID:</text>
<text class="stat-value">{{ pageData.selectedDevice.deviceIdentifier }}</text>
</view>
<!-- <view class="stat-item">
<text class="stat-label">位置坐标:</text>
<text class="stat-value">30.2680, 120.0450</text>
</view> -->
</view>
<view class="device-stats">
<view class="stat-item">
<text class="stat-label">设备来源:</text>
<text class="stat-value">灌溉设备</text>
</view>
<view class="stat-item">
<text class="stat-label">归属地:</text>
<text class="stat-value">西区灌溉基地</text>
</view>
</view>
</view>
<!-- 其他设备布局 -->
<view v-else>
<view class="codefun-flex-col group_3">
<!-- 搜索框 -->
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input
v-model="pageData.param.deviceName"
placeholder="请输入设备名称搜索"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view>
<!-- 通用设备列表区域 -->
<view class="codefun-flex-col group_3">
<!-- 搜索框 -->
<view class="codefun-flex-row codefun-items-center section_2">
<image class="image_6" src="/static/images/codefun/6c5c5a3c082b8c60a307d3a7caee623c.png" />
<u-input
v-model="pageData.param.deviceName"
:placeholder="isCameraDevice ? '请输入关键词搜索' : '请输入设备名称搜索'"
border="none"
class="codefun-ml-8"
@confirm="handleSearch"
/>
</view>
<!-- 分类标签 -->
<view class="category-tabs">
<view
v-for="category in cameraCategories"
:key="category.id"
class="category-tab"
:class="{ active: pageData.selectedCategory === category.id }"
@click="handleCategoryClick(category)"
>
{{ category.name }}
</view>
<!-- 分类标签 -->
<view class="category-tabs">
<view
v-for="category in cameraCategories"
:key="category.id"
class="category-tab"
:class="{ active: pageData.selectedCategory === category.id }"
@click="handleCategoryClick(category)"
>
{{ category.name }}
</view>
</view>
<!-- 设备卡片网格 -->
<view class="device-grid">
<view
v-for="(item, index) in pageData.list"
:key="index"
class="device-card"
:class="{ selected: item.selected }"
@click="() => {}"
>
<view class="device-card-header">
<view class="device-name">{{ item.deviceName }}</view>
<view class="device-status" :class="getStatusClass(item.connectStatus_dictText)">
{{ item.connectStatus_dictText || '未知' }}
</view>
<!-- 设备卡片网格 -->
<view class="device-grid">
<view
v-for="(item, index) in pageData.list"
:key="index"
class="device-card"
:class="{ selected: pageData.selectedDevice.id == item.id }"
@click="handleDeviceClick(item)"
>
<view class="">
<view class="device-name">{{ item.deviceName }}</view>
<!-- <view class="device-status" :class="getStatusClass(item.connectStatus_dictText)">
{{ item.connectStatus_dictText || '未知' }}
</view> -->
</view>
<!-- <view class="device-card-body">
<view class="device-detail">
<text class="detail-label">设备类型:</text>
<text class="detail-value">{{ item.deviceType_dictText || '未知' }}</text>
</view>
<view class="device-card-body">
<view class="device-detail">
<text class="detail-label">设备类型:</text>
<text class="detail-value">{{ item.deviceType_dictText || '未知' }}</text>
</view>
<view class="device-detail">
<text class="detail-label">设备编号:</text>
<text class="detail-value">{{ item.deviceIdentifier }}</text>
</view>
<view class="device-detail">
<text class="detail-label">设备编号:</text>
<text class="detail-value">{{ item.deviceIdentifier }}</text>
</view>
</view>
</view> -->
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="pageData.list.length === 0">
<text>暂无设备数据</text>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="pageData.list.length === 0">
<text>暂无设备数据</text>
</view>
</view>
......@@ -741,12 +750,10 @@ body {
}
.device-name {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 8rpx;
border-left: 6rpx solid #5db66f;
padding-left: 6rpx;
font-size: 28rpx;
font-weight: 400;
letter-spacing: 0px;
text-align: center;
}
.device-details {
......@@ -836,74 +843,145 @@ body {
}
/* 摄像头设备样式 */
.camera-layout {
/* 顶部视频占位区域 */
.video-placeholder-top {
position: relative;
width: 100%;
height: 100%;
height: 400rpx;
background-image: url('/static/images/device/video-bg.jpg');
background-size: cover;
background-position: center;
flex-shrink: 0;
}
.camera-grid {
.video-overlay {
position: absolute;
bottom: 0;
left: 0;
right: 0;
padding: 20rpx 24rpx;
background: linear-gradient(to top, rgba(0, 0, 0, 0.6), transparent);
display: flex;
justify-content: space-between;
align-items: flex-end;
}
.video-info {
display: flex;
flex-direction: column;
gap: 24rpx;
margin-top: 20rpx;
gap: 8rpx;
}
.video-location {
color: #ffffff;
font-size: 32rpx;
font-weight: bold;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
}
.video-time {
color: #ffffff;
font-size: 24rpx;
opacity: 0.9;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
}
.camera-card {
.fullscreen-icon {
width: 48rpx;
height: 48rpx;
opacity: 0.9;
}
/* 设备信息卡片样式 */
.device-info-card {
margin: 24rpx;
padding: 32rpx 24rpx;
background-color: #ffffff;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.1);
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.08);
}
.video-placeholder {
position: relative;
width: 100%;
height: 400rpx;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
.device-header {
display: flex;
align-items: flex-start;
gap: 20rpx;
margin-bottom: 24rpx;
}
.device-icon {
width: 80rpx;
height: 80rpx;
background-color: #e8f5e9;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.video-title {
position: absolute;
top: 20rpx;
left: 20rpx;
color: #ffffff;
font-size: 32rpx;
font-weight: bold;
text-shadow: 0 2rpx 4rpx rgba(0, 0, 0, 0.3);
}
.icon-img {
width: 48rpx;
height: 48rpx;
}
.play-icon {
width: 100rpx;
height: 100rpx;
opacity: 0.8;
}
.device-title-group {
flex: 1;
}
.camera-info {
padding: 24rpx;
.device-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 12rpx;
}
.device-badges {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.info-row {
display: flex;
font-size: 26rpx;
.badge {
padding: 6rpx 16rpx;
border-radius: 20rpx;
font-size: 24rpx;
}
.info-label {
color: #999999;
min-width: 140rpx;
}
.badge-green {
background-color: #5db66f;
color: #ffffff;
}
.info-value {
color: #333333;
flex: 1;
}
.badge-gray {
background-color: #e0e0e0;
color: #666666;
}
.device-stats {
display: flex;
justify-content: space-between;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
}
/* 其他设备网格样式 */
.stat-item {
flex: 1;
display: flex;
align-items: center;
}
.stat-label {
font-size: 26rpx;
color: #999999;
}
.stat-value {
font-size: 26rpx;
color: #333333;
}
.device-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
......@@ -923,6 +1001,8 @@ body {
&.selected {
border-color: #5db66f;
box-shadow: 0 4rpx 12rpx rgba(93, 182, 111, 0.3);
background: #5DB66F;
color: #FFFFFF !important;
}
}
......
......@@ -345,7 +345,7 @@ onNavigationBarButtonTap((e) => {
}
})
const toDevice = (device)=>{
Navigate.to(`/pages/device/device?deviceType=${device.deviceType}`)
Navigate.to(`/pages/device/device?deviceType=${device.deviceType}&farmBaseId=`+model.farmbaseInfo?.id)
}
</script>
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论