chuangte_bike_newxcx/page_shanghu/linshishoufei.vue

1378 lines
34 KiB
Vue
Raw Normal View History

2025-12-20 14:29:10 +08:00
<template>
<view class="page">
2026-04-02 01:48:12 +08:00
<u-navbar title="临时收费" :border-bottom="false" :background="bgc" title-color='#000' title-size='36' back-icon-color="#000"
height='44'></u-navbar>
2025-12-20 14:29:10 +08:00
<view class="tclist">
<scroll-view scroll-x="true" class="tcbox" enable-flex>
<view :class="['tcitem', tabindex == index ? 'acitve' : '']" v-for="(item,index) in taocanlist" :key="index" @click="btnitem(item,index)">
<view class="tcname">
{{item.name.length > 5 ? item.name.slice(0,4) + '...' : item.name}}
</view>
<view class="tcsm">
押金{{item.depositAmount}}
</view>
</view>
</scroll-view>
</view>
2026-04-02 01:48:12 +08:00
<view class="content">
<view class="form-card">
<view class="card-title">基本信息</view>
<view class="form-item">
<view class="label">套餐名称</view>
<input type="text" v-model="data.name" placeholder="请输入套餐名称" class="input" placeholder-style="color:#C7CDD3">
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="form-item">
<view class="label">说明内容</view>
<input type="text" v-model="data.instructions" placeholder="请输入说明内容" class="input" placeholder-style="color:#C7CDD3">
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="form-item">
<view class="label">显示顺序</view>
<input type="number" v-model="data.orderNum" placeholder="请输入显示顺序" class="input" placeholder-style="color:#C7CDD3">
</view>
<view class="tips">数字越小越靠前</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="form-card">
<view class="card-title">收费设置</view>
<view class="form-item">
<view class="label">租赁单位</view>
<view class="radio-group">
<view class="radio-tag"
v-for="(item, index) in timeList"
:key="index"
:class="{active: timevalue === item.name}"
@click="radioGroupChange(item.name)">
{{item.name}}
</view>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
<view class="form-item">
<view class="label">计费方式</view>
<view class="radio-group radio-group-wrap">
<view class="radio-tag"
:class="{active: data.ridingRule == 1}"
@click="chargeTypeChange(1)">
普通计费
</view>
<view class="radio-tag"
:class="{active: data.ridingRule == 2}"
@click="chargeTypeChange(2)">
区间计费
</view>
<view class="radio-tag"
:class="{active: data.ridingRule == 3}"
@click="chargeTypeChange(3)">
截止计费
</view>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
<template v-if="data.ridingRule == 1">
<view class="rule-box normal-rule">
<view class="rule-row">
<text class="rule-label">起步价</text>
<view class="input-wrap">
<input type="digit" inputmode="decimal" v-model="startingPrice" class="input-mini">
<text class="unit"></text>
</view>
<text class="connect"></text>
<view class="input-wrap">
<input type="number" v-model="startingTime" class="input-mini">
<text class="unit">{{timevalue}}</text>
</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="divider"></view>
<view class="rule-row">
<text class="rule-label">超出价</text>
<view class="input-wrap">
<input type="digit" inputmode="decimal" v-model="timeoutPrice" class="input-mini">
<text class="unit"></text>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<text class="connect">/</text>
<view class="input-wrap">
<input type="number" v-model="timeoutTime" class="input-mini">
<text class="unit">{{timevalue}}</text>
2025-12-20 14:29:10 +08:00
</view>
</view>
</view>
2026-04-02 01:48:12 +08:00
</template>
<template v-if="data.ridingRule == 2">
<view class="interval-list">
<view class="interval-item" v-for="(item, index) in intervalRule" :key="index">
<view class="interval-header">
<text class="interval-name">区间 {{index + 1}}</text>
<view class="delete-btn" v-if="index > 0 && index < intervalRule.length - 1" @click="deleteRule(index)">
<u-icon name="trash" color="#FF4D4F" size="28"></u-icon>
</view>
</view>
<view class="interval-body">
<view class="rule-row">
<text class="rule-label">时长范围</text>
<view class="range-inputs">
<text class="static-val">{{index === 0 ? 0 : intervalRule[index-1].end}}</text>
<text class="separator">-</text>
<block v-if="index === intervalRule.length - 1">
<text class="static-val">不限</text>
</block>
<block v-else>
<input type="number" v-model="item.end" class="input-mini" placeholder="结束时长" @blur="handleEndChange(index)">
</block>
<text class="unit">{{timevalue}}</text>
</view>
</view>
<view class="rule-row">
<text class="rule-label">收费标准</text>
<view class="price-inputs">
<text></text>
<input type="number" v-model="item.eachUnit" class="input-mini">
<text>{{timevalue}}</text>
<input type="digit" inputmode="decimal" v-model="item.fee" class="input-mini">
<text></text>
</view>
</view>
</view>
</view>
<view class="add-btn" v-if="intervalRule.length < 5" @click="addRule">
<u-icon name="plus" color="#4C97E7" size="28"></u-icon>
<text>添加区间</text>
</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
</template>
<template v-if="data.ridingRule == 3">
<view class="rule-box normal-rule deadline-rule">
<view class="rule-row">
<text class="rule-label">支付后截止到第</text>
<view class="input-wrap">
<input type="number" v-model="deadlineRule.dayOffset" class="input-mini">
<text class="unit"></text>
</view>
<view class="input-wrap time-input-wrap" style="margin-top: 0;height: 60rpx;" @click="openDeadlineTimePicker">
<text class="time-input-text">{{ deadlineRule.deadlineTime || '请选择时间' }}</text>
</view>
<text style="font-size: 28rpx;color: #333;">收费</text>
<view class="input-wrap">
<input type="digit" inputmode="decimal" v-model="deadlineRule.basePrice" class="input-mini">
<text class="unit"></text>
</view>
</view>
<view class="divider"></view>
<view class="rule-row">
<text class="rule-label">超时后每</text>
<view class="input-wrap">
<input type="number" v-model="deadlineRule.overtimeUnit" class="input-mini">
<text class="unit">{{timevalue}}</text>
</view>
<text class="connect">收费</text>
<view class="input-wrap">
<input type="digit" inputmode="decimal" v-model="deadlineRule.overtimePrice" class="input-mini">
<text class="unit"></text>
</view>
</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
</template>
<view class="form-item mt-20">
<view class="label">押金金额</view>
<view class="input-group">
<input type="digit" inputmode="decimal" v-model="data.depositAmount" placeholder="0.00" class="input text-right">
<text class="suffix"></text>
2025-12-20 14:29:10 +08:00
</view>
</view>
</view>
2026-04-02 01:48:12 +08:00
<view class="form-card">
<view class="card-title">其他设置</view>
<view class="form-item">
<view class="label">免费骑行</view>
<view class="input-group">
<input type="number" v-model="data.freeRideTime" placeholder="0" class="input text-right">
<text class="suffix">分钟</text>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
<view class="tips">前xx分钟内归还车辆不收取费用</view>
<view class="divider margin-tb"></view>
<view class="switch-item">
<view class="switch-info">
<view class="label">用户押金抵扣</view>
<view class="desc">允许用户在订单结束后使用押金抵扣费用</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<u-switch v-model="data.depositDeduction" @change="toggleUseLimits" active-color="#4C97E7" size="40"></u-switch>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="divider margin-tb"></view>
<view class="switch-item">
<view class="switch-info">
<view class="label">自动押金抵扣</view>
<view class="desc">订单结束后自动使用押金抵扣骑行费用</view>
<view class="desc" style="color: red;">抵扣金额不会超过押金</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<u-switch v-model="data.autoDeduct" @change="toggleUseLimitss" active-color="#4C97E7" size="40"></u-switch>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="form-item bg-gray" v-if="data.autoDeduct">
<view class="label">自动抵扣延迟</view>
<view class="input-group">
<input type="number" v-model="data.deductDelay" placeholder="0" class="input text-right">
<text class="suffix">小时</text>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
<view class="tips" v-if="data.autoDeduct">设置0将立即抵扣</view>
<view class="divider margin-tb"></view>
<view class="switch-item">
<view class="switch-info">
<view class="label">超时结束订单</view>
<view class="desc">超出可用时长后自动结束订单</view>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<u-switch v-model="data.timeoutFinish" @change="toggleUseLimitsss" active-color="#4C97E7" size="40"></u-switch>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="divider margin-tb"></view>
<view class="switch-item">
<view class="switch-info">
<view class="label">信用免押</view>
<view class="desc">开启后支持芝麻信用免押骑行将收取相应手续费</view>
</view>
<u-switch v-model="data.undepositEnabled" active-color="#4C97E7" size="40"></u-switch>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
<view class="form-card">
<view class="card-title" @click="showpart = true" style="display: flex;justify-content: space-between;">
<text>应用车型</text>
<u-icon name="arrow-right" color="#999" size="28"></u-icon>
2025-12-20 14:29:10 +08:00
</view>
2026-04-02 01:48:12 +08:00
<view class="tag-container" v-if="lists.suitIds && lists.suitIds.length">
<view class="car-tag" v-for="id in lists.suitIds" :key="id">
{{ getAccessoryNameById(id) }}
<view class="close-icon" @click.stop="removeSuitId(id)">×</view>
2025-12-20 14:29:10 +08:00
</view>
</view>
</view>
2026-04-02 01:48:12 +08:00
<view style="height: 180rpx;"></view>
</view>
<view class="footer-btns footer-btns-single">
<view class="btn confirm full" @click="generateQrcode">生成二维码</view>
</view>
<u-popup v-model="showpart" mode="bottom" border-radius="24">
<view class="popup-container">
<view class="popup-header">
<text class="popup-title">选择车型</text>
<u-icon name="close" color="#999" size="28" @click="closepart"></u-icon>
</view>
<scroll-view class="popup-content" scroll-y>
<view class="model-list">
<view class="model-item"
v-for="(item, index) in Accessorylist"
:key="index"
:class="{active: lists.suitIds.includes(item.id)}"
@click="chooseAcc(item.id)">
<text>{{ item.name }}</text>
<u-icon v-if="lists.suitIds.includes(item.id)" name="checkmark-circle-fill" color="#4C97E7" size="36"></u-icon>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
</scroll-view>
<view class="popup-footer">
<view class="full-btn" @click="subacc">确定</view>
2025-12-20 14:29:10 +08:00
</view>
</view>
2026-04-02 01:48:12 +08:00
</u-popup>
<u-picker mode="time" v-model="showDeadlineTimePicker" :params="deadlineTimeParams" @confirm="confirmDeadlineTime"
:default-time="deadlineRule.deadlineTime"></u-picker>
2025-12-20 14:29:10 +08:00
</view>
</template>
<script>
export default {
data() {
return {
lists: {
model: "",
fullVoltage: "",
lowVoltage: "",
fullEndurance: "",
suitIds: [],
lowBatteryReminder: '20',
lowBatteryReminderSwitch: false
},
showpart: false,
bgc: {
2026-04-02 01:48:12 +08:00
backgroundColor: "#F7F7F7",
2025-12-20 14:29:10 +08:00
},
list: [],
Accessorylist: [],
chooseIdxArr: [], // 存储选中的索引
timevalue: '分钟',
timeList: [{
name: '分钟',
disabled: false
},
{
name: '小时',
disabled: false
},
{
name: '天',
disabled: false
},
],
startingPrice: "",
startingTime: '',
timeoutPrice: '',
timeoutTime: '',
data: {
name: '',
instructions: '',
orderNum:'',
status: "0",
autoRefundDeposit: '0',
orderExceedMinutes: '',
orderExceedWarn: '',
freeRideTime: '5',
rentalUnit: 'minutes',
ridingRule: '1',
chargingCycle: '1',
chargingCycleValue: '24',
depositAmount: '200',
timeoutTime: '',
startingTime: '',
orderNum:0,
userId:'',
startRule:{},
modellds:[],
depositDeduction:false,
autoDeduct:false,
depositAmount:'',
2026-04-02 01:48:12 +08:00
undepositEnabled:false,
rule: '',
2025-12-20 14:29:10 +08:00
areaId:''
},
2026-04-02 01:48:12 +08:00
deadlineRule: {
dayOffset: '1',
deadlineTime: '23:59:59',
basePrice: '',
overtimeUnit: '1',
overtimePrice: ''
},
showDeadlineTimePicker: false,
deadlineTimeParams: {
year: false,
month: false,
day: false,
hour: true,
minute: true,
second: true
},
2025-12-20 14:29:10 +08:00
ruleId: '',
userinfo: {},
intervalRule: [
{
start: 0,
end: '',
fee: '',
eachUnit: '10'
},
{
start: '',
end: '',
fee: '',
eachUnit: '10'
},
{
start: '',
end: null,
fee: '',
eachUnit: '10'
}
],
taocanlist:[],
2026-01-19 15:27:10 +08:00
tabindex:0,
sn:'',
modelId:''
2025-12-20 14:29:10 +08:00
}
},
onLoad(e) {
2026-01-19 15:27:10 +08:00
console.log(e,'eeeeeeeeeeeeeeeeeeeeeeeeeeeee');
2025-12-20 14:29:10 +08:00
this.data.areaId = uni.getStorageSync('adminAreaid')
// if (e.ruleId) {
// this.ruleId = e.ruleId
// this.getFeeInfo()
// }
2026-01-19 15:27:10 +08:00
this.modelId = e.cxid
this.taocanlist = []
this.sn = e.sn
2025-12-20 14:29:10 +08:00
this.getinfo()
this.getAccessorylist()
this.getModelList()
},
onShow() {
},
methods: {
// 请求所有套餐
getModelList() {
2026-01-19 15:27:10 +08:00
this.$u.get(`/bst/suit/list?pageNum=1&pageSize=999&areaId=${this.data.areaId}&temp=false&modelId=${this.modelId}`).then((res) => {
2025-12-20 14:29:10 +08:00
if (res.code == 200) {
this.taocanlist = res.rows
this.ruleId = res.rows[0].id
this.getFeeInfo()
}
})
},
// 点击请求套餐详情
btnitem(item,index){
let that = this
uni.showModal({
title: '提示',
content: '切换后之前的修改将不进行保存,是否继续切换?',
showCancel: true,
success: function(res) {
if (res.confirm) {
that.tabindex = index
that.ruleId = item.id
that.getFeeInfo()
} else if (res.cancel) {
}
}
})
},
getAccessoryNameById(id) {
const item = this.Accessorylist.find(accessory => accessory.id == id)
return item ? item.name : ''
},
removeSuitId(id) {
const index = this.lists.suitIds.indexOf(id)
if (index > -1) {
this.lists.suitIds.splice(index, 1)
}
},
toggleUseLimits(e) {
2026-04-02 01:48:12 +08:00
this.data.depositDeduction = e;
2025-12-20 14:29:10 +08:00
},
toggleUseLimitss(e) {
2026-04-02 01:48:12 +08:00
this.data.autoDeduct = e;
2025-12-20 14:29:10 +08:00
},
toggleUseLimitsss(e) {
2026-04-02 01:48:12 +08:00
if(e === true){
2025-12-20 14:29:10 +08:00
let that = this
uni.showModal({
title: '安全警告!',
2026-04-28 14:01:46 +08:00
content: '开启后,订单超时将自动结束订单并锁车存在安全隐患,是否继续开启?',
2025-12-20 14:29:10 +08:00
showCancel: true,
success: function (res) {
if (res.confirm) {
2026-04-02 01:48:12 +08:00
that.data.timeoutFinish = e
2025-12-20 14:29:10 +08:00
} else if (res.cancel) {
2026-04-02 01:48:12 +08:00
that.data.timeoutFinish = false
2025-12-20 14:29:10 +08:00
}
}
})
}else{
2026-04-02 01:48:12 +08:00
this.data.timeoutFinish = e
2025-12-20 14:29:10 +08:00
}
},
closepart() {
this.showpart = false
},
subacc() {
this.showpart = false
console.log(this.chooseIdxArr)
},
chooseAcc(id) {
const index = this.lists.suitIds.indexOf(id)
if (index > -1) {
// 如果 id 已经存在于 suitIds 中,则从数组中删除
this.lists.suitIds.splice(index, 1)
} else {
// 如果 id 不存在,则添加到 suitIds 中
this.lists.suitIds.push(id)
}
},
getAccessoryNames(accessoryIds) {
const accessoryNames = this.lists.suitIds.map(id => {
const item = this.Accessorylist.find(accessory => accessory.id == id)
return item ? item.name : ''
})
// 过滤掉空值并返回数组
return accessoryNames.filter(name => name)
},
getAccessorylist() {
this.$u.get(`/bst/model/list?pageNum=1&pageSize=999&areaId=${this.data.areaId}`).then((res) => {
if (res.code == 200) {
this.Accessorylist = res.rows
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 1000
})
}
})
},
// 查询个人信息
getinfo() {
this.$u.get("/getInfo").then((res) => {
if (res.code == 200) {
this.userinfo = res.user
this.data.userId = this.userinfo.userId
}
})
},
getFeeInfo() {
this.$u.get(`/bst/suit/${this.ruleId}`).then((res) => {
if (res.code == 200) {
this.data = res.data;
2026-04-02 01:48:12 +08:00
this.lists.suitIds = res.data.modelIds || []
2025-12-20 14:29:10 +08:00
if (this.data.rentalUnit == 'minutes') {
this.timevalue='分钟'
} else if (this.data.rentalUnit == 'hours') {
this.timevalue='小时'
} else if (this.data.rentalUnit == 'day') {
this.timevalue='天'
}
if (this.data.area) {
this.returnVerify = this.data.area.returnVerify;
}
2026-04-02 01:48:12 +08:00
this.data.ridingRule = String(this.data.ridingRule || '1')
let parsedRule = this.parseRule(this.data.rule)
if (!parsedRule) {
if (this.data.ridingRule == 1) {
parsedRule = this.data.startRule || {}
} else if (this.data.ridingRule == 2) {
parsedRule = this.data.intervalRule || []
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
}
if (this.data.ridingRule == 1) {
this.timeoutTime = parsedRule.timeoutTime || '';
this.startingPrice = parsedRule.startingPrice || '';
this.startingTime = parsedRule.startingTime || '';
this.timeoutPrice = parsedRule.timeoutPrice || '';
2025-12-20 14:29:10 +08:00
} else if (this.data.ridingRule == 2) {
2026-04-02 01:48:12 +08:00
if (Array.isArray(parsedRule) && parsedRule.length) {
this.intervalRule = JSON.parse(JSON.stringify(parsedRule));
2025-12-20 14:29:10 +08:00
} else {
2026-04-02 01:48:12 +08:00
this.intervalRule = this.getDefaultIntervalRule();
}
} else if (this.data.ridingRule == 3) {
this.deadlineRule = {
dayOffset: parsedRule && parsedRule.dayOffset !== undefined ? String(parsedRule.dayOffset) : '1',
deadlineTime: parsedRule && parsedRule.deadlineTime ? parsedRule.deadlineTime : '23:59:59',
basePrice: parsedRule && parsedRule.basePrice !== undefined ? String(parsedRule.basePrice) : '',
overtimeUnit: parsedRule && parsedRule.overtimeUnit !== undefined ? String(parsedRule.overtimeUnit) : '1',
overtimePrice: parsedRule && parsedRule.overtimePrice !== undefined ? String(parsedRule.overtimePrice) : ''
2025-12-20 14:29:10 +08:00
}
}
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 1000
})
}
})
},
backpage() {
uni.navigateBack()
},
radioGroupChange(e) {
2026-04-02 01:48:12 +08:00
this.timevalue = e;
2025-12-20 14:29:10 +08:00
if (e == '分钟') {
this.data.rentalUnit = 'minutes'
} else if(e == '小时'){
this.data.rentalUnit = 'hours'
}else {
this.data.rentalUnit = 'day'
}
},
chargeTypeChange(value) {
this.data.ridingRule = value;
if(value === 2) {
2026-04-02 01:48:12 +08:00
this.intervalRule = this.getDefaultIntervalRule();
}
if (value === 3) {
this.deadlineRule = {
dayOffset: '1',
deadlineTime: '23:59:59',
basePrice: '',
overtimeUnit: '1',
overtimePrice: ''
}
}
},
getDefaultIntervalRule() {
return [
{
start: 0,
end: '',
fee: '',
eachUnit: '10'
},
{
start: '',
end: '',
fee: '',
eachUnit: '10'
},
{
start: '',
end: null,
fee: '',
eachUnit: '10'
}
]
},
parseRule(ruleStr) {
if (!ruleStr) return null
if (typeof ruleStr === 'object') return ruleStr
if (typeof ruleStr !== 'string') return null
try {
return JSON.parse(ruleStr)
} catch (error) {
return null
}
},
openDeadlineTimePicker() {
this.showDeadlineTimePicker = true
},
confirmDeadlineTime(e) {
const pad = (val) => String(val).padStart(2, '0')
if (e && e.hour !== undefined && e.minute !== undefined && e.second !== undefined) {
this.deadlineRule.deadlineTime = `${pad(e.hour)}:${pad(e.minute)}:${pad(e.second)}`
return
}
if (e && e.value) {
this.deadlineRule.deadlineTime = e.value
2025-12-20 14:29:10 +08:00
}
},
handleEndChange(index) {
if(index < this.intervalRule.length - 1) {
this.intervalRule[index + 1].start = this.intervalRule[index].end;
}
},
addRule() {
// 移除最后一个元素
const lastRule = this.intervalRule.pop();
// 添加新规则
this.intervalRule.push({
start: this.intervalRule[this.intervalRule.length - 1].end,
end: '',
fee: '',
eachUnit: '10'
});
// 添加回最后一个不限的规则
this.intervalRule.push(lastRule);
},
deleteRule(index) {
if(index === 0 || index === this.intervalRule.length - 1) return;
this.intervalRule.splice(index, 1);
// 更新后续区间的起始值
for(let i = index; i < this.intervalRule.length - 1; i++) {
this.intervalRule[i].start = this.intervalRule[i-1].end;
}
},
2026-04-02 01:48:12 +08:00
fillRulePayload(data) {
2026-01-19 15:27:10 +08:00
if (this.data.ridingRule == 2) {
2026-04-02 01:48:12 +08:00
const intervalRule = this.intervalRule.map((item, index) => ({
2026-01-19 15:27:10 +08:00
start: index === 0 ? 0 : Number(item.start),
end: index === this.intervalRule.length - 1 ? null : Number(item.end),
fee: Number(item.fee),
eachUnit: Number(item.eachUnit)
}))
2026-04-02 01:48:12 +08:00
data.rule = JSON.stringify(intervalRule)
} else if (this.data.ridingRule == 3) {
if (
this.deadlineRule.dayOffset === '' ||
this.deadlineRule.deadlineTime === '' ||
this.deadlineRule.basePrice === '' ||
this.deadlineRule.overtimeUnit === '' ||
this.deadlineRule.overtimePrice === ''
) {
uni.showToast({
title: '截止计费参数不能为空',
icon: 'none',
duration: 3000
})
return false
}
data.rule = JSON.stringify({
dayOffset: Number(this.deadlineRule.dayOffset),
deadlineTime: this.deadlineRule.deadlineTime,
basePrice: Number(this.deadlineRule.basePrice),
overtimeUnit: Number(this.deadlineRule.overtimeUnit),
overtimePrice: Number(this.deadlineRule.overtimePrice)
})
2026-01-19 15:27:10 +08:00
} else {
2026-04-02 01:48:12 +08:00
if(this.timeoutPrice === '' || this.timeoutPrice === 0){
uni.showToast({
title: '超出价不能为空或者0元',
icon: 'none',
duration: 5000
})
return false
}
data.rule = JSON.stringify({
2026-01-19 15:27:10 +08:00
timeoutTime: this.timeoutTime,
startingPrice: this.startingPrice,
startingTime: this.startingTime,
timeoutPrice: this.timeoutPrice
2026-04-02 01:48:12 +08:00
})
}
delete data.startRule
delete data.intervalRule
if (this.data.ridingRule != 1 && this.data.ridingRule != 2 && this.data.ridingRule != 3) {
uni.showToast({
title: '请选择正确计费方式',
icon: 'none',
duration: 3000
})
return false
}
return true
},
// 生成二维码(临时套餐 temp: true
generateQrcode() {
let data = {
...this.data,
type: 1,
modelIds: this.lists.suitIds,
temp: true
2026-01-19 15:27:10 +08:00
}
2026-04-02 01:48:12 +08:00
if (!this.fillRulePayload(data)) return
2026-01-19 15:27:10 +08:00
this.$u.post(`/bst/suit`, data).then((res) => {
if (res.code == 200) {
// 获取套餐id处理不同的返回结构
let suitId = '';
if (res.data && typeof res.data === 'object') {
suitId = res.data.id || res.data.suitId || res.data;
} else {
suitId = res.data;
}
console.log('套餐ID:', suitId);
console.log('完整返回数据:', res);
if (!suitId) {
uni.showToast({
title: '获取套餐ID失败',
icon: 'none',
duration: 2000
})
return;
}
console.log(this.sn,'121212121212');
// 跳转到二维码页面传递套餐id
uni.navigateTo({
url: `/page_shanghu/guanli/Qrcode?s=${this.sn}&t=${suitId}&type=3`
})
} else {
uni.showToast({
title: res.msg || '新增套餐失败',
icon: 'none',
duration: 2000
})
}
}).catch(err => {
console.error('生成二维码失败:', err);
uni.showToast({
title: '生成二维码失败',
icon: 'none',
duration: 2000
})
})
},
2025-12-20 14:29:10 +08:00
sub() {
let data = {
...this.data,
type: 1,
2026-04-02 01:48:12 +08:00
modelIds: this.lists.suitIds
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
if (!this.fillRulePayload(data)) return
2025-12-20 14:29:10 +08:00
if (this.ruleId != '') {
this.$u.put(`/bst/suit`, data).then((res) => {
if (res.code == 200) {
uni.showToast({
title: '修改成功',
icon: 'success',
duration: 1000
})
setTimeout(() => {
uni.navigateBack()
}, 1100)
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
} else {
this.$u.post(`/bst/suit`, data).then((res) => {
if (res.code == 200) {
uni.showToast({
title: '添加成功',
icon: 'success',
duration: 1000
})
setTimeout(() => {
uni.navigateBack()
}, 1100)
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
}
}
}
}
</script>
2026-04-02 01:48:12 +08:00
<style lang="scss" scoped>
2025-12-20 14:29:10 +08:00
page {
2026-04-02 01:48:12 +08:00
background-color: #F7F7F7;
}
.acitve {
border: 2rpx solid #4C97E7 !important;
background: #EBF4FF !important;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.tclist {
width: 100%;
margin-top: 20rpx;
2025-12-20 14:29:10 +08:00
padding-left: 20rpx;
2026-04-02 01:48:12 +08:00
.tcbox {
2025-12-20 14:29:10 +08:00
width: 750rpx;
display: flex;
gap: 20rpx;
2026-04-02 01:48:12 +08:00
padding-left: 10rpx;
2025-12-20 14:29:10 +08:00
height: 190rpx;
2026-04-02 01:48:12 +08:00
.tcitem {
2025-12-20 14:29:10 +08:00
width: 200rpx;
height: 148rpx;
background: #FFFFFF;
2026-04-02 01:48:12 +08:00
border-radius: 12rpx;
2025-12-20 14:29:10 +08:00
text-align: center;
2026-04-02 01:48:12 +08:00
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1rpx solid #e6e8eb;
flex-shrink: 0;
2025-12-20 14:29:10 +08:00
}
}
}
2026-04-02 01:48:12 +08:00
.tcname {
font-size: 28rpx;
color: #333;
font-weight: 500;
margin-bottom: 8rpx;
text-align: center;
word-break: break-word;
line-height: 1.3;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.tcsm {
font-size: 22rpx;
color: #999;
}
.page {
min-height: 100vh;
padding-bottom: calc(180rpx + env(safe-area-inset-bottom));
background-color: #F7F7F7;
}
.content {
padding: 20rpx 30rpx;
}
.form-card {
2025-12-20 14:29:10 +08:00
background: #FFFFFF;
2026-04-02 01:48:12 +08:00
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.03);
.card-title {
font-size: 32rpx;
2025-12-20 14:29:10 +08:00
font-weight: 600;
2026-04-02 01:48:12 +08:00
color: #333;
margin-bottom: 30rpx;
padding-left: 16rpx;
border-left: 8rpx solid #4C97E7;
line-height: 1;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.form-item {
2025-12-20 14:29:10 +08:00
display: flex;
2026-04-02 01:48:12 +08:00
justify-content: space-between;
2025-12-20 14:29:10 +08:00
align-items: center;
2026-04-02 01:48:12 +08:00
margin-bottom: 24rpx;
.label {
font-size: 28rpx;
color: #333;
font-weight: 500;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.input {
flex: 1;
text-align: right;
font-size: 28rpx;
color: #333;
height: 72rpx;
background-color: #F5F7FA;
border: 1rpx solid #E4E7ED;
border-radius: 8rpx;
padding: 0 24rpx;
margin-left: 20rpx;
&.text-right {
text-align: right;
}
&:focus {
background-color: #fff;
border-color: #4C97E7;
}
}
.radio-group {
2025-12-20 14:29:10 +08:00
display: flex;
flex-wrap: wrap;
2026-04-02 01:48:12 +08:00
gap: 16rpx;
justify-content: flex-end;
&.radio-group-wrap {
max-width: 420rpx;
}
.radio-tag {
padding: 10rpx 22rpx;
background: #F5F7FA;
border-radius: 30rpx;
2025-12-20 14:29:10 +08:00
font-size: 26rpx;
2026-04-02 01:48:12 +08:00
color: #666;
border: 1rpx solid transparent;
&.active {
background: #EBF4FF;
color: #4C97E7;
border-color: #4C97E7;
font-weight: 500;
2025-12-20 14:29:10 +08:00
}
}
}
2026-04-02 01:48:12 +08:00
.input-group {
2025-12-20 14:29:10 +08:00
display: flex;
2026-04-02 01:48:12 +08:00
align-items: center;
height: 72rpx;
background-color: #F5F7FA;
border: 1rpx solid #E4E7ED;
border-radius: 8rpx;
padding: 0 24rpx;
margin-left: 20rpx;
flex: 1;
max-width: 320rpx;
justify-content: flex-end;
&:focus-within {
background-color: #fff;
border-color: #4C97E7;
}
.input {
background-color: transparent;
border: none;
padding: 0;
margin-left: 0;
height: 100%;
flex: 1;
}
.suffix {
margin-left: 10rpx;
font-size: 28rpx;
color: #666;
}
}
&.mt-20 {
margin-top: 20rpx;
}
&.bg-gray {
background: #F8F9FB;
padding: 20rpx;
border-radius: 12rpx;
margin-top: 20rpx;
.input-group {
background-color: #fff;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
}
}
.tips {
font-size: 24rpx;
color: #999;
line-height: 1.4;
margin-top: -10rpx;
margin-bottom: 20rpx;
}
.rule-box {
background: #F8F9FB;
border-radius: 12rpx;
padding: 24rpx;
&.normal-rule {
.rule-row {
2025-12-20 14:29:10 +08:00
display: flex;
align-items: center;
2026-04-02 01:48:12 +08:00
justify-content: space-between;
flex-wrap: wrap;
gap: 10rpx;
.rule-label {
font-size: 28rpx;
color: #333;
font-weight: 500;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.input-wrap {
display: flex;
align-items: center;
background: #fff;
border-radius: 8rpx;
padding: 6rpx 12rpx;
border: 1rpx solid #e0e0e0;
.input-mini {
width: 100rpx;
text-align: center;
font-size: 28rpx;
}
.unit {
font-size: 24rpx;
color: #999;
margin-left: 6rpx;
}
}
.connect {
color: #999;
font-size: 24rpx;
margin: 0 10rpx;
}
}
.divider {
height: 1rpx;
background: #e0e0e0;
margin: 20rpx 0;
}
}
&.deadline-rule {
.rule-row {
flex-wrap: wrap;
gap: 10rpx;
}
.rule-label {
width: auto;
}
.time-input-wrap {
width: 220rpx;
justify-content: center;
.time-input-text {
min-width: 180rpx;
text-align: center;
font-size: 26rpx;
color: #333;
2025-12-20 14:29:10 +08:00
}
}
}
}
2026-04-02 01:48:12 +08:00
.interval-list {
.interval-item {
background: #F8F9FB;
border-radius: 12rpx;
padding: 20rpx;
margin-bottom: 20rpx;
.interval-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16rpx;
.interval-name {
font-size: 28rpx;
font-weight: 600;
color: #333;
}
}
.interval-body {
.rule-row {
display: flex;
align-items: center;
margin-bottom: 16rpx;
&:last-child {
margin-bottom: 0;
}
.rule-label {
width: 120rpx;
font-size: 26rpx;
color: #666;
}
.range-inputs, .price-inputs {
flex: 1;
display: flex;
align-items: center;
font-size: 26rpx;
color: #333;
.input-mini {
background: #fff;
width: 100rpx;
height: 50rpx;
border-radius: 8rpx;
text-align: center;
border: 1rpx solid #e0e0e0;
margin: 0 10rpx;
font-size: 26rpx;
}
.separator {
margin: 0 10rpx;
color: #999;
}
.unit {
margin-left: 10rpx;
color: #666;
}
.static-val {
padding: 0 10rpx;
font-weight: 500;
}
}
}
}
}
.add-btn {
display: flex;
justify-content: center;
align-items: center;
padding: 20rpx;
border: 1rpx dashed #4C97E7;
border-radius: 12rpx;
background: #EBF4FF;
text {
color: #4C97E7;
font-size: 28rpx;
margin-left: 10rpx;
}
}
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.switch-item {
2025-12-20 14:29:10 +08:00
display: flex;
justify-content: space-between;
align-items: center;
2026-04-02 01:48:12 +08:00
.switch-info {
flex: 1;
padding-right: 20rpx;
.label {
font-size: 30rpx;
color: #333;
font-weight: 500;
margin-bottom: 6rpx;
}
.desc {
font-size: 24rpx;
color: #999;
}
2025-12-20 14:29:10 +08:00
}
}
2026-04-02 01:48:12 +08:00
.tag-container {
display: flex;
flex-wrap: wrap;
gap: 16rpx;
margin-top: 10rpx;
.car-tag {
background: #EBF4FF;
color: #4C97E7;
font-size: 24rpx;
padding: 8rpx 20rpx;
border-radius: 30rpx;
2025-12-20 14:29:10 +08:00
display: flex;
align-items: center;
2026-04-02 01:48:12 +08:00
.close-icon {
margin-left: 10rpx;
font-size: 28rpx;
line-height: 1;
2025-12-20 14:29:10 +08:00
}
}
2026-04-02 01:48:12 +08:00
}
.divider {
height: 1rpx;
background: #F0F0F0;
width: 100%;
&.margin-tb {
margin: 24rpx 0;
2025-12-20 14:29:10 +08:00
}
}
}
2026-04-02 01:48:12 +08:00
.footer-btns {
position: fixed;
bottom: 0;
left: 0;
width: 100%;
background: #fff;
padding: 20rpx 30rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.05);
z-index: 100;
.btn {
height: 88rpx;
border-radius: 44rpx;
2025-12-20 14:29:10 +08:00
display: flex;
align-items: center;
justify-content: center;
2026-04-02 01:48:12 +08:00
font-size: 32rpx;
font-weight: 500;
&.confirm {
background: #4C97E7;
color: #fff;
box-shadow: 0 4rpx 12rpx rgba(76, 151, 231, 0.3);
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
&.full {
width: 100%;
}
&:active {
opacity: 0.9;
}
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
&.footer-btns-single {
justify-content: center;
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
}
.popup-container {
background: #fff;
.popup-header {
padding: 30rpx;
2025-12-20 14:29:10 +08:00
display: flex;
2026-04-02 01:48:12 +08:00
justify-content: space-between;
2025-12-20 14:29:10 +08:00
align-items: center;
2026-04-02 01:48:12 +08:00
border-bottom: 1rpx solid #F0F0F0;
.popup-title {
font-size: 32rpx;
font-weight: 600;
color: #333;
}
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.popup-content {
height: 600rpx;
.model-list {
padding: 20rpx;
.model-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 24rpx 30rpx;
border-radius: 12rpx;
margin-bottom: 16rpx;
background: #F8F9FB;
&.active {
background: #EBF4FF;
color: #4C97E7;
font-weight: 500;
}
}
}
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
.popup-footer {
padding: 20rpx 30rpx;
padding-bottom: calc(20rpx + env(safe-area-inset-bottom));
border-top: 1rpx solid #F0F0F0;
.full-btn {
width: 100%;
height: 88rpx;
background: #4C97E7;
color: #fff;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 32rpx;
font-weight: 600;
}
2025-12-20 14:29:10 +08:00
}
2026-04-02 01:48:12 +08:00
}
</style>