|
@@ -13,9 +13,7 @@
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
<el-form-item label="所属公司" prop="belongCompanyId">
|
|
<el-form-item label="所属公司" prop="belongCompanyId">
|
|
|
<el-select v-model="form.belongCompanyId" placeholder="请选择所属公司" class="w-full" filterable>
|
|
<el-select v-model="form.belongCompanyId" placeholder="请选择所属公司" class="w-full" filterable>
|
|
|
- <el-option label="公司A" value="1" />
|
|
|
|
|
- <el-option label="公司B" value="2" />
|
|
|
|
|
- <el-option label="公司C" value="3" />
|
|
|
|
|
|
|
+ <el-option v-for="item in companyList" :key="item.id" :label="`${item.companyCode} , ${item.companyName}`" :value="item.id" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -40,9 +38,7 @@
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
<el-form-item label="开票类型" prop="invoiceTypeId">
|
|
<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">
|
|
|
- <el-option label="增值税专用发票" value="1" />
|
|
|
|
|
- <el-option label="增值税普通发票" value="2" />
|
|
|
|
|
- <el-option label="电子发票" value="3" />
|
|
|
|
|
|
|
+ <el-option v-for="item in invoiceTypeList" :key="item.id" :label="item.invoiceTypeName" :value="item.id" />
|
|
|
</el-select>
|
|
</el-select>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -110,7 +106,14 @@
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
<el-form-item label="结束时间" prop="validityToDate">
|
|
<el-form-item label="结束时间" prop="validityToDate">
|
|
|
- <el-date-picker v-model="form.validityToDate" type="date" placeholder="请选择结束时间" class="w-full" style="width: 100%" />
|
|
|
|
|
|
|
+ <el-date-picker
|
|
|
|
|
+ v-model="form.validityToDate"
|
|
|
|
|
+ type="date"
|
|
|
|
|
+ placeholder="请选择结束时间"
|
|
|
|
|
+ class="w-full"
|
|
|
|
|
+ style="width: 100%"
|
|
|
|
|
+ :disabled-date="(time) => form.validityFromDate && time.getTime() < new Date(form.validityFromDate).getTime()"
|
|
|
|
|
+ />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
@@ -122,12 +125,12 @@
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
- <el-form-item label="详细地址">
|
|
|
|
|
|
|
+ <el-form-item label="详细地址" prop="address">
|
|
|
<el-cascader v-model="codeArr" :options="regionData" placeholder="请选择" @change="handleChange" style="width: 100%"></el-cascader>
|
|
<el-cascader v-model="codeArr" :options="regionData" placeholder="请选择" @change="handleChange" style="width: 100%"></el-cascader>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
<el-col :span="8">
|
|
|
- <el-form-item prop="address">
|
|
|
|
|
|
|
+ <el-form-item>
|
|
|
<el-input v-model="form.address" placeholder="请输入详细地址" />
|
|
<el-input v-model="form.address" placeholder="请输入详细地址" />
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
@@ -203,17 +206,65 @@
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
|
- <el-col :span="8">
|
|
|
|
|
|
|
+ <el-col :span="24">
|
|
|
<el-form-item label="营业执照" prop="businessLicense">
|
|
<el-form-item label="营业执照" prop="businessLicense">
|
|
|
- <el-upload action="#" :auto-upload="false">
|
|
|
|
|
- <el-button icon="Plus">上传</el-button>
|
|
|
|
|
- </el-upload>
|
|
|
|
|
|
|
+ <div
|
|
|
|
|
+ v-if="!businessForm.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;
|
|
|
|
|
+ "
|
|
|
|
|
+ @mouseenter="(e) => (e.currentTarget.style.borderColor = '#409eff')"
|
|
|
|
|
+ @mouseleave="(e) => (e.currentTarget.style.borderColor = '#d9d9d9')"
|
|
|
|
|
+ >
|
|
|
|
|
+ <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="businessForm.businessLicense"
|
|
|
|
|
+ style="width: 360px; height: 200px"
|
|
|
|
|
+ fit="contain"
|
|
|
|
|
+ :preview-src-list="[businessForm.businessLicense]"
|
|
|
|
|
+ />
|
|
|
|
|
+ <el-button
|
|
|
|
|
+ type="danger"
|
|
|
|
|
+ :icon="Delete"
|
|
|
|
|
+ circle
|
|
|
|
|
+ size="small"
|
|
|
|
|
+ style="position: absolute; top: 5px; right: 5px"
|
|
|
|
|
+ @click="businessForm.businessLicense = ''"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
</el-form-item>
|
|
</el-form-item>
|
|
|
</el-col>
|
|
</el-col>
|
|
|
</el-row>
|
|
</el-row>
|
|
|
</el-form>
|
|
</el-form>
|
|
|
</el-card>
|
|
</el-card>
|
|
|
|
|
|
|
|
|
|
+ <!-- 营业执照选择器对话框 -->
|
|
|
|
|
+ <FileSelector
|
|
|
|
|
+ v-model="businessLicenseSelectorVisible"
|
|
|
|
|
+ title="选择营业执照"
|
|
|
|
|
+ :allowed-types="[1]"
|
|
|
|
|
+ :multiple="false"
|
|
|
|
|
+ :allow-upload="true"
|
|
|
|
|
+ @confirm="handleBusinessLicenseSelected"
|
|
|
|
|
+ />
|
|
|
|
|
+
|
|
|
<!-- 联系人信息列表 -->
|
|
<!-- 联系人信息列表 -->
|
|
|
<el-card shadow="never" class="mb-4">
|
|
<el-card shadow="never" class="mb-4">
|
|
|
<template #header>
|
|
<template #header>
|
|
@@ -251,7 +302,7 @@
|
|
|
<template #header>
|
|
<template #header>
|
|
|
<div class="flex justify-between items-center">
|
|
<div class="flex justify-between items-center">
|
|
|
<span class="font-medium">销售信息</span>
|
|
<span class="font-medium">销售信息</span>
|
|
|
- <el-button type="primary" @click="handleSubmit" :loading="submitLoading">保存</el-button>
|
|
|
|
|
|
|
+ <el-button type="primary" @click="handleSubmit">保存</el-button>
|
|
|
</div>
|
|
</div>
|
|
|
</template>
|
|
</template>
|
|
|
<el-form :model="salesForm" label-width="120px">
|
|
<el-form :model="salesForm" label-width="120px">
|
|
@@ -324,8 +375,11 @@
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts" name="CustomerInfoAdd">
|
|
<script setup lang="ts" name="CustomerInfoAdd">
|
|
|
-import { listCustomerInfo, getCustomerInfo, delCustomerInfo, addCustomerInfo, updateCustomerInfo } from '@/api/customer/customerFile/customerInfo';
|
|
|
|
|
-import { CustomerInfoVO, CustomerInfoQuery, CustomerInfoForm } from '@/api/customer/customerFile/customerInfo/types';
|
|
|
|
|
|
|
+import { listCustomerInfo, getCustomerInfo, addCustomerInfo } from '@/api/customer/customerFile/customerInfo';
|
|
|
|
|
+import { CustomerInfoForm } from '@/api/customer/customerFile/customerInfo/types';
|
|
|
|
|
+import { listInvoiceType } from '@/api/customer/invoiceType';
|
|
|
|
|
+import { InvoiceTypeVO, InvoiceTypeQuery } from '@/api/customer/invoiceType/types';
|
|
|
|
|
+import FileSelector from '@/components/FileSelector/index.vue';
|
|
|
import { generateCustomerNumber } from '@/utils/customerNumber';
|
|
import { generateCustomerNumber } from '@/utils/customerNumber';
|
|
|
import type { CustomerContactForm } from '@/api/customer/customerFile/customerContact/types';
|
|
import type { CustomerContactForm } from '@/api/customer/customerFile/customerContact/types';
|
|
|
import type { InvoiceInfoForm } from '@/api/customer/customerFile/invoiceInfo/types';
|
|
import type { InvoiceInfoForm } from '@/api/customer/customerFile/invoiceInfo/types';
|
|
@@ -338,6 +392,9 @@ import { listEnterpriseScale } from '@/api/customer/customerCategory/enterpriseS
|
|
|
import { listIndustryCategory } from '@/api/customer/customerCategory/industryCategory';
|
|
import { listIndustryCategory } from '@/api/customer/customerCategory/industryCategory';
|
|
|
import type { EnterpriseScaleVO } from '@/api/customer/customerCategory/enterpriseScale/types';
|
|
import type { EnterpriseScaleVO } from '@/api/customer/customerCategory/enterpriseScale/types';
|
|
|
import type { IndustryCategoryVO } from '@/api/customer/customerCategory/industryCategory/types';
|
|
import type { IndustryCategoryVO } from '@/api/customer/customerCategory/industryCategory/types';
|
|
|
|
|
+import { listSysCompany } from '@/api/company/sysCompany';
|
|
|
|
|
+import type { SysCompanyVO } from '@/api/company/sysCompany/types';
|
|
|
|
|
+import { Plus, Delete } from '@element-plus/icons-vue';
|
|
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
const { customer_type, customer_level } = toRefs<any>(proxy?.useDict('customer_type', 'customer_level'));
|
|
const { customer_type, customer_level } = toRefs<any>(proxy?.useDict('customer_type', 'customer_level'));
|
|
@@ -357,12 +414,70 @@ const codeArr = ref([]);
|
|
|
// 下拉框数据列表
|
|
// 下拉框数据列表
|
|
|
const enterpriseScaleList = ref<EnterpriseScaleVO[]>([]);
|
|
const enterpriseScaleList = ref<EnterpriseScaleVO[]>([]);
|
|
|
const industryCategoryList = ref<IndustryCategoryVO[]>([]);
|
|
const industryCategoryList = ref<IndustryCategoryVO[]>([]);
|
|
|
|
|
+const invoiceTypeList = ref<InvoiceTypeVO[]>([]);
|
|
|
|
|
+const companyList = ref<SysCompanyVO[]>([]);
|
|
|
|
|
+
|
|
|
|
|
+// Logo选择器相关
|
|
|
|
|
+const logoSelectorVisible = ref(false);
|
|
|
|
|
+const businessLicenseSelectorVisible = ref(false);
|
|
|
|
|
+
|
|
|
|
|
+// Logo选择处理
|
|
|
|
|
+const handleLogoSelected = (files: any[]) => {
|
|
|
|
|
+ if (files && files.length > 0) {
|
|
|
|
|
+ const file = files[0]; // 取第一个文件
|
|
|
|
|
+ if (file && (file.url || file.path)) {
|
|
|
|
|
+ // form.value.logo = file.url || file.path;
|
|
|
|
|
+ ElMessage.success('Logo选择成功');
|
|
|
|
|
+
|
|
|
|
|
+ // 选择完成后清理表单验证状态
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ formRef.value?.clearValidate();
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('请选择有效的图片文件');
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('请选择有效的图片文件');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 营业执照选择处理
|
|
|
|
|
+const handleBusinessLicenseSelected = (files: any[]) => {
|
|
|
|
|
+ if (files && files.length > 0) {
|
|
|
|
|
+ const file = files[0]; // 取第一个文件
|
|
|
|
|
+ if (file && (file.url || file.path)) {
|
|
|
|
|
+ businessForm.businessLicense = file.url || file.path;
|
|
|
|
|
+ ElMessage.success('营业执照选择成功');
|
|
|
|
|
+
|
|
|
|
|
+ // 选择完成后清理表单验证状态
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ formRef.value?.clearValidate('businessLicense');
|
|
|
|
|
+ });
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('请选择有效的图片文件');
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ElMessage.error('请选择有效的图片文件');
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 监听对话框关闭,清理表单验证状态
|
|
|
|
|
+watch(logoSelectorVisible, (newVal) => {
|
|
|
|
|
+ if (!newVal) {
|
|
|
|
|
+ // 对话框关闭后清理可能的表单验证状态
|
|
|
|
|
+ nextTick(() => {
|
|
|
|
|
+ formRef.value?.clearValidate();
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+});
|
|
|
|
|
|
|
|
// 初始化
|
|
// 初始化
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
// 加载下拉框数据
|
|
// 加载下拉框数据
|
|
|
await loadEnterpriseScaleList();
|
|
await loadEnterpriseScaleList();
|
|
|
await loadIndustryCategoryList();
|
|
await loadIndustryCategoryList();
|
|
|
|
|
+ await loadInvoiceTypeList();
|
|
|
|
|
+ await loadCompanyList();
|
|
|
|
|
|
|
|
// 判断是新增还是编辑
|
|
// 判断是新增还是编辑
|
|
|
const id = route.query.id;
|
|
const id = route.query.id;
|
|
@@ -437,6 +552,26 @@ const loadIndustryCategoryList = async () => {
|
|
|
}
|
|
}
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
|
|
+// 加载开票类型列表
|
|
|
|
|
+const loadInvoiceTypeList = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listInvoiceType();
|
|
|
|
|
+ invoiceTypeList.value = res.rows || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载开票类型列表失败:', error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+// 加载公司列表
|
|
|
|
|
+const loadCompanyList = async () => {
|
|
|
|
|
+ try {
|
|
|
|
|
+ const res = await listSysCompany();
|
|
|
|
|
+ companyList.value = res.rows || [];
|
|
|
|
|
+ } catch (error) {
|
|
|
|
|
+ console.error('加载公司列表失败:', error);
|
|
|
|
|
+ }
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
// 企业基本信息表单
|
|
// 企业基本信息表单
|
|
|
const form = reactive<CustomerInfoForm>({
|
|
const form = reactive<CustomerInfoForm>({
|
|
|
customerNo: '',
|
|
customerNo: '',
|
|
@@ -499,7 +634,16 @@ const currentInvoiceIndex = ref<number>(-1);
|
|
|
|
|
|
|
|
// 表单验证规则
|
|
// 表单验证规则
|
|
|
const rules = {
|
|
const rules = {
|
|
|
- companyName: [{ required: true, message: '请输入客户名称', trigger: 'blur' }]
|
|
|
|
|
|
|
+ belongCompanyId: [{ required: true, message: '请选择所属公司', trigger: 'change' }],
|
|
|
|
|
+ customerName: [{ required: true, message: '请输入客户名称', trigger: 'blur' }],
|
|
|
|
|
+ businessCustomerName: [{ required: true, 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' }]
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
// 获取角色名称
|
|
// 获取角色名称
|