feat:购物车商品级退款
This commit is contained in:
1 parent
8648d8d8a3
commit
ca11691c03
7 files changed
+182
-62
No files matched your search
@@ -8,6 +8,14 @@ export function adminRefund(data?: Object) {
|
||||
})
|
||||
}
|
||||
|
||||
export function adminReinforceRefund(data?: Object) {
|
||||
return request({
|
||||
url: "/hard/hard-after-sale/admin-reinforce-refund",
|
||||
method: "post",
|
||||
data,
|
||||
})
|
||||
}
|
||||
|
||||
export function history(query?: Object) {
|
||||
return request({
|
||||
url: "/hard/hard-after-sale/history",
|
||||
|
||||
+42
-35
@@ -1,57 +1,64 @@
|
||||
import request from "/@/utils/request"
|
||||
|
||||
export function getCarByOrderId(query?: Object) {
|
||||
return request({
|
||||
url: '/hard/hard-car/order-id',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car/order-id",
|
||||
method: "get",
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
export function refundCar(query?: Object) {
|
||||
return request({
|
||||
url: "/hard/hard-car/refund-car",
|
||||
method: "get",
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
export function pageJoin(query?: Object) {
|
||||
return request({
|
||||
url: '/hard/hard-car/page-join',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car/page-join",
|
||||
method: "get",
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchList(query?: Object) {
|
||||
return request({
|
||||
url: '/hard/hard-car/page',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car/page",
|
||||
method: "get",
|
||||
params: query,
|
||||
})
|
||||
}
|
||||
|
||||
export function addObj(obj?: Object) {
|
||||
return request({
|
||||
url: '/hard/hard-car',
|
||||
method: 'post',
|
||||
data: obj
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car",
|
||||
method: "post",
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
export function getObj(id?: string) {
|
||||
return request({
|
||||
url: '/hard/hard-car/' + id,
|
||||
method: 'get'
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car/" + id,
|
||||
method: "get",
|
||||
})
|
||||
}
|
||||
|
||||
export function delObjs(ids?: Object) {
|
||||
return request({
|
||||
url: '/hard/hard-car',
|
||||
method: 'delete',
|
||||
data: ids
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car",
|
||||
method: "delete",
|
||||
data: ids,
|
||||
})
|
||||
}
|
||||
|
||||
export function putObj(obj?: Object) {
|
||||
return request({
|
||||
url: '/hard/hard-car',
|
||||
method: 'put',
|
||||
data: obj
|
||||
})
|
||||
return request({
|
||||
url: "/hard/hard-car",
|
||||
method: "put",
|
||||
data: obj,
|
||||
})
|
||||
}
|
||||
|
||||
+2
-2
@@ -203,13 +203,13 @@ export function useTable(options?: BasicTableProps) {
|
||||
* 刷新后不跳转第一页,则入参 getDataList(false)
|
||||
* @param refresh 是否刷新当前页码
|
||||
*/
|
||||
const getDataList = (refresh?: any) => {
|
||||
const getDataList = async (refresh?: any) => {
|
||||
// 如果需要刷新,则将state.pagination.current重置为1
|
||||
if (refresh !== false) {
|
||||
state.pagination!.current = 1
|
||||
}
|
||||
// 再次发起查询操作
|
||||
query()
|
||||
await query()
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RefundForm">
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import * as walletSettingApi from "/@/api/wallet/wallet-setting"
|
||||
|
||||
// 定义变量内容
|
||||
@@ -80,7 +81,12 @@ const getSetting = async () => {
|
||||
// 提交
|
||||
const validate = async () => {
|
||||
const valid = await dataFormRef.value.validate().catch(() => { })
|
||||
if (!valid) return false
|
||||
if (!valid) {
|
||||
if (!form.applyReason) {
|
||||
useMessage().error("请选择退款原因")
|
||||
}
|
||||
return false
|
||||
}
|
||||
return form
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
<el-tab-pane v-for="(v) in data.tabs" :key="v.name" :label="v.label" :name="v.name" />
|
||||
</el-tabs>
|
||||
<div class="container" v-loading="loading">
|
||||
<refund-form ref="refundFormRef" v-if="state.currentTab === 'INFO'" />
|
||||
<refund-table ref="refundTableRef" v-if="state.currentTab === 'CAR'" />
|
||||
<refund-form ref="refundFormRef" v-show="state.currentTab === 'INFO'" />
|
||||
<refund-table ref="refundTableRef" v-show="state.currentTab === 'CAR'" />
|
||||
</div>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
@@ -80,11 +80,20 @@ function tabClick(e: any) {
|
||||
|
||||
// 提交
|
||||
const onSubmit = async () => {
|
||||
|
||||
// 校验
|
||||
const formValidate = await refundFormRef.value?.validate()
|
||||
if (formValidate === false) return
|
||||
// 判断有没有选择退款商品
|
||||
const tableValidate = await refundTableRef.value?.validate()
|
||||
if (tableValidate === false) return
|
||||
try {
|
||||
loading.value = true
|
||||
const _data = {}
|
||||
await hardAfterSaleApi.adminRefund(_data)
|
||||
const _data = {
|
||||
...formValidate,
|
||||
orderId: state.orderId,
|
||||
carList: tableValidate
|
||||
}
|
||||
await hardAfterSaleApi.adminReinforceRefund(_data)
|
||||
useMessage().success("退款成功")
|
||||
visible.value = false
|
||||
emit("refresh")
|
||||
|
||||
@@ -27,7 +27,37 @@
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
|
||||
<el-descriptions :column="1" title="已退款商品">
|
||||
<el-descriptions-item labelClassName="no-colon">
|
||||
<el-table :data="refundSuccessList" border :cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle" @sort-change="sortChangeHandle" show-summary
|
||||
:summary-method="getSummaries">
|
||||
<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" />
|
||||
<div v-else class="w-[50px] h-[50px]" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="商品价格" align="center" prop="productPrice">
|
||||
<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 :column="1" title="退款商品">
|
||||
<template #extra>
|
||||
<el-button type="primary" text @click="handleAllRefund">全部退款</el-button>
|
||||
</template>
|
||||
<el-descriptions-item labelClassName="no-colon">
|
||||
<el-table :data="disposeDataList" border :cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle" @sort-change="sortChangeHandle" show-summary
|
||||
@@ -47,11 +77,16 @@
|
||||
<el-table-column label="退款商品数量" align="center" prop="refundProductCount">
|
||||
<template #default="{ row }">
|
||||
<div>
|
||||
<el-input-number v-if="row.productNature == 2" v-model="row.refundProductCount" :min="0"
|
||||
:max="row.productCount" :step="0.1"
|
||||
@change="handleRefundProductCount($event, row)" />
|
||||
<el-input-number v-else v-model="row.refundProductCount" :min="0"
|
||||
:max="row.productCount" @change="handleRefundProductCount($event, row)" />
|
||||
<div v-if="row.refundProductCount == row.productCount" class="color-danger text-sm">
|
||||
该商品已全部退款
|
||||
</div>
|
||||
<div v-else>
|
||||
<el-input-number size="small" v-if="row.productNature == 2"
|
||||
v-model="row.refundProductCount" :min="0" :max="row.productCount" :step="0.1"
|
||||
@change="handleRefundProductCount($event, row)" />
|
||||
<el-input-number size="small" v-else v-model="row.refundProductCount" :min="0"
|
||||
:max="row.productCount" @change="handleRefundProductCount($event, row)" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
@@ -67,6 +102,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="RefundTable">
|
||||
import { useMessage } from "/@/hooks/message"
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table"
|
||||
|
||||
import { displayPrice } from "/@/utils/formatMoney"
|
||||
@@ -79,11 +115,36 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: hardCar.getCarByOrderId,
|
||||
})
|
||||
|
||||
const disposeDataList = computed(() => {
|
||||
const refundSuccessList = ref<any>([])
|
||||
const disposeDataList = ref<any>([])
|
||||
|
||||
|
||||
// table hook
|
||||
const { getDataList, sortChangeHandle, tableStyle } = useTable(state)
|
||||
|
||||
const getCarList = async (orderId: string) => {
|
||||
state.queryForm.orderId = orderId
|
||||
// 获取订单商品列表
|
||||
await getDataList()
|
||||
if (!state.dataList || !state.dataList.length) {
|
||||
return []
|
||||
return
|
||||
}
|
||||
return state.dataList.map((item) => {
|
||||
// 获取已退款的商品
|
||||
const { data } = await hardCar.refundCar({ orderId })
|
||||
if (!data || !data.length) {
|
||||
return
|
||||
}
|
||||
refundSuccessList.value = data
|
||||
// 计算出需要退款的商品
|
||||
const refundViewList = [...state.dataList]
|
||||
for (const item of refundViewList) {
|
||||
const target = data.find((v: any) => v.productId == item.productId)
|
||||
if (!target) continue
|
||||
// 购物车商品 - 已退款商品
|
||||
item.productCount = item.productCount - target.productCount
|
||||
item.totalPrice = item.totalPrice - target.totalPrice
|
||||
}
|
||||
disposeDataList.value = refundViewList.map((item) => {
|
||||
if (!item) return null
|
||||
return {
|
||||
...item,
|
||||
@@ -91,14 +152,6 @@ const disposeDataList = computed(() => {
|
||||
refundTotalPrice: 0,
|
||||
}
|
||||
}).filter(Boolean)
|
||||
})
|
||||
|
||||
// table hook
|
||||
const { getDataList, sortChangeHandle, tableStyle } = useTable(state)
|
||||
|
||||
const getCarList = (orderId: string) => {
|
||||
state.queryForm.orderId = orderId
|
||||
getDataList()
|
||||
}
|
||||
|
||||
const handleRefundProductCount = (value: any, row: any) => {
|
||||
@@ -108,6 +161,20 @@ const handleRefundProductCount = (value: any, row: any) => {
|
||||
target.refundTotalPrice = productPrice * value
|
||||
}
|
||||
|
||||
// 全部退款
|
||||
const handleAllRefund = () => {
|
||||
if (!state.dataList || !state.dataList.length) return
|
||||
const _list = [...disposeDataList.value]
|
||||
for (const v of _list) {
|
||||
const target = state.dataList.find((item: any) => item.id == v.id)
|
||||
if (!target) continue
|
||||
v.refundProductCount = target.productCount
|
||||
v.refundTotalPrice = target.totalPrice
|
||||
|
||||
}
|
||||
disposeDataList.value = _list
|
||||
}
|
||||
|
||||
const getSummaries = (param: any) => {
|
||||
const { columns, data } = param
|
||||
const totalColumns = ["productCount", "totalPrice", "totalPrice", "refundProductCount", "refundTotalPrice"]
|
||||
@@ -129,9 +196,33 @@ const getSummaries = (param: any) => {
|
||||
return totalRow
|
||||
}
|
||||
|
||||
// 提交
|
||||
const validate = async () => {
|
||||
let valid = true
|
||||
for (const v of disposeDataList.value) {
|
||||
if (v.refundProductCount <= 0) {
|
||||
valid = false
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!valid) {
|
||||
useMessage().error("退款商品列表不能为空")
|
||||
return false
|
||||
}
|
||||
// 处理一下
|
||||
return disposeDataList.value.map((item: any) => {
|
||||
return {
|
||||
...item,
|
||||
productCount: item.refundProductCount,
|
||||
totalPrice: item.refundTotalPrice,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// 暴露变量
|
||||
defineExpose({
|
||||
getCarList,
|
||||
validate,
|
||||
})
|
||||
</script>
|
||||
|
||||
|
||||
@@ -224,8 +224,7 @@
|
||||
v-auth="'hard_hardwareOrder_edit'" @click="formDialogRef.openDialog(row.id)">
|
||||
编辑
|
||||
</el-button>
|
||||
<el-button
|
||||
v-if="!row.payRefundId && row.orderType !== '5' && !['5', '6', '8'].includes(row.payType)"
|
||||
<el-button v-if="row.orderType !== '5' && !['5', '6', '8'].includes(row.payType)"
|
||||
icon="stamp" text type="primary" v-auth="'hard_hardAfterSale_adminRefund'"
|
||||
@click="adminRefundDailogRef.openDialog(row.id)">
|
||||
退款
|
||||
@@ -402,7 +401,7 @@ const getSummaries = (param: SummaryMethodProps) => {
|
||||
{ column: "totalPrice", columnName: "商品总价", color: "#67C260" },
|
||||
{ column: "extraPrice", columnName: "额外支付", color: "#F56E9B" },
|
||||
{ column: "payPrice", columnName: "实际支付", color: "#355CF6" },
|
||||
].forEach(({ column, columnName, color }: any) => {
|
||||
].forEach(({ column, columnName, color }: any, index: number) => {
|
||||
const values = data.map((item) => Number(item[column]))
|
||||
if (!values.every((value) => Number.isNaN(value))) {
|
||||
priceVNode.push(
|
||||
|
||||
Reference in new issue
Block a user