更新采购申请
This commit is contained in:
888
src/views/purchase/purchasingrequisition/index.vue
Normal file
888
src/views/purchase/purchasingrequisition/index.vue
Normal file
@@ -0,0 +1,888 @@
|
||||
<template>
|
||||
<div class="modern-page-container">
|
||||
<div class="page-wrapper">
|
||||
<!-- 搜索表单卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Search /></el-icon>
|
||||
筛选条件
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form :model="state.queryForm" ref="searchFormRef" :inline="true" @keyup.enter="getDataList" class="search-form">
|
||||
<el-form-item label="采购编号" prop="purchaseNo">
|
||||
<el-input
|
||||
v-model="state.queryForm.purchaseNo"
|
||||
placeholder="请输入采购编号"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="采购项目名称" prop="projectName">
|
||||
<el-input
|
||||
v-model="state.queryForm.projectName"
|
||||
placeholder="请输入采购项目名称"
|
||||
clearable
|
||||
style="width: 200px" />
|
||||
</el-form-item>
|
||||
<el-form-item label="项目类别" prop="projectType">
|
||||
<el-select
|
||||
v-model="state.queryForm.projectType"
|
||||
placeholder="请选择项目类别"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option label="货物" value="A" />
|
||||
<el-option label="工程" value="B" />
|
||||
<el-option label="服务" value="C" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-select
|
||||
v-model="state.queryForm.status"
|
||||
placeholder="请选择状态"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
|
||||
<el-option label="暂存" value="-1" />
|
||||
<el-option label="运行中" value="0" />
|
||||
<el-option label="完成" value="1" />
|
||||
<el-option label="作废" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="是否集采" prop="isCentralized">
|
||||
<el-select
|
||||
v-model="state.queryForm.isCentralized"
|
||||
placeholder="请选择是否集采"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option label="否" value="0" />
|
||||
<el-option label="是" value="1" />
|
||||
</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-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Document /></el-icon>
|
||||
采购申请管理
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button
|
||||
icon="Files"
|
||||
link
|
||||
type="primary"
|
||||
|
||||
>
|
||||
采购申请汇总
|
||||
</el-button>
|
||||
<el-button
|
||||
icon="FolderAdd"
|
||||
type="primary"
|
||||
@click="handleAdd">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table
|
||||
ref="tableRef"
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
stripe
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
class="modern-table">
|
||||
<el-table-column type="index" label="序号" width="70" align="center">
|
||||
<template #header>
|
||||
<el-icon><List /></el-icon>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="purchaseNo" label="申请单编号" min-width="140" show-overflow-tooltip>
|
||||
<template #header>
|
||||
<el-icon><DocumentCopy /></el-icon>
|
||||
<span style="margin-left: 4px">申请单编号</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectName" label="采购项目名称" min-width="200" show-overflow-tooltip>
|
||||
<template #header>
|
||||
<el-icon><Document /></el-icon>
|
||||
<span style="margin-left: 4px">采购项目名称</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="applyDate" label="填报日期" width="120" align="center" show-overflow-tooltip>
|
||||
<template #header>
|
||||
<el-icon><Calendar /></el-icon>
|
||||
<span style="margin-left: 4px">填报日期</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="deptName" label="需求部门" min-width="150" show-overflow-tooltip>
|
||||
<template #header>
|
||||
<el-icon><OfficeBuilding /></el-icon>
|
||||
<span style="margin-left: 4px">需求部门</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="projectType" label="项目类别" min-width="200" align="left" show-overflow-tooltip>
|
||||
<template #header>
|
||||
<el-icon><Collection /></el-icon>
|
||||
<span style="margin-left: 4px">项目类别</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<div>
|
||||
<el-tag v-if="scope.row.projectType === 'A'" type="success" style="margin-right: 8px;">货物</el-tag>
|
||||
<el-tag v-else-if="scope.row.projectType === 'B'" type="warning" style="margin-right: 8px;">工程</el-tag>
|
||||
<el-tag v-else-if="scope.row.projectType === 'C'" type="info" style="margin-right: 8px;">服务</el-tag>
|
||||
<span v-if="scope.row.categoryName" style="color: #606266; font-size: 12px;">
|
||||
{{ scope.row.categoryName }}
|
||||
</span>
|
||||
<span v-else-if="scope.row.categoryCode" style="color: #909399; font-size: 12px;">
|
||||
{{ scope.row.categoryCode }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="budget" label="项目预算(元)" width="130" align="right">
|
||||
<template #header>
|
||||
<el-icon><Money /></el-icon>
|
||||
<span style="margin-left: 4px">项目预算</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
{{ scope.row.budget ? Number(scope.row.budget).toLocaleString() : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isSpecial" label="是否特殊" width="100" align="center">
|
||||
<template #header>
|
||||
<el-icon><Warning /></el-icon>
|
||||
<span style="margin-left: 4px">是否特殊</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-tag v-if="String(scope.row.isSpecial) === '1'" type="warning">紧急</el-tag>
|
||||
<el-tag v-else-if="String(scope.row.isSpecial) === '2'" type="danger">单一</el-tag>
|
||||
<el-tag v-else-if="String(scope.row.isSpecial) === '3'" type="info">进口</el-tag>
|
||||
<el-tag v-else-if="String(scope.row.isSpecial) === '0'" type="info">否</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="isCentralized" label="是否集采" width="100" align="center">
|
||||
<template #header>
|
||||
<el-icon><CircleCheck /></el-icon>
|
||||
<span style="margin-left: 4px">是否集采</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-tag v-if="String(scope.row.isCentralized) === '1'" type="success">是</el-tag>
|
||||
<el-tag v-else-if="String(scope.row.isCentralized) === '0'" type="info">否</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="status" label="审核状态" width="100" align="center">
|
||||
<template #header>
|
||||
<el-icon><InfoFilled /></el-icon>
|
||||
<span style="margin-left: 4px">审核状态</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<el-tooltip v-if="scope.row.flowInstId" content="点击查看审批过程" placement="top">
|
||||
<el-tag
|
||||
v-if="scope.row.status === '-2'"
|
||||
type="info"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFlowComment(scope.row)">撤回</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.status === '-1'"
|
||||
type="warning"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFlowComment(scope.row)">暂存</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.status === '0'"
|
||||
type="primary"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFlowComment(scope.row)">运行中</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.status === '1'"
|
||||
type="success"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFlowComment(scope.row)">完成</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.status === '2'"
|
||||
type="danger"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFlowComment(scope.row)">作废</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.status === '3'"
|
||||
type="info"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFlowComment(scope.row)">终止</el-tag>
|
||||
<span v-else>-</span>
|
||||
</el-tooltip>
|
||||
<template v-else>
|
||||
<el-tag v-if="scope.row.status === '-2'" type="info">撤回</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '-1'" type="warning">暂存</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '0'" type="primary">运行中</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '1'" type="success">完成</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '2'" type="danger">作废</el-tag>
|
||||
<el-tag v-else-if="scope.row.status === '3'" type="info">终止</el-tag>
|
||||
<span v-else>-</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" align="center" fixed="right" width="150">
|
||||
<template #default="scope">
|
||||
<div class="op-cell">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="View"
|
||||
@click="handleView(scope.row)">
|
||||
查看
|
||||
</el-button>
|
||||
<ActionDropdown
|
||||
:items="getActionMenuItems(scope.row)"
|
||||
@command="(command) => handleMoreCommand(command, scope.row)"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
v-if="state.pagination && state.pagination.total && state.pagination.total > 0"
|
||||
:total="state.pagination.total"
|
||||
:current="state.pagination.current"
|
||||
:size="state.pagination.size"
|
||||
@sizeChange="sizeChangeHandle"
|
||||
@currentChange="currentChangeHandle"
|
||||
/>
|
||||
</el-card>
|
||||
</div>
|
||||
|
||||
<!-- 新增/编辑/查看:统一使用 form.vue 弹窗(iframe 引入 add.vue) -->
|
||||
<FormDialog
|
||||
ref="formDialogRef"
|
||||
:dict-data="dictData"
|
||||
@refresh="getDataList" />
|
||||
|
||||
<!-- 履约验收弹窗 -->
|
||||
<PurchasingAcceptModal ref="acceptModalRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 查看审批过程(申请单审批 / 文件审批) -->
|
||||
<el-dialog
|
||||
v-model="showFlowComment"
|
||||
v-if="showFlowComment"
|
||||
:title="currFlowCommentType === 'file' ? '查看文件审批过程' : '查看审批过程'"
|
||||
top="20px"
|
||||
width="90%"
|
||||
append-to-body
|
||||
destroy-on-close
|
||||
@close="currFlowJob = null; currFlowCommentType = 'apply'">
|
||||
<FlowCommentTimeline v-if="currFlowJob" :key="String(currFlowJob.flowInstId) + currFlowCommentType" :curr-job="currFlowJob" />
|
||||
</el-dialog>
|
||||
|
||||
<!-- 实施采购:iframe 嵌入 implement.vue,供列表与流程页面使用 -->
|
||||
<ImplementForm ref="implementFormRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 采购文件审核弹窗 -->
|
||||
<DocAuditDialog ref="docAuditDialogRef" @refresh="getDataList" />
|
||||
|
||||
<!-- 采购代表弹窗 -->
|
||||
<el-dialog
|
||||
v-model="representorDialogVisible"
|
||||
title="设置采购代表"
|
||||
width="500px"
|
||||
destroy-on-close
|
||||
>
|
||||
<el-form label-width="100px">
|
||||
<el-form-item label="选择方式">
|
||||
<el-radio-group v-model="representorForm.mode">
|
||||
<el-radio label="single">指定采购代表人</el-radio>
|
||||
<el-radio label="multi">部门多人系统抽取</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item v-if="representorForm.mode === 'single'" label="采购代表人">
|
||||
<el-select
|
||||
v-model="representorForm.teacherNo"
|
||||
placeholder="请选择"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="m in representorDeptMembers" :key="m.userId || m.teacherNo || m.id" :label="m.realName || m.name || m.teacherNo" :value="m.userId || m.teacherNo || m.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item v-else label="部门多人">
|
||||
<el-select
|
||||
v-model="representorForm.multiIds"
|
||||
multiple
|
||||
placeholder="请选择多人,系统将自动抽取一人"
|
||||
clearable
|
||||
filterable
|
||||
style="width: 100%"
|
||||
>
|
||||
<el-option v-for="m in representorDeptMembers" :key="m.userId || m.teacherNo || m.id" :label="m.realName || m.name || m.teacherNo" :value="m.userId || m.teacherNo || m.id" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="representorDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" :loading="representorSubmitting" @click="handleSaveRepresentor">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PurchasingRequisition">
|
||||
import { ref, reactive, defineAsyncComponent, onMounted, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { getPage, delObj, submitObj, getArchiveDownloadUrl, getApplyTemplateDownloadUrl, getFileApplyTemplateDownloadUrl, getDeptMembers, saveRepresentor } from "/@/api/purchase/purchasingrequisition";
|
||||
import { useMessage, useMessageBox } from "/@/hooks/message";
|
||||
import { useAuth } from '/@/hooks/auth';
|
||||
import { getDicts } from '/@/api/admin/dict';
|
||||
import { getTree } from '/@/api/purchase/purchasingcategory';
|
||||
import { List, Document, DocumentCopy, Search, Money, CircleCheck, InfoFilled, Calendar, OfficeBuilding, Warning, DocumentChecked, Edit, Delete, Upload, FolderOpened, Download, User } from '@element-plus/icons-vue'
|
||||
import other from '/@/utils/other'
|
||||
import { Session } from '/@/utils/storage'
|
||||
|
||||
// 角色常量
|
||||
const PURCHASE_DEPT_AUDIT_ROLE_CODE = 'PURCHASE_DEPT_AUDIT'
|
||||
const roleCode = computed(() => Session.getRoleCode() || '')
|
||||
const isDeptAuditRole = computed(() => roleCode.value === PURCHASE_DEPT_AUDIT_ROLE_CODE)
|
||||
|
||||
// 引入组件
|
||||
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
|
||||
const ImplementForm = defineAsyncComponent(() => import('./implementForm.vue'));
|
||||
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'));
|
||||
const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue'));
|
||||
const FlowCommentTimeline = defineAsyncComponent(() => import('/@/views/jsonflow/comment/timeline.vue'));
|
||||
const DocAuditDialog = defineAsyncComponent(() => import('./docAudit/DocAuditDialog.vue'));
|
||||
|
||||
// 字典数据和品目树数据
|
||||
const dictData = ref({
|
||||
fundSourceList: [] as any[],
|
||||
isCentralizedList: [] as any[],
|
||||
isSpecialList: [] as any[],
|
||||
purchaseTypeDeptList: [] as any[],
|
||||
purchaseModeSchoolList: [] as any[],
|
||||
purchaseTypeUnionList: [] as any[],
|
||||
categoryTreeData: [] as any[],
|
||||
});
|
||||
|
||||
// 定义变量内容
|
||||
const router = useRouter()
|
||||
const tableRef = ref()
|
||||
const formDialogRef = ref()
|
||||
const acceptModalRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const docAuditDialogRef = ref()
|
||||
const { hasAuth } = useAuth()
|
||||
/** 审批过程弹窗:是否显示、当前行对应的流程 job(供 Comment 组件用)、类型(申请单/文件) */
|
||||
const showFlowComment = ref(false)
|
||||
const currFlowJob = ref<{ id?: number; flowInstId?: number } | null>(null)
|
||||
const currFlowCommentType = ref<'apply' | 'file'>('apply')
|
||||
|
||||
const implementFormRef = ref()
|
||||
|
||||
/** 采购代表弹窗 */
|
||||
const representorDialogVisible = ref(false)
|
||||
const representorCurrentRow = ref<any>(null)
|
||||
const representorForm = reactive({ mode: 'single' as 'single' | 'multi', teacherNo: '', multiIds: [] as string[] })
|
||||
const representorDeptMembers = ref<any[]>([])
|
||||
const representorSubmitting = ref(false)
|
||||
|
||||
const openRepresentorDialog = async (row: any) => {
|
||||
representorCurrentRow.value = row
|
||||
representorForm.mode = 'single'
|
||||
representorForm.teacherNo = ''
|
||||
representorForm.multiIds = []
|
||||
representorDialogVisible.value = true
|
||||
try {
|
||||
const res = await getDeptMembers()
|
||||
representorDeptMembers.value = res?.data || []
|
||||
} catch (_) {
|
||||
representorDeptMembers.value = []
|
||||
}
|
||||
}
|
||||
|
||||
const handleSaveRepresentor = async () => {
|
||||
const row = representorCurrentRow.value
|
||||
const id = row?.id ?? row?.purchaseId
|
||||
if (id == null || id === '') {
|
||||
useMessage().warning('无法获取申请单ID')
|
||||
return
|
||||
}
|
||||
if (representorForm.mode === 'single' && !representorForm.teacherNo) {
|
||||
useMessage().warning('请选择采购代表人')
|
||||
return
|
||||
}
|
||||
if (representorForm.mode === 'multi' && !representorForm.multiIds.length) {
|
||||
useMessage().warning('请选择部门多人')
|
||||
return
|
||||
}
|
||||
representorSubmitting.value = true
|
||||
try {
|
||||
const teacherNo = representorForm.mode === 'single' ? representorForm.teacherNo : undefined
|
||||
const multiIds = representorForm.mode === 'multi' ? representorForm.multiIds.join(',') : undefined
|
||||
await saveRepresentor(Number(id), teacherNo, multiIds)
|
||||
useMessage().success('保存采购代表成功')
|
||||
representorDialogVisible.value = false
|
||||
getDataList()
|
||||
} catch (e: any) {
|
||||
useMessage().error(e?.msg || '保存采购代表失败')
|
||||
} finally {
|
||||
representorSubmitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 定义响应式表格数据
|
||||
*/
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: getPage,
|
||||
queryForm: {
|
||||
purchaseNo: '',
|
||||
projectName: '',
|
||||
projectType: '',
|
||||
status: '',
|
||||
isCentralized: '',
|
||||
},
|
||||
createdIsNeed: true
|
||||
});
|
||||
|
||||
/**
|
||||
* 使用 useTable 定义表格相关操作
|
||||
*/
|
||||
const { getDataList, tableStyle, sizeChangeHandle, currentChangeHandle } = useTable(state);
|
||||
|
||||
/**
|
||||
* 重置搜索表单
|
||||
*/
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields();
|
||||
getDataList();
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增采购申请 - 统一通过 form.vue 弹窗(iframe 引入 add.vue)
|
||||
*/
|
||||
const handleAdd = () => {
|
||||
formDialogRef.value?.openDialog('add')
|
||||
};
|
||||
|
||||
/**
|
||||
/**
|
||||
* 点击审核状态:若有流程实例则打开「查看审批过程」弹窗(参考 hi-job.vue)
|
||||
* @param row - 当前行数据(需含 flowInstId)
|
||||
*/
|
||||
/** 点击审核状态:打开申请单审批过程 */
|
||||
const handleShowFlowComment = (row: any) => {
|
||||
if (!row?.flowInstId) {
|
||||
useMessage().info('暂存状态无审批过程');
|
||||
return;
|
||||
}
|
||||
currFlowCommentType.value = 'apply';
|
||||
currFlowJob.value = { id: row.id, flowInstId: row.flowInstId };
|
||||
showFlowComment.value = true;
|
||||
};
|
||||
|
||||
/** 点击文件审批状态:打开文件审批过程 */
|
||||
const handleShowFileFlowComment = (row: any) => {
|
||||
if (!row?.fileFlowInstId) {
|
||||
useMessage().info('未发起文件审批流程');
|
||||
return;
|
||||
}
|
||||
currFlowCommentType.value = 'file';
|
||||
const flowInstId = typeof row.fileFlowInstId === 'string' ? parseInt(row.fileFlowInstId, 10) : row.fileFlowInstId;
|
||||
currFlowJob.value = { id: row.id, flowInstId: Number.isNaN(flowInstId) ? row.fileFlowInstId : flowInstId };
|
||||
showFlowComment.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 打开查看对话框
|
||||
* @param row - 当前行数据
|
||||
*/
|
||||
const handleView = (row: any) => {
|
||||
formDialogRef.value?.openDialog('view', row);
|
||||
};
|
||||
|
||||
/**
|
||||
* 打开编辑对话框
|
||||
* @param row - 当前行数据
|
||||
*/
|
||||
const handleEdit = (row: any) => {
|
||||
formDialogRef.value?.openDialog('edit', row);
|
||||
};
|
||||
|
||||
/**
|
||||
* 履约验收
|
||||
* @param row - 当前行数据
|
||||
*/
|
||||
const handleAccept = (row: any) => {
|
||||
acceptModalRef.value?.open(row);
|
||||
};
|
||||
|
||||
/** 打开实施采购(仅暂存状态可点;通过 iframe 嵌入 implement.vue) */
|
||||
const handleImplement = (row: any) => {
|
||||
implementFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
/** 打开采购文件审核 */
|
||||
const handleDocAudit = (row: any) => {
|
||||
docAuditDialogRef.value?.open(row);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除当前行
|
||||
* @param row - 当前行数据
|
||||
*/
|
||||
const handleDelete = async (row: any) => {
|
||||
try {
|
||||
await useMessageBox().confirm('确定要删除该记录吗?');
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await delObj({id:row.id});
|
||||
useMessage().success('删除成功');
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err.msg || '删除失败');
|
||||
}
|
||||
};
|
||||
|
||||
/** 暂存状态下提交采购申请(启动流程) */
|
||||
const handleSubmit = async (row: any) => {
|
||||
try {
|
||||
await useMessageBox().confirm('确定要提交该采购申请并启动流程吗?');
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await submitObj({ id: row.id });
|
||||
useMessage().success('提交成功');
|
||||
getDataList();
|
||||
} catch (err: any) {
|
||||
useMessage().error(err?.msg || '提交失败');
|
||||
}
|
||||
};
|
||||
|
||||
/** 操作栏「更多」菜单项配置 */
|
||||
const getActionMenuItems = (row: any) => {
|
||||
const isTemp = row?.status === '-1';
|
||||
const isCompleted = row?.status === '1';
|
||||
const items = [
|
||||
{
|
||||
command: 'edit',
|
||||
label: '编辑',
|
||||
icon: Edit,
|
||||
visible: () => isTemp,
|
||||
},
|
||||
{
|
||||
command: 'submit',
|
||||
label: '提交',
|
||||
icon: Upload,
|
||||
visible: () => isTemp,
|
||||
},
|
||||
{
|
||||
command: 'delete',
|
||||
label: '删除',
|
||||
icon: Delete,
|
||||
visible: () => isTemp,
|
||||
},
|
||||
{
|
||||
command: 'accept',
|
||||
label: '履约验收',
|
||||
icon: DocumentChecked,
|
||||
visible: () => hasAuth('purchase_accept'),
|
||||
},
|
||||
{
|
||||
command: 'implement',
|
||||
label: '实施采购',
|
||||
icon: Upload,
|
||||
visible: () => isCompleted && hasAuth('purchase_implement'),
|
||||
},
|
||||
{
|
||||
command: 'archive',
|
||||
label: '文件归档',
|
||||
icon: FolderOpened,
|
||||
visible: () => isCompleted && hasAuth('purchase_archive'),
|
||||
},
|
||||
{
|
||||
command: 'downloadApply',
|
||||
label: '下载审批表',
|
||||
icon: Download,
|
||||
visible: () => isCompleted,
|
||||
},
|
||||
{
|
||||
command: 'representor',
|
||||
label: '采购代表',
|
||||
icon: User,
|
||||
visible: () => isDeptAuditRole.value,
|
||||
},
|
||||
// {
|
||||
// command: 'downloadFileApply',
|
||||
// label: '下载文件审批表',
|
||||
// icon: Download,
|
||||
// visible: () => true,
|
||||
// },
|
||||
// {
|
||||
// command: 'docAudit',
|
||||
// label: '采购文件审核',
|
||||
// icon: DocumentChecked,
|
||||
// visible: () => row?.implementType === '2' && row?.agentId,
|
||||
// },
|
||||
];
|
||||
// 过滤出有权限且可见的菜单项
|
||||
return items.filter(item => {
|
||||
if (item.visible === undefined) return true;
|
||||
if (typeof item.visible === 'boolean') return item.visible;
|
||||
if (typeof item.visible === 'function') return item.visible();
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
/** 处理更多操作下拉菜单命令 */
|
||||
const handleMoreCommand = (command: string, row: any) => {
|
||||
switch (command) {
|
||||
case 'edit':
|
||||
handleEdit(row);
|
||||
break;
|
||||
case 'submit':
|
||||
handleSubmit(row);
|
||||
break;
|
||||
case 'delete':
|
||||
handleDelete(row);
|
||||
break;
|
||||
case 'accept':
|
||||
handleAccept(row);
|
||||
break;
|
||||
case 'implement':
|
||||
handleImplement(row);
|
||||
break;
|
||||
case 'archive':
|
||||
handleArchive(row);
|
||||
break;
|
||||
case 'downloadApply':
|
||||
handleDownloadApply(row);
|
||||
break;
|
||||
case 'downloadFileApply':
|
||||
handleDownloadFileApply(row);
|
||||
break;
|
||||
case 'docAudit':
|
||||
handleDocAudit(row);
|
||||
break;
|
||||
case 'representor':
|
||||
openRepresentorDialog(row);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
/** 下载审批表 */
|
||||
const handleDownloadApply = (row: any) => {
|
||||
const id = row?.id ?? row?.purchaseId;
|
||||
if (id == null || id === '') {
|
||||
useMessage().warning('无法获取申请单ID');
|
||||
return;
|
||||
}
|
||||
const url = getApplyTemplateDownloadUrl(id);
|
||||
const fileName = `审批表_${row?.purchaseNo || id}.docx`;
|
||||
other.downBlobFile(url, {}, fileName);
|
||||
};
|
||||
|
||||
/** 下载文件审批表 */
|
||||
const handleDownloadFileApply = (row: any) => {
|
||||
const id = row?.id ?? row?.purchaseId;
|
||||
if (id == null || id === '') {
|
||||
useMessage().warning('无法获取申请单ID');
|
||||
return;
|
||||
}
|
||||
const url = getFileApplyTemplateDownloadUrl(id);
|
||||
const fileName = `文件审批表_${row?.purchaseNo || id}.docx`;
|
||||
other.downBlobFile(url, {}, fileName);
|
||||
};
|
||||
|
||||
/** 文件归档:按文件类型打包下载该申请单下所有附件 */
|
||||
const handleArchive = (row: any) => {
|
||||
const id = row?.id ?? row?.purchaseId;
|
||||
if (id == null || id === '') {
|
||||
useMessage().warning('无法获取申请单ID');
|
||||
return;
|
||||
}
|
||||
const url = getArchiveDownloadUrl(id);
|
||||
const fileName = `归档_${row?.purchaseNo || id}.zip`;
|
||||
other.downBlobFile(url, {}, fileName);
|
||||
};
|
||||
|
||||
// 获取字典数据和品目树数据
|
||||
const loadDictData = async () => {
|
||||
try {
|
||||
const [
|
||||
fundSourceRes,
|
||||
isCentralizedRes,
|
||||
isSpecialRes,
|
||||
purchaseTypeDeptRes,
|
||||
purchaseModeSchoolRes,
|
||||
purchaseTypeUnionRes,
|
||||
categoryTreeRes
|
||||
] = await Promise.all([
|
||||
getDicts('PURCHASE_FUND_SOURCE'),
|
||||
getDicts('PURCHASE_IS_CEN'),
|
||||
getDicts('PURCHASE_IS_SPEC'),
|
||||
getDicts('PURCHASE_TYPE_DEPT'),
|
||||
getDicts('PURCHASE_MODE_SCHOOL'),
|
||||
getDicts('PURCHASE_TYPE_UNION'),
|
||||
getTree()
|
||||
]);
|
||||
|
||||
// 处理资金来源字典
|
||||
if (fundSourceRes.data && Array.isArray(fundSourceRes.data)) {
|
||||
dictData.value.fundSourceList = fundSourceRes.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
} else {
|
||||
dictData.value.fundSourceList = [
|
||||
{ label: '切块经费', value: '0' },
|
||||
{ label: '设备购置费', value: '1' },
|
||||
{ label: '专项经费', value: '2' },
|
||||
{ label: '代办费', value: '3' },
|
||||
{ label: '培训经费', value: '4' },
|
||||
{ label: '日常公用经费', value: '5' },
|
||||
{ label: '技能大赛经费', value: '6' },
|
||||
{ label: '基本建设资金', value: '7' },
|
||||
{ label: '暂存款', value: '8' },
|
||||
{ label: '会议费', value: '9' },
|
||||
];
|
||||
}
|
||||
|
||||
// 处理是否集采字典
|
||||
if (isCentralizedRes.data && Array.isArray(isCentralizedRes.data)) {
|
||||
dictData.value.isCentralizedList = isCentralizedRes.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
} else {
|
||||
dictData.value.isCentralizedList = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '政府集中采购', value: '1' },
|
||||
{ label: '学校集中采购', value: '2' }
|
||||
];
|
||||
}
|
||||
|
||||
// 处理是否特殊情况字典
|
||||
if (isSpecialRes.data && Array.isArray(isSpecialRes.data)) {
|
||||
dictData.value.isSpecialList = isSpecialRes.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
} else {
|
||||
dictData.value.isSpecialList = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '紧急', value: '1' },
|
||||
{ label: '单一', value: '2' },
|
||||
{ label: '进口', value: '3' }
|
||||
];
|
||||
}
|
||||
|
||||
// 处理部门采购方式字典
|
||||
if (purchaseTypeDeptRes.data && Array.isArray(purchaseTypeDeptRes.data)) {
|
||||
dictData.value.purchaseTypeDeptList = purchaseTypeDeptRes.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
}
|
||||
|
||||
// 处理学校采购形式字典
|
||||
if (purchaseModeSchoolRes.data && Array.isArray(purchaseModeSchoolRes.data)) {
|
||||
dictData.value.purchaseModeSchoolList = purchaseModeSchoolRes.data.map((item: any) => ({
|
||||
label: item.label || item.dictLabel || item.name,
|
||||
value: item.value || item.dictValue || item.code
|
||||
}));
|
||||
} else {
|
||||
dictData.value.purchaseModeSchoolList = [
|
||||
{ label: '政府采购', value: '1' },
|
||||
{ label: '学校自主采购', value: '2' }
|
||||
];
|
||||
}
|
||||
|
||||
// 处理学校统一采购方式字典
|
||||
if (purchaseTypeUnionRes.data && Array.isArray(purchaseTypeUnionRes.data)) {
|
||||
dictData.value.purchaseTypeUnionList = purchaseTypeUnionRes.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;
|
||||
} else {
|
||||
dictData.value.categoryTreeData = [];
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('加载字典数据失败', err);
|
||||
// 设置默认值
|
||||
dictData.value.fundSourceList = [
|
||||
{ label: '切块经费', value: '0' },
|
||||
{ label: '设备购置费', value: '1' },
|
||||
{ label: '专项经费', value: '2' },
|
||||
{ label: '代办费', value: '3' },
|
||||
{ label: '培训经费', value: '4' },
|
||||
{ label: '日常公用经费', value: '5' },
|
||||
{ label: '技能大赛经费', value: '6' },
|
||||
{ label: '基本建设资金', value: '7' },
|
||||
{ label: '暂存款', value: '8' },
|
||||
{ label: '会议费', value: '9' },
|
||||
];
|
||||
dictData.value.isCentralizedList = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '政府集中采购', value: '1' },
|
||||
{ label: '学校集中采购', value: '2' }
|
||||
];
|
||||
dictData.value.isSpecialList = [
|
||||
{ label: '否', value: '0' },
|
||||
{ label: '紧急', value: '1' },
|
||||
{ label: '单一', value: '2' },
|
||||
{ label: '进口', value: '3' }
|
||||
];
|
||||
dictData.value.purchaseModeSchoolList = [
|
||||
{ label: '政府采购', value: '1' },
|
||||
{ label: '学校自主采购', value: '2' }
|
||||
];
|
||||
dictData.value.categoryTreeData = [];
|
||||
}
|
||||
};
|
||||
|
||||
// 页面加载时获取字典数据和品目树数据
|
||||
onMounted(() => {
|
||||
loadDictData();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '/@/assets/styles/modern-page.scss';
|
||||
|
||||
.op-cell {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.status-tag-clickable {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user