1080 lines
44 KiB
Vue
1080 lines
44 KiB
Vue
<template>
|
||
<div class="app-container supplier-edit-page" v-loading="pageLoading">
|
||
<!-- 顶部:返回 + 标题 + 保存 -->
|
||
<el-card shadow="never" class="head-card">
|
||
<div class="head-bar">
|
||
<el-button icon="ArrowLeft" @click="goBack">返回</el-button>
|
||
<div class="head-title">
|
||
<span class="supplier-name">{{ isAdd ? '新增供应商' : (form.supplierName || '-') }}</span>
|
||
<el-tag size="small" :type="isAdd ? 'warning' : 'info'">{{ isAdd ? '未保存' : '编辑中' }}</el-tag>
|
||
</div>
|
||
<div class="head-code">供应商编码:{{ form.supplierCode || '保存后可维护子表数据' }}</div>
|
||
<div class="head-right">
|
||
<el-button @click="goBack">取 消</el-button>
|
||
<el-button type="primary" :loading="saving" v-hasPermi="[isAdd ? 'customersupplier:supplierinfo:add' : 'customersupplier:supplierinfo:edit']" @click="submitForm">保 存</el-button>
|
||
</div>
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-card shadow="never">
|
||
<el-tabs v-model="activeTab">
|
||
<!-- ============ 基本信息 ============ -->
|
||
<el-tab-pane label="基本信息" name="base">
|
||
<el-form ref="supplierRef" :model="form" :rules="rules" label-width="120px" class="supplier-form">
|
||
<el-row :gutter="20">
|
||
<el-col :span="12">
|
||
<el-form-item label="供应商编码" prop="supplierCode">
|
||
<el-input v-model="form.supplierCode" placeholder="请输入供应商编码" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="供应商名称" prop="supplierName">
|
||
<el-input v-model="form.supplierName" placeholder="请输入供应商名称" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="对外代码" prop="supplierCodeDw">
|
||
<el-input v-model="form.supplierCodeDw" placeholder="请输入对外代码" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="统一社会信用代码" prop="creditCode">
|
||
<el-input v-model="form.creditCode" placeholder="在「公司主体」页签点绑定供应商后自动同步">
|
||
<template #append>
|
||
<el-tooltip content="由公司主体绑定自动同步,也可手工录入" placement="top">
|
||
<el-icon><InfoFilled /></el-icon>
|
||
</el-tooltip>
|
||
</template>
|
||
</el-input>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="供应商类型" prop="supplierType">
|
||
<el-select v-model="form.supplierType" placeholder="请选择供应商类型" clearable style="width: 100%;">
|
||
<el-option v-for="opt in supplierTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="开票类型" prop="invoiceType">
|
||
<el-select v-model="form.invoiceType" placeholder="请选择开票类型" clearable style="width: 100%;">
|
||
<el-option v-for="opt in invoiceTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="卡车行类型" prop="kacheType">
|
||
<el-select v-model="form.kacheType" placeholder="请选择卡车行类型" clearable style="width: 100%;">
|
||
<el-option v-for="opt in kacheTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="启用状态" prop="isEnable">
|
||
<el-select v-model="form.isEnable" placeholder="请选择启用状态" clearable style="width: 100%;">
|
||
<el-option label="正常" value="0" />
|
||
<el-option label="停用" value="1" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="采购员" prop="purchaserUserId">
|
||
<user-select
|
||
v-model="form.purchaserUserId"
|
||
placeholder="请选择采购员"
|
||
@change="(uid, user) => handleUserChange(uid, user, 'purchaserUser')"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="应付额度" prop="ed">
|
||
<el-input v-model="form.ed" placeholder="请输入应付额度" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="应付账期" prop="zq">
|
||
<el-input v-model="form.zq" placeholder="请输入应付账期(天)" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="结算员" prop="settlementUserId">
|
||
<user-select
|
||
v-model="form.settlementUserId"
|
||
placeholder="请选择结算员"
|
||
@change="(uid, user) => handleUserChange(uid, user, 'settlementUser')"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="跟单员" prop="serviceUserId">
|
||
<user-select
|
||
v-model="form.serviceUserId"
|
||
placeholder="请选择跟单员"
|
||
@change="(uid, user) => handleUserChange(uid, user, 'serviceUser')"
|
||
/>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="结算方式" prop="settlementType">
|
||
<el-select v-model="form.settlementType" placeholder="请选择结算方式" clearable style="width: 100%;">
|
||
<el-option
|
||
v-for="dict in settlement_type"
|
||
:key="dict.value"
|
||
:label="dict.label"
|
||
:value="dict.value"
|
||
/>
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="临时额度" prop="tempEd">
|
||
<el-input v-model="form.tempEd" placeholder="请输入临时额度" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="应付余额" prop="accountBalance">
|
||
<el-input v-model="form.accountBalance" placeholder="请输入应付余额" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="外币应付余额" prop="foreignCurrencyBalance">
|
||
<el-input v-model="form.foreignCurrencyBalance" placeholder="请输入外币应付余额" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="信用额度" prop="creditEd">
|
||
<el-input v-model="form.creditEd" placeholder="请输入信用额度" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="重量阈值" prop="weightThreshold">
|
||
<el-input v-model="form.weightThreshold" placeholder="请输入重量阈值(kg)" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="抛比" prop="throwRatio">
|
||
<el-input v-model="form.throwRatio" placeholder="请输入抛比(%)" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="合作开始日期" prop="cooperationStartDate">
|
||
<el-date-picker v-model="form.cooperationStartDate" type="date" value-format="YYYY-MM-DD" placeholder="选择合作开始日期" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="合作状态" prop="cooperationStatus">
|
||
<el-select v-model="form.cooperationStatus" placeholder="请选择合作状态" clearable style="width: 100%;">
|
||
<el-option v-for="opt in cooperationStatusOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="绑定渠道ID" prop="channelIds">
|
||
<el-input v-model="form.channelIds" type="textarea" :rows="2" placeholder="多个渠道ID用英文逗号分隔" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="备注说明" prop="remark">
|
||
<el-input v-model="form.remark" type="textarea" :rows="3" placeholder="请输入内容" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
</el-tab-pane>
|
||
|
||
<!-- ============ 公司主体 ============ -->
|
||
<el-tab-pane label="公司主体" name="company">
|
||
<div class="pane-toolbar">
|
||
<el-button type="primary" plain icon="Plus" size="small" @click="handleAddCompany">新增公司主体</el-button>
|
||
<span class="pane-tip">点击「绑定供应商」后,主表的统一社会信用代码会自动同步为该公司的信用代码</span>
|
||
</div>
|
||
<el-table :data="form.companyList" border size="small">
|
||
<el-table-column label="序号" type="index" width="55" align="center" />
|
||
<el-table-column label="公司全称" prop="companyNameFull" show-overflow-tooltip />
|
||
<el-table-column label="统一社会信用代码" prop="creditCode" width="190" show-overflow-tooltip />
|
||
<el-table-column label="法定代表人" prop="legalPerson" width="110" show-overflow-tooltip />
|
||
<el-table-column label="当前绑定" width="90" align="center">
|
||
<template #default="{ row }">
|
||
<el-tag v-if="row.creditCode && form.creditCode === row.creditCode" type="success" size="small">已绑定</el-tag>
|
||
<span v-else style="color: #999;">-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="230" align="center">
|
||
<template #default="{ row, $index }">
|
||
<el-button link type="primary" size="small" @click="handleBindCompany(row)">绑定供应商</el-button>
|
||
<el-button link type="primary" size="small" @click="handleEditCompany(row, $index)">编辑</el-button>
|
||
<el-button link type="danger" size="small" @click="handleDeleteCompany(row, $index)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
<template #empty>
|
||
<el-empty description="暂无公司主体,新增后将随供应商信息一起保存" :image-size="80" />
|
||
</template>
|
||
</el-table>
|
||
</el-tab-pane>
|
||
|
||
<!-- ============ 联系人 ============ -->
|
||
<el-tab-pane label="联系人" name="contact">
|
||
<div class="pane-toolbar">
|
||
<el-button type="primary" plain icon="Plus" size="small" @click="handleAddContact">新增联系人</el-button>
|
||
</div>
|
||
<el-table :data="form.contactList" border size="small">
|
||
<el-table-column label="序号" type="index" width="55" align="center" />
|
||
<el-table-column label="联系人" prop="contactName" width="120" show-overflow-tooltip />
|
||
<el-table-column label="职位" prop="position" width="130" show-overflow-tooltip />
|
||
<el-table-column label="所属部门" prop="department" width="130" show-overflow-tooltip />
|
||
<el-table-column label="手机号" prop="phone" width="140" show-overflow-tooltip />
|
||
<el-table-column label="邮箱" prop="email" min-width="180" show-overflow-tooltip />
|
||
<el-table-column label="默认" width="80" align="center">
|
||
<template #default="{ row }">
|
||
<el-tag v-if="row.isDefault === '1'" type="success" size="small">默认</el-tag>
|
||
<span v-else style="color: #999;">-</span>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="150" align="center">
|
||
<template #default="{ row, $index }">
|
||
<el-button link type="primary" size="small" @click="handleEditContact(row, $index)">编辑</el-button>
|
||
<el-button link type="danger" size="small" @click="handleDeleteContact(row, $index)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
<template #empty>
|
||
<el-empty description="暂无联系人,新增后将随供应商信息一起保存" :image-size="80" />
|
||
</template>
|
||
</el-table>
|
||
</el-tab-pane>
|
||
|
||
<!-- ============ 附件资料 ============ -->
|
||
<el-tab-pane label="附件资料" name="attachment">
|
||
<div class="pane-toolbar">
|
||
<el-upload
|
||
:show-file-list="false"
|
||
:action="uploadFileUrl"
|
||
:headers="uploadHeaders"
|
||
:before-upload="handleBeforeAttachmentUpload"
|
||
:on-success="handleAttachmentUploadSuccess"
|
||
:on-error="handleAttachmentUploadError"
|
||
multiple
|
||
>
|
||
<el-button type="primary" icon="Upload">上传附件</el-button>
|
||
</el-upload>
|
||
<span class="pane-tip">支持 PDF、图片、Word、Excel、压缩包,单个文件不超过 50MB;附件在点「保存」后随供应商入库</span>
|
||
</div>
|
||
<el-table :data="form.attachmentList" border size="small">
|
||
<el-table-column label="序号" type="index" width="55" align="center" />
|
||
<el-table-column label="文件名称" prop="fileName" align="center" show-overflow-tooltip min-width="180">
|
||
<template #default="{ row }">
|
||
<el-button link type="primary" @click="handleDownload(row)">{{ row.fileName }}</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="大小" width="100" align="center">
|
||
<template #default="{ row }">{{ formatFileSize(row.fileSize) }}</template>
|
||
</el-table-column>
|
||
<el-table-column label="类型" prop="fileExtension" width="80" align="center" />
|
||
<el-table-column label="附件分类" width="160" align="center">
|
||
<template #default="{ row }">
|
||
<el-select v-model="row.attachmentType" placeholder="请选择">
|
||
<el-option v-for="opt in attachmentTypeOptions" :key="opt.value" :label="opt.label" :value="opt.value" />
|
||
</el-select>
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="排序" width="90" align="center">
|
||
<template #default="{ row }">
|
||
<el-input v-model="row.sortOrder" type="number" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="备注" min-width="160" align="center">
|
||
<template #default="{ row }">
|
||
<el-input v-model="row.remark" placeholder="请输入备注" />
|
||
</template>
|
||
</el-table-column>
|
||
<el-table-column label="操作" width="130" align="center">
|
||
<template #default="{ row, $index }">
|
||
<el-button link type="primary" icon="Download" @click="handleDownload(row)">下载</el-button>
|
||
<el-button link type="danger" icon="Delete" @click="handleDeleteAttachment($index)">删除</el-button>
|
||
</template>
|
||
</el-table-column>
|
||
<template #empty>
|
||
<el-empty description="暂无附件" :image-size="80" />
|
||
</template>
|
||
</el-table>
|
||
</el-tab-pane>
|
||
</el-tabs>
|
||
</el-card>
|
||
|
||
<!-- ====== 公司主体编辑对话框 ====== -->
|
||
<el-dialog :title="companyDialogTitle" v-model="companyDialogVisible" width="900px" append-to-body>
|
||
<el-form ref="companyRef" :model="companyForm" label-width="130px">
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="公司全称" prop="companyNameFull">
|
||
<el-input v-model="companyForm.companyNameFull" placeholder="请输入公司全称" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="英文名称" prop="englishName">
|
||
<el-input v-model="companyForm.englishName" placeholder="请输入英文名称" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="统一社会信用代码" prop="creditCode">
|
||
<el-input v-model="companyForm.creditCode" placeholder="18位统一社会信用代码" maxlength="18" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="法定代表人" prop="legalPerson">
|
||
<el-input v-model="companyForm.legalPerson" placeholder="请输入法定代表人" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="法定代表人电话" prop="legalPersonPhone">
|
||
<el-input v-model="companyForm.legalPersonPhone" placeholder="请输入法定代表人电话" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="法定代表人身份证" prop="legalPersonIdCard">
|
||
<el-input v-model="companyForm.legalPersonIdCard" placeholder="请输入法定代表人身份证号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="注册资本" prop="registeredCapital">
|
||
<el-input-number v-model="companyForm.registeredCapital" :min="0" :precision="2" controls-position="right" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="币种" prop="capitalCurrency">
|
||
<el-input v-model="companyForm.capitalCurrency" placeholder="如 人民币/美元" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="实收资本" prop="paidInCapital">
|
||
<el-input-number v-model="companyForm.paidInCapital" :min="0" :precision="2" controls-position="right" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="成立日期" prop="establishDate">
|
||
<el-date-picker v-model="companyForm.establishDate" type="date" value-format="YYYY-MM-DD" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="营业期限起" prop="businessTermStart">
|
||
<el-date-picker v-model="companyForm.businessTermStart" type="date" value-format="YYYY-MM-DD" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="营业期限止" prop="businessTermEnd">
|
||
<el-date-picker v-model="companyForm.businessTermEnd" type="date" value-format="YYYY-MM-DD" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="是否长期有效" prop="businessTermPermanent">
|
||
<el-radio-group v-model="companyForm.businessTermPermanent">
|
||
<el-radio label="0">否</el-radio>
|
||
<el-radio label="1">是</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="登记机关" prop="registrationAuthority">
|
||
<el-input v-model="companyForm.registrationAuthority" placeholder="请输入登记机关" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="注册号" prop="registrationNumber">
|
||
<el-input v-model="companyForm.registrationNumber" placeholder="旧版工商注册号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="经营状态" prop="operatingStatus">
|
||
<el-input v-model="companyForm.operatingStatus" placeholder="如 存续/在业/吊销/注销" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="员工人数" prop="employeeCount">
|
||
<el-input-number v-model="companyForm.employeeCount" :min="0" controls-position="right" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="经营范围" prop="businessScope">
|
||
<el-input v-model="companyForm.businessScope" type="textarea" :rows="3" placeholder="请输入经营范围" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="主要股东" prop="shareholders">
|
||
<el-input v-model="companyForm.shareholders" type="textarea" :rows="2" placeholder="股东信息(文本或JSON)" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="公司电话" prop="companyPhone">
|
||
<el-input v-model="companyForm.companyPhone" placeholder="请输入公司电话" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="公司传真" prop="companyFax">
|
||
<el-input v-model="companyForm.companyFax" placeholder="请输入公司传真" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="公司网址" prop="companyWebsite">
|
||
<el-input v-model="companyForm.companyWebsite" placeholder="请输入公司网址" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="公司邮箱" prop="companyEmail">
|
||
<el-input v-model="companyForm.companyEmail" placeholder="请输入公司邮箱" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="省份" prop="registeredProvince" label-width="60px">
|
||
<el-input v-model="companyForm.registeredProvince" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="城市" prop="registeredCity" label-width="60px">
|
||
<el-input v-model="companyForm.registeredCity" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="区县" prop="registeredDistrict" label-width="60px">
|
||
<el-input v-model="companyForm.registeredDistrict" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="注册详细地址" prop="registeredAddressDetail">
|
||
<el-input v-model="companyForm.registeredAddressDetail" placeholder="请输入注册详细地址" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="营业执照" prop="businessLicenseUrl">
|
||
<image-upload v-model="companyForm.businessLicenseUrl" :limit="1" :size="5" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="其他附件" prop="attachmentIds">
|
||
<file-upload v-model="companyForm.attachmentIds" :limit="10" :size="50" accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.zip,.rar" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="备注" prop="remark">
|
||
<el-input v-model="companyForm.remark" type="textarea" :rows="2" placeholder="备注说明" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button type="primary" @click="submitCompanyForm">确 定</el-button>
|
||
<el-button @click="companyDialogVisible = false">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
|
||
<!-- ====== 联系人编辑对话框 ====== -->
|
||
<el-dialog :title="contactDialogTitle" v-model="contactDialogVisible" width="800px" append-to-body>
|
||
<el-form ref="contactRef" :model="contactForm" :rules="contactRules" label-width="120px">
|
||
<el-row>
|
||
<el-col :span="12">
|
||
<el-form-item label="联系人姓名" prop="contactName">
|
||
<el-input v-model="contactForm.contactName" placeholder="请输入联系人姓名" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="职位" prop="position">
|
||
<el-input v-model="contactForm.position" placeholder="如 销售经理/财务总监" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="手机号" prop="phone">
|
||
<el-input v-model="contactForm.phone" placeholder="请输入手机号" maxlength="20" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="所属部门" prop="department">
|
||
<el-input v-model="contactForm.department" placeholder="如 销售部/财务部" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="座机" prop="landline">
|
||
<el-input v-model="contactForm.landline" placeholder="含区号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="电子邮箱" prop="email">
|
||
<el-input v-model="contactForm.email" placeholder="请输入电子邮箱" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="微信号" prop="wechat">
|
||
<el-input v-model="contactForm.wechat" placeholder="请输入微信号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="QQ号" prop="qq">
|
||
<el-input v-model="contactForm.qq" placeholder="请输入QQ号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="国家/地区" prop="country" label-width="90px">
|
||
<el-input v-model="contactForm.country" placeholder="中国" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="省份" prop="province" label-width="60px">
|
||
<el-input v-model="contactForm.province" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="城市" prop="city" label-width="60px">
|
||
<el-input v-model="contactForm.city" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="6">
|
||
<el-form-item label="区/县" prop="district" label-width="60px">
|
||
<el-input v-model="contactForm.district" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="邮政编码" prop="postalCode">
|
||
<el-input v-model="contactForm.postalCode" placeholder="请输入邮政编码" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="12">
|
||
<el-form-item label="详细地址" prop="contactAddress">
|
||
<el-input v-model="contactForm.contactAddress" placeholder="街道、门牌号" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="联系人类型" prop="contactType">
|
||
<el-select v-model="contactForm.contactType" placeholder="请选择" clearable>
|
||
<el-option label="业务联系人" value="0" />
|
||
<el-option label="财务联系人" value="1" />
|
||
<el-option label="紧急联系人" value="2" />
|
||
<el-option label="其他" value="3" />
|
||
</el-select>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="是否默认" prop="isDefault">
|
||
<el-radio-group v-model="contactForm.isDefault">
|
||
<el-radio label="0">否</el-radio>
|
||
<el-radio label="1">是</el-radio>
|
||
</el-radio-group>
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="8">
|
||
<el-form-item label="排序" prop="sortOrder">
|
||
<el-input-number v-model="contactForm.sortOrder" :min="0" controls-position="right" style="width: 100%;" />
|
||
</el-form-item>
|
||
</el-col>
|
||
<el-col :span="24">
|
||
<el-form-item label="备注" prop="remark">
|
||
<el-input v-model="contactForm.remark" type="textarea" :rows="2" placeholder="请输入备注" />
|
||
</el-form-item>
|
||
</el-col>
|
||
</el-row>
|
||
</el-form>
|
||
<template #footer>
|
||
<div class="dialog-footer">
|
||
<el-button type="primary" @click="submitContactForm">确 定</el-button>
|
||
<el-button @click="contactDialogVisible = false">取 消</el-button>
|
||
</div>
|
||
</template>
|
||
</el-dialog>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup name="SupplierEdit">
|
||
import {
|
||
getSupplier, addSupplier, updateSupplier,
|
||
delSupplierCompany, delSupplierContact
|
||
} from '@/api/customersuppliermanagement/supplierinfo/supplier.js'
|
||
import { getToken } from '@/utils/auth'
|
||
import axios from 'axios'
|
||
import { saveAs } from 'file-saver'
|
||
|
||
const { proxy } = getCurrentInstance()
|
||
const route = useRoute()
|
||
const router = useRouter()
|
||
|
||
const { settlement_type } = useDict('settlement_type')
|
||
|
||
const pageLoading = ref(false)
|
||
const saving = ref(false)
|
||
const activeTab = ref('base')
|
||
|
||
const supplierId = computed(() => route.query.supplierId ? Number(route.query.supplierId) : null)
|
||
const isAdd = computed(() => !supplierId.value)
|
||
|
||
const rules = {
|
||
supplierCode: [{ required: true, message: '供应商编码不能为空', trigger: 'blur' }],
|
||
supplierName: [{ required: true, message: '供应商名称不能为空', trigger: 'blur' }]
|
||
}
|
||
|
||
const supplierTypeOptions = ref([
|
||
{ value: '1', label: '卡车行' },
|
||
{ value: '2', label: '航司代理' },
|
||
{ value: '3', label: '报关行' },
|
||
{ value: '4', label: '清关行' },
|
||
{ value: '5', label: '尾派服务商' },
|
||
{ value: '6', label: '报关代理' }
|
||
])
|
||
const invoiceTypeOptions = ref([
|
||
{ value: '1', label: '增值税普通发票' },
|
||
{ value: '2', label: '增值税专用发票' },
|
||
{ value: '3', label: '增值税电子普通发票' },
|
||
{ value: '4', label: '其他普通发票' }
|
||
])
|
||
const kacheTypeOptions = ref([
|
||
{ value: '0', label: '国内' },
|
||
{ value: '1', label: '国外' }
|
||
])
|
||
const cooperationStatusOptions = ref([
|
||
{ value: '0', label: '正常' },
|
||
{ value: '1', label: '暂停' },
|
||
{ value: '2', label: '终止' }
|
||
])
|
||
|
||
/** 空表单 */
|
||
function buildEmptyForm() {
|
||
return {
|
||
supplierId: null,
|
||
supplierCode: null,
|
||
supplierName: null,
|
||
supplierCodeDw: null,
|
||
creditCode: null,
|
||
supplierType: null,
|
||
invoiceType: null,
|
||
kacheType: null,
|
||
isEnable: null,
|
||
purchaserUserId: null,
|
||
purchaserUser: null,
|
||
ed: null,
|
||
zq: null,
|
||
settlementUserId: null,
|
||
settlementUser: null,
|
||
serviceUserId: null,
|
||
serviceUser: null,
|
||
settlementType: null,
|
||
tempEd: null,
|
||
accountBalance: null,
|
||
foreignCurrencyBalance: null,
|
||
weightThreshold: null,
|
||
throwRatio: null,
|
||
creditEd: null,
|
||
cooperationStartDate: null,
|
||
cooperationStatus: null,
|
||
channelIds: null,
|
||
attachmentList: [],
|
||
companyList: [],
|
||
contactList: [],
|
||
remark: null,
|
||
delFlag: null
|
||
}
|
||
}
|
||
const form = ref(buildEmptyForm())
|
||
|
||
/* ---------------- 用户冗余姓名 ---------------- */
|
||
function handleUserChange(uid, user, nameField) {
|
||
form.value[nameField] = user ? (user.nickName || user.userName || null) : null
|
||
}
|
||
|
||
/* ---------------- 附件上传 ---------------- */
|
||
const baseUrl = import.meta.env.VITE_APP_BASE_API
|
||
const uploadFileUrl = ref(baseUrl + '/common/upload')
|
||
const uploadHeaders = ref({ Authorization: 'Bearer ' + getToken() })
|
||
const attachmentTypeOptions = ref([
|
||
{ value: '0', label: '附件资料' },
|
||
{ value: '1', label: '供应商Logo' },
|
||
{ value: '2', label: '合同文件' },
|
||
{ value: '3', label: '其他' }
|
||
])
|
||
const ATTACHMENT_SIZE_LIMIT = 50
|
||
const ATTACHMENT_EXTENSIONS = ['pdf', 'jpg', 'jpeg', 'png', 'doc', 'docx', 'xls', 'xlsx', 'zip', 'rar']
|
||
|
||
function formatFileSize(bytes) {
|
||
if (!bytes) return '0 B'
|
||
const k = 1024
|
||
const sizes = ['B', 'KB', 'MB', 'GB']
|
||
const i = Math.floor(Math.log(bytes) / Math.log(k))
|
||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
|
||
}
|
||
|
||
function handleBeforeAttachmentUpload(file) {
|
||
const ext = (file.name.split('.').pop() || '').toLowerCase()
|
||
if (ATTACHMENT_EXTENSIONS.indexOf(ext) < 0) {
|
||
proxy.$modal.msgError(`不支持的文件格式:${ext}`)
|
||
return false
|
||
}
|
||
if (file.name.includes(',')) {
|
||
proxy.$modal.msgError('文件名不正确,不能包含英文逗号!')
|
||
return false
|
||
}
|
||
if (file.size / 1024 / 1024 >= ATTACHMENT_SIZE_LIMIT) {
|
||
proxy.$modal.msgError(`上传文件大小不能超过 ${ATTACHMENT_SIZE_LIMIT} MB!`)
|
||
return false
|
||
}
|
||
proxy.$modal.loading('正在上传文件,请稍候...')
|
||
return true
|
||
}
|
||
|
||
function handleAttachmentUploadSuccess(res, file) {
|
||
proxy.$modal.closeLoading()
|
||
if (res.code === 200) {
|
||
form.value.attachmentList.push({
|
||
attachmentId: null,
|
||
supplierId: form.value.supplierId || null,
|
||
fileName: file.name,
|
||
filePath: res.fileName,
|
||
fileSize: file.size,
|
||
fileType: file.type || '',
|
||
fileExtension: (file.name.split('.').pop() || '').toLowerCase(),
|
||
attachmentType: '0',
|
||
isLogo: '0',
|
||
sortOrder: form.value.attachmentList.length,
|
||
remark: '',
|
||
delFlag: '0'
|
||
})
|
||
} else {
|
||
proxy.$modal.msgError(res.msg || '上传文件失败')
|
||
}
|
||
}
|
||
|
||
function handleAttachmentUploadError() {
|
||
proxy.$modal.closeLoading()
|
||
proxy.$modal.msgError('上传文件失败')
|
||
}
|
||
|
||
function handleDeleteAttachment(index) {
|
||
form.value.attachmentList.splice(index, 1)
|
||
}
|
||
|
||
/** 附件下载(携带鉴权头,并以原始文件名保存) */
|
||
function handleDownload(row) {
|
||
if (!row.filePath) {
|
||
proxy.$modal.msgWarning('该附件文件路径缺失,无法下载')
|
||
return
|
||
}
|
||
proxy.$modal.loading('正在下载文件,请稍候...')
|
||
axios({
|
||
method: 'get',
|
||
url: import.meta.env.VITE_APP_BASE_API + '/common/download/resource?resource=' + encodeURIComponent(row.filePath),
|
||
responseType: 'blob',
|
||
headers: { Authorization: 'Bearer ' + getToken() }
|
||
}).then(res => {
|
||
const blob = new Blob([res.data])
|
||
saveAs(blob, row.fileName)
|
||
}).catch(() => {
|
||
proxy.$modal.msgError('下载失败')
|
||
}).finally(() => {
|
||
proxy.$modal.closeLoading()
|
||
})
|
||
}
|
||
|
||
/* ============ 公司主体子表 ============ */
|
||
const companyDialogVisible = ref(false)
|
||
const companyDialogTitle = ref('')
|
||
const companyForm = ref({})
|
||
const companyEditingIndex = ref(-1)
|
||
|
||
function resetCompanyForm() {
|
||
companyForm.value = {
|
||
companyId: null,
|
||
supplierId: null,
|
||
companyNameFull: '',
|
||
englishName: '',
|
||
creditCode: '',
|
||
legalPerson: '',
|
||
legalPersonPhone: '',
|
||
legalPersonIdCard: '',
|
||
registeredCapital: 0,
|
||
capitalCurrency: '人民币',
|
||
paidInCapital: 0,
|
||
establishDate: null,
|
||
businessTermStart: null,
|
||
businessTermEnd: null,
|
||
businessTermPermanent: '0',
|
||
registrationAuthority: '',
|
||
registrationNumber: '',
|
||
operatingStatus: '',
|
||
businessScope: '',
|
||
shareholders: '',
|
||
employeeCount: 0,
|
||
companyPhone: '',
|
||
companyFax: '',
|
||
companyWebsite: '',
|
||
companyEmail: '',
|
||
registeredProvince: '',
|
||
registeredCity: '',
|
||
registeredDistrict: '',
|
||
registeredAddressDetail: '',
|
||
businessLicenseUrl: '',
|
||
attachmentIds: '',
|
||
remark: ''
|
||
}
|
||
proxy.resetForm('companyRef')
|
||
}
|
||
|
||
/** 新增公司主体:新增供应商态下仅存本地数组,保存主表时由后端补 supplierId 一并入库 */
|
||
function handleAddCompany() {
|
||
resetCompanyForm()
|
||
companyEditingIndex.value = -1
|
||
companyDialogTitle.value = '新增公司主体'
|
||
companyDialogVisible.value = true
|
||
}
|
||
|
||
function handleEditCompany(row, index) {
|
||
resetCompanyForm()
|
||
companyForm.value = { ...row }
|
||
companyEditingIndex.value = index
|
||
companyDialogTitle.value = '修改公司主体'
|
||
companyDialogVisible.value = true
|
||
}
|
||
|
||
/** 删除公司主体:本地新增行直接移除;已入库行先调删除接口 */
|
||
function handleDeleteCompany(row, index) {
|
||
proxy.$modal.confirm('是否确认删除该条公司主体记录?').then(() => {
|
||
const doRemove = () => {
|
||
const removed = form.value.companyList.splice(index, 1)[0]
|
||
if (removed && form.value.creditCode && removed.creditCode === form.value.creditCode) {
|
||
form.value.creditCode = ''
|
||
}
|
||
proxy.$modal.msgSuccess('删除成功')
|
||
}
|
||
if (row.companyId) {
|
||
delSupplierCompany(row.companyId).then(doRemove)
|
||
} else {
|
||
doRemove()
|
||
}
|
||
}).catch(() => {})
|
||
}
|
||
|
||
function handleBindCompany(row) {
|
||
if (!row.creditCode) {
|
||
proxy.$modal.msgWarning('该公司主体未填写统一社会信用代码,无法绑定')
|
||
return
|
||
}
|
||
form.value.creditCode = row.creditCode
|
||
if (row.companyNameFull && !form.value.supplierName) {
|
||
form.value.supplierName = row.companyNameFull
|
||
}
|
||
proxy.$modal.msgSuccess('绑定成功,主表统一社会信用代码已同步')
|
||
}
|
||
|
||
function submitCompanyForm() {
|
||
if (!companyForm.value.companyNameFull) {
|
||
proxy.$modal.msgWarning('公司全称不能为空')
|
||
return
|
||
}
|
||
if (!Array.isArray(form.value.companyList)) {
|
||
form.value.companyList = []
|
||
}
|
||
if (companyEditingIndex.value >= 0) {
|
||
form.value.companyList.splice(companyEditingIndex.value, 1, { ...companyForm.value })
|
||
if (form.value.creditCode && form.value.companyList[companyEditingIndex.value].creditCode !== form.value.creditCode) {
|
||
form.value.creditCode = form.value.companyList[companyEditingIndex.value].creditCode || form.value.creditCode
|
||
}
|
||
} else {
|
||
form.value.companyList.push({ ...companyForm.value })
|
||
}
|
||
companyDialogVisible.value = false
|
||
proxy.$modal.msgSuccess(companyEditingIndex.value >= 0 ? '修改成功' : '新增成功,保存供应商后生效')
|
||
}
|
||
|
||
/* ============ 联系人子表 ============ */
|
||
const contactDialogVisible = ref(false)
|
||
const contactDialogTitle = ref('')
|
||
const contactForm = ref({})
|
||
const contactEditingIndex = ref(-1)
|
||
const contactRules = {
|
||
contactName: [{ required: true, message: '联系人姓名不能为空', trigger: 'blur' }],
|
||
phone: [{ required: true, message: '手机号不能为空', trigger: 'blur' }]
|
||
}
|
||
|
||
function resetContactForm() {
|
||
contactForm.value = {
|
||
contactId: null,
|
||
supplierId: form.value.supplierId || null,
|
||
contactName: '',
|
||
position: '',
|
||
department: '',
|
||
phone: '',
|
||
landline: '',
|
||
email: '',
|
||
wechat: '',
|
||
qq: '',
|
||
country: '中国',
|
||
province: '',
|
||
city: '',
|
||
district: '',
|
||
contactAddress: '',
|
||
postalCode: '',
|
||
isDefault: '0',
|
||
contactType: '0',
|
||
sortOrder: 0,
|
||
remark: ''
|
||
}
|
||
proxy.resetForm('contactRef')
|
||
}
|
||
|
||
function handleAddContact() {
|
||
resetContactForm()
|
||
contactEditingIndex.value = -1
|
||
contactDialogTitle.value = '新增联系人'
|
||
contactDialogVisible.value = true
|
||
}
|
||
|
||
function handleEditContact(row, index) {
|
||
resetContactForm()
|
||
contactForm.value = { ...row }
|
||
contactEditingIndex.value = index
|
||
contactDialogTitle.value = '修改联系人'
|
||
contactDialogVisible.value = true
|
||
}
|
||
|
||
/** 删除联系人:本地新增行直接移除;已入库行先调删除接口 */
|
||
function handleDeleteContact(row, index) {
|
||
proxy.$modal.confirm('是否确认删除该条联系人记录?').then(() => {
|
||
if (row.contactId) {
|
||
delSupplierContact(row.contactId).then(() => {
|
||
form.value.contactList.splice(index, 1)
|
||
proxy.$modal.msgSuccess('删除成功')
|
||
})
|
||
} else {
|
||
form.value.contactList.splice(index, 1)
|
||
proxy.$modal.msgSuccess('删除成功')
|
||
}
|
||
}).catch(() => {})
|
||
}
|
||
|
||
function submitContactForm() {
|
||
if (!contactForm.value.contactName) {
|
||
proxy.$modal.msgWarning('联系人姓名不能为空')
|
||
return
|
||
}
|
||
if (!Array.isArray(form.value.contactList)) {
|
||
form.value.contactList = []
|
||
}
|
||
if (contactEditingIndex.value >= 0) {
|
||
form.value.contactList.splice(contactEditingIndex.value, 1, { ...contactForm.value })
|
||
} else {
|
||
form.value.contactList.push({ ...contactForm.value })
|
||
}
|
||
contactDialogVisible.value = false
|
||
proxy.$modal.msgSuccess(contactEditingIndex.value >= 0 ? '修改成功' : '新增成功,保存供应商后生效')
|
||
}
|
||
|
||
/* ============ 加载 / 保存 ============ */
|
||
/** 重新拉取详情(新增保存后或修改保存后调用,确保子表主键、附件重建结果与库一致) */
|
||
function loadDetail(id) {
|
||
return getSupplier(id).then(response => {
|
||
if (!response.data) {
|
||
proxy.$modal.msgError('该供应商不存在或已被删除')
|
||
return
|
||
}
|
||
form.value = response.data
|
||
form.value.attachmentList = form.value.attachmentList || []
|
||
form.value.companyList = form.value.companyList || []
|
||
form.value.contactList = form.value.contactList || []
|
||
})
|
||
}
|
||
|
||
/** 保存:新增成功后留在本页(URL 替换为编辑态),可继续维护子表 */
|
||
function submitForm() {
|
||
proxy.$refs['supplierRef'].validate(valid => {
|
||
if (!valid) {
|
||
activeTab.value = 'base'
|
||
return
|
||
}
|
||
const nullIfEmpty = v => (v === '' || v === undefined ? null : v)
|
||
const payload = {
|
||
...form.value,
|
||
purchaserUserId: nullIfEmpty(form.value.purchaserUserId),
|
||
purchaserUser: nullIfEmpty(form.value.purchaserUser),
|
||
settlementUserId: nullIfEmpty(form.value.settlementUserId),
|
||
settlementUser: nullIfEmpty(form.value.settlementUser),
|
||
serviceUserId: nullIfEmpty(form.value.serviceUserId),
|
||
serviceUser: nullIfEmpty(form.value.serviceUser)
|
||
}
|
||
saving.value = true
|
||
const req = isAdd.value ? addSupplier(payload) : updateSupplier(payload)
|
||
req.then(res => {
|
||
if (isAdd.value) {
|
||
const newId = res.supplierId || res.data?.supplierId
|
||
proxy.$modal.msgSuccess('新增成功,已进入编辑页,可继续维护公司主体、联系人和附件')
|
||
// 替换为编辑态(query 变化触发 watch 自动拉取详情),避免返回/刷新再次新增
|
||
router.replace({ path: '/customersupplier/supplier-edit/index', query: { supplierId: newId } })
|
||
return
|
||
}
|
||
proxy.$modal.msgSuccess('保存成功')
|
||
return loadDetail(form.value.supplierId)
|
||
}).finally(() => {
|
||
saving.value = false
|
||
})
|
||
})
|
||
}
|
||
|
||
function goBack() {
|
||
router.push({ path: '/customersuppliermanagement/supplierinfo' })
|
||
}
|
||
|
||
/* ============ 初始化 ============ */
|
||
/** 按当前路由初始化页面:有supplierId拉详情,无则空表单(同路由组件复用时靠 watch 触发) */
|
||
function initByRoute() {
|
||
companyDialogVisible.value = false
|
||
contactDialogVisible.value = false
|
||
activeTab.value = 'base'
|
||
if (supplierId.value) {
|
||
pageLoading.value = true
|
||
loadDetail(supplierId.value).finally(() => { pageLoading.value = false })
|
||
} else {
|
||
form.value = buildEmptyForm()
|
||
}
|
||
}
|
||
|
||
watch(() => route.query.supplierId, (newVal, oldVal) => {
|
||
if (String(newVal || '') === String(oldVal || '')) return
|
||
initByRoute()
|
||
})
|
||
|
||
onMounted(() => {
|
||
initByRoute()
|
||
})
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.head-card {
|
||
margin-bottom: 12px;
|
||
}
|
||
.head-bar {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 14px;
|
||
}
|
||
.head-title {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 8px;
|
||
}
|
||
.supplier-name {
|
||
font-size: 16px;
|
||
font-weight: 600;
|
||
color: #303133;
|
||
}
|
||
.head-code {
|
||
color: #909399;
|
||
font-size: 13px;
|
||
}
|
||
.head-right {
|
||
margin-left: auto;
|
||
}
|
||
.pane-toolbar {
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 10px;
|
||
margin-bottom: 12px;
|
||
flex-wrap: wrap;
|
||
}
|
||
.pane-tip {
|
||
color: #909399;
|
||
font-size: 12px;
|
||
}
|
||
</style>
|