Files
yunzerwebsiteallinone/backend/src/views/apps/oa/approvalcenter/list.vue
T
2026-11-14 07:54:01 +08:00

238 lines
7.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div class="approval-page">
<div class="page-header">
<div>
<h2>审批列表</h2>
<p>处理待我审批的单据,并查看已处理记录</p>
</div>
<div class="header-actions">
<el-radio-group v-model="filters.handled" @change="handleScopeChange">
<el-radio-button :value="0">待我审批</el-radio-button>
<el-radio-button :value="1">我已处理</el-radio-button>
</el-radio-group>
<el-button :icon="Refresh" @click="loadList">刷新</el-button>
</div>
</div>
<div class="filter-card">
<el-form :inline="true" :model="filters" @submit.prevent>
<el-form-item label="单据类型">
<el-select
v-model="filters.biz_type"
clearable
placeholder="全部类型"
style="width: 160px"
@change="loadList"
>
<el-option
v-for="item in bizTypes"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" :icon="Search" @click="loadList">查询</el-button>
</el-form-item>
</el-form>
</div>
<div class="table-card">
<div class="table-scroll">
<el-table v-loading="loading" :data="list" stripe>
<el-table-column label="单据标题" min-width="200" show-overflow-tooltip>
<template #default="{ row }">{{ row.instance?.biz_title || "-" }}</template>
</el-table-column>
<el-table-column label="单据类型" width="120">
<template #default="{ row }">{{ row.instance?.biz_type || "-" }}</template>
</el-table-column>
<el-table-column label="发起人" width="120">
<template #default="{ row }">{{ row.instance?.submit_user_name || "-" }}</template>
</el-table-column>
<el-table-column prop="node_name" label="审批节点" width="160" show-overflow-tooltip>
<template #default="{ row }">{{ row.node_name || row.node_key || "-" }}</template>
</el-table-column>
<el-table-column label="单据状态" width="110">
<template #default="{ row }">
<el-tag :type="tagType(row.instance?.status_tag)">{{
row.instance?.status_label || "-"
}}</el-tag>
</template>
</el-table-column>
<el-table-column label="任务状态" width="110">
<template #default="{ row }">
<el-tag :type="tagType(row.status_tag)">{{ row.status_label || "-" }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="create_time" label="到达时间" width="170">
<template #default="{ row }">{{ row.create_time || "-" }}</template>
</el-table-column>
<el-table-column label="操作" fixed="right" width="180">
<template #default="{ row }">
<el-button link type="primary" @click="openDetail(row.instance_id)">详情</el-button>
<el-button
v-if="row.status === 0"
link
type="primary"
@click="openDetail(row.instance_id)"
>去处理</el-button
>
</template>
</el-table-column>
<template #empty><el-empty :description="emptyText" /></template>
</el-table>
</div>
<div class="pagination">
<el-pagination
:current-page="pagination.page"
:page-size="pagination.pageSize"
:total="pagination.total"
layout="total, sizes, prev, pager, next, jumper"
@update:current-page="pagination.page = $event"
@update:page-size="pagination.pageSize = $event"
@current-change="loadList"
@size-change="loadList"
/>
</div>
</div>
<DetailDrawer v-model="detailVisible" :instance-id="detailId" @changed="loadList" />
</div>
</template>
<script setup>
import { computed, onMounted, reactive, ref } from "vue";
import { ElMessage } from "element-plus";
import { Refresh, Search } from "@element-plus/icons-vue";
import DetailDrawer from "./components/DetailDrawer.vue";
import { getApprovalTodo } from "@/api/approval";
// 进销存审批由 ERP 工作台的审批列表单独处理,OA 审批中心只管其它审批
const ERP_BIZ_PREFIX = "erp_";
const ALL_NON_ERP = "non_erp";
const bizTypes = [
{ value: ALL_NON_ERP, label: "全部类型" },
{ value: "reimburse", label: "报销单" },
{ value: "oa", label: "OA 通用审批" },
];
const filters = reactive({ handled: 0, biz_type: ALL_NON_ERP });
const pagination = reactive({ page: 1, pageSize: 10, total: 0 });
const list = ref([]);
const loading = ref(false);
const detailVisible = ref(false);
const detailId = ref("");
const emptyText = computed(() =>
filters.handled === 1 ? "暂无已处理的审批" : "暂无待我审批的单据",
);
const responseData = (res) => res?.data?.data ?? res?.data ?? res ?? {};
const loadList = async () => {
loading.value = true;
try {
// 清空下拉也按「全部非 ERP 审批」处理,保证不会混入进销存审批
const scope = filters.biz_type || ALL_NON_ERP;
const data = responseData(
await getApprovalTodo({
handled: filters.handled,
biz_type: scope,
page: pagination.page,
pageSize: pagination.pageSize,
}),
);
// 后端旧版本忽略 biz_type 时再兜一层,隔离始终生效
const rows = (data.list || []).filter(
(row) => !String(row?.instance?.biz_type || "").startsWith(ERP_BIZ_PREFIX)
);
list.value = scope === ALL_NON_ERP
? rows
: rows.filter((row) => row.instance?.biz_type === scope);
pagination.total = Number(data.total || 0);
} catch (error) {
ElMessage.error(error?.message || "加载审批列表失败");
} finally {
loading.value = false;
}
};
const handleScopeChange = () => {
pagination.page = 1;
loadList();
};
const openDetail = (id) => {
detailId.value = id;
detailVisible.value = true;
};
function tagType(type) {
if (type === "error") return "danger";
return type || "info";
}
onMounted(loadList);
</script>
<style lang="less" scoped>
.approval-page {
background: var(--el-bg-color-page);
padding: 20px;
}
.page-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 16px;
h2 {
margin: 0 0 8px;
color: var(--el-text-color-primary);
font-size: 22px;
}
p {
margin: 0;
color: var(--el-text-color-secondary);
font-size: 13px;
}
}
.header-actions {
display: flex;
align-items: center;
gap: 10px;
flex-shrink: 0;
}
.filter-card,
.table-card {
background: var(--el-bg-color);
border-radius: var(--el-border-radius-base);
padding: 18px;
border: 1px solid var(--el-border-color-lighter);
}
.filter-card {
margin-bottom: 16px;
:deep(.el-form-item) {
margin-bottom: 0;
}
}
.table-scroll {
width: 100%;
}
.pagination {
display: flex;
justify-content: flex-end;
margin-top: 16px;
}
</style>