Merge branch 'developer' of ssh://code.cyweb.top:30033/scj/zhxy/v3/cloud-ui into developer
This commit is contained in:
131
src/api/finance/purchasingdoc.ts
Normal file
131
src/api/finance/purchasingdoc.ts
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2025, cyweb All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the pig4cloud.com developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
*/
|
||||
|
||||
import request from '/@/utils/request';
|
||||
|
||||
/**
|
||||
* 获取采购文件列表(含历史版本)
|
||||
* @param applyId 采购申请ID
|
||||
*/
|
||||
export function getDocList(applyId: number | string) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/list/' + applyId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传采购文件(招标代理)
|
||||
* @param data 文件信息
|
||||
*/
|
||||
export function uploadDoc(data: any) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/upload',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新上传采购文件
|
||||
* @param data 文件信息
|
||||
*/
|
||||
export function reuploadDoc(data: any) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/reupload',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取采购文件下载地址
|
||||
* @param id 采购文件ID
|
||||
*/
|
||||
export function getDocDownloadUrl(id: number | string) {
|
||||
return `/purchase/purchasingdoc/download/${id}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认无误
|
||||
* @param data 审核信息
|
||||
*/
|
||||
export function confirmDoc(data: any) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/confirm',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 退回修改
|
||||
* @param data 审核信息
|
||||
*/
|
||||
export function returnDoc(data: any) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/return',
|
||||
method: 'post',
|
||||
data
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认流程结束
|
||||
* @param applyId 采购申请ID
|
||||
*/
|
||||
export function completeDoc(applyId: number | string) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/complete',
|
||||
method: 'post',
|
||||
params: { applyId }
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取审核记录
|
||||
* @param applyId 采购申请ID
|
||||
*/
|
||||
export function getAuditRecords(applyId: number | string) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/audit-records/' + applyId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取待审核列表
|
||||
* @param params 分页参数
|
||||
*/
|
||||
export function getMyPending(params?: any) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/my-pending',
|
||||
method: 'get',
|
||||
params
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取可执行操作
|
||||
* @param applyId 采购申请ID
|
||||
*/
|
||||
export function getAvailableActions(applyId: number | string) {
|
||||
return request({
|
||||
url: '/purchase/purchasingdoc/actions/' + applyId,
|
||||
method: 'get'
|
||||
});
|
||||
}
|
||||
@@ -46,7 +46,8 @@
|
||||
<el-button
|
||||
icon="FolderAdd"
|
||||
type="primary"
|
||||
@click="formDialogRef.openDialog('add')">
|
||||
@click="formDialogRef.openDialog('add')"
|
||||
v-auth="'purchase_purchasingagent_add'">
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||
@@ -92,6 +93,7 @@
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
v-auth="'purchase_purchasingagent_edit'"
|
||||
@click="formDialogRef.openDialog('edit', scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
@@ -99,6 +101,7 @@
|
||||
icon="Delete"
|
||||
link
|
||||
type="danger"
|
||||
v-auth="'purchase_purchasingagent_del'"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
<el-button
|
||||
icon="FolderAdd"
|
||||
type="primary"
|
||||
v-auth="'purchase_purchasingcategory_add'"
|
||||
@click="formDialogRef.openDialog('add')">
|
||||
新增
|
||||
</el-button>
|
||||
@@ -66,6 +67,7 @@
|
||||
icon="Edit"
|
||||
link
|
||||
type="primary"
|
||||
v-auth="'purchase_purchasingcategory_edit'"
|
||||
@click="formDialogRef.openDialog('edit', scope.row)">
|
||||
编辑
|
||||
</el-button>
|
||||
@@ -73,6 +75,7 @@
|
||||
icon="Delete"
|
||||
link
|
||||
type="danger"
|
||||
v-auth="'purchase_purchasingcategory_del'"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8" class="mb12" v-if="!isEntrustCenterChannel || (isFlowEmbed && isPurchaseCenter)">
|
||||
<el-form-item label="采购方式" prop="purchaseType" required>
|
||||
<el-form-item label="采购方式" prop="purchaseType" :required="!isEntrustCenterChannel">
|
||||
<el-select
|
||||
v-model="dataForm.purchaseType"
|
||||
placeholder="请选择采购方式"
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<template>
|
||||
<el-table :data="records" stripe v-loading="loading" max-height="400">
|
||||
<el-table-column prop="operateTypeDesc" label="操作类型" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getOperateTypeStyle(scope.row.operateType)">
|
||||
{{ scope.row.operateTypeDesc }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operateRoleDesc" label="操作角色" width="100" />
|
||||
<el-table-column prop="operateByName" label="操作人" width="100" />
|
||||
<el-table-column prop="currentVersion" label="文件版本" width="80" align="center" />
|
||||
<el-table-column prop="remark" label="批注意见" min-width="200" show-overflow-tooltip>
|
||||
<template #default="scope">
|
||||
{{ scope.row.remark || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="operateTime" label="操作时间" width="160" />
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue'
|
||||
import { getAuditRecords } from '/@/api/finance/purchasingdoc'
|
||||
|
||||
const props = defineProps<{
|
||||
applyId: number | string
|
||||
}>()
|
||||
|
||||
const records = ref<any[]>([])
|
||||
const loading = ref(false)
|
||||
|
||||
const loadRecords = async () => {
|
||||
if (!props.applyId) return
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getAuditRecords(props.applyId)
|
||||
records.value = res.data || []
|
||||
} catch (e) {
|
||||
records.value = []
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const refresh = () => {
|
||||
loadRecords()
|
||||
}
|
||||
|
||||
const getOperateTypeStyle = (type: string) => {
|
||||
const styleMap: Record<string, string> = {
|
||||
'UPLOAD': 'primary',
|
||||
'CONFIRM': 'success',
|
||||
'RETURN': 'warning',
|
||||
'COMPLETE': 'success'
|
||||
}
|
||||
return styleMap[type] || 'info'
|
||||
}
|
||||
|
||||
watch(() => props.applyId, () => {
|
||||
loadRecords()
|
||||
}, { immediate: true })
|
||||
|
||||
defineExpose({ refresh })
|
||||
</script>
|
||||
@@ -0,0 +1,323 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
v-model="visible"
|
||||
title="采购文件审核"
|
||||
width="900px"
|
||||
destroy-on-close
|
||||
@close="handleClose">
|
||||
<el-tabs v-model="activeTab">
|
||||
<!-- 项目信息 -->
|
||||
<el-tab-pane label="项目信息" name="info">
|
||||
<el-descriptions :column="2" border>
|
||||
<el-descriptions-item label="采购编号">{{ applyInfo.purchaseNo }}</el-descriptions-item>
|
||||
<el-descriptions-item label="项目名称">{{ applyInfo.projectName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="需求部门">{{ applyInfo.deptName }}</el-descriptions-item>
|
||||
<el-descriptions-item label="预算金额">{{ applyInfo.budget ? Number(applyInfo.budget).toLocaleString() + '元' : '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="招标代理">{{ applyInfo.agentName || '-' }}</el-descriptions-item>
|
||||
<el-descriptions-item label="审核状态">
|
||||
<el-tag :type="getStatusType(applyInfo.docAuditStatus)">
|
||||
{{ getStatusLabel(applyInfo.docAuditStatus) }}
|
||||
</el-tag>
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 采购需求文件 -->
|
||||
<el-tab-pane label="采购需求文件" name="requirement">
|
||||
<el-table :data="requirementFiles" stripe v-loading="requirementLoading">
|
||||
<el-table-column prop="fileTitle" label="文件名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="fileType" label="文件类型" width="120">
|
||||
<template #default="scope">
|
||||
{{ getFileTypeLabel(scope.row.fileType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="Download" @click="handleDownloadRequirement(scope.row)">
|
||||
下载
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 采购文件 -->
|
||||
<el-tab-pane label="采购文件" name="doc">
|
||||
<div class="doc-header">
|
||||
<el-button v-if="canUpload" type="primary" icon="Upload" @click="handleUpload">
|
||||
{{ applyInfo.docAuditStatus === 'RETURNED' ? '重新上传' : '上传文件' }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-table :data="docList" stripe v-loading="docLoading">
|
||||
<el-table-column prop="fileName" label="文件名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="version" label="版本" width="80" align="center" />
|
||||
<el-table-column prop="uploadByName" label="上传人" width="100" />
|
||||
<el-table-column prop="uploadTime" label="上传时间" width="160" />
|
||||
<el-table-column label="操作" width="100" align="center">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="Download" @click="handleDownloadDoc(scope.row)">
|
||||
下载
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-tab-pane>
|
||||
|
||||
<!-- 审核记录 -->
|
||||
<el-tab-pane label="审核记录" name="audit">
|
||||
<AuditRecordList :apply-id="applyInfo.id" ref="auditRecordListRef" />
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
|
||||
<!-- 操作区域 -->
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button v-if="canConfirm" type="success" @click="handleConfirm">确认无误</el-button>
|
||||
<el-button v-if="canReturn" type="warning" @click="handleReturn">退回修改</el-button>
|
||||
<el-button v-if="canComplete" type="primary" @click="handleComplete">确认流程结束</el-button>
|
||||
<el-button @click="handleClose">关闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 退回原因弹窗 -->
|
||||
<el-dialog v-model="returnDialogVisible" title="退回原因" width="400px" append-to-body>
|
||||
<el-form>
|
||||
<el-form-item label="退回原因">
|
||||
<el-input v-model="returnRemark" type="textarea" :rows="3" placeholder="请输入退回原因" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<el-button @click="returnDialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="submitReturn">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, defineAsyncComponent } from 'vue'
|
||||
import { useMessage, useMessageBox } from '/@/hooks/message'
|
||||
import { getObj, getApplyFiles } from '/@/api/finance/purchasingrequisition'
|
||||
import { getDocList, uploadDoc, reuploadDoc, confirmDoc, returnDoc, completeDoc, getAvailableActions, getDocDownloadUrl } from '/@/api/finance/purchasingdoc'
|
||||
import other from '/@/utils/other'
|
||||
|
||||
const AuditRecordList = defineAsyncComponent(() => import('./AuditRecordList.vue'));
|
||||
|
||||
const emit = defineEmits(['refresh']);
|
||||
|
||||
const visible = ref(false)
|
||||
const activeTab = ref('info')
|
||||
const applyInfo = ref<any>({})
|
||||
const requirementFiles = ref<any[]>([])
|
||||
const requirementLoading = ref(false)
|
||||
const docList = ref<any[]>([])
|
||||
const docLoading = ref(false)
|
||||
const auditRecordListRef = ref()
|
||||
const availableActions = ref<string[]>([])
|
||||
|
||||
const returnDialogVisible = ref(false)
|
||||
const returnRemark = ref('')
|
||||
|
||||
const canUpload = computed(() => availableActions.value.includes('upload'))
|
||||
const canConfirm = computed(() => availableActions.value.includes('confirm'))
|
||||
const canReturn = computed(() => availableActions.value.includes('return'))
|
||||
const canComplete = computed(() => availableActions.value.includes('complete'))
|
||||
|
||||
const open = async (row: any) => {
|
||||
visible.value = true
|
||||
activeTab.value = 'info'
|
||||
applyInfo.value = {}
|
||||
requirementFiles.value = []
|
||||
docList.value = []
|
||||
returnRemark.value = ''
|
||||
|
||||
// 加载详情
|
||||
try {
|
||||
const res = await getObj(row.id)
|
||||
applyInfo.value = res.data || res
|
||||
} catch (e: any) {
|
||||
useMessage().error(e?.msg || '加载项目信息失败')
|
||||
return
|
||||
}
|
||||
|
||||
// 加载可执行操作
|
||||
try {
|
||||
const actionsRes = await getAvailableActions(row.id)
|
||||
availableActions.value = actionsRes.data || []
|
||||
} catch (e) {
|
||||
availableActions.value = []
|
||||
}
|
||||
|
||||
// 加载采购需求文件
|
||||
loadRequirementFiles()
|
||||
// 加载采购文件
|
||||
loadDocList()
|
||||
}
|
||||
|
||||
const loadRequirementFiles = async () => {
|
||||
if (!applyInfo.value.id) return
|
||||
requirementLoading.value = true
|
||||
try {
|
||||
const res = await getApplyFiles(applyInfo.value.id)
|
||||
const files = res.data || res || []
|
||||
// 过滤采购需求文件(fileType=120)
|
||||
requirementFiles.value = files.filter((f: any) => f.fileType === '120')
|
||||
} catch (e) {
|
||||
requirementFiles.value = []
|
||||
} finally {
|
||||
requirementLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const loadDocList = async () => {
|
||||
if (!applyInfo.value.id) return
|
||||
docLoading.value = true
|
||||
try {
|
||||
const res = await getDocList(applyInfo.value.id)
|
||||
docList.value = res.data || []
|
||||
} catch (e) {
|
||||
docList.value = []
|
||||
} finally {
|
||||
docLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleUpload = () => {
|
||||
// 触发文件上传
|
||||
const input = document.createElement('input')
|
||||
input.type = 'file'
|
||||
input.accept = '*/*'
|
||||
input.onchange = async (e: any) => {
|
||||
const file = e.target.files[0]
|
||||
if (!file) return
|
||||
// TODO: 实现文件上传到OSS,然后调用上传接口
|
||||
useMessage().info('文件上传功能需要配合OSS实现')
|
||||
}
|
||||
input.click()
|
||||
}
|
||||
|
||||
const handleDownloadRequirement = (row: any) => {
|
||||
if (row.remark) {
|
||||
const url = `/purchase/purchasingfiles/download?fileName=${encodeURIComponent(row.remark)}&fileTitle=${encodeURIComponent(row.fileTitle)}`
|
||||
other.downBlobFile(url, {}, row.fileTitle)
|
||||
}
|
||||
}
|
||||
|
||||
const handleDownloadDoc = (row: any) => {
|
||||
const url = getDocDownloadUrl(row.id)
|
||||
other.downBlobFile(url, {}, row.fileName)
|
||||
}
|
||||
|
||||
const handleConfirm = async () => {
|
||||
try {
|
||||
await useMessageBox().confirm('确定要确认该采购文件无误吗?')
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await confirmDoc({ applyId: applyInfo.value.id })
|
||||
useMessage().success('确认成功')
|
||||
emit('refresh')
|
||||
loadDocList()
|
||||
auditRecordListRef.value?.refresh()
|
||||
// 重新加载可执行操作
|
||||
const actionsRes = await getAvailableActions(applyInfo.value.id)
|
||||
availableActions.value = actionsRes.data || []
|
||||
} catch (e: any) {
|
||||
useMessage().error(e?.msg || '确认失败')
|
||||
}
|
||||
}
|
||||
|
||||
const handleReturn = () => {
|
||||
returnRemark.value = ''
|
||||
returnDialogVisible.value = true
|
||||
}
|
||||
|
||||
const submitReturn = async () => {
|
||||
try {
|
||||
await returnDoc({ applyId: applyInfo.value.id, remark: returnRemark.value })
|
||||
useMessage().success('退回成功')
|
||||
returnDialogVisible.value = false
|
||||
emit('refresh')
|
||||
loadDocList()
|
||||
auditRecordListRef.value?.refresh()
|
||||
// 重新加载可执行操作
|
||||
const actionsRes = await getAvailableActions(applyInfo.value.id)
|
||||
availableActions.value = actionsRes.data || []
|
||||
} catch (e: any) {
|
||||
useMessage().error(e?.msg || '退回失败')
|
||||
}
|
||||
}
|
||||
|
||||
const handleComplete = async () => {
|
||||
try {
|
||||
await useMessageBox().confirm('确定要确认流程结束吗?')
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
try {
|
||||
await completeDoc(applyInfo.value.id)
|
||||
useMessage().success('流程已结束')
|
||||
emit('refresh')
|
||||
loadDocList()
|
||||
auditRecordListRef.value?.refresh()
|
||||
// 重新加载可执行操作
|
||||
const actionsRes = await getAvailableActions(applyInfo.value.id)
|
||||
availableActions.value = actionsRes.data || []
|
||||
} catch (e: any) {
|
||||
useMessage().error(e?.msg || '操作失败')
|
||||
}
|
||||
}
|
||||
|
||||
const handleClose = () => {
|
||||
visible.value = false
|
||||
}
|
||||
|
||||
const getStatusType = (status: string) => {
|
||||
const typeMap: Record<string, string> = {
|
||||
'PENDING_UPLOAD': 'info',
|
||||
'ASSET_REVIEWING': 'warning',
|
||||
'DEPT_REVIEWING': 'warning',
|
||||
'AUDIT_REVIEWING': 'warning',
|
||||
'ASSET_CONFIRMING': 'primary',
|
||||
'COMPLETED': 'success',
|
||||
'RETURNED': 'danger'
|
||||
}
|
||||
return typeMap[status] || 'info'
|
||||
}
|
||||
|
||||
const getStatusLabel = (status: string) => {
|
||||
const labelMap: Record<string, string> = {
|
||||
'PENDING_UPLOAD': '待上传',
|
||||
'ASSET_REVIEWING': '资产管理处审核中',
|
||||
'DEPT_REVIEWING': '需求部门审核中',
|
||||
'AUDIT_REVIEWING': '内审部门审核中',
|
||||
'ASSET_CONFIRMING': '资产管理处确认中',
|
||||
'COMPLETED': '已完成',
|
||||
'RETURNED': '已退回'
|
||||
}
|
||||
return labelMap[status] || '-'
|
||||
}
|
||||
|
||||
const getFileTypeLabel = (type: string) => {
|
||||
const labelMap: Record<string, string> = {
|
||||
'120': '采购需求表',
|
||||
'130': '采购文件'
|
||||
}
|
||||
return labelMap[type] || type
|
||||
}
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.doc-header {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.dialog-footer {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 8px;
|
||||
}
|
||||
</style>
|
||||
193
src/views/finance/purchasingrequisition/docAudit/index.vue
Normal file
193
src/views/finance/purchasingrequisition/docAudit/index.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<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="docAuditStatus">
|
||||
<el-select
|
||||
v-model="state.queryForm.docAuditStatus"
|
||||
placeholder="请选择审核状态"
|
||||
clearable
|
||||
style="width: 200px">
|
||||
<el-option label="待上传" value="PENDING_UPLOAD" />
|
||||
<el-option label="资产管理处审核中" value="ASSET_REVIEWING" />
|
||||
<el-option label="需求部门审核中" value="DEPT_REVIEWING" />
|
||||
<el-option label="内审部门审核中" value="AUDIT_REVIEWING" />
|
||||
<el-option label="资产管理处确认中" value="ASSET_CONFIRMING" />
|
||||
<el-option label="已完成" value="COMPLETED" />
|
||||
<el-option label="已退回" value="RETURNED" />
|
||||
</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"><DocumentChecked /></el-icon>
|
||||
采购文件审核
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<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 />
|
||||
<el-table-column prop="projectName" label="项目名称" min-width="200" show-overflow-tooltip />
|
||||
<el-table-column prop="deptName" label="需求部门" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column prop="budget" label="预算金额(元)" width="120" align="right">
|
||||
<template #default="scope">
|
||||
{{ scope.row.budget ? Number(scope.row.budget).toLocaleString() : '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="docAuditStatus" label="审核状态" width="140" align="center">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.docAuditStatus)">
|
||||
{{ getStatusLabel(scope.row.docAuditStatus) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="currentDocVersion" label="当前版本" width="100" align="center">
|
||||
<template #default="scope">
|
||||
{{ scope.row.currentDocVersion || '-' }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" fixed="right" width="120">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link icon="View" @click="handleAudit(scope.row)">
|
||||
审核
|
||||
</el-button>
|
||||
</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>
|
||||
|
||||
<!-- 审核弹窗 -->
|
||||
<DocAuditDialog ref="docAuditDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="PurchasingDocAudit">
|
||||
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
|
||||
import { BasicTableProps, useTable } from "/@/hooks/table";
|
||||
import { useMessage } from "/@/hooks/message";
|
||||
import { getPage } from "/@/api/finance/purchasingrequisition";
|
||||
import { Search, DocumentChecked, List } from '@element-plus/icons-vue'
|
||||
|
||||
// 引入组件
|
||||
const DocAuditDialog = defineAsyncComponent(() => import('./DocAuditDialog.vue'));
|
||||
|
||||
const docAuditDialogRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
pageList: getPage,
|
||||
queryForm: {
|
||||
purchaseNo: '',
|
||||
projectName: '',
|
||||
docAuditStatus: '',
|
||||
},
|
||||
createdIsNeed: true
|
||||
});
|
||||
|
||||
const { getDataList, tableStyle, sizeChangeHandle, currentChangeHandle } = useTable(state);
|
||||
|
||||
const handleReset = () => {
|
||||
searchFormRef.value?.resetFields();
|
||||
getDataList();
|
||||
};
|
||||
|
||||
const getStatusType = (status: string) => {
|
||||
const typeMap: Record<string, string> = {
|
||||
'PENDING_UPLOAD': 'info',
|
||||
'ASSET_REVIEWING': 'warning',
|
||||
'DEPT_REVIEWING': 'warning',
|
||||
'AUDIT_REVIEWING': 'warning',
|
||||
'ASSET_CONFIRMING': 'primary',
|
||||
'COMPLETED': 'success',
|
||||
'RETURNED': 'danger'
|
||||
};
|
||||
return typeMap[status] || 'info';
|
||||
};
|
||||
|
||||
const getStatusLabel = (status: string) => {
|
||||
const labelMap: Record<string, string> = {
|
||||
'PENDING_UPLOAD': '待上传',
|
||||
'ASSET_REVIEWING': '资产管理处审核中',
|
||||
'DEPT_REVIEWING': '需求部门审核中',
|
||||
'AUDIT_REVIEWING': '内审部门审核中',
|
||||
'ASSET_CONFIRMING': '资产管理处确认中',
|
||||
'COMPLETED': '已完成',
|
||||
'RETURNED': '已退回'
|
||||
};
|
||||
return labelMap[status] || '-';
|
||||
};
|
||||
|
||||
const handleAudit = (row: any) => {
|
||||
docAuditDialogRef.value?.open(row);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
// 页面加载时的初始化逻辑
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '/@/assets/styles/modern-page.scss';
|
||||
</style>
|
||||
@@ -235,52 +235,7 @@
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="fileFlowStatus" label="文件审批状态" width="110" align="center">
|
||||
<template #header>
|
||||
<el-icon><DocumentChecked /></el-icon>
|
||||
<span style="margin-left: 4px">文件审批状态</span>
|
||||
</template>
|
||||
<template #default="scope">
|
||||
<template v-if="scope.row.fileFlowInstId">
|
||||
<el-tooltip content="点击查看审批过程" placement="top">
|
||||
<el-tag
|
||||
v-if="scope.row.fileFlowStatus === '-2'"
|
||||
type="info"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFileFlowComment(scope.row)">撤回</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.fileFlowStatus === '-1'"
|
||||
type="warning"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFileFlowComment(scope.row)">暂存</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.fileFlowStatus === '0'"
|
||||
type="primary"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFileFlowComment(scope.row)">运行中</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.fileFlowStatus === '1'"
|
||||
type="success"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFileFlowComment(scope.row)">完成</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.fileFlowStatus === '2'"
|
||||
type="danger"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFileFlowComment(scope.row)">作废</el-tag>
|
||||
<el-tag
|
||||
v-else-if="scope.row.fileFlowStatus === '3'"
|
||||
type="info"
|
||||
class="status-tag-clickable"
|
||||
@click="handleShowFileFlowComment(scope.row)">终止</el-tag>
|
||||
<span v-else class="status-tag-clickable" @click="handleShowFileFlowComment(scope.row)">-</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
<template v-else>
|
||||
<span style="color: #909399;">—</span>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column label="操作" align="center" fixed="right" width="150">
|
||||
<template #default="scope">
|
||||
<div class="op-cell">
|
||||
@@ -391,6 +346,9 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 采购文件审核弹窗 -->
|
||||
<DocAuditDialog ref="docAuditDialogRef" @refresh="getDataList" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -412,6 +370,7 @@ 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({
|
||||
@@ -431,6 +390,7 @@ const formDialogRef = ref()
|
||||
const acceptModalRef = ref()
|
||||
const searchFormRef = ref()
|
||||
const showSearch = ref(true)
|
||||
const docAuditDialogRef = ref()
|
||||
/** 审批过程弹窗:是否显示、当前行对应的流程 job(供 Comment 组件用)、类型(申请单/文件) */
|
||||
const showFlowComment = ref(false)
|
||||
const currFlowJob = ref<{ id?: number; flowInstId?: number } | null>(null)
|
||||
@@ -599,6 +559,11 @@ const handleImplement = (row: any) => {
|
||||
implementFormRef.value?.openDialog(row);
|
||||
};
|
||||
|
||||
/** 打开采购文件审核 */
|
||||
const handleDocAudit = (row: any) => {
|
||||
docAuditDialogRef.value?.open(row);
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除当前行
|
||||
* @param row - 当前行数据
|
||||
@@ -692,6 +657,12 @@ const getActionMenuItems = (row: any) => {
|
||||
icon: Collection,
|
||||
visible: () => row?.purchaseMode === '2' || (row?.purchaseMode === '0' && row?.purchaseType === '4'),
|
||||
},
|
||||
{
|
||||
command: 'docAudit',
|
||||
label: '采购文件审核',
|
||||
icon: DocumentChecked,
|
||||
visible: () => row?.implementType === '2' && row?.agentId,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
@@ -725,6 +696,9 @@ const handleMoreCommand = (command: string, row: any) => {
|
||||
case 'assignAgent':
|
||||
openAssignAgentDialog(row);
|
||||
break;
|
||||
case 'docAudit':
|
||||
handleDocAudit(row);
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -6,12 +6,18 @@
|
||||
<div class="card-header">
|
||||
|
||||
<div class="header-actions">
|
||||
<el-button type="primary" icon="FolderAdd" @click="openUploadDialog()">
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="FolderAdd"
|
||||
@click="openUploadDialog()"
|
||||
v-auth="'purchase_template_add'">
|
||||
新增模板
|
||||
</el-button>
|
||||
|
||||
|
||||
<el-alert type="info" :closable="false" class="mb3 mt-3" show-icon>
|
||||
此处模版中的模版编码对应用户端下载模版匹配,请勿随意修改或删除。正常情况下如有发生模版变化,重新上传即可。如有新增模版,请联系管理员进行处理。
|
||||
</el-alert>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -27,13 +33,28 @@
|
||||
<el-table-column prop="updateTime" label="更新时间" width="180" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="260" align="center" fixed="right">
|
||||
<template #default="{ row }">
|
||||
<el-button type="primary" link icon="Download" @click="handleDownload(row)">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Download"
|
||||
@click="handleDownload(row)"
|
||||
v-auth="'purchase_template_view'">
|
||||
下载
|
||||
</el-button>
|
||||
<el-button type="primary" link icon="UploadFilled" @click="openUploadDialog(row)">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="UploadFilled"
|
||||
@click="openUploadDialog(row)"
|
||||
v-auth="'purchase_template_add'">
|
||||
重新上传
|
||||
</el-button>
|
||||
<el-button type="primary" link icon="Edit" @click="openEditDialog(row)">
|
||||
<el-button
|
||||
type="primary"
|
||||
link
|
||||
icon="Edit"
|
||||
@click="openEditDialog(row)"
|
||||
v-auth="'purchase_template_add'">
|
||||
编辑
|
||||
</el-button>
|
||||
</template>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Document /></el-icon>
|
||||
业务分管部门及人员
|
||||
业务分管处室及人员
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
icon="FolderAdd"
|
||||
type="primary"
|
||||
@click="formDialogRef.openDialog()"
|
||||
v-auth="'purchase_purchasingBusinessLeader_add'">
|
||||
v-auth="'purchasing_bus_leader_add'">
|
||||
新增
|
||||
</el-button>
|
||||
<el-button
|
||||
@@ -55,13 +55,13 @@
|
||||
icon="Delete"
|
||||
type="primary"
|
||||
class="ml10"
|
||||
v-auth="'purchase_purchasingBusinessLeader_del'"
|
||||
v-auth="'purchasing_bus_leader_del'"
|
||||
@click="handleDelete(selectObjs)">
|
||||
删除
|
||||
</el-button>
|
||||
<right-toolbar
|
||||
v-model:showSearch="showSearch"
|
||||
:export="'purchase_purchasingBusinessLeader_export'"
|
||||
:export="'purchasing_bus_leader_export'"
|
||||
@exportExcel="exportExcel"
|
||||
class="ml10"
|
||||
@queryTable="getDataList" />
|
||||
@@ -116,7 +116,7 @@
|
||||
icon="Delete"
|
||||
link
|
||||
type="danger"
|
||||
v-auth="'purchase_purchasingBusinessLeader_del'"
|
||||
v-auth="'purchasing_bus_leader_del'"
|
||||
@click="handleDelete([scope.row.id])">
|
||||
删除
|
||||
</el-button>
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Document /></el-icon>
|
||||
采购分管部门及人员
|
||||
采购分管领导
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button
|
||||
|
||||
@@ -39,13 +39,15 @@
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><User /></el-icon>
|
||||
校领导(党委)管理
|
||||
校党委人员
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<el-button
|
||||
icon="FolderAdd"
|
||||
type="primary"
|
||||
@click="formDialogRef.openDialog('add')">
|
||||
@click="formDialogRef.openDialog('add')"
|
||||
v-auth="'purchase_purchasingSchoolLeader_add'"
|
||||
>
|
||||
新增
|
||||
</el-button>
|
||||
<right-toolbar v-model:showSearch="showSearch" class="ml10" @queryTable="getDataList" />
|
||||
@@ -104,6 +106,7 @@
|
||||
icon="Delete"
|
||||
link
|
||||
type="danger"
|
||||
v-auth="'purchase_purchasingSchoolLeader_del'"
|
||||
@click="handleDelete(scope.row)">
|
||||
删除
|
||||
</el-button>
|
||||
|
||||
Reference in New Issue
Block a user