Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
basic-uniapp-v3
概览
概览
详情
活动
周期分析
版本库
存储库
文件
提交
分支
标签
贡献者
分支图
比较
统计图
问题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程表
图表
维基
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
Basic
basic-uniapp-v3
Commits
a62386c0
提交
a62386c0
authored
6月 01, 2026
作者:
廖在望
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat: 农场页面修改
上级
8b825578
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
625 行增加
和
445 行删除
+625
-445
mapbox.module.js
src/components/Map/Mapbox/mapbox.module.js
+3
-3
types.ts
src/components/Map/types.ts
+4
-0
add.vue
src/pages/jidiguanli/add.vue
+173
-15
create-nongchang-form.vue
src/pages/nongchang/create-nongchang-form.vue
+173
-166
index.vue
src/pages/nongchang/detail/index.vue
+256
-242
nongchang.vue
src/pages/nongchang/nongchang.vue
+7
-7
shouye.vue
src/pages/shouye/shouye.vue
+9
-12
没有找到文件。
src/components/Map/Mapbox/mapbox.module.js
浏览文件 @
a62386c0
...
...
@@ -112,15 +112,15 @@ export default {
if (this.map && this.map.remove) {
this.map.remove()
}
let style = merge(defaultStyle, options?.style);
let style = merge(
{},
defaultStyle, options?.style);
//是否卫星图显示
if (options?.style.isImg) {
style.layers
.push(
{
style.layers
= [...style.layers,
{
id: 'wms-img_w-layer',
type: 'raster',
source: 'wms-img_w-source',
layout: { visibility: 'visible' },
}
)
}
]
}
// [107.570282, 19.474339],
// [115.629717, 34.466859],
...
...
src/components/Map/types.ts
浏览文件 @
a62386c0
...
...
@@ -10,6 +10,10 @@ export interface BasicMapPage {
*/
init
:
boolean
/**
* 地图渲染是否完成初始化(用于区分页面数据初始化和地图 geojson 渲染初始化)
*/
mapInit
?:
boolean
/**
* 页面正在请求的数据源数量,由于 setGeoJSONSourceForRequest 的异步特性,需要记录当前正在请求的数据源数量,当所有数据源请求完成时,隐藏 Loading
*/
requests
?:
number
...
...
src/pages/jidiguanli/add.vue
浏览文件 @
a62386c0
...
...
@@ -113,10 +113,11 @@
function
submit
()
{
formRef
.
value
.
validator
(
pageData
.
form
,
pageData
.
rules
,
true
).
then
((
res
)
=>
{
if
(
res
.
isPassed
)
{
pageData
.
loading
=
true
NongchangAPI
.
saveFarmbase
(
pageData
.
form
).
then
(()
=>
{
toastRef
.
value
.
show
({
type
:
'success'
,
text
:
'保存成功'
})
setTimeout
(()
=>
uni
.
navigateBack
(),
1500
)
})
})
.
finally
(()
=>
pageData
.
loading
=
false
)
}
})
}
...
...
@@ -124,20 +125,48 @@
<
template
>
<view
class=
"page"
>
<view
class=
"container"
>
<view
class=
"form-banner"
>
<text
class=
"title"
>
{{
isSave
?
'新增基地'
:
'基地详情'
}}
</text>
<text
class=
"subtitle"
>
{{
isSave
?
'录入生产基地信息,完善经营档案'
:
'查看基地详细信息'
}}
</text>
</view>
<view
class=
"form-content"
>
<fui-form
ref=
"formRef"
>
<view
class=
"section-card"
>
<fui-input
label=
"基地名称"
placeholder=
"请输入"
v-model=
"form.baseName"
required
/>
<fui-input
disabled
required
label=
"所在地区"
v-model=
"form.address"
@
click=
"show.address = true"
/>
<fui-input
label=
"详细地址"
placeholder=
"请输入"
v-model=
"form.addressDetail"
required
/>
<view
class=
"card-header"
>
<view
class=
"line"
></view>
<text>
基地基础信息
</text>
</view>
<fui-input
label=
"基地名称"
placeholder=
"请输入基地名称"
v-model=
"form.baseName"
required
label-size=
"28"
/>
<fui-form-item
required
asterisk
label=
"所在地区"
labelSize=
"28"
:labelWeight=
"400"
labelWidth=
"auto"
>
<view
class=
"picker-input"
@
click=
"show.address = true"
>
<text
class=
"select-text"
:class=
"
{ placeholder: !form.address }">
{{
form
.
address
||
'请选择所在地区'
}}
</text>
<fui-icon
name=
"arrowright"
:size=
"32"
color=
"#ccc"
></fui-icon>
</view>
</fui-form-item>
<fui-input
label=
"详细地址"
placeholder=
"请输入详细地址"
v-model=
"form.addressDetail"
required
label-size=
"28"
/>
</view>
<view
class=
"section-card"
>
<fui-input
type=
"number"
label=
"基地规模"
v-model=
"form.scale"
required
>
<view
class=
"card-header"
>
<view
class=
"line"
></view>
<text>
经营规模信息
</text>
</view>
<fui-input
type=
"number"
label=
"基地规模"
v-model=
"form.scale"
required
label-size=
"28"
>
<template
#
suffix
><text
class=
"unit"
>
亩
</text></
template
>
</fui-input>
<fui-input
disabled
required
label=
"种植作物"
v-model=
"form.growCropsText"
@
click=
"show.growCrops = true"
/>
<fui-form-item
required
asterisk
label=
"种植作物"
labelSize=
"28"
:labelWeight=
"400"
labelWidth=
"auto"
>
<view
class=
"picker-input"
@
click=
"show.growCrops = true"
>
<text
class=
"select-text"
:class=
"{ placeholder: !form.growCropsText }"
>
{{ form.growCropsText || '请选择种植作物' }}
</text>
<fui-icon
name=
"arrowright"
:size=
"32"
color=
"#ccc"
></fui-icon>
</view>
</fui-form-item>
</view>
<!-- 更多字段... -->
<view
class=
"submit-area"
v-if=
"isSave"
>
<fui-button
text=
"确认保存"
radius=
"100rpx"
@
click=
"submit"
/>
</view>
...
...
@@ -147,14 +176,142 @@
<AreaPicker
v-model:show=
"show.address"
:layer=
"3"
title=
"选择所属地区"
@
confirm=
"handleAreaConfirm"
/>
<fui-picker
:show=
"show.growCrops"
:options=
"options.growCrops"
@
change=
"handleGrowCropsChange"
@
cancel=
"show.growCrops = false"
/>
<fui-toast
ref=
"toastRef"
/>
<fui-loading
isFixed
v-if=
"pageData.loading"
backgroundColor=
"rgba(0, 0, 0, 0.4)"
/>
</view>
</template>
<
style
lang=
"scss"
scoped
>
.page
{
background-color
:
#f7f8fa
;
min-height
:
100vh
;
font-family
:
'DingTalk Sans'
,
sans-serif
;
}
.container
{
padding
:
24
rpx
;
}
.section-card
{
background
:
#fff
;
border-radius
:
24
rpx
;
padding
:
10
rpx
24
rpx
;
margin-bottom
:
24
rpx
;
}
.submit-area
{
padding
:
40
rpx
20
rpx
;
}
.unit
{
font-size
:
26
rpx
;
color
:
#999
;
margin-left
:
12
rpx
;
}
:deep
(
.fui-input__label
)
{
font-family
:
'DingTalk Sans'
!important
;
}
</
style
>
.page
{
min-height
:
100vh
;
background-color
:
#f4f7f5
;
font-family
:
'DingTalk Sans'
,
sans-serif
;
}
.form-banner
{
background-color
:
#5db66f
;
padding
:
60
rpx
40
rpx
100
rpx
;
color
:
#fff
;
.title
{
font-size
:
48
rpx
;
font-weight
:
bold
;
display
:
block
;
letter-spacing
:
2
rpx
;
}
.subtitle
{
font-size
:
26
rpx
;
opacity
:
0.9
;
margin-top
:
12
rpx
;
display
:
block
;
}
}
.form-content
{
padding
:
24
rpx
;
margin-top
:
-80
rpx
;
position
:
relative
;
z-index
:
10
;
}
.section-card
{
background-color
:
#fff
;
border-radius
:
28
rpx
;
padding
:
32
rpx
;
margin-bottom
:
28
rpx
;
box-shadow
:
0
8
rpx
20
rpx
rgba
(
0
,
0
,
0
,
0.03
);
.card-header
{
margin-bottom
:
32
rpx
;
display
:
flex
;
align-items
:
center
;
.line
{
width
:
8
rpx
;
height
:
32
rpx
;
background-color
:
#5db66f
;
border-radius
:
4
rpx
;
margin-right
:
16
rpx
;
}
text
{
font-size
:
32
rpx
;
font-weight
:
bold
;
color
:
#1a1a1a
;
}
}
}
.picker-input
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
0
20
rpx
;
width
:
100%
;
}
.select-text
{
font-size
:
28
rpx
;
color
:
#333333
;
flex
:
1
;
&.placeholder
{
color
:
#999999
;
}
}
.unit
{
font-size
:
26
rpx
;
color
:
#999
;
margin-left
:
12
rpx
;
}
.submit-area
{
padding
:
60
rpx
20
rpx
100
rpx
;
:deep(.fui-button)
{
background
:
#5db66f
!important
;
border-color
:
#5db66f
!important
;
box-shadow
:
0
8
rpx
24
rpx
rgba
(
93
,
182
,
111
,
0.3
);
}
}
:deep
(
.fui-form
)
{
background
:
transparent
;
}
:deep
(
.fui-form__item
)
{
background
:
transparent
;
border
:
none
;
margin-bottom
:
0
;
padding
:
0
;
}
:deep
(
.fui-input__wrap
)
{
padding
:
28
rpx
0
;
}
:deep
(
.fui-input__label
)
{
font-size
:
28
rpx
;
color
:
#333333
;
font-weight
:
400
;
font-family
:
'DingTalk Sans'
,
system-ui
!important
;
}
:deep
(
.fui-input__self
)
{
font-size
:
28
rpx
;
color
:
#333333
;
font-family
:
'DingTalk Sans'
,
system-ui
!important
;
}
:deep
(
.fui-input__placeholder
)
{
color
:
#d0d0d0
;
font-size
:
28
rpx
;
font-family
:
'DingTalk Sans'
!important
;
}
::v-deep
.uni-input-placeholder
{
font-size
:
28
rpx
!important
;
color
:
#999999
!important
;
font-family
:
'DingTalk Sans'
!important
;
}
:deep
(
.fui-button
)
{
font-family
:
'DingTalk Sans'
!important
;
font-weight
:
bold
!important
;
}
</
style
>
\ No newline at end of file
src/pages/nongchang/create-nongchang-form.vue
浏览文件 @
a62386c0
...
...
@@ -16,13 +16,11 @@ onLoad((pageOptions) => {
})
pageData
.
form
.
id
=
pageOptions
.
id
;
NongchangAPI
.
farmsGet
({
id
:
pageOptions
.
id
}).
then
((
res
)
=>
{
// 将 res 中的数据赋值到 formData 中,key 保持一致
Object
.
keys
(
res
).
forEach
((
key
)
=>
{
if
(
key
in
pageData
.
form
)
{
pageData
.
form
[
key
]
=
res
[
key
]
}
})
// 回显省市区名称
if
(
res
.
provinceName
&&
res
.
cityName
&&
res
.
districtName
)
{
pageData
.
form
.
provinceName
=
res
.
provinceName
pageData
.
form
.
cityName
=
res
.
cityName
...
...
@@ -30,14 +28,11 @@ onLoad((pageOptions) => {
pageData
.
form
.
provinceText
=
res
.
provinceName
+
'/'
+
res
.
cityName
+
'/'
+
res
.
districtName
}
// 编辑模式下,如果已有示例图片,需要设置到上传组件中
if
(
res
.
coverImage
)
{
nextTick
(()
=>
{
// 设置上传组件的初始文件
const
uploadComponent
=
uploadRef
.
value
if
(
uploadComponent
)
{
uploadComponent
.
clearFiles
()
// 构造文件对象格式,适配uni-file-picker的数据结构
const
fileItem
=
{
url
:
res
.
coverImage
,
name
:
res
.
coverImage
.
split
(
'/'
).
pop
()
||
'image.jpg'
,
...
...
@@ -48,8 +43,6 @@ onLoad((pageOptions) => {
})
}
// 编辑模式下,根据字典值获取对应的文本
// 延迟执行,确保字典数据已加载完成
nextTick
(()
=>
{
if
(
res
.
farmType
)
{
const
farmTypeItem
=
pageData
.
options
.
farmType
.
find
(
item
=>
item
.
value
==
res
.
farmType
)
...
...
@@ -69,9 +62,11 @@ onLoad((pageOptions) => {
}
})
onShow
(()
=>
{
// 数据字典赋值
initDict
()
pageData
.
form
.
userId
=
userStore
.
getUserInfo
.
id
if
(
!
pageData
.
form
.
id
)
{
pageData
.
form
.
ownerPhone
=
userStore
.
getUserInfo
?.
phone
||
''
}
})
const
pageData
=
reactive
({
...
...
@@ -165,6 +160,8 @@ const pageData = reactive({
],
})
const
isEditMode
=
computed
(()
=>
!!
pageData
.
form
.
id
)
function
initDict
()
{
pageData
.
options
.
mainProducts
=
dictStore
.
getDictList
.
main_business
.
map
((
item
)
=>
{
return
{
...
...
@@ -197,11 +194,10 @@ function handleChangeGrowCrops(e) {
}
const
toastRef
=
ref
()
const
uploadRef
=
ref
()
// 文件上传
function
handleUpload
(
file
)
{
pageData
.
loading
=
true
uni
.
uploadFile
({
url
:
`
${
globSetting
.
apiUrl
+
globSetting
.
urlPrefix
}
/sys/common/upload`
,
// 直接使用上传接口URL
url
:
`
${
globSetting
.
apiUrl
+
globSetting
.
urlPrefix
}
/sys/common/upload`
,
filePath
:
file
.
tempFiles
[
0
].
path
,
name
:
'file'
,
formData
:
{
...
...
@@ -218,7 +214,7 @@ function handleUpload(file) {
type
:
'success'
,
text
:
'上传成功'
,
})
pageData
.
form
.
coverImage
=
data
.
message
// 保存返回的图片信息
pageData
.
form
.
coverImage
=
data
.
message
}
}
},
...
...
@@ -235,7 +231,6 @@ function handleUpload(file) {
},
})
}
// 文件删除
function
handleDelete
(
file
)
{
uploadRef
.
value
.
clearFiles
()
pageData
.
form
.
coverImage
=
null
...
...
@@ -246,7 +241,6 @@ function submit() {
if
(
res
.
isPassed
)
{
pageData
.
loading
=
true
// 提交前处理:通过对provinceText值按/分隔,分别赋值给provinceName、cityName和districtName
if
(
pageData
.
form
.
provinceText
)
{
const
addressParts
=
pageData
.
form
.
provinceText
.
split
(
'/'
)
if
(
addressParts
.
length
>=
3
)
{
...
...
@@ -264,22 +258,14 @@ function submit() {
text
:
pageData
.
form
.
id
?
'保存修改成功'
:
'添加农场成功'
,
})
// 获取农场ID:编辑时使用当前ID,新增时从返回值获取(假设返回的是ID或包含ID的对象)
// 根据后端接口惯例,如果返回的是ID字符串直接使用,如果是对象则取id字段
// 暂时假设res为ID或者不影响跳转,优先使用pageData.form.id,如果是新增则尝试从res获取
// 如果res不是id,则需要确认接口返回值结构。通常新增接口返回ID比较合理。
// 鉴于不确定接口返回值,这里先假设编辑时id已知,新增时尝试从res获取,如果获取不到则回退到列表页
const
targetId
=
pageData
.
form
.
id
||
(
typeof
res
===
'string'
?
res
:
res
?.
id
);
setTimeout
(()
=>
{
if
(
targetId
)
{
// 跳转到农场详情页,注意路径需要是绝对路径
uni
.
redirectTo
({
url
:
`/pages/nongchang/detail/index?id=
${
targetId
}
`
})
}
else
{
// 如果没有ID,回退上一页
uni
.
navigateBack
()
}
},
500
);
...
...
@@ -294,10 +280,18 @@ function submit() {
<
template
>
<view
class=
"page"
>
<view
class=
"page-container"
>
<view
class=
"form-banner"
>
<text
class=
"title"
>
{{
isEditMode
?
'编辑农场'
:
'添加农场'
}}
</text>
<text
class=
"subtitle"
>
{{
isEditMode
?
'修改农场信息,完善经营资料'
:
'创建您的农场档案,开启智慧管理'
}}
</text>
</view>
<view
class=
"form-content"
>
<fui-form
ref=
"formRef"
>
<!-- 第一组表单 -->
<view
class=
"form-card"
>
<view
class=
"section-card"
>
<view
class=
"card-header"
>
<view
class=
"line"
></view>
<text>
农场基本信息
</text>
</view>
<fui-input
required
label=
"农场名称"
...
...
@@ -316,24 +310,13 @@ function submit() {
:labelWeight=
"400"
labelWidth=
"auto"
>
<view
class=
"
time
-input"
@
click=
"pageData.show.farmType = true"
>
<view
class=
"
picker
-input"
@
click=
"pageData.show.farmType = true"
>
<text
class=
"select-text"
:class=
"
{ placeholder: !pageData.form.farmTypeText }">
{{
pageData
.
form
.
farmTypeText
||
'请选择农场类型'
}}
</text>
<fui-icon
name=
"arrowright"
:size=
"32"
color=
"#ccc"
></fui-icon>
</view>
</fui-form-item>
<!--
<view
class=
"fui-input-wrapper"
@
click=
"pageData.show.farmType = true"
>
<fui-input
required
readonly
label=
"农场类型"
placeholder=
"请选择农场类型"
v-model=
"pageData.form.farmTypeText"
labelSize=
"28"
:labelWeight=
"400"
labelWidth=
"auto"
/>
</view>
-->
<fui-input
required
labelSize=
"28"
...
...
@@ -354,8 +337,9 @@ function submit() {
label=
"农场主电话"
placeholder=
"请输入农场主电话"
v-model=
"pageData.form.ownerPhone"
readonly
disabled
/>
<!-- 农场简介换行显示 -->
<view
class=
"form-item-block"
>
<view
class=
"form-item-label required"
>
农场简介
</view>
<fui-textarea
...
...
@@ -366,9 +350,11 @@ function submit() {
placeholder=
"请输入农场简介"
v-model=
"pageData.form.farmProfiles"
class=
"block-textarea"
background=
"#f9f9f9"
radius=
"16"
:padding=
"['24rpx','24rpx']"
/>
</view>
<!-- 农场标语 -->
<view
class=
"form-item-block"
>
<view
class=
"form-item-label"
>
农场标语
</view>
<fui-textarea
...
...
@@ -379,12 +365,18 @@ function submit() {
placeholder=
"请输入农场标语"
v-model=
"pageData.form.slogan"
class=
"block-textarea"
background=
"#f9f9f9"
radius=
"16"
:padding=
"['24rpx','24rpx']"
/>
</view>
</view>
<!-- 第二组表单 -->
<view
class=
"form-card"
>
<view
class=
"section-card"
>
<view
class=
"card-header"
>
<view
class=
"line"
></view>
<text>
经营区域信息
</text>
</view>
<fui-form-item
required
asterisk
...
...
@@ -393,24 +385,13 @@ function submit() {
:labelWeight=
"400"
labelWidth=
"auto"
>
<view
class=
"
time
-input"
@
click=
"pageData.show.address = true"
>
<view
class=
"
picker
-input"
@
click=
"pageData.show.address = true"
>
<text
class=
"select-text"
:class=
"
{ placeholder: !pageData.form.provinceText }">
{{
pageData
.
form
.
provinceText
||
'请选择归属地区'
}}
</text>
<fui-icon
name=
"arrowright"
:size=
"32"
color=
"#ccc"
></fui-icon>
</view>
</fui-form-item>
<!--
<view
class=
"fui-input-wrapper"
@
click=
"pageData.show.address = true"
>
<fui-input
required
readonly
labelWidth=
"auto"
labelSize=
"28"
:labelWeight=
"400"
label=
"归属地区"
placeholder=
"请选择归属地区"
:value=
"pageData.form.provinceText"
/>
</view>
-->
<fui-input
required
labelWidth=
"auto"
...
...
@@ -429,24 +410,13 @@ function submit() {
:labelWeight=
"400"
labelWidth=
"auto"
>
<view
class=
"
time
-input"
@
click=
"pageData.show.mainProducts = true"
>
<view
class=
"
picker
-input"
@
click=
"pageData.show.mainProducts = true"
>
<text
class=
"select-text"
:class=
"
{ placeholder: !pageData.form.growCropsText }">
{{
pageData
.
form
.
growCropsText
||
'请选择种植物种'
}}
</text>
<fui-icon
name=
"arrowright"
:size=
"32"
color=
"#ccc"
></fui-icon>
</view>
</fui-form-item>
<!--
<view
class=
"fui-input-wrapper"
@
click=
"pageData.show.mainProducts = true"
>
<fui-input
required
readonly
labelWidth=
"auto"
labelSize=
"28"
:labelWeight=
"400"
label=
"种植物种"
placeholder=
"请选择种植物种"
v-model=
"pageData.form.growCropsText"
/>
</view>
-->
<fui-input
required
size=
"28"
...
...
@@ -459,11 +429,14 @@ function submit() {
/>
</view>
<!-- 第三组表单 - 图片上传 -->
<view
class=
"form-card"
>
<!-- 上传图片换行显示 -->
<view
class=
"section-card"
>
<view
class=
"card-header"
>
<view
class=
"line"
></view>
<text>
农场展示图片
</text>
</view>
<view
class=
"form-item-block"
>
<view
class=
"form-item-label required"
>
示例图片
</view>
<view
class=
"upload-tips"
>
建议上传农场实景照片,展示农场风貌
</view>
<view
class=
"block-upload"
>
<uni-file-picker
ref=
"uploadRef"
...
...
@@ -476,8 +449,8 @@ function submit() {
</view>
</view>
<view
class=
"submit-
btn-box
"
>
<fui-button
:text=
"pageData.form.id ? '保存修改' : '添加
'"
bold
radius=
"96
rpx"
@
click=
"submit"
/>
<view
class=
"submit-
area
"
>
<fui-button
:text=
"pageData.form.id ? '保存修改' : '添加
农场'"
bold
radius=
"100
rpx"
@
click=
"submit"
/>
</view>
</fui-form>
</view>
...
...
@@ -507,105 +480,64 @@ function submit() {
<
style
lang=
"scss"
scoped
>
.page
{
background
:
#e8f5e9
;
min-height
:
100vh
;
background-color
:
#f4f7f5
;
font-family
:
'DingTalk Sans'
,
sans-serif
;
}
.page-container
{
padding
:
28
rpx
;
}
.form-card
{
background-color
:
#ffffff
;
border-radius
:
20
rpx
;
margin-bottom
:
20
rpx
;
padding
:
0
;
overflow
:
hidden
;
box-shadow
:
0
1px
3px
rgba
(
0
,
0
,
0
,
0.05
);
}
.upload-title
{
padding
:
28
rpx
;
font-size
:
28
rpx
;
color
:
#333333
;
font-weight
:
400
;
}
.upload-content
{
padding
:
0
32
rpx
32
rpx
;
}
.submit-btn-box
{
padding
:
32
rpx
0
;
}
:deep
(
.fui-button
)
{
border-color
:
#ff9800
!important
;
background
:
#ff9800
!important
;
}
:deep
(
.fui-input__wrap
),
:deep
(
.fui-textarea__wrap
)
{
padding
:
28
rpx
32
rpx
;
//
border-bottom
:
1px
solid
#e5e5e5
;
}
:deep
(
.fui-input__label
),
:deep
(
.fui-textarea__label
)
{
font-size
:
28
rpx
;
color
:
#333333
;
min-width
:
160
rpx
;
font-weight
:
400
;
}
:deep
(
.fui-input__self
),
:deep
(
.fui-textarea__self
)
{
font-size
:
28
rpx
;
color
:
#333333
;
}
:deep
(
.fui-input__placeholder
),
:deep
(
.fui-textarea__placeholder
)
{
color
:
#d0d0d0
;
font-size
:
28
rpx
;
.form-banner
{
background-color
:
#5db66f
;
padding
:
60
rpx
40
rpx
100
rpx
;
color
:
#fff
;
.title
{
font-size
:
48
rpx
;
font-weight
:
bold
;
display
:
block
;
letter-spacing
:
2
rpx
;
}
.subtitle
{
font-size
:
26
rpx
;
opacity
:
0.9
;
margin-top
:
12
rpx
;
display
:
block
;
}
}
.form-card
:deep
(
.fui-input__wrap
:last-child
),
.form-card
:deep
(
.fui-textarea__wrap
:last-child
)
{
border-bottom
:
none
;
.form-content
{
padding
:
24
rpx
;
margin-top
:
-80
rpx
;
position
:
relative
;
z-index
:
10
;
}
::v-deep
.uni-input-placeholder
{
font-size
:
28
rpx
!important
;
color
:
#999999
!important
;
}
:deep
(
.uni-textarea-placeholder
)
{
font-size
:
28
rpx
!important
;
color
:
#999999
!important
;
}
:deep
(
.fui-button
)
{
width
:
690
rpx
;
border-color
:
#5db66f
!important
;
background
:
#5db66f
!important
;
}
.section-card
{
background-color
:
#fff
;
border-radius
:
28
rpx
;
padding
:
32
rpx
;
margin-bottom
:
28
rpx
;
box-shadow
:
0
8
rpx
20
rpx
rgba
(
0
,
0
,
0
,
0.03
);
//
移除
fui-form
的默认样式
:deep
(
.fui-form
)
{
background
:
transparent
;
.card-header
{
margin-bottom
:
32
rpx
;
display
:
flex
;
align-items
:
center
;
.line
{
width
:
8
rpx
;
height
:
32
rpx
;
background-color
:
#5db66f
;
border-radius
:
4
rpx
;
margin-right
:
16
rpx
;
}
text
{
font-size
:
32
rpx
;
font-weight
:
bold
;
color
:
#1a1a1a
;
}
}
}
:deep
(
.fui-form__item
)
{
background
:
transparent
;
border
:
none
;
margin-bottom
:
0
;
padding
:
0
;
}
:deep
(
.fui-input__border-bottom
)
{
right
:
32
rpx
!important
;
}
.form-item-block
{
padding
:
24
rpx
12
rpx
;
//
border-bottom
:
1px
solid
#e5e5e5
;
padding
:
24
rpx
0
;
&:last-child
{
border-bottom
:
none
;
...
...
@@ -625,14 +557,18 @@ function submit() {
}
}
.upload-tips
{
font-size
:
22
rpx
;
color
:
#ccc
;
margin-bottom
:
20
rpx
;
}
.block-textarea
{
width
:
100%
;
padding
:
0
rpx
12
rpx
!important
;
}
.block-upload
{
width
:
100%
;
padding
:
0
20
rpx
;
:deep(.uni-file-picker__container)
{
background-color
:
#fff
!important
;
border
:
unset
!important
;
...
...
@@ -642,16 +578,86 @@ function submit() {
justify-content
:
left
!important
;
}
}
.picker-input
{
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
padding
:
0
20
rpx
;
width
:
100%
;
}
.select-text
{
font-size
:
28
rpx
;
color
:
#333333
;
padding
:
0
20
rpx
;
flex
:
1
;
&.placeholder
{
color
:
#999999
;
}
}
.fui-input-wrapper
{
cursor
:
pointer
;
.submit-area
{
padding
:
60
rpx
20
rpx
100
rpx
;
:deep(.fui-button)
{
background
:
#5db66f
!important
;
border-color
:
#5db66f
!important
;
box-shadow
:
0
8
rpx
24
rpx
rgba
(
93
,
182
,
111
,
0.3
);
}
}
:deep
(
.fui-form
)
{
background
:
transparent
;
}
:deep
(
.fui-form__item
)
{
background
:
transparent
;
border
:
none
;
margin-bottom
:
0
;
padding
:
0
;
}
:deep
(
.fui-input__wrap
),
:deep
(
.fui-textarea__wrap
)
{
padding
:
28
rpx
0
;
}
:deep
(
.fui-input__label
),
:deep
(
.fui-textarea__label
)
{
font-size
:
28
rpx
;
color
:
#333333
;
min-width
:
160
rpx
;
font-weight
:
400
;
font-family
:
'DingTalk Sans'
,
system-ui
!important
;
}
:deep
(
.fui-input__self
),
:deep
(
.fui-textarea__self
)
{
font-size
:
28
rpx
;
color
:
#333333
;
font-family
:
'DingTalk Sans'
,
system-ui
!important
;
}
:deep
(
.fui-input__placeholder
),
:deep
(
.fui-textarea__placeholder
)
{
color
:
#d0d0d0
;
font-size
:
28
rpx
;
font-family
:
'DingTalk Sans'
!important
;
}
::v-deep
.uni-input-placeholder
{
font-size
:
28
rpx
!important
;
color
:
#999999
!important
;
font-family
:
'DingTalk Sans'
!important
;
}
:deep
(
.uni-textarea-placeholder
)
{
font-size
:
28
rpx
!important
;
color
:
#999999
!important
;
font-family
:
'DingTalk Sans'
!important
;
}
:deep
(
.fui-button
)
{
font-family
:
'DingTalk Sans'
!important
;
font-weight
:
bold
!important
;
}
</
style
>
</
style
>
\ No newline at end of file
src/pages/nongchang/detail/index.vue
浏览文件 @
a62386c0
...
...
@@ -22,13 +22,33 @@
const
page
=
reactive
<
Page
>
({
id
:
'example-mapbox'
,
init
:
false
,
mapInit
:
false
,
loading
:
false
,
mapReady
:
false
,
requests
:
0
,
latest
:
null
,
query
:
{},
})
const
showDialog
=
ref
(
false
)
onHide
(()
=>
{
page
.
init
=
false
page
.
mapInit
=
false
model
.
id
=
''
model
.
name
=
''
model
.
farmbaseInfo
=
{}
model
.
farmbaseInfoList
=
[]
model
.
deviceTypeCount
=
[]
})
onShow
(()
=>
{
// getFarmbaseInfoList()
if
(
!
page
.
init
)
{
if
(
page
.
mapReady
)
{
initMapData
()
}
else
{
refreshPageData
()
}
}
})
const
model
=
reactive
({
...
...
@@ -150,278 +170,250 @@
})
}
// 地图组件
const
[
registerMap
,
map
]
=
useMapbox
({
style
:
{
zoom
:
15
,
isImg
:
true
},
onLoaded
:
async
(
data
)
=>
{
console
.
log
(
'✨✨✨ Map Loaded'
,
data
)
async
function
fetchFarmInfo
()
{
const
res
=
await
NongchangAPI
.
farmsList
()
if
(
!
res
.
records
||
res
.
records
.
length
===
0
)
{
throw
new
Error
(
'未查询到农场信息'
)
}
return
res
.
records
[
0
]
}
// 查询农场数据
const
res
=
await
NongchangAPI
.
farmsList
()
async
function
fetchFarmbaseList
(
farmId
:
string
)
{
const
res
=
await
farmbaseApi
.
list
({
farmId
})
return
res
.
records
||
[]
}
if
(
!
res
.
records
||
res
.
records
.
length
===
0
)
{
Message
.
toast
(
'未查询到农场信息'
)
return
}
async
function
refreshPageData
()
{
if
(
page
.
init
)
return
// 获取第一个农场信息
const
item
=
res
.
records
?.[
0
]
try
{
const
item
=
await
fetchFarmInfo
()
model
.
id
=
item
.
id
model
.
name
=
item
.
farmName
model
.
description
=
item
.
description
// 设置页面标题
uni
.
setNavigationBarTitle
({
title
:
item
.
farmName
,
})
uni
.
setNavigationBarTitle
({
title
:
item
.
farmName
})
// 渲染农场和基地地块数据
let
farmGeojson
=
item
.
geojson
// geojson 可能是字符串,需要解析
if
(
typeof
farmGeojson
===
'string'
)
{
const
farmbaseRecords
=
await
fetchFarmbaseList
(
model
.
id
)
model
.
farmbaseInfoList
=
farmbaseRecords
if
(
farmbaseRecords
.
length
>
0
)
{
model
.
farmbaseInfo
=
farmbaseRecords
[
0
]
}
getDeviceTypeCount
()
page
.
init
=
true
}
catch
(
error
)
{
Message
.
toast
(
error
.
message
||
'数据加载失败'
)
}
}
const
colorPool
=
[
{
fill
:
'#e74c3c'
,
line
:
'#e74c3c'
},
{
fill
:
'#3498db'
,
line
:
'#3498db'
},
{
fill
:
'#2ecc71'
,
line
:
'#2ecc71'
},
{
fill
:
'#f1c40f'
,
line
:
'#f1c40f'
},
{
fill
:
'#9b59b6'
,
line
:
'#9b59b6'
},
{
fill
:
'#e67e22'
,
line
:
'#e67e22'
},
{
fill
:
'#1abc9c'
,
line
:
'#1abc9c'
},
{
fill
:
'#e91e63'
,
line
:
'#e91e63'
},
]
function
renderFarmLayers
(
item
:
any
,
farmGeojson
:
any
)
{
if
(
!
farmGeojson
)
{
console
.
warn
(
'农场没有 geojson 数据'
)
return
}
const
farmFeatures
=
farmGeojson
.
features
?
farmGeojson
.
features
:
[
farmGeojson
]
for
(
const
feature
of
farmFeatures
)
{
feature
.
properties
=
feature
.
properties
||
{}
feature
.
properties
.
farmName
=
item
.
farmName
}
addDefaultGeoJSONSource
(
map
,
`
${
page
.
id
}
-farm-plot`
,
farmFeatures
)
map
.
addLayer
({
type
:
'fill'
,
id
:
`
${
page
.
id
}
-farm-plot-fill`
,
source
:
`
${
page
.
id
}
-farm-plot`
,
paint
:
{
'fill-color'
:
'#5db66f'
,
'fill-opacity'
:
0.2
,
'fill-outline-color'
:
'#5db66f'
,
},
})
map
.
addLayer
({
type
:
'line'
,
id
:
`
${
page
.
id
}
-farm-plot-line`
,
source
:
`
${
page
.
id
}
-farm-plot`
,
layout
:
{
'line-join'
:
'round'
,
'line-cap'
:
'round'
},
paint
:
{
'line-color'
:
'#5db66f'
,
'line-width'
:
4
},
})
}
function
renderBaseLayers
(
farmbaseRecords
:
any
[])
{
for
(
let
i
=
0
;
i
<
farmbaseRecords
.
length
;
i
++
)
{
const
base
=
farmbaseRecords
[
i
]
let
geojson
=
base
.
geojson
if
(
typeof
geojson
===
'string'
)
{
try
{
farmGeojson
=
JSON
.
parse
(
farmG
eojson
)
geojson
=
JSON
.
parse
(
g
eojson
)
}
catch
(
e
)
{
console
.
error
(
'解析农场 geojson 失败:'
,
e
)
farmGeojson
=
null
console
.
error
(
`解析基地
${
base
.
baseName
}
geojson 失败:`
,
e
)
continue
}
}
if
(
farmGeojson
)
{
const
farmFeatures
=
farmGeojson
.
features
?
farmGeojson
.
features
:
[
farmGeojson
]
// 注入农场名称到每个 feature
for
(
const
feature
of
farmFeatures
)
{
feature
.
properties
=
feature
.
properties
||
{}
feature
.
properties
.
farmName
=
item
.
farmName
}
addDefaultGeoJSONSource
(
map
,
`
${
page
.
id
}
-farm-plot`
,
farmFeatures
)
// 添加农场填充层
map
.
addLayer
({
type
:
'fill'
,
id
:
`
${
page
.
id
}
-farm-plot-fill`
,
source
:
`
${
page
.
id
}
-farm-plot`
,
paint
:
{
'fill-color'
:
'#5db66f'
,
'fill-opacity'
:
0.2
,
'fill-outline-color'
:
'#5db66f'
,
},
})
map
.
addLayer
({
type
:
'line'
,
id
:
`
${
page
.
id
}
-farm-plot-line`
,
source
:
`
${
page
.
id
}
-farm-plot`
,
layout
:
{
'line-join'
:
'round'
,
'line-cap'
:
'round'
,
},
paint
:
{
'line-color'
:
'#5db66f'
,
'line-width'
:
4
,
},
})
// 添加农场名称文字标签(已禁用)
// map.addLayer({
// type: 'symbol',
// id: `${page.id}-farm-label`,
// source: `${page.id}-farm-plot`,
// layout: {
// 'text-field': ['get', 'farmName'],
// 'text-size': 16,
// 'text-anchor': 'center',
// 'text-allow-overlap': true,
// },
// paint: {
// 'text-color': '#ffffff',
// 'text-halo-color': '#5db66f',
// 'text-halo-width': 2,
// },
// })
}
else
{
console
.
warn
(
'农场没有 geojson 数据, item:'
,
JSON
.
stringify
(
item
)?.
substring
(
0
,
500
))
if
(
!
geojson
)
continue
const
color
=
colorPool
[
i
%
colorPool
.
length
]
const
sourceId
=
`
${
page
.
id
}
-base-plot-
${
base
.
id
}
`
const
features
=
geojson
.
features
?
geojson
.
features
:
[
geojson
]
for
(
const
feature
of
features
)
{
feature
.
properties
=
feature
.
properties
||
{}
feature
.
properties
.
baseName
=
base
.
baseName
}
// 查询农场基地信息
const
farmbaseRes
=
await
farmbaseApi
.
list
({
farmId
:
model
.
id
})
const
farmbaseRecords
=
farmbaseRes
.
records
||
[]
model
.
farmbaseInfoList
=
farmbaseRecords
addDefaultGeoJSONSource
(
map
,
sourceId
,
features
)
// 预定义颜色池(每个基地循环使用)
const
colorPool
=
[
{
fill
:
'#e74c3c'
,
line
:
'#e74c3c'
},
// 红
{
fill
:
'#3498db'
,
line
:
'#3498db'
},
// 蓝
{
fill
:
'#2ecc71'
,
line
:
'#2ecc71'
},
// 绿
{
fill
:
'#f1c40f'
,
line
:
'#f1c40f'
},
// 黄
{
fill
:
'#9b59b6'
,
line
:
'#9b59b6'
},
// 紫
{
fill
:
'#e67e22'
,
line
:
'#e67e22'
},
// 橙
{
fill
:
'#1abc9c'
,
line
:
'#1abc9c'
},
// 青
{
fill
:
'#e91e63'
,
line
:
'#e91e63'
},
// 粉
]
map
.
addLayer
({
type
:
'fill'
,
id
:
`
${
sourceId
}
-fill`
,
source
:
sourceId
,
paint
:
{
'fill-color'
:
color
.
fill
,
'fill-opacity'
:
0.5
,
'fill-outline-color'
:
color
.
line
,
},
})
// 为每个基地创建独立的 source 和 layer
for
(
let
i
=
0
;
i
<
farmbaseRecords
.
length
;
i
++
)
{
const
base
=
farmbaseRecords
[
i
]
let
geojson
=
base
.
geojson
// geojson 可能是字符串,需要解析
if
(
typeof
geojson
===
'string'
)
{
try
{
geojson
=
JSON
.
parse
(
geojson
)
}
catch
(
e
)
{
console
.
error
(
`解析基地
${
base
.
baseName
}
geojson 失败:`
,
e
)
continue
}
}
map
.
addLayer
({
type
:
'line'
,
id
:
`
${
sourceId
}
-line`
,
source
:
sourceId
,
layout
:
{
'line-join'
:
'round'
,
'line-cap'
:
'round'
},
paint
:
{
'line-color'
:
color
.
line
,
'line-width'
:
3
},
})
if
(
!
geojson
)
continue
map
.
addLayer
({
type
:
'symbol'
,
id
:
`
${
sourceId
}
-label`
,
source
:
sourceId
,
layout
:
{
'text-field'
:
[
'get'
,
'baseName'
],
'text-size'
:
14
,
'text-anchor'
:
'center'
,
'text-offset'
:
[
0
,
0
],
'text-allow-overlap'
:
true
,
},
paint
:
{
'text-color'
:
'#ffffff'
,
'text-halo-color'
:
color
.
line
,
'text-halo-width'
:
2
,
},
})
}
}
// 为当前基地分配颜色
const
color
=
colorPool
[
i
%
colorPool
.
length
]
const
sourceId
=
`
${
page
.
id
}
-base-plot-
${
base
.
id
}
`
const
fillLayerId
=
`
${
sourceId
}
-fill`
const
lineLayerId
=
`
${
sourceId
}
-line`
const
labelLayerId
=
`
${
sourceId
}
-label`
function
flyToBaseCenter
(
firstBase
:
any
)
{
let
firstGeojson
=
firstBase
.
geojson
if
(
typeof
firstGeojson
===
'string'
)
{
try
{
firstGeojson
=
JSON
.
parse
(
firstGeojson
)
}
catch
(
e
)
{
firstGeojson
=
null
}
}
// 处理 geojson,注入基地名称属性
const
features
=
geojson
.
features
?
geojson
.
features
:
[
geojson
]
for
(
const
feature
of
features
)
{
feature
.
properties
=
feature
.
properties
||
{}
feature
.
properties
.
baseName
=
base
.
baseName
if
(
firstGeojson
)
{
const
coords
=
firstGeojson
.
features
?.[
0
]?.
geometry
?.
coordinates
?.[
0
]
if
(
coords
&&
coords
.
length
>
0
)
{
let
minLon
=
Number
.
POSITIVE_INFINITY
let
minLat
=
Number
.
POSITIVE_INFINITY
let
maxLon
=
Number
.
NEGATIVE_INFINITY
let
maxLat
=
Number
.
NEGATIVE_INFINITY
for
(
const
c
of
coords
)
{
if
(
c
[
0
]
<
minLon
)
minLon
=
c
[
0
]
if
(
c
[
0
]
>
maxLon
)
maxLon
=
c
[
0
]
if
(
c
[
1
]
<
minLat
)
minLat
=
c
[
1
]
if
(
c
[
1
]
>
maxLat
)
maxLat
=
c
[
1
]
}
const
center
:
[
number
,
number
]
=
[(
minLon
+
maxLon
)
/
2
,
(
minLat
+
maxLat
)
/
2
]
baseCenterLonLat
.
value
=
center
map
.
flyTo
({
center
,
zoom
:
15
,
duration
:
0
})
}
}
else
if
(
firstBase
.
longitude
&&
firstBase
.
latitude
)
{
const
center
:
[
number
,
number
]
=
[
Number
(
firstBase
.
longitude
),
Number
(
firstBase
.
latitude
)]
baseCenterLonLat
.
value
=
center
map
.
flyTo
({
center
,
zoom
:
15
,
duration
:
0
})
}
}
// 添加 source
addDefaultGeoJSONSource
(
map
,
sourceId
,
features
)
// 添加填充层(直接创建,不使用 addDefaultSplotLayer)
map
.
addLayer
({
type
:
'fill'
,
id
:
fillLayerId
,
source
:
sourceId
,
paint
:
{
'fill-color'
:
color
.
fill
,
'fill-opacity'
:
0.5
,
'fill-outline-color'
:
color
.
line
,
},
})
async
function
initMapData
()
{
if
(
page
.
mapInit
)
return
// 添加边框层
map
.
addLayer
({
type
:
'line'
,
id
:
lineLayerId
,
source
:
sourceId
,
layout
:
{
'line-join'
:
'round'
,
'line-cap'
:
'round'
,
},
paint
:
{
'line-color'
:
color
.
line
,
'line-width'
:
3
,
},
})
try
{
page
.
loading
=
true
// 添加基地名称文字标签
map
.
addLayer
({
type
:
'symbol'
,
id
:
labelLayerId
,
source
:
sourceId
,
layout
:
{
'text-field'
:
[
'get'
,
'baseName'
],
'text-size'
:
14
,
'text-anchor'
:
'center'
,
'text-offset'
:
[
0
,
0
],
'text-allow-overlap'
:
true
,
},
paint
:
{
'text-color'
:
'#ffffff'
,
'text-halo-color'
:
color
.
line
,
'text-halo-width'
:
2
,
},
})
}
const
item
=
await
fetchFarmInfo
()
model
.
id
=
item
.
id
model
.
name
=
item
.
farmName
model
.
description
=
item
.
description
// 将地图视角飞到第一个基地的上方
if
(
farmbaseRecords
.
length
>
0
)
{
const
firstBase
=
farmbaseRecords
[
0
]
model
.
farmbaseInfo
=
firstBase
let
firstGeojson
=
firstBase
.
geojson
if
(
typeof
firstGeojson
===
'string'
)
{
try
{
firstGeojson
=
JSON
.
parse
(
firstGeojson
)
}
catch
(
e
)
{
firstGeojson
=
null
}
}
if
(
firstGeojson
)
{
const
coords
=
firstGeojson
.
features
?.[
0
]?.
geometry
?.
coordinates
?.[
0
]
if
(
coords
&&
coords
.
length
>
0
)
{
let
minLon
=
Number
.
POSITIVE_INFINITY
let
minLat
=
Number
.
POSITIVE_INFINITY
let
maxLon
=
Number
.
NEGATIVE_INFINITY
let
maxLat
=
Number
.
NEGATIVE_INFINITY
for
(
const
c
of
coords
)
{
if
(
c
[
0
]
<
minLon
)
minLon
=
c
[
0
]
if
(
c
[
0
]
>
maxLon
)
maxLon
=
c
[
0
]
if
(
c
[
1
]
<
minLat
)
minLat
=
c
[
1
]
if
(
c
[
1
]
>
maxLat
)
maxLat
=
c
[
1
]
}
const
center
:
[
number
,
number
]
=
[(
minLon
+
maxLon
)
/
2
,
(
minLat
+
maxLat
)
/
2
]
baseCenterLonLat
.
value
=
center
map
.
flyTo
({
center
,
zoom
:
15
,
duration
:
0
,
})
}
}
else
if
(
firstBase
.
longitude
&&
firstBase
.
latitude
)
{
const
center
:
[
number
,
number
]
=
[
Number
(
firstBase
.
longitude
),
Number
(
firstBase
.
latitude
)]
baseCenterLonLat
.
value
=
center
map
.
flyTo
({
center
,
zoom
:
15
,
duration
:
0
,
})
uni
.
setNavigationBarTitle
({
title
:
item
.
farmName
})
let
farmGeojson
=
item
.
geojson
if
(
typeof
farmGeojson
===
'string'
)
{
try
{
farmGeojson
=
JSON
.
parse
(
farmGeojson
)
}
catch
(
e
)
{
console
.
error
(
'解析农场 geojson 失败:'
,
e
)
farmGeojson
=
null
}
}
getDeviceTypeCount
(
)
renderFarmLayers
(
item
,
farmGeojson
)
// 如果农场没有 geojson 但有坐标,则使用坐标定位
if
(
!
farmGeojson
&&
item
.
longitude
&&
item
.
latitude
)
{
model
.
lonlat
=
`
${
item
.
longitude
}
,
${
item
.
latitude
}
`
}
else
if
(
!
farmGeojson
&&
!
item
.
longitude
)
{
model
.
lonlat
=
'111.024108, 29.554847'
Message
.
toast
(
'未设置农场坐标位置,已使用模拟位置数据'
)
}
const
farmbaseRecords
=
await
fetchFarmbaseList
(
model
.
id
)
model
.
farmbaseInfoList
=
farmbaseRecords
// 渲染设备数据
renderBaseLayers
(
farmbaseRecords
)
// 渲染设备数据
model
.
devices
=
[
turf
.
point
([
111.024108
,
29.554847
],
{
name
:
'设备1'
,
description
:
'设备1描述'
,
icon
:
'GD'
,
popup
:
`{{name}}`
,
}),
turf
.
point
([
111.023139
,
29.55539
],
{
name
:
'设备2'
,
description
:
'设备2描述'
,
icon
:
'JCD'
,
popup
:
`{{name}}`
,
}),
turf
.
point
([
111.024989
,
29.555435
],
{
name
:
'设备3'
,
description
:
'设备3描述'
,
icon
:
'BZ'
,
popup
:
`{{name}}`
,
}),
turf
.
point
([
111.024108
,
29.554847
],
{
name
:
'设备1'
,
description
:
'设备1描述'
,
icon
:
'GD'
,
popup
:
'{{name}}'
}),
turf
.
point
([
111.023139
,
29.55539
],
{
name
:
'设备2'
,
description
:
'设备2描述'
,
icon
:
'JCD'
,
popup
:
'{{name}}'
}),
turf
.
point
([
111.024989
,
29.555435
],
{
name
:
'设备3'
,
description
:
'设备3描述'
,
icon
:
'BZ'
,
popup
:
'{{name}}'
}),
]
addDefaultGeoJSONSource
(
map
,
`
${
page
.
id
}
-symbol`
,
model
.
devices
)
addDefaultSymbolLayer
(
map
,
`
${
page
.
id
}
-symbol`
,
{
layout
:
{
'text-field'
:
''
,
'icon-image'
:
[
'get'
,
'icon'
],
'icon-size'
:
1
,
},
layout
:
{
'text-field'
:
''
,
'icon-image'
:
[
'get'
,
'icon'
],
'icon-size'
:
1
},
})
if
(
farmbaseRecords
.
length
>
0
)
{
model
.
farmbaseInfo
=
farmbaseRecords
[
0
]
flyToBaseCenter
(
farmbaseRecords
[
0
])
}
getDeviceTypeCount
()
page
.
init
=
true
page
.
mapInit
=
true
}
catch
(
error
)
{
Message
.
toast
(
error
.
message
||
'数据加载失败'
)
}
finally
{
page
.
loading
=
false
}
}
const
[
registerMap
,
map
]
=
useMapbox
({
style
:
{
zoom
:
15
,
isImg
:
true
},
onLoaded
:
async
(
data
)
=>
{
console
.
log
(
'✨✨✨ Map Loaded'
,
data
)
page
.
mapReady
=
true
await
initMapData
()
},
onSourceRequestHandle
:
()
=>
{
page
.
requests
--
...
...
@@ -519,6 +511,11 @@
function
onBackClick
()
{
uni
.
navigateBack
({
delta
:
1
,
fail
:
()
=>
{
uni
.
switchTab
({
url
:
'/pages/nongchang/nongchang'
})
}
})
}
...
...
@@ -679,7 +676,7 @@
</view>
</view>
</view>
<view
class=
"box-3"
>
<view
class=
"box-3"
v-if=
"model.farmbaseInfoList && model.farmbaseInfoList.length > 0"
>
<!-- 基地切换 -->
<view
class=
"box-3-tags"
>
<view
...
...
@@ -693,7 +690,7 @@
</view>
</view>
</view>
<view
class=
"box-3-info"
>
<view
class=
"box-3-info"
v-if=
"model.farmbaseInfo && model.farmbaseInfo.id"
>
<view
class=
"box-3-info-item"
>
<view
class=
"box-3-info-item-text-box"
>
<text
class=
"box-3-info-item-text1"
>
总面积:
</text>
...
...
@@ -728,12 +725,12 @@
</view>
</view>
</view>
<view
class=
"box-4"
>
<view
class=
"box-4"
v-if=
"model.farmbaseInfoList && model.farmbaseInfoList.length > 0"
>
<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>
<view
class=
"box-4-device"
>
<view
class=
"box-4-device"
v-if=
"model.deviceTypeCount && model.deviceTypeCount.length > 0"
>
<view
class=
"box-4-device-item"
v-for=
"(device, index) in model.deviceTypeCount"
...
...
@@ -752,6 +749,9 @@
</view>
</view>
</view>
<view
class=
"box-4-empty"
v-else
>
<text
class=
"empty-text"
>
暂无设备数据
</text>
</view>
</view>
</view>
</view>
...
...
@@ -1207,6 +1207,20 @@
}
}
}
.box-4-empty
{
width
:
100%
;
padding
:
60
rpx
0
;
text-align
:
center
;
background-color
:
#fff
;
border-radius
:
18
rpx
;
margin-top
:
10
rpx
;
.empty-text
{
font-size
:
28
rpx
;
color
:
#999
;
}
}
}
}
}
...
...
src/pages/nongchang/nongchang.vue
浏览文件 @
a62386c0
<
script
setup
lang=
"ts"
>
import
{
reactive
}
from
'vue'
import
{
reactive
,
getCurrentInstance
}
from
'vue'
import
{
onShow
}
from
'@dcloudio/uni-app'
const
instance
=
getCurrentInstance
()
// import WeatherForecast from './components/WeatherForecast.vue'
import
dayjs
from
'dayjs'
import
Navigate
from
'@/utils/page/navigate'
...
...
@@ -454,7 +456,7 @@
pageData
.
agricultureClass
.
videoList
.
forEach
((
_
,
index
)
=>
{
if
(
index
!==
currentIndex
)
{
try
{
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
)
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
,
instance
.
proxy
)
videoContext
.
pause
()
}
catch
(
error
)
{
console
.
log
(
'停止视频失败:'
,
error
)
...
...
@@ -469,7 +471,7 @@
}
function
playVideo
(
index
)
{
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
)
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
,
instance
.
proxy
)
videoContext
.
requestFullScreen
({
direction
:
0
})
videoContext
.
play
()
}
...
...
@@ -477,7 +479,7 @@
function
handleFullscreenChange
(
e
:
any
,
index
)
{
console
.
log
(
`视频
${
index
}
全屏状态改变`
)
if
(
!
e
.
detail
.
fullScreen
)
{
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
)
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
,
instance
.
proxy
)
videoContext
.
pause
()
}
}
...
...
@@ -494,12 +496,10 @@
}
onHide
(()
=>
{
// 停止所有其他视频的播放(只暂停,不重置位置)
pageData
.
agricultureClass
.
videoList
.
forEach
((
_
,
index
)
=>
{
try
{
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
)
const
videoContext
=
uni
.
createVideoContext
(
`video
${
index
}
`
,
instance
.
proxy
)
videoContext
.
pause
()
// 不重置到开头,保留播放位置
}
catch
(
error
)
{
console
.
log
(
'停止视频失败:'
,
error
)
}
...
...
src/pages/shouye/shouye.vue
浏览文件 @
a62386c0
...
...
@@ -15,6 +15,7 @@ import { useUserStore } from '@/store/modules/user'
const
userStore
=
useUserStore
()
const
dictStore
=
useDictStore
()
const
instance
=
getCurrentInstance
()
const
model
=
reactive
({
// 湖南省人民政府
location
:
'112.982931,28.116698'
,
...
...
@@ -452,7 +453,7 @@ function handleVideoPause(currentIndex) {
function handleFullscreenChange(e: any, index) {
console.log(`
视频
$
{
index
}
全屏状态改变
`)
if (!e.detail.fullScreen) {
const videoContext = uni.createVideoContext(`
video$
{
index
}
`)
const videoContext = uni.createVideoContext(`
video$
{
index
}
`
, instance.proxy
)
videoContext.pause()
}
}
...
...
@@ -473,14 +474,14 @@ function handleMetadataLoaded(e: any,video:any) {
function handleVideoPlay(currentIndex) {
pageData.agricultureClass.videoList.forEach((_, index) => {
if (index !== currentIndex) {
const videoContext = uni.createVideoContext(`
video$
{
index
}
`)
const videoContext = uni.createVideoContext(`
video$
{
index
}
`
, instance.proxy
)
videoContext.pause()
}
})
}
function playVideo(index) {
const videoContext = uni.createVideoContext(`
video$
{
index
}
`)
const videoContext = uni.createVideoContext(`
video$
{
index
}
`
, instance.proxy
)
videoContext.requestFullScreen({ direction: 0 })
videoContext.play()
}
...
...
@@ -508,21 +509,16 @@ function toNewsDetail(item) {
}
onHide(() => {
// 停止所有其他视频的播放(只暂停,不重置位置)
pageData.agricultureClass.videoList.forEach((_, index) => {
try {
const videoContext = uni.createVideoContext(`
video$
{
index
}
`)
const videoContext = uni.createVideoContext(`
video$
{
index
}
`
, instance.proxy
)
videoContext.pause()
// 不重置到开头,保留播放位置
} catch (error) {
console.log('停止视频失败:', error)
}
})
})
// 引入实例
const instance = getCurrentInstance();
const getDomDataSetFunc = (domName='',datasetName='index') =>{
return new Promise((resolve,reject)=>{
const queryDataget = uni.createSelectorQuery().in(instance.proxy);
...
...
@@ -717,9 +713,9 @@ export default {
</view>
<view
class=
"codefun-flex-row section_5"
>
<view
v-show=
"item.status"
v-for=
"item in pageData.serviceItems"
:key=
"item.id"
class=
"codefun-flex-col codefun-items-center group_10
mt-5
"
@
click=
"onMenuItemClick(item)"
>
class=
"codefun-flex-col codefun-items-center group_10"
@
click=
"onMenuItemClick(item)"
>
<image
class=
"image_11"
:src=
"item.icon_url"
/>
<text
class=
"font_2 mt-
11
"
>
{{
item
.
name
}}
</text>
<text
class=
"font_2 mt-
3
"
>
{{
item
.
name
}}
</text>
</view>
</view>
<swiper
:autoplay=
"true"
:interval=
"5000"
:duration=
"500"
:circular=
"true"
:vertical=
"true"
...
...
@@ -1164,7 +1160,8 @@ export default {
}
.group_10
{
margin-bottom
:
15
rpx
;
margin-top
:
5
rpx
;
margin-bottom
:
18
rpx
;
flex
:
1
1
173.5
rpx
;
.text_50
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论