采购更新

This commit is contained in:
吴红兵
2026-03-11 22:14:38 +08:00
parent 4fe8453fdf
commit ad78c6c70d
4 changed files with 208 additions and 122 deletions

View File

@@ -75,7 +75,7 @@
<el-divider content-position="left">审核流程</el-divider>
<flow-comment-timeline v-if="flowInstId" :flow-inst-id="flowInstId" />
<FlowCommentTimeline v-if="flowInstId" :curr-job="{ flowInstId }" />
</template>
<template #footer>
@@ -91,11 +91,13 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { ref, defineAsyncComponent } from 'vue';
import { useMessage } from '/@/hooks/message';
import { getDetail } from '/@/api/purchase/purchasingcontract';
import { previewFileById, downloadFileById } from '/@/api/purchase/purchasingrequisition';
const FlowCommentTimeline = defineAsyncComponent(() => import('/@/views/jsonflow/comment/timeline.vue'));
interface FileItem {
id: string;
name: string;

View File

@@ -16,7 +16,7 @@
<el-row :gutter="20">
<el-col :span="12" class="mb12">
<el-form-item label="合同编号" prop="contractNo">
<el-input v-model="formData.contractNo" placeholder="请输入合同编号" />
<el-input v-model="formData.contractNo" placeholder="请输入合同编号" disabled />
</el-form-item>
</el-col>
<el-col :span="12" class="mb12">
@@ -178,12 +178,17 @@ const open = async (id: string, openMode: 'add' | 'edit' | 'view' = 'add') => {
const res = await getObj(id);
applyData.value = res?.data || {};
// 新增时,合同编号默认为采购编号
if (mode.value === 'add') {
formData.value.contractNo = applyData.value.purchaseNo || '';
}
const contractRes = await getByPurchaseId(id);
const contractData = contractRes?.data;
if (contractData) {
formData.value = {
purchaseId: id,
contractNo: contractData.contractNo || '',
contractNo: contractData.contractNo || applyData.value.purchaseNo || '',
contractName: contractData.contractName || '',
money: contractData.money,
isBidding: contractData.isBidding || '0',
@@ -215,7 +220,7 @@ const open = async (id: string, openMode: 'add' | 'edit' | 'view' = 'add') => {
console.error('获取数据失败', e);
useMessage().error('获取数据失败');
}
};
};
const resetForm = () => {
formData.value = {

View File

@@ -33,24 +33,24 @@
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="160px" :disabled="isViewMode">
<el-row :gutter="20">
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="合同编号" prop="contractNo">
<el-input v-model="formData.contractNo" placeholder="请输入合同编号" />
<el-input v-model="formData.contractNo" placeholder="请输入合同编号" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="合同名称" prop="contractName">
<el-input v-model="formData.contractName" placeholder="请输入合同名称" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="合同金额(元)" prop="money">
<el-input-number v-model="formData.money" :precision="2" :min="0" :controls="false" style="width: 100%" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="是否需要招标" prop="isBidding">
<el-radio-group v-model="formData.isBidding">
<el-radio label="0"></el-radio>
@@ -60,7 +60,7 @@
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="是否需要法律顾问" prop="isLegalAdviser">
<el-radio-group v-model="formData.isLegalAdviser">
<el-radio label="0"></el-radio>
@@ -68,7 +68,7 @@
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="是否涉及多个部门" prop="isDepts">
<el-radio-group v-model="formData.isDepts">
<el-radio label="0"></el-radio>
@@ -78,7 +78,7 @@
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-col :span="12" class="mb12">
<el-form-item label="是否全校合同" prop="isSchool">
<el-radio-group v-model="formData.isSchool">
<el-radio label="0"></el-radio>
@@ -150,7 +150,7 @@ import { useRoute } from 'vue-router';
import { Document, Tickets, FolderOpened } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { getObj } from '/@/api/purchase/purchasingrequisition';
import { getByPurchaseId, updateContract } from '/@/api/purchase/purchasingcontract';
import { getByPurchaseId, getByFlowInstId, updateContract } from '/@/api/purchase/purchasingcontract';
import { previewFileById, downloadFileById } from '/@/api/purchase/purchasingrequisition';
import { currElTabIsSave } from '/@/api/order/order-key-vue';
@@ -208,6 +208,13 @@ const previewVisible = ref(false);
const previewTitle = ref('');
const previewUrl = ref('');
const effectiveFlowInstId = computed(() => {
if (props.currJob?.flowInstId) {
return props.currJob.flowInstId;
}
return route.query.flowInstId ? Number(route.query.flowInstId) : null;
});
const effectivePurchaseId = computed(() => {
if (props.currJob?.orderId) {
return String(props.currJob.orderId);
@@ -232,41 +239,76 @@ const loadApplyData = async () => {
};
const loadContractData = async () => {
if (!effectivePurchaseId.value) return;
let contractData: any = null;
let purchaseId = effectivePurchaseId.value;
// 优先使用 flowInstId 获取合同数据(审核流程嵌入时)
if (effectiveFlowInstId.value) {
try {
fileLoading.value = true;
const res = await getByPurchaseId(effectivePurchaseId.value);
const res = await getByFlowInstId(effectiveFlowInstId.value);
if (res.code === 0 && res.data) {
const data = res.data;
formData.value = {
purchaseId: effectivePurchaseId.value,
contractNo: data.contractNo || '',
contractName: data.contractName || '',
money: data.money,
isBidding: data.isBidding || '0',
isLegalAdviser: data.isLegalAdviser || '0',
legalAdviserOpinion: data.legalAdviserOpinion || '',
isDepts: data.isDepts || '0',
isSchool: data.isSchool || '0',
remarks: data.remarks || '',
contractFileIds: [],
supplementFileIds: [],
};
(formData.value as any).flowStatus = data.flowStatus;
if (data.contractFiles && data.contractFiles.length > 0) {
contractFiles.value = data.contractFiles;
}
if (data.supplementFiles && data.supplementFiles.length > 0) {
supplementFiles.value = data.supplementFiles;
}
contractData = res.data;
purchaseId = res.data.purchaseId || purchaseId;
}
} catch (e: any) {
ElMessage.error(e?.msg || '加载合同信息失败');
} finally {
fileLoading.value = false;
}
}
// 如果通过 flowInstId 没有获取到数据,则使用 purchaseId 获取
if (!contractData && purchaseId) {
try {
fileLoading.value = true;
const res = await getByPurchaseId(purchaseId);
if (res.code === 0 && res.data) {
contractData = res.data;
}
} catch (e: any) {
ElMessage.error(e?.msg || '加载合同信息失败');
} finally {
fileLoading.value = false;
}
}
if (contractData) {
formData.value = {
purchaseId: purchaseId,
contractNo: contractData.contractNo || '',
contractName: contractData.contractName || '',
money: contractData.money,
isBidding: contractData.isBidding || '0',
isLegalAdviser: contractData.isLegalAdviser || '0',
legalAdviserOpinion: contractData.legalAdviserOpinion || '',
isDepts: contractData.isDepts || '0',
isSchool: contractData.isSchool || '0',
remarks: contractData.remarks || '',
contractFileIds: [],
supplementFileIds: [],
};
(formData.value as any).flowStatus = contractData.flowStatus;
if (contractData.contractFiles && contractData.contractFiles.length > 0) {
contractFiles.value = contractData.contractFiles;
}
if (contractData.supplementFiles && contractData.supplementFiles.length > 0) {
supplementFiles.value = contractData.supplementFiles;
}
// 如果有 purchaseId加载采购申请信息
if (purchaseId && !applyData.value.id) {
try {
const applyRes = await getObj(purchaseId);
if (applyRes.code === 0 && applyRes.data) {
applyData.value = applyRes.data;
}
} catch (e) {
console.error('加载采购申请信息失败', e);
}
}
}
};
const handlePreview = async (row: any) => {
@@ -313,7 +355,7 @@ const handleFlowSave = async () => {
await updateContract({
...formData.value,
purchaseId: effectivePurchaseId.value,
purchaseId: formData.value.purchaseId || effectivePurchaseId.value,
contractFileIds,
supplementFileIds,
});

View File

@@ -39,6 +39,14 @@
<el-option label="是" value="1" />
</el-select>
</el-form-item>
<el-form-item label="是否特殊" prop="isSpecial">
<el-select v-model="state.queryForm.isSpecial" placeholder="请选择是否特殊" clearable style="width: 200px">
<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-form-item label="采购形式" prop="purchaseMode">
<el-select
v-model="state.queryForm.purchaseMode"
@@ -51,13 +59,25 @@
<el-option label="学校统一采购" value="2" />
</el-select>
</el-form-item>
<el-form-item label="采购方式" prop="purchaseType">
<el-form-item v-if="state.queryForm.purchaseMode === '1'" label="采购途径" prop="purchaseChannel">
<el-select
v-model="state.queryForm.purchaseChannel"
placeholder="请选择采购途径"
clearable
style="width: 200px"
@change="handlePurchaseChannelChange"
>
<el-option label="自行采购" value="1" />
<el-option label="委托采购中心采购" value="2" />
</el-select>
</el-form-item>
<el-form-item v-if="showPurchaseTypeSelect" label="采购方式" prop="purchaseType">
<el-select v-model="state.queryForm.purchaseType" placeholder="请选择采购方式" clearable style="width: 200px">
<el-option v-for="item in purchaseTypeSearchOptions" :key="item.value" :label="item.label" :value="item.value" />
<el-option v-for="item in purchaseTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</el-form-item>
<el-form-item label="需求部门" prop="deptId">
<el-select v-model="state.queryForm.deptId" placeholder="请选择需求部门" clearable filterable style="width: 200px">
<el-select v-model="state.queryForm.deptCode" placeholder="请选择需求部门" clearable filterable style="width: 200px">
<el-option v-for="item in secondDeptList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</el-form-item>
@@ -345,7 +365,14 @@
<template v-if="scope.row.status === '1'">
<el-tooltip v-if="scope.row.contractFlowStatus" content="点击查看合同详情" placement="top">
<el-tag
v-if="scope.row.contractFlowStatus === '0'"
v-if="scope.row.contractFlowStatus === '-1'"
type="info"
class="status-tag-clickable"
@click="handleEditContract(scope.row)"
>已上传
</el-tag>
<el-tag
v-else-if="scope.row.contractFlowStatus === '0'"
type="warning"
class="status-tag-clickable"
@click="handleShowContractDetail(scope.row)"
@@ -365,9 +392,6 @@
@click="handleShowContractDetail(scope.row)"
>已作废
</el-tag>
<el-tag v-else type="info" class="status-tag-clickable" @click="handleShowContractDetail(scope.row)">{{
scope.row.contractFlowStatus
}}</el-tag>
</el-tooltip>
<el-button v-else type="primary" link size="small" @click="handleAddContract(scope.row)">添加合同</el-button>
</template>
@@ -593,45 +617,46 @@ const dictData = ref({
const purchaseTypeDeptDelegationList = ref<any[]>([]); // 委托采购中心采购方式字典
const secondDeptList = ref<any[]>([]); // 二级部门列表
// 采购方式搜索选项(根据采购形式动态变化)
const purchaseTypeSearchOptions = computed(() => {
// 是否显示采购方式选择框
const showPurchaseTypeSelect = computed(() => {
const mode = state.queryForm.purchaseMode;
if (mode === '2') {
// 学校统一采购:使用UNION_PURCHASE_TYPE字典
return dictData.value.purchaseTypeUnionList;
// 学校统一采购:显示采购方式
return true;
} else if (mode === '1') {
// 部门自行采购:合并DEPT_PURCHASE_TYPE和PURCHASE_TYPE_DEPT_DELEGATION
return [...dictData.value.purchaseTypeDeptList, ...purchaseTypeDeptDelegationList.value];
// 部门自行采购:需要先选择采购途径
return !!state.queryForm.purchaseChannel;
}
// 未选择采购形式时,显示所有选项
return [...dictData.value.purchaseTypeDeptList, ...purchaseTypeDeptDelegationList.value, ...dictData.value.purchaseTypeUnionList];
return false;
});
// 采购形式变化时清空采购方式
// 采购方式选项(根据采购形式和采购途径动态变化)
const purchaseTypeOptions = computed(() => {
const mode = state.queryForm.purchaseMode;
if (mode === '2') {
// 学校统一采购:使用 UNION_PURCHASE_TYPE 字典
return dictData.value.purchaseTypeUnionList;
} else if (mode === '1') {
const channel = state.queryForm.purchaseChannel;
if (channel === '1') {
// 自行采购:使用 DEPT_PURCHASE_TYPE 字典
return dictData.value.purchaseTypeDeptList;
} else if (channel === '2') {
// 委托采购中心采购:使用 PURCHASE_TYPE_DEPT_DELEGATION 字典
return purchaseTypeDeptDelegationList.value;
}
}
return [];
});
// 采购形式变化时清空采购途径和采购方式
const handlePurchaseModeChange = () => {
state.queryForm.purchaseChannel = '';
state.queryForm.purchaseType = '';
};
// 搜索条件相关数据
const purchaseTypeDeptDelegationList = ref<any[]>([]); // 委托采购中心采购方式字典
const secondDeptList = ref<any[]>([]); // 二级部门列表
// 采购方式搜索选项(根据采购形式动态变化)
const purchaseTypeSearchOptions = computed(() => {
const mode = state.queryForm.purchaseMode;
if (mode === '2') {
// 学校统一采购使用UNION_PURCHASE_TYPE字典
return dictData.value.purchaseTypeUnionList;
} else if (mode === '1') {
// 部门自行采购合并DEPT_PURCHASE_TYPE和PURCHASE_TYPE_DEPT_DELEGATION
return [...dictData.value.purchaseTypeDeptList, ...purchaseTypeDeptDelegationList.value];
}
// 未选择采购形式时,显示所有选项
return [...dictData.value.purchaseTypeDeptList, ...purchaseTypeDeptDelegationList.value, ...dictData.value.purchaseTypeUnionList];
});
// 采购形式变化时清空采购方式
const handlePurchaseModeChange = () => {
// 采购途径变化时清空采购方式
const handlePurchaseChannelChange = () => {
state.queryForm.purchaseType = '';
};
@@ -726,9 +751,11 @@ const state: BasicTableProps = reactive<BasicTableProps>({
projectType: '',
status: '',
isCentralized: '',
isSpecial: '',
purchaseMode: '',
purchaseChannel: '',
purchaseType: '',
deptId: '',
deptCode: '',
},
createdIsNeed: true,
});
@@ -837,6 +864,16 @@ const handleAddContract = (row: any) => {
purchaseContractDialogRef.value?.open(String(id), 'add');
};
/** 点击已上传合同:打开采购合同编辑弹窗 */
const handleEditContract = (row: any) => {
const id = row?.id ?? row?.purchaseId;
if (!id) {
useMessage().warning('无法获取采购申请ID');
return;
}
purchaseContractDialogRef.value?.open(String(id), 'edit');
};
/** 点击采购合同状态:打开采购合同详情弹窗 */
const handleShowContractDetail = (row: any) => {
const id = row?.id ?? row?.purchaseId;