对接U存款通道
This commit is contained in:
parent
6b49a037e0
commit
02c0e84c07
|
|
@ -47,3 +47,20 @@ export const createBuyEx = (data: {
|
||||||
}) => {
|
}) => {
|
||||||
return request.post('/delphiPay/createBuyEx', data, { showMessage: false })
|
return request.post('/delphiPay/createBuyEx', data, { showMessage: false })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ERC支付
|
||||||
|
export const ERCPay = (data: {
|
||||||
|
channel_id: number
|
||||||
|
amount: string
|
||||||
|
}) => {
|
||||||
|
return request.post('/upay/ERCPay', data, { showMessage: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
// TRC支付
|
||||||
|
export const TRCPay = (data: {
|
||||||
|
channel_id: number
|
||||||
|
amount: string
|
||||||
|
}) => {
|
||||||
|
return request.post('/upay/TRCPay', data, { showMessage: false })
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@
|
||||||
<!-- 存款弹窗 -->
|
<!-- 存款弹窗 -->
|
||||||
<RechangeDialog class="rechange-pay-dialog" :visible="dialogVisible" title="存款" width="600px" :show-footer="false"
|
<RechangeDialog class="rechange-pay-dialog" :visible="dialogVisible" title="存款" width="600px" :show-footer="false"
|
||||||
@cancel="handleCancel" @close="handleClose">
|
@cancel="handleCancel" @close="handleClose">
|
||||||
<!-- type === 8 时显示新样式(选择金额和支付方式) -->
|
<!-- channelCode === 'DELPHIPAY' 时显示新样式(选择金额和支付方式) -->
|
||||||
<template v-if="rechangeForm.type === 8">
|
<template v-if="rechangeForm.channelCode === 'DELPHIPAY'">
|
||||||
<!-- 步骤1:选择金额和支付方式 -->
|
<!-- 步骤1:选择金额和支付方式 -->
|
||||||
<template v-if="payStep === 1">
|
<template v-if="payStep === 1">
|
||||||
<!-- 渠道信息 -->
|
<!-- 渠道信息 -->
|
||||||
|
|
@ -114,7 +114,56 @@
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!-- type !== 8 时显示老样式(银行卡信息 + 上传凭证) -->
|
<template v-else-if="rechangeForm.channelCode === 'TRC' || rechangeForm.channelCode === 'ERC'">
|
||||||
|
|
||||||
|
<div class="crypto-section">
|
||||||
|
<div class="crypto-left">
|
||||||
|
<div class="crypto-title">请向以下地址转账</div>
|
||||||
|
<div class="qrcode-box">
|
||||||
|
<img :src="cryptoQrcode" alt="请生成钱包地址二维码" class="crypto-qrcode" />
|
||||||
|
<!-- <div v-else class="qrcode-loading">
|
||||||
|
<el-icon class="is-loading" size="48">
|
||||||
|
<Loading />
|
||||||
|
</el-icon>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<div class="crypto-tip">扫描二维码获取钱包地址</div>
|
||||||
|
</div>
|
||||||
|
<div class="crypto-right">
|
||||||
|
<div class="wallet-title">钱包地址</div>
|
||||||
|
<div class="wallet-address-row">
|
||||||
|
<el-input v-model="rechangeForm.address" readonly size="large" class="wallet-address-input">
|
||||||
|
<template #append>
|
||||||
|
<el-button @click="handleCopyAddress" class="copy-btn">
|
||||||
|
<el-icon><DocumentCopy /></el-icon>
|
||||||
|
<span>复制</span>
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
|
<div class="wallet-type">
|
||||||
|
<span class="type-label">钱包类型:</span>
|
||||||
|
<span class="type-value">{{ rechangeForm.channelCode === 'TRC' ? 'USDT-TRC20' : 'USDT-ERC20' }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- 充值金额 -->
|
||||||
|
<el-form-item label="充值金额" size="large" prop="depositAmount">
|
||||||
|
<el-input v-model="rechangeForm.depositAmount" placeholder="请输入充值金额生成二维码和钱包地址" size="large" @input="handleAmountInput">
|
||||||
|
<template #suffix>
|
||||||
|
<span class="currency-suffix">USDT</span>
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<!-- 按钮区 -->
|
||||||
|
<div class="dialog-actions">
|
||||||
|
<el-button type="primary" size="large" :loading="submitLoading" @click="handleGenerateQrcode">
|
||||||
|
生成二维码
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 时显示老样式(银行卡信息 + 上传凭证) -->
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<el-form ref="rechangeFormRef" :model="rechangeForm" :rules="rechangeFormRules" label-position="top">
|
<el-form ref="rechangeFormRef" :model="rechangeForm" :rules="rechangeFormRules" label-position="top">
|
||||||
<!-- 渠道信息 -->
|
<!-- 渠道信息 -->
|
||||||
|
|
@ -204,7 +253,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Check, Loading, Plus } from '@element-plus/icons-vue'
|
import { Check, Loading, Plus, DocumentCopy } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'Rechange'
|
name: 'Rechange'
|
||||||
|
|
@ -217,7 +266,7 @@ import RechangeTable from '@/components/common/Table.vue'
|
||||||
import RechangeDialog from '@/components/common/Dialog.vue'
|
import RechangeDialog from '@/components/common/Dialog.vue'
|
||||||
import { usePageLoading } from '@/composables/useLoading'
|
import { usePageLoading } from '@/composables/useLoading'
|
||||||
import { rechangeTableColumns } from './options'
|
import { rechangeTableColumns } from './options'
|
||||||
import { getRechargeChannelList, getApplyCustomerRef, getKycDetail, createBuyEx, rechargeApi } from '@/api/modules/capital/rechangeChanl'
|
import { getRechargeChannelList, getApplyCustomerRef, getKycDetail, createBuyEx, rechargeApi, ERCPay, TRCPay } from '@/api/modules/capital/rechangeChanl'
|
||||||
import { uploadImageApi } from '@/api/modules/upload'
|
import { uploadImageApi } from '@/api/modules/upload'
|
||||||
import QRCode from 'qrcode'
|
import QRCode from 'qrcode'
|
||||||
import alipayIcon from '@/assets/images/zfb.png'
|
import alipayIcon from '@/assets/images/zfb.png'
|
||||||
|
|
@ -285,6 +334,9 @@ const qrcodeImageUrls = ref<string[]>([])
|
||||||
// 支付链接列表
|
// 支付链接列表
|
||||||
const paymentUrls = ref<string[]>([])
|
const paymentUrls = ref<string[]>([])
|
||||||
|
|
||||||
|
// 虚拟货币二维码
|
||||||
|
const cryptoQrcode = ref('')
|
||||||
|
|
||||||
// 生成二维码
|
// 生成二维码
|
||||||
const generateQRCode = async (url: string) => {
|
const generateQRCode = async (url: string) => {
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
|
@ -431,6 +483,9 @@ const handleOpenDialog = async (row: any) => {
|
||||||
beneficiaryBankAccount: row.beneficiary_bank_account || '',
|
beneficiaryBankAccount: row.beneficiary_bank_account || '',
|
||||||
address: (row as any).address || '',
|
address: (row as any).address || '',
|
||||||
}
|
}
|
||||||
|
if (rechangeForm.value.channelCode === 'TRC' || rechangeForm.value.channelCode === 'ERC') {
|
||||||
|
rechangeForm.value.address = ''
|
||||||
|
}
|
||||||
// 重置支付状态
|
// 重置支付状态
|
||||||
payStep.value = 1
|
payStep.value = 1
|
||||||
selectedMethod.value = ''
|
selectedMethod.value = ''
|
||||||
|
|
@ -441,6 +496,33 @@ const handleOpenDialog = async (row: any) => {
|
||||||
rechangeFormRef.value?.clearValidate()
|
rechangeFormRef.value?.clearValidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成虚拟货币二维码
|
||||||
|
const generateCryptoQrcode = async (address: string) => {
|
||||||
|
if (!address) return
|
||||||
|
try {
|
||||||
|
const dataUrl = await QRCode.toDataURL(address, {
|
||||||
|
width: 200,
|
||||||
|
margin: 4,
|
||||||
|
})
|
||||||
|
cryptoQrcode.value = dataUrl
|
||||||
|
} catch (error) {
|
||||||
|
console.error('生成二维码失败:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 复制钱包地址
|
||||||
|
const handleCopyAddress = async () => {
|
||||||
|
const address = rechangeForm.value.address
|
||||||
|
if (!address) return
|
||||||
|
try {
|
||||||
|
await navigator.clipboard.writeText(address)
|
||||||
|
ElMessage.success('复制成功')
|
||||||
|
} catch (error) {
|
||||||
|
console.error('复制失败:', error)
|
||||||
|
ElMessage.error('复制失败')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 选择快捷金额
|
// 选择快捷金额
|
||||||
const handleQuickAmount = (amount: number) => {
|
const handleQuickAmount = (amount: number) => {
|
||||||
rechangeForm.value.depositAmount = amount.toString()
|
rechangeForm.value.depositAmount = amount.toString()
|
||||||
|
|
@ -545,6 +627,20 @@ const handleUpload = async (options: any) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 生成二维码
|
||||||
|
const handleGenerateQrcode = async () => {
|
||||||
|
let pay = ERCPay
|
||||||
|
if(rechangeForm.value.channelCode === 'TRC'){
|
||||||
|
pay = TRCPay
|
||||||
|
}
|
||||||
|
const res: any = await pay({
|
||||||
|
channel_id: rechangeForm.value.id,
|
||||||
|
amount: rechangeForm.value.depositAmount,
|
||||||
|
})
|
||||||
|
rechangeForm.value.address = res.wallet_url || ''
|
||||||
|
await generateCryptoQrcode(res.wallet_url || '')
|
||||||
|
}
|
||||||
|
|
||||||
// 老表单提交(type !== 8 时使用)
|
// 老表单提交(type !== 8 时使用)
|
||||||
const handleOldSubmit = async () => {
|
const handleOldSubmit = async () => {
|
||||||
try {
|
try {
|
||||||
|
|
@ -577,6 +673,7 @@ const handleCancel = () => {
|
||||||
payStep.value = 1
|
payStep.value = 1
|
||||||
selectedMethod.value = ''
|
selectedMethod.value = ''
|
||||||
voucherUrl.value = ''
|
voucherUrl.value = ''
|
||||||
|
cryptoQrcode.value = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
// 关闭弹窗
|
// 关闭弹窗
|
||||||
|
|
@ -943,6 +1040,113 @@ onMounted(() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 虚拟货币存款样式
|
||||||
|
.crypto-section {
|
||||||
|
display: flex;
|
||||||
|
gap: 32px;
|
||||||
|
background: #f5f7fa;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 24px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
.crypto-left {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.crypto-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode-box {
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding: 16px;
|
||||||
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crypto-qrcode {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
|
||||||
|
.qrcode-loading {
|
||||||
|
color: #409eff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.crypto-tip {
|
||||||
|
margin-top: 12px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.crypto-right {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.wallet-title {
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #303133;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-address-row {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
|
||||||
|
.wallet-address-input {
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
border-radius: 8px 0 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.el-input__inner) {
|
||||||
|
font-family: monospace;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy-btn {
|
||||||
|
padding: 0 16px;
|
||||||
|
border-left: none;
|
||||||
|
border-radius: 0 8px 8px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.wallet-type {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
padding: 12px 16px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 8px;
|
||||||
|
border-left: 3px solid #409eff;
|
||||||
|
|
||||||
|
.type-label {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #909399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.type-value {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #409eff;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 上传凭证样式
|
// 上传凭证样式
|
||||||
.voucher-uploader {
|
.voucher-uploader {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ export const rules = (menuForm: any, iconOptions: any[]): FormRules => {
|
||||||
// 3. 路由路径:必填 + 格式校验(以/开头,仅包含字母/数字/下划线/斜杠)
|
// 3. 路由路径:必填 + 格式校验(以/开头,仅包含字母/数字/下划线/斜杠)
|
||||||
path: [
|
path: [
|
||||||
{ required: true, message: '请输入前端路由路径', trigger: 'blur' },
|
{ required: true, message: '请输入前端路由路径', trigger: 'blur' },
|
||||||
{ pattern: /^\/[a-zA-Z0-9_\/]+$/, message: '前端路由路径必须以/开头,仅包含字母、数字、下划线和斜杠', trigger: 'blur' }
|
{ pattern: /^\/[a-zA-Z0-9_/]+$/, message: '前端路由路径必须以/开头,仅包含字母、数字、下划线和斜杠', trigger: 'blur' }
|
||||||
],
|
],
|
||||||
// 4. 后端路由:可选,但填了就必须是指定范围(匹配你提供的后端路由列表)
|
// 4. 后端路由:可选,但填了就必须是指定范围(匹配你提供的后端路由列表)
|
||||||
api: [
|
api: [
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue