332 lines
9.3 KiB
Vue
332 lines
9.3 KiB
Vue
<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>
|