Files
hzdyjs/✅出国记录变更历史显示功能实现完成.md
T
2025-10-14 16:41:19 +08:00

14 KiB

✅ 出国记录变更历史显示功能实现完成报告

📋 功能概述

实现日期: 2025-10-13
开发者: AI Assistant
需求描述: 在"出国申请"菜单下的"出国记录"选项卡中,点击"查看详情"按钮时,在弹窗界面中显示该记录的变更历史记录。


🎯 功能说明

业务流程

  1. 变更申请提交 → 用户在"出国行程变更申请"菜单下的"变更申请"选项卡提交变更
  2. 变更审批 → 管理员在"出国行程变更审批"菜单中审批变更申请
  3. 变更记录流转 → 审批通过后,变更记录会显示在两个地方:
    • 出国行程变更申请 → "变更记录"选项卡
    • 出国申请 → "出国记录"选项卡 → 查看详情弹窗中的"变更历史记录"区域 ✅ (本次实现)

数据关联关系

出国申请 (rs_overseas_application)
    ↓ 审批通过
出国记录 (rs_overseas_record)
    ↓ recordId 关联
出国行程变更 (rs_overseas_itinerary_change)

🛠️ 实现内容

1. 前端API导入

文件: web/src/views/rs/overseas/index.vue

修改内容:

// 导入变更历史查询API
import {
  // ... 其他API
  getItineraryChangeHistory,  // 新增:查询变更历史
  // ... 其他类型
} from '@/api/rs/overseas';

// 导入EditPen图标用于变更历史标题
import { UploadFilled, Document, Loading, Download, Delete, View, EditPen } from '@element-plus/icons-vue';

2. 状态管理

添加变更历史相关状态:

const state = reactive({
  // ... 其他状态
  
  // 变更历史记录
  changeHistoryLoading: false,
  changeHistoryList: [] as any[],
  
  // ... 其他状态
});

3. 核心方法实现

3.1 修改查看记录详情方法

原方法:

const handleViewRecord = (row: OverseasRecordVO) => {
  console.log('查看记录:', row);
  state.viewData = row;
  state.viewDialog.visible = true;
  state.viewDialog.title = '出国记录详情';
};

修改后:

const handleViewRecord = async (row: OverseasRecordVO) => {
  // 查看记录详情
  console.log('查看记录:', row);
  state.viewData = row;
  state.viewDialog.visible = true;
  state.viewDialog.title = '出国记录详情';
  
  // 加载该记录的变更历史
  await loadChangeHistory(row.recordId);
};

3.2 新增加载变更历史方法

// 加载变更历史记录
const loadChangeHistory = async (recordId: number) => {
  if (!recordId) {
    console.warn('recordId为空,无法加载变更历史');
    state.changeHistoryList = [];
    return;
  }
  
  state.changeHistoryLoading = true;
  try {
    console.log('🔄 开始加载变更历史记录, recordId:', recordId);
    const response = await getItineraryChangeHistory(recordId);
    if (response.code === 200) {
      state.changeHistoryList = response.data || [];
      console.log('✅ 变更历史记录加载成功, 共', state.changeHistoryList.length, '条记录');
    } else {
      console.warn('⚠️ 获取变更历史失败:', response.msg);
      state.changeHistoryList = [];
    }
  } catch (error) {
    console.error('❌ 加载变更历史记录失败:', error);
    state.changeHistoryList = [];
  } finally {
    state.changeHistoryLoading = false;
  }
};

3.3 新增变更状态Tag类型方法

// 获取变更状态的Tag类型
const getChangeStatusTagType = (status: string): 'success' | 'warning' | 'danger' | 'info' => {
  const typeMap: Record<string, 'success' | 'warning' | 'danger' | 'info'> = {
    '0': 'warning', // 待审核
    '1': 'success', // 已通过
    '2': 'danger', // 已拒绝
    '3': 'info' // 已撤回
  };
  return typeMap[status] || 'info';
};

4. UI界面实现

在记录详情弹窗中增加变更历史区域:

<!-- 变更历史记录 -->
<div v-if="state.viewData && 'recordId' in state.viewData" style="margin-top: 20px;">
  <el-divider content-position="left">
    <span style="font-size: 16px; font-weight: bold; color: #409eff;">
      <el-icon style="vertical-align: middle; margin-right: 5px;"><EditPen /></el-icon>
      变更历史记录
    </span>
  </el-divider>
  
  <!-- 变更历史列表 -->
  <div v-loading="state.changeHistoryLoading">
    <el-empty 
      v-if="!state.changeHistoryLoading && state.changeHistoryList.length === 0" 
      description="暂无变更记录"
      :image-size="80"
    />
    
    <el-table 
      v-else
      :data="state.changeHistoryList" 
      border 
      style="width: 100%"
      max-height="400px"
    >
      <el-table-column label="变更时间" align="center" prop="createTime" min-width="160" />
      <el-table-column label="变更类型" align="center" prop="changeType" min-width="150">
        <template #default="scope">
          <el-tag 
            v-for="(type, index) in (scope.row.changeType || '').split(',')" 
            :key="index"
            style="margin: 2px;"
            size="small"
          >
            {{ type }}
          </el-tag>
        </template>
      </el-table-column>
      <el-table-column label="原目的地" align="center" prop="originalDestination" min-width="120" />
      <el-table-column label="新目的地" align="center" prop="newDestination" min-width="120" />
      <el-table-column label="原出国时间" align="center" min-width="200">
        <template #default="scope">
          {{ formatDate(scope.row.originalStartDate) }} 至 {{ formatDate(scope.row.originalEndDate) }}
        </template>
      </el-table-column>
      <el-table-column label="新出国时间" align="center" min-width="200">
        <template #default="scope">
          {{ formatDate(scope.row.newStartDate) }} 至 {{ formatDate(scope.row.newEndDate) }}
        </template>
      </el-table-column>
      <el-table-column label="变更原因" align="center" prop="changeReason" min-width="200" show-overflow-tooltip />
      <el-table-column label="状态" align="center" prop="statusText" min-width="100">
        <template #default="scope">
          <el-tag :type="getChangeStatusTagType(scope.row.status)">{{ scope.row.statusText }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column label="审批意见" align="center" prop="approvalOpinion" min-width="150" show-overflow-tooltip />
    </el-table>
  </div>
</div>

📊 功能展示

详情弹窗结构

┌────────────────────────────────────────┐
│     出国记录详情                        │
├────────────────────────────────────────┤
│ 【基本信息】                            │
│  - 姓名、性别、出生年月、政治面貌       │
│  - 工作部门、职称、职务、证件信息       │
│  - 出国时间、目的地、行程安排等         │
├────────────────────────────────────────┤
│ 【变更历史记录】✨ 新增                 │
│  ┌──────────────────────────────────┐ │
│  │ 📝 变更历史记录                   │ │
│  ├──────────────────────────────────┤ │
│  │ 📋 变更记录列表表格                │ │
│  │  - 变更时间                        │ │
│  │  - 变更类型(支持多个标签)         │ │
│  │  - 原目的地 → 新目的地              │ │
│  │  - 原时间 → 新时间                  │ │
│  │  - 变更原因                        │ │
│  │  - 审批状态                        │ │
│  │  - 审批意见                        │ │
│  └──────────────────────────────────┘ │
├────────────────────────────────────────┤
│ [下载因私出国(境)情况回执] [关闭]     │
└────────────────────────────────────────┘

状态标签配色

状态 显示文字 标签颜色
0 待审核 warning (橙色)
1 已通过 success (绿色)
2 已拒绝 danger (红色)
3 已撤回 info (灰色)

🔗 后端API支持

API接口信息

  • 接口地址: GET /rs/itinerary/change/record/{recordId}/history
  • 权限标识: rs:itineraryChange:query
  • 返回数据: 该出国记录的所有变更历史记录列表

前端API定义

文件: web/src/api/rs/overseas.ts

// 查询某个记录的变更历史
export function getItineraryChangeHistory(recordId: string | number) {
  return request({
    url: `/rs/itinerary/change/record/${recordId}/history`,
    method: 'get'
  });
}

✅ 完成清单

  • 导入变更历史查询API
  • 添加变更历史状态管理
  • 修改查看记录详情方法,增加加载变更历史
  • 实现加载变更历史的方法
  • 实现变更状态Tag类型方法
  • 在详情弹窗UI中增加变更历史展示区域
  • 添加EditPen图标导入
  • 代码linter检查通过

🧪 测试指南

测试前提条件

  1. 数据库准备: 确保 rs_overseas_itinerary_change 表已创建并有测试数据
  2. 权限配置: 用户具有 rs:overseas:query 和 rs:itineraryChange:query 权限
  3. 测试数据: 至少有一条出国记录,并且该记录有对应的变更历史

测试步骤

1️⃣ 准备测试数据

-- 查询已有的出国记录
SELECT record_id, applicant_name, destination 
FROM rs_overseas_record 
WHERE deleted = 0 
LIMIT 5;

-- 查询某个记录的变更历史
SELECT * FROM rs_overseas_itinerary_change 
WHERE record_id = <你的record_id> 
AND deleted = 0;

2️⃣ 前端功能测试

步骤:

  1. 登录系统
  2. 进入菜单: 人事管理 → 出国申请
  3. 切换到 "出国记录" 选项卡
  4. 找到有变更历史的记录,点击 "查看详情" 按钮 (👁 图标)
  5. 在弹出的详情弹窗中,向下滚动到底部
  6. 查看 "变更历史记录" 区域

预期结果:

  • ✅ 弹窗正常打开,显示出国记录详情
  • ✅ 底部显示 "变更历史记录" 标题(带蓝色图标)
  • ✅ 如果有变更历史,显示变更记录表格
  • ✅ 如果没有变更历史,显示 "暂无变更记录" 提示
  • ✅ 变更类型显示为多个标签(如果有多个变更类型)
  • ✅ 状态标签颜色正确显示(待审核=橙色,已通过=绿色等)
  • ✅ 所有字段数据正确显示

3️⃣ 边界情况测试

测试场景:

  • 没有变更历史的记录 → 应显示 "暂无变更记录"
  • 有多条变更历史的记录 → 应显示所有变更记录
  • 变更历史有多个变更类型 → 应显示多个标签
  • recordId为空的记录 → 应正常处理,不报错

4️⃣ 控制台日志检查

打开浏览器控制台,查看日志输出:

✅ 正常日志示例:
🔄 开始加载变更历史记录, recordId: 123456789
✅ 变更历史记录加载成功, 共 2 条记录

📝 功能特点

1. 用户体验优化

  • ✨ 自动加载: 打开详情弹窗时自动加载变更历史,无需手动刷新
  • 🔄 加载动画: 显示loading状态,提升用户体验
  • 📊 表格展示: 使用表格形式,清晰展示所有变更信息
  • 🏷️ 多标签支持: 变更类型支持多个标签显示
  • 🎨 状态配色: 不同状态使用不同颜色的标签,一目了然

2. 数据完整性

  • 📅 时间对比: 清晰对比原时间和新时间
  • 🗺️ 目的地对比: 清晰对比原目的地和新目的地
  • 📋 变更原因: 显示详细的变更原因说明
  • 💬 审批意见: 显示审批人的审批意见

3. 技术实现

  • 🔗 API关联: 通过recordId关联查询变更历史
  • 🛡️ 错误处理: 完善的错误处理和日志记录
  • 🎯 类型安全: TypeScript类型定义完整
  • ⚡ 性能优化: 异步加载,不阻塞主流程

🔍 常见问题

Q1: 为什么看不到变更历史记录?

可能原因:

  1. 该出国记录确实没有提交过行程变更申请
  2. 变更申请还未通过审批
  3. recordId为空或不正确

排查步骤:

-- 检查记录是否存在变更历史
SELECT * FROM rs_overseas_itinerary_change 
WHERE record_id = <你的record_id> 
AND deleted = 0;

Q2: 变更类型标签不显示

可能原因: changeType 字段为空或格式不正确

解决方案: 确保变更类型字段有值,多个类型用逗号分隔

Q3: 加载失败

检查项:

  1. 浏览器控制台是否有错误信息
  2. 网络请求是否成功(开发者工具 → Network)
  3. 用户是否有 rs:itineraryChange:query 权限

🎯 后续优化建议

功能扩展

  1. 🔍 详情查看: 点击变更记录可查看完整的变更详情
  2. 📊 统计信息: 显示变更次数统计
  3. 🔔 变更提醒: 有新变更时给予提醒
  4. 📥 导出功能: 支持导出变更历史记录

性能优化

  1. ⚡ 懒加载: 只在展开变更历史时才加载数据
  2. 💾 缓存机制: 缓存已加载的变更历史
  3. 📄 分页支持: 变更记录很多时支持分页

📅 开发记录

时间 版本 说明
2025-10-13 v1.0 ✅ 初版实现完成
- 前端UI展示
- API集成
- 状态管理
- 功能测试

📚 相关文档


👥 相关人员

  • 需求提出: 用户
  • 功能开发: AI Assistant
  • 技术审核: 待定
  • 测试验证: 待定

🎉 功能已完成,等待测试验证!