feat:审批
This commit is contained in:
1 parent
f5c3e0b0ea
commit
cd86ae5521
18 files changed
+2025
-1658
No files matched your search
@@ -1,284 +1,303 @@
|
||||
<template>
|
||||
<div class="layout-padding">
|
||||
<div v-loading="loading" class="layout-padding-auto layout-padding-view" style="overflow: scroll !important;">
|
||||
<el-descriptions :column="3" border title="订单信息">
|
||||
<el-descriptions-item :span="3" label="订单号: ">
|
||||
{{ globalData.detail.id }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="订单类型: ">
|
||||
<dict-tag :options="hard_order_type" :value="globalData.detail.orderType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="付款方式: ">
|
||||
<dict-tag :options="hard_pay_type" :value="globalData.detail.payType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="订单状态: ">
|
||||
<dict-tag :options="hard_order_status" :value="globalData.detail.orderStatus" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="商户: ">
|
||||
<span> {{ globalData.detail.merchantName }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备名: ">
|
||||
<span> {{ globalData.detail.hardName }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备类型: ">
|
||||
<span> {{ globalData.detail.hardType }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="商品总价: ">
|
||||
<span class="color-success">
|
||||
{{ displayPrice(globalData.detail.totalPrice) }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="额外支付: ">
|
||||
<span class="color-danger">
|
||||
{{ displayPrice(globalData.detail.extraPrice) }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="实际支付: ">
|
||||
<span class="color-primary">
|
||||
{{ displayPrice(globalData.detail.payPrice) }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" title="商品信息">
|
||||
<el-descriptions-item labelClassName="no-colon">
|
||||
<el-table :data="state.dataList" v-loading="state.loading" border :cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle" @sort-change="sortChangeHandle">
|
||||
<el-table-column label="商品名" align="center" prop="productName" />
|
||||
<el-table-column label="商品图片" align="center" prop="code">
|
||||
<template #default="{ row }">
|
||||
<preview-image v-if="row.productPic" :src="row.productPic" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" align="center" prop="ticketId">
|
||||
<template #default="{ row }">
|
||||
<span>{{ displayPrice(row.productPrice) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品数量" align="center" prop="productCount" />
|
||||
<el-table-column label="商品总额" align="center" prop="totalPrice">
|
||||
<template #default="{ row }">
|
||||
<span>{{ displayPrice(row.totalPrice) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<div class="layout-padding">
|
||||
<div v-loading="loading" class="layout-padding-auto layout-padding-view" style="overflow: scroll !important">
|
||||
<el-descriptions :column="3" border title="订单信息">
|
||||
<el-descriptions-item :span="3" label="订单号: ">
|
||||
{{ globalData.detail.id }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="订单类型: ">
|
||||
<dict-tag :options="hard_order_type" :value="globalData.detail.orderType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="付款方式: ">
|
||||
<dict-tag :options="hard_pay_type" :value="globalData.detail.payType" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="订单状态: ">
|
||||
<dict-tag :options="hard_order_status" :value="globalData.detail.orderStatus" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="商户: ">
|
||||
<span> {{ globalData.detail.merchantName }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备名: ">
|
||||
<span> {{ globalData.detail.hardName }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="设备类型: ">
|
||||
<span> {{ globalData.detail.hardType }}</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="商品总价: ">
|
||||
<span class="color-success">
|
||||
{{ displayPrice(globalData.detail.totalPrice) }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="额外支付: ">
|
||||
<span class="color-danger">
|
||||
{{ displayPrice(globalData.detail.extraPrice) }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="实际支付: ">
|
||||
<span class="color-primary">
|
||||
{{ displayPrice(globalData.detail.payPrice) }}
|
||||
</span>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions :column="1" title="商品信息">
|
||||
<el-descriptions-item labelClassName="no-colon">
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
border
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
@sort-change="sortChangeHandle"
|
||||
>
|
||||
<el-table-column label="商品名" align="center" prop="productName" />
|
||||
<el-table-column label="商品图片" align="center" prop="code">
|
||||
<template #default="{ row }">
|
||||
<preview-image v-if="row.productPic" :src="row.productPic" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" align="center" prop="ticketId">
|
||||
<template #default="{ row }">
|
||||
<span>{{ displayPrice(row.productPrice) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品数量" align="center" prop="productCount" />
|
||||
<el-table-column label="商品总额" align="center" prop="totalPrice">
|
||||
<template #default="{ row }">
|
||||
<span>{{ displayPrice(row.totalPrice) }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<!-- 退款状态 -->
|
||||
<el-descriptions v-if="globalData.afterSaleData.id" :column="2" border title="退款状态">
|
||||
<el-descriptions-item :column="1" label="退款状态: ">
|
||||
<dict-tag :options="hard_sale_status" :value="globalData.afterSaleData.status" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item :column="1"
|
||||
v-if="globalData.type == 'apply' && globalData.afterSaleData.status == 10" label="操作: "
|
||||
label-class-name="no-colon">
|
||||
<div class="flex justify-evenly">
|
||||
<el-button type="primary" @click="agree">
|
||||
同意售后
|
||||
</el-button>
|
||||
<el-button type="danger" @click="refundRejectRef.openDialog(globalData.detail.id)">
|
||||
拒绝售后
|
||||
</el-button>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<!-- 退款状态 -->
|
||||
<el-descriptions v-if="globalData.afterSaleData.id" :column="2" border title="退款状态">
|
||||
<el-descriptions-item :column="1" label="退款状态: ">
|
||||
<dict-tag :options="hard_sale_status" :value="globalData.afterSaleData.status" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item
|
||||
:column="1"
|
||||
v-if="globalData.type == 'apply' && globalData.afterSaleData.status == 10"
|
||||
label="操作: "
|
||||
label-class-name="no-colon"
|
||||
>
|
||||
<div class="flex justify-evenly">
|
||||
<el-button type="primary" @click="agree"> 同意售后 </el-button>
|
||||
<el-button type="danger" @click="refundRejectRef.openDialog(globalData.detail.id)"> 拒绝售后 </el-button>
|
||||
</div>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-descriptions v-if="globalData.afterSaleData.id" border title="售后信息">
|
||||
<el-descriptions-item :span="3" label="退款编号: ">
|
||||
{{ globalData.afterSaleData.no }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="售后类型: ">
|
||||
<dict-tag :options="hard_after_sale_type" :value="globalData.afterSaleData.type" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="售后方式: ">
|
||||
<dict-tag :options="hard_after_sale_way" :value="globalData.afterSaleData.way" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="退款金额: ">
|
||||
{{ displayPrice(globalData.afterSaleData.refundPrice) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="退款原因: ">
|
||||
{{ globalData.afterSaleData.applyReason }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="补充描述: ">
|
||||
{{ globalData.afterSaleData.applyDescription }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions v-if="globalData.afterSaleData.id" border title="售后信息">
|
||||
<el-descriptions-item :span="3" label="退款编号: ">
|
||||
{{ globalData.afterSaleData.no }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="售后类型: ">
|
||||
<dict-tag :options="hard_after_sale_type" :value="globalData.afterSaleData.type" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="售后方式: ">
|
||||
<dict-tag :options="hard_after_sale_way" :value="globalData.afterSaleData.way" />
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="退款金额: ">
|
||||
{{ displayPrice(globalData.afterSaleData.refundPrice) }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="退款原因: ">
|
||||
{{ globalData.afterSaleData.applyReason }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="补充描述: ">
|
||||
{{ globalData.afterSaleData.applyDescription }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-descriptions v-if="globalData.log && globalData.log.length" title="售后日志">
|
||||
<el-descriptions-item labelClassName="no-colon">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="v in globalData.log" :key="v.id" :timestamp="v.createTime"
|
||||
placement="top">
|
||||
<div class="el-timeline-right-content">
|
||||
<span>{{ v.content }}</span>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
<el-descriptions v-if="globalData.log && globalData.log.length" title="售后日志">
|
||||
<el-descriptions-item labelClassName="no-colon">
|
||||
<el-timeline>
|
||||
<el-timeline-item v-for="v in globalData.log" :key="v.id" :timestamp="v.createTime" placement="top">
|
||||
<div class="el-timeline-right-content">
|
||||
<span>{{ v.content }}</span>
|
||||
</div>
|
||||
</el-timeline-item>
|
||||
</el-timeline>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</div>
|
||||
|
||||
<refund-reject-form ref="refundRejectRef" @refresh="getDetail" />
|
||||
</div>
|
||||
<refund-reject-form ref="refundRejectRef" @refresh="getDetail" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="order-refund">
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { useDict } from '/@/hooks/dict';
|
||||
import * as hardOrder from "/@/api/hard/hard-order";
|
||||
import * as hardCar from "/@/api/hard/hard-car";
|
||||
import * as hardAfterSaleApi from '/@/api/hard/hard-after-sale'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table"
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message"
|
||||
import { useDict } from "/@/hooks/dict"
|
||||
import * as hardOrder from "/@/api/hard/hard-order"
|
||||
import * as hardCar from "/@/api/hard/hard-car"
|
||||
import * as hardAfterSaleApi from "/@/api/hard/hard-after-sale"
|
||||
import { displayPrice } from "/@/utils/formatMoney"
|
||||
import { ElLoading } from 'element-plus'
|
||||
import { ElLoading } from "element-plus"
|
||||
|
||||
// 引入组件
|
||||
const RefundRejectForm = defineAsyncComponent(() => import('./refund-reject.vue'));
|
||||
const RefundRejectForm = defineAsyncComponent(() => import("./refund-reject.vue"))
|
||||
|
||||
// 定义查询字典
|
||||
const { hard_pay_type, hard_order_type, hard_order_status, hard_after_sale_way, hard_after_sale_type, hard_sale_status } = useDict("hard_pay_type", "hard_order_type", "hard_order_status", "hard_after_sale_way", "hard_after_sale_type", "hard_sale_status")
|
||||
const {
|
||||
hard_pay_type,
|
||||
hard_order_type,
|
||||
hard_order_status,
|
||||
hard_after_sale_way,
|
||||
hard_after_sale_type,
|
||||
hard_sale_status,
|
||||
} = useDict(
|
||||
"hard_pay_type",
|
||||
"hard_order_type",
|
||||
"hard_order_status",
|
||||
"hard_after_sale_way",
|
||||
"hard_after_sale_type",
|
||||
"hard_sale_status",
|
||||
)
|
||||
|
||||
const { query } = useRoute()
|
||||
const refundRejectRef = ref()
|
||||
const loading = ref(false)
|
||||
const globalData = reactive<any>({
|
||||
type: "",
|
||||
detail: {},
|
||||
afterSaleData: {},
|
||||
log: []
|
||||
type: "",
|
||||
detail: {},
|
||||
afterSaleData: {},
|
||||
log: [],
|
||||
})
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
createdIsNeed: false,
|
||||
queryForm: {},
|
||||
pagination: {
|
||||
size: 100,
|
||||
},
|
||||
pageList: hardCar.getCarByOrderId
|
||||
createdIsNeed: false,
|
||||
queryForm: {},
|
||||
pagination: {
|
||||
size: 100,
|
||||
},
|
||||
pageList: hardCar.getCarByOrderId,
|
||||
})
|
||||
|
||||
// table hook
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, sortChangeHandle, downBlobFile, tableStyle } =
|
||||
useTable(state)
|
||||
|
||||
onMounted(async () => {
|
||||
const type = query.type as unknown as any
|
||||
if (type) {
|
||||
globalData.type = type
|
||||
}
|
||||
await getDetail()
|
||||
const type = query.type as unknown as any
|
||||
if (type) {
|
||||
globalData.type = type
|
||||
}
|
||||
await getDetail()
|
||||
})
|
||||
|
||||
const agree = async () => {
|
||||
let loading: any = null
|
||||
try {
|
||||
await useMessage().delConfirm("是否同意售后?")
|
||||
loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: '提交中',
|
||||
background: 'rgba(0, 0, 0, 0.7)',
|
||||
})
|
||||
await hardAfterSaleApi.agree({ id: globalData.afterSaleData.id })
|
||||
await getDetail()
|
||||
} finally {
|
||||
setTimeout(() => loading.close(), 1000)
|
||||
}
|
||||
let loading: any = null
|
||||
try {
|
||||
await useMessage().delConfirm("是否同意售后?")
|
||||
loading = ElLoading.service({
|
||||
lock: true,
|
||||
text: "提交中",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
})
|
||||
await hardAfterSaleApi.agree({ id: globalData.afterSaleData.id })
|
||||
await getDetail()
|
||||
} finally {
|
||||
setTimeout(() => loading.close(), 1000)
|
||||
}
|
||||
}
|
||||
|
||||
const getDetail = async () => {
|
||||
const id = query.id as unknown as any
|
||||
if (!id) return
|
||||
state.queryForm.orderId = id
|
||||
const { data: orderData } = await hardOrder.getObj(id)
|
||||
globalData.detail = orderData
|
||||
getDataList()
|
||||
const { data: afterSaleData } = await hardAfterSaleApi.detailByOrderId({ orderId: id })
|
||||
if (afterSaleData && afterSaleData.id) {
|
||||
globalData.afterSaleData = afterSaleData
|
||||
const { data: log } = await hardAfterSaleApi.history({ id: afterSaleData.id })
|
||||
globalData.log = log
|
||||
}
|
||||
const id = query.id as unknown as any
|
||||
if (!id) return
|
||||
state.queryForm.orderId = id
|
||||
const { data: orderData } = await hardOrder.getObj(id)
|
||||
globalData.detail = orderData
|
||||
getDataList()
|
||||
const { data: afterSaleData } = await hardAfterSaleApi.detailByOrderId({ orderId: id })
|
||||
if (afterSaleData && afterSaleData.id) {
|
||||
globalData.afterSaleData = afterSaleData
|
||||
const { data: log } = await hardAfterSaleApi.history({ id: afterSaleData.id })
|
||||
globalData.log = log
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:deep(.el-descriptions) {
|
||||
&:not(:nth-child(1)) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
&:not(:nth-child(1)) {
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.el-descriptions__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.el-descriptions__title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
&::before {
|
||||
display: inline-block;
|
||||
width: 3px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
background-color: #409eff;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
&::before {
|
||||
display: inline-block;
|
||||
width: 3px;
|
||||
height: 20px;
|
||||
margin-right: 10px;
|
||||
background-color: #409eff;
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
||||
.el-descriptions-item__container {
|
||||
margin: 0 10px;
|
||||
.el-descriptions-item__container {
|
||||
margin: 0 10px;
|
||||
|
||||
.no-colon {
|
||||
margin: 0;
|
||||
.no-colon {
|
||||
margin: 0;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
}
|
||||
&::after {
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 时间线样式调整
|
||||
:deep(.el-timeline) {
|
||||
margin: 10px 0 0 160px;
|
||||
margin: 10px 0 0 160px;
|
||||
|
||||
.el-timeline-item__wrapper {
|
||||
position: relative;
|
||||
top: -20px;
|
||||
.el-timeline-item__wrapper {
|
||||
position: relative;
|
||||
top: -20px;
|
||||
|
||||
.el-timeline-item__timestamp {
|
||||
position: absolute !important;
|
||||
top: 10px;
|
||||
left: -150px;
|
||||
}
|
||||
}
|
||||
.el-timeline-item__timestamp {
|
||||
position: absolute !important;
|
||||
top: 10px;
|
||||
left: -150px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-timeline-right-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 30px;
|
||||
padding: 10px;
|
||||
background-color: #409eff;
|
||||
.el-timeline-right-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
min-height: 30px;
|
||||
padding: 10px;
|
||||
background-color: #409eff;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 13px;
|
||||
border-color: transparent #409eff transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 8px;
|
||||
content: '';
|
||||
}
|
||||
}
|
||||
&::before {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
left: 13px;
|
||||
border-color: transparent #409eff transparent transparent;
|
||||
border-style: solid;
|
||||
border-width: 8px;
|
||||
content: "";
|
||||
}
|
||||
}
|
||||
|
||||
.el-timeline-item__node {
|
||||
position: absolute;
|
||||
left: -5px;
|
||||
top: -50%;
|
||||
transform: translateY(100%);
|
||||
display: flex;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 10px;
|
||||
background: #409eff;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.el-timeline-item__node {
|
||||
position: absolute;
|
||||
left: -5px;
|
||||
top: -50%;
|
||||
transform: translateY(100%);
|
||||
display: flex;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
font-size: 10px;
|
||||
background: #409eff;
|
||||
border-radius: 50%;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -167,7 +167,7 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200">
|
||||
<el-table-column fixed="right" label="操作" width="200">
|
||||
<template #default="{ row }">
|
||||
<el-button icon="ShoppingCartFull" text type="primary" @click="shopCarDialogRef.openDialog(row.id)"
|
||||
>购物车</el-button
|
||||
|
||||
Reference in new issue
Block a user