<script setup lang="ts">
|
import { onMounted, ref } from 'vue';
|
import { IconifyIcon } from '@vben/icons';
|
import { usePortalMenus } from '#/components/portal/use-portal-menus';
|
import { getTaskTodoPage } from '#/api/bpm/task';
|
|
const { features, goMenu } = usePortalMenus();
|
const loading = ref(true), failed = ref(false);
|
const tasks = ref<{ id: string; name: string }[]>([]);
|
async function load() {
|
loading.value = true; failed.value = false;
|
try { const result = await getTaskTodoPage({ pageNo: 1, pageSize: 6 }); tasks.value = (result.list ?? []).map((task) => ({ id: String(task.id), name: task.name || '未命名任务' })); }
|
catch { failed.value = true; tasks.value = []; }
|
finally { loading.value = false; }
|
}
|
onMounted(load);
|
</script>
|
|
<template><article class="portal-todo-panel"><div class="todo-heading"><h2><IconifyIcon icon="lucide:list-todo" />我的待办</h2><button type="button" @click="goMenu(features.todo)">更多 <IconifyIcon icon="lucide:chevron-right" /></button></div><div v-if="loading" class="todo-status" role="status">正在加载待办…</div><div v-else-if="failed" class="todo-status" role="status"><span>待办加载失败</span><button type="button" @click="load">重新加载</button></div><div v-else-if="!tasks.length" class="todo-status"><IconifyIcon icon="lucide:inbox" /><span>暂无待办任务</span></div><ul v-else><li v-for="task in tasks" :key="task.id"><button type="button" @click="goMenu(features.todo)"><span>{{ task.name }}</span><IconifyIcon icon="lucide:chevron-right" /></button></li></ul></article></template>
|
|
<style scoped>
|
.portal-todo-panel { padding: 18px; border: 1px solid #e1ebf5; border-radius: 6px; background: #fff; }.todo-heading { display: flex; align-items: center; justify-content: space-between; margin-bottom: 15px; }.todo-heading h2 { display: flex; align-items: center; gap: 9px; margin: 0; color: #153a62; font-size: 17px; font-weight: 700; }.todo-heading h2 :deep(svg) { width: 19px; color: #b7242d; }.todo-heading button { display: flex; align-items: center; color: #5c7187; font-size: 11px; }.todo-status { display: flex; min-height: 230px; flex-direction: column; align-items: center; justify-content: center; gap: 12px; color: #5c7187; font-size: 13px; }.todo-status > :deep(svg) { width: 32px; height: 32px; color: #b6c9dc; }.todo-status button { min-height: 30px; padding: 4px 12px; border: 1px solid #d8e5f3; border-radius: 4px; color: #2b6094; background: #f6faff; }ul { margin: 0; padding: 0; list-style: none; }li + li { border-top: 1px solid #edf3f8; }li button { display: flex; width: 100%; min-height: 39px; align-items: center; justify-content: space-between; gap: 12px; color: #315273; font-size: 12px; text-align: left; }li span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }li :deep(svg) { width: 14px; flex: none; }button { cursor: pointer; }button:focus-visible { outline: 2px solid #2c70b2; outline-offset: 3px; }
|
</style>
|