更新采购申请前端

This commit is contained in:
吴红兵
2026-02-08 16:29:04 +08:00
parent 123c28b345
commit 5dc9b39cab
7 changed files with 502 additions and 2506 deletions

View File

@@ -193,38 +193,21 @@
<span v-else>-</span>
</template>
</el-table-column>
<el-table-column label="操作" align="center" fixed="right" width="360">
<el-table-column label="操作" align="center" fixed="right" width="150">
<template #default="scope">
<el-button
icon="View"
link
type="primary"
@click="handleView(scope.row)">
查看
</el-button>
<el-button
v-if="scope.row.status === '-1'"
icon="Edit"
link
type="primary"
@click="handleEdit(scope.row)">
编辑
</el-button>
<el-button
v-if="scope.row.status === '-1'"
icon="Delete"
link
type="danger"
@click="handleDelete(scope.row)">
删除
</el-button>
<el-button
icon="DocumentChecked"
link
type="primary"
@click="handleAccept(scope.row)">
履约验收
</el-button>
<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>
@@ -241,28 +224,7 @@
</el-card>
</div>
<!-- 新增页面 iframe 对话框 -->
<el-dialog
v-model="showAddIframe"
title="新增采购申请"
width="90%"
:style="{ maxWidth: '1600px' }"
:close-on-click-modal="false"
:close-on-press-escape="true"
destroy-on-close
class="iframe-dialog"
@close="closeAddIframe">
<div class="iframe-dialog-content">
<iframe
ref="addIframeRef"
:src="addIframeSrc"
frameborder="0"
class="add-iframe"
/>
</div>
</el-dialog>
<!-- 编辑新增表单对话框 -->
<!-- 新增/编辑/查看统一使用 form.vue 弹窗iframe 引入 add.vue -->
<FormDialog
ref="formDialogRef"
:dict-data="dictData"
@@ -274,17 +236,18 @@
</template>
<script setup lang="ts" name="PurchasingRequisition">
import { ref, reactive, defineAsyncComponent, onUnmounted, onMounted } from 'vue'
import { ref, reactive, defineAsyncComponent, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { BasicTableProps, useTable } from "/@/hooks/table";
import { getPage, delObj } from "/@/api/finance/purchasingrequisition";
import { getPage, delObj, submitObj } from "/@/api/finance/purchasingrequisition";
import { useMessage, useMessageBox } from "/@/hooks/message";
import { getDicts } from '/@/api/admin/dict';
import { getTree } from '/@/api/finance/purchasingcategory';
import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, InfoFilled, Calendar, OfficeBuilding, Warning, DocumentChecked } from '@element-plus/icons-vue'
import { List, Document, DocumentCopy, Search, Collection, Money, CircleCheck, InfoFilled, Calendar, OfficeBuilding, Warning, DocumentChecked, Edit, Delete, Upload } from '@element-plus/icons-vue'
// 引入组件
const FormDialog = defineAsyncComponent(() => import('./form.vue'));
const ActionDropdown = defineAsyncComponent(() => import('/@/components/tools/action-dropdown.vue'));
const PurchasingAcceptModal = defineAsyncComponent(() => import('./accept/PurchasingAcceptModal.vue'));
// 字典数据和品目树数据
@@ -305,9 +268,6 @@ const formDialogRef = ref()
const acceptModalRef = ref()
const searchFormRef = ref()
const showSearch = ref(true)
const showAddIframe = ref(false)
const addIframeRef = ref<HTMLIFrameElement>()
const addIframeSrc = ref('')
/**
* 定义响应式表格数据
@@ -338,42 +298,10 @@ const handleReset = () => {
};
/**
* 新增采购申请 - 在 iframe 中展示
* 新增采购申请 - 统一通过 form.vue 弹窗iframe 引入 add.vue
*/
const handleAdd = () => {
// 构建 iframe 的 src使用当前页面的 hash 路由
const baseUrl = window.location.origin + window.location.pathname
addIframeSrc.value = `${baseUrl}#/finance/purchasingrequisition/add`
showAddIframe.value = true
// 监听来自 iframe 的消息
window.addEventListener('message', handleIframeMessage)
};
/**
* 关闭新增 iframe
*/
const closeAddIframe = () => {
showAddIframe.value = false
// 移除消息监听器
window.removeEventListener('message', handleIframeMessage)
};
/**
* 处理 iframe 发送的消息
*/
const handleIframeMessage = (event: MessageEvent) => {
// 验证消息来源(可选,根据实际需求)
// if (event.origin !== window.location.origin) return
if (event.data && event.data.type === 'purchasingrequisition:submitSuccess') {
// 提交成功,关闭 iframe 并刷新列表
closeAddIframe()
getDataList()
useMessage().success('提交成功')
} else if (event.data && event.data.type === 'purchasingrequisition:close') {
// 关闭 iframe
closeAddIframe()
}
formDialogRef.value?.openDialog('add')
};
/**
@@ -421,6 +349,71 @@ const handleDelete = async (row: any) => {
}
};
/** 暂存状态下提交采购申请(启动流程) */
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';
return [
{
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: () => true,
},
];
};
/** 处理更多操作下拉菜单命令 */
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;
}
};
// 获取字典数据和品目树数据
const loadDictData = async () => {
try {
@@ -566,53 +559,15 @@ onMounted(() => {
loadDictData();
});
// 组件卸载时清理事件监听器
onUnmounted(() => {
window.removeEventListener('message', handleIframeMessage)
});
</script>
<style scoped lang="scss">
@import '/@/assets/styles/modern-page.scss';
.iframe-dialog-content {
width: 100%;
height: 70vh;
min-height: 500px;
max-height: calc(100vh - 200px);
position: relative;
overflow: hidden;
.add-iframe {
width: 100%;
height: 100%;
min-height: 500px;
border: none;
display: block;
}
}
:deep(.iframe-dialog) {
.el-dialog {
display: flex;
flex-direction: column;
max-height: 90vh;
margin-top: 5vh !important;
}
.el-dialog__header {
flex-shrink: 0;
padding: 20px 20px 10px;
}
.el-dialog__body {
padding: 20px;
overflow-y: auto;
overflow-x: hidden;
flex: 1;
min-height: 0;
max-height: calc(100vh - 200px);
}
.op-cell {
display: flex;
align-items: center;
justify-content: center;
}
</style>