| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082 |
- <template>
- <div class="p-4">
- <!-- 企业基本信息 -->
- <el-card shadow="never" class="mb-4">
- <template #header>
- <div class="flex justify-between items-center">
- <span class="font-medium">企业基本信息 </span>
- <el-button v-if="!isViewMode" type="primary" style="float: right" @click="handleSave">保存</el-button>
- <!-- <span class="font-medium"
- >企业基本信息 / <span style="color: #ff0033">客户编号:{{ customerNumber }}</span></span
- > -->
- </div>
- </template>
- <el-form ref="formRef" :model="form" :rules="rules" label-width="140px">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="所属公司" prop="belongCompanyId">
- <el-select
- v-model="form.belongCompanyId"
- placeholder="请选择所属公司"
- class="w-full"
- filterable
- @change="handCompanyChange"
- :disabled="isViewMode"
- >
- <el-option v-for="item in companyList" :key="item.id" :label="`${item.companyCode} , ${item.companyName}`" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="客户名称" prop="customerName">
- <el-input v-model="form.customerName" placeholder="请输入客户名称" :disabled="isViewMode"> </el-input>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="工商名称" prop="businessCustomerName">
- <el-input v-model="form.businessCustomerName" placeholder="请输入工商名称" @blur="selectBusinessBtn" :disabled="isViewMode"> </el-input>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="企业简称" prop="shortName">
- <el-input v-model="form.shortName" placeholder="请输入企业简称" :disabled="isViewMode" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="开票类型" prop="invoiceTypeId">
- <el-select v-model="form.invoiceTypeId" placeholder="请选择开票类型" class="w-full" :disabled="isViewMode">
- <el-option
- v-for="item in invoiceTypeList"
- :key="item.id"
- :label="`${item.invoiceTypeNo} , ${item.invoiceTypeName}`"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="企业规模" prop="enterpriseScaleId">
- <el-select v-model="form.enterpriseScaleId" placeholder="请选择企业规模" class="w-full" filterable :disabled="isViewMode">
- <el-option
- v-for="item in enterpriseScaleList"
- :key="item.id"
- :label="`${item.enterpriseScaleCode} , ${item.enterpriseScaleName}`"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="客户类别" prop="customerTypeId">
- <el-select v-model="form.customerTypeId" placeholder="请选择客户类别" class="w-full" filterable :disabled="isViewMode">
- <el-option v-for="item in customerTypeList" :key="item.id" :label="`${item.typeCode} , ${item.typeName}`" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="行业类别" prop="industryCategoryId">
- <el-select v-model="form.industryCategoryId" placeholder="请选择行业类别" class="w-full" filterable :disabled="isViewMode">
- <el-option
- v-for="item in industryCategoryList"
- :key="item.id"
- :label="`${item.industryCode} , ${item.industryCategoryName}`"
- :value="item.id"
- />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="客户等级" prop="customerLevelId">
- <el-select v-model="form.customerLevelId" placeholder="请选择客户等级" class="w-full" filterable :disabled="isViewMode">
- <el-option v-for="item in customerLevelList" :key="item.id" :label="`${item.levelCode} , ${item.levelName}`" :value="item.id" />
- </el-select>
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="固定电话" prop="landline">
- <el-input v-model="form.landline" placeholder="请输入固定电话" :disabled="isViewMode" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="传真" prop="fax">
- <el-input v-model="form.fax" placeholder="请输入传真" :disabled="isViewMode" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="网址" prop="url">
- <el-input v-model="form.url" placeholder="请输入网址" :disabled="isViewMode" />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="邮政编码" prop="postCode">
- <el-input v-model="form.postCode" placeholder="请输入邮政编码" :disabled="isViewMode" />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="开始时间" prop="validityFromDate">
- <el-date-picker
- v-model="form.validityFromDate"
- type="date"
- placeholder="请选择开始时间"
- class="w-full"
- value-format="YYYY-MM-DD"
- style="width: 100%"
- :disabled="isViewMode"
- />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="结束时间" prop="validityToDate">
- <el-date-picker
- v-model="form.validityToDate"
- type="date"
- placeholder="请选择结束时间"
- class="w-full"
- value-format="YYYY-MM-DD"
- style="width: 100%"
- :disabled-date="(time) => form.validityFromDate && time.getTime() < new Date(form.validityFromDate).getTime()"
- :disabled="isViewMode"
- />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <!-- <el-col :span="8">
- <el-form-item label="发票抬头" prop="invoiceTop">
- <el-input v-model="form.invoiceTop" placeholder="请输入发票抬头" disabled />
- </el-form-item>
- </el-col> -->
- <el-col :span="8">
- <el-form-item label="详细地址" prop="address">
- <el-cascader
- v-model="codeArr"
- :options="regionData as any"
- placeholder="请选择"
- @change="handleChange"
- style="width: 100%"
- :disabled="isViewMode"
- ></el-cascader>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label-width="0">
- <el-input v-model="form.address" placeholder="请输入详细地址" :disabled="isViewMode" />
- </el-form-item>
- </el-col>
- </el-row>
- </el-form>
- </el-card>
- <!-- 工商信息 -->
- <el-card shadow="never" class="mb-4">
- <template #header>
- <div class="flex justify-between items-center">
- <span class="font-medium">工商信息</span>
- </div>
- </template>
- <el-form :model="businessInfo" label-width="140px">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="企业工商名称">
- <el-input v-model="businessInfo.businessCustomerName" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="社会信用代码">
- <el-input v-model="businessInfo.socialCreditCode" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="法人姓名">
- <el-input v-model="businessInfo.legalPersonName" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="注册资本">
- <el-input v-model="businessInfo.registeredCapital" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="登记机关">
- <el-input v-model="businessInfo.registrationAuthority" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="成立日期">
- <el-input v-model="businessInfo.establishmentDate" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="吊销日期">
- <el-input v-model="businessInfo.revocationDate" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="登记状态">
- <el-input v-model="businessInfo.registrationStatus" disabled />
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="实缴资本">
- <el-input v-model="businessInfo.paidInCapital" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <el-col :span="16">
- <el-form-item label="详细地址">
- <el-input v-model="businessInfo.businessAddress" disabled />
- </el-form-item>
- </el-col>
- </el-row>
- <el-row :gutter="20">
- <!-- <el-col :span="24">
- <el-form-item label="营业执照">
- <div
- v-if="!businessInfo.businessLicense"
- class="upload-box"
- @click="businessLicenseSelectorVisible = true"
- style="
- width: 360px;
- height: 200px;
- border: 2px dashed #d9d9d9;
- border-radius: 4px;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: pointer;
- transition: all 0.3s;
- "
- >
- <div style="text-align: center; color: #8c939d">
- <el-icon :size="40" style="margin-bottom: 8px">
- <Plus />
- </el-icon>
- <div style="font-size: 14px">点击上传</div>
- </div>
- </div>
- <div v-else style="position: relative; display: inline-block">
- <el-image
- :src="businessInfo.businessLicense"
- style="width: 360px; height: 200px"
- fit="contain"
- :preview-src-list="[businessInfo.businessLicense]"
- />
- <el-button
- type="danger"
- :icon="Delete"
- circle
- size="small"
- style="position: absolute; top: 5px; right: 5px"
- @click="businessInfo.businessLicense = ''"
- />
- </div>
- </el-form-item>
- </el-col> -->
- </el-row>
- </el-form>
- </el-card>
- <!-- 公司开票信息 -->
- <el-card shadow="never" class="mb-4">
- <template #header>
- <div class="flex justify-between items-center">
- <span class="font-medium">企业开票信息</span>
- <el-button v-if="!isViewMode" type="primary" @click="handleAddInvoice">新增</el-button>
- </div>
- </template>
- <el-table :data="invoiceList" border>
- <el-table-column type="index" label="序号" align="center" width="60" />
- <el-table-column label="是否主账号" align="center" prop="isPrimaryAccount" min-width="120">
- <template #default="{ row }">
- <span>{{ row.isPrimaryAccount === '0' ? '是' : '否' }}</span>
- </template>
- </el-table-column>
- <el-table-column label="开户行名称" align="center" prop="bankName" min-width="180" />
- <el-table-column label="银行账户" align="center" prop="bankAccount" min-width="180" />
- <el-table-column v-if="!isViewMode" label="操作" align="center" width="150" fixed="right">
- <template #default="{ row, $index }">
- <el-button link type="primary" @click="handleEditInvoice(row, $index)">编辑</el-button>
- <el-button link type="danger" @click="removeInvoice(row)">删除</el-button>
- </template>
- </el-table-column>
- </el-table>
- </el-card>
- <el-card shadow="never" class="mb-4">
- <template #header>
- <el-row :gutter="10" class="mb8" type="flex" justify="space-between" align="middle">
- <span style="font-size: 16px; font-weight: 500">销售信息</span>
- </el-row>
- </template>
- <el-form ref="salesFormRef" :model="form" label-width="140px">
- <el-row :gutter="20">
- <el-col :span="8">
- <el-form-item label="业务人员" prop="salesPersonId">
- <el-select
- v-model="form.salesPersonId"
- placeholder="请选择业务人员"
- class="w-full"
- filterable
- @change="handleSalesPersonChange"
- :disabled="isViewMode"
- >
- <el-option v-for="item in comStaffList" :key="item.staffId" :label="`${item.staffCode} , ${item.staffName}`" :value="item.staffId" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="客服人员" prop="serviceStaffId">
- <el-select v-model="form.serviceStaffId" placeholder="请选择客服人员" class="w-full" filterable :disabled="isViewMode">
- <el-option v-for="item in comStaffList" :key="item.staffId" :label="`${item.staffCode} , ${item.staffName}`" :value="item.staffId" />
- </el-select>
- </el-form-item>
- </el-col>
- <el-col :span="8">
- <el-form-item label="所属部门" prop="belongingDepartmentId">
- <el-input v-model="deptName" placeholder="请选择所属部门" class="w-full" disabled />
- </el-form-item>
- </el-col>
- </el-row> </el-form
- ></el-card>
- <!-- 添加/编辑开票信息对话框 -->
- <add-invoice-dialog v-model="invoiceDialogVisible" :edit-data="currentInvoice" @confirm="handleInvoiceConfirm" />
- <!-- 营业执照选择器对话框 -->
- <FileSelector
- v-model="businessLicenseSelectorVisible"
- title="选择营业执照"
- :allowed-types="[1]"
- :multiple="false"
- :allow-upload="true"
- @confirm="handleBusinessLicenseSelected"
- />
- </div>
- </template>
- <script setup lang="ts" name="BaseInfo">
- import { getCustomerInfo, updateCustomerInfo } from '@/api/customer/customerFile/customerInfo';
- import type { CustomerInfoForm } from '@/api/customer/customerFile/customerInfo/types';
- import type { BusinessInfoForm } from '@/api/customer/customerFile/businessInfo/types';
- import type { InvoiceInfoForm } from '@/api/customer/customerFile/invoiceInfo/types';
- import { listInvoiceInfo, getInvoiceInfo, addInvoiceInfo, updateInvoiceInfo, delInvoiceInfo } from '@/api/customer/customerFile/invoiceInfo';
- import { listSettlementMethod } from '@/api/customer/settlementMethod';
- import { SettlementMethodVO } from '@/api/customer/settlementMethod/types';
- import { listCustomerLevel } from '@/api/customer/customerLevel';
- import { CustomerLevelVO } from '@/api/customer/customerLevel/types';
- import { listCustomerType } from '@/api/customer/customerType';
- import { CustomerTypeVO, CustomerTypeQuery } from '@/api/customer/customerType/types';
- import { getBusinessInfoBycustomerName } from '@/api/customer/customerFile/businessInfo';
- import { listCreditLevel } from '@/api/customer/creditLevel';
- import { CreditLevelVO, CreditLevelQuery } from '@/api/customer/creditLevel/types';
- import AddInvoiceDialog from '../components/addInvoiceDialog.vue';
- import { regionData } from 'element-china-area-data';
- import { listEnterpriseScale } from '@/api/customer/customerCategory/enterpriseScale';
- import { listIndustryCategory } from '@/api/customer/customerCategory/industryCategory';
- import { listInvoiceType } from '@/api/customer/invoiceType';
- import type { EnterpriseScaleVO } from '@/api/customer/customerCategory/enterpriseScale/types';
- import type { IndustryCategoryVO } from '@/api/customer/customerCategory/industryCategory/types';
- import type { InvoiceTypeVO } from '@/api/customer/invoiceType/types';
- import { listCompany } from '@/api/company/company';
- import { CompanyVO } from '@/api/company/company/types';
- import { listComStaff } from '@/api/company/comStaff';
- import { listErpStaff } from '@/api/erpData/erpStaff';
- import { ComStaffVO, ComStaffQuery } from '@/api/company/comStaff/types';
- import { ErpStaffVO } from '@/api/erpData/erpStaff/types';
- import { listDept, getDept } from '@/api/system/dept';
- import { DeptVO } from '@/api/system/dept/types';
- import { listErpDept, getErpDept } from '@/api/erpData/erpDept';
- import { ErpDeptVO } from '@/api/erpData/erpDept/types';
- import FileSelector from '@/components/FileSelector/index.vue';
- import { Plus, Delete } from '@element-plus/icons-vue';
- import { listComCurrency } from '@/api/company/comCurrency';
- import { listTaxrate } from '@/api/company/taxrate';
- import { ComCurrencyVO } from '@/api/company/comCurrency/types';
- const { proxy } = getCurrentInstance() as ComponentInternalInstance;
- const { order_check_way, customer_type, customer_level, customer_source, sell_channel, erp_is_enabled } = toRefs<any>(
- proxy?.useDict('order_check_way', 'customer_type', 'customer_level', 'customer_source', 'sell_channel', 'erp_is_enabled')
- );
- // 接收父组件传递的props
- const props = defineProps<{
- customerId?: string | number;
- customerNo?: string;
- }>();
- const route = useRoute();
- const router = useRouter();
- // 查看模式
- const isViewMode = computed(() => route.query.status === 'view');
- const unitPriceArr = ref([
- { label: '含税', value: 'True' },
- { label: '不含税', value: 'False' }
- ]);
- const formRef = ref<any>(null);
- const salesFormRef = ref<any>(null);
- const submitLoading = ref(false);
- const custId = ref<string | number>('');
- const customerNumber = ref('');
- const codeArr = ref([]);
- // 下拉框数据列表
- const enterpriseScaleList = ref<EnterpriseScaleVO[]>([]);
- const industryCategoryList = ref<IndustryCategoryVO[]>([]);
- const invoiceTypeList = ref<InvoiceTypeVO[]>([]);
- const companyList = ref<CompanyVO[]>([]);
- const settlementMethodList = ref<SettlementMethodVO[]>([]);
- const creditLevelList = ref<CreditLevelVO[]>([]);
- const customerLevelList = ref<CustomerLevelVO[]>([]);
- const customerTypeList = ref<CustomerTypeVO[]>([]);
- const comStaffList = ref<ErpStaffVO[]>([]);
- const comDeptList = ref<ErpDeptVO[]>([]);
- const currencyList = ref<ComCurrencyVO[]>([]);
- const taxrateList = ref<any[]>([]);
- // 企业基本信息(用于显示)
- const customerInfo = reactive<any>({
- customerNo: '',
- belongCompanyName: '',
- companyName: '',
- businessCustomerName: '',
- shortName: '',
- invoiceTypeName: '',
- enterpriseScale: '',
- customerTypeName: '',
- industryCategory: '',
- customerLevelName: '',
- landline: '',
- fax: '',
- url: '',
- postCode: '',
- validityFromDate: '',
- validityToDate: '',
- invoiceTop: '',
- provincialCityCounty: '',
- address: ''
- });
- // 企业基本信息表单(用于编辑)
- const form = reactive<CustomerInfoForm>({
- id: undefined,
- customerNo: '',
- belongCompanyId: undefined,
- companyName: '',
- businessCustomerName: '',
- shortName: '',
- invoiceTypeId: undefined,
- enterpriseScaleId: undefined,
- customerTypeId: undefined,
- industryCategoryId: undefined,
- customerLevelId: undefined,
- landline: '',
- fax: '',
- url: '',
- postCode: '',
- validityFromDate: undefined,
- validityToDate: undefined,
- invoiceTop: '',
- address: '',
- regProvincialNo: '',
- regCityNo: '',
- regCountyNo: '',
- provincialCityCounty: '',
- status: '0',
- remark: '',
- salesPersonId: undefined,
- serviceStaffId: undefined,
- belongingDepartmentId: undefined
- });
- // 工商信息(只读)
- const businessInfo = reactive<BusinessInfoForm>({
- businessCustomerName: '',
- socialCreditCode: '',
- legalPersonName: '',
- registeredCapital: '',
- registrationAuthority: '',
- establishmentDate: '',
- revocationDate: '',
- registrationStatus: '',
- paidInCapital: undefined,
- businessAddress: '',
- businessLicense: '',
- status: '0'
- });
- // 开票信息列表
- const invoiceList = ref<InvoiceInfoForm[]>([]);
- const invoiceDialogVisible = ref(false);
- const currentInvoice = ref<InvoiceInfoForm | undefined>(undefined);
- const currentInvoiceIndex = ref<number>(-1);
- // 营业执照上传相关
- const uploadRef = ref();
- const uploadLoading = ref(false);
- const businessLicenseSelectorVisible = ref(false);
- const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/common/upload';
- const uploadHeaders = ref({
- Authorization: 'Bearer ' + localStorage.getItem('token')
- });
- // 打开添加开票信息对话框
- const handleAddInvoice = () => {
- currentInvoice.value = {};
- currentInvoice.value.taxId = businessInfo.socialCreditCode;
- currentInvoice.value.address = businessInfo.businessAddress;
- currentInvoiceIndex.value = -1;
- invoiceDialogVisible.value = true;
- };
- // 更新工商信息
- const handleUpdate = () => {
- // 触发上传
- uploadRef.value?.$el.querySelector('input[type="file"]')?.click();
- };
- // 上传前验证
- const beforeUpload = (file: File) => {
- const isImage = file.type.startsWith('image/');
- const isPDF = file.type === 'application/pdf';
- const isLt10M = file.size / 1024 / 1024 < 10;
- if (!isImage && !isPDF) {
- ElMessage.error('只能上传图片或PDF文件!');
- return false;
- }
- if (!isLt10M) {
- ElMessage.error('文件大小不能超过 10MB!');
- return false;
- }
- uploadLoading.value = true;
- return true;
- };
- // 处理业务人员选择变化
- const handleSalesPersonChange = async (staffId: any) => {
- // 根据选中的业务人员ID,找到对应的部门ID
- const selectedStaff = comStaffList.value.find((staff) => staff.staffId === staffId);
- if (selectedStaff && selectedStaff.deptId) {
- // 确保 deptId 的类型一致
- form.belongingDepartmentId = String(selectedStaff.deptId);
- // 如果部门不在列表中,从API获取
- const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(selectedStaff.deptId));
- if (!deptExists) {
- try {
- const res = await getDept(selectedStaff.deptId);
- if (res.data) {
- comDeptList.value.push(res.data as any);
- }
- } catch (error) {
- console.error('获取部门信息失败:', error);
- }
- }
- }
- };
- // 上传成功回调
- const handleUploadSuccess = (response: any) => {
- uploadLoading.value = false;
- if (response.code === 200) {
- businessInfo.businessLicense = response.data.url || response.data.fileName;
- ElMessage.success('上传成功');
- // TODO: 这里可以调用OCR识别接口,自动填充工商信息
- // 如果后端提供了OCR识别接口,可以在这里调用
- // recognizeBusinessLicense(response.data.url);
- } else {
- ElMessage.error(response.msg || '上传失败');
- }
- };
- // 上传失败回调
- const handleUploadError = () => {
- uploadLoading.value = false;
- ElMessage.error('上传失败,请重试');
- };
- // 预览营业执照
- const previewLicense = () => {
- if (businessInfo.businessLicense) {
- window.open(businessInfo.businessLicense, '_blank');
- }
- };
- // 营业执照选择处理
- const handleBusinessLicenseSelected = (files: any[]) => {
- if (files && files.length > 0) {
- const file = files[0]; // 取第一个文件
- if (file && (file.url || file.path)) {
- businessInfo.businessLicense = file.url || file.path;
- ElMessage.success('营业执照选择成功');
- } else {
- ElMessage.error('请选择有效的图片文件');
- }
- } else {
- ElMessage.error('请选择有效的图片文件');
- }
- };
- // 表单验证规则
- const rules = {
- belongCompanyId: [{ required: true, message: '请选择所属公司', trigger: 'change' }],
- customerName: [{ required: true, message: '请输入客户名称', trigger: 'blur' }],
- businessCustomerName: [
- { required: true, message: '请输入工商名称', trigger: 'blur' },
- {
- // 允许:中文 + 常见标点 (括号、中圆点、横杠)
- // 禁止:数字、字母、空格、@#$%等其他符号
- pattern: /^[\u4e00-\u9fa5()()·\-]+$/,
- message: '名称不能包含数字、字母或特殊符号,仅限中文及常用标点',
- trigger: 'blur'
- }
- ],
- shortName: [{ required: true, message: '请输入企业简称', trigger: 'blur' }],
- invoiceTypeId: [{ required: true, message: '请选择开票类型', trigger: 'change' }],
- enterpriseScaleId: [{ required: true, message: '请选择企业规模', trigger: 'change' }],
- customerTypeId: [{ required: true, message: '请选择客户类别', trigger: 'change' }],
- industryCategoryId: [{ required: true, message: '请选择行业类别', trigger: 'change' }],
- customerLevelId: [{ required: true, message: '请选择客户等级', trigger: 'change' }],
- address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }]
- // salesPersonId: [{ required: true, message: '请选择业务人员', trigger: 'change' }],
- // serviceStaffId: [{ required: true, message: '请选择客服人员', trigger: 'change' }]
- };
- // 初始化
- onMounted(async () => {
- // 加载下拉框数据
- await loadEnterpriseScaleList();
- await loadIndustryCategoryList();
- await loadInvoiceTypeList();
- await loadCompanyList();
- await loadSettlementMethodList();
- await loadCreditLevelList();
- await loadCustomerLevelList();
- await loadCustomerTypeList();
- await loadComStaffList();
- await loadComDeptList();
- // 优先使用props传递的customerId,否则从路由获取
- const id = props.customerId || route.query.id;
- if (id) {
- custId.value = id as string;
- await loadCustomerData(id as any);
- }
- });
- const handCompanyChange = async (val) => {
- try {
- try {
- // 1. 处理清空情况
- if (!val) {
- form.companyName = '';
- return;
- }
- // 2. 在本地列表中查找完整对象
- const selectedCompany = companyList.value.find((item) => item.id === val);
- if (selectedCompany) {
- // 3. 赋值操作
- form.companyName = selectedCompany.companyName;
- } else {
- // 如果本地列表没找到(可能是数据不同步),可以选择清空或调用接口查询
- form.companyName = '';
- }
- } catch (error) {}
- } catch (error) {}
- };
- // 监听props变化
- watch(
- () => props.customerId,
- (newId) => {
- if (newId) {
- custId.value = newId;
- loadCustomerData(newId);
- }
- }
- );
- const selectBusinessBtn = async () => {
- try {
- // 验证基本信息表单
- await formRef.value.validateField('businessCustomerName');
- const res = await getBusinessInfoBycustomerName(form.businessCustomerName);
- const data = res.data;
- // 填充信息
- Object.assign(businessInfo, data);
- form.invoiceTop = data.businessCustomerName;
- form.businessCustomerName = data.businessCustomerName;
- } catch (error) {
- // ElMessage.error('查询工商信息失败');
- }
- };
- // 加载企业规模列表
- const loadEnterpriseScaleList = async () => {
- try {
- const res = await listEnterpriseScale({ dataSource: 'A10' } as any);
- enterpriseScaleList.value = res.rows || [];
- } catch (error) {
- console.error('加载企业规模列表失败:', error);
- }
- };
- // 加载行业类别列表
- const loadIndustryCategoryList = async () => {
- try {
- const res = await listIndustryCategory({ dataSource: 'A10' } as any);
- industryCategoryList.value = res.rows || [];
- } catch (error) {
- console.error('加载行业类别列表失败:', error);
- }
- };
- // 加载开票类型列表
- const loadInvoiceTypeList = async () => {
- try {
- const res = await listInvoiceType({ dataSource: 'A10' } as any);
- invoiceTypeList.value = res.rows || [];
- } catch (error) {
- console.error('加载开票类型列表失败:', error);
- }
- };
- // 加载公司列表
- const loadCompanyList = async () => {
- try {
- const query: any = { isShow: '0', dataSource: 'A10' };
- const res = await listCompany(query);
- companyList.value = res.rows || [];
- } catch (error) {
- console.error('加载公司列表失败:', error);
- }
- };
- // 加载结算方式列表
- const loadSettlementMethodList = async () => {
- try {
- const query: any = { isShow: '0' };
- const res = await listSettlementMethod(query);
- settlementMethodList.value = res.rows || [];
- } catch (error) {
- console.error('加载结算方式列表失败:', error);
- }
- };
- // 加载信用等级列表
- const loadCreditLevelList = async () => {
- try {
- const query: any = { dataSource: 'A10' };
- const res = await listCreditLevel(query);
- creditLevelList.value = res.rows || [];
- } catch (error) {
- console.error('加载信用等级列表失败:', error);
- }
- };
- // 加载客户等级列表
- const loadCustomerLevelList = async () => {
- try {
- const res = await listCustomerLevel({ dataSource: 'A10' } as any);
- customerLevelList.value = res.rows || [];
- } catch (error) {
- console.error('加载客户等级列表失败:', error);
- }
- };
- // 加载客户类别列表
- const loadCustomerTypeList = async () => {
- try {
- const res = await listCustomerType({ dataSource: 'A10' } as any);
- customerTypeList.value = res.rows || [];
- } catch (error) {
- console.error('加载客户类别列表失败:', error);
- }
- };
- // 加载员工列表
- const loadComStaffList = async () => {
- try {
- const query: any = {};
- const res = await listComStaff(query);
- comStaffList.value = res.rows || [];
- } catch (error) {
- console.error('加载员工列表失败:', error);
- }
- };
- // 加载部门列表
- const loadComDeptList = async () => {
- try {
- const res = await listDept();
- // 处理可能的不同返回结构
- comDeptList.value = res.rows || res.data || [];
- } catch (error) {
- console.error('加载部门列表失败:', error);
- }
- };
- // 加载客户数据
- const loadCustomerData = async (id: any) => {
- try {
- const res = await getCustomerInfo(id);
- const data = res.data;
- // 填充基本信息
- customerInfo.customerNo = data.customerNo || '';
- customerInfo.belongCompanyName = getCompanyName(data.belongCompanyId);
- customerInfo.companyName = data.companyName || '';
- customerInfo.businessCustomerName = data.businessCustomerName || '';
- customerInfo.shortName = data.shortName || '';
- customerInfo.invoiceTypeName = getInvoiceTypeName(data.invoiceTypeId);
- customerInfo.enterpriseScale = data.enterpriseScale || '';
- customerInfo.customerTypeName = getCustomerTypeName(data.customerTypeId);
- customerInfo.industryCategory = data.industryCategory || '';
- customerInfo.customerLevelName = getCustomerLevelName(data.customerLevelId);
- customerInfo.landline = data.landline || '';
- customerInfo.fax = data.fax || '';
- customerInfo.url = data.url || '';
- customerInfo.postCode = data.postCode || '';
- customerInfo.validityFromDate = data.validityFromDate || '';
- customerInfo.validityToDate = data.validityToDate || '';
- customerInfo.invoiceTop = data.invoiceTop || '';
- customerInfo.provincialCityCounty = data.provincialCityCounty || '';
- customerInfo.address = data.address || '';
- // 填充工商信息
- if (data.customerBusinessInfoVo) {
- Object.assign(businessInfo, data.customerBusinessInfoVo);
- }
- // 填充表单数据(用于编辑)
- Object.assign(form, data);
- customerNumber.value = data.customerNo || '';
- // 如果有省市区编码,回显到级联选择器
- if (data.regProvincialNo && data.regCityNo && data.regCountyNo) {
- codeArr.value = [data.regProvincialNo, data.regCityNo, data.regCountyNo] as any;
- }
- // 填充开票信息列表
- loadInvoiceList(id);
- } catch (error) {
- console.error('加载客户数据失败:', error);
- ElMessage.error('加载客户数据失败');
- }
- };
- // 格式化方法
- const getCompanyName = (id: string | number | undefined) => {
- const map: Record<string, string> = { '1': '公司A', '2': '公司B', '3': '公司C' };
- return map[String(id)] || '-';
- };
- const getInvoiceTypeName = (id: string | number | undefined) => {
- const map: Record<string, string> = {
- '1': '增值税专用发票',
- '2': '增值税普通发票',
- '3': '电子发票'
- };
- return map[String(id)] || '-';
- };
- const getCustomerTypeName = (id: string | number | undefined) => {
- const map: Record<string, string> = {
- '1': '重点客户',
- '2': '普通客户',
- '3': '潜在客户'
- };
- return map[String(id)] || '-';
- };
- const getCustomerLevelName = (id: string | number | undefined) => {
- const map: Record<string, string> = { '1': 'A级', '2': 'B级', '3': 'C级', '4': 'D级' };
- return map[String(id)] || '-';
- };
- // 部门名称(响应式)
- const deptName = ref('');
- // 处理区域选择变化
- const handleChange = (val: string[]) => {
- // 保存编码
- form.regProvincialNo = val[0];
- form.regCityNo = val[1];
- form.regCountyNo = val[2];
- // 根据编码获取名称
- const names: string[] = [];
- if (val[0]) {
- const province = regionData.find((item: any) => item.value === val[0]);
- if (province) {
- names.push(province.label);
- if (val[1] && province.children) {
- const city = province.children.find((item: any) => item.value === val[1]);
- if (city) {
- names.push(city.label);
- if (val[2] && city.children) {
- const county = city.children.find((item: any) => item.value === val[2]);
- if (county) {
- names.push(county.label);
- }
- }
- }
- }
- }
- }
- // 将省市区名称用斜杠连接
- form.provincialCityCounty = names.join('/');
- };
- // 编辑开票信息
- const handleEditInvoice = (row: InvoiceInfoForm, index: number) => {
- currentInvoice.value = { ...row };
- currentInvoiceIndex.value = index;
- invoiceDialogVisible.value = true;
- };
- // 确认添加/编辑开票信息
- const handleInvoiceConfirm = (data: InvoiceInfoForm) => {
- // if (currentInvoiceIndex.value >= 0) {
- // // 编辑
- // invoiceList.value[currentInvoiceIndex.value] = data;
- // } else {
- // // 新增
- // invoiceList.value.push(data);
- // }
- data.customerId = custId.value;
- if (data.id) {
- updateInvoiceInfo(data).then(() => {
- ElMessage.success('修改成功');
- // 刷新列表
- loadInvoiceList(custId.value);
- });
- } else {
- addInvoiceInfo(data).then(() => {
- ElMessage.success('保存成功');
- // 刷新列表
- loadInvoiceList(custId.value);
- });
- }
- };
- const loadInvoiceList = (customerId: string | number) => {
- const params = {
- customerId,
- pageNum: 1,
- pageSize: 50
- };
- listInvoiceInfo(params).then((res) => {
- invoiceList.value = res.rows;
- });
- };
- // 删除开票信息
- const removeInvoice = (data: any) => {
- ElMessageBox.confirm('确定要删除该开票信息吗?', '提示', {
- confirmButtonText: '确定',
- cancelButtonText: '取消',
- type: 'warning'
- })
- .then(() => {
- delInvoiceInfo(data.id).then(() => {
- loadInvoiceList(custId.value);
- });
- ElMessage.success('删除成功');
- })
- .catch(() => {});
- };
- // 保存按钮
- const handleSave = async () => {
- try {
- await formRef.value.validate();
- submitLoading.value = true;
- const submitData: CustomerInfoForm = {
- ...form,
- customerBusinessBo: businessInfo,
- customerInvoiceInfoBoList: invoiceList.value
- };
- await updateCustomerInfo(submitData);
- ElMessage.success('保存成功');
- // 重新加载数据
- await loadCustomerData(custId.value);
- } catch (error) {
- const isValidationError = error && typeof error === 'object' && 'fields' in error;
- if (isValidationError) {
- console.warn('表单验证未通过', error);
- return;
- }
- ElMessage.error('保存失败,请稍后重试或联系管理员');
- } finally {
- submitLoading.value = false;
- }
- };
- // 监听部门ID变化,自动加载部门名称
- watch(
- () => form.belongingDepartmentId,
- async (newDeptId) => {
- if (!newDeptId) {
- deptName.value = '';
- return;
- }
- // 先从列表中查找
- const dept = comDeptList.value.find((d) => String(d.deptId) === String(newDeptId));
- if (dept) {
- deptName.value = dept.deptName;
- return;
- }
- // 如果列表中没有,从API获取
- try {
- const res = await getDept(newDeptId);
- if (res.data) {
- deptName.value = res.data.deptName;
- comDeptList.value.push(res.data as any);
- }
- } catch (error) {
- console.error('获取部门信息失败:', error);
- deptName.value = String(newDeptId);
- }
- },
- { immediate: true }
- );
- </script>
- <style scoped>
- .upload-box:hover {
- border-color: #409eff !important; /* 鼠标悬停时变蓝 */
- }
- </style>
|