1.1.62 订单激活时校验客户开票资料,若为空则弹框维护客户信息。

dev
yinq 17 hours ago
parent e52c0893ac
commit 5795a7e3ec

@ -1,7 +1,7 @@
import request from '@/utils/request';
import { AxiosPromise } from 'axios';
import { ProjectInfoVO, ProjectInfoForm, ProjectInfoQuery } from '@/api/oa/erp/projectInfo/types';
import { ContractOrderPurchaseMaterialVO } from '@/api/oa/erp/contractOrder/types';
import { ContractOrderPurchaseMaterialVO, PartyACustomerValidateVO } from '@/api/oa/erp/contractOrder/types';
/**
*
@ -87,3 +87,14 @@ export const getContractOrderPurchaseMaterialList = (projectId: string | number)
});
};
/**
*
* @param contractId ID
*/
export const validPartyACustomerForOrderActivate = (contractId: string | number): AxiosPromise<PartyACustomerValidateVO> => {
return request({
url: '/oa/erp/contractOrder/validPartyACustomer/' + contractId,
method: 'get'
});
};

@ -10,3 +10,15 @@ export interface ContractOrderPurchaseMaterialVO {
purchasedAmount?: number;
unpurchasedAmount?: number;
}
/** 订单激活甲方客户信息校验结果 */
export interface PartyACustomerValidateVO {
valid: boolean;
oneCustomerId?: string | number;
customerName?: string;
ossIdMissing?: boolean;
taxNumberMissing?: boolean;
bankAccountOpeningMissing?: boolean;
bankNumberMissing?: boolean;
message?: string;
}

@ -10,6 +10,22 @@
>
本合同由合同内容变更生成激活后将继承原合同关联项目并作废原合同下方关联项目已预填原合同项目
</el-alert>
<el-alert
v-if="partyACustomerValidate && !partyACustomerValidate.valid"
type="warning"
:closable="false"
show-icon
style="margin-bottom: 12px"
>
<template #default>
<span>
合同甲方客户{{ partyACustomerValidate.customerName || '—' }}信息不完整缺少{{ partyACustomerMissingText }}订单激活前请先完善客户信息
</span>
<el-button v-if="!isFormDisabled" type="primary" link style="margin-left: 8px" @click="openPartyACustomerDialog">
维护客户信息
</el-button>
</template>
</el-alert>
<el-card shadow="never" style="margin-top: 0">
<approvalButton
@submitForm="submitForm"
@ -438,6 +454,41 @@
@confirm-call-back="projectSelectCallback"
/>
<!-- 维护甲方客户信息 -->
<el-dialog
v-model="partyACustomerDialog.visible"
title="维护甲方客户信息"
width="640px"
append-to-body
destroy-on-close
>
<el-form ref="partyACustomerFormRef" :model="partyACustomerForm" :rules="partyACustomerRules" label-width="100px">
<el-form-item label="客户名称">
<el-input v-model="partyACustomerForm.customerName" disabled />
</el-form-item>
<el-form-item label="税号" prop="taxNumber">
<el-input v-model="partyACustomerForm.taxNumber" placeholder="请输入税号" />
</el-form-item>
<el-form-item label="开户银行" prop="bankAccountOpening">
<el-input v-model="partyACustomerForm.bankAccountOpening" placeholder="请输入开户银行" />
</el-form-item>
<el-form-item label="银行账号" prop="bankNumber">
<el-input v-model="partyACustomerForm.bankNumber" placeholder="请输入银行账号" />
</el-form-item>
<el-form-item label="开票附件" prop="ossId">
<FileUpload
v-model="partyACustomerOssIdString"
:limit="5"
:fileType="['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt', 'pdf', 'zip', 'rar', 'jpg', 'jpeg', 'png']"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button type="primary" :loading="partyACustomerDialog.loading" @click="submitPartyACustomerForm"> </el-button>
<el-button @click="partyACustomerDialog.visible = false"> </el-button>
</template>
</el-dialog>
<!-- 提交审批组件 -->
<submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" />
<!-- 审批记录 -->
@ -450,7 +501,8 @@ import { ref, reactive, computed, toRefs, getCurrentInstance, onMounted, nextTic
import { useRoute, useRouter } from 'vue-router';
import type { ComponentInternalInstance } from 'vue';
import { getErpProjectInfoList, getProjectInfo } from '@/api/oa/erp/projectInfo';
import { saveContractOrder, updateContractOrder, submitContractOrderAndFlowStart } from '@/api/oa/erp/contractOrder';
import { saveContractOrder, updateContractOrder, submitContractOrderAndFlowStart, validPartyACustomerForOrderActivate } from '@/api/oa/erp/contractOrder';
import type { PartyACustomerValidateVO } from '@/api/oa/erp/contractOrder/types';
import { ProjectInfoForm, ProjectInfoVO } from '@/api/oa/erp/projectInfo/types';
import { getErpProjectContractsList } from '@/api/oa/erp/projectContracts';
import { ProjectContractsVO } from '@/api/oa/erp/projectContracts/types';
@ -470,7 +522,8 @@ import type { FormInstance } from 'element-plus';
import { getErpProjectPlanStageList, listErpProjectPlanStage } from '@/api/oa/erp/erpProjectPlanStage';
import { ErpProjectPlanStageForm, ErpProjectPlanStageQuery } from '@/api/oa/erp/erpProjectPlanStage/types';
import { listContractInfo, getContractInfo } from '@/api/oa/erp/contractInfo';
import { getCrmCustomerInfoList } from '@/api/oa/crm/customerInfo';
import { getCrmCustomerInfoList, getCustomerInfo, updateCustomerInfo } from '@/api/oa/crm/customerInfo';
import type { CustomerInfoForm } from '@/api/oa/crm/customerInfo/types';
import { getBasePaymentStageList } from '@/api/oa/base/paymentStage';
import { PaymentStageVO } from '@/api/oa/base/paymentStage/types';
import { getInfo } from '@/api/login';
@ -953,6 +1006,110 @@ const REPAYMENT_RATE_EPSILON = 0.01;
/** 是否禁用表单(查看/审批模式) */
const isFormDisabled = computed(() => routeParams.value.type === 'view' || routeParams.value.type === 'approval');
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
const partyACustomerValidate = ref<PartyACustomerValidateVO | null>(null);
const partyACustomerFormRef = ref<FormInstance>();
const partyACustomerFullData = ref<CustomerInfoForm | null>(null);
const partyACustomerDialog = reactive({
visible: false,
loading: false
});
const partyACustomerForm = reactive({
customerName: '',
taxNumber: '',
bankAccountOpening: '',
bankNumber: '',
ossId: undefined as string | number | undefined
});
const partyACustomerRules = {
taxNumber: [{ required: true, message: '税号不能为空', trigger: 'blur' }],
bankAccountOpening: [{ required: true, message: '开户银行不能为空', trigger: 'blur' }],
bankNumber: [{ required: true, message: '银行账号不能为空', trigger: 'blur' }],
ossId: [{ required: true, message: '请上传开票附件', trigger: 'change' }]
};
const partyACustomerOssIdString = computed({
get() {
const v = partyACustomerForm.ossId;
return v === undefined || v === null ? '' : String(v);
},
set(val: string) {
partyACustomerForm.ossId = val || undefined;
}
});
const partyACustomerMissingText = computed(() => {
const result = partyACustomerValidate.value;
if (!result) return '';
const labels: string[] = [];
if (result.ossIdMissing) labels.push('附件');
if (result.taxNumberMissing) labels.push('税号');
if (result.bankAccountOpeningMissing) labels.push('开户银行');
if (result.bankNumberMissing) labels.push('银行账号');
return labels.join('、') || '—';
});
const checkPartyACustomerForOrderActivate = async () => {
const contractId = form.value.contractId || routeParams.value.contractId;
if (!contractId) {
partyACustomerValidate.value = null;
return;
}
try {
const res = await validPartyACustomerForOrderActivate(contractId);
partyACustomerValidate.value = res.data;
} catch (error) {
console.error('校验甲方客户信息失败:', error);
partyACustomerValidate.value = null;
}
};
const openPartyACustomerDialog = async () => {
const customerId = partyACustomerValidate.value?.oneCustomerId;
if (!customerId) {
proxy?.$modal.msgWarning('未获取到甲方客户信息');
return;
}
try {
const res = await getCustomerInfo(customerId);
partyACustomerFullData.value = { ...(res.data || {}) };
partyACustomerForm.customerName = res.data?.customerName || '';
partyACustomerForm.taxNumber = res.data?.taxNumber || '';
partyACustomerForm.bankAccountOpening = res.data?.bankAccountOpening || '';
partyACustomerForm.bankNumber = res.data?.bankNumber || '';
partyACustomerForm.ossId = res.data?.ossId;
partyACustomerDialog.visible = true;
} catch (error) {
console.error('加载客户信息失败:', error);
proxy?.$modal.msgError('加载客户信息失败');
}
};
const submitPartyACustomerForm = () => {
partyACustomerFormRef.value?.validate(async (valid: boolean) => {
if (!valid || !partyACustomerFullData.value?.customerId) return;
partyACustomerDialog.loading = true;
try {
await updateCustomerInfo({
...partyACustomerFullData.value,
taxNumber: partyACustomerForm.taxNumber,
bankAccountOpening: partyACustomerForm.bankAccountOpening,
bankNumber: partyACustomerForm.bankNumber,
ossId: partyACustomerForm.ossId
});
proxy?.$modal.msgSuccess('客户信息保存成功');
partyACustomerDialog.visible = false;
await checkPartyACustomerForOrderActivate();
} catch (error) {
console.error('保存客户信息失败:', error);
} finally {
partyACustomerDialog.loading = false;
}
});
};
/** 附件 ID 与字符串双向转换(供 FileUpload 使用) */
const ossIdString = computed({
get() {
@ -1022,6 +1179,10 @@ function isRepaymentRateTotalValid(): boolean {
const submitForm = (status: string, mode: boolean) => {
projectInfoFormRef.value?.validate(async (valid: boolean) => {
if (!valid) return;
if (!isFormDisabled.value && partyACustomerValidate.value && !partyACustomerValidate.value.valid) {
proxy?.$modal.msgWarning('请先完善合同甲方客户信息(附件、税号、开户银行、银行账号)');
return;
}
if (!isRepaymentRateTotalValid()) {
proxy?.$modal.msgWarning('回款信息预计回款比例之和必须为100%');
return;
@ -1254,6 +1415,7 @@ onMounted(async () => {
console.error('获取合同信息失败:', error);
}
}
await checkPartyACustomerForOrderActivate();
proxy?.$modal.closeLoading();
});
});

Loading…
Cancel
Save