Files
cashier-web/src/views/order/index/components/detail.vue

644 lines
18 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>
<div v-loading="loading">
<el-drawer title="订单详情" size="60%" v-model="drawer" direction="rtl" @close="reset">
<div class="header">
<div class="title" style="text-align: center">收银订单</div>
<div class="container" v-if="user">
<div class="info_content">
<div class="item">
<div class="label">会员信息</div>
<div class="row">
<div>会员昵称-{{ user.nickName || "" }}</div>
<div>联系电话-{{ user.phone || "" }}</div>
</div>
</div>
</div>
</div>
<div v-else>
<h3>服务员下单</h3>
</div>
<div class="table">
<div class="item">
<div class="t">订单状态</div>
<div class="b">
<el-tag :type="detail.status == 'closed' ? 'success' : 'warning'">
{{ statusFilter(detail.status) }}
</el-tag>
</div>
</div>
<div class="item">
<div class="t">订单金额</div>
<div class="b">{{ returnOriginAmount }}</div>
</div>
<div class="item">
<div class="t">订单类型</div>
<div class="b">
{{ sendTypeFilter(detail.sendType) }}
</div>
</div>
</div>
<div class="table">
<div class="item">
<div class="t">订单编号</div>
<div class="b">
{{ detail.orderNo }}
</div>
</div>
<div class="item">
<div class="t">下单时间</div>
<div class="b">{{ timeFilter(detail.createdAt) }}</div>
</div>
<div class="item">
<div class="t">支付时间</div>
<div class="b">
{{ timeFilter(detail.createdAt) }}
</div>
</div>
</div>
</div>
<div class="container">
<!-- <el-tabs v-model="type" @tab-click="getTableData"> -->
<!-- <el-tab-pane label="基本信息" name="1"> -->
<div class="info_content">
<!-- <div class="item">
<div class="label">会员信息</div>
<div class="row">
<div>会员昵称-</div>
<div>联系电话-</div>
</div>
</div> -->
<div class="item">
<div class="label">收款详情</div>
<!-- <div class="row">
<div>商品金额{{ detail.productAmount }}</div>
<div>打包费{{ detail.packFee || "-" }}</div>
</div> -->
<div class="row">
<div>打包费{{ detail.packFee || "-" }}</div>
<div>订单原价{{ detail.originAmount }}</div>
<div>优惠金额{{ detail.discountAmount }}</div>
<div>积分抵扣{{ detail.pointsDiscountAmount }}</div>
<div>
实收金额
<span style="color: red">{{ detail.payAmount }}</span>
<el-button
v-if="detail.status != 'unpaid' && detail.payAmount < detail.refundAmount"
size="small"
type="danger"
class="u-m-l-10"
@click="tuikuan()"
>
<span>退款</span>
</el-button>
</div>
</div>
<div class="row">
<div>
退款金额{{ detail.refundAmount }}
<span
style="color: #ff9731; cursor: pointer"
v-if="detail.isRefund"
@click="type = '3'"
>
退款详情>
</span>
</div>
<div>支付方式{{ returnPayType(detail.payType) }}</div>
</div>
</div>
</div>
<div>
<div style="margin-bottom: 16px; font-size: 16px">商品信息</div>
<template v-for="(item, index) in detail.detailMap" :key="index">
<h4>{{ index }}次下单</h4>
<el-table
:data="item"
:ref="'refTable' + index"
@select-all="tableSelectAll($event, index)"
>
<!-- <el-table-column type="selection" width="55" /> -->
<el-table-column label="数量" type="selection">
<template v-slot="scope">
<div v-if="detail.status == 'unpaid'">
<el-checkbox
v-if="scope.row.num - scope.row.returnNum > 0"
v-model="scope.row.checked"
/>
</div>
<div v-else>
<el-checkbox
v-if="scope.row.num - scope.row.refundNum > 0"
v-model="scope.row.checked"
/>
</div>
</template>
</el-table-column>
<el-table-column label="商品">
<template v-slot="scope">
<div class="shop_info">
<el-image
:src="scope.row.productImg"
style="width: 40px; height: 40px"
></el-image>
<div class="info">
<span :class="[scope.row.isVip == 1 ? 'colorStyle' : '']">
{{ scope.row.productName }}
</span>
<span style="color: #999">{{ scope.row.productSkuName }}</span>
</div>
</div>
</template>
</el-table-column>
<el-table-column label="数量">
<template v-slot="scope">x{{ scope.row.num }}</template>
</el-table-column>
<el-table-column label="单价">
<template v-slot="scope">{{ scope.row.unitPrice }}</template>
</el-table-column>
<el-table-column label="小计">
<template v-slot="scope">{{ scope.row.payAmount }}</template>
</el-table-column>
<el-table-column label="实付">
<template v-slot="scope">{{ scope.row.payAmount }}</template>
</el-table-column>
<el-table-column v-if="detail.status == 'unpaid'" label="可退菜数量" align="center">
<template v-slot="scope">
<el-input-number
v-if="scope.row.checked"
:min="0"
style="width: 120px"
v-model="scope.row.selNumber"
:max="scope.row.num - scope.row.returnNum"
></el-input-number>
<span class="" v-else>{{ scope.row.num - scope.row.returnNum }}</span>
</template>
</el-table-column>
<el-table-column v-else label="可退款数量" align="center">
<template v-slot="scope">
<el-input-number
v-if="scope.row.checked"
:min="0"
style="width: 120px"
v-model="scope.row.selNumber"
:max="scope.row.num - scope.row.refundNum"
></el-input-number>
<span class="" v-else>{{ scope.row.num - scope.row.refundNum }}</span>
</template>
</el-table-column>
<el-table-column label="已退" width="100" align="center">
<template v-slot="scope">
<span v-if="detail.status == 'unpaid'">{{ scope.row.returnNum }}</span>
<span v-else>{{ scope.row.refundNum }}</span>
</template>
</el-table-column>
<el-table-column label="操作">
<template v-slot="scope">
<template v-if="detail.status != 'unpaid'">
<el-button
v-if="canTuikuan(scope.row)"
link
size="small"
@click="tuikuan(scope.row)"
>
<span>退款</span>
</el-button>
<span class="color-999" v-if="scope.row.status == 'refund'">已退款</span>
</template>
<template v-if="detail.status == 'unpaid'">
<el-button
v-if="canTuicai(scope.row)"
link
size="small"
@click="tuicai(scope.row)"
>
<span>退菜</span>
</el-button>
<span class="color-999" v-else>已退菜</span>
</template>
</template>
</el-table-column>
</el-table>
</template>
<!-- 退款 -->
<div
class="u-p-20 u-flex u-row-right"
v-if="detail.status !== 'refund' && detail.status !== 'unpaid'"
>
<el-checkbox
v-model="allSelected"
@change="allSelectedChange"
label="全选"
></el-checkbox>
<el-button type="danger" class="u-m-l-20" @click.stop="tuikuan('all')">退款</el-button>
</div>
<!-- 退菜 -->
<div class="u-p-20 u-flex u-row-right" v-if="detail.status == 'unpaid'">
<el-checkbox
v-model="allSelected"
@change="allSelectedChange"
label="全选"
></el-checkbox>
<el-button type="danger" class="u-m-l-20" @click.stop="tuicai('all')">退菜</el-button>
</div>
</div>
</div>
</el-drawer>
<!-- 退款 -->
<return-money
:modal="false"
ref="refReturnMoney"
:max="selGoods.num"
:goods="selGoods"
@confirm="refReturnMoneyConfirm"
></return-money>
<!-- 退菜 -->
<order-return-cart ref="refReturnCart" @confirm="refReturnCartConfirm"></order-return-cart>
</div>
</template>
<script>
import returnMoney from "./return-money.vue";
import orderReturnCart from "./order-return-cart.vue";
import { ElMessage } from "element-plus";
import { returnOptionsLabel } from "../config/config";
import * as $util from "../order_goods_util.js";
import orderApi from "@/api/order/order";
import shopUserApi from "@/api/account/shopUser";
import orderEnum from "./orderEnum";
import dayjs from "dayjs";
export default {
components: {
returnMoney,
orderReturnCart,
},
data() {
return {
allSelected: false,
user: "",
orderEnum,
drawer: false,
type: "1",
detail: "",
loading: false,
refoundList: [],
selGoods: { num: 1 },
};
},
watch: {
drawer: function (newval) {
if (!newval) {
this.close();
}
},
},
computed: {
vipDiscountAmount() {
return 0;
},
youHuiJinE() {
const n = 0;
return n;
},
//计算订单原金额
returnOriginAmount() {
let amount = 0;
if (this.detail && this.detail.originAmount) {
return this.detail.originAmount;
}
if (!this.detail) {
return 0;
}
for (let i in this.detail.detailMap) {
amount += this.detail.detailMap[i].reduce((pre, cur) => {
return pre + cur.payAmount;
}, 0);
}
return amount.toFixed(2);
},
},
methods: {
tableSelect(e) {
console.log(e);
},
tableSelectAll(e, index) {
const arr = this.detail.detailMap[index];
for (let i in arr) {
arr[i].checked = e.length ? true : false;
}
},
tableSelectionChange(e) {
console.log(e);
},
rowClick(row, index) {
this.$refs["refTable" + index][0].toggleRowSelection(row);
},
selectionChange(e) {
console.log(e);
},
allSelectedChange(newval) {
for (let i in this.detail.detailMap) {
for (let key in this.detail.detailMap[i]) {
this.detail.detailMap[i][key].checked = newval;
}
}
},
reset() {
this.user = "";
this.allSelected = false;
this.$emit("close");
},
returnPayType(payType) {
if (!payType) {
return "";
}
console.log(payType.replace("_pay", ""));
return returnOptionsLabel("payType", payType.replace("_pay", ""));
},
to2(n) {
return Number(n).toFixed(2);
},
orderTypeFilter(t) {
if (t) {
return t && orderEnum.orderType.find((item) => item.key == t).label;
} else {
return t;
}
},
sendTypeFilter(t) {
if (t) {
return orderEnum.sendType.find((item) => item.key == t).label;
} else {
return t;
}
},
statusFilter(t) {
return returnOptionsLabel("status", t);
},
timeFilter(t) {
if (t) {
return dayjs(t).format("YYYY-MM-DD HH:mm:ss");
} else {
return "-";
}
},
isShowGoodsVipPrice(item) {
return $util.isShowGoodsVipPrice(item);
},
isUseCalcPrice(item) {
return $util.isUseCalcPrice(this.detail, item);
},
close() {
console.log("drawer close");
this.$emit("close");
},
isTui(item) {
return $util.isTui(item);
},
canTuikuan(item) {
return $util.canTuiKuan(this.detail, item);
},
canTuicai(item) {
return $util.canTuicai(this.detail, item);
},
async refReturnMoneyConfirm(e) {
const res = await orderApi.refundOrder({
...e,
orderId: this.detail.id,
});
ElMessage.success("退款成功");
this.update();
},
update() {
this.tbOrderInfoDetail(this.detail.id);
},
async refReturnCartConfirm(e) {
const res = await orderApi.refundOrder({
...e,
orderId: this.detail.id,
});
ElMessage.success("退菜成功");
this.update();
},
tuikuan(item) {
if (!item) {
this.$refs.refReturnMoney.open([], this.detail);
return;
}
let arr = [];
if (item === "all") {
for (let i in this.detail.detailMap) {
this.detail.detailMap[i].map((v) => {
if (v.checked && v.selNumber) {
arr.push(v);
}
});
}
} else {
arr = [item];
}
if (arr.length == 0) {
return ElMessage.error("请选择要退款的商品和数量");
}
this.$refs.refReturnMoney.open(arr, this.detail);
},
tuicai(item) {
let arr = [];
if (item === "all") {
for (let i in this.detail.detailMap) {
this.detail.detailMap[i].map((v) => {
if (v.checked && v.selNumber) {
arr.push(v);
}
});
}
} else {
arr = [item];
}
if (arr.length == 0) {
return ElMessage.error("请选择要退菜的商品和数量");
}
console.log(arr);
this.$refs.refReturnCart.open(arr, this.detail);
},
// 获取订单详情
async tbOrderInfoDetail(id) {
try {
this.loading = true;
const res = await orderApi.get({ orderId: id });
if (res.userId) {
shopUserApi.get({ userId: res.userId }).then((res1) => {
this.user = res1;
});
}
for (let i in res.detailMap) {
res.detailMap[i] = res.detailMap[i].map((v) => {
console.log(v.num - (res.status == "unpaid" ? v.returnNum : v.refundNum));
return {
...v,
checked: false,
selNumber: v.num - (res.status == "unpaid" ? v.returnNum : v.refundNum),
};
});
}
this.detail = res;
this.loading = false;
} catch (error) {
console.log(error);
}
},
show(obj) {
this.drawer = true;
this.type = "1";
this.detail = "";
this.tbOrderInfoDetail(obj.id);
},
},
};
</script>
<style scoped lang="scss">
.packeFee {
width: 40px;
box-sizing: border-box;
height: 40px;
background: #3f9eff;
color: #fff;
font-size: 12px;
display: flex;
justify-content: center;
align-items: center;
white-space: nowrap;
}
.shop_info {
display: flex;
.info {
flex: 1;
display: flex;
flex-direction: column;
padding-left: 6px;
}
}
.header {
padding: 0 20px 0;
.title {
font-size: 20px;
color: #ff9731;
}
.table {
display: flex;
padding: 20px 0;
.item {
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
font-size: 14px;
.b {
padding-top: 20px;
border: none;
}
}
}
}
.line-th {
text-decoration: line-through;
}
.container {
padding: 0 20px;
font-size: 14px;
.info_content {
padding: 20px 0;
.item {
border-bottom: 1px dashed #ececec;
padding-bottom: 20px;
&:not(:first-child) {
margin-top: 20px;
}
.label {
position: relative;
padding-left: 20px;
color: #333;
&::after {
content: "";
width: 4px;
height: 100%;
position: absolute;
left: 0;
top: 0;
background-color: #1890ff;
}
}
.row {
display: flex;
color: #555;
padding-top: 20px;
div {
width: 25%;
}
}
}
}
.refund_wrap {
.row {
border-bottom: 1px dashed #ececec;
padding-bottom: 20px;
&:not(:first-child) {
margin-top: 20px;
}
.time {
font-weight: bold;
color: #333;
}
.list {
.list_row {
display: flex;
padding-top: 10px;
.item {
flex: 1;
display: flex;
color: #555;
.name {
margin-left: 6px;
}
}
}
}
.foot {
color: #333;
display: flex;
justify-content: flex-end;
}
}
}
}
.colorStyle {
color: #ffc315;
}
</style>