Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
032ca494
提交
032ca494
authored
12月 06, 2025
作者:
宇宙超人
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
1
上级
45e70da5
显示空白字符变更
内嵌
并排
正在显示
6 个修改的文件
包含
478 行增加
和
278 行删除
+478
-278
pages.json
src/pages.json
+2
-15
save-dialog.vue
src/pages/device/components/save-dialog.vue
+77
-79
device.vue
src/pages/device/device.vue
+379
-179
login.vue
src/pages/login/login.vue
+1
-0
index.vue
src/pages/nongchang/detail/index.vue
+17
-3
proxy.ts
src/utils/proxy.ts
+2
-2
没有找到文件。
src/pages.json
浏览文件 @
032ca494
...
...
@@ -546,24 +546,11 @@
{
"path"
:
"pages/device/device"
,
"style"
:
{
"navigationBarTitleText"
:
"
物联
设备"
,
"navigationBarTitleText"
:
"
基地
设备"
,
"enablePullDownRefresh"
:
false
,
"navigationBarBackgroundColor"
:
"#5DB66F"
,
"navigationBarTextStyle"
:
"white"
,
"backgroundColorBottom"
:
"#F2F2F2"
,
"app-plus"
:
{
"titleNView"
:
{
"buttons"
:
[
{
"text"
:
"+ 添加设备"
,
"fontSrc"
:
"/static/uni.ttf"
,
"color"
:
"#fff"
,
"fontSize"
:
"26rpx"
,
"width"
:
"auto"
}
]
}
}
"backgroundColorBottom"
:
"#F2F2F2"
}
},
{
...
...
src/pages/device/components/save-dialog.vue
浏览文件 @
032ca494
<
script
setup
lang=
"ts"
>
import
{
computed
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
useDictStore
}
from
'@/store/modules/dict'
import
*
as
NongchangAPI
from
'@/api/model/nongchang'
import
{
computed
,
reactive
,
ref
,
watch
}
from
'vue'
import
{
useDictStore
}
from
'@/store/modules/dict'
import
*
as
NongchangAPI
from
'@/api/model/nongchang'
// 定义Props
interface
Props
{
// 定义Props
interface
Props
{
show
:
boolean
editData
?:
any
farmId
:
any
,
farmBaseId
:
any
,
}
farmId
:
any
farmBaseId
:
any
}
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
const
props
=
withDefaults
(
defineProps
<
Props
>
(),
{
show
:
false
,
editData
:
null
,
farmId
:
0
,
farmBaseId
:
0
,
})
farmId
:
0
,
farmBaseId
:
0
,
})
// 定义Emits
const
emit
=
defineEmits
<
{
// 定义Emits
const
emit
=
defineEmits
<
{
'update:show'
:
[
value
:
boolean
]
submit
:
[
data
:
any
]
close
:
[]
}
>
()
}
>
()
// 表单引用
const
formRef
=
ref
()
const
loading
=
ref
(
false
)
const
showDeviceTypePicker
=
ref
(
false
)
// 表单引用
const
formRef
=
ref
()
const
loading
=
ref
(
false
)
const
showDeviceTypePicker
=
ref
(
false
)
// 字典存储
const
dictStore
=
useDictStore
()
// 字典存储
const
dictStore
=
useDictStore
()
// 表单数据
const
formData
=
reactive
({
// 表单数据
const
formData
=
reactive
({
deviceName
:
''
,
deviceType
:
''
,
deviceTypeText
:
''
,
deviceIdentifier
:
''
,
})
})
// 设备类型选项 - 使用字典数据
const
deviceTypeOptions
=
computed
(()
=>
{
// 设备类型选项 - 使用字典数据
const
deviceTypeOptions
=
computed
(()
=>
{
return
(
dictStore
.
getDictList
.
deviceType
?.
map
((
item
:
any
)
=>
({
value
:
item
.
value
,
text
:
item
.
text
,
}))
||
[]
)
})
})
// 设备类型选择器数据 (不再需要,因为fui-picker使用options属性)
// 设备类型选择器数据 (不再需要,因为fui-picker使用options属性)
// 计算属性
const
dialogTitle
=
computed
(()
=>
{
// 计算属性
const
dialogTitle
=
computed
(()
=>
{
return
props
.
editData
?
'编辑设备'
:
'添加设备'
})
})
const
submitButtonText
=
computed
(()
=>
{
const
submitButtonText
=
computed
(()
=>
{
return
props
.
editData
?
'保存'
:
'确认'
})
})
// 表单验证规则
const
rules
=
{
// 表单验证规则
const
rules
=
{
deviceName
:
[
{
required
:
true
,
message
:
'请输入设备名称'
,
trigger
:
'blur'
},
{
min
:
2
,
max
:
50
,
message
:
'设备名称长度在2-50个字符之间'
,
trigger
:
'blur'
},
...
...
@@ -84,10 +83,10 @@
trigger
:
'blur'
,
},
],
}
}
// 监听显示状态
watch
(
// 监听显示状态
watch
(
()
=>
props
.
show
,
(
newVal
)
=>
{
if
(
newVal
&&
props
.
editData
)
{
...
...
@@ -99,10 +98,10 @@
resetFormData
()
}
},
)
)
// 重置表单数据
function
resetFormData
()
{
// 重置表单数据
function
resetFormData
()
{
formData
.
deviceName
=
''
formData
.
deviceType
=
''
formData
.
deviceTypeText
=
''
...
...
@@ -112,12 +111,11 @@
if
(
formRef
.
value
)
{
formRef
.
value
.
resetFields
()
}
}
}
// 加载编辑数据
function
loadEditData
()
{
if
(
!
props
.
editData
)
return
// 加载编辑数据
function
loadEditData
()
{
if
(
!
props
.
editData
)
return
formData
.
deviceName
=
props
.
editData
.
deviceName
||
''
formData
.
deviceType
=
props
.
editData
.
deviceType
||
''
...
...
@@ -135,17 +133,17 @@ return
}
else
{
formData
.
deviceTypeText
=
''
}
}
}
// 设备类型选择确认
function
handleDeviceTypeConfirm
(
e
:
any
)
{
// 设备类型选择确认
function
handleDeviceTypeConfirm
(
e
:
any
)
{
formData
.
deviceType
=
e
.
value
formData
.
deviceTypeText
=
e
.
text
showDeviceTypePicker
.
value
=
false
}
}
// 提交表单
async
function
handleSubmit
()
{
// 提交表单
async
function
handleSubmit
()
{
try
{
console
.
log
(
formData
)
// 先进行表单验证
...
...
@@ -192,21 +190,21 @@ return
}
finally
{
loading
.
value
=
false
}
}
}
// 关闭弹窗
function
handleClose
()
{
// 关闭弹窗
function
handleClose
()
{
emit
(
'update:show'
,
false
)
emit
(
'close'
)
}
}
// 暴露方法给父组件
defineExpose
({
// 暴露方法给父组件
defineExpose
({
resetFormData
,
setLoading
:
(
value
:
boolean
)
=>
{
loading
.
value
=
value
},
})
})
</
script
>
<
template
>
...
...
@@ -271,23 +269,23 @@ return
</
template
>
<
style
lang=
"scss"
scoped
>
.dialog-content
{
.dialog-content
{
padding
:
10
rpx
30
rpx
;
width
:
90%
;
max-height
:
80vh
;
overflow-y
:
auto
;
}
}
.section-title
{
.section-title
{
font-size
:
32
rpx
;
font-weight
:
600
;
color
:
#333
;
margin
:
20
rpx
0
30
rpx
0
;
padding-left
:
20
rpx
;
border-left
:
6
rpx
solid
#5db66f
;
}
}
.dialog-buttons
{
.dialog-buttons
{
display
:
flex
;
gap
:
20
rpx
;
margin-top
:
40
rpx
;
...
...
@@ -310,10 +308,10 @@ return
border
:
2
rpx
solid
#dcdfe6
;
}
}
}
}
//
uview-plus
表单样式调整
::v-deep
.u-form-item
{
//
uview-plus
表单样式调整
::v-deep
.u-form-item
{
margin-bottom
:
40
rpx
;
.u-form-item__body
{
...
...
@@ -336,8 +334,8 @@ return
flex
:
1
;
min-width
:
0
;
}
}
.address-display
{
}
.address-display
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
...
...
@@ -357,15 +355,15 @@ return
.placeholder-text
{
color
:
#c0c4cc
;
}
}
}
::v-deep
.u-form-item__body__left__content__required
{
::v-deep
.u-form-item__body__left__content__required
{
position
:
static
;
padding-right
:
10
rpx
;
}
}
//
输入框样式优化
::v-deep
.u-input
{
//
输入框样式优化
::v-deep
.u-input
{
.u-input__content
{
padding
:
0
;
...
...
@@ -390,10 +388,10 @@ return
}
}
}
}
}
//
模态框样式调整
::v-deep
.u-modal
{
//
模态框样式调整
::v-deep
.u-modal
{
.u-modal__content
{
border-radius
:
20
rpx
;
padding
:
20
rpx
0
rpx
;
...
...
@@ -409,5 +407,5 @@ return
color
:
#333
;
}
}
}
}
</
style
>
src/pages/device/device.vue
浏览文件 @
032ca494
<
script
setup
>
import
{
reactive
,
ref
}
from
'vue'
import
{
onNavigationBarButtonTap
}
from
'@dcloudio/uni-app'
import
SaveDialog
from
'./components/save-dialog.vue'
import
*
as
NongchangAPI
from
'@/api/model/nongchang'
const
isOnePage
=
ref
(
true
)
const
paging
=
ref
(
null
)
const
pageData
=
reactive
({
import
{
reactive
,
ref
,
computed
}
from
'vue'
import
{
onLoad
,
onNavigationBarButtonTap
}
from
'@dcloudio/uni-app'
import
SaveDialog
from
'./components/save-dialog.vue'
import
*
as
NongchangAPI
from
'@/api/model/nongchang'
import
{
useDictStore
}
from
'@/store/modules/dict'
import
{
merge
}
from
'lodash-es'
const
dictStore
=
useDictStore
()
const
deviceType
=
ref
(
''
)
// 设备类型参数
const
pageData
=
reactive
({
param
:
{
pageNo
:
1
,
pageSize
:
10
,
deviceName
:
''
,
deviceType
:
''
,
// 添加设备类型筛选
},
list
:
[],
})
// 滑动操作选项
const
swipeOptions
=
[
{
text
:
'编辑'
,
style
:
{
backgroundColor
:
'var(--fui-color-primary)'
,
},
},
{
text
:
'删除'
,
style
:
{
backgroundColor
:
'var(--fui-color-danger)'
,
},
},
]
function
getList
()
{
if
(
!
paging
.
value
)
return
NongchangAPI
.
getDeviceList
(
pageData
.
param
)
.
then
((
res
)
=>
{
pageData
.
total
=
res
.
total
paging
.
value
.
complete
(
res
.
records
)
})
.
catch
(()
=>
{
paging
.
value
.
complete
(
false
)
})
}
function
queryList
(
pageNo
,
pageSize
)
{
pageData
.
param
.
pageNo
=
pageNo
pageData
.
param
.
pageSize
=
pageSize
selectedCategory
:
'all'
,
})
// 摄像头设备的分类标签
const
cameraCategories
=
computed
(()
=>
{
const
dictList
=
dictStore
.
getDictList
.
deviceType
?.
map
((
item
)
=>
({
id
:
item
.
value
,
name
:
item
.
text
,
}))
||
[]
return
[{
id
:
'all'
,
name
:
'全部'
},
...
dictList
]
})
onLoad
((
options
)
=>
{
// 获取设备类型参数
if
(
options
.
deviceType
)
{
deviceType
.
value
=
options
.
deviceType
pageData
.
param
.
deviceType
=
options
.
deviceType
}
})
// 判断是否为摄像头设备
const
isCameraDevice
=
computed
(()
=>
{
return
deviceType
.
value
===
'1'
})
// 获取设备列表
function
getList
()
{
// TODO: API请求留空,后续实现
// NongchangAPI.getDeviceList(pageData.param)
// .then((res) => {
// pageData.list = res.records || []
// })
// .catch(() => {
// pageData.list = []
// })
}
function
handleSearch
()
{
// 搜索时重新获取列表
getList
()
}
}
function
handleSearch
()
{
// 重置页码为1,重新搜索
pageData
.
param
.
pageNo
=
1
if
(
paging
.
value
)
{
paging
.
value
.
reload
()
}
}
const
showDialog
=
ref
(
false
)
const
currentEditData
=
ref
(
null
)
onNavigationBarButtonTap
((
_
)
=>
{
const
showDialog
=
ref
(
false
)
const
currentEditData
=
ref
(
null
)
onNavigationBarButtonTap
((
_
)
=>
{
showAddDialog
()
})
function
showAddDialog
()
{
})
function
showAddDialog
()
{
currentEditData
.
value
=
null
showDialog
.
value
=
true
}
}
function
showEditDialog
(
device
)
{
currentEditData
.
value
=
device
showDialog
.
value
=
true
}
function
handleSubmitSuccess
()
{
function
handleSubmitSuccess
()
{
// 提交成功后刷新列表
handleSearch
()
}
getList
()
}
function
handleDialogClose
()
{
function
handleDialogClose
()
{
// 弹窗关闭后的处理逻辑
}
}
// 删除设备
async
function
handleDelete
(
id
)
{
try
{
await
uni
.
showModal
({
title
:
'确认删除'
,
content
:
'确定要删除这个设备吗?'
,
success
:
async
(
res
)
=>
{
if
(
res
.
confirm
)
{
await
NongchangAPI
.
delDevice
(
id
)
uni
.
showToast
({
title
:
'删除成功'
,
icon
:
'success'
})
handleSearch
()
}
},
})
}
catch
(
error
)
{
uni
.
showToast
({
title
:
'删除失败'
,
icon
:
'none'
})
}
}
// 获取状态样式类
function
getStatusClass
(
status
)
{
if
(
status
===
'已连接'
)
return
'status-connected'
if
(
status
===
'未连接'
)
return
'status-disconnected'
// 获取状态样式类
function
getStatusClass
(
status
)
{
if
(
status
===
'已连接'
)
return
'status-connected'
if
(
status
===
'未连接'
)
return
'status-disconnected'
return
'status-unknown'
}
// 处理滑动打开事件
function
handleSwipeOpen
(
index
)
{
// 关闭其他已打开的滑动单元格,确保同时只有一个处于打开状态
pageData
.
list
.
forEach
((
item
,
i
)
=>
{
item
.
isShow
=
i
===
index
})
}
}
// 处理滑动操作
function
handleSwipeAction
(
e
,
device
)
{
const
index
=
e
.
index
const
position
=
e
.
position
if
(
position
===
'right'
)
{
if
(
index
===
0
)
{
// 编辑操作
showEditDialog
(
device
)
}
else
if
(
index
===
1
)
{
// 删除操作
handleDelete
(
device
.
id
)
}
}
}
// 分类标签点击
function
handleCategoryClick
(
category
)
{
pageData
.
selectedCategory
=
category
.
id
// TODO: 根据分类筛选设备
getList
()
}
</
script
>
<
template
>
<view
class=
"codefun-flex-col page"
>
<z-paging
ref=
"paging"
v-model=
"pageData.list"
@
query=
"queryList"
>
<!-- 摄像头设备布局 -->
<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"
/>
...
...
@@ -145,33 +109,103 @@ return 'status-disconnected'
/>
</view>
<!-- 设备列表 -->
<view
class=
"device-list"
>
<uni-swipe-action>
<uni-swipe-action-item
<!-- 分类标签 -->
<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=
"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>
</view>
<!-- 空状态 -->
<view
class=
"empty-state"
v-if=
"pageData.list.length === 0"
>
<text>
暂无设备数据
</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=
"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"
:right-options=
"swipeOptions"
@
click=
"(e) => handleSwipeAction(e, item)"
class=
"device-card"
:class=
"
{ selected: item.selected }"
@click="() => {}"
>
<view
class=
"device-item"
>
<view
class=
"device-info"
>
<view
class=
"device-card-header"
>
<view
class=
"device-name"
>
{{
item
.
deviceName
}}
</view>
<view
class=
"device-details"
>
<text
class=
"device-type"
>
类型:
{{
item
.
deviceType_dictText
||
'未知'
}}
</text>
<text
class=
"device-identifier"
>
标识:
{{
item
.
deviceIdentifier
}}
</text>
<view
class=
"device-status"
:class=
"getStatusClass(item.connectStatus_dictText)"
>
{{
item
.
connectStatus_dictText
||
'未知'
}}
</view>
</view>
<view
class=
"device-status-time"
>
<text
class=
"device-status"
:class=
"getStatusClass(item.connectStatus)"
>
{{
item
.
connectStatus_dictText
||
'未知'
}}
</text>
<view
style=
"opacity: 0"
>
1
</view>
<view
class=
"device-time"
>
添加日期:
{{
item
.
createTime
}}
</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>
</view>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
<!-- 空状态 -->
...
...
@@ -179,7 +213,8 @@ return 'status-disconnected'
<text>
暂无设备数据
</text>
</view>
</view>
</z-paging>
</view>
<!-- 弹窗组件 -->
<SaveDialog
:show=
"showDialog"
...
...
@@ -192,31 +227,31 @@ return 'status-disconnected'
</
template
>
<
style
lang=
"scss"
>
body
{
body
{
background-color
:
#e6f5e8
;
}
}
.mt-5
{
.mt-5
{
margin-top
:
10
rpx
;
}
}
.mt-11
{
.mt-11
{
margin-top
:
22
rpx
;
}
}
.ml-5
{
.ml-5
{
margin-left
:
10
rpx
;
}
}
.ml-13
{
.ml-13
{
margin-left
:
26
rpx
;
}
}
.ml-9
{
.ml-9
{
margin-left
:
18
rpx
;
}
}
.page
{
.page
{
background-color
:
#e6f5e8
;
mix-blend-mode
:
NOTTHROUGH
;
width
:
100%
;
...
...
@@ -679,14 +714,14 @@ return 'status-disconnected'
line-height
:
25.76
rpx
;
color
:
#ffffff
;
}
}
}
/* 设备列表样式 */
.device-list
{
/* 设备列表样式 */
.device-list
{
margin-top
:
20
rpx
;
}
}
.device-item
{
.device-item
{
background-color
:
#ffffff
;
border-radius
:
16
rpx
;
padding
:
24
rpx
;
...
...
@@ -694,82 +729,247 @@ return 'status-disconnected'
//
justify-content
:
space-between
;
align-items
:
center
;
box-shadow
:
0
2
rpx
12
rpx
rgba
(
0
,
0
,
0
,
0.1
);
}
}
::v-deep
.uni-swipe
{
::v-deep
.uni-swipe
{
border-radius
:
16
rpx
;
margin-bottom
:
20
rpx
;
}
}
.device-info
{
.device-info
{
flex
:
1
;
}
}
.device-name
{
.device-name
{
font-size
:
32
rpx
;
font-weight
:
bold
;
color
:
#333333
;
margin-bottom
:
8
rpx
;
border-left
:
6
rpx
solid
#5db66f
;
padding-left
:
6
rpx
;
}
}
.device-details
{
.device-details
{
display
:
flex
;
flex-direction
:
column
;
gap
:
6
rpx
;
margin-bottom
:
8
rpx
;
}
}
.device-type
,
.device-identifier
{
.device-type
,
.device-identifier
{
font-size
:
24
rpx
;
color
:
#666666
;
}
}
.device-status-time
{
.device-status-time
{
display
:
flex
;
flex-direction
:
column
;
align-items
:
flex-end
;
gap
:
6
rpx
;
min-width
:
180
rpx
;
}
}
.device-status
{
.device-status
{
font-size
:
24
rpx
;
font-weight
:
bold
;
}
}
.device-time
{
.device-time
{
font-size
:
22
rpx
;
color
:
#999999
;
}
}
.device-actions
{
.device-actions
{
display
:
flex
;
flex-direction
:
column
;
gap
:
12
rpx
;
}
}
.status-connected
{
.status-connected
{
color
:
#5db66f
!important
;
font-weight
:
bold
;
}
}
.status-disconnected
{
.status-disconnected
{
color
:
#f44336
!important
;
font-weight
:
bold
;
}
}
.status-unknown
{
.status-unknown
{
color
:
#ff9800
!important
;
font-weight
:
bold
;
}
}
.empty-state
{
.empty-state
{
text-align
:
center
;
padding
:
100
rpx
0
;
color
:
#999999
;
font-size
:
28
rpx
;
}
/* 分类标签样式 */
.category-tabs
{
display
:
flex
;
gap
:
16
rpx
;
padding
:
24
rpx
0
;
overflow-x
:
auto
;
white-space
:
nowrap
;
}
.category-tab
{
padding
:
12
rpx
32
rpx
;
background-color
:
#ffffff
;
border-radius
:
40
rpx
;
font-size
:
28
rpx
;
color
:
#333333
;
cursor
:
pointer
;
flex-shrink
:
0
;
border
:
2
rpx
solid
transparent
;
transition
:
all
0.3s
;
&.active
{
background-color
:
#5db66f
;
color
:
#ffffff
;
font-weight
:
bold
;
}
}
/* 摄像头设备样式 */
.camera-layout
{
width
:
100%
;
height
:
100%
;
}
.camera-grid
{
display
:
flex
;
flex-direction
:
column
;
gap
:
24
rpx
;
margin-top
:
20
rpx
;
}
.camera-card
{
background-color
:
#ffffff
;
border-radius
:
16
rpx
;
overflow
:
hidden
;
box-shadow
:
0
2
rpx
12
rpx
rgba
(
0
,
0
,
0
,
0.1
);
}
.video-placeholder
{
position
:
relative
;
width
:
100%
;
height
:
400
rpx
;
background
:
linear-gradient
(
135deg
,
#667eea
0%
,
#764ba2
100%
);
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
.video-title
{
position
:
absolute
;
top
:
20
rpx
;
left
:
20
rpx
;
color
:
#ffffff
;
font-size
:
32
rpx
;
font-weight
:
bold
;
text-shadow
:
0
2
rpx
4
rpx
rgba
(
0
,
0
,
0
,
0.3
);
}
.play-icon
{
width
:
100
rpx
;
height
:
100
rpx
;
opacity
:
0.8
;
}
}
.camera-info
{
padding
:
24
rpx
;
display
:
flex
;
flex-direction
:
column
;
gap
:
12
rpx
;
.info-row
{
display
:
flex
;
font-size
:
26
rpx
;
.info-label
{
color
:
#999999
;
min-width
:
140
rpx
;
}
.info-value
{
color
:
#333333
;
flex
:
1
;
}
}
}
/* 其他设备网格样式 */
.device-grid
{
display
:
grid
;
grid-template-columns
:
repeat
(
3
,
1
fr
);
gap
:
20
rpx
;
margin-top
:
20
rpx
;
}
.device-card
{
background-color
:
#ffffff
;
border-radius
:
16
rpx
;
padding
:
24
rpx
;
box-shadow
:
0
2
rpx
8
rpx
rgba
(
0
,
0
,
0
,
0.08
);
cursor
:
pointer
;
transition
:
all
0.3s
;
border
:
2
rpx
solid
transparent
;
&.selected
{
border-color
:
#5db66f
;
box-shadow
:
0
4
rpx
12
rpx
rgba
(
93
,
182
,
111
,
0.3
);
}
}
.device-card-header
{
display
:
flex
;
flex-direction
:
column
;
gap
:
8
rpx
;
margin-bottom
:
16
rpx
;
border-bottom
:
2
rpx
solid
#f0f0f0
;
padding-bottom
:
16
rpx
;
.device-name
{
font-size
:
28
rpx
;
font-weight
:
bold
;
color
:
#333333
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
.device-status
{
font-size
:
22
rpx
;
font-weight
:
bold
;
}
}
.device-card-body
{
display
:
flex
;
flex-direction
:
column
;
gap
:
12
rpx
;
.device-detail
{
font-size
:
22
rpx
;
display
:
flex
;
flex-direction
:
column
;
gap
:
4
rpx
;
.detail-label
{
color
:
#999999
;
}
.detail-value
{
color
:
#666666
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
</
style
>
src/pages/login/login.vue
浏览文件 @
032ca494
...
...
@@ -286,6 +286,7 @@
:required=
"false"
clearable
trim
type=
"number"
placeholder=
"请输入手机号"
v-model=
"model.form.data.username"
name=
"mobile"
...
...
src/pages/nongchang/detail/index.vue
浏览文件 @
032ca494
...
...
@@ -15,6 +15,7 @@ import type { ToolBoxButtonHandleEvent } from '@/components/Map/Widgets/ToolBox'
import
{
ToolBoxWidget
,
useToolBoxWidget
}
from
'@/components/Map/Widgets/ToolBox'
import
*
as
NongchangAPI
from
'@/api/model/nongchang'
import
*
as
farmbaseApi
from
'@/api/model/farmbase'
import
navigate
from
'@/utils/page/navigate'
// 页面参数
const
page
=
reactive
<
Page
>
({
...
...
@@ -343,6 +344,9 @@ onNavigationBarButtonTap((e) => {
Navigate
.
to
(
`/pages/jidiguanli/add?farmId=
${
model
.
id
}
`
)
}
})
const
toDevice
=
(
device
)
=>
{
Navigate
.
to
(
`/pages/device/device?deviceType=
${
device
.
deviceType
}
`
)
}
</
script
>
<
template
>
...
...
@@ -485,16 +489,20 @@ onNavigationBarButtonTap((e) => {
<view
class=
"box-4"
>
<view
class=
"box-4-title"
>
<view
class=
"box-4-title-text1"
><text>
基地设备
</text></view>
<view
class=
"box-4-title-text2"
@
click=
"showDialog
=
true"
><text>
+ 添加设备
</text></view>
<view
class=
"box-4-title-text2"
@
click=
"showDialog
=
true"
><text>
+ 添加设备
</text></view>
</view>
<view
class=
"box-4-device"
>
<view
class=
"box-4-device-item"
v-for=
"(device, index) in model.deviceTypeCount"
:key=
"index"
@
click=
"toDevice(device)"
>
<view
class=
"box-4-item-icon"
>
<image
class=
"box-4-item-icon-image"
:src=
"`/static/images/nongchang/device$
{device.deviceType}.png`" />
<image
class=
"box-4-item-icon-image"
:src=
"`/static/images/nongchang/device$
{device.deviceType}.png`"
/>
</view>
<view
class=
"box-4-item-content"
>
<text
class=
"box-4-item-text1"
>
{{
device
.
deviceName
}}
</text>
...
...
@@ -506,7 +514,13 @@ onNavigationBarButtonTap((e) => {
</view>
</view>
</view>
<SaveDialog
:show=
"showDialog"
:farmId=
"model.id"
:farmBaseId=
"model.farmbaseInfo?.id"
@
submitSuccess=
"getDeviceTypeCount"
@
close=
"showDialog=false"
/>
<SaveDialog
:show=
"showDialog"
:farmId=
"model.id"
:farmBaseId=
"model.farmbaseInfo?.id"
@
submitSuccess=
"getDeviceTypeCount"
@
close=
"showDialog = false"
/>
</view>
</
template
>
...
...
src/utils/proxy.ts
浏览文件 @
032ca494
...
...
@@ -11,8 +11,8 @@ const PROXY_LIST: [[string, string]?] = [
// [`http://192.168.0.100:18100`, `https://oss.beta.app.yiring.com`],
// 开发环境(预览)
//
[`http://192.168.0.156:18100`, `http://111.22.182.169:49091`],
[
`http://192.168.0.156:18100`
,
`http://36.133.16.81:42111`
],
[
`http://192.168.0.156:18100`
,
`http://111.22.182.169:49091`
],
//
[`http://192.168.0.156:18100`, `http://36.133.16.81:42111`],
]
/**
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论