订单详情

merge-requests/11/head
ch 2 years ago
parent 3cf9e54b01
commit 0f0b283387

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 763 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 752 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 812 B

@ -15,7 +15,7 @@
@extend *;
}
}
body, dl, dd, h1, h2, h3, h4, h5, p, figure, form, ul, ol { margin: 0; font-size: .16rem;}
body, dl, dd, h1, h2, h3, h4, h5, p, figure, form, ul, ol { margin: 0; font-size: 14px;}
ul, ol, input, button { padding: 0;}
ul, ol, li { list-style: none;list-style-type: none}
h1, h2, h3, h4, h5 { font-size: 100%;}

@ -2,12 +2,12 @@
* @Author: ch
* @Date: 2022-05-08 00:39:50
* @LastEditors: ch
* @LastEditTime: 2022-05-08 17:25:08
* @LastEditTime: 2022-05-09 21:17:10
* @Description: file content
-->
<template>
<el-dialog title="打开微信扫描付款" width="380px" class="box" center
:visible="visible" @open="getCodeImg" @close="close">
:visible.sync="myVisible" @open="getCodeImg" @close="close">
<div class="pay">
<span class="pay--timer" v-if="startSecondNum">{{timerTxt}}</span>
<UiMoney class="money" sufSize="14px" preSize="14px" size="20px"
@ -41,26 +41,34 @@ export default {
},
data(){
return {
imgUrl : 'https://pay.mashibing.com/api/scan/imgs/d2VpeGluOi8vd3hwYXkvYml6cGF5dXJsP3ByPVo4alVpUmF6eg==.png',
imgUrl : '',
timerTxt : '',
timerStop : null,
startSecondNum : 1800
startSecondNum : 0
}
},
mounted(){
this.timer()
computed:{
myVisible : {
get(){
return this.visible;
},
set(val){
this.$emit('update:visible', val)
}
}
},
methods : {
async getCodeImg(){
this.startSecondNum = 1800;
//
if(this.timerStop){
clearTimeout(this.timerStop);
}
this.timerStop = null;
const {error, result} = await ApiPostPayCdoeImg({orderId : this.orderId});
if(error){
return false;
}
//
if(this.timerStop){
clearTimeout(this.timerStop);
}
this.timer();
this.imgUrl = result.dataInfo.codeImgData;
},

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-05-09 11:31:29
* @LastEditors: ch
* @LastEditTime: 2022-05-09 14:22:43
* @LastEditTime: 2022-05-09 15:24:30
* @Description: 按钮每个类型有设置默认高 宽度默认随内容变化有特殊大小需要自定义class控制
props
type 固定按钮类型 红色面板 red_panel 红色描边red_line 黄色面板yellow_panel 黄色线条yellow_line 黄色渐变yellow_gradual 灰色grey
@ -33,9 +33,7 @@ export default {
computed : {
myClass(){
let classStr = this.type ? ` ui-button__${this.type}` : '';
if(this.radius && typeof this.radius === 'boolean'){
classStr += ' ui-button__radius'
}
classStr += this.radius ? ` ui-button__radius` : '';
classStr += this.disabled ? ' ui-button__disabled' : '';
return classStr;
}
@ -79,12 +77,15 @@ export default {
background:#FF512B;
height: 30px;
padding: 0 10px;
border: none;
color: #fff;
}
&__yellow_gradual{
background: linear-gradient(270deg, #FFA25A 0%, #FF7F39 100%);
height: 42px;
background: linear-gradient(90deg, #FFA25A 0%, #FF7F39 100%);
height: 30px;
border: none;
color: #fff;
padding: 0 10px;
}
&__grey{
background:#f5f5f5;

@ -0,0 +1,27 @@
<!--
* @Author: ch
* @Date: 2022-05-09 20:00:57
* @LastEditors: ch
* @LastEditTime: 2022-05-09 20:04:59
* @Description: file content
-->
<template>
<el-dialog :visible="visible" @close="close">
<slot></slot>
</el-dialog>
</template>
<script>
export default {
props: {
visible : {
type : Boolean,
default : false
}
},
methods:{
close(...args){
this.$emit('close', args)
}
}
}
</script>

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-05-07 22:40:55
* @LastEditors: ch
* @LastEditTime: 2022-05-08 14:24:16
* @LastEditTime: 2022-05-09 16:04:47
* @Description: file content
-->
<template>
@ -23,6 +23,8 @@ export default {
border:1px solid #ddd;
&--head{
height: 42px;
line-height: 42px;
padding: 0 30px;
background: #f8f8f8;
}
}

@ -18,7 +18,7 @@ export default {
</script>
<style lang="scss" scoped>
.account{
padding-top: 370px;
padding: 30px 0;
margin: 0 auto;
display: flex;
&--nav{

@ -2,9 +2,69 @@
* @Author: ch
* @Date: 2022-05-08 01:14:03
* @LastEditors: ch
* @LastEditTime: 2022-05-08 01:14:31
* @LastEditTime: 2022-05-09 20:50:56
* @Description: file content
-->
<template>
<div>订单详情页</div>
<div>
<div class="box">
<StatusInfo :orderInfo="orderInfo" @cancel="getOrderInfo"
@receive="getOrderInfo"/>
<StatusStep :orderInfo="orderInfo" />
</div>
<LogisitcsInfo :orderInfo="orderInfo" />
<div class="pay-type" v-if="orderInfo.payType !== 1">
<p>支付方式{{orderInfo.payTypeDesc}}</p>
<p>支付时间{{orderInfo.submitTime}}</p>
</div>
<GoodsInfo :orderInfo="orderInfo"/>
</div>
</template>
<script>
import {ApiGetOrderDetail} from '@/plugins/api/order';
import StatusInfo from './module/StatusInfo.vue';
import StatusStep from './module/StatusStep.vue';
import LogisitcsInfo from './module/LogisitcsInfo.vue';
import GoodsInfo from './module/GoodsInfo.vue';
export default {
components: { StatusInfo, StatusStep, LogisitcsInfo, GoodsInfo },
data(){
return {
orderInfo : {}
}
},
mounted(){
this.getOrderInfo();
},
methods:{
/**
* 获取订单最新信息
*/
async getOrderInfo(){
const {error, result} = await ApiGetOrderDetail(this.$route.query.id);
if(error){
this.$message.warning(error.message);
return false;
}
this.orderInfo = {...result};
},
}
}
</script>
<style lang="scss" scoped>
.box{
border: 1px solid #ddd;
border-radius: 4px;
display: flex;
}
.pay-type{
border: 1px solid #ddd;
background: #f8f8f8;
height: 59px;
line-height: 59px;
padding: 0 30px;
display: flex;
justify-content: space-between;
}
</style>

@ -0,0 +1,122 @@
<!--
* @Author: ch
* @Date: 2022-05-09 20:20:02
* @LastEditors: ch
* @LastEditTime: 2022-05-09 20:41:46
* @Description: file content
-->
<template>
<el-dialog :visible.sync="myVisible" title="取消订单原因" width="380px">
<ul class="cancel">
<li v-for="item in cancelData" :key="item.value" @click="selected = item.value"
:class="selected == item.value && 'cancel__active'">
{{item.label}}
</li>
</ul>
<UiButton type="yellow_gradual" class="btn" :radius="true" :disabled="!selected"
@click="cancelOrder">确认取消</UiButton>
</el-dialog>
</template>
<script>
import {ApiPutCancelOrder,ApiPutOrderReceive} from '@/plugins/api/order'
import UiButton from '../../../../../../components/UiButton.vue';
export default {
components: { UiButton },
props : {
visible : {
type : Boolean,
default : false
},
orderId : {
type : Number
}
},
data(){
return {
selected : '',
cancelData : [
{value : 1, label : '我不想买了'},
{value : 2, label : '地址信息填写错误'},
{value : 3, label : '商品降价'},
{value : 4, label : '商品无货'},
{value : 5, label : '其他'}
]
}
},
computed:{
myVisible : {
get(){
return this.visible;
},
set(val){
this.$emit('update:visible', val)
}
}
},
methods:{
async cancelOrder(){
const ooderId = this.orderId;
const {error, result} = await ApiPutCancelOrder({
cancelReasonType : this.selected,
orderId : ooderId
});
if(error){
this.$message.error(error.message);
return false;
}
this.myVisible = false;
this.$emit('cancel')
//
}
}
}
</script>
<style lang="scss" scoped>
.cancel{
width: 320px;
margin: 0 auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-top: 10px;
li{
width: 150px;
height: 36px;
line-height: 36px;
text-align: center;
border: 1px solid #ddd;
cursor: pointer;
margin: 15px 0;
&.cancel__active{
border-color: #FF875B;
color: #FF875B;
}
}
}
.btn{
width: 320px;
height: 36px;
margin-top: 25px;
}
/deep/{
.el-dialog{
border-radius: 4px;
}
.el-dialog__header{
padding: 30px 0 15px;
}
.el-dialog__title{
font-size: 20px;
font-weight: bold;
}
.el-dialog__body{
padding-top: 0;
padding-bottom: 50px;
}
.el-dialog__headerbtn{
top: 32px;
right: 30px;
}
}
</style>

@ -0,0 +1,127 @@
<!--
* @Author: ch
* @Date: 2022-05-09 16:24:49
* @LastEditors: ch
* @LastEditTime: 2022-05-09 21:26:52
* @Description: file content
-->
<template>
<div>
<table class="goods">
<thead>
<tr>
<th>商品信息</th>
<th width="96">单价</th>
<th width="96">数量</th>
<th width="163">实付款</th>
<th width="135">操作</th>
</tr>
</thead>
<tbody>
<tr v-for="i in products" :key="i.orderProductId">
<td class="not-border"><UIGoodsInfo :goods="i"/></td>
<td class="not-border">
<UiMoney :money="i.realAmount" float/>
</td>
<td class="not-border">{{i.quantity}}</td>
<td>
<UiMoney :money="i.realAmount" float/>
</td>
<td>
<template v-if="i.afterSaleApplyFlag || [2,3,4].includes(i.detailStatus)">
<a v-if="i.afterSaleApplyFlag"></a>
<span v-else>
{{ i.detailStatus === 2 ? '退款中' : i.detailStatus === 3 ? '已退款' : '退款关闭'}}
</span>
</template>
</td>
</tr>
</tbody>
</table>
<div class="message">
<div>
<label>买家留言</label>
<span>{{orderInfo.userMessage || '无'}}</span>
</div>
<div>
<p>
<label>商品总额</label>
<UiMoney :money="orderInfo.totalAmount" float/>
</p>
<p>
<label>运费</label>
<UiMoney :money="orderInfo.shippingAmount" float/>
</p>
<p>
<label>
{{orderInfo.orderStatus == 1 ? '应付款:' : '实付款:'}}
</label>
<UiMoney :money="orderInfo.payAmount" float prefix suffix/>
</p>
</div>
</div>
</div>
</template>
<script>
import UIGoodsInfo from '@/components/UIGoodsInfo.vue'
import UiMoney from '@/components/UiMoney.vue'
export default {
components: { UIGoodsInfo, UiMoney },
props : {
orderInfo : {
type : Object,
default : () => ({})
}
},
computed:{
products (){
return this.orderInfo.products || []
}
}
}
</script>
<style lang="scss" scoped>
.goods{
width: 100%;
border: 1px solid #ddd;
margin-top: 30px;
th{
height: 42px;
background: #f8f8f8;
font-weight: normal
};
td{
text-align: center;
border: 1px solid #ddd;
padding: 10px 20px;
&.not-border{
border-left: 0;
border-right: 0;
}
}
tbody tr:first-child td{
padding-top: 20px
}
tbody tr:last-child td{
padding-bottom: 20px
}
}
.message{
border: 1px solid #ddd;
border-top: 0;
display: flex;
justify-content: space-between;
padding: 30px;
p{
width: 250px;
display: flex;
justify-content: space-between;
&:nth-child(2){
margin: 20px 0;
}
}
}
</style>

@ -0,0 +1,136 @@
<!--
* @Author: ch
* @Date: 2022-05-09 15:52:51
* @LastEditors: ch
* @LastEditTime: 2022-05-09 18:05:32
* @Description: file content
-->
<template>
<div class="logisitcs">
<UiLineBox class="logisitcs--info" title="收货人信息">
<div class="title" slot="head">
<b>收货人信息</b>
</div>
<div slot="body" class="info">
<p>
<label>收货人</label>
<span>{{logisitcsInfo.recipientName}}</span>
</p>
<p>
<label>手机号码</label>
<span>{{logisitcsInfo.recipientPhone}}</span>
</p>
<p>
<label>收货地址</label>
<span>{{logisitcsInfo.recipientAddress}}{{logisitcsInfo.recipientAddress}}{{logisitcsInfo.recipientAddress}}</span>
</p>
</div>
</UiLineBox>
<UiLineBox class="logisitcs--list" v-if="logisitcsList.length">
<div slot="head" class="title">
<b>物流信息</b>
<span>中嘻嘻嘻</span>
</div>
<ul slot="body" class="list">
<li v-for="(item, idx) in logisitcsList" :key="idx">
<b class="item--time">{{item.time}}</b>
<span class="item--ctx">{{item.context}}</span>
</li>
</ul>
</UiLineBox>
</div>
</template>
<script>
import UiLineBox from '@/components/UiLineBox.vue'
export default {
components: { UiLineBox },
props : {
orderInfo : {
type : Object,
defalut : () => ({})
}
},
computed:{
logisitcsInfo(){
return this.orderInfo.logistics || {}
},
logisitcsList(){
return this.logisitcsInfo.logisticsDataList || []
}
}
}
</script>
<style lang="scss" scoped>
.logisitcs{
display: flex;
margin: 30px 0;
&--info{
flex: 1;
}
&--list{
width: 670px;
margin-left: 28px;
}
}
.info{
padding: 20px 30px;
color: #666;
p{
display: flex;
margin-bottom:20px ;
label{
width: 70px;
}
span{
flex: 1;
}
}
}
.list{
padding: 30px ;
height: 180px;
overflow-y: auto;
li{
position: relative;
padding-left: 20px;
padding-bottom: 20px;
font-size: 14px;
b{
display: block;
line-height: 14px;
margin-bottom: 10px;
}
span{
color: #999;
}
&::before{
display: block;
width: 10px;
height: 10px;
content: '';
border-radius: 50%;
background: #1EBC20;
position: absolute;
left: 0;
top: 2px;
}
&::after{
display: block;
content: '';
height: 100%;
width: 2px;
left: 5px;
top: 2px;
border-left: 1px solid #1EBC20;
position: absolute;
}
&:last-child{
padding-bottom: 0;
&::after{
display: none;
}
}
}
}
</style>

@ -0,0 +1,157 @@
<!--
* @Author: ch
* @Date: 2022-05-09 14:41:37
* @LastEditors: ch
* @LastEditTime: 2022-05-09 21:12:47
* @Description: file content
-->
<template>
<div class="operation">
<span>订单编号{{orderInfo.orderNo}}</span>
<p>订单状态{{orderInfo.orderStatusDesc}}</p>
<span>{{ctxCon.tips}}</span>
<div class="operation--btns">
<!-- 已发货可以确认收货 -->
<UiButton v-if="orderInfo.orderStatus === 4" type="yellow_gradual" :radius="true" @click="receive"></UiButton>
<!-- 待支付可以取消支付订单 -->
<template v-if="orderInfo.orderStatus === 1">
<UiButton type="yellow_gradual" :radius="true" @click="payVisible = true">去支付</UiButton>
<UiButton type="grey" :radius="true" @click="cancelVisible=true"></UiButton>
</template>
</div>
<Cancel :visible.sync="cancelVisible" :orderId="orderInfo.orderId" @cancel="cancel"/>
<BsPay :visible.sync="payVisible" :orderId="orderInfo.orderId"/>
</div>
</template>
<script>
import BsPay from '../../../../../../components/BsPay.vue'
import UiButton from '../../../../../../components/UiButton.vue'
import Cancel from './Cancel.vue'
export default {
components: { UiButton, Cancel, BsPay },
props: {
orderInfo : {
type : Object,
default : () => ({})
}
},
data(){
return {
ctxData : {
//
'1' : {name:'待付款', tips:''},
//
'2' : {name:'交易关闭' , tips:'关闭原因'},
//
'3' : {name:'等待发货', tips:'您的包裹整装待发'},
//
'4' : {name:'已发货', tips:'您的包裹正向您飞来'},
//
'5' : {name:'已收货'},
//
'6' : {name:'交易成功'},
},
ctxCon : {},
startSecondNum : 0,
timerStop : null,
cancelVisible : false,
payVisible : false
}
},
watch : {
orderInfo(nVal){
const {orderStatus} = this.orderInfo;
this.ctxCon = this.ctxData[orderStatus];
if(orderStatus === 1){
//
if(this.timerStop){
clearTimeout(this.timerStop);
}
this.calcTimerStartSecondNum();
this.timer();
}else if(orderStatus === 2){
this.ctxCon.tips = this.orderInfo.cancelReason;
}
}
},
methods:{
/**
* 计算倒计时开始秒数
*/
calcTimerStartSecondNum(){
let expireTime = (new Date(this.orderInfo.expireTime.replace(/-/g,'/'))).getTime(),
curTime = (new Date(this.orderInfo.serverTime.replace(/-/g,'/'))).getTime(),
second = Math.floor((expireTime - curTime) / 1000);
this.startSecondNum = second > 0 ? second : 0;
},
/**
* 待付款的倒计时
*/
timer(){
if(this.startSecondNum == 0){
this.$emit('close');
return;
}
this.startSecondNum--;
let minute = parseInt(this.startSecondNum / 60);
let second = parseInt(this.startSecondNum % 60);
this.ctxCon.tips = `剩余${minute > 0 ? `${minute}` : ''} ${second}`;
this.timerStop = setTimeout(()=>this.timer(),1000)
},
/**
* 确认收货
*/
receive(){
this.$confirm('确认已经收到货了吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const {error} = await ApiPutOrderReceive({orderId : this.orderInfo.orderId});
if(error){
uni.$toast(error.message);
return false;
}
this.$message({
type: 'success',
message: '成功收货!'
});
this.$emit('receive')
});
},
cancel(){
this.$emit('cancel')
}
}
}
</script>
<style lang="scss" scoped>
.operation{
width: 300px;
height: 200px;
background: #f8f8f8;
padding-top: 20px;
text-align: center;
border-right: 1px solid #ddd;
span{
color: #999;
}
p{
font-size: 14px;
margin: 30px 0 15px;
}
&--btns{
margin-top: 30px;
button{
margin: 0 7px;
width: 100px;
}
}
}
</style>

@ -0,0 +1,72 @@
<!--
* @Author: ch
* @Date: 2022-05-09 14:41:37
* @LastEditors: ch
* @LastEditTime: 2022-05-09 19:55:10
* @Description: file content
-->
<template>
<ul class="step">
<li v-for="item in steps" :key="item.operationType">
<img src="@/assets/img/account/order_status_1.png"/>
<b>{{item.operationTypeDesc}}</b>
<span>{{item.createTime}}</span>
<span>{{item.createTime}}</span>
</li>
</ul>
</template>
<script>
import UiButton from '../../../../../../components/UiButton.vue'
export default {
components: { UiButton },
props: {
orderInfo : {
type : Object,
default : () => ({})
}
},
data(){
return {
}
},
computed:{
steps(){
const normalStep = [
{type : 1, name : '待付款' },
{type : 6, name : '支付订单' },
{type : 7, name : '平台发货' },
{type : 1, name : '确认收货' },
{type : 1, name : '交易完成' },
{type : 2, name : '交易关闭' }
];
return [];
}
},
methods:{
}
}
</script>
<style lang="scss" scoped>
.step{
padding: 45px 65px 0 65px;
display: flex;
flex: 1;
justify-content: space-between;
li{
text-align: center;
img{
width: 66px;
}
b{
display: block;
margin: 10px 0;
color: #999;
}
span{
display: block;
color: #666;
}
}
}
</style>

@ -2,7 +2,7 @@
* @Author: ch
* @Date: 2022-05-04 17:30:58
* @LastEditors: ch
* @LastEditTime: 2022-05-09 14:13:53
* @LastEditTime: 2022-05-09 14:33:52
* @Description: file content
-->
@ -113,7 +113,7 @@ export default {
},
cancelPay(){
this.$router.replace('/order/detail')
this.$router.replace(`/account/order/detail?id=${this.orderId}`)
}
}
}

Loading…
Cancel
Save