mirror of
https://gitee.com/bootx/dax-pay-ui
synced 2026-08-13 07:45:41 +08:00
feat 储值卡管理和结算台
This commit is contained in:
43
src/enums/payment/voucherEnum.ts
Normal file
43
src/enums/payment/voucherEnum.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* 储值卡常量
|
||||
*/
|
||||
export enum VoucherEnum {
|
||||
/**
|
||||
* 状态-正常
|
||||
*/
|
||||
STATUS_NORMAL = 'normal',
|
||||
|
||||
/**
|
||||
* 状态-停用
|
||||
*/
|
||||
STATUS_FORBIDDEN = 'forbidden',
|
||||
|
||||
/**
|
||||
* 储值卡日志-开通
|
||||
*/
|
||||
LOG_ACTIVE = 'active',
|
||||
|
||||
/**
|
||||
* 储值卡日志-预冻结额度
|
||||
*/
|
||||
LOG_FREEZE_BALANCE = 'freeze',
|
||||
|
||||
/**
|
||||
* 储值卡日志-扣减并解冻余额
|
||||
*/
|
||||
LOG_REDUCE_AND_UNFREEZE_BALANCE = 'reduceAndUnfreeze',
|
||||
|
||||
/**
|
||||
* 储值卡日志-直接支付
|
||||
*/
|
||||
LOG_PAY = 'pay',
|
||||
/**
|
||||
* 储值卡日志-取消支付
|
||||
*/
|
||||
LOG_CLOSE_PAY = 'closePay',
|
||||
|
||||
/**
|
||||
* 储值卡日志-退款到本卡中
|
||||
*/
|
||||
LOG_REFUND_SELF = 'refundSelf',
|
||||
}
|
||||
@@ -18,15 +18,15 @@
|
||||
<a-form-item label="订单名称" name="title">
|
||||
<a-input v-model:value="form.title" />
|
||||
</a-form-item>
|
||||
<a-form-item label="异步支付金额" name="asyncAmount">
|
||||
<a-form-item label="微信/支付宝金额" name="asyncAmount">
|
||||
<a-input-number placeholder="请输入金额" :precision="2" v-model:value="form.asyncAmount" />
|
||||
</a-form-item>
|
||||
<!-- <a-form-item label="钱包支付" name="walletAmount">-->
|
||||
<!-- <a-input-number placeholder="请输入金额" :precision="2" v-model:value="form.walletAmount" />-->
|
||||
<!-- <template #help>-->
|
||||
<!-- <span>钱包余额:{{ wallet.balance }}</span>-->
|
||||
<!-- </template>-->
|
||||
<!-- </a-form-item>-->
|
||||
<a-form-item label="钱包支付" name="walletAmount">
|
||||
<a-input-number placeholder="请输入金额" :precision="2" v-model:value="form.walletAmount" />
|
||||
<template #help>
|
||||
<span>钱包余额:{{ wallet.balance }}</span>
|
||||
</template>
|
||||
</a-form-item>
|
||||
<a-form-item label="现金支付" name="cashAmount">
|
||||
<a-input-number placeholder="请输入金额" :precision="2" v-model:value="form.cashAmount" />
|
||||
</a-form-item>
|
||||
@@ -43,18 +43,18 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { $ref } from 'vue/macros'
|
||||
import { combinationPay, findStatusByBusinessId, findWalletByUser } from '/@/views/demo/payment/cashier/Cashier.api'
|
||||
import { combinationPay, findStatusByBusinessId } from '/@/views/demo/payment/cashier/Cashier.api'
|
||||
import { Voucher } from '/@/views/modules/payment/voucher/Voucher.api'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { FormInstance } from 'ant-design-vue/lib/form'
|
||||
import { useIntervalFn } from '@vueuse/core'
|
||||
import { onMounted } from 'vue'
|
||||
import CashierQrCode from './CashierQrCode.vue'
|
||||
import { Wallet } from '/src/views/modules/payment/wallet/Wallet.api'
|
||||
import { payChannelEnum } from '/@/enums/payment/payChannelEnum'
|
||||
import { payWayEnum } from '/@/enums/payment/payWayEnum'
|
||||
import { findByParamKey } from '/@/api/common/Parameter'
|
||||
import { PayStatus } from '/@/enums/payment/PayStatus'
|
||||
import { findByUser as findWalletByUser, Wallet } from '/@/views/modules/payment/wallet/Wallet.api'
|
||||
|
||||
const { createMessage } = useMessage()
|
||||
|
||||
@@ -73,15 +73,15 @@
|
||||
]
|
||||
let loading = $ref(false)
|
||||
let visible = $ref(false)
|
||||
// let wallet = $ref<Wallet>({ balance: 0 })
|
||||
let voucher = $ref<Voucher>({})
|
||||
let wallet = $ref<Wallet>({ balance: 0 })
|
||||
let form = $ref({
|
||||
payChannel: payChannelEnum.ALI,
|
||||
payWay: payWayEnum.QRCODE,
|
||||
businessId: '',
|
||||
title: '测试支付订单',
|
||||
asyncAmount: null,
|
||||
// walletAmount: null,
|
||||
walletAmount: null,
|
||||
cashAmount: null,
|
||||
mchCode: '',
|
||||
mchAppCode: '',
|
||||
@@ -89,7 +89,7 @@
|
||||
const rules = {
|
||||
payChannel: [{ required: true, message: '支付通道不可为空' }],
|
||||
businessId: [{ required: true, message: '业务ID不可为空' }],
|
||||
title: [{ required: true, message: '标题不可为空' }],
|
||||
title: [{ required: true, message: '金额不可=不可为空' }],
|
||||
payWay: [{ required: true, message: '支付方式不可为空' }],
|
||||
}
|
||||
|
||||
@@ -116,15 +116,22 @@
|
||||
init()
|
||||
})
|
||||
|
||||
/**
|
||||
* 初始化钱包信息
|
||||
*/
|
||||
function initWallet() {
|
||||
// 获取钱包
|
||||
findWalletByUser().then((res) => {
|
||||
wallet = res.data
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
async function init() {
|
||||
// findWalletByUser().then(({ data }) => {
|
||||
// wallet = data
|
||||
// })
|
||||
genOrderNo()
|
||||
|
||||
initWallet()
|
||||
// 获取商户和应用编码
|
||||
form.mchCode = (await findByParamKey('CashierMchCode')).data
|
||||
form.mchAppCode = (await findByParamKey('CashierMchAppCode')).data
|
||||
@@ -134,6 +141,9 @@
|
||||
form.businessId = 'P' + new Date().getTime()
|
||||
}
|
||||
|
||||
/**
|
||||
* 支付
|
||||
*/
|
||||
function pay() {
|
||||
formRef?.validate().then(async () => {
|
||||
loading = true
|
||||
@@ -141,7 +151,7 @@
|
||||
const payWayList = [
|
||||
{ payChannel: form.payChannel, payWay: form.payWay, amount: form.asyncAmount },
|
||||
{ payChannel: payChannelEnum.CASH, payWay: payWayEnum.NORMAL, amount: form.cashAmount },
|
||||
// { payChannel: 5, amount: form.walletAmount },
|
||||
{ payChannel: payChannelEnum.WALLET, payWay: payWayEnum.NORMAL, amount: form.walletAmount },
|
||||
]
|
||||
// 异步
|
||||
const { data } = await combinationPay({
|
||||
@@ -161,15 +171,21 @@
|
||||
loading = false
|
||||
resume()
|
||||
} else {
|
||||
genOrderNo()
|
||||
initWallet()
|
||||
createMessage.success('支付成功')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭
|
||||
*/
|
||||
function handleCancel() {
|
||||
cashierQrCode.handleClose()
|
||||
loading = false
|
||||
genOrderNo()
|
||||
initWallet()
|
||||
pause()
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
import { FormInstance } from 'ant-design-vue/lib/form'
|
||||
import { useIntervalFn } from '@vueuse/core'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { findByCardNo, Voucher } from '/@/views/modules/payment/voucher/Voucher.api'
|
||||
import { getAndJudgeVoucher, Voucher } from '/@/views/modules/payment/voucher/Voucher.api'
|
||||
import CashierQrCode from './CashierQrCode.vue'
|
||||
import { payChannelEnum } from '/@/enums/payment/payChannelEnum'
|
||||
import { findByParamKey } from '/@/api/common/Parameter'
|
||||
@@ -183,7 +183,7 @@
|
||||
*/
|
||||
function getVoucher() {
|
||||
if (form.voucherNo) {
|
||||
findByCardNo(form.voucherNo).then(({ data }) => {
|
||||
getAndJudgeVoucher(form.voucherNo).then(({ data }) => {
|
||||
voucher = data
|
||||
})
|
||||
}
|
||||
|
||||
@@ -64,9 +64,9 @@ export function del(id) {
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
export function findByCardNo(cardNo) {
|
||||
export function getAndJudgeVoucher(cardNo) {
|
||||
return defHttp.get<Result<Voucher>>({
|
||||
url: '/voucher/findByCardNo',
|
||||
url: '/voucher/getAndJudgeVoucher',
|
||||
params: { cardNo },
|
||||
})
|
||||
}
|
||||
@@ -120,5 +120,5 @@ export interface Voucher extends BaseEntity {
|
||||
// 结束时间
|
||||
endTime?: string
|
||||
// 状态
|
||||
status?: number
|
||||
status?: string
|
||||
}
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
</a-form-item>
|
||||
<a-form-item label="默认状态" name="status">
|
||||
<a-radio-group v-model:value="form.status">
|
||||
<a-radio :value="1">启用</a-radio>
|
||||
<a-radio :value="2">停用</a-radio>
|
||||
<a-radio :value="VoucherEnum.STATUS_NORMAL">启用</a-radio>
|
||||
<a-radio :value="VoucherEnum.STATUS_FORBIDDEN">停用</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
@@ -65,6 +65,7 @@
|
||||
import { computed, nextTick } from 'vue'
|
||||
import BasicModal from '/@/components/Modal/src/BasicModal.vue'
|
||||
import { generationBatch } from '/@/views/modules/payment/voucher/Voucher.api'
|
||||
import { VoucherEnum } from '/@/enums/payment/voucherEnum'
|
||||
|
||||
const { handleCancel, labelCol, wrapperCol, modalWidth, title, confirmLoading, visible, editable, showable, formEditType } = useFormEdit()
|
||||
const { createMessage } = useMessage()
|
||||
@@ -78,7 +79,7 @@
|
||||
enduring: true,
|
||||
startTime: null,
|
||||
endTime: null,
|
||||
status: 1,
|
||||
status: VoucherEnum.STATUS_NORMAL,
|
||||
})
|
||||
|
||||
const rules = computed<Record<string, Rule[]>>(() => {
|
||||
@@ -95,8 +96,8 @@
|
||||
|
||||
function init() {
|
||||
visible.value = true
|
||||
// confirmLoading.value = true
|
||||
resetForm()
|
||||
confirmLoading.value = false
|
||||
}
|
||||
|
||||
// 时间范围变动
|
||||
@@ -118,6 +119,7 @@
|
||||
}
|
||||
await generationBatch(form)
|
||||
visible.value = false
|
||||
confirmLoading.value = false
|
||||
emits('ok')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -24,6 +24,9 @@
|
||||
<a-descriptions-item label="有效期">
|
||||
{{ form.enduring ? '长期' : '期限' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="状态">
|
||||
{{ form.status === VoucherEnum.STATUS_NORMAL ? '正常' : '停用' }}
|
||||
</a-descriptions-item>
|
||||
<a-descriptions-item label="开始时间">
|
||||
{{ form.startTime }}
|
||||
</a-descriptions-item>
|
||||
@@ -43,6 +46,7 @@
|
||||
import { get, Voucher } from './Voucher.api'
|
||||
import { FormInstance, Rule } from 'ant-design-vue/lib/form'
|
||||
import BasicModal from '/@/components/Modal/src/BasicModal.vue'
|
||||
import { VoucherEnum } from "../../../../enums/payment/voucherEnum";
|
||||
const { handleCancel, modalWidth, confirmLoading, visible } = useFormEdit()
|
||||
// 表单
|
||||
const formRef = $ref<FormInstance>()
|
||||
@@ -55,7 +59,7 @@
|
||||
enduring: true,
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
status: 0,
|
||||
status: undefined,
|
||||
})
|
||||
// 入口
|
||||
function init(id) {
|
||||
|
||||
@@ -41,12 +41,12 @@
|
||||
<template #overlay>
|
||||
<a-menu>
|
||||
<a-menu-item>
|
||||
<a-link danger v-if="row.status === 1" @click="lockConfirm(row.id, true)">停用</a-link>
|
||||
<a-link v-if="row.status === 2" @click="lockConfirm(row.id, false)">启用</a-link>
|
||||
<a-link @click="showLogs(row.id)">日志</a-link>
|
||||
</a-menu-item>
|
||||
<a-menu-item>
|
||||
<a-link danger v-if="row.status === 'normal'" @click="lockConfirm(row.id, true)">停用</a-link>
|
||||
<a-link v-if="row.status === 'forbidden'" @click="lockConfirm(row.id, false)">启用</a-link>
|
||||
</a-menu-item>
|
||||
<!-- <a-menu-item>-->
|
||||
<!-- <a-link>金额变动</a-link>-->
|
||||
<!-- </a-menu-item>-->
|
||||
</a-menu>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
|
||||
33
src/views/modules/payment/voucher/VoucherLog.api.ts
Normal file
33
src/views/modules/payment/voucher/VoucherLog.api.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { PageResult, Result } from '/#/axios'
|
||||
import { defHttp } from '/@/utils/http/axios'
|
||||
import { BaseEntity } from '/#/web'
|
||||
|
||||
/**
|
||||
* 根据储值卡Id查询日志分页
|
||||
*/
|
||||
export function pageByVoucherId(params) {
|
||||
return defHttp.get<Result<PageResult<VoucherLog>>>({
|
||||
url: '/voucher/log/pageByVoucherId',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 储值卡日志
|
||||
*/
|
||||
export interface VoucherLog extends BaseEntity {
|
||||
/** 储值卡id */
|
||||
voucherId: string
|
||||
/** 储值卡号 */
|
||||
voucherNo: string
|
||||
/** 金额 */
|
||||
amount: number
|
||||
/** 类型 */
|
||||
type: string
|
||||
/** 交易记录ID */
|
||||
paymentId: string
|
||||
/** 业务ID */
|
||||
businessId: string
|
||||
/** 备注 */
|
||||
remark: string
|
||||
}
|
||||
79
src/views/modules/payment/voucher/VoucherLogList.vue
Normal file
79
src/views/modules/payment/voucher/VoucherLogList.vue
Normal file
@@ -0,0 +1,79 @@
|
||||
<template>
|
||||
<basic-drawer forceRender showFooter v-bind="$attrs" title="钱包日志列表" width="60%" :visible="visible" @close="visible = false">
|
||||
<vxe-toolbar ref="xToolbar" custom :refresh="{ queryMethod: queryPage }" />
|
||||
<vxe-table row-id="id" ref="xTable" :data="pagination.records" :loading="loading">
|
||||
<vxe-column type="seq" title="序号" width="60" />
|
||||
<vxe-column field="type" title="类型">
|
||||
<template #default="{ row }">
|
||||
{{ dictConvert('WalletLogType', row.type) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="amount" title="金额" />
|
||||
<vxe-column field="operationSource" title="操作类型">
|
||||
<template #default="{ row }">
|
||||
{{ dictConvert('WalletLogOperation', row.operationSource) }}
|
||||
</template>
|
||||
</vxe-column>
|
||||
<vxe-column field="createTime" title="操作时间" />
|
||||
<vxe-column field="remark" title="备注" />
|
||||
<template #footer>
|
||||
<a-button key="cancel" @click="handleCancel">取消</a-button>
|
||||
</template>
|
||||
</vxe-table>
|
||||
<vxe-pager
|
||||
size="medium"
|
||||
:loading="loading"
|
||||
:current-page="pagination.current"
|
||||
:page-size="pagination.size"
|
||||
:total="pagination.total"
|
||||
@page-change="handleTableChange"
|
||||
/>
|
||||
</basic-drawer>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import BasicDrawer from '/@/components/Drawer/src/BasicDrawer.vue'
|
||||
import useTablePage from '/@/hooks/bootx/useTablePage'
|
||||
import { useMessage } from '/@/hooks/web/useMessage'
|
||||
import { useDict } from '/@/hooks/bootx/useDict'
|
||||
import { QueryField } from '/@/components/Bootx/Query/Query'
|
||||
import { VxeTableInstance, VxeToolbarInstance } from 'vxe-table'
|
||||
import { nextTick } from 'vue'
|
||||
import { pageByVoucherId } from "/@/views/modules/payment/voucher/VoucherLog.api";
|
||||
|
||||
// 使用hooks
|
||||
const { handleTableChange, pageQueryResHandel, resetQueryParams, pagination, pages, model, loading } = useTablePage(queryPage)
|
||||
const { notification, createMessage } = useMessage()
|
||||
const { dictConvert } = useDict()
|
||||
|
||||
// 查询条件
|
||||
const fields = [] as QueryField[]
|
||||
let visible = $ref(false)
|
||||
let walletId = $ref<string>()
|
||||
|
||||
const xTable = $ref<VxeTableInstance>()
|
||||
const xToolbar = $ref<VxeToolbarInstance>()
|
||||
|
||||
nextTick(() => {
|
||||
xTable?.connect(xToolbar as VxeToolbarInstance)
|
||||
})
|
||||
|
||||
function init(id) {
|
||||
visible = true
|
||||
walletId = id
|
||||
queryPage()
|
||||
}
|
||||
// 分页查询
|
||||
function queryPage() {
|
||||
pageByVoucherId({
|
||||
...model.queryParam,
|
||||
...pages,
|
||||
walletId,
|
||||
}).then(({ data }) => {
|
||||
pageQueryResHandel(data)
|
||||
})
|
||||
}
|
||||
defineExpose({ init })
|
||||
</script>
|
||||
|
||||
<style scoped lang="less"></style>
|
||||
Reference in New Issue
Block a user