604 lines
23 KiB
Vue
604 lines
23 KiB
Vue
<template>
|
||
<view class="zcfangan">
|
||
<view class="name" style="margin-bottom: 24rpx;font-size:36rpx;font-weight: 700;">
|
||
选择套餐
|
||
</view>
|
||
<view class="fanganlist">
|
||
<view hover-class="app-tap-hover"
|
||
v-for="(item,index) in taocanlist" :key="index"
|
||
:class="['fanganlist_item', fanganindex == index ? 'gaoliang' : '', item.ridingRule == 2 ? 'interval-billing' : '', item.ridingRule == 3 ? 'deadline-billing' : '']"
|
||
@click="onSelect(index, item)">
|
||
<view class="check-icon" v-if="fanganindex == index">
|
||
<text class="check-mark">✓</text>
|
||
</view>
|
||
|
||
<template v-if="item.ridingRule == 1">
|
||
<scroll-view
|
||
class="package-name-wrapper"
|
||
:id="'package-name-' + index"
|
||
:ref="'packageName' + index"
|
||
scroll-x="true"
|
||
:scroll-left="packageNameScrollLeft[index] || 0"
|
||
:show-scrollbar="false"
|
||
:enable-back-to-top="false"
|
||
:scroll-with-animation="false">
|
||
<view class="package-name-content" :style="{ justifyContent: packageNeedScroll[index] ? 'flex-start' : 'center' }">
|
||
<view class="package-name" :class="{ 'selected': fanganindex == index }">{{item.name}}</view>
|
||
<view v-if="packageNeedScroll[index]" class="package-name package-name-duplicate" style="margin-left: 40rpx;" :class="{ 'selected': fanganindex == index }">{{item.name}}</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="package-price">
|
||
<text class="price-value">{{item.startRule.startingPrice}}</text>
|
||
<text class="price-unit">元</text>
|
||
</view>
|
||
<view class="package-duration">{{getPackageDuration(item)}}</view>
|
||
</template>
|
||
|
||
<template v-if="item.ridingRule == 2">
|
||
<scroll-view
|
||
class="package-name-wrapper"
|
||
:id="'package-name-' + index"
|
||
:ref="'packageName' + index"
|
||
scroll-x="true"
|
||
:scroll-left="packageNameScrollLeft[index] || 0"
|
||
:show-scrollbar="false"
|
||
:enable-back-to-top="false"
|
||
:scroll-with-animation="false">
|
||
<view class="package-name-content" :style="{ justifyContent: packageNeedScroll[index] ? 'flex-start' : 'center' }">
|
||
<view class="package-name" :class="{ 'selected': fanganindex == index }">{{item.name}}</view>
|
||
<view v-if="packageNeedScroll[index]" class="package-name package-name-duplicate" style="margin-left: 40rpx;" :class="{ 'selected': fanganindex == index }">{{item.name}}</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="interval-list">
|
||
<view class="interval-item" v-for="(rule, ruleIndex) in item.intervalRule" :key="ruleIndex">
|
||
<view class="interval-content">
|
||
<view class="interval-left">
|
||
<text class="interval-range">
|
||
<text v-if="rule.end == null || rule.end === undefined">
|
||
{{rule.start == null ? '0' : rule.start}}
|
||
<text v-if="item.rentalUnit == 'hours'">时</text>
|
||
<text v-if="item.rentalUnit == 'minutes'">分</text>
|
||
<text v-if="item.rentalUnit == 'day'">天</text>
|
||
以上
|
||
</text>
|
||
<text v-else>
|
||
{{rule.start == null ? '0' : rule.start}}-{{rule.end}}
|
||
<text v-if="item.rentalUnit == 'hours'">时</text>
|
||
<text v-if="item.rentalUnit == 'minutes'">分</text>
|
||
<text v-if="item.rentalUnit == 'day'">天</text>
|
||
</text>
|
||
</text>
|
||
</view>
|
||
<view class="interval-right">
|
||
每<text class="interval-price">{{rule.fee}}</text>
|
||
<text class="interval-unit">元/{{rule.eachUnit}}
|
||
<text v-if="item.rentalUnit == 'hours'">时</text>
|
||
<text v-if="item.rentalUnit == 'minutes'">分</text>
|
||
<text v-if="item.rentalUnit == 'day'">天</text>
|
||
</text>
|
||
</view>
|
||
</view>
|
||
<view class="interval-divider" v-if="ruleIndex < item.intervalRule.length - 1"></view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<template v-if="item.ridingRule == 3">
|
||
<scroll-view
|
||
class="package-name-wrapper"
|
||
:id="'package-name-' + index"
|
||
:ref="'packageName' + index"
|
||
scroll-x="true"
|
||
:scroll-left="packageNameScrollLeft[index] || 0"
|
||
:show-scrollbar="false"
|
||
:enable-back-to-top="false"
|
||
:scroll-with-animation="false">
|
||
<view class="package-name-content" :style="{ justifyContent: packageNeedScroll[index] ? 'flex-start' : 'center' }">
|
||
<view class="package-name" :class="{ 'selected': fanganindex == index }">{{item.name}}</view>
|
||
<view v-if="packageNeedScroll[index]" class="package-name package-name-duplicate" style="margin-left: 40rpx;" :class="{ 'selected': fanganindex == index }">{{item.name}}</view>
|
||
</view>
|
||
</scroll-view>
|
||
<view class="package-price">
|
||
<text class="price-value">{{item.deadlineRule && item.deadlineRule.basePrice != null ? item.deadlineRule.basePrice : 0}}</text>
|
||
<text class="price-unit">元</text>
|
||
</view>
|
||
<view class="package-duration">{{item.deadlineRule && item.deadlineRule.deadlineTime ? item.deadlineRule.deadlineTime : '23:59:59'}}前还车</view>
|
||
</template>
|
||
</view>
|
||
</view>
|
||
|
||
<view class="wei" v-if="taocanlist.length == 0">
|
||
当前车辆车型未配置套餐,请管理员前往车型中配置!
|
||
</view>
|
||
|
||
<view class="package-info-box" v-if="taocanlist.length != 0">
|
||
<view class="package-header">
|
||
<view class="package-title">套餐说明</view>
|
||
<view class="package-buttons">
|
||
<view class="parking-btn" @click="onElectronicFence">
|
||
<u-icon name="tags" color="#4297F3" size="22"></u-icon>
|
||
<text class="btn-text">电子围栏</text>
|
||
</view>
|
||
<view class="parking-btn" @click="$emit('check-location')">
|
||
<u-icon name="map" color="#4297F3" size="22"></u-icon>
|
||
<text class="btn-text">还车点</text>
|
||
</view>
|
||
<view class="parking-btn" @click="$emit('contact-service')">
|
||
<u-icon name="phone-fill" color="#4297F3" size="22"></u-icon>
|
||
<text class="btn-text">客服</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="package-content">
|
||
<view class="info-item" v-if="actiobj.freeRideTime != null && actiobj.freeRideTime != '' && actiobj.freeRideTime != 0">
|
||
<view class="info-icon-wrap"><u-icon name="clock" color="#10B981" size="28"></u-icon></view>
|
||
<view class="info-text">
|
||
免费骑行<text class="highlight">{{actiobj.freeRideTime == null ? '0' : actiobj.freeRideTime}}</text>分钟
|
||
</view>
|
||
</view>
|
||
<view class="info-item" v-if="taocanlist[fanganindex] && taocanlist[fanganindex].ridingRule == 1">
|
||
<view class="info-icon-wrap"><u-icon name="red-packet" color="#F17F37" size="28"></u-icon></view>
|
||
<view class="info-text">
|
||
超出计费<text class="highlight">{{taocanlist[fanganindex].startRule.timeoutPrice}}</text>元/<text class="highlight">{{taocanlist[fanganindex].startRule.timeoutTime}}</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">小时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分钟</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
,不足<text class="highlight">{{taocanlist[fanganindex].startRule.timeoutTime}}</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">小时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分钟</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
按<text class="highlight">{{taocanlist[fanganindex].startRule.timeoutTime}}</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">小时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分钟</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>算
|
||
</view>
|
||
</view>
|
||
<view class="info-item" v-if="taocanlist[fanganindex] && taocanlist[fanganindex].ridingRule == 2 && taocanlist[fanganindex].intervalRule && taocanlist[fanganindex].intervalRule.length > 0">
|
||
<view class="info-icon-wrap"><u-icon name="red-packet" color="#F17F37" size="28"></u-icon></view>
|
||
<view class="info-text">
|
||
区间计费:
|
||
<text v-for="(rule, ruleIndex) in taocanlist[fanganindex].intervalRule" :key="ruleIndex">
|
||
<text v-if="rule.end == null || rule.end === undefined">
|
||
{{rule.start == null ? '0' : rule.start}}
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
以上每<text class="highlight">{{rule.eachUnit}}</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
<text class="highlight">{{rule.fee}}</text>元
|
||
</text>
|
||
<text v-else>
|
||
{{rule.start == null ? '0' : rule.start}}-{{rule.end}}
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
每<text class="highlight">{{rule.eachUnit}}</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
<text class="highlight">{{rule.fee}}</text>元
|
||
</text>
|
||
<text v-if="ruleIndex < taocanlist[fanganindex].intervalRule.length - 1">;</text>
|
||
</text>
|
||
</view>
|
||
</view>
|
||
<view class="info-item" v-if="taocanlist[fanganindex] && taocanlist[fanganindex].ridingRule == 3 && taocanlist[fanganindex].deadlineRule">
|
||
<view class="info-icon-wrap"><u-icon name="red-packet" color="#F17F37" size="28"></u-icon></view>
|
||
<view class="info-text">
|
||
支付后第<text class="highlight">{{taocanlist[fanganindex].deadlineRule.dayOffset || 1}}</text>天(第1天为当天)截止<text class="highlight">{{taocanlist[fanganindex].deadlineRule.deadlineTime || '23:59:59'}}</text>前还车收费
|
||
<text class="highlight">{{taocanlist[fanganindex].deadlineRule.basePrice || 0}}</text>元,超时后每<text class="highlight">{{taocanlist[fanganindex].deadlineRule.overtimeUnit || 1}}</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'hours'">小时</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'minutes'">分钟</text>
|
||
<text v-if="taocanlist[fanganindex].rentalUnit == 'day'">天</text>
|
||
收费<text class="highlight">{{taocanlist[fanganindex].deadlineRule.overtimePrice || 0}}</text>元
|
||
</view>
|
||
</view>
|
||
<view class="info-item" v-if="bikeobj.areaDispatchFee != null">
|
||
<view class="info-icon-wrap"><u-icon name="map" color="#666" size="28"></u-icon></view>
|
||
<view class="info-text">
|
||
还车点外还车将额外产生调度费<text class="highlight">{{bikeobj.areaDispatchFee == null ? '--' : bikeobj.areaDispatchFee}}</text>元
|
||
</view>
|
||
</view>
|
||
<view class="info-item" v-if="bikeobj.areaVehicleManagementFee != null">
|
||
<view class="info-icon-wrap"><u-icon name="map" color="#666" size="28"></u-icon></view>
|
||
<view class="info-text">
|
||
运营区外还车将额外产生调度费<text class="highlight">{{bikeobj.areaVehicleManagementFee == null ? '--' : bikeobj.areaVehicleManagementFee}}</text>元
|
||
</view>
|
||
</view>
|
||
<view class="info-item" v-if="instructions != null && instructions != ''">
|
||
<view class="info-icon-wrap"><u-icon name="file-text" color="#4297F3" size="28"></u-icon></view>
|
||
<view class="info-text">说明:{{instructions == null ? '暂无说明' : instructions}}</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'PackageSelector',
|
||
props: {
|
||
taocanlist: { type: Array, default: () => [] },
|
||
fanganindex: { type: Number, default: 0 },
|
||
bikeobj: { type: Object, default: () => ({}) },
|
||
actiobj: { type: Object, default: () => ({}) },
|
||
instructions: { type: String, default: '' }
|
||
},
|
||
data() {
|
||
return {
|
||
packageNameScrollLeft: {},
|
||
packageNeedScroll: {},
|
||
scrollTimers: {},
|
||
scrollPauseTimers: {}
|
||
}
|
||
},
|
||
watch: {
|
||
// 不在此监听 fanganindex:与 onSelect 里 startAutoScroll 重复触发,会叠加多套定时器导致横向滚动失控
|
||
taocanlist(newList) {
|
||
if (newList.length > 0) {
|
||
this.$nextTick(() => {
|
||
setTimeout(() => {
|
||
this.startAutoScroll(0)
|
||
}, 800)
|
||
})
|
||
}
|
||
}
|
||
},
|
||
beforeDestroy() {
|
||
this.clearAllScrollTimers()
|
||
},
|
||
methods: {
|
||
clearAllScrollTimers() {
|
||
for (let key in this.scrollTimers) {
|
||
if (this.scrollTimers[key]) {
|
||
clearInterval(this.scrollTimers[key])
|
||
delete this.scrollTimers[key]
|
||
}
|
||
}
|
||
for (let key in this.scrollPauseTimers) {
|
||
if (this.scrollPauseTimers[key]) {
|
||
clearTimeout(this.scrollPauseTimers[key])
|
||
delete this.scrollPauseTimers[key]
|
||
}
|
||
}
|
||
},
|
||
onElectronicFence() {
|
||
const id = this.bikeobj && this.bikeobj.areaId
|
||
if (!id) {
|
||
uni.showToast({ title: '未获取到运营区信息', icon: 'none' })
|
||
return
|
||
}
|
||
uni.navigateTo({
|
||
url: '/pages/myorder/returned/tingche?areaId=' + id + '&mode=fence'
|
||
})
|
||
},
|
||
onSelect(index, item) {
|
||
this.clearAllScrollTimers()
|
||
const list = this.taocanlist || []
|
||
for (let i = 0; i < list.length; i++) {
|
||
this.$set(this.packageNameScrollLeft, i, 0)
|
||
this.$set(this.packageNeedScroll, i, false)
|
||
}
|
||
this.$emit('select', index, item)
|
||
this.$nextTick(() => {
|
||
this.startAutoScroll(index)
|
||
})
|
||
},
|
||
startAutoScroll(index) {
|
||
if (this.scrollTimers[index]) {
|
||
clearInterval(this.scrollTimers[index])
|
||
delete this.scrollTimers[index]
|
||
}
|
||
const startKey = 'start_' + index
|
||
if (this.scrollPauseTimers[startKey]) {
|
||
clearTimeout(this.scrollPauseTimers[startKey])
|
||
delete this.scrollPauseTimers[startKey]
|
||
}
|
||
this.$set(this.packageNeedScroll, index, false)
|
||
this.$set(this.packageNameScrollLeft, index, 0)
|
||
|
||
const packageItem = this.taocanlist[index]
|
||
if (!packageItem || !packageItem.name || packageItem.name.length <= 10) return
|
||
|
||
this.$nextTick(() => {
|
||
setTimeout(() => {
|
||
const query = uni.createSelectorQuery().in(this)
|
||
query.select('#package-name-' + index).boundingClientRect((containerRect) => {
|
||
if (containerRect && containerRect.width) {
|
||
const query2 = uni.createSelectorQuery().in(this)
|
||
query2.select('#package-name-' + index + ' .package-name').boundingClientRect((contentRect) => {
|
||
if (contentRect && contentRect.width) {
|
||
if (contentRect.width > containerRect.width) {
|
||
this.$set(this.packageNeedScroll, index, true)
|
||
this.$nextTick(() => {
|
||
setTimeout(() => {
|
||
const maxScrollLeft = contentRect.width
|
||
this.$set(this.packageNameScrollLeft, index, 0)
|
||
setTimeout(() => {
|
||
this.startLoopScroll(index, maxScrollLeft)
|
||
}, 300)
|
||
}, 100)
|
||
})
|
||
} else {
|
||
this.$set(this.packageNeedScroll, index, false)
|
||
this.$set(this.packageNameScrollLeft, index, 0)
|
||
}
|
||
}
|
||
}).exec()
|
||
}
|
||
}).exec()
|
||
}, 300)
|
||
})
|
||
},
|
||
startLoopScroll(index, maxScrollLeft) {
|
||
if (this.scrollTimers[index]) {
|
||
clearInterval(this.scrollTimers[index])
|
||
delete this.scrollTimers[index]
|
||
}
|
||
const startKey = 'start_' + index
|
||
if (this.scrollPauseTimers[startKey]) {
|
||
clearTimeout(this.scrollPauseTimers[startKey])
|
||
delete this.scrollPauseTimers[startKey]
|
||
}
|
||
let currentScroll = 0
|
||
const scrollStep = 0.5
|
||
const startTimer = setTimeout(() => {
|
||
this.scrollTimers[index] = setInterval(() => {
|
||
if (!this.scrollTimers[index]) return
|
||
currentScroll += scrollStep
|
||
if (currentScroll >= maxScrollLeft) currentScroll = 0
|
||
this.$set(this.packageNameScrollLeft, index, Math.round(currentScroll))
|
||
}, 80)
|
||
}, 600)
|
||
this.scrollPauseTimers[startKey] = startTimer
|
||
},
|
||
getPackageDuration(item) {
|
||
if (item.ridingRule == 1 && item.startRule) {
|
||
let time = item.startRule.startingTime
|
||
if (item.rentalUnit == 'hours') return time + '小时'
|
||
if (item.rentalUnit == 'minutes') return time + '分钟'
|
||
if (item.rentalUnit == 'day') return time + '天'
|
||
return time + '分钟'
|
||
} else if (item.ridingRule == 2 && item.intervalRule && item.intervalRule.length > 0) {
|
||
let lastRule = item.intervalRule[item.intervalRule.length - 1]
|
||
let end = lastRule.end
|
||
if (end == null || end === undefined) {
|
||
let nameMatch = item.name.match(/(\d+)/)
|
||
if (nameMatch) end = parseInt(nameMatch[1])
|
||
else return '不限'
|
||
}
|
||
if (item.rentalUnit == 'hours') return end + '小时'
|
||
if (item.rentalUnit == 'minutes') return end + '分钟'
|
||
if (item.rentalUnit == 'day') return end + '天'
|
||
return end + '分钟'
|
||
} else if (item.ridingRule == 3 && item.deadlineRule) {
|
||
return '截止' + (item.deadlineRule.deadlineTime || '23:59:59')
|
||
}
|
||
let nameMatch = item.name.match(/(\d+)/)
|
||
if (nameMatch) {
|
||
let num = parseInt(nameMatch[1])
|
||
if (item.name.includes('小时') || item.name.includes('时')) return num + '小时'
|
||
if (item.name.includes('天')) return num + '天'
|
||
if (item.name.includes('分钟') || item.name.includes('分')) return num + '分钟'
|
||
}
|
||
return '--'
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.zcfangan {
|
||
margin: auto;
|
||
padding-right: 0 !important;
|
||
box-sizing: border-box;
|
||
width: 698rpx;
|
||
border-radius: 20rpx;
|
||
margin-top: 16rpx;
|
||
|
||
.name {
|
||
font-size: 32rpx;
|
||
color: #111827;
|
||
font-weight: 700;
|
||
letter-spacing: 0.5rpx;
|
||
}
|
||
.wei {
|
||
margin-top: 30rpx;
|
||
width: 100%;
|
||
text-align: center;
|
||
color: #ccc;
|
||
}
|
||
.fanganlist {
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
justify-content: space-between;
|
||
gap: 16rpx;
|
||
|
||
.fanganlist_item {
|
||
position: relative;
|
||
width: 48%;
|
||
padding: 28rpx 20rpx;
|
||
background: #fff;
|
||
border-radius: 20rpx;
|
||
border: 3rpx solid #E5E7EB;
|
||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.06);
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: center;
|
||
height: 218rpx;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
transition: all 0.3s ease;
|
||
|
||
.check-icon {
|
||
position: absolute;
|
||
bottom: 0;
|
||
right: 0;
|
||
width: 56rpx;
|
||
height: 56rpx;
|
||
background: linear-gradient(135deg, #4297F3 0%, #60A5FA 100%);
|
||
clip-path: polygon(100% 0, 100% 100%, 0 100%);
|
||
display: flex;
|
||
align-items: flex-end;
|
||
justify-content: flex-end;
|
||
padding: 0 6rpx 6rpx 0;
|
||
box-sizing: border-box;
|
||
z-index: 10;
|
||
.check-mark {
|
||
font-size: 28rpx;
|
||
font-weight: 700;
|
||
color: #FFFFFF;
|
||
line-height: 1;
|
||
}
|
||
}
|
||
|
||
.package-name-wrapper {
|
||
width: 100%;
|
||
margin-bottom: 18rpx;
|
||
::v-deep .uni-scroll-view { width: 100%; }
|
||
::v-deep .uni-scroll-view-content { display: flex; align-items: center; }
|
||
}
|
||
.package-name-content {
|
||
display: flex;
|
||
align-items: center;
|
||
white-space: nowrap;
|
||
}
|
||
.package-name {
|
||
font-size: 32rpx;
|
||
font-weight: 700;
|
||
color: #1F2937;
|
||
text-align: center;
|
||
letter-spacing: 0.5rpx;
|
||
white-space: nowrap;
|
||
display: inline-block;
|
||
flex-shrink: 0;
|
||
&.selected { color: #4297F3; font-weight: 700; }
|
||
}
|
||
.package-price {
|
||
display: flex;
|
||
align-items: baseline;
|
||
justify-content: center;
|
||
margin-bottom: 10rpx;
|
||
.price-value { font-size: 52rpx; font-weight: 700; color: #F17F37; line-height: 1; letter-spacing: -1rpx; }
|
||
.price-unit { font-size: 30rpx; font-weight: 600; color: #F17F37; margin-left: 4rpx; }
|
||
}
|
||
.package-duration { font-size: 26rpx; font-weight: 500; color: #6B7280; text-align: center; }
|
||
|
||
&.gaoliang {
|
||
border-color: #4297F3;
|
||
border-width: 3rpx;
|
||
background: linear-gradient(135deg, #F0F7FF 0%, #FFFFFF 100%);
|
||
box-shadow: 0 6rpx 20rpx rgba(66, 151, 243, 0.25);
|
||
}
|
||
|
||
&.interval-billing {
|
||
align-items: flex-start;
|
||
padding: 24rpx;
|
||
min-height: auto;
|
||
justify-content: flex-start;
|
||
.package-name-wrapper { margin-bottom: 24rpx; width: 100%; }
|
||
.interval-list {
|
||
width: 100%;
|
||
margin-bottom: 16rpx;
|
||
background: #F9FAFB;
|
||
border-radius: 12rpx;
|
||
padding: 12rpx;
|
||
.interval-item {
|
||
width: 100%;
|
||
.interval-content {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
padding: 14rpx 0;
|
||
.interval-left {
|
||
display: flex; align-items: center; flex: 1;
|
||
.interval-range { font-size: 28rpx; font-weight: 600; color: #111827; line-height: 1.6; }
|
||
}
|
||
.interval-right {
|
||
display: flex; align-items: baseline; flex-shrink: 0; font-weight: 500;
|
||
.interval-price { font-size: 30rpx; font-weight: 700; color: #F17F37; margin-right: 6rpx; }
|
||
.interval-unit { font-size: 26rpx; color: #6B7280; }
|
||
}
|
||
}
|
||
.interval-divider {
|
||
width: 100%; height: 2rpx;
|
||
background: repeating-linear-gradient(to right, #E5E7EB 0, #E5E7EB 8rpx, transparent 8rpx, transparent 16rpx);
|
||
margin: 14rpx 0;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.package-info-box {
|
||
width: 698rpx;
|
||
margin: 24rpx auto 0;
|
||
background: #fff;
|
||
border-radius: 24rpx;
|
||
padding: 32rpx;
|
||
box-sizing: border-box;
|
||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.08);
|
||
border: 1rpx solid #F3F4F6;
|
||
|
||
.package-header {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
margin-bottom: 24rpx;
|
||
}
|
||
.package-title { font-size: 32rpx; color: #1F2937; font-weight: 700; letter-spacing: 0.5rpx; }
|
||
.package-content {
|
||
.info-item {
|
||
display: flex;
|
||
flex-direction: row;
|
||
align-items: flex-start;
|
||
padding: 8rpx 0;
|
||
border-left: 4rpx solid transparent;
|
||
&:last-child { margin-bottom: 0; }
|
||
.info-icon-wrap {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
flex-shrink: 0;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
margin-right: 8rpx;
|
||
}
|
||
.info-text {
|
||
flex: 1;
|
||
min-width: 0;
|
||
font-size: 28rpx;
|
||
font-weight: 500;
|
||
color: #374151;
|
||
line-height: 40rpx;
|
||
margin-left: 0;
|
||
.highlight { color: #F17F37; font-weight: 700; font-size: 30rpx; }
|
||
}
|
||
}
|
||
}
|
||
.package-buttons {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 12rpx;
|
||
.parking-btn {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
padding: 8rpx 18rpx;
|
||
background: rgba(66, 151, 243, 0.1);
|
||
border: 1rpx solid rgba(66, 151, 243, 0.3);
|
||
border-radius: 32rpx;
|
||
gap: 6rpx;
|
||
transition: all 0.2s ease;
|
||
&:active { transform: scale(0.96); background: rgba(66, 151, 243, 0.15); }
|
||
.btn-text { font-size: 24rpx; color: #4297F3; font-weight: 500; }
|
||
}
|
||
}
|
||
}
|
||
</style>
|