更改前端代码

main
dqytc 2026-08-07 14:13:09 +08:00
parent acd5ffce20
commit 63555f9094
5 changed files with 121 additions and 68 deletions

View File

@ -394,7 +394,9 @@ function toPersonalOpenListVo(a) {
customerName: a.customerName,
certificateNumber: a.certificateNumber,
mobilePhone: a.mobilePhone,
bankCardNumber: a.bankCardNumber,
// 列表页展示开户成功后的主账户账号(未开立成功前为空字符串),不展示银行卡号,
// 与企业开户申请列表 toEnterpriseOpenListVo 的字段取舍保持一致
mainAccountNo: a.mainAccountNo || '',
channelNo: a.channelNo,
applicationStatus: a.applicationStatus,
failReason: a.failReason,

View File

@ -21,6 +21,7 @@
:row-key="rowKey"
:pagination="pagination"
:row-selection="tableRowSelection"
:scroll="scroll"
@change="handleTableChange"
>
<template v-for="name in forwardSlotNames" #[name]="slotProps" :key="name">
@ -41,7 +42,12 @@ const props = defineProps({
pageSize: { type: Number, default: 10 },
// Boolean (checkbox ); 'radio' ()
rowSelection: { type: [Boolean, String], default: true },
selectedRowKeys: { type: Array, default: () => [] }
selectedRowKeys: { type: Array, default: () => [] },
// a-table scroll fixed(""),
// { x: 'max-content' } , antd vue fixed
// table-layout fixed, width
// ( fixed scroll.x bug ), vc-table Table.js mergedTableLayout
scroll: { type: Object, default: undefined }
})
const emit = defineEmits(['update:selectedRowKeys', 'search'])

View File

@ -24,7 +24,7 @@
<a-spin :spinning="busy" :tip="busyTip">
<a-page-header :title="pageTitle" @back="goBack">
<template v-if="isCreate && !submittedApplicationNo" #extra>
<a-space wrap>
<a-space wrap ref="agreementSectionRef">
<a-checkbox v-model:checked="agreementChecked">本人已阅读并同意</a-checkbox>
<a @click="showAgreement('service')"></a>
<a @click="showAgreement('privacy')"></a>
@ -62,15 +62,19 @@
:disabled="isDetail"
class="open-form"
>
<div ref="channelSectionRef">
<a-form-item label="渠道归属" required>
<ChannelSelect v-model:model-value="channelNo" placeholder="请选择核心企业" style="width: 300px" />
</a-form-item>
</div>
<div ref="customerSectionRef">
<a-form-item label="客户" required>
<a-space>
<a-input :value="form.customerName" placeholder="请选择客户" disabled style="width: 200px" />
<a-button v-if="!isDetail" @click="openPicker">{{ form.customerId ? '' : '' }}</a-button>
</a-space>
</a-form-item>
</div>
<a-form-item label="身份证号" required>
<a-input :value="form.certificateNumber" disabled placeholder="请输入身份证号" />
</a-form-item>
@ -112,6 +116,7 @@
<a-input v-model:value="form.jobNote" placeholder="职业为“其他”时请填写备注" style="width: 300px" />
</a-form-item>
<div ref="certPhotoSectionRef">
<a-form-item label="证件照片" :required="isCreate">
<a-space size="large" align="start">
<div>
@ -156,6 +161,7 @@
身份证信息与所选客户信息不一致,请核实后重新上传身份证或重新选择客户,当前无法提交
</div>
</a-form-item>
</div>
<a-form-item label="银行卡号" name="bankCardNumber" required validate-trigger="blur">
<a-input v-model:value="form.bankCardNumber" placeholder="请输入16位或19位银行卡号" style="width: 300px" />
@ -245,6 +251,19 @@ const pickerRef = ref(null)
const channelNo = ref(undefined)
const agreementChecked = ref(false)
// ,( a-form-item name ,
// antd scrollToField, ref )
const agreementSectionRef = ref(null)
const channelSectionRef = ref(null)
const customerSectionRef = ref(null)
const certPhotoSectionRef = ref(null)
function scrollToSection(sectionRef) {
const el = sectionRef?.value?.$el || sectionRef?.value
if (el && typeof el.scrollIntoView === 'function') {
el.scrollIntoView({ behavior: 'smooth', block: 'center' })
}
}
const mode = computed(() => {
if (route.path.endsWith('/edit')) return 'edit'
if (route.path.endsWith('/detail')) return 'detail'
@ -371,8 +390,10 @@ const rules = {
if (res.data.code === 200) {
lastVerifiedCardKey.value = key
// ,,()
// :query-card-info bankNo ""(),
// payBankNo ""( create-draft ""),, payBankNo
form.bankName = res.data.data?.bankName || ''
form.bankNo = res.data.data?.bankNo || ''
form.bankNo = res.data.data?.payBankNo || ''
return Promise.resolve()
}
form.bankName = ''
@ -575,36 +596,50 @@ onMounted(() => {
// ://///
// ""(create ,)""
// ,,,
//
async function validateBeforeSubmit() {
if (isCreate.value && !agreementChecked.value) {
scrollToSection(agreementSectionRef)
showErrorModal('请先阅读并勾选同意用户支付服务协议与隐私政策')
return false
}
if (!channelNo.value) {
scrollToSection(channelSectionRef)
showErrorModal('请先选择渠道归属')
return false
}
if (!form.customerId) {
scrollToSection(customerSectionRef)
showErrorModal('请先选择客户')
return false
}
if (idCardFrontUploading.value || idCardBackUploading.value || facePhotoUploading.value) {
scrollToSection(certPhotoSectionRef)
showErrorModal('证件照片正在上传中,请稍候')
return false
}
// , loadDetail fileNo ,
if (isCreate.value && (!idCardFrontFileNo.value || !idCardBackFileNo.value || !facePhotoFileNo.value)) {
scrollToSection(certPhotoSectionRef)
showErrorModal('请上传身份证人像面、国徽面和正面免冠照')
return false
}
if (identityMismatch.value) {
scrollToSection(certPhotoSectionRef)
showErrorModal('身份证信息与所选客户信息不一致,请核实后重新上传身份证或重新选择客户')
return false
}
try {
await formRef.value.validate()
return true
} catch {
} catch (err) {
// /// a-form-item name+rules ,
// (antd vue Form scrollToField, fieldId DOM )
const firstErrorName = err?.errorFields?.[0]?.name
if (firstErrorName) {
formRef.value.scrollToField(firstErrorName, { behavior: 'smooth', block: 'center' })
}
return false
}
}

View File

@ -10,6 +10,7 @@
:columns="columns"
:fetch-data="loadList"
:row-selection="false"
:scroll="{ x: 'max-content' }"
:initial-search="{ applicationNo: '', customerNameLike: '', certificateNumber: '', applicationStatus: undefined, startDate: undefined, endDate: undefined, organizationId: getCurrentOrganizationId() }"
>
<template #search="{ form }">
@ -97,18 +98,24 @@ const statusMap = {
APPLY_FAILED: { text: '申请失败', color: 'red' }
}
// "" fixed:'right' , width,
// ProTable scroll={x:'max-content'}(), antd vue fixed
// table-layout fixed,,
const columns = [
{ title: '序号', dataIndex: 'index', width: 60 },
{ title: '申请编号', dataIndex: 'applicationNo' },
{ title: '客户姓名', dataIndex: 'customerName' },
{ title: '身份证号', dataIndex: 'certificateNumber' },
{ title: '手机号', dataIndex: 'mobilePhone' },
{ title: '银行卡号', dataIndex: 'bankCardNumber' },
{ title: '状态', dataIndex: 'applicationStatus' },
{ title: '渠道编号', dataIndex: 'channelNo' },
{ title: '失败原因', dataIndex: 'failReason' },
{ title: '创建时间', dataIndex: 'createdAt' },
{ title: '操作', dataIndex: 'action', width: 200 }
{ title: '申请编号', dataIndex: 'applicationNo', width: 220 },
{ title: '客户姓名', dataIndex: 'customerName', width: 110 },
{ title: '身份证号', dataIndex: 'certificateNumber', width: 180 },
{ title: '手机号', dataIndex: 'mobilePhone', width: 130 },
// (),,
// , EnterpriseOpenList.vue ""
{ title: '主账户账号', dataIndex: 'mainAccountNo', width: 180 },
{ title: '状态', dataIndex: 'applicationStatus', width: 110 },
{ title: '渠道编号', dataIndex: 'channelNo', width: 110 },
{ title: '失败原因', dataIndex: 'failReason', width: 320 },
{ title: '创建时间', dataIndex: 'createdAt', width: 170 },
// ,"//"
{ title: '操作', dataIndex: 'action', width: 200, fixed: 'right' }
]
async function loadList(params) {

View File

@ -905,7 +905,10 @@
`applicationNo`/`customerNameLike`(客户姓名模糊)/`certificateNumber`/`applicationStatus`/
`startDate`/`endDate`/`page`/`pageSize`/`orgId`,响应 `{total,page,pageSize,records}`,
`records` 内每项含 `applicationNo`/`customerName`/`certificateNumber`/`mobilePhone`/
`bankCardNumber`/`channelNo`/`applicationStatus`/`failReason`/`createdAt`/`updatedAt`。
`mainAccountNo`(开户成功后的主账户账号,未开立成功前为空)/`channelNo`/
`applicationStatus`/`failReason`/`createdAt`/`updatedAt`。**2026-08-07 起列表页不再展示
银行卡号,改为展示 `mainAccountNo`**,与 `enterprise-open-application/list`
"主账户账号"列口径保持一致。
- `POST /api/wallet-management/personal-opening/detail`:假设请求 `{applicationNo}`,响应
字段在 `create-draft` 请求体(`accountProperty`/`customerId`/`certificateType`/
`certificateNumber`/`certificateEffectiveDate`/`certificateExpiryDate`/`issuingAuthority`/