chuangte_bike_newxcx/page_shanghu/guanli/admin_order.vue
2025-04-01 21:35:30 +08:00

986 lines
24 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 :is-back="false" title="订单管理" :border-bottom="false" :background="bgc" title-color='#2E4975'
title-size='36' height='45'></u-navbar>
<view class="top_box">
<view class="left_text">
时间范围
</view>
<view class="timebox">
<view class="left_time" @click="time1=true">
{{firsTime}}
</view>
-
<view class="right_time" @click="time2=true">
{{lasTime}}
</view>
</view>
</view>
<view class="top_box" style="margin-top: 20rpx;">
<view class="left_text" @click="shows=true">
{{tit}}
<view class="iconfont icon-xiangxia1"></view>
</view>
<view class="sear_ipt">
<input type="text" v-model="searchKeyword" placeholder="请输入内容" class="input"
placeholder-style="color:#C7CDD3" @input="search()">
</view>
</view>
<view class="tap">
<view class="tap_cont " :class="zhuangtai==''?'act1':''" @click="changeidx('')">
全部
</view>
<view class="tap_cont" :class="zhuangtai=='PROCESSING'?'act1':''" @click="changeidx('PROCESSING')">
进行中
</view>
<view class="tap_cont" :class="zhuangtai=='WAIT_PAY'?'act1':''" @click="changeidx('WAIT_PAY')">
待支付
</view>
<view class="tap_cont" :class="zhuangtai=='FINISHED'?'act1':''" @click="changeidx('FINISHED')">
已完成
</view>
</view>
<u-mask :show="show" :z-index='100' />
<u-picker mode="time" v-model="time1" :params="params" @confirm="confirm1"
:default-time='pickertime'></u-picker>
<u-picker mode="time" v-model="time2" :params="params" @confirm="confirm2"
:default-time='pickertime'></u-picker>
<scroll-view class="warp_box" @scrolltolower="handqixing" scroll-y>
<view class="swiper-item ">
<view class="card" v-for="(item,index) in allList" :key="index" @click="toOrderDetail(item.deviceSn,item.id)">
<view class="line"></view>
<view class="top_info">
<view class="top_info_left">
订单编号:{{item.no}}
</view>
<view class="top_info_right" v-if="item.status=='PROCESSING'">
<view class="yuan"></view>
进行中
</view>
<view class="top_info_right" v-if="item.status== 'WAIT_PAY'"
style="color: orangered;">
<view class="yuan" style="background: orangered;"></view>
待支付
</view>
<view class="top_info_right" v-if="item.status=='FINISHED'" style="color: green;">
<view class="yuan" style="background: green;"></view>
已完成
</view>
</view>
<view class="lines"></view>
<view class="order_info">
<view class="info_li">
<view class="half_info_li">
租赁用户:<span>{{item.userName}}</span>
</view>
</view>
<view class="info_li">
<view class="half_info_li">
车辆编号:<span>{{item.deviceSn}}</span>
</view>
<view class="half_info_li">
租赁时长:<span>{{computedList(item.duration)}}</span>
</view>
</view>
<view class="info_li">
<view class="half_info_li">
订单费用:<span>{{item.totalFee}}元</span>
</view>
<view class="half_info_li">
有无退款:<span v-if="item.payRefunded>0" style="color: red;">有</span>
<span v-else>无</span>
</view>
</view>
<view class="info_li">
<view class="half_info_li">
开始时间:<span>{{formatDate(item.startTime)}}</span>
</view>
<view class="half_info_li" v-if="item.deviceVehicleNum">
车牌号:<span>{{item.deviceVehicleNum}}</span>
</view>
<view class="half_info_li" v-else>
车牌号:<span>--</span>
</view>
</view>
</view>
<!-- <view class="btn_box">
<view class="btn" v-if="item.status=='PROCESSING'" @click.stop="showfzs(item)">
辅助还车
</view>
<view class="btn" v-if="item.status=='FINISHED'" @click.stop="showtks(item)">
退款
</view>
</view> -->
</view>
<view class="" style="width: 100%;text-align: center;color: #ccc;margin-top: 30rpx;">
当前没有更多订单啦...
</view>
</view>
</scroll-view>
<view class="tip_box" v-if="showfz">
<view class="top">
<view class="tip">
提示
</view>
<view class="txt">
确定要辅助还车吗?
</view>
</view>
<view class="bot">
<view class="bot_left" @click="closefz()">
取消
</view>
<view class="bot_right" @click="backDevice()">
确定
</view>
</view>
</view>
<view class="tip_box" v-if="showgj">
<view class="top">
<view class="tip">
改价
</view>
<view class="ipt_box">
<view class="text">
运营区外调度费
</view>
<view class="ipt">
<input type="text" v-model="orderInfo.dispatchFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3">
</view>
</view>
<view class="ipt_box">
<view class="text">
停车点外调度费
</view>
<view class="ipt">
<input type="text" v-model="orderInfo.manageFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3">
</view>
</view>
<view class="ipt_box">
<view class="text">
骑行费
</view>
<view class="ipt">
<input type="text" v-model="orderInfo.ridingFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3">
</view>
</view>
<view class="ipt_box">
<view class="text">
预约费
</view>
<view class="ipt">
<input type="text" v-model="orderInfo.appointmentFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3">
</view>
</view>
</view>
<view class="bot">
<view class="bot_left" @click="closegj()">
取消
</view>
<view class="bot_right" @click="changeMoney()">
确定
</view>
</view>
</view>
<view class="tip_box" v-if="showtk">
<view class="top" v-if="showtk">
<view class="tip">
退款
</view>
<view class="ipt_box">
<view class="text">
运营区外调度费
</view>
<view class="ipt">
<input type="text" v-model="dispatchFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3" @input="checkAndUpdate('dispatchFee')">
</view>
</view>
<view class="ipt_box" style="width:100%;margin-top: 6rpx;">
<view class="width:10% ;">
</view>
<view style="color: #ccc;margin-left: auto; font-size: 24rpx;">
最大可退款金额:{{orderInfo.dispatchFee}}元
</view>
</view>
<view class="ipt_box">
<view class="text">
停车点外调度费
</view>
<view class="ipt">
<input type="text" v-model="manageFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3" @input="checkAndUpdate('manageFee')">
</view>
</view>
<view class="ipt_box" style="width:100%;margin-top: 6rpx;">
<view class="width:10% ;">
</view>
<view style="color: #ccc;margin-left: auto; font-size: 24rpx;">
最大可退款金额:{{orderInfo.manageFee}}元
</view>
</view>
<view class="ipt_box">
<view class="text">
骑行费
</view>
<view class="ipt">
<input type="text" v-model="ridingFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3" @input="checkAndUpdate('ridingFee')">
</view>
</view>
<view class="ipt_box" style="width:100%;margin-top: 6rpx;">
<view class="width:10% ;">
</view>
<view style="color: #ccc;margin-left: auto; font-size: 24rpx;">
最大可退款金额:{{orderInfo.ridingFee}}元
</view>
</view>
<view class="ipt_box">
<view class="text">
预约费
</view>
<view class="ipt">
<input type="text" v-model="appointmentFee" placeholder="0.00" class="input"
placeholder-style="color:#C7CDD3" @input="checkAndUpdate('appointmentFee')">
</view>
</view>
<view class="ipt_box" style="width:100%;margin-top: 6rpx;">
<view class="width:10% ;">
</view>
<view style="color: #ccc;margin-left: auto; font-size: 24rpx;">
最大可退款金额:{{orderInfo.appointmentFee}}元
</view>
</view>
<view class="ipt_box">
<view class="text">
原因
</view>
<view class="ipt">
<input type="text" v-model="reason" placeholder="选填" class="input"
placeholder-style="color:#C7CDD3" @input="checkAndUpdate('reason')">
</view>
</view>
</view>
<view class="bot">
<view class="bot_left" @click="closetk()">
取消
</view>
<view class="bot_right" @click="backMoney()">
确定
</view>
</view>
</view>
<u-select v-model="shows" :list="list" title='添加方式' @confirm="searchconfirm"></u-select>
<TabBar :indexs='3' style=""></TabBar>
</view>
</template>
<script>
import TabBar from '@/page_shanghu/components/tab-bar/tab-bar.vue';
let timerId;
let timerId1;
export default {
components: {
TabBar
},
data() {
return {
bgc: {
backgroundColor: "#F7FAFE",
},
params: {
year: true,
month: true,
day: true,
hour: false,
minute: false,
second: false
},
pickertime: '',
time1: false,
time2: false,
lasTime: '',
firsTime: '',
searchKeyword: '',
curtitidx: '',
swiperHeight: 400,
allList: [],
ingList: [],
reprement: [],
alreadyList: [],
show: false,
showfz: false,
showgj: false,
showtk: false,
orderInfo: {},
loading: false,
initialValues: {
},
areaId: false,
tit: '车牌号',
shows: false,
list: [{
value: '1',
label: '手机号'
},
{
value: '2',
label: '车牌号'
}],
typeidx: '2',
areainfo: {},
passList: [],
dispatchFee: 0,
manageFee: 0,
ridingFee: 0,
appointmentFee: 0,
reason: '',
pageNum: 1,
isback: false,
zhuangtai:'',
total:''
}
},
onShow() {
if (uni.getStorageSync('adminAreaid')) {
this.areaId = uni.getStorageSync('adminAreaid')
this.orderList()
this.getArea()
}
},
watch: {
},
computed: {
userId() {
return this.$store.getters.userId;
},
},
computed: {
},
onReachBottom() {
},
methods: {
handqixing() {
console.log(11);
if(this.total > this.allList.length){
this.orderList()
}
},
getArea() {
let id = this.areaId
this.$u.get(`/bst/area/${id}`).then((res) => {
if (res.code == 200) {
this.areainfo = res.data
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
},
formatDate(value) {
if (!value) return ''
let date = new Date(value)
let month = date.getMonth() + 1 // 月份从0开始计数所以加1
let day = date.getDate()
let hours = date.getHours()
let minutes = date.getMinutes()
// 确保月份、日期、小时和分钟都是两位数
month = month < 10 ? '0' + month : month
day = day < 10 ? '0' + day : day
hours = hours < 10 ? '0' + hours : hours
minutes = minutes < 10 ? '0' + minutes : minutes
return `${month}-${day} ${hours}:${minutes}`
},
searchconfirm(e) {
this.typeidx = e[0].value
this.tit = e[0].label
},
computedList(seconds, showSeconds = true) {
if (isNaN(seconds)) return "--";
const h = Math.floor(seconds / 3600);
const m = Math.floor((seconds % 3600) / 60);
const s = seconds % 60;
const parts = [];
if (h > 0) parts.push(`${h}时`);
if (m > 0 || h > 0) parts.push(`${m}分`); // 如果有小时则始终显示分钟
if (showSeconds) parts.push(`${s}秒`);
return parts.join("") || "0钟";
},
toOrderDetail(id,orid) {
uni.navigateTo({
url: '/page_shanghu/guanli/order_detail?id=' + id + '&orid=' + orid
})
},
checkAndUpdate(key) {
clearTimeout(timerId)
timerId = setTimeout(() => {
let inputValue = parseFloat(this.orderInfo[key]);
let initialValue = parseFloat(this.initialValues[key]);
if (inputValue > initialValue) {
this.orderInfo[key] = initialValue;
}
}, 500)
},
// 退款
backMoney() {
if (this.isback == false) {
this.isback = true
uni.showLoading({
title: '加载中'
})
let data = {
orderNo: this.orderInfo.orderNo,
dispatchFee: this.dispatchFee,
manageFee: this.manageFee,
ridingFee: this.ridingFee,
appointmentFee: this.appointmentFee,
// reason: this.reason
}
if (
data.dispatchFee > this.orderInfo.dispatchFee ||
data.manageFee > this.orderInfo.manageFee ||
data.ridingFee > this.orderInfo.ridingFee ||
data.appointmentFee > this.orderInfo.appointmentFee
) {
uni.showToast({
title: '退款金额不能大于实际支付金额',
icon: 'none',
duration: 2000
})
return // 阻止请求的发送
}
this.$u.put('/appVerify/order/refund', data).then((res) => {
this.isback = false
if (res.code === 200) {
// 处理接口返回的数据,将边界数据转换为地图组件需要的折线结构
this.show = false
this.showgj = false
this.showtk = false
this.orderInfo = {}
this.orderList()
this.showtk = false
uni.showToast({
title: '退款成功',
icon: 'none',
duration: 2000
})
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
}).catch(error => {
console.error("Error fetching area data:", error)
})
}
},
showtks(item) {
this.orderInfo = item
this.show = true
this.showtk = true
this.initialValues.dispatchFee = this.orderInfo.dispatchFee
this.initialValues.manageFee = this.orderInfo.manageFee
this.initialValues.ridingFee = this.orderInfo.ridingFee
this.initialValues.appointmentFee = this.orderInfo.appointmentFee
},
closetk() {
this.show = false
this.showtk = false
this.orderInfo = {}
},
// 改价
changeMoney() {
uni.showLoading({
title: '加载中'
})
let data = {
orderNo: this.orderInfo.orderNo,
dispatchFee: this.orderInfo.dispatchFee,
manageFee: this.orderInfo.manageFee,
ridingFee: this.orderInfo.ridingFee,
appointmentFee: this.orderInfo.appointmentFee,
}
this.$u.put('/appVerify/order/editPrice', data).then((res) => {
if (res.code === 200) {
// 处理接口返回的数据,将边界数据转换为地图组件需要的折线结构
this.show = false
this.showgj = false
this.orderInfo = {}
if (this.curtitidx == 0) {
this.orderList()
} else if (this.curtitidx == 2) {
this.orderList2()
}
uni.showToast({
title: '改价成功',
icon: 'none',
duration: 2000
})
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
},
showgjs(item) {
this.orderInfo = item
this.show = true
this.showgj = true
},
closegj() {
this.show = false
this.showgj = false
this.orderInfo = {}
},
// 还车
backDevice() {
uni.showLoading({
title: '加载中'
})
this.$u.post('/appVerify/device/return?orderNo=' + this.orderInfo.orderNo + '&returnType=2').then((
res) => {
if (res.code === 200) {
// 处理接口返回的数据,将边界数据转换为地图组件需要的折线结构
this.show = false
this.showfz = false
this.orderInfo = {}
this.orderList()
this.pageNum = 1
uni.showToast({
title: '还车成功',
icon: 'none',
duration: 2000
});
} else {
uni.showToast({
title: res.msg,
icon: 'none',
duration: 2000
})
}
})
},
closefz() {
this.show = false
this.showfz = false
this.orderInfo = {}
},
showfzs(item) {
this.orderInfo = item
this.show = true
this.showfz = true
},
orderList() {
let data = {};
if (this.typeidx == 1) {
data = {
phonenumber: this.searchKeyword,
status: this.zhuangtai,
createDateRange:this.firsTime == '' ? '' : this.lasTime == '' ? '' : this.firsTime + ',' + this.lasTime,
areaId: this.areaId,
pageSize: 20,
pageNum: this.pageNum
};
} else if (this.typeidx == 2) { // 修改条件为 this.typeidx == 2
data = {
vehicleNum: this.searchKeyword,
type: '1',
status:this.zhuangtai,
createDateRange:this.firsTime == '' ? '' : this.lasTime == '' ? '' : this.firsTime + ',' + this.lasTime,
areaId: this.areaId,
pageSize: 20,
pageNum: this.pageNum
};
}
this.loading = false
this.$u.get('/bst/order/list?', data).then((res) => {
if (res.code === 200) {
this.total = res.total
if(this.pageNum == 1){
this.allList = res.rows
}else{
this.allList = this.allList.concat(res.rows)
}
console.log(this.allList);
this.pageNum++
this.loading = true
this.curtitidx = 0
this.$forceUpdate()
}
})
},
async changeidx(idx) {
this.zhuangtai = idx
this.pageNum = 1
this.allList = []
this.ingList = []
this.reprement = []
this.alreadyList = []
this.orderList()
},
confirm1(e) {
console.log(e, 'eeeeeeee');
this.firsTime = e.year + '-' + e.month + '-' + e.day
this.pageNum = 1
this.orderList()
},
confirm2(e) {
this.lasTime = e.year + '-' + e.month + '-' + e.day
this.pageNum = 1
this.orderList()
},
search() {
this.pageNum = 1
this.allList = []
this.ingList = []
this.reprement = []
this.alreadyList = []
clearTimeout(timerId1);
timerId1 = setTimeout(() => {
this.pageNum = 1
this.orderList()
}, 500)
// 根据关键字过滤 this.classlist
},
}
}
</script>
<style lang="scss">
page {
background-color: #fff;
}
.page {
width: 750rpx;
.tip_box {
position: fixed;
left: 72rpx;
top: 628rpx;
width: 610rpx;
background: #FFFFFF;
border-radius: 30rpx 30rpx 30rpx 30rpx;
z-index: 110;
padding-bottom: 100rpx;
.top {
padding: 52rpx 38rpx 42rpx 36rpx;
.ipt_box {
margin-top: 22rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
.text {
width: 350rpx;
font-weight: 400;
font-size: 32rpx;
color: #3D3D3D;
}
.ipt {
padding: 10rpx 18rpx;
display: flex;
align-items: center;
justify-content: space-between;
margin-left: 26rpx;
width: 420rpx;
height: 64rpx;
border-radius: 0rpx 0rpx 0rpx 0rpx;
border: 2rpx solid #979797;
.input {
width: 80%;
}
}
}
.tip {
width: 100%;
text-align: center;
font-weight: 700;
font-size: 32rpx;
color: #3D3D3D;
}
.txt {
margin-top: 32rpx;
width: 100%;
text-align: center;
font-weight: 500;
font-size: 32rpx;
color: #3D3D3D;
}
}
.bot {
position: absolute;
width: 610rpx;
display: flex;
flex-wrap: nowrap;
bottom: -20rpx;
.bot_left {
border-radius: 0rpx 0rpx 0rpx 30rpx;
width: 50%;
height: 86rpx;
display: flex;
align-items: center;
justify-content: center;
font-weight: 500;
font-size: 32rpx;
color: #3D3D3D;
background: #EEEEEE;
}
.bot_right {
border-radius: 0rpx 0rpx 30rpx 0rpx;
width: 50%;
height: 86rpx;
background: #4C97E7;
display: flex;
align-items: center;
justify-content: center;
color: #FFFFFF;
font-weight: 500;
font-size: 32rpx;
}
}
}
.warp_box {
height: 61vh;
overflow: scroll;
.swiper-item {
.card {
margin: 16rpx auto;
width: 750rpx;
background: #fff;
.btn_box {
display: flex;
flex-wrap: nowrap;
align-items: center;
width: 100%;
height: 96rpx;
.btn {
display: flex;
align-items: center;
justify-content: center;
font-weight: 400;
font-size: 36rpx;
color: #3D3D3D;
width: 49%;
}
.btn_line {
width: 0rpx;
height: 51rpx;
border: 2rpx solid #4C97E7;
}
}
.order_info {
padding: 0rpx 30rpx;
display: flex;
flex-wrap: wrap;
.info_li {
display: flex;
flex-wrap: nowrap;
width: 100%;
font-weight: 400;
font-size: 28rpx;
color: #808080;
.half_info_li:first-child {
width: 60%;
}
.half_info_li {
width: 40%;
font-weight: 400;
font-size: 28rpx;
color: #808080;
span{
color: #000;
}
}
}
}
.line {
width: 750rpx;
height: 22rpx;
background: #F6F6F6;
border-radius: 0rpx 0rpx 0rpx 0rpx;
}
.lines {
width: 750rpx;
height: 2rpx;
background: #f7f7f7;
}
.top_info {
padding: 24rpx 32rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
.top_info_left {
width: 70%;
font-weight: 400;
font-size: 28rpx;
color: #3D3D3D;
font-weight: 600;
white-space: nowrap;
/* 禁止换行 */
overflow: hidden;
/* 超出部分隐藏 */
text-overflow: ellipsis;
/* 显示省略号 */
}
.top_info_right {
display: flex;
flex-wrap: nowrap;
align-items: center;
margin-left: auto;
.yuan {
margin-right: 12rpx;
border-radius: 50%;
width: 14rpx;
height: 14rpx;
background: #4C97E7;
}
font-weight: 400;
font-size: 28rpx;
color: #4C97E7;
}
}
}
}
}
.tap {
margin-top: 24rpx;
width: 750rpx;
display: flex;
flex-wrap: nowrap;
align-items: center;
justify-content: space-around;
.tap_cont {
text-align: center;
padding-bottom: 15rpx;
width: 100rpx;
font-weight: 500;
font-size: 32rpx;
color: #3D3D3D;
border-bottom: 6rpx solid #fff;
}
.act1 {
border-bottom: 6rpx solid #4C97E7;
color: #4C97E7;
}
}
.top_box {
display: flex;
flex-wrap: nowrap;
align-items: center;
padding: 28rpx 30rpx;
// padding: 20rpx 0;
margin: 0 auto;
width: 672rpx;
height: 100rpx;
background: #FFFFFF;
box-shadow: 0rpx 4rpx 22rpx 0rpx rgba(0, 0, 0, 0.07);
border-radius: 10rpx 10rpx 10rpx 10rpx;
.left_text {
display: flex;
flex-wrap: nowrap;
align-items: center;
width: 25%;
font-weight: 400;
font-size: 32rpx;
color: #3D3D3D;
.icon-xiangxia1 {
font-size: 26rpx;
}
}
.timebox {
width: 75%;
display: flex;
flex-wrap: nowrap;
align-items: center;
margin-left: 34rpx;
.left_time {
text-align: center;
margin-right: 6rpx;
height: 50rpx;
width: 45%;
border: 2rpx solid #ccc;
border-radius: 12rpx;
font-weight: 400;
font-size: 32rpx;
color: #979797;
}
.right_time {
text-align: center;
margin-left: 6rpx;
height: 50rpx;
width: 45%;
border: 2rpx solid #ccc;
border-radius: 12rpx;
font-weight: 400;
font-size: 32rpx;
color: #979797;
}
}
}
}
</style>