718 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Vue
		
	
	
	
			
		
		
	
	
			718 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Vue
		
	
	
	
| <!--
 | |
|  * @Descripttion: 订单撤销页面
 | |
|  * @version: 1.0.0
 | |
|  * @Author: kBank
 | |
|  * @Date: 2022-11-21 15:11:22
 | |
| -->
 | |
| <template>
 | |
|   <view class="content">
 | |
|     <view
 | |
|       v-for="(item, index) in orderLists"
 | |
|       :key="`order-${item.orderCode || index}`"
 | |
|       class="orderList_i"
 | |
|     >
 | |
|       <view @click.stop="getDetails(item)">
 | |
|         <view class="disFlex atm just mbt10">
 | |
|           <view class="disFlex atm">
 | |
|             <view class="quan">{{ item.orderTypeVal }}</view>
 | |
|             <view class="tit1">订单编号{{ item.orderCode }}</view>
 | |
|           </view>
 | |
|           <view class="tit2">
 | |
|             {{ item.orderStatusVal }}
 | |
|           </view>
 | |
|         </view>
 | |
| 
 | |
|         <view
 | |
|           v-for="(ctem, cndex) in item.itemList"
 | |
|           :key="`item-${ctem.productName || cndex}`"
 | |
|           class="disFlex atm just mbt10"
 | |
|         >
 | |
|           <view class="disFlex atm">
 | |
|             <img :src="ctem.cover" alt="商品图片" />
 | |
|             <view class="tit3">
 | |
|               {{ ctem.productName }}
 | |
|             </view>
 | |
|           </view>
 | |
|           <view style="text-align: right">
 | |
|             <view class="tit4">
 | |
|               {{ formatPrice(ctem.price) }}
 | |
|             </view>
 | |
|             <view class="tit5">x{{ ctem.quantity }}</view>
 | |
|           </view>
 | |
|         </view>
 | |
| 
 | |
|         <view class="tit1">创建时间:{{ item.creationTime }}</view>
 | |
|       </view>
 | |
| 
 | |
|       <view class="xian"></view>
 | |
| 
 | |
|       <view class="disFlex">
 | |
|         <view style="flex: 1"></view>
 | |
|         <view class="disFlex">
 | |
|           <u-button
 | |
|             type="primary"
 | |
|             class="lBtn"
 | |
|             :plain="true"
 | |
|             shape="circle"
 | |
|             text="撤销订单"
 | |
|             color="#999"
 | |
|             @click="cancleOrder(item)"
 | |
|           ></u-button>
 | |
|         </view>
 | |
|       </view>
 | |
|     </view>
 | |
| 
 | |
|     <!-- 订单详情弹窗 -->
 | |
|     <u-popup
 | |
|       v-model="detailsShow"
 | |
|       class="pop"
 | |
|       closeable
 | |
|       :round="10"
 | |
|       mode="center"
 | |
|       @close="detailsShow = false"
 | |
|     >
 | |
|       <view class="pop_a">
 | |
|         <view class="t_tit">订单详情</view>
 | |
|         <view class="pop_t">商品信息</view>
 | |
|         <view class="xian"></view>
 | |
| 
 | |
|         <view class="orderList_a">
 | |
|           <view
 | |
|             v-for="(ctem, cndex) in details.itemList"
 | |
|             :key="`detail-item-${ctem.productName || cndex}`"
 | |
|             class="disFlex atm just mbt10"
 | |
|           >
 | |
|             <view class="disFlex just" style="flex: 1">
 | |
|               <img :src="ctem.cover" alt="商品图片" />
 | |
|               <view style="flex: 1">
 | |
|                 <view class="disFlex atm just">
 | |
|                   <view class="tit3">
 | |
|                     {{ ctem.productName }}
 | |
|                   </view>
 | |
|                   <view class="tit5">x{{ ctem.quantity }}</view>
 | |
|                 </view>
 | |
|                 <view
 | |
|                   class="tit3"
 | |
|                   style="color: #999; font-size: 24rpx; margin-top: 6rpx"
 | |
|                 >
 | |
|                   {{ ctem.specsName }}
 | |
|                 </view>
 | |
|                 <view class="tit4">
 | |
|                   {{ formatPrice(ctem.price) }}
 | |
|                 </view>
 | |
|               </view>
 | |
|             </view>
 | |
|           </view>
 | |
|         </view>
 | |
| 
 | |
|         <view class="disFlex atm just mbt10">
 | |
|           <view class="tit1">订单金额</view>
 | |
|           <view class="tit6">
 | |
|             {{ formatCurrency(details.orderAmount) }}
 | |
|           </view>
 | |
|         </view>
 | |
| 
 | |
|         <view class="disFlex atm just mbt10">
 | |
|           <view class="tit1">订单业绩</view>
 | |
|           <view class="tit6">
 | |
|             {{ formatCurrency(details.orderAchieve) }}
 | |
|           </view>
 | |
|         </view>
 | |
| 
 | |
|         <!-- 暂时注释的订单业绩(BV)
 | |
|         <view class="disFlex atm just mbt10">
 | |
|           <view class="tit1">订单业绩(BV)</view>
 | |
|           <view class="tit6">
 | |
|             {{ formatCurrency(details.orderAssAchieve) }}
 | |
|           </view>
 | |
|         </view>
 | |
|         -->
 | |
| 
 | |
|         <view class="xian"></view>
 | |
| 
 | |
|         <view class="pop_t mbt10">收货人信息</view>
 | |
|         <view class="disFlex atm mbt10 tit6">
 | |
|           <view>{{ details.recName }}</view>
 | |
|           <view>{{ details.recPhone }}</view>
 | |
|         </view>
 | |
|         <view class="mbt10 tit1">
 | |
|           {{ details.recProvince }} {{ details.recCity }}
 | |
|           {{ details.recCounty }} {{ details.address }}
 | |
|         </view>
 | |
|       </view>
 | |
|     </u-popup>
 | |
|   </view>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| import * as api from '@/config/order.js'
 | |
| import { ORDER_STATUS } from '@/util/common'
 | |
| export default {
 | |
|   name: 'CancelOrder',
 | |
|   data() {
 | |
|     return {
 | |
|       orderTypes: [],
 | |
|       rightShow: false,
 | |
|       remarkEd: '',
 | |
|       content: '确认取消订单?',
 | |
|       isRemark: false,
 | |
|       cancelCode: '',
 | |
|       details: {},
 | |
|       orderStatusList: ORDER_STATUS,
 | |
|       detailsShow: false,
 | |
|       isTab: -1,
 | |
|       // 查询参数
 | |
|       queryParams: {
 | |
|         pageNum: 1,
 | |
|         pageSize: 50,
 | |
|       },
 | |
|       select: {
 | |
|         orderType: '',
 | |
|       },
 | |
|       orderLists: [],
 | |
|     }
 | |
|   },
 | |
| 
 | |
|   onLoad() {
 | |
|     this.getDataList()
 | |
|   },
 | |
| 
 | |
|   onShow() {},
 | |
| 
 | |
|   onReachBottom() {
 | |
|     this.queryParams.pageNum++
 | |
|     this.getDataList()
 | |
|   },
 | |
| 
 | |
|   methods: {
 | |
|     /**
 | |
|      * 格式化价格显示
 | |
|      */
 | |
|     formatPrice(price) {
 | |
|       if (!price && price !== 0) return ''
 | |
|       // 这里可以根据需要调用相应的格式化方法
 | |
|       return this.numberToCurrency(this.isLocal(price))
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 格式化货币显示
 | |
|      */
 | |
|     formatCurrency(amount) {
 | |
|       if (!amount && amount !== 0) return ''
 | |
|       return this.toThousandthAndKeepDecimal(amount)
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 数字转货币格式 - 替代原来的filter
 | |
|      */
 | |
|     numberToCurrency(num) {
 | |
|       // 这里实现原来filter的逻辑
 | |
|       if (!num && num !== 0) return ''
 | |
|       return parseFloat(num).toFixed(2)
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 本地化处理 - 替代原来的filter
 | |
|      */
 | |
|     isLocal(value) {
 | |
|       // 这里实现原来filter的逻辑
 | |
|       return value
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 千分位格式化 - 替代原来的filter
 | |
|      */
 | |
|     toThousandthAndKeepDecimal(num) {
 | |
|       if (!num && num !== 0) return '0.00'
 | |
|       return parseFloat(num)
 | |
|         .toFixed(2)
 | |
|         .replace(/\d{1,3}(?=(\d{3})+(\.\d*)?$)/g, '$&,')
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 撤销订单
 | |
|      */
 | |
|     cancleOrder(item) {
 | |
|       const that = this
 | |
|       uni.showModal({
 | |
|         title: '确定撤销订单?',
 | |
|         success: function (response) {
 | |
|           if (response.confirm) {
 | |
|             api
 | |
|               .selfRevokeListCheck(item)
 | |
|               .then(res => {
 | |
|                 if (res.code === 200) {
 | |
|                   api
 | |
|                     .selfRevokeOrder(item)
 | |
|                     .then(res => {
 | |
|                       if (res.code === 200) {
 | |
|                         uni.showToast({
 | |
|                           title: res.msg,
 | |
|                           icon: 'none',
 | |
|                           duration: 1500,
 | |
|                         })
 | |
|                         that.orderLists = []
 | |
|                         that.getDataList()
 | |
|                       } else {
 | |
|                         uni.showToast({
 | |
|                           title: res.msg,
 | |
|                           icon: 'none',
 | |
|                           duration: 1500,
 | |
|                         })
 | |
|                       }
 | |
|                     })
 | |
|                     .catch(error => {
 | |
|                       console.error('撤销订单失败:', error)
 | |
|                       uni.showToast({
 | |
|                         title: '撤销订单失败',
 | |
|                         icon: 'none',
 | |
|                         duration: 1500,
 | |
|                       })
 | |
|                     })
 | |
|                 } else {
 | |
|                   uni.showToast({
 | |
|                     title: res.msg,
 | |
|                     icon: 'none',
 | |
|                     duration: 1500,
 | |
|                   })
 | |
|                 }
 | |
|               })
 | |
|               .catch(error => {
 | |
|                 console.error('检查撤销条件失败:', error)
 | |
|                 uni.showToast({
 | |
|                   title: '操作失败,请重试',
 | |
|                   icon: 'none',
 | |
|                   duration: 1500,
 | |
|                 })
 | |
|               })
 | |
|           }
 | |
|         },
 | |
|       })
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 获取订单详情
 | |
|      */
 | |
|     getDetails(item) {
 | |
|       api
 | |
|         .orderDetails(item.orderCode)
 | |
|         .then(res => {
 | |
|           this.details = res.data || {}
 | |
|           this.detailsShow = true
 | |
|         })
 | |
|         .catch(error => {
 | |
|           console.error('获取订单详情失败:', error)
 | |
|           uni.showToast({
 | |
|             title: '获取订单详情失败',
 | |
|             icon: 'none',
 | |
|             duration: 1500,
 | |
|           })
 | |
|         })
 | |
|     },
 | |
| 
 | |
|     /**
 | |
|      * 获取数据列表
 | |
|      */
 | |
|     getDataList() {
 | |
|       api
 | |
|         .selfRevokeList(Object.assign({}, this.queryParams))
 | |
|         .then(res => {
 | |
|           this.orderLists = this.orderLists.concat(res.rows || [])
 | |
|           this.total = res.total
 | |
|         })
 | |
|         .catch(error => {
 | |
|           console.error('获取订单列表失败:', error)
 | |
|           uni.showToast({
 | |
|             title: '获取订单列表失败',
 | |
|             icon: 'none',
 | |
|             duration: 1500,
 | |
|           })
 | |
|         })
 | |
|     },
 | |
|   },
 | |
| }
 | |
| </script>
 | |
| 
 | |
| <style lang="scss" scoped>
 | |
| .index_header {
 | |
|   background: #fff;
 | |
|   font-size: 18px;
 | |
|   font-family:
 | |
|     PingFang SC-Semibold,
 | |
|     PingFang SC;
 | |
|   font-weight: 600;
 | |
|   color: #333333;
 | |
|   text-align: center;
 | |
|   padding: 10px 0;
 | |
|   position: fixed;
 | |
|   width: 100%;
 | |
|   z-index: 100000000;
 | |
| }
 | |
| 
 | |
| .shareImg {
 | |
|   position: fixed;
 | |
|   margin: 14rpx 24rpx;
 | |
|   z-index: 1000000000;
 | |
|   right: 10rpx;
 | |
|   top: 10rpx;
 | |
| 
 | |
|   img {
 | |
|     width: 40rpx;
 | |
|     height: 40rpx;
 | |
|   }
 | |
| }
 | |
| 
 | |
| .zhan1 {
 | |
|   height: 50px;
 | |
| }
 | |
| 
 | |
| .seach {
 | |
|   background: #fff;
 | |
|   overflow: hidden;
 | |
|   padding: 20rpx;
 | |
|   display: flex;
 | |
|   justify-content: space-between;
 | |
|   align-items: center;
 | |
|   position: relative;
 | |
|   border-bottom: 2rpx solid #eee;
 | |
| 
 | |
|   .seach_i {
 | |
|     padding: 0 20rpx;
 | |
|     border-radius: 34rpx;
 | |
|     background: #f5f6f8;
 | |
|     flex: 1;
 | |
|   }
 | |
| 
 | |
|   .seatch_r {
 | |
|     background: #005bac;
 | |
|     border-radius: 50%;
 | |
|     padding: 8rpx;
 | |
|     margin-left: 24rpx;
 | |
|   }
 | |
| }
 | |
| 
 | |
| .timeSlide {
 | |
|   display: flex;
 | |
|   align-items: center;
 | |
|   padding: 38rpx 26rpx;
 | |
| 
 | |
|   .timeA {
 | |
|     font-size: 26rpx;
 | |
|     font-family: Source Han Sans CN;
 | |
|     font-weight: 400;
 | |
|     color: #333;
 | |
|     margin-right: 46rpx;
 | |
|     border-bottom: 2rpx solid #fff;
 | |
|   }
 | |
| 
 | |
|   .timeB {
 | |
|     width: 158rpx;
 | |
|     font-size: 24rpx;
 | |
|     font-family: Arial;
 | |
|     font-weight: 400;
 | |
|     color: #999999;
 | |
|     margin-right: 46rpx;
 | |
|     border-bottom: 2rpx solid #eee;
 | |
|     text-align: center;
 | |
|   }
 | |
| }
 | |
| 
 | |
| .tab {
 | |
|   display: flex;
 | |
|   align-items: center;
 | |
|   justify-content: space-between;
 | |
|   padding: 0 24rpx;
 | |
|   margin-top: 20rpx;
 | |
|   margin-bottom: 6rpx;
 | |
| }
 | |
| 
 | |
| .tab_i {
 | |
|   text-align: center;
 | |
|   font-size: 28rpx;
 | |
|   font-family: PingFang SC;
 | |
|   font-weight: 400;
 | |
|   color: #333333;
 | |
|   white-space: nowrap;
 | |
|   display: flex;
 | |
|   flex-direction: column;
 | |
|   align-items: center;
 | |
| }
 | |
| 
 | |
| .heng {
 | |
|   width: 24px;
 | |
|   height: 2px;
 | |
|   background: #ed1d25;
 | |
|   border-radius: 1px 1px 1px 1px;
 | |
|   margin-top: 4rpx;
 | |
| }
 | |
| 
 | |
| .heng1 {
 | |
|   width: 24px;
 | |
|   height: 2px;
 | |
|   background: #fff;
 | |
|   border-radius: 1px 1px 1px 1px;
 | |
|   margin-top: 4rpx;
 | |
| }
 | |
| 
 | |
| .hui {
 | |
|   height: 10rpx;
 | |
|   background: #eee;
 | |
| }
 | |
| 
 | |
| .zhan {
 | |
|   height: 80rpx;
 | |
| }
 | |
| 
 | |
| .con_top {
 | |
|   position: fixed;
 | |
|   background: #fff;
 | |
|   width: 100%;
 | |
|   z-index: 10;
 | |
| }
 | |
| 
 | |
| .disFlex {
 | |
|   display: flex;
 | |
| }
 | |
| 
 | |
| .atm {
 | |
|   align-items: center;
 | |
| }
 | |
| 
 | |
| .just {
 | |
|   justify-content: space-between;
 | |
| }
 | |
| 
 | |
| .mbt10 {
 | |
|   margin-bottom: 14rpx;
 | |
| }
 | |
| 
 | |
| .orderList_i {
 | |
|   padding: 25rpx;
 | |
|   border-bottom: 22rpx solid #eee;
 | |
|   background: #fff;
 | |
| 
 | |
|   img {
 | |
|     width: 124rpx;
 | |
|     height: 124rpx;
 | |
|     border-radius: 20rpx;
 | |
|     margin-right: 20rpx;
 | |
|   }
 | |
| }
 | |
| 
 | |
| .orderList_a {
 | |
|   img {
 | |
|     width: 124rpx;
 | |
|     height: 124rpx;
 | |
|     border-radius: 20rpx;
 | |
|     margin-right: 20rpx;
 | |
|   }
 | |
| }
 | |
| 
 | |
| .quan {
 | |
|   background: #3d3d3d;
 | |
|   border-radius: 15px;
 | |
|   font-size: 20rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #ffffff;
 | |
|   padding: 5rpx 20rpx;
 | |
|   margin-right: 10rpx;
 | |
| }
 | |
| 
 | |
| .tit1 {
 | |
|   font-size: 24rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #999999;
 | |
| }
 | |
| 
 | |
| .tit2 {
 | |
|   font-size: 24rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #69a35b;
 | |
| }
 | |
| 
 | |
| .tit3 {
 | |
|   font-size: 28rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #333333;
 | |
| }
 | |
| 
 | |
| .tit4 {
 | |
|   font-size: 24rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #005bac;
 | |
| }
 | |
| 
 | |
| .tit5 {
 | |
|   font-size: 22rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #666666;
 | |
| }
 | |
| 
 | |
| .tit6 {
 | |
|   font-size: 26rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: 400;
 | |
|   color: #333333;
 | |
| }
 | |
| 
 | |
| .xian {
 | |
|   background: #eee;
 | |
|   height: 2rpx;
 | |
|   margin: 20rpx 0;
 | |
| }
 | |
| 
 | |
| .lBtn {
 | |
|   margin-right: 20rpx;
 | |
| }
 | |
| 
 | |
| .pop_a {
 | |
|   padding: 20rpx;
 | |
| }
 | |
| 
 | |
| .t_tit {
 | |
|   text-align: center;
 | |
|   margin-top: 20px;
 | |
| }
 | |
| 
 | |
| .pop_t {
 | |
|   font-size: 28rpx;
 | |
|   font-family: Source Han Sans CN;
 | |
|   font-weight: bold;
 | |
|   color: #333333;
 | |
| }
 | |
| 
 | |
| :deep(.u-popup__content) {
 | |
|   // width: 90%;
 | |
| }
 | |
| 
 | |
| .pop :deep(.u-popup__content) {
 | |
|   width: 90%;
 | |
| }
 | |
| 
 | |
| .rightPopup {
 | |
|   width: 645rpx;
 | |
| 
 | |
|   .popup_top {
 | |
|     padding: 25rpx;
 | |
|     background-color: rgba(176, 196, 222, 0.45);
 | |
|     display: flex;
 | |
|     justify-content: space-between;
 | |
|     align-items: center;
 | |
|     font-size: 28rpx;
 | |
|     font-family: Source Han Sans CN;
 | |
|     font-weight: 400;
 | |
|     color: #333333;
 | |
|     border-bottom: 2rpx solid #eeeeee;
 | |
| 
 | |
|     .top_red {
 | |
|       color: #005bac;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .typesBox {
 | |
|     margin-top: 40rpx;
 | |
| 
 | |
|     .typeTitle {
 | |
|       padding: 0 24rpx;
 | |
|       font-size: 30rpx;
 | |
|       font-family: Source Han Sans CN;
 | |
|       font-weight: bold;
 | |
|       color: #333333;
 | |
|     }
 | |
| 
 | |
|     .choiceBox {
 | |
|       padding: 0 12rpx;
 | |
|       display: flex;
 | |
|       margin-top: 17rpx;
 | |
|       align-items: center;
 | |
| 
 | |
|       .flex_btn {
 | |
|         background-color: #f4f4f4;
 | |
|         display: flex;
 | |
|         align-items: center;
 | |
|         justify-content: center;
 | |
|         padding: 14rpx 20rpx;
 | |
|         border-radius: 30rpx;
 | |
|         font-size: 24rpx;
 | |
|         font-family: Source Han Sans CN;
 | |
|         font-weight: 400;
 | |
|         color: #333333;
 | |
|         margin: 17rpx 5rpx;
 | |
|         width: 100%;
 | |
|       }
 | |
| 
 | |
|       .selectbtn {
 | |
|         background-color: #005bac;
 | |
|         color: #ffffff;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     .choiceBox1 {
 | |
|       padding: 0 12rpx;
 | |
|       display: flex;
 | |
|       margin-top: 17rpx;
 | |
|       align-items: center;
 | |
|       flex-wrap: wrap;
 | |
| 
 | |
|       .flex_btn {
 | |
|         background-color: rgba(176, 196, 222, 0.45);
 | |
|         display: flex;
 | |
|         align-items: center;
 | |
|         justify-content: center;
 | |
|         padding: 14rpx 20rpx;
 | |
|         border-radius: 30rpx;
 | |
|         font-size: 24rpx;
 | |
|         font-family: Source Han Sans CN;
 | |
|         font-weight: 400;
 | |
|         color: #333333;
 | |
|         margin: 17rpx 5rpx;
 | |
|       }
 | |
| 
 | |
|       .selectbtn {
 | |
|         background-color: #005bac;
 | |
|         color: #ffffff;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   .footer {
 | |
|     position: fixed;
 | |
|     bottom: 0;
 | |
|     display: flex;
 | |
|     align-items: center;
 | |
|     width: 100%;
 | |
| 
 | |
|     .footer_l {
 | |
|       width: 327rpx;
 | |
|       text-align: center;
 | |
|       background: #f3f3f3;
 | |
|       height: 100rpx;
 | |
|       line-height: 100rpx;
 | |
|     }
 | |
| 
 | |
|     .footer_r {
 | |
|       width: 327rpx;
 | |
|       text-align: center;
 | |
|       background: #005bac;
 | |
|       height: 100rpx;
 | |
|       line-height: 100rpx;
 | |
|       color: #fff;
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| .contain :deep(.u-transition) {
 | |
|   top: 45px !important;
 | |
| }
 | |
| 
 | |
| .timePicker :deep(.u-transition) {
 | |
|   z-index: 10076 !important;
 | |
| }
 | |
| </style>
 |