提交 8f0c58fd 作者: 宇宙超人

设备列表页面

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