perf 订单相关管理页面优化

This commit is contained in:
DaxPay
2024-08-16 18:05:01 +08:00
parent b90d4a4c72
commit 790d6dddd6
7 changed files with 325 additions and 57 deletions

View File

@@ -0,0 +1,102 @@
/**
* 支付状态
*/
export enum PayStatusEnum{
/**
* 支付中
*/
PROGRESS = 'progress',
/**
* 成功
*/
SUCCESS = 'success',
/**
* 支付关闭
*/
CLOSE = 'close',
/**
* 支付撤销
*/
CANCEL = 'cancel',
/**
* 失败
*/
FAIL = 'fail',
/**
* 支付超时
*/
TIMEOUT = 'timeout',
}
/**
* 支付订单的退款状态
*/
export enum PayRefundStatusEnum{
/**
* 未退款
*/
NO_REFUND = 'no_refund',
/**
* 退款中
*/
REFUNDING = 'refunding',
/**
* 部分退款
*/
PARTIAL_REFUND = 'partial_refund',
/**
* 全部退款
*/
REFUNDED = 'refunded',
}
/**
* 支付订单的分账状态
*/
export enum PayAllocStatusEnum{
/**
* 待分账
*/
WAITING = 'waiting',
/**
* 已分账
*/
ALLOCATION = 'allocation',
}
/**
* 退款状态枚举
*/
export enum RefundStatusEnum{
/**
* 退款中
*/
PROGRESS = 'progress',
/**
* 成功
*/
SUCCESS = 'success',
/**
* 关闭
*/
CLOSE = 'close',
/**
* 失败
*/
FAIL = 'fail',
}
/**
* 转账状态
*/
export enum TransferStatusEnum{
/** 转账中 */
PROGRESS = 'progress',
/** 转账成功 */
SUCCESS = 'success',
/** 转账关闭 */
FAIL = 'fail',
/** 转账失败 */
CLOSE = 'close',
}

View File

@@ -1,6 +1,11 @@
import { defHttp } from '@/utils/http/axios'
import { PageResult, Result } from '#/axios'
import { MchEntity } from '#/web'
import {
PayAllocStatusEnum,
PayRefundStatusEnum,
PayStatusEnum,
} from '@/enums/daxpay/TradeStatusEnum'
/**
* 分页
@@ -72,6 +77,55 @@ export function getTotalAmount(param) {
})
}
/**
* 显示样式优化
*/
export function cellStyle({ row, column }) {
// 支付状态
if (column.field == 'status') {
switch (row.status) {
case PayStatusEnum.SUCCESS:
return { color: 'green' }
case PayStatusEnum.FAIL:
return { color: 'red' }
case PayStatusEnum.PROGRESS:
return { color: 'orange' }
case PayStatusEnum.CLOSE:
return { color: 'gray' }
case PayStatusEnum.CANCEL:
return { color: 'gray' }
default:
return { color: 'red' }
}
}
// 分账状态
if (column.field == 'allocStatus') {
switch (row.allocStatus) {
case PayAllocStatusEnum.WAITING:
return { color: 'orange' }
case PayAllocStatusEnum.ALLOCATION:
return { color: 'green' }
default:
return { color: 'red' }
}
}
// 退款状态
if (column.field == 'refundStatus') {
switch (row.refundStatus) {
case PayRefundStatusEnum.NO_REFUND:
return { color: 'gray' }
case PayRefundStatusEnum.REFUNDED:
return { color: 'green' }
case PayRefundStatusEnum.REFUNDING:
return { color: 'orange' }
case PayRefundStatusEnum.PARTIAL_REFUND:
return { color: 'gray' }
default:
return { color: 'red' }
}
}
}
/**
* 支付记录
*/

View File

@@ -20,22 +20,22 @@
{{ order.refundableBalance }}
</a-descriptions-item>
<a-descriptions-item label="支付状态" :span="8">
{{ dictConvert('PayStatus', order.status) }}
{{ dictConvert('pay_status', order.status) }}
</a-descriptions-item>
<a-descriptions-item label="订单号" :span="16">
{{ order.orderNo }}
</a-descriptions-item>
<a-descriptions-item label="分账状态" :span="8">
{{ dictConvert('PayOrderAllocStatus', order.allocStatus) || '无' }}
{{ dictConvert('pay_alloc_status', order.allocStatus) || '无' }}
</a-descriptions-item>
<a-descriptions-item label="通道交易号" :span="16">
{{ order.outOrderNo || '无' }}
</a-descriptions-item>
<a-descriptions-item label="退款状态" :span="8">
{{ dictConvert('PayOrderRefundStatus', order.refundStatus) || '无' }}
{{ dictConvert('pay_refund_status', order.refundStatus) || '无' }}
</a-descriptions-item>
<a-descriptions-item label="商户订单号" :span="16">
{{ dictConvert('PayOrderRefundStatus', order.refundStatus) || '无' }}
{{ order.bizOrderNo || '无' }}
</a-descriptions-item>
<a-descriptions-item label="自动分账" :span="8">
{{ order.autoAllocation || '无' }}

View File

@@ -55,9 +55,9 @@
dictConvert('pay_status', row.status) || '无'
}}</template>
</vxe-column>
<vxe-column field="refundStatus" title="退款态" :min-width="120">
<vxe-column field="refundStatus" title="退款态" :min-width="120">
<template #default="{ row }">{{
dictConvert('pay_order_refund_status', row.refundStatus) || ''
dictConvert('pay_refund_status', row.refundStatus) || ''
}}</template>
</vxe-column>
<vxe-column field="allocation" title="分账" :min-width="160">
@@ -68,7 +68,7 @@
</vxe-column>
<vxe-column field="allocStatus" title="分账状态" :min-width="160">
<template #default="{ row }">
{{ dictConvert('PayOrderAllocStatus', row.allocStatus) || '无' }}
{{ dictConvert('pay_alloc_status', row.allocStatus) || '无' }}
</template>
</vxe-column>
<vxe-column field="createTime" title="创建时间" sortable :min-width="230" />
@@ -83,22 +83,27 @@
</a>
<template #overlay>
<a-menu>
<!-- <a-menu-item>-->
<!-- <a-link @click="sync(row)">同步</a-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item v-if="[payStatus.PROGRESS].includes(row.status)">-->
<!-- <a-link @click="closeOrder(row)" danger>关闭</a-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item-->
<!-- v-if="row.allocStatus === 'waiting' && payStatus.SUCCESS === row.status"-->
<!-- >-->
<!-- <a-link @click="allocation(row)">分账</a-link>-->
<!-- </a-menu-item>-->
<!-- <a-menu-item-->
<!-- v-if="[payStatus.SUCCESS].includes(row.status) && row.refundableBalance > 0"-->
<!-- >-->
<!-- <a-link @click="refund(row)" danger>退款</a-link>-->
<!-- </a-menu-item>-->
<a-menu-item>
<a-link @click="sync(row)">同步</a-link>
</a-menu-item>
<a-menu-item v-if="[PayStatusEnum.PROGRESS].includes(row.status)">
<a-link @click="closeOrder(row)" danger>关闭</a-link>
</a-menu-item>
<a-menu-item
v-if="
row.allocStatus === PayAllocStatusEnum.WAITING &&
PayStatusEnum.SUCCESS === row.status
"
>
<a-link @click="allocation(row)">分账</a-link>
</a-menu-item>
<a-menu-item
v-if="
[PayStatusEnum.SUCCESS].includes(row.status) && row.refundableBalance > 0
"
>
<a-link @click="refund(row)" danger>退款</a-link>
</a-menu-item>
</a-menu>
</template>
</a-dropdown>
@@ -115,16 +120,25 @@
@page-change="handleTableChange"
/>
<PayOrderInfo ref="payOrderInfo" />
<RefundModel ref="refundModel" @ok="queryPage" />
</div>
</div>
</template>
<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'
import { allocationByOrderNo, close, getTotalAmount, page, syncByOrderNo } from './PayOrder.api'
import {
allocationByOrderNo,
close,
getTotalAmount,
page,
syncByOrderNo,
cellStyle,
} from './PayOrder.api'
import useTablePage from '@/hooks/bootx/useTablePage'
import PayOrderInfo from './PayOrderInfo.vue'
import BQuery from '@/components/Bootx/Query/BQuery.vue'
import RefundModel from './RefundModel.vue'
import { useMessage } from '@/hooks/web/useMessage'
import { LIST, QueryField, STRING } from '@/components/Bootx/Query/Query'
import { useDict } from '@/hooks/bootx/useDict'
@@ -132,8 +146,8 @@
import ALink from '@/components/Link/Link.vue'
import { LabeledValue } from 'ant-design-vue/lib/select'
import { Icon } from '@/components/Icon'
import { PayAllocStatusEnum, PayStatusEnum } from '@/enums/daxpay/TradeStatusEnum'
const payStatus = ref('')
// 使用hooks
const {
handleTableChange,
@@ -178,7 +192,6 @@
},
{ field: 'channel', name: '支付通道', type: LIST, selectList: channelList.value },
{ field: 'method', name: '支付方式', type: LIST, selectList: methodList.value },
{ field: 'errorCode', name: '错误码', type: STRING },
{ field: 'status', name: '支付状态', type: LIST, selectList: payStatusList.value },
{
field: 'refundStatus',
@@ -209,11 +222,11 @@
* 初始化数据
*/
async function initData() {
channelList.value = await dictDropDown('PayChannel')
methodList.value = await dictDropDown('PayMethod')
payStatusList.value = await dictDropDown('PayStatus')
payRefundStatusList.value = await dictDropDown('PayOrderRefundStatus')
payAllocStatusList.value = await dictDropDown('PayOrderAllocStatus')
channelList.value = await dictDropDown('channel')
methodList.value = await dictDropDown('pay_method')
payStatusList.value = await dictDropDown('pay_status')
payRefundStatusList.value = await dictDropDown('pay_refund_status')
payAllocStatusList.value = await dictDropDown('pay_alloc_status')
}
/**
* 分页查询
@@ -300,27 +313,6 @@
},
})
}
/**
* 显示样式优化
*/
function cellStyle({ row, column }) {
if (column.field == 'status') {
if (row.status == 'success') {
return { color: 'green' }
}
if (row.status == 'fail') {
return { color: 'red' }
}
if (row.status == 'progress') {
return { color: 'orange' }
}
if (row.status == 'close') {
return { color: 'gray' }
}
return { color: 'red' }
}
}
</script>
<style lang="less" scoped></style>

View File

@@ -0,0 +1,120 @@
<template>
<basic-modal
title="退款申请"
v-bind="$attrs"
:loading="confirmLoading"
:width="modalWidth"
:open="visible"
:mask-closable="showable"
@cancel="handleCancel"
>
<a-form
ref="formRef"
:model="form"
:label-col="labelCol"
:rules="{ amount: [{ required: true, message: '请输入退款金额' }] }"
:wrapper-col="wrapperCol"
>
<a-form-item label="标题">
{{ order.title }}
</a-form-item>
<a-form-item label="订单号">
<a-tag>{{ order.orderNo }}</a-tag>
</a-form-item>
<a-form-item label="商户订单号">
<a-tag>{{ order.bizOrderNo }}</a-tag>
</a-form-item>
<a-form-item label="退款金额" name="amount">
<a-input-number
:min="0.01"
:max="order.refundableBalance"
:precision="2"
v-model:value="form.amount"
/>
</a-form-item>
<a-form-item label="原因" name="reason">
<a-textarea v-model:value="form.reason" :rows="3" />
</a-form-item>
</a-form>
<template #footer>
<a-space>
<a-button key="cancel" @click="handleCancel">取消</a-button>
<a-button key="forward" :loading="confirmLoading" type="primary" @click="handleOk"
>确定</a-button
>
</a-space>
</template>
</basic-modal>
</template>
<script lang="ts" setup>
import useFormEdit from '@/hooks/bootx/useFormEdit'
import { refund } from '../refund/RefundOrder.api'
import BasicModal from '@/components/Modal/src/BasicModal.vue'
import { FormInstance } from 'ant-design-vue/lib/form'
import { useMessage } from '@/hooks/web/useMessage'
import { nextTick, ref } from 'vue'
import { getOrder, PayOrder } from './PayOrder.api'
const { handleCancel, labelCol, wrapperCol, modalWidth, confirmLoading, visible, showable } =
useFormEdit()
const { createMessage, createConfirm } = useMessage()
let order = ref<PayOrder>({})
const formRef = ref<FormInstance>()
let form = ref({
// 订单号
orderNo: '',
// 原因
reason: '',
// 退款金额
amount: 0.01,
})
const emits = defineEmits(['ok'])
/**
* 入口
*/
async function init(id) {
resetForm()
confirmLoading.value = true
visible.value = true
getOrder(id).then(({ data }) => {
order.value = data
form.value.orderNo = data.orderNo as string
form.value.amount = data.refundableBalance as number
confirmLoading.value = false
})
}
/**
* 退款
*/
function handleOk() {
createConfirm({
iconType: 'warning',
title: '警告',
content: '确实要申请退款!',
onOk: () => {
confirmLoading.value = true
refund(form.value).then(() => {
visible.value = false
createMessage.success('退款请求已提交')
emits('ok')
})
},
})
}
/**
* 重置表单
*/
function resetForm() {
nextTick(() => {
formRef.value?.resetFields()
})
}
defineExpose({ init })
</script>
<style scoped></style>

View File

@@ -37,7 +37,7 @@ export function getByRefundNo(refundNo) {
*/
export function refund(params) {
return defHttp.post<Result<void>>({
url: '/order/refund/refund',
url: '/order/refund/create',
data: params,
})
}

View File

@@ -15,7 +15,7 @@
<vxe-toolbar ref="xToolbar" custom :refresh="{ queryMethod: queryPage }">
<template #buttons>
<span style="font-size: 18px"
>退款金额: {{ totalAmount ? totalAmoun : 0 }}</span
>退款金额: {{ totalAmount ? totalAmount : 0 }}</span
>
</template>
</vxe-toolbar>
@@ -48,7 +48,7 @@
</vxe-column>
<vxe-column field="channel" title="支付通道" :min-width="120">
<template #default="{ row }">
{{ dictConvert('PayChannel', row.channel) }}
{{ dictConvert('channel', row.channel) }}
</template>
</vxe-column>
<vxe-column field="amount" title="退款金额(元)" :min-width="140">
@@ -58,7 +58,7 @@
</vxe-column>
<vxe-column field="refundStatus" title="状态" :min-width="80">
<template #default="{ row }">
{{ dictConvert('RefundStatus', row.status) }}
{{ dictConvert('refund_status', row.status) }}
</template>
</vxe-column>
<vxe-column field="createTime" title="创建时间" sortable :min-width="230" />
@@ -138,7 +138,7 @@
field: 'outOrderNo',
type: STRING,
name: '通道订单号',
placeholder: '请输入三方支付的通道订单号',
placeholder: '请输入通道订单号',
},
{ field: 'title', type: STRING, name: '原支付标题', placeholder: '请输入原支付标题' },
{ field: 'errorCode', name: '错误码', type: STRING },