foreign-admin-ui/src/views/capital/rechange/index.vue

332 lines
9.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="rechange-page">
<!-- 页面标题 -->
<div class="page-title">存款</div>
<!-- 存款渠道列表每行提供一个存款按钮 -->
<RechangeTable :table-data="channelList" :columns="tableColumns" :highlight-current-row="false">
<template #action="{ row }">
<el-button type="primary" size="small" @click="handleOpenDialog(row)">
存款
</el-button>
</template>
</RechangeTable>
</div>
<!-- 存款弹窗改为和设计图一致的支付面板布局 -->
<RechangeDialog class="rechange-pay-dialog" :visible="dialogVisible" title=" " width="640px" :show-footer="false"
@cancel="handleCancel" @close="handleClose">
<div class="dialog-content">
<!-- 顶部标题展示当前点击的存款渠道名称 -->
<div class="dialog-page-title">{{ rechangeForm.channelName || '存款渠道名称' }}</div>
<!-- 存款面板当前为纯前端演示后续可在确认支付时接入真实接口 -->
<el-form ref="rechangeFormRef" :model="rechangeForm" :rules="rechangeFormRules" label-position="top"
class="pay-form">
<el-form-item prop="depositAccount">
<template #label>
<span class="required-label">存款账户</span>
</template>
<el-input v-model="rechangeForm.depositAccount" disabled />
</el-form-item>
<el-form-item prop="supportedCurrency">
<template #label>
<span class="required-label">支持币种</span>
</template>
<div class="currency-box">{{ rechangeForm.supportedCurrency }}</div>
</el-form-item>
<el-form-item prop="depositAmount">
<template #label>
<span class="required-label">存款金额</span>
</template>
<el-input v-model="rechangeForm.depositAmount" placeholder="请输入金额">
<template #prepend>{{ rechangeForm.amountCurrency }}</template>
</el-input>
<!-- 快捷金额:模拟截图中的金额快捷按钮 -->
<div class="quick-amounts">
<el-button v-for="amount in rechangeQuickAmounts" :key="amount" plain size="small"
@click="handleQuickAmount(amount)">
{{ amount }}
</el-button>
</div>
</el-form-item>
</el-form>
<!-- 按钮区:上一步用于关闭弹窗返回列表,确认支付用于提交当前输入 -->
<div class="dialog-actions">
<el-button class="prev-btn" @click="handlePrevStep">上一步</el-button>
<el-button type="primary" class="confirm-btn" @click="handleSubmit">确认支付</el-button>
</div>
</div>
</RechangeDialog>
</template>
<script setup lang="ts">
defineOptions({
name: 'Rechange'
})
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage } from 'element-plus'
import { nextTick, ref } from 'vue'
import RechangeTable from '@/components/common/Table.vue'
import RechangeDialog from '@/components/common/Dialog.vue'
import { rechangeQuickAmounts, rechangeTableColumns } from './options'
// 列表单行数据结构:额外保留弹窗里会用到的账户和金额币种字段。
interface RechangeRow {
id: number
depositChannel: string
channelName: string
supportedCurrency: string
processingTime: string
singleAmount: string
depositAccount: string
amountCurrency: string
}
// 弹窗表单数据结构:当前只维护弹窗所需字段。
interface RechangeFormData {
id: number
channelName: string
depositAccount: string
supportedCurrency: string
amountCurrency: string
depositAmount: string
}
// mock 列表数据:当前仅用于页面展示。
const channelList = ref<RechangeRow[]>([
{
id: 1,
depositChannel: 'BANK-CNY',
channelName: '存款渠道名称',
supportedCurrency: 'CNY',
processingTime: '5-10分钟',
singleAmount: '100 - 50,000',
depositAccount: '只能在总钱包充值',
amountCurrency: 'USD',
},
{
id: 2,
depositChannel: 'BANK-USD',
channelName: '银行卡入金',
supportedCurrency: 'USD',
processingTime: '5-10分钟',
singleAmount: '100 - 50,000',
depositAccount: '只能在总钱包充值',
amountCurrency: 'USD',
},
{
id: 3,
depositChannel: 'USDT-TRC20',
channelName: '数字货币入金',
supportedCurrency: 'USDT',
processingTime: '1-3分钟',
singleAmount: '50 - 100,000',
depositAccount: '只能在总钱包充值',
amountCurrency: 'USDT',
},
])
// 表格列配置
const tableColumns = ref(rechangeTableColumns)
// 弹窗基础状态
const dialogVisible = ref(false)
const currentRowId = ref<number | null>(null)
const rechangeFormRef = ref<FormInstance>()
// 默认表单:弹窗关闭时回到初始状态。
const createDefaultForm = (): RechangeFormData => ({
id: 0,
channelName: '',
depositAccount: '',
supportedCurrency: '',
amountCurrency: '',
depositAmount: '',
})
const rechangeForm = ref<RechangeFormData>(createDefaultForm())
// 表单校验规则:当前只校验本次存款金额。
const rechangeFormRules = ref<FormRules<RechangeFormData>>({
depositAmount: [
{ required: true, message: '请输入存款金额', trigger: ['blur', 'change'] },
{ pattern: /^\d+(\.\d{1,2})?$/, message: '金额格式不正确最多保留2位小数', trigger: ['blur', 'change'] },
],
})
// 重置弹窗表单:统一给关闭、取消、提交成功等场景复用。
const resetDialogForm = () => {
rechangeForm.value = createDefaultForm()
currentRowId.value = null
rechangeFormRef.value?.clearValidate()
}
// 打开弹窗:把当前行参数带入支付面板。
const handleOpenDialog = async (row: RechangeRow) => {
currentRowId.value = row.id
rechangeForm.value = {
id: row.id,
channelName: row.channelName,
depositAccount: row.depositAccount,
supportedCurrency: row.supportedCurrency,
amountCurrency: row.amountCurrency,
depositAmount: '',
}
dialogVisible.value = true
await nextTick()
rechangeFormRef.value?.clearValidate()
}
// 快捷金额按钮:点击后直接回填到金额输入框。
const handleQuickAmount = (amount: string) => {
rechangeForm.value.depositAmount = amount
}
// 上一步:当前等价于关闭弹窗,返回列表。
const handlePrevStep = () => {
dialogVisible.value = false
resetDialogForm()
}
// 提交:当前先做前端校验和成功提示,后续再接支付接口。
const handleSubmit = async () => {
try {
await rechangeFormRef.value?.validate()
ElMessage.success(`已进入支付确认流程渠道ID${currentRowId.value}`)
dialogVisible.value = false
resetDialogForm()
} catch (error) {
console.error('存款表单校验失败', error)
}
}
// 取消弹窗
const handleCancel = () => {
dialogVisible.value = false
resetDialogForm()
}
// 关闭弹窗
const handleClose = () => {
dialogVisible.value = false
resetDialogForm()
}
</script>
<style scoped lang="scss">
.rechange-page {
height: 100%;
// 页面标题样式贴近截图的简洁列表页风格
.page-title {
margin-bottom: 16px;
font-size: 28px;
font-weight: 600;
color: #303133;
}
}
.dialog-content {
padding: 6px 8px 0;
}
.dialog-page-title {
margin-bottom: 24px;
font-size: 24px;
font-weight: 600;
color: #303133;
}
.pay-form {
:deep(.el-form-item) {
margin-bottom: 28px;
}
:deep(.el-form-item__label) {
padding-bottom: 10px;
}
:deep(.el-input__wrapper),
:deep(.el-input-group__prepend) {
height: 46px;
font-size: 14px;
}
}
.required-label {
position: relative;
padding-left: 12px;
font-size: 16px;
color: #303133;
&::before {
position: absolute;
left: 0;
top: 1px;
color: #f56c6c;
content: '*';
}
}
.currency-box {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 116px;
height: 60px;
padding: 0 24px;
font-size: 18px;
color: #303133;
background: #fff;
border: 1px solid #dcdfe6;
box-sizing: border-box;
}
.quick-amounts {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 12px;
:deep(.el-button) {
min-width: 72px;
margin-left: 0;
color: #3b82f6;
border-color: #3b82f6;
}
}
.dialog-actions {
display: flex;
gap: 44px;
margin-top: 44px;
padding-left: 6px;
}
.prev-btn,
.confirm-btn {
min-width: 98px;
height: 44px;
}
.prev-btn {
color: #3b82f6;
border-color: #3b82f6;
}
:deep(.rechange-pay-dialog .el-dialog__header) {
display: none;
}
:deep(.rechange-pay-dialog .el-dialog__body) {
padding: 26px 26px 30px;
}
</style>