Files
nxxmdata/docs/导出功能修复总结.md
2025-10-09 17:59:26 +08:00

7.8 KiB
Raw Blame History

保险端导出功能修复总结

修复时间

2025年10月9日

问题描述

前端导出Excel功能虽然能收到后端返回的Excel文件数据Blob格式但文件无法正常下载或内容异常。

问题根源

1. 后端问题

  • 路由顺序错误:部分模块的 /export 路由放在动态路由 /:id 之后导致404错误
  • 缺少导出方法:部分控制器缺少 exportToExcel 方法

2. 前端问题

  • request.js 响应处理handleResponse 函数不支持 blob 类型响应
  • Blob 包装错误:前端代码使用 new Blob([response.data]) 重复包装已经是 Blob 的数据

修复方案

后端修复insurance_backend

1. 添加导出方法到控制器

为以下控制器添加了 exportToExcel 方法:

  • userController.js - 用户管理导出
  • supervisoryTaskController.js - 监管任务导出
  • installationTaskController.js - 待安装任务导出
  • deviceAlertController.js - 设备预警导出
  • insuranceTypeController.js - 保险类型导出
  • policyController.js - 保单管理导出
  • livestockClaimController.js - 理赔管理导出
  • livestockPolicyController.js - 生资保单管理导出
  • operationLogController.js - 操作日志导出

2. 修复路由顺序

在以下路由文件中,将 /export/stats 路由移到 /:id 之前:

  • routes/users.js
  • routes/supervisoryTasks.js
  • routes/installationTasks.js
  • routes/deviceAlerts.js
  • routes/insuranceTypes.js
  • routes/policies.js
  • routes/livestockClaims.js
  • routes/livestockPolicies.js
  • routes/operationLogs.js

正确的路由顺序示例:

// 1. 统计接口
router.get('/stats', jwtAuth, requirePermission('xxx:read'), controller.getStats);

// 2. 导出接口
router.get('/export', jwtAuth, requirePermission('xxx:read'), controller.exportToExcel);

// 3. 列表接口
router.get('/', jwtAuth, requirePermission('xxx:read'), controller.getList);

// 4. 详情接口(动态路由放最后)
router.get('/:id', jwtAuth, requirePermission('xxx:read'), controller.getById);

3. 导出工具类

创建了通用的导出工具 utils/excelExport.js,提供:

  • exportToExcel(data, columns, sheetName) - 生成Excel文件
  • formatDate(date) - 格式化日期
  • formatStatus(status, statusMap) - 格式化状态

前端修复insurance_admin-system

1. 修复 request.js

修改 src/utils/request.js 中的 handleResponse 函数,添加对 blob 类型的支持:

const handleResponse = async (response) => {
  let data
  
  try {
    const contentType = response.headers.get('content-type')
    
    // 处理Excel文件下载
    if (contentType && contentType.includes('application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')) {
      data = await response.blob()
    } else if (contentType && contentType.includes('application/json')) {
      data = await response.json()
    } else {
      data = await response.text()
    }
  } catch (error) {
    data = null
  }
  
  if (!response.ok) {
    const error = new Error(data?.message || `HTTP ${response.status}: ${response.statusText}`)
    error.response = {
      status: response.status,
      statusText: response.statusText,
      data: data
    }
    throw error
  }
  
  return { data, status: response.status, statusText: response.statusText }
}

2. 修复前端页面的 Blob 处理

修改以下页面中的导出方法,将:

const url = window.URL.createObjectURL(new Blob([response.data]))

改为:

const url = window.URL.createObjectURL(response.data)

已修复的页面:

  • UserManagement.vue - 用户管理
  • MessageNotification.vue - 消息通知(设备预警)
  • InsuranceTypeManagement.vue - 保险类型管理
  • PolicyManagement.vue - 保单管理
  • ClaimManagement.vue - 理赔管理
  • SupervisionTaskManagement.vue - 监管任务管理
  • CompletedTaskManagement.vue - 监管任务结项
  • InstallationTaskManagement.vue - 待安装任务
  • LivestockPolicyManagement.vue - 生资保单管理
  • SystemSettings.vue - 系统设置(操作日志)
  • ApplicationManagement.vue - 申请管理

导出功能支持的筛选参数

用户管理

  • search - 用户名搜索
  • status - 状态筛选

监管任务

  • policyNumber - 保单编号
  • customerName - 客户姓名

待安装任务

  • policyNumber - 保单编号
  • keyword - 关键字搜索

设备预警

  • alert_level - 预警级别
  • alert_type - 预警类型
  • status - 处理状态
  • is_read - 是否已读

保险类型

  • name - 险种名称
  • status - 状态

保单管理

  • policy_number - 保单编号
  • policyholder_name - 投保人姓名
  • status - 状态

理赔管理

  • claim_number - 理赔编号
  • claimant_name - 理赔人姓名
  • status - 状态

生资保单

  • policy_no - 保单号
  • farmer_name - 农户姓名
  • policy_status - 保单状态

操作日志

  • username - 用户名
  • operation_type - 操作类型
  • operation_module - 操作模块
  • startDate - 开始日期
  • endDate - 结束日期

技术要点

1. Excel 文件生成

  • 使用 exceljs 库生成 Excel 文件
  • 支持自定义列宽、表头、数据格式化
  • 自动设置表头样式(加粗、边框)

2. 数据格式化

  • 日期格式:YYYY-MM-DD HH:mm:ss
  • 状态映射:使用中文映射英文状态值
  • 空值处理显示为空字符串或0

3. 文件下载

  • Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
  • Content-Disposition: attachment; filename=xxx_${timestamp}.xlsx
  • 前端使用 window.URL.createObjectURL 创建下载链接

4. 权限控制

  • 所有导出接口都需要 JWT 认证
  • 需要相应模块的读取权限

测试步骤

  1. 启动后端服务

    cd insurance_backend
    node src/app.js
    

    确保服务运行在 http://localhost:3000

  2. 启动前端服务

    cd insurance_admin-system
    npm run dev
    
  3. 测试导出功能

    • 登录系统admin / 123456
    • 进入各个功能模块
    • 点击"导出Excel"按钮
    • 验证文件能正常下载且内容正确

常见问题排查

1. 404 错误

  • 原因:导出路由在动态路由之后
  • 解决:将 /export 路由移到 /:id 之前

2. Excel 文件损坏或无法打开

  • 原因:前端重复包装 Blob 数据
  • 解决:直接使用 response.data,不要用 new Blob([response.data])

3. 导出的 Excel 为空

  • 原因:数据库查询条件有误或数据为空
  • 解决检查控制器中的查询逻辑和where条件

4. 权限错误

  • 原因:用户没有导出权限
  • 解决:在数据库中为用户角色添加相应的导出权限

注意事项

  1. 不要修改端口号后端固定3000端口前端固定3001端口
  2. 测试文件清理:所有测试文件会自动删除
  3. 权限验证:确保每个导出接口都有权限中间件
  4. 数据量控制:大量数据导出时注意性能和内存占用
  5. 文件命名:使用时间戳避免文件名冲突

后续优化建议

  1. 分页导出:对于大量数据,支持分批导出
  2. 异步导出:数据量大时改为异步任务,生成后通知用户下载
  3. 导出模板:提供 Excel 模板下载功能
  4. 导出历史:记录导出操作日志
  5. 格式选择:支持导出为 CSV、PDF 等其他格式
  6. 数据汇总:在 Excel 中添加汇总统计信息

相关文档

  • 后端接口文档:insurance_backend/docs/EXPORT_IMPLEMENTATION_GUIDE.md
  • API 文档Swagger UI http://localhost:3000/api-docs
  • 前端环境配置:insurance_admin-system/ENV_CONFIG.md