提交 258ed913 作者: 宇宙超人

样式修改

上级 ab875674
...@@ -31,6 +31,20 @@ export default { ...@@ -31,6 +31,20 @@ export default {
return return
} }
// 处理tooltip formatter函数序列化问题
if (option.tooltip && option.tooltip.formatter) {
const formatterStr = option.tooltip.formatter
if (typeof formatterStr === 'string') {
try {
// 使用eval在视图层重新构建函数
// 支持箭头函数和普通函数
option.tooltip.formatter = eval('(' + formatterStr + ')')
} catch (e) {
// renderjs视图层不支持console,静默处理错误
}
}
}
this.option = merge(this.option, option) this.option = merge(this.option, option)
if (typeof window.echarts === 'object' && typeof window.echarts.init === 'function') { if (typeof window.echarts === 'object' && typeof window.echarts.init === 'function') {
this.init() this.init()
...@@ -40,5 +54,16 @@ export default { ...@@ -40,5 +54,16 @@ export default {
}) })
} }
}, },
// 添加update方法,在这里重新定义tooltip的formatter
update() {
// 确保图表实例存在
if (this.chart) {
// 重新设置option,确保tooltip formatter正确绑定
if (this.option && this.option.tooltip && typeof this.option.tooltip.formatter === 'function') {
// 重新绑定formatter函数
this.chart.setOption(this.option, true);
}
}
}
}, },
} }
\ No newline at end of file
...@@ -15,6 +15,12 @@ ...@@ -15,6 +15,12 @@
}, },
methods: { methods: {
setOption(option) { setOption(option) {
// 处理tooltip formatter函数序列化
if (option.tooltip && typeof option.tooltip.formatter === 'function') {
// 将函数转换为字符串,在视图层重新构建
option.tooltip.formatter = option.tooltip.formatter.toString()
}
this.option = { this.option = {
id: this.id, id: this.id,
...option, ...option,
......
...@@ -80,8 +80,8 @@ export function useMapbox<T extends MapboxInstance, P extends MapboxConfig>( ...@@ -80,8 +80,8 @@ export function useMapbox<T extends MapboxInstance, P extends MapboxConfig>(
getInstance()?.setLayoutProperty(layerId, name, value), getInstance()?.setLayoutProperty(layerId, name, value),
setFilter: (layerId: string, filter: any[]) => getInstance()?.setFilter(layerId, filter), setFilter: (layerId: string, filter: any[]) => getInstance()?.setFilter(layerId, filter),
flyTo: (options: mapboxgl.FlyToOptions) => getInstance()?.flyTo(options), flyTo: (options: mapboxgl.FlyToOptions) => getInstance()?.flyTo(options),
addMarker: (id: string, lnglat: [number, number], popup?: string, popupDefaultOpen?: boolean) => addMarker: (id: string, lnglat: [number, number], popup?: string, popupDefaultOpen?: boolean, imageUrl?: string, iconSize?: [number, number]) =>
getInstance()?.addMarker(id, lnglat, popup, popupDefaultOpen), getInstance()?.addMarker(id, lnglat, popup, popupDefaultOpen, imageUrl, iconSize),
removeMarker: (id: string) => getInstance()?.removeMarker(id), removeMarker: (id: string) => getInstance()?.removeMarker(id),
removePopup: () => getInstance()?.removePopup(), removePopup: () => getInstance()?.removePopup(),
loadImage: (url: string, callback: (error: Error | null, image: HTMLImageElement) => void) => loadImage: (url: string, callback: (error: Error | null, image: HTMLImageElement) => void) =>
......
...@@ -828,9 +828,11 @@ export interface MapboxInstance { ...@@ -828,9 +828,11 @@ export interface MapboxInstance {
* @param lngLat 经纬度 * @param lngLat 经纬度
* @param popup 弹窗内容 * @param popup 弹窗内容
* @param popupDefaultOpen 是否默认打开弹窗 * @param popupDefaultOpen 是否默认打开弹窗
* @param imageUrl 自定义图标图片URL
* @param iconSize 图标大小 [width, height]
* @link https://docs.mapbox.com/mapbox-gl-js/api/markers/#marker * @link https://docs.mapbox.com/mapbox-gl-js/api/markers/#marker
*/ */
addMarker(id: string, lngLat: number[], popup?: string, popupDefaultOpen?: boolean): void addMarker(id: string, lngLat: number[], popup?: string, popupDefaultOpen?: boolean, imageUrl?: string, iconSize?: [number, number]): void
/** /**
* 移除 Marker * 移除 Marker
* @param id Marker ID * @param id Marker ID
......
...@@ -372,7 +372,7 @@ ...@@ -372,7 +372,7 @@
this.tryTriggerChange() this.tryTriggerChange()
}, },
addMarker(id, lngLat, popup, popupDefaultOpen) { addMarker(id, lngLat, popup, popupDefaultOpen, imageUrl, iconSize) {
// 加入到 change 事件队列中 // 加入到 change 事件队列中
this.changeOptionsQueue.push({ this.changeOptionsQueue.push({
fn: 'addMarker', fn: 'addMarker',
...@@ -380,6 +380,8 @@ ...@@ -380,6 +380,8 @@
lngLat, lngLat,
popup, popup,
popupDefaultOpen, popupDefaultOpen,
imageUrl,
iconSize,
}) })
// 尝试触发 change 事件 // 尝试触发 change 事件
......
...@@ -73,6 +73,18 @@ window.onPopupContentEventHandle = function (e) { ...@@ -73,6 +73,18 @@ window.onPopupContentEventHandle = function (e) {
} }
} }
// 全局暴露 navigateToDetail 方法,供 popup 中的按钮调用
window.navigateToDetail = function (data) {
if ($vm) {
// 调用逻辑层方法,通过 onEventHandle 传递事件
$vm.$ownerInstance.callMethod('onEventHandle', {
type: 'custom',
name: 'navigateToDetail',
data,
})
}
}
const defaultEmptyGeoJSON = { const defaultEmptyGeoJSON = {
type: 'FeatureCollection', type: 'FeatureCollection',
features: [], features: [],
...@@ -543,12 +555,32 @@ export default { ...@@ -543,12 +555,32 @@ export default {
}, },
changeAddMarkerOptions(options) { changeAddMarkerOptions(options) {
if (this.checkOnChangeValidity(options)) { if (this.checkOnChangeValidity(options)) {
const { id, lngLat, popup, popupDefaultOpen, ...rest } = options const { id, lngLat, popup, popupDefaultOpen, element, imageUrl, iconSize, ...rest } = options
if (this.markers[id]) { if (this.markers[id]) {
this.markers[id].remove() this.markers[id].remove()
} }
const marker = new window.mapboxgl.Marker({ scale: 0.8, ...rest }).setLngLat(lngLat).addTo(this.map) let markerElement = element
// 如果提供了图片URL,创建自定义元素
if (imageUrl && !element) {
markerElement = document.createElement('div')
markerElement.className = 'custom-marker'
markerElement.style.backgroundImage = `url(${imageUrl})`
markerElement.style.width = iconSize ? `${iconSize[0]}px` : '40px'
markerElement.style.height = iconSize ? `${iconSize[1]}px` : '40px'
markerElement.style.backgroundSize = 'cover'
markerElement.style.borderRadius = '50%'
markerElement.style.cursor = 'pointer'
markerElement.style.border = '2px solid white'
markerElement.style.boxShadow = '0 2px 8px rgba(0,0,0,0.3)'
}
// 如果有自定义元素,使用它;否则使用默认配置
const marker = markerElement
? new window.mapboxgl.Marker(markerElement).setLngLat(lngLat).addTo(this.map)
: new window.mapboxgl.Marker({ scale: 0.8, ...rest }).setLngLat(lngLat).addTo(this.map)
if (popup) { if (popup) {
const popupComponent = new window.mapboxgl.Popup({ options: { closeButton: true } }).setHTML(popup) const popupComponent = new window.mapboxgl.Popup({ options: { closeButton: true } }).setHTML(popup)
marker.setPopup(popupComponent) marker.setPopup(popupComponent)
......
...@@ -3,6 +3,13 @@ ...@@ -3,6 +3,13 @@
function onApplyClick() { function onApplyClick() {
Message.alert('申请功能暂不可用,敬请期待~', '温馨提示') Message.alert('申请功能暂不可用,敬请期待~', '温馨提示')
} }
// 查看大图
function onViewImage(imageUrl) {
uni.previewImage({
urls: [imageUrl]
})
}
</script> </script>
<template> <template>
...@@ -167,11 +174,13 @@ ...@@ -167,11 +174,13 @@
<view class="codefun-mt-18 codefun-flex-row equal-division_2"> <view class="codefun-mt-18 codefun-flex-row equal-division_2">
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-center image-wrapper equal-division-item_2" class="codefun-flex-col codefun-justify-start codefun-items-center image-wrapper equal-division-item_2"
@click="onViewImage('/static/images/codefun/e10c098c837a0091dfe41ecd14dbaff5.png')"
> >
<image class="image_7" src="/static/images/codefun/e10c098c837a0091dfe41ecd14dbaff5.png" /> <image class="image_7" src="/static/images/codefun/e10c098c837a0091dfe41ecd14dbaff5.png" />
</view> </view>
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-center image-wrapper equal-division-item_2 ml-15" class="codefun-flex-col codefun-justify-start codefun-items-center image-wrapper equal-division-item_2 ml-15"
@click="onViewImage('/static/images/codefun/7ad157344b66cce4731d077aa759c0f9.png')"
> >
<image class="image_7" src="/static/images/codefun/7ad157344b66cce4731d077aa759c0f9.png" /> <image class="image_7" src="/static/images/codefun/7ad157344b66cce4731d077aa759c0f9.png" />
</view> </view>
......
<!-- 农场详情 --> <!-- 农场详情 -->
<script setup lang="ts"> <script setup lang="ts">
import RegisterDialog from './register-dialog.vue'
import * as turf from '@turf/turf' import * as turf from '@turf/turf'
import type { Page } from './config' import type { Page } from './config'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
...@@ -56,6 +57,12 @@ const model = reactive({ ...@@ -56,6 +57,12 @@ const model = reactive({
longitude: uni.getStorageSync('location').lon, longitude: uni.getStorageSync('location').lon,
latitude: uni.getStorageSync('location').lat, latitude: uni.getStorageSync('location').lat,
}, },
// 选中的用工信息
selectedEmployment: null,
showEmploymentPopup: false,
searchText: '',
// 标记点击事件是否已绑定
clickEventBound: false,
}) })
onLoad((options) => { onLoad((options) => {
...@@ -70,52 +77,12 @@ onLoad((options) => { ...@@ -70,52 +77,12 @@ onLoad((options) => {
// 地图组件 // 地图组件
const center: [number, number] = [uni.getStorageSync('location').lon, uni.getStorageSync('location').lat] const center: [number, number] = [uni.getStorageSync('location').lon, uni.getStorageSync('location').lat]
const registerDialogRef = ref()
const [registerMap, map] = useMapbox({ const [registerMap, map] = useMapbox({
style: { center, zoom: 12 }, style: { center, zoom: 12 },
onLoaded: (data) => { onLoaded: (data) => {
// 渲染用户当前位置 // 渲染用户当前位置
const userLocationPoint = turf.point([ renderUserLocation()
model.userLocation.longitude,
model.userLocation.latitude
], {
name: '我的位置',
description: '当前位置',
icon: 'GD',
popup: `我的位置`,
})
addDefaultGeoJSONSource(map, `${page.id}-user-location`, [userLocationPoint])
addDefaultSymbolLayer(map, `${page.id}-user-location`, {
layout: {
'text-field': '',
'icon-image': ['get', 'icon'],
'icon-size': 1.2,
'icon-allow-overlap': true,
},
paint: {
'icon-color': '#FF4444',
},
})
const employments = []
// 渲染设备数据
model.employmentList.forEach((item) => {
employments.push(
turf.point([item.longitude, item.latitude], {
name: item.name,
description: item.content,
icon: 'GD',
popup: `{{name}}`,
}),
)
})
addDefaultGeoJSONSource(map, `${page.id}-text`, employments)
addDefaultSymbolLayer(map, `${page.id}-text`, {
layout: {
'text-field': '',
'icon-image': ['get', 'icon'],
'icon-size': 1,
},
})
}, },
onSourceRequestHandle: () => { onSourceRequestHandle: () => {
page.requests-- page.requests--
...@@ -126,7 +93,166 @@ const [registerMap, map] = useMapbox({ ...@@ -126,7 +93,166 @@ const [registerMap, map] = useMapbox({
onSourceRequestErrorHandle: () => { onSourceRequestErrorHandle: () => {
Message.hideLoading() Message.hideLoading()
}, },
onMapEvent: (event) => {
// 处理来自 renderjs 层的自定义事件
if (event.type === 'custom' && event.name === 'navigateToDetail') {
console.log('接收到导航事件,id:', event)
registerDialogRef.value.open({ id: event.data })
// Navigate.to(`/pages/linghuoyonggong/detail/index?id=${event.data}`)
}
},
}) })
// 创建弹框HTML内容
function createPopupHTML(employment) {
if (!employment) return ''
const distance = getDistanceText(employment)
console.log('employment', employment)
return `
<div style="
max-width: 280px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Hiragino Sans GB', 'Microsoft YaHei', sans-serif;
">
<div style="display: flex; gap: 6px; margin-bottom: 12px;">
<!-- 左侧图标 -->
<div style="
width: 48px;
height: 48px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
">
<img src="${employment.picture}" style="width: 48px; height: 48px; border-radius: 50%;" />
</div>
<!-- 右侧内容 -->
<div style="flex: 1; min-width: 0;">
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px;">
<div style="
font-size: 16px;
font-weight: 600;
color: #333333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
">${employment.name}</div>
<div style="
background: #E8F5E9;
color: #4CAF50;
padding: 2px 8px;
border-radius: 12px;
font-size: 12px;
white-space: nowrap;
margin-left: 8px;
">📍 ${distance}</div>
</div>
<div style="display: flex; gap: 12px; font-size: 13px; color: #666666; margin-bottom: 8px;">
<span>⏱ 时长${
employment.daysDiff || getDaysDiff(employment.starttime, employment.estimatedendtime)
}天</span>
<span>👥 需${employment.workers || 0}人</span>
<span>💰 ${employment.price || 0}元/天</span>
</div>
</div>
</div>
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="display: flex; align-items: center; gap: 4px;">
<span style="color: #FF9800; font-size: 16px;">★★★★</span>
<span style="color: #E0E0E0; font-size: 16px;">★</span>
<span style="font-size: 13px; color: #666666; margin-left: 4px;">4</span>
</div>
<a href="#" onclick="window.navigateToDetail('${employment.id}'); return false;" style="
display: inline-block;
padding: 6px 20px;
background: linear-gradient(135deg, #5DB66F 0%, #4CAF50 100%);
color: white;
text-decoration: none;
border-radius: 16px;
font-size: 14px;
font-weight: 500;
outline: none;
border: none;
transition: opacity 0.2s;">
我想去
</a>
</div>
</div>
`
}
// 渲染用户位置
function renderUserLocation() {
const markerId = `my-local`
// 修复 App 端图片路径问题
const imageUrl = '/static/images/local-map.png'
let finalImageUrl = imageUrl
// #ifdef APP-PLUS
// 在 App 端使用绝对路径
finalImageUrl = `./static/images/local-map.png`
// #endif
const iconSize: [number, number] = [40, 40] // 图标大小
// 使用 addMarker 添加到地图,带上 popup 和自定义图标
map.addMarker(
markerId,
[model.userLocation.longitude, model.userLocation.latitude],
'',
false, // 不默认打开
finalImageUrl, // 自定义图标图片URL
iconSize, // 图标大小
)
}
// 渲染用工标记
function renderEmploymentMarkers() {
if (!map) {
console.warn('地图未初始化')
return
}
console.log('渲染用工标记数量:', model.employmentList.length)
console.log('用工数据:', model.employmentList)
// 使用 Marker 方式渲染带自定义图标的标记
model.employmentList.forEach((item) => {
if (item.longitude && item.latitude) {
const markerId = `employment-marker-${item.id}`
let imageUrl = item.picture || '/static/images/linghuoyonggong/default-icon.png'
const iconSize: [number, number] = [40, 40] // 图标大小
// #ifdef APP-PLUS
// 处理 App 端图片路径
if (imageUrl.startsWith('/static/')) {
imageUrl = `.${imageUrl}`
}
// #endif
// 使用 addMarker 添加到地图,带上 popup 和自定义图标
map.addMarker(
markerId,
[item.longitude, item.latitude],
createPopupHTML(item),
false, // 不默认打开
imageUrl, // 自定义图标图片URL
iconSize, // 图标大小
)
}
})
// 绑定点击事件标记
if (!model.clickEventBound) {
console.log('标记点击事件已绑定')
model.clickEventBound = true
}
}
// 分类标签点击事件 // 分类标签点击事件
function onCategoryTabClick(tab: any) { function onCategoryTabClick(tab: any) {
model.search.type = tab.id model.search.type = tab.id
...@@ -169,6 +295,11 @@ function getEmploymentList() { ...@@ -169,6 +295,11 @@ function getEmploymentList() {
} }
model.total = total model.total = total
// 数据加载完成后渲染地图标记
nextTick(() => {
renderEmploymentMarkers()
})
}) })
} catch (error) { } catch (error) {
console.error('获取用工列表失败:', error) console.error('获取用工列表失败:', error)
...@@ -211,7 +342,7 @@ function backToUserLocation() { ...@@ -211,7 +342,7 @@ function backToUserLocation() {
uni.showToast({ uni.showToast({
title: '已回到当前位置', title: '已回到当前位置',
icon: 'none', icon: 'none',
duration: 1500 duration: 1500,
}) })
} else { } else {
// 重新获取用户位置 // 重新获取用户位置
...@@ -228,33 +359,13 @@ function backToUserLocation() { ...@@ -228,33 +359,13 @@ function backToUserLocation() {
lat: res.latitude, lat: res.latitude,
}) })
// 更新地图上的用户位置标记
const userLocationPoint = turf.point([res.longitude, res.latitude], {
name: '我的位置',
description: '当前位置',
icon: 'user-location-icon',
popup: `我的位置`,
})
addDefaultGeoJSONSource(map, `${page.id}-user-location`, [userLocationPoint])
addDefaultSymbolLayer(map, `${page.id}-user-location`, {
layout: {
'text-field': '',
'icon-image': ['get', 'icon'],
'icon-size': 1.2,
'icon-allow-overlap': true,
},
paint: {
'icon-color': '#FF4444',
},
})
// 飞到用户位置 // 飞到用户位置
flyTo(map, [res.longitude, res.latitude], 15, 0.5) flyTo(map, [res.longitude, res.latitude], 15, 0.5)
uni.showToast({ uni.showToast({
title: '已获取并回到当前位置', title: '已获取并回到当前位置',
icon: 'none', icon: 'none',
duration: 1500 duration: 1500,
}) })
} }
}, },
...@@ -263,14 +374,41 @@ function backToUserLocation() { ...@@ -263,14 +374,41 @@ function backToUserLocation() {
uni.showToast({ uni.showToast({
title: '获取位置失败,请检查定位权限', title: '获取位置失败,请检查定位权限',
icon: 'none', icon: 'none',
duration: 2000 duration: 2000,
}) })
} },
}) })
} }
} }
// 关闭弹框
function closeEmploymentPopup() {
model.showEmploymentPopup = false
model.selectedEmployment = null
}
// 计算距离显示
function getDistanceText(employment) {
if (!employment || !employment.longitude || !employment.latitude) {
return '未知'
}
// 使用turf计算距离
const from = turf.point([model.userLocation.longitude, model.userLocation.latitude])
const to = turf.point([employment.longitude, employment.latitude])
const distance = turf.distance(from, to, { units: 'kilometers' })
if (distance < 1) {
return `${Math.round(distance * 1000)}m`
}
return `${distance.toFixed(1)}km`
}
// 发布用工
function handlePublish() {
Navigate.to('/pages/linghuoyonggong/form')
}
onNavigationBarButtonTap((e) => { onNavigationBarButtonTap((e) => {
console.log(e)
if (e.index === 0) { if (e.index === 0) {
Navigate.to('/pages/linghuoyonggong/linghuoyonggong') Navigate.to('/pages/linghuoyonggong/linghuoyonggong')
} }
...@@ -281,9 +419,14 @@ onNavigationBarButtonTap((e) => { ...@@ -281,9 +419,14 @@ onNavigationBarButtonTap((e) => {
<view class="page h-95_dl_5vh bg-#E6F5E8 flex flex-col justify-between"> <view class="page h-95_dl_5vh bg-#E6F5E8 flex flex-col justify-between">
<view class="h-200rpx p-3"> <view class="h-200rpx p-3">
<view class="w-full h-60rpx border-rd-3xl!"> <view class="w-full h-60rpx border-rd-3xl!">
<fui-input :bottomLeft="0" class="w-full h-full border-rd-3xl!" borderTop placeholder="请输入搜索内容" <fui-input
:bottomLeft="0"
class="w-full h-full border-rd-3xl!"
borderTop
placeholder="请输入搜索内容"
placeholderStyle="color: #CCCCCC; font-weight: 400; font-family: PingFangSC-Regular;" placeholderStyle="color: #CCCCCC; font-weight: 400; font-family: PingFangSC-Regular;"
v-model="text"> v-model="model.searchText"
>
<template #left> <template #left>
<view class="fui-left__icon"> <view class="fui-left__icon">
<fui-icon name="search" color="#CCCCCC" :size="36" /> <fui-icon name="search" color="#CCCCCC" :size="36" />
...@@ -292,10 +435,13 @@ onNavigationBarButtonTap((e) => { ...@@ -292,10 +435,13 @@ onNavigationBarButtonTap((e) => {
</fui-input> </fui-input>
</view> </view>
<view class="codefun-mt-14 codefun-flex-row group_2 gap-2"> <view class="codefun-mt-14 codefun-flex-row group_2 gap-2">
<view v-for="tab in model.categoryTabs" :key="tab.id" <view
v-for="tab in model.categoryTabs"
:key="tab.id"
class="codefun-flex-col codefun-justify-start codefun-items-center" class="codefun-flex-col codefun-justify-start codefun-items-center"
:class="[tab.id === model.search.type ? 'text-wrapper' : 'text-wrapper_2']" :class="[tab.id === model.search.type ? 'text-wrapper' : 'text-wrapper_2']"
@click="onCategoryTabClick(tab)"> @click="onCategoryTabClick(tab)"
>
<text class="font_2 text_2"> <text class="font_2 text_2">
{{ tab.name }} {{ tab.name }}
</text> </text>
...@@ -311,10 +457,18 @@ onNavigationBarButtonTap((e) => { ...@@ -311,10 +457,18 @@ onNavigationBarButtonTap((e) => {
<!-- 回到当前位置按钮 --> <!-- 回到当前位置按钮 -->
<view class="location-control" @click="backToUserLocation"> <view class="location-control" @click="backToUserLocation">
<view class="location-button"> <view class="location-button">
<fui-icon name="location" color="#5DB66F" :size="36" /> <image src="/static/images/toLocal.png" style="width: 58rpx; height: 58rpx"></image>
<!-- <fui-icon name="location" color="#5DB66F" :size="36" /> -->
</view> </view>
</view> </view>
</view> </view>
<fui-fab position="right" distance="30" bottom="240" width="96" @click="handlePublish">
<view class="text-white text-center">
<view class="fab-icon" />
<view style="font-size: 24rpx">发布</view>
</view>
</fui-fab>
<RegisterDialog ref="registerDialogRef" />
</view> </view>
</template> </template>
...@@ -322,7 +476,7 @@ onNavigationBarButtonTap((e) => { ...@@ -322,7 +476,7 @@ onNavigationBarButtonTap((e) => {
// //
.page { .page {
min-height: 100vh; min-height: 100vh;
background: #E6F5E8; background: #e6f5e8;
.map-box { .map-box {
// #ifdef APP-PLUS // #ifdef APP-PLUS
...@@ -336,7 +490,7 @@ onNavigationBarButtonTap((e) => { ...@@ -336,7 +490,7 @@ onNavigationBarButtonTap((e) => {
width: 690rpx; width: 690rpx;
left: 30rpx; left: 30rpx;
border-radius: 20rpx; border-radius: 20rpx;
background: #E6F5E8; background: #e6f5e8;
} }
.group_2 { .group_2 {
...@@ -381,28 +535,28 @@ onNavigationBarButtonTap((e) => { ...@@ -381,28 +535,28 @@ onNavigationBarButtonTap((e) => {
.location-control { .location-control {
position: absolute; position: absolute;
bottom: 100rpx; bottom: 100rpx;
right: 30rpx; right: 10rpx;
z-index: 1000; z-index: 1000;
.location-button { .location-button {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
width: 80rpx; // width: 80rpx;
height: 80rpx; // height: 80rpx;
background: rgba(255, 255, 255, 0.95); background: rgba(255, 255, 255, 0.95);
border-radius: 50%; border-radius: 50%;
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15); box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.15);
backdrop-filter: blur(10rpx); backdrop-filter: blur(10rpx);
border: 2rpx solid #5DB66F; // border: 2rpx solid #5db66f;
transition: all 0.3s ease; transition: all 0.3s ease;
&:active { &:active {
transform: scale(0.95); transform: scale(0.95);
background: linear-gradient(135deg, #5DB66F 0%, #4CAF50 100%); background: linear-gradient(135deg, #5db66f 0%, #4caf50 100%);
:deep(.fui-icon) { :deep(.fui-icon) {
color: #FFFFFF !important; color: #ffffff !important;
} }
} }
...@@ -413,4 +567,16 @@ onNavigationBarButtonTap((e) => { ...@@ -413,4 +567,16 @@ onNavigationBarButtonTap((e) => {
} }
} }
} }
::v-deep .mapboxgl-popup {
max-width: 568rpx !important;
}
::v-deep .fui-fab__btn-main {
background: linear-gradient(124.25deg, #a5d63f 0%, #5db66f 100%) !important;
box-shadow: 0px 1px 8px #5db66f;
}
::v-deep .mapboxgl-popup a {
outline: none !important;
-webkit-tap-highlight-color: transparent !important;
-webkit-touch-callout: none !important;
}
</style> </style>
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
{{ model.msg.phone }} {{ model.msg.phone }}
</view> </view>
</view> </view>
<view class="msgBox flex justify-between items-center text-30"> <!-- <view class="msgBox flex justify-between items-center text-30">
<view class="text-#999999"> 邮箱 </view> <view class="text-#999999"> 邮箱 </view>
<view class="text-#333333"> <view class="text-#333333">
{{ model.msg.email }} {{ model.msg.email }}
...@@ -106,7 +106,6 @@ ...@@ -106,7 +106,6 @@
align="right" align="right"
:text="model.msg.orgCodeTxt ? `${model.msg.orgCodeTxt}` : '- -'" :text="model.msg.orgCodeTxt ? `${model.msg.orgCodeTxt}` : '- -'"
/> />
<!-- {{ model.msg.orgCodeTxt ? model.msg.orgCodeTxt : '- -' }} -->
</view> </view>
</view> </view>
<view class="msgBox lastBox flex justify-between items-center text-30"> <view class="msgBox lastBox flex justify-between items-center text-30">
...@@ -114,7 +113,7 @@ ...@@ -114,7 +113,7 @@
<view class="text-#333333"> <view class="text-#333333">
{{ model.msg.postText ? model.msg.postText : '- -' }} {{ model.msg.postText ? model.msg.postText : '- -' }}
</view> </view>
</view> </view> -->
</view> </view>
</view> </view>
</template> </template>
......
<script setup lang="ts"> <script setup lang="ts">
import dayjs from 'dayjs' import dayjs from 'dayjs'
import * as WeatherAPI from '@/api/model/weather' import * as WeatherAPI from '@/api/model/weather'
import { Echarts, useEcharts } from '@/components/Echarts' import { Echarts, useEcharts } from '@/components/Echarts'
import { getDayLabelValue, getWeatherIcon } from '@/utils/weather' import { getDayLabelValue, getWeatherIcon } from '@/utils/weather'
// 逐 7 天预报图表 // 逐 7 天预报图表
const [register7Forecast, Forecast7Chart] = useEcharts() const [register7Forecast, Forecast7Chart] = useEcharts()
const model = reactive({ const model = reactive({
days: 15, days: 15,
updateTime: '-', updateTime: '-',
})
onLoad(async () => {
const location = uni.getStorageSync('location')
const forecasts = await WeatherAPI.forecast(`${location.lon},${location.lat}`, model.days).then((res) => {
model.updateTime = dayjs(res.data.updateTime).format('YYYY-MM-DD HH:mm')
return res.data.daily
}) })
console.log('forecasts', forecasts)
onLoad(async () => { // 逐 7 天预报数据
const location = uni.getStorageSync('location') const _7DayForecastData = forecasts.map((item, index) => {
const forecasts = await WeatherAPI.forecast(`${location.lon},${location.lat}`, model.days).then((res) => { return {
model.updateTime = dayjs(res.data.updateTime).format('YYYY-MM-DD HH:mm') minTem: item.tempMin,
return res.data.daily maxTem: item.tempMax,
}) textDay: item.textDay,
console.log('forecasts', forecasts) textNight: item.textNight,
dayWeather: item.iconDay,
nightWeather: item.iconNight,
fxDate: item.fxDate,
...getDayLabelValue(index),
}
})
const _7DayForecastMaxTemValue = Math.max(..._7DayForecastData.map((item) => Number(item.maxTem)))
// 逐 7 天预报数据 // 设置逐 7 天预报图表参数
const _7DayForecastData = forecasts.map((item, index) => { Forecast7Chart.setOption({
return { tooltip: {
minTem: item.tempMin, show: true,
maxTem: item.tempMax, trigger: 'axis',
textDay: item.textDay, axisPointer: {
textNight: item.textNight, type: 'shadow',
dayWeather: item.iconDay, },
nightWeather: item.iconNight, formatter: (params) => {
fxDate: item.fxDate, // 过滤掉星期标签、日期标签和天气图标
...getDayLabelValue(index), const filteredParams = params.filter(param => {
return param.seriesName !== '星期标签' &&
param.seriesName !== '日期标签' &&
param.seriesName !== '天气图标';
});
if (filteredParams.length === 0) return '';
let result = '';
filteredParams.forEach(param => {
// 只显示有意义的数值信息
if (param.seriesName === '最高温度' || param.seriesName === '最低温度') {
result += `${param.seriesName}: ${param.value}°<br/>`;
}
});
return result;
} }
}) },
const _7DayForecastMaxTemValue = Math.max(..._7DayForecastData.map((item) => Number(item.maxTem))) grid: {
const _7DayForecastMinTemValue = Math.min(..._7DayForecastData.map((item) => Number(item.minTem))) top: '10%',
bottom: '10%',
// 设置逐 7 天预报图表参数 left: '0',
Forecast7Chart.setOption({ right: '3%',
tooltip: { },
trigger: 'axis', xAxis: {
axisPointer: { type: 'category',
type: 'shadow', data: _7DayForecastData.map((item) => item.textNight),
}, axisLine: {
show: false,
}, },
grid: { axisTick: {
top: '25%', show: false,
bottom: '10%',
left: '0',
right: '3%',
}, },
xAxis: { axisLabel: {
type: 'category', show: true, // 隐藏x轴标签
data: _7DayForecastData.map((item) => item.value), interval: 0,
axisLine: { color: '#999',
show: false, fontSize: 11,
},
axisTick: {
show: false,
},
axisLabel: {
show: false, // 隐藏x轴标签
},
}, },
yAxis: { },
type: 'value', yAxis: {
splitLine: { type: 'value',
show: false, splitLine: {
}, show: false,
axisLabel: { },
show: false, axisLabel: {
}, show: false,
},
},
series: [
// 顶部星期标签(今天、明天、周X)- 第一行
{
name: '星期标签',
type: 'scatter',
data: _7DayForecastData.map((item, index) => {
return {
value: [index, Number(_7DayForecastMaxTemValue) + 10.5],
symbolSize: 0,
label: {
show: true,
position: 'top',
formatter: item.label,
fontSize: 14,
color: '#333333',
fontWeight: 'bold',
},
}
}),
},
// 顶部日期标签(09/10)- 第二行
{
name: '日期标签',
type: 'scatter',
data: _7DayForecastData.map((item, index) => {
return {
value: [index, Number(_7DayForecastMaxTemValue) + 6],
symbolSize: 0,
label: {
show: true,
position: 'top',
formatter: `${item.value}\n${item.textDay}\n`,
fontSize: 12,
color: '#666666',
},
}
}),
},
// 天气图标 - 第三行
{
name: '天气图标',
type: 'scatter',
data: _7DayForecastData.map((item, index) => {
return {
value: [index, Number(_7DayForecastMaxTemValue) + 5],
symbol: `image://${getWeatherIcon(String(item.dayWeather))}`,
symbolSize: [28, 28],
}
}),
}, },
series: [
{ // 最高温度线
name: '最高温度', {
type: 'line', name: '最高温度',
data: _7DayForecastData.map((item) => item.maxTem), type: 'line',
smooth: true, data: _7DayForecastData.map((item) => item.maxTem),
smooth: true,
color: '#F79D80',
symbolSize: 6,
label: {
show: true,
position: 'top',
formatter: '{c}°',
color: '#F79D80', color: '#F79D80',
symbolSize: 6, fontSize: 11,
label: {
show: true,
position: 'top',
formatter: '{c}°',
color: '#F79D80',
fontSize: 11,
},
}, },
{ },
name: '最低温度', // 最低温度线
type: 'line', {
data: _7DayForecastData.map((item) => item.minTem), name: '最低温度',
smooth: true, type: 'line',
data: _7DayForecastData.map((item) => item.minTem),
smooth: true,
color: '#52C41A',
symbolSize: 6,
label: {
show: true,
position: 'bottom',
formatter: '{c}°',
color: '#52C41A', color: '#52C41A',
symbolSize: 6, fontSize: 11,
label: {
show: true,
position: 'bottom',
formatter: '{c}°',
color: '#52C41A',
fontSize: 11,
},
},
{
name: '白天天气',
type: 'scatter',
data: _7DayForecastData.map((item, index) => {
console.log('item', item,[index, Number(_7DayForecastMaxTemValue) + 3])
return {
value: [index, Number(_7DayForecastMaxTemValue) + 3],
symbol: `image://${getWeatherIcon(String(item.dayWeather))}`,
symbolSize: [20, 20],
symbolOffset: [0, -12],
label: {
show: true,
position: 'top',
formatter: `${item.label}\n${item.value}\n${item.textDay}`,
fontSize: 11,
color: '#333',
fontWeight: 'bold',
lineHeight: 18,
},
}
}),
}, },
{ },
name: '天气描述', ],
type: 'scatter',
data: _7DayForecastData.map((item, index) => {
return {
value: [index, Number(_7DayForecastMinTemValue) - 3],
symbolSize: 0,
label: {
show: true,
position: 'bottom',
formatter: item.textDay,
fontSize: 10,
color: '#999',
},
}
}),
},
],
})
}) })
})
</script> </script>
<template> <template>
...@@ -151,7 +185,7 @@ ...@@ -151,7 +185,7 @@
<!-- 逐 7 天预报图表 --> <!-- 逐 7 天预报图表 -->
<view class="rain-forecast mt-2rpx bg-#fff rd-1.5 shadow flex flex-col px-2"> <view class="rain-forecast mt-2rpx bg-#fff rd-1.5 shadow flex flex-col px-2">
<view class="flex items-center justify-between pt-3 px-2"> <view class="flex items-center justify-between pt-3 px-2">
<view class="text-32 font-600">{{ model.days }} 天预报</view> <view class="text-32 font-600">{{ model.days }}天预报</view>
<!-- <view class="text-24">发布时间:{{ model.updateTime }}</view> --> <!-- <view class="text-24">发布时间:{{ model.updateTime }}</view> -->
</view> </view>
<scroll-view class="flex-1" scroll-x="true"> <scroll-view class="flex-1" scroll-x="true">
...@@ -162,5 +196,5 @@ ...@@ -162,5 +196,5 @@
</template> </template>
<style lang="scss" scoped> <style lang="scss" scoped>
// //
</style> </style>
...@@ -440,7 +440,7 @@ ...@@ -440,7 +440,7 @@
<view class="box-4"> <view class="box-4">
<view class="box-4-title"> <view class="box-4-title">
<view class="box-4-title-text1"><text>基地设备</text></view> <view class="box-4-title-text1"><text>基地设备</text></view>
<view class="box-4-title-text2"><text>+ 添加设备</text></view> <navigator url="/pages/device/device" class="box-4-title-text2"><text>+ 添加设备</text></navigator>
</view> </view>
<view class="box-4-device"> <view class="box-4-device">
<view class="box-4-device-item" v-for="(device, index) in model.deviceTypeCount" :key="index"> <view class="box-4-device-item" v-for="(device, index) in model.deviceTypeCount" :key="index">
......
...@@ -3,6 +3,7 @@ import { reactive } from 'vue' ...@@ -3,6 +3,7 @@ import { reactive } from 'vue'
import { onPullDownRefresh, onShow } from '@dcloudio/uni-app' import { onPullDownRefresh, onShow } from '@dcloudio/uni-app'
import WeatherForecast from './components/WeatherForecast.vue' import WeatherForecast from './components/WeatherForecast.vue'
import Navigate from '@/utils/page/navigate' import Navigate from '@/utils/page/navigate'
import dayjs from 'dayjs'
import * as NongChangAPI from '@/api/model/nongchang' import * as NongChangAPI from '@/api/model/nongchang'
import { useUserStore } from '@/store/modules/user' import { useUserStore } from '@/store/modules/user'
...@@ -21,7 +22,7 @@ onShow(() => { ...@@ -21,7 +22,7 @@ onShow(() => {
// 农技课堂 // 农技课堂
getAgricultureClassList() getAgricultureClassList()
// 智能设备 // 智能设备
getDeviceList() // getDeviceList()
// 获取农村 // 获取农村
getFarmList() getFarmList()
}) })
...@@ -253,10 +254,9 @@ function getCommonToolsList() { ...@@ -253,10 +254,9 @@ function getCommonToolsList() {
}) })
} }
function getAgricultureClassList() { function getAgricultureClassList() {
getVideoList({ pageNo: 1, pageSize: 3, status: 1, classify: 3 }).then((res) => { getVideoList({ pageNo: 1, pageSize: 10, status: 1, classify: 3 }).then((res) => {
const { records } = res const { records } = res
pageData.agricultureClass.videoList = records pageData.agricultureClass.videoList = records
pageData.agricultureClass.title = records[0]?.title
}) })
} }
...@@ -509,8 +509,12 @@ onHide(() => { ...@@ -509,8 +509,12 @@ onHide(() => {
<text class="codefun-ml-8 font_2 text_2">{{ pageData.header.searchPlaceholder }}</text> <text class="codefun-ml-8 font_2 text_2">{{ pageData.header.searchPlaceholder }}</text>
</view> --> </view> -->
<view class="codefun-flex-row equal-division section_3"> <view class="codefun-flex-row equal-division section_3">
<view v-for="item in pageData.menuItems" :key="item.id" <view
class="codefun-flex-col codefun-items-center" @click="onMenuItemClick(item)"> v-for="item in pageData.menuItems"
:key="item.id"
class="codefun-flex-col codefun-items-center"
@click="onMenuItemClick(item)"
>
<image class="image_6" :src="item.icon_url" /> <image class="image_6" :src="item.icon_url" />
<text class="font_3 mt-13" :class="`text_${item.id + 2}`">{{ item.name }}</text> <text class="font_3 mt-13" :class="`text_${item.id + 2}`">{{ item.name }}</text>
</view> </view>
...@@ -530,7 +534,8 @@ onHide(() => { ...@@ -530,7 +534,8 @@ onHide(() => {
<text class="font_4 text_9">{{ pageData.farmInfo.area }}</text> <text class="font_4 text_9">{{ pageData.farmInfo.area }}</text>
</view> </view>
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_2 ml-3"> class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_2 ml-3"
>
<text class="font_4 text_10">{{ pageData.farmInfo.crops }}</text> <text class="font_4 text_10">{{ pageData.farmInfo.crops }}</text>
</view> </view>
</view> </view>
...@@ -557,26 +562,33 @@ onHide(() => { ...@@ -557,26 +562,33 @@ onHide(() => {
</view> </view>
<view class="h-300rpx codefun-flex-col mr-3.5 mt-17 nongchang_box relative"> <view class="h-300rpx codefun-flex-col mr-3.5 mt-17 nongchang_box relative">
<image class="w-full h-full" src="/static/images/nongchang/mynongchang-1.png" /> <image class="w-full h-full" src="/static/images/nongchang/mynongchang-1.png" />
<view v-show="pageData.hasFarm" <view
class="w-240rpx h-80rpx flex-center border-rd-3xl absolute top-50% left-50% color-#ffffff" v-show="pageData.hasFarm"
class="w-280rpx h-80rpx flex-center border-rd-3xl absolute top-50% left-50% color-#ffffff"
style=" style="
background-color: rgb(255 255 255 / 20%); background-color: rgb(255 255 255 / 20%);
border: 1rpx solid #fff; border: 1rpx solid #fff;
transform: translateY(-50%) translateX(-50%); transform: translateY(-50%) translateX(-50%);
" @click="toDetail(pageData.farmInfo)"> "
@click="toDetail(pageData.farmInfo)"
>
<image class="mr-1 w-40 h-40" src="/static/images/nongchang/eye-white.png" /> <image class="mr-1 w-40 h-40" src="/static/images/nongchang/eye-white.png" />
<text style="font-family: '思源黑体'; font-weight: 300">进入农场</text> <text style="font-family: '思源黑体'; font-weight: 300">进入农场</text>
</view> </view>
<view v-show="!pageData.hasFarm" <view
class="w-240rpx h-80rpx flex-center border-rd-3xl absolute top-50% left-50% color-#ffffff" v-show="!pageData.hasFarm"
class="w-280rpx h-80rpx flex-center border-rd-3xl absolute top-50% left-50% color-#ffffff"
style=" style="
background-color: rgb(255 255 255 / 20%); background-color: rgb(255 255 255 / 20%);
border: 1rpx solid #fff; border: 1rpx solid #fff;
transform: translateY(-50%) translateX(-50%); transform: translateY(-50%) translateX(-50%);
" @click="toAdd"> "
@click="toAdd"
>
<image class="mr-1 w-40 h-40" src="/static/images/nongchang/add.png" /> <image class="mr-1 w-40 h-40" src="/static/images/nongchang/add.png" />
<text style="font-family: '思源黑体'; font-weight: 300">添加农场</text> <text class="fontsize_28" style="font-family: '思源黑体'; font-weight: 400;color: #fff;">添加我的农场</text>
</view> </view>
<view class="absolute nongchang-remark">基于农场实时精细化气象数据基地设备管理</view>
</view> </view>
</view> </view>
<view class="codefun-flex-col group_10"> <view class="codefun-flex-col group_10">
...@@ -589,8 +601,8 @@ onHide(() => { ...@@ -589,8 +601,8 @@ onHide(() => {
<view class="codefun-flex-row equal-division_3"> <view class="codefun-flex-row equal-division_3">
<template v-for="model in pageData.agricultureModels" :key="model.id"> <template v-for="model in pageData.agricultureModels" :key="model.id">
<view class="codefun-flex-col equal-division-item_5 group_11"> <view class="codefun-flex-col equal-division-item_5 group_11">
<view class=" flex-row" style="text-align: center;"> <view class="flex-row" style="text-align: center">
<view class=" flex-center"> <view class="flex-center">
<image class="w-80 h-80" :src="model.icon_url" /> <image class="w-80 h-80" :src="model.icon_url" />
</view> </view>
<view class=""> <view class="">
...@@ -600,7 +612,8 @@ onHide(() => { ...@@ -600,7 +612,8 @@ onHide(() => {
</view> </view>
<view <view
class="codefun-flex-col codefun-justify-start codefun-items-center codefun-self-center text-wrapper_3 mt-2!" class="codefun-flex-col codefun-justify-start codefun-items-center codefun-self-center text-wrapper_3 mt-2!"
@click="onAgricultureModelClick(model)"> @click="onAgricultureModelClick(model)"
>
<text class="font_8 text_24">查看介绍</text> <text class="font_8 text_24">查看介绍</text>
</view> </view>
</view> </view>
...@@ -609,27 +622,34 @@ onHide(() => { ...@@ -609,27 +622,34 @@ onHide(() => {
</view> </view>
<view class="codefun-mt-12 codefun-flex-col section_8"> <view class="codefun-mt-12 codefun-flex-col section_8">
<view class="codefun-flex-row equal-division_4"> <view class="codefun-flex-row equal-division_4">
<view class="codefun-flex-row codefun-justify-center equal-division-item_6 section_9" <view
@click="onViewMoreFlexibleEmployment(1)"> class="codefun-flex-row codefun-justify-center equal-division-item_6 section_9"
@click="onViewMoreFlexibleEmployment(1)"
>
<text class="codefun-self-start font_9 text_25">{{ <text class="codefun-self-start font_9 text_25">{{
pageData.flexibleEmployment.working pageData.flexibleEmployment.working
}}</text> }}</text>
<image class="codefun-self-center image_8 ml-9" <image
src="/static/images/codefun/e12b4605ec265981ebf23e742ae09d77.png" /> class="codefun-self-center image_8 ml-9"
src="/static/images/codefun/e12b4605ec265981ebf23e742ae09d77.png"
/>
</view> </view>
<view <view
class="codefun-flex-row codefun-justify-evenly equal-division-item_6 section_10 ml-11" class="codefun-flex-row codefun-justify-evenly equal-division-item_6 section_10 ml-11"
@click="onViewMoreFlexibleEmployment(2)"> @click="onViewMoreFlexibleEmployment(2)"
>
<text class="codefun-self-start font_9 text_26">{{ <text class="codefun-self-start font_9 text_26">{{
pageData.flexibleEmployment.earning pageData.flexibleEmployment.earning
}}</text> }}</text>
<image class="codefun-self-center image_9" <image
src="/static/images/codefun/abc27711926ec08e17bd512f96740931.png" /> class="codefun-self-center image_9"
src="/static/images/codefun/abc27711926ec08e17bd512f96740931.png"
/>
</view> </view>
</view> </view>
<text class="codefun-self-start font_10 text_27 mt-7">{{ <text class="codefun-self-start font_10 text_27 mt-7">{{
pageData.flexibleEmployment.progress pageData.flexibleEmployment.progress
}}</text> }}</text>
</view> </view>
</view> </view>
</view> </view>
...@@ -639,11 +659,17 @@ onHide(() => { ...@@ -639,11 +659,17 @@ onHide(() => {
<text class="font_6 text_29" @click="onBaseManagementClick">更多</text> <text class="font_6 text_29" @click="onBaseManagementClick">更多</text>
</view> </view>
<view class="codefun-flex-row equal-division_5 mt-17"> <view class="codefun-flex-row equal-division_5 mt-17">
<view v-for="(item, index) in pageData.baseManagement" :key="item.id" <view
class="codefun-flex-col section_11 equal-division-item_7 gap-1 justify-center align-center" v-for="(item, index) in pageData.baseManagement"
:class="{ 'ml-9': index > 0 }" @click="onBaseManagementClick(item)"> :key="item.id"
class="codefun-flex-col section_11 equal-division-item_7 gap-1 justify-center align-center"
:class="{ 'ml-9': index > 0 }"
@click="onBaseManagementClick(item)"
>
<image class="image_5" :src="item.icon" /> <image class="image_5" :src="item.icon" />
<text class="fontsize_24 font_11 mt-0.5" :class="`text_${30 + item.id - 1}`">{{ item.name }}</text> <text class="fontsize_24 font_11 mt-0.5" :class="`text_${30 + item.id - 1}`">{{
item.name
}}</text>
<view class="group_25"> <view class="group_25">
<text class="font_12" :class="`text_${35 + item.id - 1}`">{{ item.num }}</text> <text class="font_12" :class="`text_${35 + item.id - 1}`">{{ item.num }}</text>
<text class="font_10" :class="`text_${35 + item.id + 3}`">{{ item.unit }}</text> <text class="font_10" :class="`text_${35 + item.id + 3}`">{{ item.unit }}</text>
...@@ -651,179 +677,73 @@ onHide(() => { ...@@ -651,179 +677,73 @@ onHide(() => {
</view> </view>
</view> </view>
</view> </view>
<view class="codefun-flex-col group_21" id="monitorWarning">
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_22">
<text class="font text_42">监测预警</text>
<text class="font_6 text_43 text_44" @click="onViewMoreMonitoring">更多</text>
</view>
<view class="codefun-flex-col section_12">
<view class="codefun-flex-row codefun-items-center group_23">
<view class="codefun-flex-col codefun-items-end codefun-shrink-0">
<text class="font_13 text_45">80</text>
<text class="codefun-mt-16 font_13 text_46">60</text>
<text class="codefun-mt-16 font_13 text_47">40</text>
<text class="codefun-mt-16 font_13 text_48">20</text>
<text class="codefun-mt-16 font_13 text_49">0</text>
</view>
<view class="codefun-flex-col codefun-flex-1 codefun-relative group_24 ml-7">
<view class="divider" />
<view class="divider view_2" />
<view class="divider view_3" />
<view
class="codefun-flex-col codefun-justify-start codefun-items-start image-wrapper pos_2">
<image class="codefun-shrink-0 image_11"
src="/static/images/codefun/fb791ee7e711cfb556043cb81d3c32b1.png" />
</view>
<view class="divider pos" />
<view class="divider pos_3" />
</view>
</view>
<view class="codefun-mt-10 codefun-flex-col codefun-justify-start group_25">
<view class="codefun-flex-row equal-division_6">
<view class="codefun-flex-col codefun-items-center section_13 equal-division-item_8">
<image class="image_12"
src="/static/images/codefun/68bae99a74dc71e194d799ee24c1f023.png" />
<view
class="codefun-mt-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4">
<text class="font_10 text_50">气象灾害</text>
</view>
<view
class="codefun-mt-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4">
<text class="font_10 text_53">台风预警</text>
</view>
</view>
<view class="codefun-flex-col section_13 equal-division-item_8 ml-11">
<image class="codefun-self-center image_12"
src="/static/images/codefun/29bc217d767c53f1f4968ddcf08b6d85.png" />
<view
class="codefun-mt-4 codefun-flex-col codefun-items-center codefun-self-stretch">
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4">
<text class="font_10 text_51">作物倒伏</text>
</view>
<view
class="codefun-mt-4 codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_4">
<text class="font_10 text_54">中等风险</text>
</view>
</view>
</view>
<view class="codefun-flex-col section_13 section_14 ml-11">
<image class="codefun-self-center image_12"
src="/static/images/codefun/143013b1c946e75b10133de0db6d9c7f.png" />
<view
class="codefun-mt-4 codefun-flex-col codefun-justify-start codefun-items-center codefun-self-stretch text-wrapper_5">
<text class="font_10 text_52">病虫害风险</text>
</view>
<view
class="codefun-mt-4 codefun-flex-col codefun-justify-start codefun-items-center codefun-self-stretch text-wrapper_5">
<text class="font_10 text_55">水稻稻瘟病</text>
</view>
</view>
</view>
</view>
</view>
</view>
<view class="codefun-flex-col group_21"> <view class="codefun-flex-col group_21">
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_22"> <view class="codefun-flex-row codefun-justify-between codefun-items-center group_22">
<text class="font text_42">常用工具</text> <text class="font text_42">常用工具</text>
<text class="font_6 text_43 text_44" @click="onViewMoreTools">更多</text> <text class="font_6 text_43 text_44" @click="onViewMoreTools">更多</text>
</view> </view>
<view class="codefun-flex-col section_12"> <view class="codefun-flex-col section_12">
<view class="flex-center flex-wrap pt-3"> <view class="flex-center flex-wrap pt-3">
<view v-for="tool in pageData.commonTools" :key="tool.id" <view
v-for="tool in pageData.commonTools"
:key="tool.id"
class="px-3 py-3 bg-white rounded-lg flex-center flex-col gap-2" class="px-3 py-3 bg-white rounded-lg flex-center flex-col gap-2"
@click="onClickTool(tool)"> @click="onClickTool(tool)"
>
<image class="w-100 h-100" :src="tool.icon" mode="scaleToFill" /> <image class="w-100 h-100" :src="tool.icon" mode="scaleToFill" />
<view class="text-24 fontsize_28">{{ tool.name }}</view> <view class="text-24 fontsize_28">{{ tool.name }}</view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<view class="codefun-flex-col group_26 mt-21">
<view class="codefun-flex-row codefun-justify-between codefun-items-baseline">
<text class="font text_56">智能设备</text>
<text class="font_6 text_57" @click="onDeviceManagementClick">设备管理</text>
</view>
<view class="codefun-flex-row group_26 mt-17 gap-2">
<view v-for="(device, index) in pageData.smartDevices" :key="device.id"
class="section_16 codefun-flex-row codefun-justify-center codefun-items-center codefun-shrink-0 codefun-relative">
<image class="image_13"
:src="device.isOnline === 1 ? pageData.smartDeviceIcon[0] : pageData.smartDeviceIcon[1]" />
<view class="codefun-ml-8 codefun-flex-col">
<text class="font_10">{{ device.deviceName }}</text>
<view class="codefun-mt-10 codefun-flex-row codefun-items-center">
<view class="section_17" v-if="index !== 1" />
<view class="section_18" v-if="index === 1" />
<text class="codefun-ml-4 font_4" :class="index !== 1 ? 'text_59' : 'text_60'"
:style="{ color: device.statusColor }">
{{ device.isOnline_dictText }}
</text>
</view>
</view>
</view>
</view>
</view>
<view class="codefun-flex-col group_28" id="creditCenter">
<text class="codefun-self-start font text_61">信用中心</text>
<view
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch section_19 mt-21">
<image class="image_15" :src="pageData.creditCenter.image" />
<view class="codefun-flex-col codefun-items-start group_29">
<text class="text_62">{{ userStore.getUserInfo?.creditScore || 600 }}</text>
<text class="font_5 text_63 mt-13">{{ pageData.creditCenter.rating }}</text>
<text class="font_10 text_64 mt-13">{{ pageData.creditCenter.tips }}</text>
<view
class="codefun-flex-col codefun-justify-start codefun-items-center text-wrapper_6 mt-13"
@click="onViewFinancialServices">
<text class="font_15 text_65">{{ pageData.creditCenter.actionText }}</text>
</view>
</view>
</view>
</view>
<view class="codefun-flex-col group_30"> <view class="codefun-flex-col group_30">
<view class="codefun-flex-row codefun-justify-between codefun-items-center group_22"> <view class="codefun-flex-row codefun-justify-between codefun-items-center group_22">
<text class="font text_66">农技学习</text> <text class="font text_66">农技学习</text>
<text class="font_6 text_43 text_67" @click="onViewMoreClass">查看更多</text> <text class="font_6 text_43 text_67" @click="onViewMoreClass">查看更多</text>
</view> </view>
<view class="codefun-flex-col section_20 !relative"> <view class="codefun-flex-col section_20 !relative rounded-lg" style="margin-left: -28rpx">
<fui-swiper-dot :items="pageData.agricultureClass.videoList" :current="pageData.current" <fui-waterfall topGap="20" leftGap="20" rightGap="20" bottomGap="20">
:styles="{ <fui-waterfall-item
height: 10, v-for="(video, index) in pageData.agricultureClass.videoList"
activeWidth: 40, :key="index"
background: '#dff0e2', :src="video.thumbnailPath"
activeBackground: '#5db66f', @click="playVideo(index)"
bottom: 10, >
}"> <view class="flex flex-col justify-between pl-2 pr-2 pb-2">
<swiper class="fui-banner__wrap" circular :indicator-dots="false" :autoplay="false" <view class="fontsize_28 mt-1 mb-2 font-13">{{ video.title }}</view>
:interval="8000" :duration="300" :disable-touch="false" :touch-angle="45" <view class="flex justify-between text-25 color-#686868">
:threshold="50" @change="handleChangeVideo" @transition="handleTransition"> <view class="mr-1 flex-center">
<swiper-item v-for="(video, index) in pageData.agricultureClass.videoList" :key="index"> <view class="flex-center text-24 lh-24rpx"
<image :src="video.thumbnailPath" mode="scaleToFill" class="w-654rpx h-358rpx" >{{ video.viewCount || 0 }}次播放</view
@click="playVideo(index)" /> >
<video :id="`video${index}`" :src="video.url" :poster="video.thumbnailPath"
:title="video.title" :controls="true" style="width: 654rpx; height: 358rpx"
:autoplay="false" :muted="false" :loop="true" :show-play-btn="true"
:show-center-play-btn="true" :enable-progress-gesture="true"
:show-progress="true" :direction="0" object-fit="contain"
@loadedmetadata="handleMetadataLoaded" @play="handleVideoPlay(index)"
@pause="handleVideoPause(index)"
@fullscreenchange="handleFullscreenChange($event, index)"
class="!hidden"></video>
<view class="describe relative">
<text class="codefun-self-start font text_34">{{
pageData.agricultureClass.title
}}</text>
<view
class="codefun-flex-row codefun-justify-between codefun-items-center codefun-self-stretch mt-13">
<image src="/static/images/codefun/play.png" mode="scaleToFill"
class="absolute w-64 h-64 top--150 left-275"
@click="playVideo(index)" />
<text class="font_14 text_36">{{ pageData.agricultureClass.time }}</text>
</view> </view>
<text>{{ dayjs(video.publishDate).format('MM-DD') }}</text>
</view> </view>
</swiper-item> </view>
</swiper> <video
</fui-swiper-dot> :id="`video${index}`"
:src="video.url"
:poster="video.thumbnailPath"
:title="video.title"
:controls="true"
:autoplay="false"
:muted="false"
:loop="true"
:show-play-btn="true"
:show-center-play-btn="true"
:enable-progress-gesture="true"
:show-progress="true"
:direction="0"
object-fit="contain"
@loadedmetadata="handleMetadataLoaded"
@play="handleVideoPlay(index)"
@pause="handleVideoPause(index)"
@fullscreenchange="handleFullscreenChange($event, index)"
class="!hidden"
></video>
</fui-waterfall-item>
</fui-waterfall>
</view> </view>
</view> </view>
</view> </view>
...@@ -989,7 +909,6 @@ onHide(() => { ...@@ -989,7 +909,6 @@ onHide(() => {
} }
.group_4 { .group_4 {
// position: absolute; // position: absolute;
// right: 147rpx; // right: 147rpx;
// top: 6rpx; // top: 6rpx;
...@@ -999,7 +918,6 @@ onHide(() => { ...@@ -999,7 +918,6 @@ onHide(() => {
} }
.equal-division-item_3 { .equal-division-item_3 {
// position: absolute; // position: absolute;
// right: 13rpx; // right: 13rpx;
// top: 6rpx; // top: 6rpx;
...@@ -1516,11 +1434,13 @@ onHide(() => { ...@@ -1516,11 +1434,13 @@ onHide(() => {
.divider { .divider {
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
background-image: repeating-linear-gradient(90deg, background-image: repeating-linear-gradient(
#c6cacd, 90deg,
#c6cacd 1.36%, #c6cacd,
transparent 1.36%, #c6cacd 1.36%,
transparent 2.717%); transparent 1.36%,
transparent 2.717%
);
background-position: -4rpx 0rpx; background-position: -4rpx 0rpx;
height: 2rpx; height: 2rpx;
} }
...@@ -1809,10 +1729,7 @@ onHide(() => { ...@@ -1809,10 +1729,7 @@ onHide(() => {
position: relative; position: relative;
margin-right: 28rpx; margin-right: 28rpx;
height: 418rpx; height: 418rpx;
// padding: 271.06rpx 36.64rpx 22rpx 48rpx;
padding: 20rpx;
padding-bottom: 0; padding-bottom: 0;
background-color: #ffffff;
border-radius: 16rpx; border-radius: 16rpx;
mix-blend-mode: NOTTHROUGH; mix-blend-mode: NOTTHROUGH;
...@@ -1988,4 +1905,17 @@ onHide(() => { ...@@ -1988,4 +1905,17 @@ onHide(() => {
.font_11 { .font_11 {
color: #666666; color: #666666;
} }
.nongchang-remark {
font-size: 24rpx;
font-weight: 400;
letter-spacing: 0px;
line-height: 18px;
color: #ffffff;
text-align: center;
vertical-align: middle;
bottom: 30rpx;
width: 312rpx;
left: 50%;
transform: translateX(-50%);
}
</style> </style>
...@@ -144,7 +144,8 @@ export function getDayLabelValue(index: number) { ...@@ -144,7 +144,8 @@ export function getDayLabelValue(index: number) {
} else if (index === 1) { } else if (index === 1) {
dayLabel = '明天' dayLabel = '明天'
} else { } else {
dayLabel = dayjs().day(dayOfWeek).format('dddd') const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
dayLabel = weekdays[dayOfWeek]
} }
return { return {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论