feat: 新增企业客户新增/编辑/查看表单页
parent
3e3a2097a3
commit
801cadbcc4
|
|
@ -0,0 +1,275 @@
|
|||
<!-- src/views/customer/enterprise/EnterpriseForm.vue -->
|
||||
<template>
|
||||
<div class="enterprise-customer-form-page">
|
||||
<a-page-header :title="pageTitle" @back="goBack" />
|
||||
<a-card>
|
||||
<a-form ref="formRef" layout="vertical" :model="form" :rules="rules" :disabled="isDetail">
|
||||
<a-form-item v-if="!isDetail" label="所属渠道" required>
|
||||
<ChannelSelect v-model:model-value="channelNo" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="营业执照照片">
|
||||
<LicenseUpload :channel-no="channelNo" v-model:file-no="form.businessLicenseFileNo" />
|
||||
<div v-if="isEdit" class="hint">编辑模式下无法读取历史营业执照图片,如需变更请重新上传</div>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="所属机构" name="organizationId">
|
||||
<OrgTreeSelect v-model="form.organizationId" placeholder="请选择所属机构" />
|
||||
</a-form-item>
|
||||
<a-form-item label="企业名称" name="enterpriseName">
|
||||
<a-input v-model:value="form.enterpriseName" placeholder="请输入企业名称" />
|
||||
</a-form-item>
|
||||
<a-form-item label="证件类型">
|
||||
<a-input value="营业执照" disabled />
|
||||
</a-form-item>
|
||||
<a-form-item label="营业执照号" name="businessLicense">
|
||||
<a-input v-model:value="form.businessLicense" placeholder="请输入营业执照号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="证件生效日" name="certificateEffectiveDate">
|
||||
<a-date-picker v-model:value="effectiveDateValue" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
</a-form-item>
|
||||
<a-form-item label="证件到期日" name="certificateExpiryDate">
|
||||
<a-date-picker v-model:value="expiryDateValue" style="width: 100%" value-format="YYYY-MM-DD" />
|
||||
<div v-if="isExpired" class="expired-hint">证件已过期,请更换有效证件</div>
|
||||
</a-form-item>
|
||||
<a-form-item label="手机号码" name="mobilePhone">
|
||||
<a-input v-model:value="form.mobilePhone" placeholder="请输入11位手机号" />
|
||||
</a-form-item>
|
||||
<a-form-item label="证件地址" name="certificateAddress">
|
||||
<a-input v-model:value="form.certificateAddress" placeholder="请输入详细地址" />
|
||||
</a-form-item>
|
||||
<a-form-item label="经营范围" name="businessScope">
|
||||
<a-textarea v-model:value="form.businessScope" placeholder="请输入经营范围" :rows="3" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="法定代表人">
|
||||
<a-space>
|
||||
<span v-if="legalRepName">{{ legalRepName }}</span>
|
||||
<a-button v-if="!isDetail" @click="openLegalRepPicker">选择</a-button>
|
||||
</a-space>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-if="isCreate" label="股东高管信息">
|
||||
<a-table :columns="relatedPersonColumns" :data-source="relatedPersonList" :pagination="false" row-key="individualId">
|
||||
<template #bodyCell="{ column, record, index }">
|
||||
<template v-if="column.dataIndex === 'customerName'">{{ record.customerName }}</template>
|
||||
<template v-else-if="column.dataIndex === 'relatedType'">
|
||||
<a-select v-model:value="record.relatedType" style="width: 140px">
|
||||
<a-select-option value="SHAREHOLDER">股东</a-select-option>
|
||||
<a-select-option value="EXECUTIVE">高管</a-select-option>
|
||||
<a-select-option value="BENEFICIARY_OWNER">受益所有人</a-select-option>
|
||||
</a-select>
|
||||
</template>
|
||||
<template v-else-if="column.dataIndex === 'certificateNumber'">{{ record.certificateNumber }}</template>
|
||||
<template v-else-if="column.dataIndex === 'action'">
|
||||
<a @click="removeRelatedPerson(index)">删除</a>
|
||||
</template>
|
||||
</template>
|
||||
</a-table>
|
||||
<a-button style="margin-top: 8px" @click="openRelatedPersonPicker">添加股东/高管</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item v-else label="股东高管信息">
|
||||
<div class="hint">股东高管信息仅支持新增时登记,当前接口不支持查询或修改,如需变更请联系技术支持核实数据</div>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
|
||||
<a-space v-if="!isDetail">
|
||||
<a-button type="primary" :loading="submitting" @click="handleSubmit">提交</a-button>
|
||||
<a-button @click="goBack">取消</a-button>
|
||||
</a-space>
|
||||
</a-card>
|
||||
|
||||
<PersonalCustomerPicker ref="legalRepPickerRef" @select="handleLegalRepSelect" />
|
||||
<PersonalCustomerPicker ref="relatedPersonPickerRef" @select="handleRelatedPersonSelect" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, reactive, computed, onMounted } from 'vue'
|
||||
import { useRoute, useRouter } from 'vue-router'
|
||||
import { message } from 'ant-design-vue'
|
||||
import dayjs from 'dayjs'
|
||||
import ChannelSelect from '@/components/ChannelSelect.vue'
|
||||
import LicenseUpload from '@/components/LicenseUpload.vue'
|
||||
import OrgTreeSelect from '@/components/OrgTreeSelect.vue'
|
||||
import PersonalCustomerPicker from '@/components/PersonalCustomerPicker.vue'
|
||||
import {
|
||||
fetchEnterpriseCustomerDetailApi,
|
||||
createEnterpriseCustomerApi,
|
||||
updateEnterpriseCustomerApi
|
||||
} from '@/api/customer'
|
||||
import { fetchPersonalCustomerDetailApi } from '@/api/customer'
|
||||
import { phoneValidatorRule, businessLicenseValidatorRule } from '@/utils/validators'
|
||||
|
||||
const route = useRoute()
|
||||
const router = useRouter()
|
||||
|
||||
const mode = computed(() => route.query.mode || 'create')
|
||||
const isCreate = computed(() => mode.value === 'create')
|
||||
const isEdit = computed(() => mode.value === 'edit')
|
||||
const isDetail = computed(() => mode.value === 'detail')
|
||||
const pageTitle = computed(() => ({ create: '新增企业客户', edit: '编辑企业客户', detail: '查看企业客户' }[mode.value]))
|
||||
|
||||
const channelNo = ref(undefined)
|
||||
const submitting = ref(false)
|
||||
const formRef = ref(null)
|
||||
const legalRepName = ref('')
|
||||
const legalRepPickerRef = ref(null)
|
||||
const relatedPersonPickerRef = ref(null)
|
||||
const relatedPersonList = ref([])
|
||||
|
||||
const form = reactive({
|
||||
id: '',
|
||||
organizationId: undefined,
|
||||
enterpriseName: '',
|
||||
businessLicense: '',
|
||||
certificateEffectiveDate: '',
|
||||
certificateExpiryDate: '',
|
||||
mobilePhone: '',
|
||||
certificateAddress: '',
|
||||
businessScope: '',
|
||||
businessLicenseFileNo: '',
|
||||
legalRepresentativeId: undefined
|
||||
})
|
||||
|
||||
const effectiveDateValue = computed({
|
||||
get: () => (form.certificateEffectiveDate ? dayjs(form.certificateEffectiveDate) : undefined),
|
||||
set: (val) => (form.certificateEffectiveDate = val ? val.format('YYYY-MM-DD') : '')
|
||||
})
|
||||
const expiryDateValue = computed({
|
||||
get: () => (form.certificateExpiryDate ? dayjs(form.certificateExpiryDate) : undefined),
|
||||
set: (val) => (form.certificateExpiryDate = val ? val.format('YYYY-MM-DD') : '')
|
||||
})
|
||||
const isExpired = computed(
|
||||
() => !!form.certificateExpiryDate && dayjs(form.certificateExpiryDate).isBefore(dayjs(), 'day')
|
||||
)
|
||||
|
||||
const rules = {
|
||||
organizationId: [{ required: true, message: '请选择所属机构' }],
|
||||
enterpriseName: [{ required: true, message: '请输入企业名称' }],
|
||||
businessLicense: [businessLicenseValidatorRule()],
|
||||
mobilePhone: [phoneValidatorRule()]
|
||||
}
|
||||
|
||||
const relatedPersonColumns = [
|
||||
{ title: '客户名称', dataIndex: 'customerName' },
|
||||
{ title: '关联人类型', dataIndex: 'relatedType', width: 160 },
|
||||
{ title: '证件号码', dataIndex: 'certificateNumber' },
|
||||
{ title: '操作', dataIndex: 'action', width: 80 }
|
||||
]
|
||||
|
||||
function openLegalRepPicker() {
|
||||
legalRepPickerRef.value.show()
|
||||
}
|
||||
|
||||
function handleLegalRepSelect(record) {
|
||||
form.legalRepresentativeId = record.id
|
||||
legalRepName.value = record.customerName
|
||||
}
|
||||
|
||||
function openRelatedPersonPicker() {
|
||||
relatedPersonPickerRef.value.show()
|
||||
}
|
||||
|
||||
async function handleRelatedPersonSelect(record) {
|
||||
// IndividualCustomerListVo 不含证件生效日,需要额外查一次详情补全
|
||||
const detailRes = await fetchPersonalCustomerDetailApi({ id: record.id })
|
||||
const detail = detailRes.data.code === 200 ? detailRes.data.data : record
|
||||
relatedPersonList.value.push({
|
||||
individualId: record.id,
|
||||
customerName: record.customerName,
|
||||
relatedType: 'SHAREHOLDER',
|
||||
certificateType: detail.certificateType || 'ID_CARD',
|
||||
certificateNumber: detail.certificateNumber,
|
||||
certificateEffectiveDate: detail.certificateEffectiveDate,
|
||||
certificateExpiryDate: detail.certificateExpiryDate
|
||||
})
|
||||
}
|
||||
|
||||
function removeRelatedPerson(index) {
|
||||
relatedPersonList.value.splice(index, 1)
|
||||
}
|
||||
|
||||
async function loadDetail(id) {
|
||||
const res = await fetchEnterpriseCustomerDetailApi({ id })
|
||||
if (res.data.code === 200) {
|
||||
Object.assign(form, res.data.data)
|
||||
if (res.data.data.legalRepresentativeId) {
|
||||
const repRes = await fetchPersonalCustomerDetailApi({ id: res.data.data.legalRepresentativeId })
|
||||
if (repRes.data.code === 200) legalRepName.value = repRes.data.data.customerName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (route.query.id) {
|
||||
loadDetail(route.query.id)
|
||||
}
|
||||
})
|
||||
|
||||
function goBack() {
|
||||
router.push('/customer/enterprise')
|
||||
}
|
||||
|
||||
async function handleSubmit() {
|
||||
try {
|
||||
await formRef.value.validate()
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
submitting.value = true
|
||||
try {
|
||||
const toFullDate = (d) => (d ? `${d} 00:00:00` : undefined)
|
||||
const payload = {
|
||||
organizationId: form.organizationId,
|
||||
enterpriseName: form.enterpriseName,
|
||||
businessLicense: form.businessLicense,
|
||||
certificateType: 'BUSINESS_LICENSE',
|
||||
certificateNumber: form.businessLicense,
|
||||
certificateEffectiveDate: toFullDate(form.certificateEffectiveDate),
|
||||
certificateExpiryDate: toFullDate(form.certificateExpiryDate),
|
||||
mobilePhone: form.mobilePhone,
|
||||
certificateAddress: form.certificateAddress,
|
||||
businessScope: form.businessScope,
|
||||
businessLicenseFileNo: form.businessLicenseFileNo,
|
||||
legalRepresentativeId: form.legalRepresentativeId
|
||||
}
|
||||
let res
|
||||
if (isCreate.value) {
|
||||
const enterpriseRelatedPersonBtoList = relatedPersonList.value.map((item) => ({
|
||||
individualId: item.individualId,
|
||||
relatedType: item.relatedType,
|
||||
certificateType: item.certificateType,
|
||||
certificateNumber: item.certificateNumber,
|
||||
certificateEffectiveDate: toFullDate(item.certificateEffectiveDate),
|
||||
certificateExpiryDate: toFullDate(item.certificateExpiryDate)
|
||||
}))
|
||||
res = await createEnterpriseCustomerApi({
|
||||
createEnterpriseCustomerBto: { ...payload, enterpriseRelatedPersonBtoList },
|
||||
enableOcr: true
|
||||
})
|
||||
} else {
|
||||
res = await updateEnterpriseCustomerApi({ id: form.id, ...payload })
|
||||
}
|
||||
if (res.data.code === 200) {
|
||||
message.success(isCreate.value ? '新增成功' : '修改成功')
|
||||
goBack()
|
||||
}
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.expired-hint {
|
||||
color: #ff4d4f;
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
.hint {
|
||||
color: #999;
|
||||
font-size: 12px;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue