mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-05-13 01:46:01 +08:00
feat(daxpay): 添加分账交易相关功能
- 新增分账交易 API 接口 - 实现分账订单列表、明细列表和交易信息页面 - 添加分账重试、同步和完结功能 - 优化表格样式和操作功能
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
<template>
|
||||
<basic-drawer
|
||||
forceRender
|
||||
v-bind="$attrs"
|
||||
title="分账订单明细"
|
||||
width="60%"
|
||||
:visible="visible"
|
||||
@close="visible = false"
|
||||
>
|
||||
<vxe-toolbar ref="xToolbar" custom :refresh="{ queryMethod: queryPage }" />
|
||||
<vxe-table
|
||||
keyField="id"
|
||||
ref="xTable"
|
||||
:data="records"
|
||||
:loading="loading"
|
||||
:cell-style="cellStyle"
|
||||
>
|
||||
<vxe-column type="seq" width="60" />
|
||||
<vxe-column field="receiverNo" title="接收方编号" :min-width="120" />
|
||||
<vxe-column field="receiverName" title="接收方姓名" :min-width="100" />
|
||||
<vxe-column field="receiverType" title="接收方类型" :min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ dictConvert('AllocReceiverType', row.receiverType) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="rate" title="分账比例" :min-width="100">
|
||||
<template #default="{ row }"> {{ row.rate / 100.0 }}% </template>
|
||||
</vxe-column>
|
||||
<vxe-column field="amount" title="分账金额" :min-width="100">
|
||||
<template #default="{ row }"> {{ row.amount / 100.0 }} 元 </template>
|
||||
</vxe-column>
|
||||
<vxe-column field="result" title="分账结果" :min-width="130">
|
||||
<template #default="{ row }"> {{ dictConvert('AllocDetailResult', row.result) }} </template>
|
||||
</vxe-column>
|
||||
<vxe-column field="errorMsg" title="错误原因" :min-width="160">
|
||||
<template #default="{ row }"> {{ row.errorMsg }} </template>
|
||||
</vxe-column>
|
||||
<vxe-column field="finishTime" title="完成时间" :min-width="160">
|
||||
<template #default="{ row }"> {{ row.finishTime }} </template>
|
||||
</vxe-column>
|
||||
<vxe-column fixed="right" :min-width="60" :showOverflow="false" title="操作">
|
||||
<template #default="{ row }">
|
||||
<span>
|
||||
<a href="javascript:" @click="show(row)">查看</a>
|
||||
</span>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
</basic-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { nextTick, ref } from 'vue'
|
||||
import useTablePage from '@/hooks/bootx/useTablePage'
|
||||
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
|
||||
import BasicDrawer from '@/components/Drawer/src/BasicDrawer.vue'
|
||||
import { useDict } from '@/hooks/bootx/useDict'
|
||||
import { AllocationOrder, AllocationOrderDetail, detailList } from './Allocation.api'
|
||||
// 使用hooks
|
||||
const { loading } = useTablePage(queryPage)
|
||||
const { dictConvert } = useDict()
|
||||
|
||||
let visible = ref(false)
|
||||
let order = ref<AllocationOrder>({})
|
||||
let records = ref<AllocationOrderDetail[]>([])
|
||||
const xTable = ref<VxeTableInstance>()
|
||||
const xToolbar = ref<VxeToolbarInstance>()
|
||||
const allocationOrderDetailInfo = ref<any>()
|
||||
|
||||
nextTick(() => {
|
||||
xTable.value?.connect(xToolbar.value as VxeToolbarInstance)
|
||||
})
|
||||
|
||||
/**
|
||||
* 入口
|
||||
* @param record
|
||||
*/
|
||||
function init(record) {
|
||||
visible.value = true
|
||||
order.value = record
|
||||
queryPage()
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
function queryPage() {
|
||||
loading.value = true
|
||||
detailList(order.value.id).then(({ data }) => {
|
||||
records.value = data
|
||||
loading.value = false
|
||||
})
|
||||
}
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
function show(record) {
|
||||
allocationOrderDetailInfo.value.init(record)
|
||||
}
|
||||
|
||||
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' }
|
||||
}
|
||||
if (column.field == 'asyncPay') {
|
||||
if (row.asyncPay) {
|
||||
return { color: 'green' }
|
||||
} else {
|
||||
return { color: 'gray' }
|
||||
}
|
||||
}
|
||||
if (column.field == 'combinationPay') {
|
||||
if (row.combinationPay) {
|
||||
return { color: 'green' }
|
||||
} else {
|
||||
return { color: 'gray' }
|
||||
}
|
||||
}
|
||||
}
|
||||
defineExpose({
|
||||
init,
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
@@ -0,0 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="less">
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,270 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="m-3 p-3 pt-5 bg-white">
|
||||
<b-query
|
||||
:query-params="model.queryParam"
|
||||
:fields="fields"
|
||||
:default-item-count="3"
|
||||
@query="queryPage"
|
||||
@reset="resetQueryParams"
|
||||
/>
|
||||
</div>
|
||||
<div class="m-3 p-3 bg-white">
|
||||
<vxe-toolbar ref="xToolbar" custom :refresh="{ queryMethod: queryPage }" />
|
||||
<vxe-table
|
||||
keyField="id"
|
||||
ref="xTable"
|
||||
:data="pagination.records"
|
||||
:loading="loading"
|
||||
:sort-config="{ remote: true, trigger: 'cell' }"
|
||||
@sort-change="sortChange"
|
||||
>
|
||||
<vxe-column type="seq" title="序号" width="60" />
|
||||
<vxe-column field="allocNo" title="分账单号" :min-width="230">
|
||||
<template #default="{ row }">
|
||||
<a @click="show(row)">
|
||||
{{ row.allocNo }}
|
||||
</a>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="title" title="订单标题" :min-width="150" />
|
||||
<vxe-column field="orderNo" title="支付订单号" :min-width="230">
|
||||
<template #default="{ row }">
|
||||
<a @click="showPayOrder(row)">
|
||||
{{ row.orderNo }}
|
||||
</a>
|
||||
</template>
|
||||
</vxe-column>
|
||||
|
||||
<vxe-column field="channel" title="所属通道" :min-width="100">
|
||||
<template #default="{ row }">
|
||||
<a-tag>{{ dictConvert('PayChannel', row.channel) }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="amount" title="总分账金额(元)" :min-width="120">
|
||||
<template #default="{ row }">
|
||||
{{ row.amount ? (row.amount / 100).toFixed(2) : 0 }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="status" title="状态" :min-width="120">
|
||||
<template #default="{ row }">
|
||||
<a-tag>{{ dictConvert('AllocOrderStatus', row.status) }}</a-tag>
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="result" title="分账结果" :min-width="100">
|
||||
<template #default="{ row }">
|
||||
{{ dictConvert('AllocOrderResult', row.result) }}
|
||||
</template> </vxe-column
|
||||
><vxe-column field="errorMsg" title="错误原因" :min-width="160" />
|
||||
<vxe-column field="createTime" title="创建时间" :min-width="160" />
|
||||
<vxe-column fixed="right" :min-width="200" :showOverflow="false" title="操作">
|
||||
<template #default="{ row }">
|
||||
<a-link @click="show(row)">查看</a-link>
|
||||
<a-divider type="vertical" />
|
||||
<a-link @click="showDetail(row)">明细列表</a-link>
|
||||
<a-divider type="vertical" />
|
||||
<a-dropdown>
|
||||
<a>
|
||||
更多
|
||||
<icon icon="ant-design:down-outlined" :size="12" />
|
||||
</a>
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item
|
||||
v-if="
|
||||
['allocation_processing', 'allocation_end', 'allocation_failed'].includes(
|
||||
row.status,
|
||||
)
|
||||
"
|
||||
>
|
||||
<a-link @click="retryInfo(row)">重试</a-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<a-link @click="syncInfo(row)">同步</a-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item v-if="['allocation_end', 'finish_failed'].includes(row.status)">
|
||||
<a-link @click="finishInfo(row)">完结</a-link>
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</template>
|
||||
</vxe-column>
|
||||
</vxe-table>
|
||||
<vxe-pager
|
||||
size="medium"
|
||||
:loading="loading"
|
||||
:current-page="pagination.current"
|
||||
:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
@page-change="handleTableChange"
|
||||
/>
|
||||
</div>
|
||||
<AllocDetailList ref="allocDetailList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from 'vue'
|
||||
import { page, sync, finish, retry } from './Allocation.api'
|
||||
import useTablePage from '@/hooks/bootx/useTablePage'
|
||||
import { VxeTable, VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
|
||||
import { useMessage } from '@/hooks/web/useMessage'
|
||||
import { useDict } from '@/hooks/bootx/useDict'
|
||||
import ALink from '/@/components/Link/Link.vue'
|
||||
import BQuery from '/@/components/Bootx/Query/BQuery.vue'
|
||||
import { LIST, QueryField, STRING } from '@/components/Bootx/Query/Query'
|
||||
import { LabeledValue } from 'ant-design-vue/lib/select'
|
||||
import { FormEditType } from '@/enums/formTypeEnum'
|
||||
import AllocDetailList from './AllocDetailList.vue'
|
||||
import { Icon } from '@/components/Icon'
|
||||
|
||||
// 使用hooks
|
||||
const {
|
||||
handleTableChange,
|
||||
pageQueryResHandel,
|
||||
resetQueryParams,
|
||||
pagination,
|
||||
sortChange,
|
||||
sortParam,
|
||||
pages,
|
||||
model,
|
||||
loading,
|
||||
} = useTablePage(queryPage)
|
||||
const { createMessage, createConfirm } = useMessage()
|
||||
const { dictConvert } = useDict()
|
||||
|
||||
const xTable = ref<VxeTableInstance>()
|
||||
const xToolbar = ref<VxeToolbarInstance>()
|
||||
const allocDetailList = ref<any>()
|
||||
const allocationOrderInfo = ref<any>()
|
||||
|
||||
let payChannelList = ref<LabeledValue[]>([])
|
||||
const payOrderInfo = ref<any>()
|
||||
|
||||
const fields = computed(() => {
|
||||
return [
|
||||
{
|
||||
field: 'channel',
|
||||
type: LIST,
|
||||
name: '分账通道',
|
||||
placeholder: '请选择分账通道',
|
||||
selectList: payChannelList.value,
|
||||
},
|
||||
{ field: 'orderNo', type: STRING, name: '分账订单号', placeholder: '请输入分账订单号' },
|
||||
{ field: 'paymentId', type: STRING, name: '支付订单ID', placeholder: '请输入支付订单ID' },
|
||||
{ field: 'title', type: STRING, name: '支付订单标题', placeholder: '请输入支付订单标题' },
|
||||
{ field: 'allocNo', type: STRING, name: '分账业务号', placeholder: '请输入分账业务号' },
|
||||
] as QueryField[]
|
||||
})
|
||||
onMounted(() => {
|
||||
vxeBind()
|
||||
initData()
|
||||
queryPage()
|
||||
})
|
||||
|
||||
/**
|
||||
* 绑定
|
||||
*/
|
||||
function vxeBind() {
|
||||
xTable.value?.connect(xToolbar.value as VxeToolbarInstance)
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
async function initData() {
|
||||
// findChannels().then(({ data }) => (payChannelList.value = data))
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看
|
||||
*/
|
||||
function show(record) {
|
||||
allocationOrderInfo.value.init(record.allocNo, FormEditType.Show)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账明细列表
|
||||
* @param record
|
||||
*/
|
||||
function showDetail(record) {
|
||||
allocDetailList.value.init(record)
|
||||
}
|
||||
|
||||
/**
|
||||
* 查看支付单信息
|
||||
*/
|
||||
function showPayOrder(record) {
|
||||
payOrderInfo.value.init(record.orderNo)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步分账状态
|
||||
* @param record
|
||||
*/
|
||||
function syncInfo(record) {
|
||||
createConfirm({
|
||||
iconType: 'info',
|
||||
title: '同步分账状态',
|
||||
content: '确定同步分账状态吗?',
|
||||
onOk: () => {
|
||||
sync(record.allocNo).then(() => {
|
||||
createMessage.success('同步成功')
|
||||
queryPage()
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账重试
|
||||
*/
|
||||
function retryInfo(record) {
|
||||
createConfirm({
|
||||
iconType: 'info',
|
||||
title: '分账重试',
|
||||
content: '确定分账重试吗?',
|
||||
onOk: () => {
|
||||
retry(record.bizAllocNo).then(() => {
|
||||
createMessage.success('分账重试请求发送成功')
|
||||
queryPage()
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 完结分账
|
||||
*/
|
||||
function finishInfo(record) {
|
||||
createConfirm({
|
||||
iconType: 'info',
|
||||
title: '完结分账',
|
||||
content: '确定完结分账吗?',
|
||||
onOk: () => {
|
||||
finish(record.allocNo).then(() => {
|
||||
createMessage.success('完结请求发送成功')
|
||||
queryPage()
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*/
|
||||
function queryPage() {
|
||||
loading.value = true
|
||||
page({
|
||||
...model.queryParam,
|
||||
...pages,
|
||||
...sortParam,
|
||||
}).then(({ data }) => {
|
||||
pageQueryResHandel(data)
|
||||
})
|
||||
return Promise.resolve()
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
171
src/views/daxpay/common/allocation/transaction/Allocation.api.ts
Normal file
171
src/views/daxpay/common/allocation/transaction/Allocation.api.ts
Normal file
@@ -0,0 +1,171 @@
|
||||
import { defHttp } from '@/utils/http/axios'
|
||||
import { PageResult, Result } from '#/axios'
|
||||
import { MchEntity } from '#/web'
|
||||
|
||||
/**
|
||||
* 分页
|
||||
*/
|
||||
export function page(params) {
|
||||
return defHttp.get<Result<PageResult<AllocationOrder>>>({
|
||||
url: '/allocation/transaction/page',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询详情
|
||||
*/
|
||||
export function get(id) {
|
||||
return defHttp.get<Result<AllocationOrder>>({
|
||||
url: '/allocation/transaction/findById',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单详细信息
|
||||
*/
|
||||
export function getOrderByAllocNo(allocNo: string) {
|
||||
return defHttp.get<Result>({
|
||||
url: '/allocation/transaction/findByAllocNo',
|
||||
params: { allocNo },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 扩展信息
|
||||
*/
|
||||
export function getExtra(id) {
|
||||
return defHttp.get<Result<AllocationOrder>>({
|
||||
url: '/allocation/transaction/findById',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 明细列表
|
||||
*/
|
||||
export function detailList(orderId) {
|
||||
return defHttp.get<Result<AllocationOrderDetail[]>>({
|
||||
url: '/allocation/transaction/detail/findAll',
|
||||
params: { orderId },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 明细详情
|
||||
*/
|
||||
export function detail(id) {
|
||||
return defHttp.get<Result<AllocationOrderDetail>>({
|
||||
url: '/allocation/transaction/detail/findById',
|
||||
params: { id },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账完结
|
||||
*/
|
||||
export function finish(allocNo) {
|
||||
return defHttp.post<Result<AllocationOrder>>({
|
||||
url: '/allocation/transaction/finish',
|
||||
params: { allocNo },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账完结
|
||||
*/
|
||||
export function retry(bizAllocNo) {
|
||||
return defHttp.post<Result<AllocationOrder>>({
|
||||
url: '/allocation/transaction/retry',
|
||||
params: { bizAllocNo },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询分账结果
|
||||
*/
|
||||
export function sync(allocNo) {
|
||||
return defHttp.post<Result<AllocationOrder>>({
|
||||
url: '/allocation/transaction/sync',
|
||||
params: { allocNo },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账订单
|
||||
*/
|
||||
export interface AllocationOrder extends MchEntity {
|
||||
// 分账单号
|
||||
allocNo?: string
|
||||
// 商户分账单号
|
||||
bizAllocNo?: string
|
||||
// 通道分账号
|
||||
outAllocNo?: string
|
||||
// 支付订单ID
|
||||
orderId?: string
|
||||
// 支付订单号
|
||||
orderNo?: string
|
||||
// 商户支付订单号
|
||||
bizOrderNo?: string
|
||||
// 外部系统支付订单号
|
||||
outOrderNo?: string
|
||||
// 支付订单标题
|
||||
title?: string
|
||||
// 所属通道
|
||||
channel?: string
|
||||
// 总分账金额
|
||||
amount?: number
|
||||
// 分账描述
|
||||
description?: string
|
||||
// 状态
|
||||
status?: string
|
||||
// 处理结果
|
||||
result?: string
|
||||
// 完成时间
|
||||
finishTime?: string
|
||||
// 异步通知地址
|
||||
notifyUrl?: string
|
||||
// 商户扩展参数
|
||||
attach?: string
|
||||
// 附加参数
|
||||
extraParam?: string
|
||||
// 请求时间
|
||||
reqTime?: string
|
||||
// 支付终端ip
|
||||
clientIp?: string
|
||||
// 错误码
|
||||
errorCode?: string
|
||||
// 错误原因
|
||||
errorMsg?: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 分账订单明细
|
||||
*/
|
||||
export interface AllocationOrderDetail extends MchEntity {
|
||||
// 分账订单ID
|
||||
orderId?: string
|
||||
// 分账明细单号
|
||||
receiverId?: string
|
||||
// 比例
|
||||
rate: number
|
||||
// 金额
|
||||
amount: number
|
||||
// 分账接收方类型
|
||||
receiverType?: string
|
||||
// 接收方账号
|
||||
receiverAccount?: string
|
||||
// 接收方姓名
|
||||
receiverName?: string
|
||||
// 接收方编号
|
||||
receiverNo?: string
|
||||
// 分账结果
|
||||
result?: string
|
||||
// 错误代码
|
||||
errorCode?: string
|
||||
// 错误原因
|
||||
errorMsg?: string
|
||||
// 完成时间
|
||||
finishTime?: string
|
||||
}
|
||||
Reference in New Issue
Block a user