powerbank/pages/index/index.vue
2024-06-17 18:03:50 +08:00

954 lines
23 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="page">
<!-- 用户首页显示 -->
<view class="useryonghu">
<u-navbar :is-back="false" :border-bottom="false" :background="bgc" title-color='#2E4975' title-size='36'
height='8'></u-navbar>
<view class="title">
充电宝
</view>
<view class="ditu">
<view class="dtxs">
<map class='map' id="map" :latitude="latitude" :longitude="longitude" @markertap="handleMapClick"
:show-location="true" :markers="covers" :scale="mapScale" />
</view>
<view class="fujin">
<image @click="onControltap" style="width: 76rpx;height: 76rpx;position: absolute;right: 40rpx;"
src="https://api.ccttiot.com/smartmeter/img/static/uOS9p7Sy1K9WpVQgD3b9" mode=""></image>
</view>
<view class="tubiao">
<view class="gr" @click="btnindex(1)">
<image src="https://api.ccttiot.com/smartmeter/img/static/u9QWVWIpUsXIK1Avpt3k" mode=""
style="width: 96rpx;height:98rpx;"></image>
<!-- 个人中心 -->
</view>
<view class="gr" @click="btnindex(2)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uTiL5UkPc0jHlCrEg43v" mode=""
style="width: 96rpx;height:102rpx;"></image>
<!-- 我的订单 -->
</view>
<view class="gr" @click="btnindex(3)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uxi72kKTEFRd5aX3r4Lk" mode=""
style="width: 96rpx;height:98rpx;"></image>
<!-- 附近门店 -->
</view>
<view class="gr" @click="btnindex(4)">
<image src="https://api.ccttiot.com/smartmeter/img/static/uWT7I8JchvWR0adEuDE5" mode=""
style="width: 96rpx;height:94rpx;"></image>
<!-- 联系客服 -->
</view>
</view>
<view class="guangg">
<image :src="imgad" mode=""></image>
</view>
<view class="saoma" @click="scanQRCode">
<view>
<image style="margin-bottom: 10rpx;"
src="https://api.ccttiot.com/smartmeter/img/static/uPapXlAygHNzrml29Bhv" mode=""></image>
扫码充电
</view>
</view>
</view>
</view>
<!-- 租借中弹窗 -->
<view class="zujie" v-if="zujieflag">
<view class="tit">
<text>租借中</text> <text @click="btnzujie">X</text>
</view>
<view class="tishi">
每个用户限借1台归还可直接根据充电宝提示插入空位
</view>
<view class="xiang">
<view class="fenz">
<text>{{zujieobj.remainingTime}}</text> <text>{{zujiemoney > zujieobj.priceStandard.feeMaxPrice ? zujieobj.priceStandard.feeMaxPrice : zujiemoney}}</text>
</view>
<view class="shic">
<text>使用时长</text> <text>预估金额</text>
</view>
<view class="tits">
价格明细
</view>
<view class="shic">
<text>订单金额</text> <text>{{zujiemoney > zujieobj.priceStandard.feeMaxPrice ? zujieobj.priceStandard.feeMaxPrice : zujiemoney}}</text>
</view>
<view class="shuom">
<text v-if="zujieobj.priceStandard.feeMode == 2">{{zujieobj.priceStandard.feePrice}}元/小时</text>
<text v-if="zujieobj.priceStandard.feeMode == 1">{{zujieobj.priceStandard.feePrice}}元/半小时</text>
,前{{zujieobj.priceStandard.feeFreeTime}}分钟免费,
<text v-if="zujieobj.priceStandard.feeMode == 2">不足一小时按一小时计费,</text>
<text v-if="zujieobj.priceStandard.feeMode == 1">不足半小时按半小时计费,</text>
总封顶{{zujieobj.priceStandard.feeMaxPrice}}元
</view>
<view class="tits">
租借信息
</view>
<view class="shic">
<text>租借时间</text> <text>{{zujieobj.startRentTime}}</text>
</view>
<view class="shic">
<text>租借方式</text> <text v-if="zujieobj.rentType == 1">普通租赁</text> <text
v-if="zujieobj.rentType == 2">免押金租赁</text>
</view>
<view class="shic">
<text style="width: 260rpx;">租借地点</text> <text>{{zujieobj.startStoreAddress}}</text>
</view>
<view class="shic">
<text>归还时间</text> <text>{{zujieobj.endRentTime == null ? '-' : zujieobj.endRentTime}}</text>
</view>
<view class="shic">
<text style="width: 260rpx;">归还地点</text>
<text>{{zujieobj.endStoreAddress == null ? '-' : zujieobj.endStoreAddress}}</text>
</view>
<view class="shic">
<text>租借电池</text> <text>{{zujieobj.deviceSn}}</text>
</view>
<view class="shic">
<text>订单编号</text> <text>{{zujieobj.orderNo}} <text class="fz"
@click="copyText('S1269876456368798741201')">复制</text> </text>
</view>
<view class="huan" @click="btnsale(zujieobj.orderId)">
不想还了,留下充电宝
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
params: {
year: true,
month: true,
day: true,
hour: false,
minute: false,
second: false
},
dateindex: 1,
latitude: '', // 初始纬度
longitude: '', // 初始经度
covers: [], // 覆盖物数组
jinweidu: '',
zujieflag: false,
listmap: [],
mapScale: 16,
datetime: 0,
dingobj: '',
mapContext: null,
mapScaleInterval: null,
zujieobj: {},
zujiemoney: '',
timer: null,
imgad:''
};
},
onReady() {
this.mapContext = uni.createMapContext('map', this)
this.mapScaleInterval = setInterval(this.updateMarkers, 1000)
},
beforeDestroy() {
if (this.mapScaleInterval) {
clearInterval(this.mapScaleInterval)
this.mapScaleInterval = null
}
},
onShow() {
this.jmlogin()
this.getuser()
setTimeout(()=>{
this.getorder()
},1000)
this.startTimer()
this.getad()
},
onHide() {
// 在页面隐藏时清除定时器
this.clearTimer()
},
onUnload() {
this.clearTimer()
},
methods: {
getad() {
this.$u.get("/app/ad").then((res) => {
if (res.code == 200) {
this.imgad = res.data.picture
}
})
},
btnsale(orderId){
this.$u.put(`/app/order/rent/${orderId}/toSale`).then(res => {
if(res.code == 200){
let orderNo = res.data
let data = {
orderNo:orderNo,
channelId:1
}
this.$u.put('/app/order/sale/prePay',data).then(res => {
if(res.code == 200){
uni.requestPayment({
provider: 'wxpay',
timeStamp: res.data.timeStamp,
nonceStr: res.data.nonceStr,
package: res.data.packageVal,
signType: res.data.signType,
paySign: res.data.paySign,
success: (res) => {
// console.log(res, '支付成功');
this.$u.put(`/app/order/sale/${orderNo}/refreshPayResult`).then(res =>{
if(res.code == 200){
this.zujieflag = false
}
})
},
fail(err) {
// 支付失败逻辑
uni.showToast({
title: '支付失败',
icon: 'none',
duration: 2000
});
}
})
}else if(res.code == 500){
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
}else if(res.code == 500){
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
});
}
})
},
startTimer() {
// 如果之前已经存在定时器,先清除它
this.clearTimer();
this.timer = setInterval(() => {
this.getorder()
}, 60000);
},
clearTimer() {
// 清除定时器
if (this.timer) {
clearInterval(this.timer)
this.timer = null;
}
},
// 查询当前是否有进行中订单
getorder() {
this.$u.get('/app/order/rent/using').then(res => {
if (res.code == 200) {
if (res.data) {
this.zujieflag = true
this.zujieobj = res.data
if (this.zujieobj.endRentTime == null) {
var targetDate = new Date(this.zujieobj.startRentTime)
var currentDate = new Date()
var diff = targetDate - currentDate
var absDiff = Math.abs(diff)
var hours = Math.floor(absDiff / (1000 * 60 * 60))
var minutes = Math.floor((absDiff % (1000 * 60 * 60)) / (1000 * 60))
let formattedMinutes = minutes < 10 ? '0' + minutes : minutes
this.zujieobj.remainingTime = hours + '小时' + formattedMinutes + '分钟'
if (this.zujieobj.priceStandard.feeMode == 2) {
if (minutes >= this.zujieobj.priceStandard.feeFreeTime) {
this.zujiemoney = (hours + 1) * this.zujieobj.priceStandard.feePrice
} else {
this.zujiemoney = hours * this.zujieobj.priceStandard.feePrice
}
}else if(this.zujieobj.priceStandard.feeMode == 1){
if (minutes >= this.zujieobj.priceStandard.feeFreeTime) {
this.zujiemoney = (hours * 2 + 1) * this.zujieobj.priceStandard.feePrice
if(minutes >= 30){
this.zujiemoney = (hours * 2 + 2) * this.zujieobj.priceStandard.feePrice
}
} else {
this.zujiemoney = hours * 2 * this.zujieobj.priceStandard.feePrice
}
}
} else {
var targetDate = new Date(this.zujieobj.endRentTime)
var currentDate = new Date()
var diff = targetDate - currentDate
var absDiff = Math.abs(diff)
var hours = Math.floor(absDiff / (1000 * 60 * 60))
var minutes = Math.floor((absDiff % (1000 * 60 * 60)) / (1000 * 60))
let formattedMinutes = minutes < 10 ? '0' + minutes : minutes
this.zujieobj.remainingTime = hours + '小时' + formattedMinutes + '分钟'
if (this.zujieobj.priceStandard.feeMode == 2) {
if (minutes >= this.zujieobj.priceStandard.feeFreeTime) {
this.zujiemoney = (hours + 1) * this.zujieobj.priceStandard.feePrice
} else {
this.zujiemoney = hours * this.zujieobj.priceStandard.feePrice
}
}else if(this.zujieobj.priceStandard.feeMode == 1){
if (minutes >= this.zujieobj.priceStandard.feeFreeTime) {
this.zujiemoney = (hours * 2 + 1) * 2 * this.zujieobj.priceStandard.feePrice
if(minutes >= 30){
this.zujiemoney = (hours * 2 + 2) * this.zujieobj.priceStandard.feePrice
}
} else {
this.zujiemoney = hours * 2 * this.zujieobj.priceStandard.feePrice
}
}
}
}else{
this.zujieflag = false
}
}
})
},
onControltap(control) {
this.setMapScale()
},
async setMapScale(e, val) {
let mapContext = uni.createMapContext('map', this);
let setScale = () => {
return new Promise((resolve, reject) => {
mapContext.getScale({
success: r => {
resolve()
}
})
})
};
await setScale();
mapContext.moveToLocation({
success: (res) => {
const timer = setTimeout(() => {
clearTimeout(timer);
}, 500);
}
})
},
updateMarkers() {
this.mapContext.getScale({
success: (res) => {
this.covers = []
if (res.scale <= 14) {
this.addMarkersWithoutLabels()
} else {
this.addMarkersWithLabels()
}
},
fail: (error) => {
// console.error('获取地图缩放级别失败:', error);
},
});
},
addMarkersWithoutLabels() {
this.listmap.forEach((item) => {
const shopCover = {
id: parseFloat(item.storeId),
latitude: item.lat,
longitude: item.lng,
width: 25,
height: 30,
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uI3B6yPwtiUBD3vafLtw',
borderColor:'#fff',
borderRadius:5,
bgColor: 'rgba(255, 255, 255, 0.7)'
};
this.covers.push(shopCover)
});
},
addMarkersWithLabels() {
this.listmap.forEach((item) => {
const shopCover = {
id: parseFloat(item.storeId),
latitude: item.lat,
longitude: item.lng,
width: 25,
height: 30,
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uI3B6yPwtiUBD3vafLtw',
label: {
content: item.name,
anchorX: this.calculateAnchorX(item.name),
fontWeight: 700,
color: '#25D088',
textShadow: '2px 2px 0px #000, -2px -2px 0px #000, 2px -2px 0px #000, -2px 2px 0px #000',
rotate: 20,
borderColor:'#fff',
borderRadius:5,
bgColor: 'rgba(255, 255, 255, 0.7)'
}
}
this.covers.push(shopCover)
});
},
calculateAnchorX(name) {
let chineseLength = 0;
let englishLength = 0;
for (let i = 0; i < name.length; i++) {
const charCode = name.charCodeAt(i);
if (charCode >= 0x4e00 && charCode <= 0x9fa5) {
chineseLength++;
} else if (/[a-zA-Z]/.test(name[i])) {
englishLength = englishLength + 0.3
}
}
const totalLength = chineseLength + englishLength * 2
return -totalLength * 7
},
btnzujie() {
this.zujieflag = false
},
scanQRCode() {
uni.scanCode({
onlyFromCamera: true,
scanType: ['qrCode'],
success: res => {
console.log('扫描结果:', res)
let result = res.result
uni.navigateTo({
url: '/page_user/yajin/index?sn=' + result
})
},
fail: err => {
console.error('扫描失败:', err)
uni.showToast({
title: '扫描失败',
icon: 'none'
})
}
});
},
copyText(text) {
uni.setClipboardData({
data: text, //要被复制的内容
success: () => {
uni.showToast({
title: '复制成功'
})
}
});
},
// 保存当前用户信息
getuser() {
this.$u.get('/app/user/userInfo').then(res => {
if (res.code == 200) {
if (uni.setStorageSync('userdata')) {
uni.removeStorageSync('userdata')
uni.setStorageSync('userdata', res.data)
} else {
uni.setStorageSync('userdata', res.data)
}
}
})
},
btnindex(num) {
if (num == 2) {
uni.navigateTo({
url: '/pages/myorder/index'
})
} else if (num == 3) {
uni.navigateTo({
url: '/pages/nearbystores/index'
})
} else if (num == 1) {
uni.navigateTo({
url: '/pages/personal/index'
})
} else {
uni.navigateTo({
url: '/pages/abbr/index'
})
}
},
getMyLocation() {
uni.getLocation({
type: 'wgs84',
success: (res) => {
this.jinweidu = res.longitude + ',' + res.latitude
this.latitude = Number(res.latitude.toFixed(5)) - 0.004
this.longitude = Number(res.longitude.toFixed(5)) + 0.004
this.setMapScale()
// 请求附近的店铺
this.$u.get("/app/store/listNearBy?center=" + this.jinweidu + '&radius=' + 1000).then(
res => {
if (res.code == 200) {
this.listmap = res.data
res.data.forEach(item => {
const shopCover = {
id: parseFloat(item.storeId),
latitude: item.lat,
longitude: item.lng,
width: 25,
height: 30,
iconPath: 'https://api.ccttiot.com/smartmeter/img/static/uI3B6yPwtiUBD3vafLtw',
label: {
content: item.name,
anchorX: (() => {
if (item.name.length <= 2) {
return -12
} else if (item.name.length <= 3) {
return -20
} else if (item.name.length <= 4) {
return -25
} else if (item.name.length <= 5) {
return -30
} else if (item.name.length <= 6) {
return -35
} else if (item.name.length <= 8) {
return -40
} else if (item.name.length <=
10) {
return -45
} else {
return -item.name.length * 5
}
})(),
fontWeight: 700,
color: '#25D088',
textShadow: '2px 2px 0px white, -2px -2px 0px white, 2px -2px 0px white, -2px 2px 0px white',
borderColor:'#fff',
borderRadius:5,
bgColor: 'rgba(255, 255, 255, 0.7)'
}
};
this.covers.push(shopCover)
});
}
})
},
fail: (err) => {
console.error('获取位置失败:', err)
}
});
},
// 未登录调静默获取token
jmlogin() {
let taht = this
wx.login({
success(res) {
if (res.code) {
let data = {
loginCode: res.code,
}
taht.$u.post('/app/auth/wxLogin', data).then(res => {
if (res.code == 10003) {
// uni.navigateTo({
// url: '/pages/login/login'
// })
} else if (res.code == 200) {
uni.setStorageSync('token', res.token);
taht.getMyLocation()
}
})
}
},
})
},
handleMapClick(event) {
console.log(event)
const markerId = event.markerId;
uni.navigateTo({
url: '/page_user/ditu?markerId=' + markerId
})
},
},
mounted() {
this.getMyLocation(); // 获取并设置自身位置的覆盖物
}
};
</script>
<style lang="scss">
/deep/ .map {
width: 100%;
height: 100%;
}
.dateactive {
background: #E1F3ED;
}
page {
background: linear-gradient(180deg, #25CE88 0%, rgba(255, 255, 255, 0) 100%);
border-radius: 0rpx 0rpx 0rpx 0rpx;
}
.page {
width: 750rpx;
padding-left: 34rpx;
padding-right: 34rpx;
box-sizing: border-box;
// position: fixed;
// top: 0;
// left: 0;
.zujie {
width: 750rpx;
height: 1238rpx;
background: #F7F7F7;
box-shadow: 0rpx 10rpx 64rpx 0rpx rgba(0, 0, 0, 0.08);
position: fixed;
left: 0;
bottom: 30rpx;
border-radius: 30rpx 30rpx 0 0;
.tit {
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
padding: 30rpx 64rpx;
box-sizing: border-box;
display: flex;
justify-content: space-between;
}
.tishi {
font-size: 24rpx;
color: #666666;
font-weight: 500;
padding-left: 72rpx;
}
.xiang {
width: 680rpx;
height: 1110rpx;
background: #FFFFFF;
padding: 32rpx 38rpx;
box-sizing: border-box;
margin: auto;
margin-top: 28rpx;
border-radius: 20rpx 20rpx 0 0;
.huan {
width: 558rpx;
height: 90rpx;
line-height: 90rpx;
background: linear-gradient(270deg, #54DAA1 0%, #19CD82 100%);
border-radius: 54rpx 54rpx 54rpx 54rpx;
text-align: center;
font-weight: 600;
font-size: 36rpx;
color: #FFFFFF;
margin: auto;
margin-top: 40rpx;
}
.shuom {
font-weight: 600;
font-size: 24rpx;
color: #333333;
margin-top: 24rpx;
}
.tits {
font-weight: 600;
font-size: 32rpx;
color: #333333;
margin-top: 24rpx;
}
.shic {
display: flex;
justify-content: space-between;
font-size: 24rpx;
color: #666666;
margin-top: 30rpx;
.fz {
display: inline-block;
border: 1px solid #808080;
border-radius: 10rpx;
padding: 4rpx 14rpx;
box-sizing: border-box;
margin-left: 10rpx;
}
}
.fenz {
display: flex;
justify-content: space-between;
font-weight: 500;
font-size: 40rpx;
color: #3D3D3D;
text {
font-weight: 600;
font-size: 40rpx;
color: #3D3D3D;
}
}
}
}
// 代理样式
.userdaili {
.gongneng {
width: 680rpx;
height: 304rpx;
background: #FFFFFF;
border-radius: 24rpx 24rpx 24rpx 24rpx;
padding: 0 50rpx;
box-sizing: border-box;
.icons {
display: inline-block;
width: 145rpx;
text-align: center;
image {
margin-top: 34rpx;
width: 50px;
height: 50px;
}
}
}
.ordertongji {
width: 680rpx;
height: 342rpx;
background: #FFFFFF;
border-radius: 24rpx 24rpx 24rpx 24rpx;
.shuju {
display: flex;
justify-content: space-between;
padding: 0 40rpx;
box-sizing: border-box;
margin-top: 24rpx;
.ddje {
text-align: center;
.shu {
font-weight: 500;
font-size: 40rpx;
color: #3D3D3D;
}
.sb {
margin-top: 20rpx;
font-weight: 500;
font-size: 20rpx;
color: #3D3D3D;
}
}
}
.date {
padding-left: 80rpx;
padding-right: 80rpx;
box-sizing: border-box;
display: flex;
justify-content: space-between;
margin-top: 26rpx;
text {
padding: 6rpx 18rpx;
box-sizing: border-box;
background: #eee;
border-radius: 10rpx 10rpx 10rpx 10rpx;
font-size: 24rpx;
color: #808080;
}
}
.orderday {
display: flex;
justify-content: space-between;
width: 100%;
padding: 10rpx 12rpx;
box-sizing: border-box;
text {
margin-right: 10rpx;
border-radius: 20rpx;
text-align: center;
display: inline-block;
width: 148rpx;
height: 84rpx;
text-align: center;
line-height: 84rpx;
}
}
}
.dttitle {
margin: 36rpx 0;
font-weight: 500;
font-size: 36rpx;
color: #3D3D3D;
}
.zhanghu {
margin-top: 32rpx;
width: 680rpx;
height: 264rpx;
background: #FFFFFF;
border-radius: 24rpx 24rpx 24rpx 24rpx;
padding: 36rpx 38rpx;
box-sizing: border-box;
.zhtitle {
display: flex;
justify-content: space-between;
.sj {
display: flex;
justify-content: space-between;
text {
font-size: 24rpx;
color: #3D3D3D;
}
}
.tx {
font-size: 24rpx;
color: #27D089;
}
}
.zhje {
margin-top: 20rpx;
display: flex;
justify-content: space-between;
border-bottom: 1px solid #ccc;
padding-bottom: 20rpx;
text {
font-weight: 500;
font-size: 48rpx;
color: #3D3D3D;
}
.btntx {
width: 156rpx;
height: 42rpx;
background: linear-gradient(270deg, #54DAA1 0%, #19CD82 100%);
border-radius: 40rpx 40rpx 40rpx 40rpx;
font-size: 24rpx;
color: #FFFFFF;
text-align: center;
line-height: 42rpx;
margin-top: 10rpx;
}
}
.buc {
margin-top: 20rpx;
font-size: 24rpx;
color: #979797;
}
}
}
//样式结束
.title {
font-weight: 600;
font-size: 36rpx;
color: #3D3D3D;
line-height: 50rpx;
text-align: left;
font-style: normal;
text-transform: none;
}
.guangg {
image {
width: 680rpx;
height: 238rpx;
border-radius: 20rpx;
}
}
.saoma {
width: 750rpx;
height: 186rpx;
background: #FFFFFF;
position: fixed;
bottom: 0;
left: 0;
padding-top: 38rpx;
border-radius: 54rpx 54rpx 0 0;
view {
text-align: center;
width: 676rpx;
height: 102rpx;
background: linear-gradient(270deg, #54DAA1 0%, #19CD82 100%);
border-radius: 54rpx 54rpx 54rpx 54rpx;
font-weight: 500;
font-size: 40rpx;
color: #FFFFFF;
margin: auto;
line-height: 102rpx;
}
image {
width: 56rpx;
height: 56rpx;
vertical-align: middle;
margin-right: 10rpx;
}
}
.ditu {
width: 100%;
height: 964rpx;
background: #FFFFFF;
border-radius: 38rpx 38rpx 38rpx 38rpx;
margin-top: 34rpx;
padding-top: 16rpx;
position: relative;
.fujin {
position: absolute;
top: 730rpx;
padding-left: 30rpx;
width: 100%;
image {
width: 210rpx;
height: 74rpx;
}
}
.dtxs {
width: 642rpx;
height: 812rpx;
margin: auto;
}
.tubiao {
display: flex;
justify-content: space-between;
padding: 20rpx 50rpx;
box-sizing: border-box;
.gr {
text-align: center;
width: 100%;
font-weight: 400;
font-size: 24rpx;
color: #3D3D3D;
image {
display: block;
margin: auto;
margin-bottom: 14rpx;
}
}
}
}
}
</style>