feat: 已实现订单基本逻辑,到完成,却订单售后

This commit is contained in:
2026-07-30 15:55:00 +08:00
parent 1cbacf987d
commit 5de4d6f9f4
15 changed files with 781 additions and 176 deletions
@@ -68,81 +68,222 @@ layout("/layouts/platform.html"){
></el-pagination>
</el-card>
<el-dialog :close-on-click-modal="false" :title="'子订单详情 - ' + currentMainOrderId" :visible.sync="subDialogVisible" top="5vh" width="88%">
<el-table :data="subOrderList" border size="small" style="width: 100%" v-loading="subLoading">
<el-table-column align="center" label="子订单号" min-width="170" prop="orderId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="订单编码" min-width="150" prop="orderNumberId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="供应商" min-width="130" prop="supplierName" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="工号" min-width="110" prop="userAccount"></el-table-column>
<el-table-column align="center" label="创建时间" min-width="160" prop="orderCreateTime"></el-table-column>
<el-table-column align="center" label="订单状态" min-width="100">
<template slot-scope="{row}">
<el-tag :type="orderStatusType(row.orderState)" size="mini">{{ orderStateName(row.orderState) }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="消费积分" min-width="100" prop="pointsPrice"></el-table-column>
<el-table-column align="center" label="物流单号" min-width="140" prop="logisticsOrderId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="发票代码" min-width="120" prop="invoiceCode" show-overflow-tooltip></el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="180">
<template slot-scope="{row}">
<el-button @click="openProducts(row, false)" size="mini">商品</el-button>
<el-button @click="openExchange(row)" size="mini" type="warning">售后</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="subPageForm.pageNumber"
:page-size="subPageForm.pageSize"
:total="subPageForm.totalCount"
@current-change="subPageChange"
layout="total, prev, pager, next"
style="margin-top: 16px; text-align: right"
></el-pagination>
<span slot="footer">
<el-button @click="subDialogVisible = false">关闭</el-button>
</span>
</el-dialog>
<el-dialog :close-on-click-modal="false" :title="productDialogTitle" :visible.sync="productDialogVisible" width="72%">
<el-table :data="productList" border size="small" v-loading="productLoading">
<el-table-column align="center" label="商品名称" min-width="220" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="SKU" min-width="140" prop="sku" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="数量" width="90" prop="number"></el-table-column>
<el-table-column align="center" label="单价" width="110" prop="price"></el-table-column>
<el-table-column align="center" label="税率" width="110" prop="taxRate"></el-table-column>
<el-table-column align="center" label="图片信息" min-width="180" prop="picInfo" show-overflow-tooltip></el-table-column>
</el-table>
<span slot="footer">
<el-button @click="productDialogVisible = false">关闭</el-button>
</span>
</el-dialog>
<el-dialog :close-on-click-modal="false" :title="'售后单 - ' + currentSubOrderId" :visible.sync="exchangeDialogVisible" width="82%">
<el-table :data="exchangeList" border size="small" v-loading="exchangeLoading">
<el-table-column align="center" label="售后订单号" min-width="170" prop="orderId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="供应商" min-width="130" prop="supplierName" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="工号" min-width="110" prop="userAccount"></el-table-column>
<el-table-column align="center" label="创建时间" min-width="160" prop="orderCreateTime"></el-table-column>
<el-table-column align="center" label="状态" min-width="100">
<template slot-scope="{row}">
<el-tag :type="orderStatusType(row.orderState)" size="mini">{{ orderStateName(row.orderState) }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="退款" width="100" prop="refund"></el-table-column>
<el-table-column align="center" label="消费积分" width="110" prop="pointsPrice"></el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="100">
<template slot-scope="{row}">
<el-button @click="openProducts(row, true)" size="mini">商品</el-button>
</template>
</el-table-column>
</el-table>
<span slot="footer">
<el-button @click="exchangeDialogVisible = false">关闭</el-button>
</span>
</el-dialog>
<order-sub-list-dialog
:order-status-type="orderStatusType"
:order-state-name="orderStateName"
:visible.sync="subDialogVisible"
:main-order-id="currentMainOrderId"
></order-sub-list-dialog>
</div>
<script nonce="${cspNonce!}">
Vue.component("order-detail-dialog", {
props: {
visible: Boolean,
orderId: String
},
data() {
return {
loading: false,
productList: []
}
},
watch: {
visible(val) {
if (val) {
this.loadProducts()
}
},
orderId() {
if (this.visible) {
this.loadProducts()
}
}
},
methods: {
close() {
this.$emit("update:visible", false)
},
async loadProducts() {
if (!this.orderId) {
this.productList = []
return
}
this.loading = true
const resp = await this.$axios.post(loc() + "/productList", { orderId: this.orderId })
this.loading = false
if (resp.code === 0) {
this.productList = (resp.data || []).map((item) => Object.assign({}, item, {
orderId: this.orderId
}))
} else if (this.$message) {
this.$message.warning(resp.msg)
}
}
},
template: `
<el-dialog :close-on-click-modal="false" title="子订单商品明细" :visible="visible" @update:visible="$emit('update:visible', $event)" width="72%">
<el-table :data="productList" border size="small" v-loading="loading">
<el-table-column align="center" label="订单号" min-width="180" prop="orderId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="SKU" min-width="140" prop="sku" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="商品名称" min-width="220" prop="name" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="商品单价" width="110" prop="price"></el-table-column>
<el-table-column align="center" label="商品图片" width="120">
<template slot-scope="{row}">
<el-image
v-if="row.fileId"
:src="row.fileId"
style="width: 60px; height: 60px"
fit="contain"
preview-teleported
></el-image>
</template>
</el-table-column>
<el-table-column align="center" label="商品数量" width="110" prop="number"></el-table-column>
<el-table-column align="center" label="税率" width="110" prop="taxRate"></el-table-column>
</el-table>
<span slot="footer">
<el-button @click="close">关闭</el-button>
</span>
</el-dialog>
`
})
Vue.component("order-sub-list-dialog", {
props: {
visible: Boolean,
mainOrderId: String,
orderStateName: Function,
orderStatusType: Function
},
data() {
return {
loading: false,
subOrderList: [],
pageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0
},
detailVisible: false,
detailOrderId: null
}
},
watch: {
visible(val) {
if (val) {
this.pageForm.pageNumber = 1
this.pageData()
}
},
mainOrderId() {
if (this.visible) {
this.pageForm.pageNumber = 1
this.pageData()
}
}
},
methods: {
close() {
this.$emit("update:visible", false)
},
async pageData() {
if (!this.mainOrderId) {
this.subOrderList = []
return
}
this.loading = true
const resp = await this.$axios.post(loc() + "/subPageData", {
pageNumber: this.pageForm.pageNumber,
pageSize: this.pageForm.pageSize,
mainOrderId: this.mainOrderId
})
this.loading = false
if (resp.code === 0) {
this.subOrderList = resp.data.list || []
this.pageForm.totalCount = resp.data.totalCount || 0
} else if (this.$message) {
this.$message.warning(resp.msg)
}
},
pageChange(val) {
this.pageForm.pageNumber = val
this.pageData()
},
deliveryStatusName(value) {
const map = {
0: "未发货",
1: "已发货"
}
return map[value] || "-"
},
deliveryStatusType(value) {
const map = {
0: "warning",
1: "success"
}
return map[value] || "info"
},
openDetails(row) {
this.detailOrderId = row.orderId
this.detailVisible = true
}
},
template: `
<div>
<el-dialog :close-on-click-modal="false" :title="'子订单详情 - ' + (mainOrderId || '')" :visible="visible" @update:visible="$emit('update:visible', $event)" top="5vh" width="88%">
<el-table :data="subOrderList" border size="small" style="width: 100%" v-loading="loading">
<el-table-column align="center" label="子订单号" min-width="170" prop="orderId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="订单编码" min-width="150" prop="orderNumberId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="供应商名称" min-width="150" prop="supplierName" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="应用名称" min-width="120" prop="aplName" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="创建时间" min-width="160" prop="orderCreateTime"></el-table-column>
<el-table-column align="center" label="订单状态" min-width="110">
<template slot-scope="{row}">
<el-tag :type="orderStatusType(row.orderState)" size="mini">{{ orderStateName(row.orderState) }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="订单总金额" min-width="120" prop="totalPrice"></el-table-column>
<el-table-column align="center" label="消费积分" min-width="110" prop="pointsPrice"></el-table-column>
<el-table-column align="center" label="供应商ID" min-width="120" prop="supplierId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="工号" min-width="120" prop="userAccount" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="更新时间" min-width="160" prop="orderUpdateTime"></el-table-column>
<el-table-column align="center" label="发货时间" min-width="160" prop="deliveryTime"></el-table-column>
<el-table-column align="center" label="确认收货时间" min-width="160" prop="orderFinishTime"></el-table-column>
<el-table-column align="center" label="完成时间" min-width="160" prop="orderCompleteTime"></el-table-column>
<el-table-column align="center" label="发货状态" min-width="100">
<template slot-scope="{row}">
<el-tag :type="deliveryStatusType(row.deliveryStatus)" size="mini">{{ deliveryStatusName(row.deliveryStatus) }}</el-tag>
</template>
</el-table-column>
<el-table-column align="center" label="运费金额" min-width="110" prop="freightCost"></el-table-column>
<el-table-column align="center" label="积分退回" min-width="110" prop="refund"></el-table-column>
<el-table-column align="center" label="物流单号" min-width="140" prop="logisticsOrderId" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="物流承运商" min-width="140" prop="crrgBsnNm" show-overflow-tooltip></el-table-column>
<el-table-column align="center" label="发票代码" min-width="120" prop="invoiceCode" show-overflow-tooltip></el-table-column>
<el-table-column align="center" fixed="right" label="操作" width="90">
<template slot-scope="{row}">
<el-button @click="openDetails(row)" size="mini">详情</el-button>
</template>
</el-table-column>
</el-table>
<el-pagination
:current-page="pageForm.pageNumber"
:page-size="pageForm.pageSize"
:total="pageForm.totalCount"
@current-change="pageChange"
layout="total, prev, pager, next"
style="margin-top: 16px; text-align: right"
></el-pagination>
<span slot="footer">
<el-button @click="close">关闭</el-button>
</span>
</el-dialog>
<order-detail-dialog :visible.sync="detailVisible" :order-id="detailOrderId"></order-detail-dialog>
</div>
`
})
new Vue({
el: "#app",
mixins: [initTableMixins],
@@ -162,22 +303,7 @@ layout("/layouts/platform.html"){
logisticsOrderId: null
},
subDialogVisible: false,
subLoading: false,
currentMainOrderId: null,
subOrderList: [],
subPageForm: {
pageNumber: 1,
pageSize: 10,
totalCount: 0
},
productDialogVisible: false,
productDialogTitle: "商品明细",
productLoading: false,
productList: [],
exchangeDialogVisible: false,
exchangeLoading: false,
currentSubOrderId: null,
exchangeList: [],
orderStateOptions: [
{ value: "0", label: "待付款" },
{ value: "1", label: "已支付" },
@@ -227,52 +353,7 @@ layout("/layouts/platform.html"){
},
openSubOrders(row) {
this.currentMainOrderId = row.orderId
this.subPageForm.pageNumber = 1
this.subDialogVisible = true
this.subPageData()
},
async subPageData() {
this.subLoading = true
const resp = await this.$axios.post(loc() + "/subPageData", {
pageNumber: this.subPageForm.pageNumber,
pageSize: this.subPageForm.pageSize,
mainOrderId: this.currentMainOrderId
})
this.subLoading = false
if (resp.code === 0) {
this.subOrderList = resp.data.list || []
this.subPageForm.totalCount = resp.data.totalCount || 0
} else {
this.notifyWarning(resp.msg)
}
},
subPageChange(val) {
this.subPageForm.pageNumber = val
this.subPageData()
},
async openProducts(row, exchange) {
this.productDialogTitle = (exchange ? "售后单商品明细 - " : "子订单商品明细 - ") + row.orderId
this.productDialogVisible = true
this.productLoading = true
const resp = await this.$axios.post(loc() + (exchange ? "/exchangeProductList" : "/productList"), { orderId: row.orderId })
this.productLoading = false
if (resp.code === 0) {
this.productList = resp.data || []
} else {
this.notifyWarning(resp.msg)
}
},
async openExchange(row) {
this.currentSubOrderId = row.orderId
this.exchangeDialogVisible = true
this.exchangeLoading = true
const resp = await this.$axios.post(loc() + "/exchangeList", { mainOrderId: row.orderId })
this.exchangeLoading = false
if (resp.code === 0) {
this.exchangeList = resp.data || []
} else {
this.notifyWarning(resp.msg)
}
},
orderStateName(value) {
const item = this.orderStateOptions.find((v) => String(v.value) === String(value))
@@ -88,7 +88,7 @@ const msg= {
未读
</van-tag>
</div>
<div class="message-time">{{formatTime(message.createdAt)}}</div>
<div class="message-time">{{formatTime(message.sendTime || message.createdAt)}}</div>
</div>
<div class="message-content">{{getContentPreview(message.content)}}</div>
<div class="message-arrow">
@@ -122,7 +122,7 @@ const msg= {
<van-tag :type="currentMessage?.globalMessage?.type === 1 ? 'danger' : 'primary'">
{{getMessageTypeName(currentMessage?.globalMessage?.type)}}
</van-tag>
<span class="detail-time">{{formatTime(currentMessage.createdAt)}}</span>
<span class="detail-time">{{formatTime((currentMessage.globalMessage && currentMessage.globalMessage.sendTime) || currentMessage.createdAt)}}</span>
</div>
</div>
<div class="detail-content" v-html="currentMessage?.globalMessage?.content"></div>
@@ -315,6 +315,7 @@ const msg= {
// 格式化时间
formatTime(timestamp) {
if (!timestamp) return ''
return this.$moment(timestamp).format('MM-DD HH:mm')
}
},
@@ -442,6 +443,7 @@ const msg= {
line-height: 1.8;
font-size: 15px;
color: #323233;
white-space: pre-line;
}
/deep/ .detail-content img {
@@ -455,6 +457,16 @@ const msg= {
margin: 12px 0;
}
/deep/ .detail-content ol {
list-style-type: decimal;
padding-left: 22px;
margin: 6px 0;
}
/deep/ .detail-content li {
display: list-item;
}
/* 标签页样式优化 */
/deep/ .van-tabs__nav {
background-color: #fff;