|
|
@@ -5,7 +5,7 @@
|
|
|
<template #header>
|
|
|
<div class="flex justify-between items-center">
|
|
|
<span class="font-medium">企业基本信息 </span>
|
|
|
- <el-button type="primary" style="float: right" @click="handleSave">保存</el-button>
|
|
|
+ <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
|
|
|
> -->
|
|
|
@@ -15,19 +15,26 @@
|
|
|
<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">
|
|
|
+ <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="请输入客户名称"> </el-input>
|
|
|
+ <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"> </el-input>
|
|
|
+ <el-input v-model="form.businessCustomerName" placeholder="请输入工商名称" @blur="selectBusinessBtn" :disabled="isViewMode"> </el-input>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -35,12 +42,12 @@
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="企业简称" prop="shortName">
|
|
|
- <el-input v-model="form.shortName" placeholder="请输入企业简称" />
|
|
|
+ <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">
|
|
|
+ <el-select v-model="form.invoiceTypeId" placeholder="请选择开票类型" class="w-full" :disabled="isViewMode">
|
|
|
<el-option
|
|
|
v-for="item in invoiceTypeList"
|
|
|
:key="item.id"
|
|
|
@@ -52,7 +59,7 @@
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="企业规模" prop="enterpriseScaleId">
|
|
|
- <el-select v-model="form.enterpriseScaleId" placeholder="请选择企业规模" class="w-full" filterable>
|
|
|
+ <el-select v-model="form.enterpriseScaleId" placeholder="请选择企业规模" class="w-full" filterable :disabled="isViewMode">
|
|
|
<el-option
|
|
|
v-for="item in enterpriseScaleList"
|
|
|
:key="item.id"
|
|
|
@@ -67,14 +74,14 @@
|
|
|
<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>
|
|
|
+ <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>
|
|
|
+ <el-select v-model="form.industryCategoryId" placeholder="请选择行业类别" class="w-full" filterable :disabled="isViewMode">
|
|
|
<el-option
|
|
|
v-for="item in industryCategoryList"
|
|
|
:key="item.id"
|
|
|
@@ -86,7 +93,7 @@
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="客户等级" prop="customerLevelId">
|
|
|
- <el-select v-model="form.customerLevelId" placeholder="请选择客户等级" class="w-full" filterable>
|
|
|
+ <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>
|
|
|
@@ -96,17 +103,17 @@
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="固定电话" prop="landline">
|
|
|
- <el-input v-model="form.landline" placeholder="请输入固定电话" />
|
|
|
+ <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="请输入传真" />
|
|
|
+ <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="请输入网址" />
|
|
|
+ <el-input v-model="form.url" placeholder="请输入网址" :disabled="isViewMode" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -114,7 +121,7 @@
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="邮政编码" prop="postCode">
|
|
|
- <el-input v-model="form.postCode" placeholder="请输入邮政编码" />
|
|
|
+ <el-input v-model="form.postCode" placeholder="请输入邮政编码" :disabled="isViewMode" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
@@ -126,6 +133,7 @@
|
|
|
class="w-full"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
style="width: 100%"
|
|
|
+ :disabled="isViewMode"
|
|
|
/>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
@@ -139,6 +147,7 @@
|
|
|
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>
|
|
|
@@ -158,12 +167,13 @@
|
|
|
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="请输入详细地址" />
|
|
|
+ <el-input v-model="form.address" placeholder="请输入详细地址" :disabled="isViewMode" />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -175,7 +185,6 @@
|
|
|
<template #header>
|
|
|
<div class="flex justify-between items-center">
|
|
|
<span class="font-medium">工商信息</span>
|
|
|
- <el-button type="primary" @click="handleUpdate">更新</el-button>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
@@ -294,7 +303,7 @@
|
|
|
<template #header>
|
|
|
<div class="flex justify-between items-center">
|
|
|
<span class="font-medium">企业开票信息</span>
|
|
|
- <el-button type="primary" @click="handleAddInvoice">新增</el-button>
|
|
|
+ <el-button v-if="!isViewMode" type="primary" @click="handleAddInvoice">新增</el-button>
|
|
|
</div>
|
|
|
</template>
|
|
|
<el-table :data="invoiceList" border>
|
|
|
@@ -306,7 +315,7 @@
|
|
|
</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 label="操作" align="center" width="150" fixed="right">
|
|
|
+ <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>
|
|
|
@@ -314,27 +323,31 @@
|
|
|
</el-table-column>
|
|
|
</el-table>
|
|
|
</el-card>
|
|
|
-
|
|
|
- <!-- 销售信息 --改为 ERP数据-->
|
|
|
<el-card shadow="never" class="mb-4">
|
|
|
<template #header>
|
|
|
- <div class="flex justify-between items-center">
|
|
|
- <span class="font-medium">ERP销售信息</span>
|
|
|
- <!-- <el-button type="primary" @click="handleSave">保存</el-button> -->
|
|
|
- </div>
|
|
|
+ <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="salesForm" :rules="salesRules" label-width="140px">
|
|
|
+ <el-form ref="salesFormRef" :model="form" label-width="140px">
|
|
|
<el-row :gutter="20">
|
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="业务人员" prop="salesPersonId" required>
|
|
|
- <el-select v-model="salesForm.salesPersonId" placeholder="请选择业务人员" class="w-full" filterable @change="handleSalesPersonChange">
|
|
|
+ <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" required>
|
|
|
- <el-select v-model="salesForm.serviceStaffId" placeholder="请选择客服人员" class="w-full" filterable>
|
|
|
+ <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>
|
|
|
@@ -344,131 +357,8 @@
|
|
|
<el-input v-model="deptName" placeholder="请选择所属部门" class="w-full" disabled />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="信用等级" prop="creditManagementId">
|
|
|
- <el-select v-model="salesForm.creditManagementId" placeholder="请选择信用等级" class="w-full" filterable>
|
|
|
- <el-option
|
|
|
- v-for="item in creditLevelList"
|
|
|
- :key="item.id"
|
|
|
- :label="`${item.creditLevelNo} , ${item.creditLevelName}`"
|
|
|
- :value="item.id"
|
|
|
- />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="信用额度" prop="creditAmount">
|
|
|
- <el-input v-model="salesForm.creditAmount" :controls="false" class="w-full" placeholder="请输入信用额度" style="width: 100%" disabled />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="可用额度" prop="remainingQuota">
|
|
|
- <el-input
|
|
|
- v-model="salesForm.remainingQuota"
|
|
|
- :controls="false"
|
|
|
- class="w-full"
|
|
|
- placeholder="请输入可用额度"
|
|
|
- style="width: 100%"
|
|
|
- disabled
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
-
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="订单审核" prop="orderAudit">
|
|
|
- <el-select v-model="salesForm.orderAudit" placeholder="请选择" class="w-full" filterable>
|
|
|
- <el-option v-for="dict in order_check_way" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="支付密码" prop="creditPaymentPassword">
|
|
|
- <el-input v-model="salesForm.creditPaymentPassword" type="password" placeholder="请输入支付密码" show-password />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <!-- <el-col :span="8">
|
|
|
- <el-form-item label="收款条件" prop="accountPeriod">
|
|
|
- <el-select v-model="salesForm.accountPeriod" placeholder="请选择收款条件" class="w-full" filterable>
|
|
|
- <el-option v-for="item in settlementMethodList" :key="item.id" :label="item.settlementName" :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="settlementMethod">
|
|
|
- <el-select v-model="salesForm.settlementMethod" placeholder="请选择结算方式" class="w-full" filterable>
|
|
|
- <el-option v-for="item in settlementMethodList" :key="item.id" :label="item.settlementName" :value="item.id" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="客户来源" prop="payDays">
|
|
|
- <el-select v-model="salesForm.customerSource" class="w-full" filterable>
|
|
|
- <el-option v-for="dict in customer_source" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="销售通路" prop="payDays">
|
|
|
- <el-select v-model="salesForm.sellChannel" class="w-full" filterable>
|
|
|
- <el-option v-for="dict in sell_channel" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="税码" prop="rateId">
|
|
|
- <el-select v-model="salesForm.rateId" placeholder="税码" class="w-full" filterable>
|
|
|
- <el-option v-for="item in taxrateList" :key="item.id" :label="item.taxrateNo" :value="item.id" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="交易币别" prop="dealCurrencyId">
|
|
|
- <el-select v-model="salesForm.dealCurrencyId" placeholder="请选择交易币别" class="w-full" filterable>
|
|
|
- <el-option v-for="item in currencyList" :key="item.id" :label="item.currencyName" :value="item.id" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="账款归属" prop="payDays">
|
|
|
- <el-input v-model="form.customerNo" disabled />
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- <el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="单价含税" prop="payDays">
|
|
|
- <el-select v-model="salesForm.unitPrice" placeholder="单价含税" class="w-full" filterable>
|
|
|
- <el-option v-for="item in unitPriceArr" :key="item.value" :label="item.label" :value="item.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="账款额度超限" prop="creditLimit">
|
|
|
- <el-select v-model="salesForm.creditLimit" placeholder="请选择账款额度超限" class="w-full" filterable>
|
|
|
- <el-option v-for="dict in erp_is_enabled" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- <el-col :span="8">
|
|
|
- <el-form-item label="账款超期" prop="creditTimeLimit">
|
|
|
- <el-select v-model="salesForm.creditTimeLimit" placeholder="请选择账款超期" class="w-full" filterable>
|
|
|
- <el-option v-for="dict in erp_is_enabled" :key="dict.value" :label="dict.label" :value="dict.value" />
|
|
|
- </el-select>
|
|
|
- </el-form-item>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
- </el-form>
|
|
|
- </el-card>
|
|
|
+ </el-row> </el-form
|
|
|
+ ></el-card>
|
|
|
|
|
|
<!-- 添加/编辑开票信息对话框 -->
|
|
|
<add-invoice-dialog v-model="invoiceDialogVisible" :edit-data="currentInvoice" @confirm="handleInvoiceConfirm" />
|
|
|
@@ -489,7 +379,6 @@
|
|
|
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 { SalesInfoForm } from '@/api/customer/customerFile/salesInfo/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';
|
|
|
@@ -536,6 +425,9 @@ const props = defineProps<{
|
|
|
|
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
|
+
|
|
|
+// 查看模式
|
|
|
+const isViewMode = computed(() => route.query.status === 'view');
|
|
|
const unitPriceArr = ref([
|
|
|
{ label: '含税', value: 'True' },
|
|
|
{ label: '不含税', value: 'False' }
|
|
|
@@ -610,7 +502,10 @@ const form = reactive<CustomerInfoForm>({
|
|
|
regCountyNo: '',
|
|
|
provincialCityCounty: '',
|
|
|
status: '0',
|
|
|
- remark: ''
|
|
|
+ remark: '',
|
|
|
+ salesPersonId: undefined,
|
|
|
+ serviceStaffId: undefined,
|
|
|
+ belongingDepartmentId: undefined
|
|
|
});
|
|
|
|
|
|
// 工商信息(只读)
|
|
|
@@ -629,28 +524,6 @@ const businessInfo = reactive<BusinessInfoForm>({
|
|
|
status: '0'
|
|
|
});
|
|
|
|
|
|
-// 销售信息
|
|
|
-const salesForm = reactive<SalesInfoForm>({
|
|
|
- salesPersonId: undefined,
|
|
|
- serviceStaffId: undefined,
|
|
|
- belongingDepartmentId: undefined,
|
|
|
- creditManagementId: undefined,
|
|
|
- creditAmount: undefined,
|
|
|
- remainingQuota: undefined,
|
|
|
- orderAudit: undefined,
|
|
|
- creditPaymentPassword: '',
|
|
|
- accountPeriod: '',
|
|
|
- payDays: undefined,
|
|
|
- customerSource: '1',
|
|
|
- unitPrice: 'True',
|
|
|
- sellChannel: '1',
|
|
|
- creditLimit: '1',
|
|
|
- creditTimeLimit: '1',
|
|
|
- dealCurrencyId: undefined,
|
|
|
- settlementMethod: undefined,
|
|
|
- status: '0'
|
|
|
-});
|
|
|
-
|
|
|
// 开票信息列表
|
|
|
const invoiceList = ref<InvoiceInfoForm[]>([]);
|
|
|
const invoiceDialogVisible = ref(false);
|
|
|
@@ -666,6 +539,105 @@ 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' }],
|
|
|
@@ -687,39 +659,8 @@ const rules = {
|
|
|
industryCategoryId: [{ required: true, message: '请选择行业类别', trigger: 'change' }],
|
|
|
customerLevelId: [{ required: true, message: '请选择客户等级', trigger: 'change' }],
|
|
|
address: [{ required: true, message: '请输入详细地址', trigger: 'blur' }]
|
|
|
-};
|
|
|
-
|
|
|
-// 销售信息表单验证规则
|
|
|
-const salesRules = {
|
|
|
- salesPersonId: [{ required: true, message: '请选择业务人员', trigger: 'change' }],
|
|
|
- serviceStaffId: [{ required: true, message: '请选择客服人员', trigger: 'change' }]
|
|
|
-};
|
|
|
-
|
|
|
-// 加载币种列表
|
|
|
-const loadCurrencyList = async () => {
|
|
|
- try {
|
|
|
- const res = await listComCurrency({
|
|
|
- isShow: '0',
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 1000
|
|
|
- });
|
|
|
- currencyList.value = res.rows || [];
|
|
|
- } catch (error) {
|
|
|
- console.error('加载币种列表失败:', error);
|
|
|
- currencyList.value = [];
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-// 加载税码列表
|
|
|
-const loadTaxrateList = async () => {
|
|
|
- try {
|
|
|
- const res = await listTaxrate({
|
|
|
- isShow: '0',
|
|
|
- pageNum: 1,
|
|
|
- pageSize: 1000
|
|
|
- });
|
|
|
- taxrateList.value = res.rows || [];
|
|
|
- } catch (error) {}
|
|
|
+ // salesPersonId: [{ required: true, message: '请选择业务人员', trigger: 'change' }],
|
|
|
+ // serviceStaffId: [{ required: true, message: '请选择客服人员', trigger: 'change' }]
|
|
|
};
|
|
|
|
|
|
// 初始化
|
|
|
@@ -735,8 +676,6 @@ onMounted(async () => {
|
|
|
await loadCustomerTypeList();
|
|
|
await loadComStaffList();
|
|
|
await loadComDeptList();
|
|
|
- await loadCurrencyList();
|
|
|
- await loadTaxrateList();
|
|
|
|
|
|
// 优先使用props传递的customerId,否则从路由获取
|
|
|
const id = props.customerId || route.query.id;
|
|
|
@@ -881,7 +820,7 @@ const loadCustomerTypeList = async () => {
|
|
|
const loadComStaffList = async () => {
|
|
|
try {
|
|
|
const query: any = {};
|
|
|
- const res = await listErpStaff(query);
|
|
|
+ const res = await listComStaff(query);
|
|
|
comStaffList.value = res.rows || [];
|
|
|
} catch (error) {
|
|
|
console.error('加载员工列表失败:', error);
|
|
|
@@ -891,7 +830,7 @@ const loadComStaffList = async () => {
|
|
|
// 加载部门列表
|
|
|
const loadComDeptList = async () => {
|
|
|
try {
|
|
|
- const res = await listErpDept();
|
|
|
+ const res = await listDept();
|
|
|
// 处理可能的不同返回结构
|
|
|
comDeptList.value = res.rows || res.data || [];
|
|
|
} catch (error) {
|
|
|
@@ -940,26 +879,6 @@ const loadCustomerData = async (id: any) => {
|
|
|
codeArr.value = [data.regProvincialNo, data.regCityNo, data.regCountyNo] as any;
|
|
|
}
|
|
|
|
|
|
- // 填充销售信息
|
|
|
- if (data.customerSalesInfoVo) {
|
|
|
- Object.assign(salesForm, data.customerSalesInfoVo);
|
|
|
-
|
|
|
- // 如果有部门ID,且部门不在列表中,从API获取
|
|
|
- if (salesForm.belongingDepartmentId) {
|
|
|
- const deptExists = comDeptList.value.find((d) => String(d.deptId) === String(salesForm.belongingDepartmentId));
|
|
|
- if (!deptExists) {
|
|
|
- try {
|
|
|
- const deptRes = await getErpDept(salesForm.belongingDepartmentId);
|
|
|
- if (deptRes.data) {
|
|
|
- comDeptList.value.push(deptRes.data);
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- console.error('获取部门信息失败:', error);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// 填充开票信息列表
|
|
|
loadInvoiceList(id);
|
|
|
} catch (error) {
|
|
|
@@ -1000,37 +919,6 @@ const getCustomerLevelName = (id: string | number | undefined) => {
|
|
|
// 部门名称(响应式)
|
|
|
const deptName = ref('');
|
|
|
|
|
|
-// 监听部门ID变化,自动加载部门名称
|
|
|
-watch(
|
|
|
- () => salesForm.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 }
|
|
|
-);
|
|
|
-
|
|
|
// 处理区域选择变化
|
|
|
const handleChange = (val: string[]) => {
|
|
|
// 保存编码
|
|
|
@@ -1065,105 +953,6 @@ const handleChange = (val: string[]) => {
|
|
|
form.provincialCityCounty = names.join('/');
|
|
|
};
|
|
|
|
|
|
-// 处理业务人员选择变化
|
|
|
-const handleSalesPersonChange = async (staffId: any) => {
|
|
|
- // 根据选中的业务人员ID,找到对应的部门ID
|
|
|
- const selectedStaff = comStaffList.value.find((staff) => staff.staffId === staffId);
|
|
|
- if (selectedStaff && selectedStaff.deptId) {
|
|
|
- // 确保 deptId 的类型一致
|
|
|
- salesForm.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 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 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 handleEditInvoice = (row: InvoiceInfoForm, index: number) => {
|
|
|
currentInvoice.value = { ...row };
|
|
|
@@ -1225,32 +1014,13 @@ const removeInvoice = (data: any) => {
|
|
|
|
|
|
// 保存按钮
|
|
|
const handleSave = async () => {
|
|
|
- // 1. 先检查 ref 是否存在,避免静默失败
|
|
|
- if (!formRef.value || !salesFormRef.value) {
|
|
|
- ElMessage.error('表单组件未加载,请刷新页面');
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
try {
|
|
|
- if (!salesForm.salesPersonId) {
|
|
|
- ElMessage.warning('请选择业务人员!');
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!salesForm.serviceStaffId) {
|
|
|
- ElMessage.warning('请选择客服人员!');
|
|
|
- return;
|
|
|
- }
|
|
|
- // 2. 串行验证,任何一步失败都会抛出异常,进入 catch
|
|
|
- // 注意:ElementPlus 的 validate 失败时会 reject 一个包含错误信息的对象
|
|
|
await formRef.value.validate();
|
|
|
- await salesFormRef.value.validate();
|
|
|
-
|
|
|
submitLoading.value = true;
|
|
|
|
|
|
const submitData: CustomerInfoForm = {
|
|
|
...form,
|
|
|
customerBusinessBo: businessInfo,
|
|
|
- customerSalesInfoBo: salesForm,
|
|
|
customerInvoiceInfoBoList: invoiceList.value
|
|
|
};
|
|
|
|
|
|
@@ -1260,30 +1030,50 @@ const handleSave = async () => {
|
|
|
|
|
|
// 重新加载数据
|
|
|
await loadCustomerData(custId.value);
|
|
|
-
|
|
|
- // 可选:保存成功后重置表单或关闭弹窗
|
|
|
- // emit('update:visible', false);
|
|
|
} catch (error) {
|
|
|
- // 3. 关键优化:区分验证错误和系统错误
|
|
|
-
|
|
|
- // ElementPlus 的 validate 失败时,error 通常是一个包含 fields 信息的对象
|
|
|
- // 或者你可以判断 error 是否包含特定的验证失败标记
|
|
|
const isValidationError = error && typeof error === 'object' && 'fields' in error;
|
|
|
- // 有些版本可能是 error instanceof Error 且 message 包含特定字样,具体视 EP 版本而定
|
|
|
- // 最简单的判断:如果是因为 validate 抛出的,通常不需要报全局错误,因为表单上已经红字提示了
|
|
|
|
|
|
if (isValidationError) {
|
|
|
console.warn('表单验证未通过', error);
|
|
|
- // 让用户专注于表单上的红色提示,不要弹全局 Toast 干扰用户
|
|
|
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 {
|