客户新增

This commit is contained in:
‘huanghaiixia’
2025-11-25 12:12:15 +08:00
parent 65575b40ad
commit c8c20d5b52
6 changed files with 556 additions and 78 deletions

View File

@ -6,10 +6,10 @@
<a-button style="margin-right: 10px" @click="close">
<slot name="icon"><close-outlined /></slot>取消
</a-button>
<a-button v-if="mode != 'view'" style="margin-right: 10px" type="primary" @click="handleSubmit">
<a-button v-if="mode != 'view'" style="margin-right: 10px" type="primary" @click="handleSubmit('save')">
<slot name="icon"><save-outlined /></slot>保存
</a-button>
<a-button v-if="mode != 'view'" style="margin-right: 10px" type="primary" @click="handleSubmit">
<a-button v-if="mode != 'view'" style="margin-right: 10px" type="primary" @click="handleSubmit('submit')">
<slot name="icon"><check-circle-outlined /></slot>保存并提交
</a-button>
<a-button v-if="mode != 'view'" style="margin-right: 10px" type="primary" @click="handleSubmit">
@ -45,13 +45,13 @@
</a-form-item>
</a-col>
<a-col :span="24">
<a-form-item label="客户名称" name="cuName" :label-col="{ span: 3 }" :wrapper-col="{ span: 24 }">
<a-textarea v-model:value="formState.cuName" placeholder="请输入客户名称" :auto-size="{ minRows: 1, maxRows: 5 }"/>
<a-form-item label="客户名称" name="cuSname" :label-col="{ span: 3 }" :wrapper-col="{ span: 24 }">
<a-textarea v-model:value="formState.cuSname" placeholder="请输入客户名称" :auto-size="{ minRows: 1, maxRows: 5 }"/>
</a-form-item>
</a-col>
<a-col :span="8">
<a-form-item label="客户简称" name="cuSname">
<a-input v-model:value="formState.cuSname" placeholder="请输入客户简称" />
<a-form-item label="客户简称" name="di">
<a-input v-model:value="formState.di" placeholder="请输入客户简称" />
</a-form-item>
</a-col>
<a-col :span="8">
@ -235,15 +235,15 @@
<span style="font-size: 12px;font-weight: normal;">需上传证书营业执照危险化学品许可证/燃气经营许可证/危险化学品道路运输许可证等证书</span>
</div>
</template>
<a-button v-if="mode != 'view'" type="primary" @click="handleAdd('certificate')">新增证书</a-button>
<a-button v-if="mode != 'view'" type="primary" style="margin-bottom: 10px;" @click="handleAdd('certificate')">新增证书</a-button>
<a-table :columns="columnsCertificate" :data-source="dataCertificate" >
<template #bodyCell="{ column, record }">
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'operation'">
<a style="margin-right: 10px" @click="btnCheck('certificate', 'edit', record)">编辑</a>
<a style="margin-right: 10px" @click="btnCheck('certificate', 'delete', record)">删除</a>
<a style="margin-right: 10px" @click="btnCheck('certificate', 'delete', record, index)">删除</a>
<a style="margin-right: 10px" @click="btnCheck('certificate', 'view', record)">查看</a>
<ArrowUpOutlined style="margin-right: 10px;" class="btn" @click="btnCheck('certificate', 'up', record, column.index)" />
<ArrowDownOutlined class="btn" @click="btnCheck('certificate', 'down', record, column.index)" />
<ArrowUpOutlined style="margin-right: 10px;" class="btn" @click="btnCheck('certificate', 'up', record, index)" />
<ArrowDownOutlined class="btn" @click="btnCheck('certificate', 'down', record, index)" />
</template>
</template>
</a-table>
@ -256,8 +256,14 @@
<span style="font-size: 12px;font-weight: normal;">至少填写一条银行信息</span>
</div>
</template>
<a-button v-if="mode != 'view'" type="primary" @click="handleAdd('bank')">新增银行账户</a-button>
<a-button v-if="mode != 'view'" type="primary" style="margin-bottom: 10px;" @click="handleAdd('bank')">新增银行账户</a-button>
<a-table :columns="columnsBank" :data-source="dataBank" >
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'operation'">
<a style="margin-right: 10px" @click="btnCheck('bank', 'edit', record)">编辑</a>
<a style="margin-right: 10px" @click="btnCheck('bank', 'delete', record, index)">删除</a>
</template>
</template>
</a-table>
</a-card>
<a-card :bordered="false" >
@ -268,12 +274,12 @@
<span style="font-size: 12px;font-weight: normal;">至少填写一条联系人信息</span>
</div>
</template>
<a-button v-if="mode != 'view'" type="primary" @click="handleAdd('contact')">新增联系人</a-button>
<a-button v-if="mode != 'view'" type="primary" style="margin-bottom: 10px;" @click="handleAdd('contact')">新增联系人</a-button>
<a-table :columns="columnsContact" :data-source="dataContact" >
<template #bodyCell="{ column, record }">
<template #bodyCell="{ column, record, index }">
<template v-if="column.dataIndex === 'operation'">
<a style="margin-right: 10px" @click="btnCheck('contact', 'edit', record)">编辑</a>
<a style="margin-right: 10px" @click="btnCheck('contact', 'delete', record)">删除</a>
<a style="margin-right: 10px" @click="btnCheck('contact', 'delete', record, index)">删除</a>
</template>
</template>
</a-table>
@ -286,10 +292,11 @@
</div>
</template>
<a-upload
v-model:file-list="fileList"
:multiple="true"
:showUploadList="false"
name="file"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
:action="data.action"
:headers="data.headers"
@change="handleChangeFile"
>
<a-button>
@ -298,6 +305,19 @@
</a-button>
</a-upload>
<a-table :columns="columnsFile" :data-source="dataFile" >
<template #bodyCell="{ column,record,index, text }">
<template v-if="column.dataIndex === 'fileOrg'">
<a :href="record.filePath" :download="record.fileOrg" target="_blank">{{record.fileOrg}}</a>
</template>
<template v-if="column.dataIndex === 'docDesc'">
<a-input :placeholder="t('请输入附件说明')" v-model:value="record.docDesc" />
</template>
<template v-if="column.dataIndex === 'operation'">
<a style="margin-right: 10px" @click="btnCheck('file', 'delete', record, index)">删除</a>
<ArrowUpOutlined style="margin-right: 10px;" class="btn" @click="btnCheck('file', 'up', record, index)" />
<ArrowDownOutlined class="btn" @click="btnCheck('file', 'down', record, index)" />
</template>
</template>
</a-table>
</a-card>
</a-form>
@ -305,6 +325,7 @@
</a-spin>
<certificateModal @register="registerCertificate" @success="handleSuccessCertificate" />
<contactModal @register="registerContact" @success="handleSuccessContact" />
<bankModal @register="registerBank" @success="handleSuccessBank"/>
</template>
<script lang="ts" setup>
@ -320,9 +341,15 @@
import { getDictionary } from '/@/api/sales/Customer';
import certificateModal from './components/certificateModal.vue';
import contactModal from './components/contactModal.vue';
import bankModal from './components/bankModal.vue';
import { useModal } from '/@/components/Modal';
import { validateScript } from '/@/utils/event/design';
import { addLngCustomer,updateLngCustomer,getLngCustomer } from '/@/api/sales/Customer';
import dayjs from 'dayjs';
import { getAppEnvConfig } from '/@/utils/env';
import { getToken } from '/@/utils/auth';
import { uploadSrc, uploadBlobApi } from '/@/api/sys/upload';
import { message } from 'ant-design-vue';
const dynamicComponent = ref(null);
const formType = ref('2'); // 0 新建 1 修改 2 查看
const formRef = ref();
@ -338,24 +365,22 @@ import { validateScript } from '/@/utils/event/design';
const tabStore = useMultipleTabStore();
const formProps = ref(null);
const formId = ref(currentRoute.value?.params?.id);
const pageType = ref(currentRoute.value?.params?.type);
const pageId = ref(currentRoute.value?.params?.id || '');
const spinning = ref(false);
const { notification } = useMessage();
const { t } = useI18n();
const hash = location.hash || location.pathname;
const mode = ref('read');
if (hash.indexOf('createForm') > 0) {
mode.value = 'create';
} else if (hash.indexOf('updateForm') > 0) {
mode.value = 'update';
} else if (hash.indexOf('viewForm') > 0) {
mode.value = 'view';
}
const data = reactive({
info: {},
action: '',
headers: { Authorization: '' },
photoUrl: '',
});
const formState = reactive({
valid: 'Y',
approCode: 'WTJ',
tSign: 'N',
lngCustomerAttrPowerList:[
{
"capacity": '',
@ -366,11 +391,12 @@ import { validateScript } from '/@/utils/event/design';
const [registerCertificate, { openModal:openModalCertificate }] = useModal();
const [registerContact, { openModal:openModalContact }] = useModal();
const [registerBank, { openModal:openModalBank}] = useModal();
const fileList = reactive([])
const rules: Record<string, Rule[]> = {
cuMcode: [{ required: true, message: "该项为必填项", trigger: 'change' }],
cuName: [{ required: true, message: "该项为必填项", trigger: 'change' }],
di: [{ required: true, message: "该项为必填项", trigger: 'change' }],
cuSname: [{ required: true, message: "该项为必填项", trigger: 'change'}],
natureCode: [{ required: true, message: "该项为必填项", trigger: 'change'}],
classCode: [{ required: true, message: "该项为必填项", trigger: 'change'}],
@ -378,6 +404,7 @@ import { validateScript } from '/@/utils/event/design';
prepaySign: [{ required: true, message: "该项为必填项", trigger: 'change'}],
onlineSign: [{ required: true, message: "该项为必填项", trigger: 'change'}],
rateShare: [{ required: false, message: "该项为必填项", trigger: 'change'}],
tSign: [{ required: false, message: "该项为必填项", trigger: 'change'}],
};
const layout = {
labelCol: { span: 9 },
@ -434,8 +461,22 @@ import { validateScript } from '/@/utils/event/design';
onMounted(() => {
getOption()
if (pageId.value) {
getList(pageId.value)
}
data.action = getAppEnvConfig().VITE_GLOB_API_URL + uploadSrc;
data.headers.Authorization = `Bearer ${getToken()}`;
});
async function getList(id) {
let data = await getLngCustomer(id)
Object.assign(formState, {...data})
formState.lngCustomerAttrPowerList = formState.lngCustomerAttrPowerList || [{}]
Object.assign(dataBank, formState.lngCustomerBankList || [])
Object.assign(dataCertificate, formState.lngCustomerDocList || [])
Object.assign(dataContact, formState.lngCustomerContactList || [])
Object.assign(dataUpload, formState.lngFileUploadList || [])
}
async function getOption() {
optionSelect.cuMcodeList = await getDictionary('LNG_ENT_PR')
optionSelect.natureCodeList = await getDictionary('LNG_NATURE')
@ -461,44 +502,122 @@ import { validateScript } from '/@/utils/event/design';
}
const handleAdd = (val)=> {
if (val ==='certificate') {
openModalCertificate(true,);
openModalCertificate(true,{isUpdate: false});
}
if (val ==='contact'){
openModalContact(true, {});
}
if (val == 'bank'){
openModalBank(true,{isUpdate: false})
}
}
const btnCheck = (type, btn, record, index) => {
console.log(index, 555, type, )
// 证书
if (type == 'certificate') {
if (btn == 'edit') {
openModalCertificate(true, {record: record,isUpdate: true});
if (btn == 'edit' || btn == 'view') {
openModalCertificate(true, {record: record,isUpdate: true, btnType: btn});
}
if (type === 'delete') {
if (btn == 'delete') {
dataCertificate.splice(index, 1)
}
if (btn == 'up') {
if (index === 0) {
return
}
dataCertificate[index] = dataCertificate.splice(index-1, 1, dataCertificate[index])[0];
}
if (btn == 'down') {
if (index === dataCertificate.length - 1) {
return
}
dataCertificate[index] = dataCertificate.splice(index+1, 1, dataCertificate[index])[0];
}
}
// 联系人
if (type == 'contact') {
if (btn == 'edit') {
openModalContact(true, {record: record,isUpdate: true});
}
if (type === 'delete') {
if (btn == 'delete') {
dataContact.splice(index, 1)
}
}
// 银行
if (type == 'bank') {
if (btn == 'edit') {
openModalBank(true, {record: record,isUpdate: true});
}
if (btn == 'delete') {
dataBank.splice(index, 1)
}
}
// 附件
if (type == 'file') {
if (btn == 'delete') {
dataFile.splice(index, 1)
}
if (btn == 'up') {
if (index === 0) {
return
}
dataFile[index] = dataFile.splice(index-1, 1, dataFile[index])[0];
}
if (btn == 'down') {
if (index === dataFile.length - 1) {
return
}
dataFile[index] = dataFile.splice(index+1, 1, dataFile[index])[0];
}
}
}
const swapItems = (arr, index1, index2,direction) =>{
arr[index1] = arr.splice(index2, 1, arr[index1])[0];
return arr;
};
const handleSuccessCertificate = (val) => {
let idx =dataCertificate.findIndex(v => v.docTypeCode == val.docTypeCode)
if (!idx) {
if (idx <0) {
dataCertificate.push(val)
}
}
const handleSuccessContact = (val)=> {
dataContact.push(val)
}
function handleChangeFile(val) {
const handleSuccessBank = (val) => {
dataBank.push(val)
}
function handleChangeFile(info) {
console.log(info, 'info', info.file.status)
if (info.file.status !== 'uploading') {
}
if (info.file.status === 'done') {
if (info.file && info.file.response && info.file.response.code == 0) {
message.success(t(`{name}上传成功!`, { name: info.file.name }));
console.log(info, t('上传成功'));
// 存储原始URL到info.fileUrl用于提交改了
data.info.fileUrl = info.file.response.data.fileUrl;
data.fileName = info.file.response.data.fileName;
// 显示使用fileUrlFixed如果有否则使用fileUrl (改了)
data.photoUrl = info.file.response.data.fileUrlFixed || info.file.response.data.fileUrl;
let obj = {
fileOrg: data.fileName,
filePath: data.photoUrl,
}
dataFile.push(obj)
} else {
message.error(t('上传照片失败'));
}
} else if (info.file.status === 'error') {
message.error(t(`{name}上传失败.`, { name: info.file.name }));
}
}
@ -525,37 +644,70 @@ import { validateScript } from '/@/utils/event/design';
}
function close() {
tabStore.closeTab(currentRoute.value, router);
tabStore.closeTab(currentRoute.value, router);
}
async function handleSubmit() {
try {
await formRef.value.validateFields();
console.log(44454)
return true;
} catch (errorInfo) {
console.log(444)
return false;
async function handleSubmit(type) {
try {
await formRef.value.validateFields();
if (!dataBank.length) {
notification.warning({
message: 'Tip',
description: '请添加银行信息'
})
return
}
if (!dataCertificate.length) {
notification.warning({
message: 'Tip',
description: '请添加资质证书'
})
return
}
if (!dataContact.length) {
notification.warning({
message: 'Tip',
description: '请添加联系人'
})
return
}
let obj = {
...formState,
lngCustomerBankList: dataBank,
lngCustomerDocList: dataCertificate,
lngCustomerContactList: dataContact,
}
spinning.value = true;
let request = pageType.value === 'add' ? addLngCustomer :updateLngCustomer
try {
obj.lngCustomerDocList.forEach(v => {
v.dateFrom = dayjs(v.dateFrom ).valueOf()
v.dateTo = dayjs(v.dateTo ).valueOf()
})
await request(obj);
notification.success({
message: 'Tip',
description: pageType.value === 'add' ? t('新增成功!') : t('修改成功!')
}); //提示消息
formRef.value.resetFields();
setTimeout(() => {
bus.emit(FORM_LIST_MODIFIED, { path: formPath });
close();
}, 1000);
} finally {
spinning.value = false;
}
return
spinning.value = true;
try {
const saveSuccess = await saveModal();
if (saveSuccess) {
notification.success({
message: 'Tip',
description: formType.value === '0' ? t('新增成功!') : t('修改成功!')
}); //提示消息
formRef.value.resetFields();
setTimeout(() => {
bus.emit(FORM_LIST_MODIFIED, { path: formPath, mode });
close();
}, 1000);
}
} finally {
spinning.value = false;
}
} catch (errorInfo) {
notification.warning({
message: 'Tip',
description: '请完善信息'
});
}
}
async function saveModal() {