feat(web): 注册与资质表单新增基本户信息与发票类型
- HjcEnterpriseForm.vue:新增账户名称/账号/开户银行/开户支行四个输入与发票类型单选
(VAT_SPECIAL 电子专票 / VAT_NORMAL 电子普票,无默认值),模板 + validate + buildPayload + fill 四处同步
- 账号只做长度与字符校验(^[0-9]{8,32}$),与后端 validateRegister 一致,不加真实性校验
- 必填提示点名到具体项:请填写基本户账户名称 / 开户银行 / 开户支行,未选发票类型提示「请选择发票类型」
- register.vue、tender/qualification.vue 表单初值补齐 5 个字段
- 回显兼容 bank_account_name 与 bankAccountName 两种键名
This commit is contained in:
@@ -27,6 +27,59 @@
|
|||||||
<input v-model="form.contactEmail" type="email" class="field" :disabled="readonly" placeholder="企业邮箱" />
|
<input v-model="form.contactEmail" type="email" class="field" :disabled="readonly" placeholder="企业邮箱" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<h3 class="border-l-4 border-blue-600 pl-2 pt-2 text-sm font-semibold text-blue-600">
|
||||||
|
基本户信息与发票类型
|
||||||
|
</h3>
|
||||||
|
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="block text-sm text-gray-600">账户名称</label>
|
||||||
|
<input
|
||||||
|
v-model="form.bankAccountName"
|
||||||
|
class="field"
|
||||||
|
:disabled="readonly"
|
||||||
|
maxlength="255"
|
||||||
|
placeholder="基本户账户名称,可与上方企业名称不同"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="block text-sm text-gray-600">账号</label>
|
||||||
|
<input
|
||||||
|
v-model="form.bankAccountNo"
|
||||||
|
class="field"
|
||||||
|
:disabled="readonly"
|
||||||
|
maxlength="32"
|
||||||
|
placeholder="基本户账号,8-32 位数字"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="block text-sm text-gray-600">开户银行</label>
|
||||||
|
<input v-model="form.bankName" class="field" :disabled="readonly" maxlength="128" placeholder="如:中国工商银行" />
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="block text-sm text-gray-600">开户支行</label>
|
||||||
|
<input
|
||||||
|
v-model="form.bankBranch"
|
||||||
|
class="field"
|
||||||
|
:disabled="readonly"
|
||||||
|
maxlength="128"
|
||||||
|
placeholder="如:南宁市民族大道支行"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="space-y-1">
|
||||||
|
<label class="block text-sm text-gray-600">发票类型</label>
|
||||||
|
<div class="flex flex-wrap items-center gap-6 pt-1">
|
||||||
|
<label
|
||||||
|
v-for="t in INVOICE_TYPES"
|
||||||
|
:key="t.value"
|
||||||
|
class="flex items-center gap-2 text-sm"
|
||||||
|
:class="readonly ? 'text-gray-400' : 'text-gray-700'"
|
||||||
|
>
|
||||||
|
<input v-model="form.invoiceType" type="radio" :value="t.value" :disabled="readonly" />
|
||||||
|
{{ t.label }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3 class="border-l-4 border-blue-600 pl-2 pt-2 text-sm font-semibold text-blue-600">经办人信息</h3>
|
<h3 class="border-l-4 border-blue-600 pl-2 pt-2 text-sm font-semibold text-blue-600">经办人信息</h3>
|
||||||
|
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
@@ -115,6 +168,18 @@ const ocrHints = reactive<Record<string, string>>({ license: '', idcard_front: '
|
|||||||
/** 材料类型:仅身份证人像面与营业执照需要 OCR */
|
/** 材料类型:仅身份证人像面与营业执照需要 OCR */
|
||||||
const OCR_TYPES = ['license', 'idcard_front']
|
const OCR_TYPES = ['license', 'idcard_front']
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发票类型:单选、**无默认值**、必选。取值与后端 `hjc_invoice.invoice_type` 口径一致,
|
||||||
|
* 不要另起字符串字面量(与 h5 端 components/EnterpriseForm.vue 保持一致)。
|
||||||
|
*/
|
||||||
|
const INVOICE_TYPES = [
|
||||||
|
{ value: 'VAT_SPECIAL', label: '电子专票' },
|
||||||
|
{ value: 'VAT_NORMAL', label: '电子普票' }
|
||||||
|
]
|
||||||
|
|
||||||
|
/** 基本户账号:与后端 validateRegister 一致,仅做长度与字符校验(纯数字 8-32 位) */
|
||||||
|
const BANK_ACCOUNT_NO_RE = /^[0-9]{8,32}$/
|
||||||
|
|
||||||
async function onPick(m: any, e: Event) {
|
async function onPick(m: any, e: Event) {
|
||||||
const input = e.target as HTMLInputElement
|
const input = e.target as HTMLInputElement
|
||||||
const file = input.files?.[0]
|
const file = input.files?.[0]
|
||||||
@@ -192,12 +257,16 @@ function removeImage(m: any) {
|
|||||||
if (ocrHints[m.materialType] !== undefined) ocrHints[m.materialType] = ''
|
if (ocrHints[m.materialType] !== undefined) ocrHints[m.materialType] = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 必填校验:企业联系电话、企业地址选填,其余必填;4 类证件必传 */
|
/** 必填校验:企业联系电话、企业地址选填,其余必填(含基本户 4 项与发票类型);4 类证件必传 */
|
||||||
function validate(): boolean {
|
function validate(): boolean {
|
||||||
|
const f = form.value
|
||||||
const required: Array<[string, string]> = [
|
const required: Array<[string, string]> = [
|
||||||
['name', '企业名称'],
|
['name', '企业名称'],
|
||||||
['creditCode', '纳税人识别号'],
|
['creditCode', '纳税人识别号'],
|
||||||
['contactEmail', '企业邮箱'],
|
['contactEmail', '企业邮箱'],
|
||||||
|
['bankAccountName', '基本户账户名称'],
|
||||||
|
['bankName', '开户银行'],
|
||||||
|
['bankBranch', '开户支行'],
|
||||||
['agentName', '经办人姓名'],
|
['agentName', '经办人姓名'],
|
||||||
['idCardNo', '经办人身份证号'],
|
['idCardNo', '经办人身份证号'],
|
||||||
['agentEmail', '经办人邮箱'],
|
['agentEmail', '经办人邮箱'],
|
||||||
@@ -206,11 +275,21 @@ function validate(): boolean {
|
|||||||
]
|
]
|
||||||
if (props.showPassword) required.unshift(['password', '登录密码'])
|
if (props.showPassword) required.unshift(['password', '登录密码'])
|
||||||
for (const [key, label] of required) {
|
for (const [key, label] of required) {
|
||||||
if (!form.value[key]) {
|
if (!String(f[key] ?? '').trim()) {
|
||||||
uniToast(`请填写${label}`)
|
uniToast(`请填写${label}`)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 账号:空值已在上面的必填循环里点名提示;这里只负责长度与字符
|
||||||
|
if (!BANK_ACCOUNT_NO_RE.test(String(f.bankAccountNo ?? '').trim())) {
|
||||||
|
uniToast('基本户账号只能为 8-32 位数字')
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
// 发票类型无默认值,未选时提交前拦截
|
||||||
|
if (!INVOICE_TYPES.some((t) => t.value === f.invoiceType)) {
|
||||||
|
uniToast('请选择发票类型')
|
||||||
|
return false
|
||||||
|
}
|
||||||
if (materials.value.some((m: any) => !m.fileUrl)) {
|
if (materials.value.some((m: any) => !m.fileUrl)) {
|
||||||
uniToast('请上传全部证件')
|
uniToast('请上传全部证件')
|
||||||
return false
|
return false
|
||||||
@@ -225,7 +304,7 @@ function normalizeDateTime(v: string) {
|
|||||||
return s.length === 16 ? `${s}:00` : s
|
return s.length === 16 ? `${s}:00` : s
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 提交用载荷(含证件材料,授权到期时间已规范化为后端格式) */
|
/** 提交用载荷(含基本户与发票类型、证件材料,授权到期时间已规范化为后端格式) */
|
||||||
function buildPayload() {
|
function buildPayload() {
|
||||||
const f = form.value
|
const f = form.value
|
||||||
return {
|
return {
|
||||||
@@ -234,6 +313,11 @@ function buildPayload() {
|
|||||||
contactPhone: f.contactPhone,
|
contactPhone: f.contactPhone,
|
||||||
contactEmail: f.contactEmail,
|
contactEmail: f.contactEmail,
|
||||||
address: f.address,
|
address: f.address,
|
||||||
|
bankAccountName: f.bankAccountName,
|
||||||
|
bankAccountNo: f.bankAccountNo,
|
||||||
|
bankName: f.bankName,
|
||||||
|
bankBranch: f.bankBranch,
|
||||||
|
invoiceType: f.invoiceType,
|
||||||
agentName: f.agentName,
|
agentName: f.agentName,
|
||||||
agentEmail: f.agentEmail,
|
agentEmail: f.agentEmail,
|
||||||
agentPhone: f.agentPhone,
|
agentPhone: f.agentPhone,
|
||||||
@@ -256,6 +340,12 @@ function fill(data: any) {
|
|||||||
f.contactPhone = data.contactPhone || ''
|
f.contactPhone = data.contactPhone || ''
|
||||||
f.contactEmail = data.contactEmail || ''
|
f.contactEmail = data.contactEmail || ''
|
||||||
f.address = data.address || ''
|
f.address = data.address || ''
|
||||||
|
// 兼容后端列名风格(bank_account_name)与 Java 属性风格(bankAccountName)两种回显键
|
||||||
|
f.bankAccountName = data.bankAccountName ?? data.bank_account_name ?? ''
|
||||||
|
f.bankAccountNo = data.bankAccountNo ?? data.bank_account_no ?? ''
|
||||||
|
f.bankName = data.bankName ?? data.bank_name ?? ''
|
||||||
|
f.bankBranch = data.bankBranch ?? data.bank_branch ?? ''
|
||||||
|
f.invoiceType = data.invoiceType ?? data.invoice_type ?? ''
|
||||||
f.agentName = data.agentName || ''
|
f.agentName = data.agentName || ''
|
||||||
f.idCardNo = data.idCardNo || ''
|
f.idCardNo = data.idCardNo || ''
|
||||||
f.agentEmail = data.agentEmail || ''
|
f.agentEmail = data.agentEmail || ''
|
||||||
|
|||||||
@@ -109,6 +109,12 @@ const form = ref<Record<string, any>>({
|
|||||||
address: '',
|
address: '',
|
||||||
contactPhone: '',
|
contactPhone: '',
|
||||||
contactEmail: '',
|
contactEmail: '',
|
||||||
|
bankAccountName: '',
|
||||||
|
bankAccountNo: '',
|
||||||
|
bankName: '',
|
||||||
|
bankBranch: '',
|
||||||
|
// 发票类型:单选、无默认值(未选时提交被拦截)
|
||||||
|
invoiceType: '',
|
||||||
agentName: '',
|
agentName: '',
|
||||||
idCardNo: '',
|
idCardNo: '',
|
||||||
agentEmail: '',
|
agentEmail: '',
|
||||||
|
|||||||
@@ -62,6 +62,12 @@ const form = ref<Record<string, any>>({
|
|||||||
contactPhone: '',
|
contactPhone: '',
|
||||||
contactEmail: '',
|
contactEmail: '',
|
||||||
address: '',
|
address: '',
|
||||||
|
bankAccountName: '',
|
||||||
|
bankAccountNo: '',
|
||||||
|
bankName: '',
|
||||||
|
bankBranch: '',
|
||||||
|
// 发票类型:单选、无默认值(未选时提交被拦截)
|
||||||
|
invoiceType: '',
|
||||||
agentName: '',
|
agentName: '',
|
||||||
idCardNo: '',
|
idCardNo: '',
|
||||||
agentEmail: '',
|
agentEmail: '',
|
||||||
|
|||||||
Reference in New Issue
Block a user