Merge branch 'developer' of ssh://code.cyweb.top:30033/scj/zhxy/v3/cloud-ui into developer

This commit is contained in:
zhoutianchi
2026-02-27 18:03:23 +08:00
13 changed files with 784 additions and 68 deletions

View 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'
});
}

View File

@@ -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" />
@@ -91,14 +92,16 @@
<el-button
icon="Edit"
link
type="primary"
type="primary"
v-auth="'purchase_purchasingagent_edit'"
@click="formDialogRef.openDialog('edit', scope.row)">
编辑
</el-button>
<el-button
icon="Delete"
link
type="danger"
type="danger"
v-auth="'purchase_purchasingagent_del'"
@click="handleDelete(scope.row)">
删除
</el-button>

View File

@@ -12,7 +12,8 @@
<div class="header-actions">
<el-button
icon="FolderAdd"
type="primary"
type="primary"
v-auth="'purchase_purchasingcategory_add'"
@click="formDialogRef.openDialog('add')">
新增
</el-button>
@@ -65,14 +66,16 @@
<el-button
icon="Edit"
link
type="primary"
type="primary"
v-auth="'purchase_purchasingcategory_edit'"
@click="formDialogRef.openDialog('edit', scope.row)">
编辑
</el-button>
<el-button
icon="Delete"
link
type="danger"
type="danger"
v-auth="'purchase_purchasingcategory_del'"
@click="handleDelete(scope.row)">
删除
</el-button>

View File

@@ -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="请选择采购方式"

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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;
}
};

View File

@@ -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>

View File

@@ -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

View File

@@ -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>

View File

@@ -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

View File

@@ -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" />
@@ -103,7 +105,8 @@
<el-button
icon="Delete"
link
type="danger"
type="danger"
v-auth="'purchase_purchasingSchoolLeader_del'"
@click="handleDelete(scope.row)">
删除
</el-button>