Merge branch 'feature-purchase' into developer

This commit is contained in:
吴红兵
2026-03-11 16:28:46 +08:00
2 changed files with 170 additions and 16 deletions

View File

@@ -437,3 +437,12 @@ export function getSupplementFilesByApplyId(applyId: string) {
params: { purchaseId: applyId },
});
}
export function exportPurchaseApply(params?: any) {
return request({
url: '/purchase/purchasingapply/export',
method: 'get',
params,
responseType: 'blob',
});
}

View File

@@ -39,9 +39,32 @@
<el-option label="是" value="1" />
</el-select>
</el-form-item>
<el-form-item label="采购形式" prop="purchaseMode">
<el-select
v-model="state.queryForm.purchaseMode"
placeholder="请选择采购形式"
clearable
style="width: 200px"
@change="handlePurchaseModeChange"
>
<el-option label="部门自行采购" value="1" />
<el-option label="学校统一采购" value="2" />
</el-select>
</el-form-item>
<el-form-item 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-select>
</el-form-item>
<el-form-item label="需求部门" prop="deptId">
<el-select v-model="state.queryForm.deptId" 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>
<el-form-item>
<el-button type="primary" icon="Search" @click="getDataList">查询</el-button>
<el-button icon="Refresh" @click="handleReset">重置</el-button>
<el-button type="success" icon="Download" @click="handleExport">导出</el-button>
</el-form-item>
</el-form>
</el-card>
@@ -206,7 +229,9 @@
>
</el-tag>
<el-tooltip
v-if="scope.row.status === '1' && scope.row.purchaseMode === '1' && scope.row.purchaseChannel === '1' && scope.row.purchaseType !=='6'"
v-if="
scope.row.status === '1' && scope.row.purchaseMode === '1' && scope.row.purchaseChannel === '1' && scope.row.purchaseType !== '6'
"
:content="getSupplementTooltip(scope.row)"
placement="top"
>
@@ -319,16 +344,30 @@
<template #default="scope">
<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'" type="warning" class="status-tag-clickable" @click="handleShowContractDetail(scope.row)"
<el-tag
v-if="scope.row.contractFlowStatus === '0'"
type="warning"
class="status-tag-clickable"
@click="handleShowContractDetail(scope.row)"
>运行中
</el-tag>
<el-tag v-else-if="scope.row.contractFlowStatus === '1'" type="success" class="status-tag-clickable" @click="handleShowContractDetail(scope.row)"
<el-tag
v-else-if="scope.row.contractFlowStatus === '1'"
type="success"
class="status-tag-clickable"
@click="handleShowContractDetail(scope.row)"
>已完成
</el-tag>
<el-tag v-else-if="scope.row.contractFlowStatus === '2'" type="info" class="status-tag-clickable" @click="handleShowContractDetail(scope.row)"
<el-tag
v-else-if="scope.row.contractFlowStatus === '2'"
type="info"
class="status-tag-clickable"
@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-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>
@@ -482,6 +521,7 @@ import {
saveRepresentor,
listDownloadUrls,
updateFiles,
exportPurchaseApply,
} from '/@/api/purchase/purchasingrequisition';
import { useMessage, useMessageBox } from '/@/hooks/message';
import { useAuth } from '/@/hooks/auth';
@@ -515,6 +555,7 @@ import {
import other from '/@/utils/other';
import { Session } from '/@/utils/storage';
import { getByPurchaseId } from '/@/api/purchase/purchasingcontract';
import { getDeptListByLevelTwo } from '/@/api/basic/basicdept';
// 角色常量
const PURCHASE_DEPT_AUDIT_ROLE_CODE = 'PURCHASE_DEPT_AUDIT';
@@ -548,6 +589,52 @@ const dictData = ref({
categoryTreeData: [] as any[],
});
// 搜索条件相关数据
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 = () => {
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 = () => {
state.queryForm.purchaseType = '';
};
// 定义变量内容
const router = useRouter();
const tableRef = ref();
@@ -639,6 +726,9 @@ const state: BasicTableProps = reactive<BasicTableProps>({
projectType: '',
status: '',
isCentralized: '',
purchaseMode: '',
purchaseType: '',
deptId: '',
},
createdIsNeed: true,
});
@@ -1072,8 +1162,16 @@ const handleArchive = (row: any) => {
// 获取字典数据和品目树数据
const loadDictData = async () => {
try {
const [fundSourceRes, isCentralizedRes, isSpecialRes, purchaseTypeDeptRes, purchaseModeSchoolRes, purchaseTypeUnionRes, categoryTreeRes] =
await Promise.all([
const [
fundSourceRes,
isCentralizedRes,
isSpecialRes,
purchaseTypeDeptRes,
purchaseModeSchoolRes,
purchaseTypeUnionRes,
categoryTreeRes,
purchaseTypeDeptDelegationRes,
] = await Promise.all([
getDicts('PURCHASE_FUND_SOURCE'),
getDicts('PURCHASE_IS_CEN'),
getDicts('PURCHASE_IS_SPEC'),
@@ -1081,6 +1179,7 @@ const loadDictData = async () => {
getDicts('PURCHASE_MODE_SCHOOL'),
getDicts('PURCHASE_TYPE_UNION'),
getTree(),
getDicts('PURCHASE_TYPE_DEPT_DELEGATION'),
]);
// 处理资金来源字典
@@ -1162,6 +1261,14 @@ const loadDictData = async () => {
}));
}
// 处理委托采购中心采购方式字典
if (purchaseTypeDeptDelegationRes.data && Array.isArray(purchaseTypeDeptDelegationRes.data)) {
purchaseTypeDeptDelegationList.value = purchaseTypeDeptDelegationRes.data.map((item: any) => ({
label: item.label || item.dictLabel || item.name,
value: item.value || item.dictValue || item.code,
}));
}
// 处理品目树数据
if (categoryTreeRes.data && Array.isArray(categoryTreeRes.data)) {
dictData.value.categoryTreeData = categoryTreeRes.data;
@@ -1202,9 +1309,47 @@ const loadDictData = async () => {
}
};
// 获取二级部门列表
const loadSecondDeptList = async () => {
try {
const res = await getDeptListByLevelTwo();
if (res.data && Array.isArray(res.data)) {
secondDeptList.value = res.data.map((item: any) => ({
id: item.id || item.deptId,
name: item.name || item.deptName,
}));
}
} catch (err) {
console.error('加载二级部门列表失败', err);
secondDeptList.value = [];
}
};
// 导出功能
const handleExport = async () => {
try {
const res: any = await exportPurchaseApply(state.queryForm);
downloadFile(res, '采购申请列表.xlsx');
} catch (err: any) {
useMessage().error(err.msg || '导出失败');
}
};
const downloadFile = (blob: Blob, fileName: string) => {
const url = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = fileName;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
};
// 页面加载时获取字典数据和品目树数据
onMounted(() => {
loadDictData();
loadSecondDeptList();
});
</script>