ruoyi-plus-vben5/apps/web-antd/src/views/workflow/task/taskWaiting.vue

218 lines
6.2 KiB
Vue
Raw Normal View History

2024-12-18 15:36:12 +08:00
<!-- eslint-disable no-use-before-define -->
2024-08-07 08:57:56 +08:00
<script setup lang="ts">
2024-12-12 16:07:42 +08:00
import type { FlowInfoResponse } from '#/api/workflow/instance/model';
import type { TaskInfo } from '#/api/workflow/task/model';
2024-11-21 17:02:22 +08:00
2024-12-12 16:07:42 +08:00
import { computed, onMounted, ref } from 'vue';
2024-12-16 09:45:00 +08:00
import { Page } from '@vben/common-ui';
2024-12-17 15:08:31 +08:00
import { useTabs } from '@vben/hooks';
2024-12-16 09:45:00 +08:00
2024-12-18 15:36:12 +08:00
import { FilterOutlined, RedoOutlined } from '@ant-design/icons-vue';
import {
Empty,
Form,
FormItem,
Input,
InputSearch,
Popover,
Spin,
} from 'ant-design-vue';
import { cloneDeep, debounce } from 'lodash-es';
2024-12-12 16:07:42 +08:00
import { flowInfo } from '#/api/workflow/instance';
import { pageByTaskWait } from '#/api/workflow/task';
2024-11-21 16:29:40 +08:00
2024-12-16 09:45:00 +08:00
import { ApprovalCard, ApprovalPanel } from '../components';
2024-11-21 17:02:22 +08:00
2024-12-12 16:07:42 +08:00
const emptyImage = Empty.PRESENTED_IMAGE_SIMPLE;
const taskList = ref<({ active: boolean } & TaskInfo)[]>([]);
const taskTotal = ref(0);
const page = ref(1);
2024-12-18 15:36:12 +08:00
const loading = ref(false);
const defaultFormData = {
flowName: '', // 流程定义名称
nodeName: '', // 任务名称
flowCode: '', // 流程定义编码
};
const formData = ref(cloneDeep(defaultFormData));
2024-12-12 16:07:42 +08:00
/**
* 是否已经加载全部数据 taskList.length === taskTotal
*/
const isLoadComplete = computed(
() => taskList.value.length === taskTotal.value,
);
2024-12-18 15:36:12 +08:00
/**
* @param resetFields 是否清空查询参数
*/
async function reload(resetFields: boolean = false) {
page.value = 1;
currentTask.value = undefined;
taskTotal.value = 0;
lastSelectId.value = '';
if (resetFields) {
formData.value = cloneDeep(defaultFormData);
}
loading.value = true;
const resp = await pageByTaskWait({
pageSize: 10,
pageNum: page.value,
...formData.value,
});
2024-12-12 16:07:42 +08:00
taskList.value = resp.rows.map((item) => ({ ...item, active: false }));
taskTotal.value = resp.total;
2024-12-18 15:36:12 +08:00
loading.value = false;
}
onMounted(reload);
2024-12-12 16:07:42 +08:00
const handleScroll = debounce(async (e: Event) => {
2024-11-21 17:02:22 +08:00
if (!e.target) {
return;
}
// e.target.scrollTop 是元素顶部到当前可视区域顶部的距离,即已滚动的高度。
// e.target.clientHeight 是元素的可视高度。
// e.target.scrollHeight 是元素的总高度。
const { scrollTop, clientHeight, scrollHeight } = e.target as HTMLElement;
// 判断是否滚动到底部
const isBottom = scrollTop + clientHeight >= scrollHeight;
2024-11-21 19:21:20 +08:00
2024-12-12 16:07:42 +08:00
// 滚动到底部且没有加载完成
if (isBottom && !isLoadComplete.value) {
2024-12-18 15:36:12 +08:00
loading.value = true;
2024-12-12 16:07:42 +08:00
page.value += 1;
2024-12-18 15:36:12 +08:00
const resp = await pageByTaskWait({
pageSize: 10,
pageNum: page.value,
...formData.value,
});
2024-12-12 16:07:42 +08:00
taskList.value.push(
...resp.rows.map((item) => ({ ...item, active: false })),
);
2024-12-18 15:36:12 +08:00
loading.value = false;
2024-12-12 16:07:42 +08:00
}
}, 200);
2024-11-21 19:21:20 +08:00
2024-12-12 16:07:42 +08:00
const currentInstance = ref<FlowInfoResponse>();
2024-11-25 15:02:01 +08:00
2024-11-21 19:53:16 +08:00
const lastSelectId = ref('');
2024-12-16 09:45:00 +08:00
const currentTask = ref<TaskInfo>();
2024-12-12 16:07:42 +08:00
async function handleCardClick(item: TaskInfo) {
const { id, businessId } = item;
2024-11-21 19:53:16 +08:00
// 点击的是同一个
if (lastSelectId.value === id) {
return;
}
2024-12-16 09:45:00 +08:00
currentTask.value = item;
2024-11-21 19:53:16 +08:00
// 反选状态 & 如果已经点击了 不变 & 保持只能有一个选中
2024-12-12 16:07:42 +08:00
taskList.value.forEach((item) => {
2024-11-21 19:53:16 +08:00
item.active = item.id === id;
2024-11-21 19:21:20 +08:00
});
2024-11-21 19:53:16 +08:00
lastSelectId.value = id;
2024-12-12 16:07:42 +08:00
const resp = await flowInfo(businessId);
currentInstance.value = resp;
2024-11-21 19:21:20 +08:00
}
2024-12-17 15:08:31 +08:00
const { refreshTab } = useTabs();
2024-08-07 08:57:56 +08:00
</script>
<template>
2024-11-21 16:29:40 +08:00
<Page :auto-content-height="true">
<div class="flex h-full gap-2">
2024-12-12 16:07:42 +08:00
<div
class="bg-background flex h-full min-w-[320px] max-w-[320px] flex-col rounded-lg"
>
2024-11-21 19:53:16 +08:00
<!-- 搜索条件 -->
<div
class="bg-background z-100 sticky left-0 top-0 w-full rounded-t-lg border-b-[1px] border-solid p-2"
>
2024-12-18 15:36:12 +08:00
<div class="flex items-center gap-1">
<InputSearch
v-model:value="formData.flowName"
placeholder="流程名称搜索"
@search="reload(false)"
/>
<a-button @click="reload(true)">
<RedoOutlined />
</a-button>
<Popover placement="rightTop" title="搜索" trigger="click">
<template #content>
<Form>
<FormItem label="任务名称">
<Input
v-model:value="formData.nodeName"
placeholder="请输入"
/>
</FormItem>
<FormItem label="流程编码">
<Input
v-model:value="formData.flowCode"
placeholder="请输入"
/>
</FormItem>
<FormItem>
<a-button type="primary" @click="reload(false)">
搜索
</a-button>
<a-button class="ml-2" @click="reload(true)">重置</a-button>
</FormItem>
</Form>
</template>
<a-button>
<FilterOutlined />
</a-button>
</Popover>
</div>
2024-11-21 19:53:16 +08:00
</div>
<div
2024-12-18 15:36:12 +08:00
class="thin-scrollbar relative flex flex-1 flex-col gap-2 overflow-y-auto py-3"
2024-11-21 19:53:16 +08:00
@scroll="handleScroll"
>
2024-12-12 16:07:42 +08:00
<template v-if="taskList.length > 0">
<ApprovalCard
v-for="item in taskList"
:key="item.id"
:info="item"
class="mx-2"
@click="handleCardClick(item)"
/>
</template>
<Empty v-else :image="emptyImage" />
2024-12-18 15:36:12 +08:00
<div
v-if="loading"
class="absolute left-0 top-0 flex h-full w-full items-center justify-center bg-[rgba(0,0,0,0.1)]"
>
<Spin tip="加载中..." />
</div>
2024-11-21 16:29:40 +08:00
</div>
2024-11-21 19:53:16 +08:00
<!-- total显示 -->
<div
class="bg-background sticky bottom-0 w-full rounded-b-lg border-t-[1px] py-2"
>
<div class="flex items-center justify-center">
2024-12-17 09:26:41 +08:00
{{ taskTotal }} 条记录
2024-11-21 19:53:16 +08:00
</div>
</div>
2024-11-21 16:29:40 +08:00
</div>
2024-12-17 15:08:31 +08:00
<ApprovalPanel :task="currentTask" type="approve" @reload="refreshTab" />
2024-11-21 16:29:40 +08:00
</div>
</Page>
2024-08-07 08:57:56 +08:00
</template>
2024-11-25 15:41:14 +08:00
<style lang="scss" scoped>
.thin-scrollbar {
&::-webkit-scrollbar {
width: 5px;
}
}
:deep(.ant-card-body) {
@apply thin-scrollbar;
}
</style>