chuangte_bike_newxcx/page_shanghu/gongzuotai/ChargingTemplate.vue

565 lines
13 KiB
Vue
Raw 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">
<u-navbar title="套餐模板" :border-bottom="false" :background="bgc" title-color='#000' title-size='36' back-icon-color="#000"
height='44'></u-navbar>
<view class="content">
<view class="modelCard" v-for="(item,index) in list" :key="index">
<view class="card-header">
<view class="title-wrap">
<text class="title">{{item.name}}</text>
<view class="tag"
:class="item.ridingRule == 1 ? 'tag-normal' : (item.ridingRule == 2 ? 'tag-interval' : 'tag-deadline')">
{{item.ridingRule == 1 ? '普通计费' : (item.ridingRule == 2 ? '区间计费' : '截止计费')}}
</view>
</view>
<u-switch v-model="item.isOpen" @change="change(item)" active-color="#4C97E7" size="40"></u-switch>
</view>
<view class="divider"></view>
<view class="card-body">
<view class="info-row" v-if="item.instructions">
<text class="label">说明:</text>
<text class="value">{{item.instructions}}</text>
</view>
<!-- 普通计费展示 -->
<view v-if="item.ridingRule==1 && item.startRule" class="rule-box normal-rule">
<view class="rule-row">
<view class="rule-item">
<text class="item-label">起步价</text>
<view class="item-value-box">
<text class="price">{{item.startRule.startingPrice || '0'}}</text>
<text class="unit">元</text>
</view>
<text class="item-desc">含{{item.startRule.startingTime || '0'}}{{getUnitText(item.rentalUnit)}}</text>
</view>
<view class="v-divider"></view>
<view class="rule-item">
<text class="item-label">时长费</text>
<view class="item-value-box">
<text class="price">{{item.startRule.timeoutPrice || '0'}}</text>
<text class="unit">元</text>
</view>
<text class="item-desc">每{{ item.startRule.timeoutTime || '1'}}{{getUnitText(item.rentalUnit)}}</text>
</view>
</view>
</view>
<!-- 区间计费展示 -->
<view v-if="item.ridingRule==2 && item.intervalRule" class="rule-box interval-rule">
<view class="interval-list">
<view class="interval-item" v-for="(rule, ruleIndex) in item.intervalRule" :key="ruleIndex">
<view class="time-range">
<view class="dot"></view>
<text v-if="ruleIndex === item.intervalRule.length-1">
{{rule.start}} {{getUnitText(item.rentalUnit)}}以上
</text>
<text v-else>
{{rule.start}}-{{rule.end}} {{getUnitText(item.rentalUnit)}}
</text>
</view>
<view class="price-info">
<text class="price">{{rule.fee}}</text>
<text class="unit">元/{{rule.eachUnit}}{{getUnitText(item.rentalUnit)}}</text>
</view>
</view>
</view>
<view class="interval-tip">
<u-icon name="info-circle" color="#4C97E7" size="24" style="margin-right: 8rpx;"></u-icon>
<text>不同时段按对应标准计费</text>
</view>
</view>
<!-- 截止计费展示 -->
<view v-if="item.ridingRule==3 && item.deadlineRule" class="rule-box deadline-rule">
<view class="deadline-line">
支付后第{{item.deadlineRule.dayOffset || 1}}天第1天为当天截止{{item.deadlineRule.deadlineTime || '23:59:59'}}前还车收费{{item.deadlineRule.basePrice || 0}}元
</view>
<view class="deadline-line">
超时后每{{item.deadlineRule.overtimeUnit || 1}}{{getUnitText(item.rentalUnit)}}收费{{item.deadlineRule.overtimePrice || 0}}元
</view>
</view>
<!-- 无数据提示 -->
<view v-if="!item.startRule && !item.intervalRule && !item.deadlineRule" class="no-data">
暂无计费规则数据
</view>
</view>
<view class="card-footer">
<view class="action-btn delete" @click="del(item)">
<u-icon name="trash" size="32"></u-icon>
<text>删除</text>
</view>
<view class="v-divider"></view>
<view class="action-btn edit" @click="todetail(item)">
<u-icon name="edit-pen" size="32"></u-icon>
<text>编辑</text>
</view>
</view>
</view>
<view class="loading-text">
{{ list.length == 0 ? '暂无模板' : '当前没有更多模版咯...' }}
</view>
<view style="height: 120rpx;"></view>
</view>
<view class="fixed-btn-box">
<view class="add-btn" @click="addmodel()">
<u-icon name="plus" color="#fff" size="32" style="margin-right: 10rpx;"></u-icon>
新增模板
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
bgc: {
backgroundColor: "#F7F7F7",
},
list: [],
areaId:''
}
},
onShow() {
if (uni.getStorageSync('adminAreaid')) {
this.areaId = uni.getStorageSync('adminAreaid')
}
this.getModelList()
},
methods: {
parseRule(rule) {
if (!rule) return null
if (typeof rule === 'object') return rule
if (typeof rule !== 'string') return null
try {
return JSON.parse(rule)
} catch (error) {
return null
}
},
getUnitText(unit) {
const map = {
'minutes': '分钟',
'hours': '小时',
'day': '天'
}
return map[unit] || '分钟'
},
// 停用按钮
change(item){
console.log(item);
let data = {
id:item.id,
status: item.isOpen ? 0 : 1
}
this.$u.put(`/bst/suit`,data).then(res =>{
if(res.code == 200){
uni.showToast({
title: '操作成功',
icon: 'success',
duration:2000
})
this.getModelList()
}else{
uni.showToast({
title: res.msg,
icon: 'none',
duration:2000
})
// Revert if failed
item.isOpen = !item.isOpen;
}
}).catch(() => {
item.isOpen = !item.isOpen;
})
},
addmodel() {
uni.navigateTo({
url: '/page_shanghu/gongzuotai/ChargingDetail'
})
},
del(item) {
// 显示确认删除的提示框
uni.showModal({
title: '确认删除',
content: '确定删除该收费方式?',
success: (res) => {
if (res.confirm) {
// 如果用户点击了确认,执行删除操作
this.$u.delete(`/bst/suit/${item.id}`).then((res) => {
if (res.code == 200) {
this.getModelList(); // 刷新列表
} else {
// 处理接口返回错误的情况
uni.showToast({
title: res.msg,
icon: 'none',
duration:2000
});
}
})
} else if (res.cancel) {
// 用户取消删除操作
console.log('取消删除')
}
}
});
},
todetail(item) {
uni.navigateTo({
url: '/page_shanghu/gongzuotai/ChargingDetail?ruleId=' + item.id
})
},
getModelList() {
if (!this.areaId && uni.getStorageSync('adminAreaid')) {
this.areaId = uni.getStorageSync('adminAreaid')
}
this.$u.get("/getInfo").then(res => {
if(res.code == 200){
const areaParam = this.areaId ? `&areaId=${this.areaId}` : ''
this.$u.get(`/bst/suit/list?pageNum=1&pageSize=999${areaParam}&temp=false`).then((res) => {
if (res.code == 200) {
this.list = res.rows.map(item => {
item.ridingRule = Number(item.ridingRule || 1)
const parsedRule = this.parseRule(item.rule)
if (item.ridingRule === 1) {
item.startRule = parsedRule && !Array.isArray(parsedRule)
? parsedRule
: (this.parseRule(item.startRule) || item.startRule || null)
item.intervalRule = null
item.deadlineRule = null
} else if (item.ridingRule === 2) {
item.intervalRule = Array.isArray(parsedRule)
? parsedRule
: (this.parseRule(item.intervalRule) || item.intervalRule || null)
item.startRule = null
item.deadlineRule = null
} else if (item.ridingRule === 3) {
item.deadlineRule = parsedRule && !Array.isArray(parsedRule)
? parsedRule
: null
item.startRule = null
item.intervalRule = null
} else {
item.startRule = null
item.intervalRule = null
item.deadlineRule = null
}
item.isOpen = item.status == 0
return item
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration:2000
})
}
})
}
})
},
}
}
</script>
<style lang="scss" scoped>
page {
background-color: #F7F7F7;
}
.page {
min-height: 100vh;
}
.content {
padding: 24rpx;
}
.modelCard {
background: #FFFFFF;
border-radius: 20rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.03);
overflow: hidden;
.card-header {
padding: 24rpx 30rpx;
display: flex;
justify-content: space-between;
align-items: center;
.title-wrap {
display: flex;
align-items: center;
.title {
font-size: 32rpx;
font-weight: 600;
color: #333;
margin-right: 16rpx;
}
.tag {
font-size: 20rpx;
padding: 4rpx 12rpx;
border-radius: 8rpx;
&.tag-normal {
background: #EBF4FF;
color: #4C97E7;
}
&.tag-interval {
background: #F0F9EB;
color: #67C23A;
}
&.tag-deadline {
background: #FFF7E6;
color: #FA8C16;
}
}
}
}
.divider {
height: 1rpx;
background: #f5f5f5;
margin: 0 24rpx;
}
.card-body {
padding: 24rpx 30rpx;
.info-row {
display: flex;
font-size: 26rpx;
margin-bottom: 24rpx;
.label {
color: #999;
min-width: 80rpx;
}
.value {
color: #666;
flex: 1;
}
}
.rule-box {
background: #F8F9FB;
border-radius: 12rpx;
padding: 24rpx;
&.normal-rule {
.rule-row {
display: flex;
align-items: center;
.rule-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
.item-label {
font-size: 24rpx;
color: #999;
margin-bottom: 8rpx;
}
.item-value-box {
display: flex;
align-items: baseline;
margin-bottom: 8rpx;
.price {
font-size: 40rpx;
font-weight: 600;
color: #333;
line-height: 1;
}
.unit {
font-size: 24rpx;
color: #666;
margin-left: 4rpx;
}
}
.item-desc {
font-size: 22rpx;
color: #999;
}
}
.v-divider {
width: 1rpx;
height: 60rpx;
background: #E0E0E0;
margin: 0 20rpx;
}
}
}
&.interval-rule {
.interval-list {
.interval-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 16rpx 0;
border-bottom: 1rpx dashed #E0E0E0;
&:last-child {
border-bottom: none;
}
.time-range {
display: flex;
align-items: center;
font-size: 28rpx;
color: #333;
.dot {
width: 8rpx;
height: 8rpx;
background: #4C97E7;
border-radius: 50%;
margin-right: 12rpx;
}
}
.price-info {
display: flex;
align-items: baseline;
.price {
font-size: 32rpx;
font-weight: 600;
color: #FF4D4F;
margin-right: 4rpx;
}
.unit {
font-size: 22rpx;
color: #999;
}
}
}
}
.interval-tip {
margin-top: 16rpx;
font-size: 22rpx;
color: #4C97E7;
display: flex;
align-items: center;
background: #EBF4FF;
padding: 8rpx 16rpx;
border-radius: 8rpx;
}
}
&.deadline-rule {
.deadline-line {
font-size: 24rpx;
color: #666;
line-height: 1.8;
}
}
}
.no-data {
text-align: center;
color: #ccc;
font-size: 24rpx;
padding: 20rpx 0;
}
}
.card-footer {
border-top: 1rpx solid #f5f5f5;
display: flex;
align-items: center;
height: 88rpx;
.action-btn {
flex: 1;
display: flex;
justify-content: center;
align-items: center;
font-size: 28rpx;
text {
margin-left: 10rpx;
}
&.delete {
color: #FF4D4F;
}
&.edit {
color: #4C97E7;
}
&:active {
background: #f9f9f9;
}
}
.v-divider {
width: 1rpx;
height: 32rpx;
background: #E0E0E0;
}
}
}
.loading-text {
text-align: center;
color: #999;
font-size: 24rpx;
padding: 20rpx 0;
}
.fixed-btn-box {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
padding: 20rpx 40rpx;
padding-bottom: 40rpx;
background: #fff;
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05);
z-index: 10;
.add-btn {
width: 100%;
height: 88rpx;
background: #4C97E7;
border-radius: 44rpx;
color: #fff;
font-size: 32rpx;
font-weight: 600;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(76, 151, 231, 0.3);
&:active {
opacity: 0.9;
}
}
}
</style>