Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
8f0c58fd
提交
8f0c58fd
authored
12月 07, 2025
作者:
宇宙超人
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
设备列表页面
上级
8d25a329
显示空白字符变更
内嵌
并排
正在显示
3 个修改的文件
包含
197 行增加
和
113 行删除
+197
-113
nongchang.ts
src/api/model/nongchang.ts
+4
-0
device.vue
src/pages/device/device.vue
+192
-112
index.vue
src/pages/nongchang/detail/index.vue
+1
-1
没有找到文件。
src/api/model/nongchang.ts
浏览文件 @
8f0c58fd
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
...
...
src/pages/device/device.vue
浏览文件 @
8f0c58fd
...
@@ -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.selecte
d }"
:class=
"
{ selected: pageData.selectedDevice.id == item.i
d }"
@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
:
32
rpx
;
font-size
:
28
rpx
;
font-weight
:
bold
;
font-weight
:
400
;
color
:
#333333
;
letter-spacing
:
0px
;
margin-bottom
:
8
rpx
;
text-align
:
center
;
border-left
:
6
rpx
solid
#5db66f
;
padding-left
:
6
rpx
;
}
}
.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
:
400
rpx
;
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
:
20
rpx
24
rpx
;
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
:
24
rpx
;
gap
:
8
rpx
;
margin-top
:
20
rpx
;
}
}
.camera-card
{
.video-location
{
color
:
#ffffff
;
font-size
:
32
rpx
;
font-weight
:
bold
;
text-shadow
:
0
2
rpx
4
rpx
rgba
(
0
,
0
,
0
,
0.3
);
}
.video-time
{
color
:
#ffffff
;
font-size
:
24
rpx
;
opacity
:
0.9
;
text-shadow
:
0
2
rpx
4
rpx
rgba
(
0
,
0
,
0
,
0.3
);
}
.fullscreen-icon
{
width
:
48
rpx
;
height
:
48
rpx
;
opacity
:
0.9
;
}
/* 设备信息卡片样式 */
.device-info-card
{
margin
:
24
rpx
;
padding
:
32
rpx
24
rpx
;
background-color
:
#ffffff
;
background-color
:
#ffffff
;
border-radius
:
16
rpx
;
border-radius
:
16
rpx
;
overflow
:
hidden
;
box-shadow
:
0
2
rpx
12
rpx
rgba
(
0
,
0
,
0
,
0.08
);
box-shadow
:
0
2
rpx
12
rpx
rgba
(
0
,
0
,
0
,
0.1
);
}
}
.video-placeholder
{
.device-header
{
position
:
relative
;
display
:
flex
;
width
:
100%
;
align-items
:
flex-start
;
height
:
400
rpx
;
gap
:
20
rpx
;
background
:
linear-gradient
(
135deg
,
#667eea
0%
,
#764ba2
100%
);
margin-bottom
:
24
rpx
;
}
.device-icon
{
width
:
80
rpx
;
height
:
80
rpx
;
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
:
48
rpx
;
top
:
20
rpx
;
height
:
48
rpx
;
left
:
20
rpx
;
}
color
:
#ffffff
;
.device-title-group
{
flex
:
1
;
}
.device-title
{
font-size
:
32
rpx
;
font-size
:
32
rpx
;
font-weight
:
bold
;
font-weight
:
bold
;
text-shadow
:
0
2
rpx
4
rpx
rgba
(
0
,
0
,
0
,
0.3
);
color
:
#333333
;
}
margin-bottom
:
12
rpx
;
.play-icon
{
width
:
100
rpx
;
height
:
100
rpx
;
opacity
:
0.8
;
}
}
}
.camera-info
{
.device-badges
{
padding
:
24
rpx
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
gap
:
12
rpx
;
gap
:
12
rpx
;
}
.badge
{
padding
:
6
rpx
16
rpx
;
border-radius
:
20
rpx
;
font-size
:
24
rpx
;
}
.badge-green
{
background-color
:
#5db66f
;
color
:
#ffffff
;
}
.badge-gray
{
background-color
:
#e0e0e0
;
color
:
#666666
;
}
.info-row
{
.device-stats
{
display
:
flex
;
display
:
flex
;
font-size
:
26
rpx
;
justify-content
:
space-between
;
margin-bottom
:
16
rpx
;
.info-label
{
&:last-child
{
color
:
#999999
;
margin-bottom
:
0
;
min-width
:
140
rpx
;
}
}
}
.info-value
{
.stat-item
{
color
:
#333333
;
flex
:
1
;
flex
:
1
;
}
display
:
flex
;
}
align-items
:
center
;
}
.stat-label
{
font-size
:
26
rpx
;
color
:
#999999
;
}
.stat-value
{
font-size
:
26
rpx
;
color
:
#333333
;
}
}
/* 其他设备网格样式 */
.device-grid
{
.device-grid
{
display
:
grid
;
display
:
grid
;
grid-template-columns
:
repeat
(
3
,
1
fr
);
grid-template-columns
:
repeat
(
3
,
1
fr
);
...
@@ -923,6 +1001,8 @@ body {
...
@@ -923,6 +1001,8 @@ body {
&.selected
{
&.selected
{
border-color
:
#5db66f
;
border-color
:
#5db66f
;
box-shadow
:
0
4
rpx
12
rpx
rgba
(
93
,
182
,
111
,
0.3
);
box-shadow
:
0
4
rpx
12
rpx
rgba
(
93
,
182
,
111
,
0.3
);
background
:
#5DB66F
;
color
:
#FFFFFF
!important
;
}
}
}
}
...
...
src/pages/nongchang/detail/index.vue
浏览文件 @
8f0c58fd
...
@@ -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
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论