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

229 lines
6.6 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";
const bizTypes = [
{ value: "reimburse", label: "报销单" },
{ value: "oa", label: "OA 通用审批" },
];
const filters = reactive({ handled: 0, biz_type: "" });
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 {
const data = responseData(
await getApprovalTodo({
handled: filters.handled,
biz_type: filters.biz_type || "",
page: pagination.page,
pageSize: pagination.pageSize,
}),
);
// 前端二次过滤:类型下拉切换后即时生效
const rows = data.list || [];
list.value = filters.biz_type
? rows.filter((row) => row.instance?.biz_type === filters.biz_type)
: rows;
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>