8.9 KiB
8.9 KiB
任务管理页面设计文档
1. 页面概述
任务管理页面是系统的核心功能模块之一,允许主管和管理员对任务进行全面的管理。用户可以在此页面上查看所有任务,并使用筛选、排序和搜索功能快速定位任务。此外,页面还支持任务的分配、审核以及查看任务详情等操作。
2. 页面布局
2.1 布局结构
页面采用经典的后台管理布局:
- 顶部: 包含页面标题和操作按钮(如"新建任务")。
- 中部: 筛选和搜索区域,提供多种条件来过滤任务列表。
- 下部: 任务数据表格,以列表形式展示任务,并包含操作列。
- 底部: 分页组件,用于浏览大量任务数据。
2.2 响应式设计
- 桌面端: 多列表格,所有筛选条件水平排列。
- 平板端: 表格列数减少,部分次要信息可能隐藏,筛选条件折叠或垂直排列。
- 移动端: 表格转为卡片列表视图,每个卡片显示一个任务的核心信息,筛选功能通过抽屉或模态框提供。
3. 组件结构
<template>
<div class="task-management-page">
<!-- 页面头部 -->
<el-page-header title="任务管理" content="任务列表与分配" />
<el-card class="page-container">
<!-- 筛选与搜索区域 -->
<div class="filter-container">
<el-form :model="filters" inline>
<el-form-item label="任务状态">
<el-select v-model="filters.status" placeholder="请选择状态" clearable>
<el-option label="待处理" value="PENDING" />
<el-option label="进行中" value="IN_PROGRESS" />
<el-option label="已完成" value="COMPLETED" />
<el-option label="已审核" value="REVIEWED" />
</el-select>
</el-form-item>
<el-form-item label="执行人">
<el-input v-model="filters.assignee" placeholder="请输入执行人" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
<el-button icon="Refresh" @click="handleReset">重置</el-button>
</el-form-item>
</el-form>
</div>
<!-- 操作按钮区域 -->
<div class="action-buttons">
<el-button type="primary" icon="Plus" @click="handleCreateTask" v-permission="'SUPERVISOR'">
新建任务
</el-button>
</div>
<!-- 任务表格 -->
<el-table :data="tasks" v-loading="loading" stripe>
<el-table-column type="index" width="50" />
<el-table-column prop="title" label="任务标题" min-width="150" />
<el-table-column prop="grid" label="所属网格" />
<el-table-column prop="assignee" label="执行人" />
<el-table-column prop="status" label="状态">
<template #default="{ row }">
<el-tag :type="getStatusTagType(row.status)">{{ formatStatus(row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="createdAt" label="创建时间" sortable />
<el-table-column label="操作" width="200" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="handleView(row)">查看</el-button>
<el-button link type="primary" @click="handleAssign(row)" v-if="canAssign(row)">分配</el-button>
<el-button link type="primary" @click="handleReview(row)" v-if="canReview(row)">审核</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页组件 -->
<el-pagination
v-if="total > 0"
class="pagination-container"
:current-page="pagination.page"
:page-size="pagination.pageSize"
:total="total"
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</el-card>
<!-- 任务分配/审核/新建的对话框 -->
<TaskFormDialog v-model="dialogVisible" :task-id="selectedTaskId" :mode="dialogMode" @success="handleSuccess" />
</div>
</template>
4. 数据结构
// 任务筛选条件
interface TaskFilters {
status?: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'REVIEWED';
assignee?: string;
}
// 分页信息
interface Pagination {
page: number;
pageSize: number;
}
// 任务列表项
interface TaskItem {
id: number;
title: string;
grid: string;
assignee: string | null;
status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'REVIEWED';
createdAt: string;
}
// 对话框模式
type DialogMode = 'create' | 'assign' | 'review' | 'view';
5. 状态管理
// 组件内状态
const filters = ref<TaskFilters>({});
const pagination = ref<Pagination>({ page: 1, pageSize: 10 });
const dialogVisible = ref(false);
const selectedTaskId = ref<number | null>(null);
const dialogMode = ref<DialogMode>('view');
// 全局状态 (Pinia Store)
const taskStore = useTaskStore();
const { tasks, total, loading } = storeToRefs(taskStore);
const authStore = useAuthStore();
const { user } = storeToRefs(authStore);
6. 交互逻辑
6.1 数据获取与筛选
const fetchTasks = () => {
taskStore.fetchTasks({ ...filters.value, ...pagination.value });
};
onMounted(fetchTasks);
const handleSearch = () => {
pagination.value.page = 1;
fetchTasks();
};
const handleReset = () => {
filters.value = {};
handleSearch();
};
const handleSizeChange = (size: number) => {
pagination.value.pageSize = size;
fetchTasks();
};
const handleCurrentChange = (page: number) => {
pagination.value.page = page;
fetchTasks();
};
6.2 表格操作
const handleView = (task: TaskItem) => {
selectedTaskId.value = task.id;
dialogMode.value = 'view';
dialogVisible.value = true;
};
const handleAssign = (task: TaskItem) => {
selectedTaskId.value = task.id;
dialogMode.value = 'assign';
dialogVisible.value = true;
};
const handleReview = (task: TaskItem) => {
selectedTaskId.value = task.id;
dialogMode.value = 'review';
dialogVisible.value = true;
};
const handleCreateTask = () => {
selectedTaskId.value = null;
dialogMode.value = 'create';
dialogVisible.value = true;
};
const handleSuccess = () => {
dialogVisible.value = false;
fetchTasks(); // 操作成功后刷新列表
};
6.3 权限控制
const canAssign = (task: TaskItem) => {
return user.value?.role === 'SUPERVISOR' && task.status === 'PENDING';
};
const canReview = (task: TaskItem) => {
return user.value?.role === 'SUPERVISOR' && task.status === 'COMPLETED';
};
6.4 辅助函数
const formatStatus = (status: TaskItem['status']) => {
const map = { PENDING: '待处理', IN_PROGRESS: '进行中', COMPLETED: '已完成', REVIEWED: '已审核' };
return map[status] || '未知';
};
// getStatusTagType 函数同仪表盘页面设计
7. API 调用
// api/tasks.ts
export const taskApi = {
getTasks: (params) => apiClient.get('/management/tasks', { params }),
// ... 其他任务相关API
};
// stores/task.ts
export const useTaskStore = defineStore('task', {
state: () => ({
tasks: [] as TaskItem[],
total: 0,
loading: false,
}),
actions: {
async fetchTasks(params) {
this.loading = true;
try {
const { data } = await taskApi.getTasks(params);
this.tasks = data.items;
this.total = data.total;
} catch (error) {
console.error('获取任务列表失败', error);
} finally {
this.loading = false;
}
}
}
});
8. 样式设计
.task-management-page {
padding: 24px;
.page-container {
margin-top: 24px;
padding: 24px;
border-radius: 8px;
border: none;
}
.filter-container {
margin-bottom: 20px;
}
.action-buttons {
margin-bottom: 20px;
}
.pagination-container {
margin-top: 24px;
display: flex;
justify-content: flex-end;
}
}
9. 测试用例
-
单元测试:
- 测试权限控制函数
canAssign和canReview的逻辑。 - 测试
formatStatus辅助函数的正确性。 - 测试 Pinia store 的 action 是否能正确调用 API 并更新 state。
- 测试权限控制函数
-
集成测试:
- 测试筛选、搜索和重置功能是否正常工作。
- 测试分页组件是否能正确切换页面和每页数量。
- 测试"查看"、"分配"、"审核"、"新建"按钮能否正确打开对应模式的对话框。
- 测试对话框操作成功后,任务列表是否刷新。
10. 性能优化
- 后端分页: 必须使用后端分页来处理大量任务数据。
- 防抖: 对搜索输入框使用防抖处理,避免用户输入时频繁触发 API 请求。
- 组件懒加载:
TaskFormDialog组件可以通过动态导入实现懒加载,只在需要时才加载。
