| | |
| | | <template> |
| | | <view class="device"> |
| | | <Navbar title="设备列表"></Navbar> |
| | | <view class="content"> |
| | | <view class="list"> |
| | | <block v-for="(item,index) in facitilyList" :key="index"> |
| | | <view class="item"> |
| | | <view class="item-img"> |
| | | <image v-if="item.facilityUrl" :src="BASE_URL + '/upload' + item.facilityUrl" alt='' mode="aspectFit"></image> |
| | | <image v-else src="../../static/images/facilityImg.svg" alt='' mode="aspectFit"></image> |
| | | </view> |
| | | <view class="item-info"> |
| | | <view class="info-name"> |
| | | <view class="name">{{item.facilityName}}</view> |
| | | <view class="btn" @click="handleQushui(item.id)">取水</view> |
| | | </view> |
| | | <view class="info-addr" @click="openMap(item.lat,item.lon)"> |
| | | <text class="addr-text">地址:{{item.address}}</text> |
| | | <view> |
| | | <image src="../../static/images/icon-point.svg" alt=''></image> |
| | | <text>{{item.distanceValue}}km</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </block> |
| | | </view> |
| | | </view> |
| | | <uni-popup ref="qushuiDialog" type="dialog"> |
| | | <uni-popup-dialog type="info" cancelText="取消" confirmText="确认" title="请输入取水量" |
| | | @confirm="dialogConfirm" |
| | | @close="dialogClose" |
| | | > |
| | | <view> |
| | | <input v-model="qushuiNum" placeholder="请输入取水量(L)" /> |
| | | </view> |
| | | </uni-popup-dialog> |
| | | </uni-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import{ ref, onMounted } from 'vue' |
| | | import Navbar from '../../components/navbar/navbar.vue' |
| | | import { getFacitily } from '@/api/index.js' |
| | | import { BASE_URL } from '../../config/index.js' |
| | | |
| | | const userLocation = ref() |
| | | const facitilyList = ref([]) |
| | | const qushuiDialog = ref() |
| | | const facitilyId = ref() |
| | | const qushuiNum = ref() |
| | | |
| | | const getFacitilyList = () => { |
| | | const data = { |
| | | longitude: userLocation.value?.lon, |
| | | latitude: userLocation.value?.lat, |
| | | limit: 100, |
| | | page: 1 |
| | | } |
| | | getFacitily(data).then(res => { |
| | | if(res.code === 200) { |
| | | facitilyList.value = res.data.list |
| | | } |
| | | }) |
| | | } |
| | | |
| | | // 根据经纬度计算距离,根据经纬度计算距离,参数分别为第一点的纬度,经度(用户);第二点的纬度,经度(设备) |
| | | const getDistances = (lat1, lon1, lat2, lon2) => { |
| | | let EARTH_RADIUS = 6378.137;// 地球半径 |
| | | let radLat1 = lat1 * Math.PI / 180.0; //lat1 * Math.PI / 180.0=>弧度计算 |
| | | let radLat2 = lat2 * Math.PI / 180.0; |
| | | let a = radLat1 - radLat2; |
| | | let b = lon1 * Math.PI / 180.0 - lon2 * Math.PI / 180.0; |
| | | let s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); |
| | | s = s * EARTH_RADIUS; |
| | | s = Math.round(s * 10000) / 10000;// 输出为公里 |
| | | return { m: s * 1000, km: Number(s.toFixed(2)) } |
| | | // 取水 |
| | | const handleQushui = (id) => { |
| | | facitilyId.value = id |
| | | qushuiDialog.value.open() |
| | | } |
| | | |
| | | // 取消 |
| | | const dialogClose = () => { |
| | | facitilyId.value = '' |
| | | qushuiNum.value = '' |
| | | } |
| | | |
| | | // 确认 |
| | | const dialogConfirm = () => { |
| | | |
| | | } |
| | | |
| | | //打开地图导航 |
| | | const openMap = (lat,lon) => { |
| | | uni.openLocation({ |
| | | latitude: parseFloat(lat), |
| | | longitude: parseFloat(lon), |
| | | scale:18 |
| | | }) |
| | | } |
| | | |
| | | //获取用户位置并存储 |
| | | const storageLocation = () => { |
| | | uni.getLocation({ |
| | | type:'gcj02', |
| | | isHighAccuracy:true, |
| | | success:(res) =>{ |
| | | userLocation.value = { |
| | | lat: res.latitude, |
| | | lon: res.longitude |
| | | } |
| | | uni.setStorageSync('userLocation',JSON.stringify(userLocation.value)) |
| | | }, |
| | | fail:(err) =>{ |
| | | locationToast() |
| | | } |
| | | }) |
| | | } |
| | | //用户拒绝授权 |
| | | const locationToast = () => { |
| | | uni.showModal({ |
| | | title: "请求授权当前位置", |
| | | content: "请求获取您的位置,加载附近饮水设备信息!", |
| | | confirmText: "前往设置", |
| | | success: (res) => { |
| | | if (res.confirm) { |
| | | uni.openSetting({ |
| | | success:(res1) =>{ //打开设置成功 |
| | | if (res1.authSetting['scope.userLocation']){ |
| | | setTimeout(() =>{ |
| | | storageLocation() |
| | | },1000) |
| | | } |
| | | }, |
| | | }) |
| | | }else{ |
| | | uni.showToast({ |
| | | title: '请先授权!', |
| | | duration: 2000, |
| | | icon:'none' |
| | | }); |
| | | } |
| | | }, |
| | | }); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | userLocation.value = JSON.parse(uni.getStorageSync('userLocation')) |
| | | const location = uni.getStorageSync('userLocation') |
| | | if(location) { |
| | | userLocation.value = JSON.parse(location) |
| | | getFacitilyList() |
| | | }else{ |
| | | locationToast() |
| | | } |
| | | }) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .content{ |
| | | width: 100%; |
| | | height:calc(100vh - 176rpx); |
| | | background:linear-gradient(to top,#FFFFFF,#E8EFFF); |
| | | padding:32rpx 32rpx 100rpx; |
| | | box-sizing: border-box; |
| | | .list{ |
| | | width:100%; |
| | | height:100%; |
| | | overflow: scroll; |
| | | // background-color: #f1ffef; |
| | | .item{ |
| | | height:200rpx; |
| | | width:100%; |
| | | background-color: #FFFFFF; |
| | | border-radius: 24rpx; |
| | | padding:0 20rpx; |
| | | margin-bottom:20rpx; |
| | | box-sizing: border-box; |
| | | display: flex; |
| | | align-items:center; |
| | | .item-img{ |
| | | image{ |
| | | width:130rpx; |
| | | height: 130rpx; |
| | | } |
| | | } |
| | | .item-info{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | margin-left:20rpx; |
| | | justify-content: space-between; |
| | | .info-name{ |
| | | color:#222c35; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | .btn{ |
| | | padding: 10rpx 20rpx; |
| | | background-color: $uni-primary; |
| | | border-radius: 10rpx; |
| | | color: #fff; |
| | | } |
| | | } |
| | | .info-addr{ |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items:center; |
| | | .addr-text{ |
| | | width:340rpx; |
| | | height:80rpx; |
| | | color: #6a6e75; |
| | | font-size:26rpx; |
| | | } |
| | | view{ |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items:center; |
| | | image{ |
| | | width:50rpx; |
| | | height:50rpx; |
| | | } |
| | | text{ |
| | | color: #6a6e75; |
| | | font-size:26rpx; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |