Files
Environment-Monitoring-System/Design/frontend_Design/FeedbackManagementPage_Design.md
ChuXun 4ce487588a 1
2025-10-19 20:31:01 +08:00

7.8 KiB
Raw Blame History

反馈管理页面设计文档

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. 测试用例

  1. 单元测试:

    • 测试 Pinia store 的各个 action 是否能正常工作。
    • 测试 FeedbackDetailDialog 组件在接收到 feedbackId 后是否能正确加载和显示数据。
  2. 集成测试:

    • 测试筛选功能是否能正确过滤反馈列表。
    • 测试分页是否正常。
    • 测试点击"查看详情"按钮是否能打开对话框并加载正确的反馈信息。
    • 测试在详情对话框中提交处理意见后,列表中的反馈状态是否更新。