7.8 KiB
7.8 KiB
反馈管理页面设计文档
1. 页面概述
反馈管理页面是管理员和主管处理用户提交的环境问题报告、建议或其他反馈的核心平台。此页面旨在提供一个高效的工作流程,用于审查、分类、回复和跟踪所有用户反馈,确保问题得到及时响应和解决。
2. 页面布局
2.1 布局结构
页面布局与任务管理页面类似,遵循标准的后台管理界面设计:
- 顶部: 筛选区域,允许管理员按反馈状态(待处理、已处理)、反馈类型或提交时间进行过滤。
- 中部: 反馈列表,以表格或卡片列表的形式展示反馈信息。
- 底部: 分页控件。
2.2 响应式设计
- 桌面端: 使用多列数据表格,清晰展示反馈的各项信息。
- 移动端: 转换为卡片式列表,每张卡片突出显示反馈标题、提交人和状态,并提供点击查看详情的入口。
3. 组件结构
<template>
<div class="feedback-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="RESOLVED" />
</el-select>
</el-form-item>
<el-form-item label="提交人">
<el-input v-model="filters.submitter" placeholder="输入提交人姓名/ID" clearable />
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleSearch">搜索</el-button>
</el-form-item>
</el-form>
</div>
<!-- 反馈表格 -->
<el-table :data="feedbackList" v-loading="loading" stripe>
<el-table-column prop="title" label="反馈标题" min-width="200" />
<el-table-column prop="submitterName" label="提交人" width="120" />
<el-table-column prop="createdAt" label="提交时间" width="180" sortable />
<el-table-column prop="status" label="状态" width="100">
<template #default="{ row }">
<el-tag :type="row.status === 'PENDING' ? 'warning' : 'success'">
{{ row.status === 'PENDING' ? '待处理' : '已处理' }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="操作" width="150" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="handleViewDetails(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>
<!-- 反馈详情对话框 -->
<FeedbackDetailDialog
v-model="dialogVisible"
:feedback-id="selectedFeedbackId"
@processed="handleProcessed"
/>
</div>
</template>
4. 数据结构
// 反馈筛选条件
interface FeedbackFilters {
status?: 'PENDING' | 'RESOLVED';
submitter?: string;
}
// 反馈列表项
interface FeedbackListItem {
id: number;
title: string;
submitterName: string;
createdAt: string;
status: 'PENDING' | 'RESOLVED';
}
// 反馈详情 (用于对话框)
interface FeedbackDetail extends FeedbackListItem {
content: string;
images: string[]; // 图片 URL 列表
location: string;
contact: string;
handlerNotes?: string; // 处理备注
}
5. 状态管理
// 组件内状态
const filters = ref<FeedbackFilters>({});
const pagination = ref({ page: 1, pageSize: 10 });
const dialogVisible = ref(false);
const selectedFeedbackId = ref<number | null>(null);
// 全局状态 (Pinia Store)
const feedbackStore = useFeedbackStore();
const { feedbackList, total, loading } = storeToRefs(feedbackStore);
6. 交互逻辑
6.1 数据获取与筛选
const fetchFeedback = () => {
feedbackStore.fetchFeedbackList({ ...filters.value, ...pagination.value });
};
onMounted(fetchFeedback);
const handleSearch = () => {
pagination.value.page = 1;
fetchFeedback();
};
// 分页逻辑 (handleSizeChange, handleCurrentChange) 与任务管理页面类似
6.2 查看详情与处理
const handleViewDetails = (feedback: FeedbackListItem) => {
selectedFeedbackId.value = feedback.id;
dialogVisible.value = true;
};
// 当详情对话框中完成处理后被调用
const handleProcessed = () => {
dialogVisible.value = false;
fetchFeedback(); // 刷新列表以更新状态
};
7. API 调用
7.1 反馈管理 API
// api/feedback.ts
export const feedbackApi = {
getFeedbackList: (params) => apiClient.get('/management/feedback', { params }),
getFeedbackDetail: (id: number) => apiClient.get(`/management/feedback/${id}`),
processFeedback: (id: number, data: { notes: string }) => apiClient.post(`/management/feedback/${id}/process`, data),
};
7.2 Pinia Store
// stores/feedback.ts
export const useFeedbackStore = defineStore('feedback', {
state: () => ({
feedbackList: [] as FeedbackListItem[],
total: 0,
loading: false,
currentFeedbackDetail: null as FeedbackDetail | null,
}),
actions: {
async fetchFeedbackList(params) {
this.loading = true;
try {
const { data } = await feedbackApi.getFeedbackList(params);
this.feedbackList = data.items;
this.total = data.total;
} finally {
this.loading = false;
}
},
async fetchFeedbackDetail(id: number) {
const { data } = await feedbackApi.getFeedbackDetail(id);
this.currentFeedbackDetail = data;
},
async processFeedback(payload: { id: number; notes: string }) {
await feedbackApi.processFeedback(payload.id, { notes: payload.notes });
}
}
});
8. 样式设计
.feedback-management-page {
padding: 24px;
.page-container {
margin-top: 24px;
padding: 24px;
border-radius: 8px;
border: none;
}
.filter-container {
margin-bottom: 20px;
}
.pagination-container {
margin-top: 24px;
display: flex;
justify-content: flex-end;
}
}
9. 关联组件
FeedbackDetailDialog.vue
这是一个关键的子组件,用于显示反馈的完整信息,并提供处理功能。
- Props:
modelValue(for v-model),feedbackId - 功能:
- 接收
feedbackId,在对话框打开时调用 store action 获取反馈详情。 - 展示反馈的文本内容、联系方式、地理位置和图片(图片可点击放大预览)。
- 提供一个文本域供管理员填写处理备注。
- 提供一个"标记为已处理"的按钮,点击后调用 store action 提交处理结果。
- 操作成功后,emit 一个
processed事件通知父组件刷新列表。
- 接收
10. 测试用例
-
单元测试:
- 测试 Pinia store 的各个 action 是否能正常工作。
- 测试
FeedbackDetailDialog组件在接收到feedbackId后是否能正确加载和显示数据。
-
集成测试:
- 测试筛选功能是否能正确过滤反馈列表。
- 测试分页是否正常。
- 测试点击"查看详情"按钮是否能打开对话框并加载正确的反馈信息。
- 测试在详情对话框中提交处理意见后,列表中的反馈状态是否更新。
