完善小程序
This commit is contained in:
263
docs/导出功能修复总结.md
Normal file
263
docs/导出功能修复总结.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# 保险端导出功能修复总结
|
||||
|
||||
## 修复时间
|
||||
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`
|
||||
|
||||
**正确的路由顺序示例:**
|
||||
```javascript
|
||||
// 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 类型的支持:
|
||||
|
||||
```javascript
|
||||
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 处理
|
||||
|
||||
修改以下页面中的导出方法,将:
|
||||
```javascript
|
||||
const url = window.URL.createObjectURL(new Blob([response.data]))
|
||||
```
|
||||
|
||||
改为:
|
||||
```javascript
|
||||
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. **启动后端服务**
|
||||
```bash
|
||||
cd insurance_backend
|
||||
node src/app.js
|
||||
```
|
||||
确保服务运行在 `http://localhost:3000`
|
||||
|
||||
2. **启动前端服务**
|
||||
```bash
|
||||
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`
|
||||
|
||||
86
docs/待安装任务导出字段说明.md
Normal file
86
docs/待安装任务导出字段说明.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# 待安装任务导出字段映射说明
|
||||
|
||||
## 数据库字段对照表
|
||||
|
||||
| Excel列名 | 数据库字段 | 字段说明 | 是否必填 |
|
||||
|---------|----------|---------|---------|
|
||||
| 申请单号 | application_number | 申请单号 | 是 |
|
||||
| 保单编号 | policy_number | 保单编号 | 是 |
|
||||
| 产品名称 | product_name | 产品名称 | 是 |
|
||||
| 客户姓名 | customer_name | 客户姓名 | 是 |
|
||||
| 证件类型 | id_type | 证件类型 | 是 |
|
||||
| 证件号码 | id_number | 证件号码 | 是 |
|
||||
| 养殖生资种类 | livestock_supply_type | 养殖生资种类 | 否 |
|
||||
| 安装状态 | installation_status | 安装状态 | 是 |
|
||||
| 优先级 | priority | 任务优先级 | 是 |
|
||||
| 安装地址 | installation_address | 安装地址 | 否 |
|
||||
| 联系电话 | contact_phone | 联系电话 | 否 |
|
||||
| 任务生成时间 | task_generated_time | 任务生成时间 | 否 |
|
||||
| 安装完成时间 | installation_completed_time | 安装完成时间 | 否 |
|
||||
| 创建时间 | created_at | 创建时间 | 是 |
|
||||
| 更新时间 | updated_at | 更新时间 | 是 |
|
||||
|
||||
## 字段值说明
|
||||
|
||||
### 证件类型 (id_type)
|
||||
- 身份证
|
||||
- 护照
|
||||
- 军官证
|
||||
- 士兵证
|
||||
- 港澳台居民居住证
|
||||
- 其他
|
||||
|
||||
### 安装状态 (installation_status)
|
||||
- 待安装
|
||||
- 安装中
|
||||
- 已安装
|
||||
- 安装失败
|
||||
- 已取消
|
||||
|
||||
### 优先级 (priority)
|
||||
- 低
|
||||
- 中
|
||||
- 高
|
||||
- 紧急
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **数据库字段格式**:使用下划线命名(snake_case)
|
||||
2. **模型字段格式**:使用驼峰命名(camelCase)
|
||||
3. **raw查询返回**:返回的是数据库字段名(下划线格式)
|
||||
4. **空值处理**:
|
||||
- 字符串字段:显示为空字符串 `''`
|
||||
- 日期字段:通过 `ExcelExport.formatDate()` 处理,空值显示为空字符串
|
||||
5. **状态值**:直接使用数据库中的中文值,不需要额外映射
|
||||
|
||||
## 导出示例数据
|
||||
|
||||
```json
|
||||
{
|
||||
"applicationNumber": "APP001",
|
||||
"policyNumber": "POL001",
|
||||
"productName": "智能耳标监控系统",
|
||||
"customerName": "张三",
|
||||
"idType": "身份证",
|
||||
"idNumber": "110101199001011234",
|
||||
"livestockSupplyType": "牛养殖",
|
||||
"installationStatus": "待安装",
|
||||
"priority": "高",
|
||||
"installationAddress": null,
|
||||
"contactPhone": null,
|
||||
"taskGeneratedTime": "2025-09-22 18:28:58",
|
||||
"installationCompletedTime": null,
|
||||
"createdAt": "2025-09-22 18:28:58",
|
||||
"updatedAt": "2025-09-22 18:28:58"
|
||||
}
|
||||
```
|
||||
|
||||
## 修复历史
|
||||
|
||||
### 2025-10-09 修复内容
|
||||
1. ✅ 修复字段映射错误(驼峰 → 下划线)
|
||||
2. ✅ 添加缺失字段:证件类型、优先级、安装地址、联系电话、更新时间
|
||||
3. ✅ 移除不存在的字段映射
|
||||
4. ✅ 删除多余的状态映射逻辑
|
||||
5. ✅ 统一空值处理方式
|
||||
|
||||
313
docs/监管任务模块问题诊断报告.md
Normal file
313
docs/监管任务模块问题诊断报告.md
Normal file
@@ -0,0 +1,313 @@
|
||||
# 监管任务模块问题诊断报告
|
||||
|
||||
## 诊断时间
|
||||
2025年10月9日
|
||||
|
||||
## 问题描述
|
||||
用户反映:监管任务结项管理模块,表中有数据,但是前端页面没有数据,后端API接口返回也没数据。
|
||||
|
||||
## 诊断结果
|
||||
|
||||
### ✅ 后端状态 - 完全正常
|
||||
|
||||
#### 1. 数据库层面
|
||||
- **表名**:`supervisory_tasks`
|
||||
- **数据**:存在1条测试数据
|
||||
- **结构**:正确
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM supervisory_tasks;
|
||||
-- 结果: 1条记录
|
||||
|
||||
SELECT * FROM supervisory_tasks LIMIT 1;
|
||||
-- 数据正常,包含完整字段
|
||||
```
|
||||
|
||||
#### 2. Model层面
|
||||
- **模型文件**:`models/SupervisoryTask.js`
|
||||
- **表映射**:正确 (`tableName: 'supervisory_tasks'`)
|
||||
- **查询测试**:✅ 通过
|
||||
```javascript
|
||||
// 直接通过Model查询成功
|
||||
const tasks = await SupervisoryTask.findAll();
|
||||
// 结果: 返回1条记录
|
||||
```
|
||||
|
||||
#### 3. API层面
|
||||
- **控制器**:`controllers/supervisoryTaskController.js`
|
||||
- **路由**:`routes/supervisoryTasks.js`
|
||||
- **注册**:✅ 正确注册在 `src/app.js`
|
||||
- `/api/supervisory-tasks` (备用路径)
|
||||
- `/api/supervision-tasks` (主要路径 - 前端使用)
|
||||
- **API测试**:✅ 完全正常
|
||||
|
||||
**API测试结果:**
|
||||
```bash
|
||||
GET /api/supervision-tasks?page=1&limit=10
|
||||
Authorization: Bearer <token>
|
||||
|
||||
响应:
|
||||
{
|
||||
"code": 200,
|
||||
"status": "success",
|
||||
"message": "获取监管任务列表成功",
|
||||
"data": {
|
||||
"list": [
|
||||
{
|
||||
"id": 1,
|
||||
"applicationNumber": "APP2025001",
|
||||
"policyNumber": "POL2025001",
|
||||
"productName": "农业保险产品",
|
||||
"customerName": "张三",
|
||||
"taskStatus": "待处理",
|
||||
"priority": "中",
|
||||
...
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"limit": 10
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4. 后端服务状态
|
||||
- **端口**:3000
|
||||
- **状态**:✅ 正在运行
|
||||
- **PID**:19340
|
||||
|
||||
### ✅ 前端状态
|
||||
|
||||
#### 1. 服务状态
|
||||
- **端口**:3001
|
||||
- **状态**:✅ 正在运行
|
||||
- **PID**:18648
|
||||
|
||||
#### 2. 代理配置
|
||||
```javascript
|
||||
// vite.config.js
|
||||
proxy: {
|
||||
'/insurance/api': {
|
||||
target: 'http://localhost:3000',
|
||||
changeOrigin: true,
|
||||
rewrite: (path) => path.replace(/^\/insurance/, '')
|
||||
}
|
||||
}
|
||||
```
|
||||
配置:✅ 正确
|
||||
|
||||
#### 3. API配置
|
||||
```javascript
|
||||
// src/utils/api.js
|
||||
export const supervisionTaskApi = {
|
||||
getList: (params) => api.get('/supervision-tasks', { params }),
|
||||
getStats: () => api.get('/supervision-tasks/stats'),
|
||||
export: (params) => api.get('/supervision-tasks/export', { params, responseType: 'blob' }),
|
||||
...
|
||||
}
|
||||
```
|
||||
配置:✅ 正确
|
||||
|
||||
#### 4. 环境配置
|
||||
```javascript
|
||||
// src/config/env.js
|
||||
const envConfig = {
|
||||
baseURL: '/insurance/api',
|
||||
timeout: 10000
|
||||
}
|
||||
```
|
||||
配置:✅ 正确
|
||||
|
||||
## 可能的问题原因
|
||||
|
||||
### 1. 认证Token问题 ⚠️
|
||||
前端可能没有正确发送认证token或token已过期。
|
||||
|
||||
**验证方法**:
|
||||
```javascript
|
||||
// 在浏览器控制台检查
|
||||
localStorage.getItem('accessToken')
|
||||
localStorage.getItem('refreshToken')
|
||||
```
|
||||
|
||||
### 2. 请求拦截器问题 ⚠️
|
||||
前端的请求拦截器可能没有正确添加Authorization头。
|
||||
|
||||
**检查文件**:`insurance_admin-system/src/utils/request.js`
|
||||
|
||||
### 3. 数据响应格式解析问题 ⚠️
|
||||
前端页面可能没有正确解析后端返回的数据格式。
|
||||
|
||||
**后端返回格式**:
|
||||
```javascript
|
||||
{
|
||||
data: {
|
||||
status: 'success',
|
||||
data: {
|
||||
list: [...],
|
||||
total: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**前端期望格式**:需要检查 `CompletedTaskManagement.vue` 和 `SupervisionTaskManagement.vue`
|
||||
|
||||
### 4. 路由路径不匹配 ⚠️
|
||||
如果前端使用了错误的API路径。
|
||||
|
||||
### 5. 跨域问题 ⚠️
|
||||
虽然后端配置了CORS,但可能存在配置问题。
|
||||
|
||||
## 建议的解决步骤
|
||||
|
||||
### 步骤1:检查用户登录状态
|
||||
```javascript
|
||||
// 在浏览器控制台执行
|
||||
console.log('Token:', localStorage.getItem('accessToken'));
|
||||
console.log('是否登录:', !!localStorage.getItem('accessToken'));
|
||||
```
|
||||
|
||||
### 步骤2:检查网络请求
|
||||
1. 打开浏览器开发者工具 (F12)
|
||||
2. 切换到 Network 标签
|
||||
3. 刷新页面
|
||||
4. 查找 `/supervision-tasks` 请求
|
||||
5. 检查:
|
||||
- 请求URL是否正确
|
||||
- 请求头是否包含 `Authorization: Bearer <token>`
|
||||
- 响应状态码
|
||||
- 响应内容
|
||||
|
||||
### 步骤3:检查控制台错误
|
||||
1. 打开浏览器开发者工具Console标签
|
||||
2. 查看是否有JavaScript错误
|
||||
3. 查看是否有API请求失败的错误信息
|
||||
|
||||
### 步骤4:强制刷新Token
|
||||
```javascript
|
||||
// 在前端代码中
|
||||
1. 清除现有token
|
||||
localStorage.clear()
|
||||
|
||||
2. 重新登录
|
||||
使用账号: admin
|
||||
密码: 123456
|
||||
```
|
||||
|
||||
### 步骤5:检查数据处理逻辑
|
||||
检查前端页面中的数据响应处理:
|
||||
|
||||
**CompletedTaskManagement.vue**:
|
||||
```javascript
|
||||
// 第466-476行
|
||||
const response = await supervisionTaskApi.getList(params)
|
||||
console.log('监管任务结项API响应:', response)
|
||||
|
||||
if (response.data && response.data.status === 'success') {
|
||||
taskList.value = response.data.data.list || []
|
||||
pagination.total = response.data.data.total || 0
|
||||
}
|
||||
```
|
||||
|
||||
**SupervisionTaskManagement.vue**:
|
||||
```javascript
|
||||
// 第513-522行
|
||||
const response = await supervisionTaskApi.getList(params)
|
||||
console.log('监管任务API响应:', response)
|
||||
|
||||
if (response.data && response.data.status === 'success') {
|
||||
tableData.value = response.data.data.list
|
||||
pagination.total = response.data.data.total
|
||||
}
|
||||
```
|
||||
|
||||
## 测试命令
|
||||
|
||||
### 测试数据库
|
||||
```bash
|
||||
cd insurance_backend
|
||||
node test-supervisory-table.js
|
||||
```
|
||||
|
||||
### 测试API(需要后端服务运行)
|
||||
```bash
|
||||
cd insurance_backend
|
||||
node test-full-api-flow.js
|
||||
```
|
||||
|
||||
### 启动后端服务
|
||||
```bash
|
||||
cd insurance_backend
|
||||
npm start
|
||||
```
|
||||
|
||||
### 启动前端服务
|
||||
```bash
|
||||
cd insurance_admin-system
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## 前端调试代码
|
||||
|
||||
在浏览器控制台执行以下代码测试API:
|
||||
|
||||
```javascript
|
||||
// 1. 获取token
|
||||
const token = localStorage.getItem('accessToken');
|
||||
console.log('Token:', token);
|
||||
|
||||
// 2. 手动测试API
|
||||
fetch('/insurance/api/supervision-tasks?page=1&limit=10', {
|
||||
headers: {
|
||||
'Authorization': `Bearer ${token}`,
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(data => {
|
||||
console.log('API响应:', data);
|
||||
if (data.status === 'success') {
|
||||
console.log('✓ 数据获取成功');
|
||||
console.log('记录数:', data.data.total);
|
||||
console.log('数据列表:', data.data.list);
|
||||
} else {
|
||||
console.log('✗ 响应状态异常');
|
||||
}
|
||||
})
|
||||
.catch(err => console.error('✗ 请求失败:', err));
|
||||
```
|
||||
|
||||
## 结论
|
||||
|
||||
**后端完全正常**,问题很可能出在前端的以下几个方面:
|
||||
|
||||
1. **认证token未正确发送**(最可能)
|
||||
2. **数据响应格式解析错误**
|
||||
3. **页面组件渲染逻辑问题**
|
||||
4. **浏览器缓存问题**
|
||||
|
||||
建议用户按照上述步骤逐一排查,特别是先检查浏览器Network标签中的实际请求情况。
|
||||
|
||||
## 文件清单
|
||||
|
||||
### 后端文件
|
||||
- ✅ `models/SupervisoryTask.js` - 模型定义正确
|
||||
- ✅ `controllers/supervisoryTaskController.js` - 控制器逻辑正确
|
||||
- ✅ `routes/supervisoryTasks.js` - 路由配置正确
|
||||
- ✅ `src/app.js` - 路由注册正确
|
||||
|
||||
### 前端文件
|
||||
- ✅ `src/config/env.js` - 环境配置(新增)
|
||||
- ✅ `src/utils/api.js` - API封装正确
|
||||
- ✅ `src/utils/request.js` - 请求工具配置正确
|
||||
- ✅ `src/views/CompletedTaskManagement.vue` - 已更新使用API
|
||||
- ✅ `src/views/SupervisionTaskManagement.vue` - 已使用API
|
||||
- ✅ `vite.config.js` - 代理配置正确
|
||||
|
||||
### 测试文件(可删除)
|
||||
- `insurance_backend/test-supervisory-table.js`
|
||||
- `insurance_backend/test-api-response.js`
|
||||
- `insurance_backend/test-api-direct.js`
|
||||
- `insurance_backend/test-full-api-flow.js`
|
||||
|
||||
267
docs/监管任务结项管理API封装修复说明.md
Normal file
267
docs/监管任务结项管理API封装修复说明.md
Normal file
@@ -0,0 +1,267 @@
|
||||
# 监管任务结项管理API封装修复说明
|
||||
|
||||
## 修复日期
|
||||
2025年10月9日
|
||||
|
||||
## 问题描述
|
||||
监管任务结项管理模块(`CompletedTaskManagement.vue`)中使用了模拟数据,没有调用真实的后端API接口。需要将其改为使用封装的API工具类。
|
||||
|
||||
## 修复内容
|
||||
|
||||
### 1. 创建环境配置文件 `src/config/env.js`
|
||||
|
||||
创建了统一的环境配置文件,用于管理所有API URL和环境变量:
|
||||
|
||||
**主要功能:**
|
||||
- 支持多环境配置(development、production、test)
|
||||
- 统一管理API基础URL、超时时间等配置
|
||||
- 定义了所有API端点的路径常量
|
||||
|
||||
**配置项:**
|
||||
```javascript
|
||||
{
|
||||
baseURL: '/insurance/api',
|
||||
timeout: 10000,
|
||||
wsURL: 'ws://localhost:3000'
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 更新 API 工具类 `src/utils/api.js`
|
||||
|
||||
在 `supervisionTaskApi` 中添加了两个新的API方法:
|
||||
|
||||
```javascript
|
||||
export const supervisionTaskApi = {
|
||||
// ... 现有方法
|
||||
archive: (id) => api.patch(`/supervision-tasks/${id}/archive`),
|
||||
downloadReport: (id) => api.get(`/supervision-tasks/${id}/report`, { responseType: 'blob' })
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 更新请求工具 `src/utils/request.js`
|
||||
|
||||
- 导入环境配置文件
|
||||
- 使用 `envConfig.baseURL` 和 `envConfig.timeout` 替代硬编码的配置
|
||||
|
||||
**修改前:**
|
||||
```javascript
|
||||
const API_CONFIG = {
|
||||
baseURL: '/insurance/api',
|
||||
timeout: 10000
|
||||
}
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```javascript
|
||||
import envConfig from '@/config/env'
|
||||
|
||||
const API_CONFIG = {
|
||||
baseURL: envConfig.baseURL,
|
||||
timeout: envConfig.timeout
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 更新用户状态管理 `src/stores/user.js`
|
||||
|
||||
- 导入环境配置文件
|
||||
- 在刷新token的fetch请求中使用 `envConfig.baseURL`
|
||||
|
||||
**修改前:**
|
||||
```javascript
|
||||
const response = await fetch('/insurance/api/auth/refresh', {
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
**修改后:**
|
||||
```javascript
|
||||
import envConfig from '@/config/env'
|
||||
|
||||
const response = await fetch(`${envConfig.baseURL}/auth/refresh`, {
|
||||
// ...
|
||||
})
|
||||
```
|
||||
|
||||
### 5. 完善监管任务结项管理 `src/views/CompletedTaskManagement.vue`
|
||||
|
||||
#### 5.1 获取任务列表 `fetchTaskList`
|
||||
|
||||
**修改前:** 使用模拟数据
|
||||
|
||||
**修改后:** 调用真实API
|
||||
```javascript
|
||||
const fetchTaskList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const params = {
|
||||
page: pagination.current,
|
||||
limit: pagination.pageSize,
|
||||
taskStatus: 'completed' // 只获取已完成的任务
|
||||
}
|
||||
|
||||
// 添加搜索条件
|
||||
if (searchForm.taskName) {
|
||||
params.taskName = searchForm.taskName
|
||||
}
|
||||
if (searchForm.status) {
|
||||
params.status = searchForm.status
|
||||
}
|
||||
if (searchForm.dateRange && searchForm.dateRange.length === 2) {
|
||||
params.startDate = searchForm.dateRange[0].format('YYYY-MM-DD')
|
||||
params.endDate = searchForm.dateRange[1].format('YYYY-MM-DD')
|
||||
}
|
||||
|
||||
const response = await supervisionTaskApi.getList(params)
|
||||
// 处理响应...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.2 获取统计数据 `fetchStats`
|
||||
|
||||
新增函数,调用统计API获取实时数据:
|
||||
```javascript
|
||||
const fetchStats = async () => {
|
||||
try {
|
||||
const response = await supervisionTaskApi.getStats()
|
||||
if (response.data && response.data.status === 'success') {
|
||||
const statsData = response.data.data
|
||||
stats.total = statsData.total || 0
|
||||
stats.thisMonth = statsData.thisMonth || 0
|
||||
stats.archived = statsData.archived || 0
|
||||
stats.avgDuration = statsData.avgDuration || 0
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取统计数据失败:', error)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.3 下载报告 `handleDownload`
|
||||
|
||||
**修改前:** 仅显示提示信息
|
||||
|
||||
**修改后:** 调用API下载报告文件
|
||||
```javascript
|
||||
const handleDownload = async (record) => {
|
||||
try {
|
||||
message.loading(`正在下载 ${record.taskName} 的报告...`, 0)
|
||||
|
||||
const response = await supervisionTaskApi.downloadReport(record.id)
|
||||
|
||||
// 创建下载链接
|
||||
const url = window.URL.createObjectURL(response.data)
|
||||
const link = document.createElement('a')
|
||||
link.href = url
|
||||
link.setAttribute('download', `${record.taskName}_报告_${new Date().getTime()}.pdf`)
|
||||
document.body.appendChild(link)
|
||||
link.click()
|
||||
document.body.removeChild(link)
|
||||
window.URL.revokeObjectURL(url)
|
||||
|
||||
message.destroy()
|
||||
message.success('报告下载成功')
|
||||
} catch (error) {
|
||||
message.destroy()
|
||||
console.error('下载报告失败:', error)
|
||||
message.error('下载报告失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 5.4 归档任务 `handleArchive`
|
||||
|
||||
**修改前:** 仅显示成功提示
|
||||
|
||||
**修改后:** 调用API执行归档操作
|
||||
```javascript
|
||||
const handleArchive = async (record) => {
|
||||
try {
|
||||
const response = await supervisionTaskApi.archive(record.id)
|
||||
if (response.data && response.data.status === 'success') {
|
||||
message.success(`任务 ${record.taskName} 已归档`)
|
||||
fetchTaskList()
|
||||
} else {
|
||||
message.error(response.data?.message || '归档失败')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('归档任务失败:', error)
|
||||
message.error('归档任务失败,请稍后重试')
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 修复后的优势
|
||||
|
||||
1. **统一配置管理**:所有API URL通过env.js统一管理,便于维护和切换环境
|
||||
2. **代码规范**:所有API调用都使用封装的工具类,符合项目规范
|
||||
3. **功能完整**:实现了真实的数据获取、统计、导出、归档、下载报告等功能
|
||||
4. **错误处理**:完善的错误提示和异常处理
|
||||
5. **用户体验**:添加了加载提示和操作反馈
|
||||
|
||||
## 后端需要实现的接口
|
||||
|
||||
为了使前端功能完整可用,后端需要实现以下接口:
|
||||
|
||||
### 1. 获取监管任务列表(支持已完成任务筛选)
|
||||
- **路径**:`GET /supervision-tasks`
|
||||
- **参数**:
|
||||
- `page`: 页码
|
||||
- `limit`: 每页数量
|
||||
- `taskStatus`: 任务状态(completed)
|
||||
- `taskName`: 任务名称(可选)
|
||||
- `status`: 状态(completed/archived)(可选)
|
||||
- `startDate`: 开始日期(可选)
|
||||
- `endDate`: 结束日期(可选)
|
||||
|
||||
### 2. 获取统计数据
|
||||
- **路径**:`GET /supervision-tasks/stats`
|
||||
- **返回数据**:
|
||||
```javascript
|
||||
{
|
||||
total: 总结项任务数,
|
||||
thisMonth: 本月结项数,
|
||||
archived: 已归档任务数,
|
||||
avgDuration: 平均处理时长(天)
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 归档任务
|
||||
- **路径**:`PATCH /supervision-tasks/:id/archive`
|
||||
- **说明**:将已完成的任务标记为已归档
|
||||
|
||||
### 4. 下载任务报告
|
||||
- **路径**:`GET /supervision-tasks/:id/report`
|
||||
- **返回**:PDF文件流
|
||||
- **说明**:生成并下载任务报告
|
||||
|
||||
### 5. 导出任务列表
|
||||
- **路径**:`GET /supervision-tasks/export`
|
||||
- **参数**:与获取列表接口相同的筛选参数
|
||||
- **返回**:Excel文件流
|
||||
|
||||
## 测试建议
|
||||
|
||||
1. 测试获取已完成任务列表功能
|
||||
2. 测试搜索和筛选功能
|
||||
3. 测试统计数据显示
|
||||
4. 测试任务归档功能
|
||||
5. 测试报告下载功能
|
||||
6. 测试导出Excel功能
|
||||
7. 测试不同环境下的API调用(开发、测试、生产)
|
||||
|
||||
## 相关文件
|
||||
|
||||
- `insurance_admin-system/src/config/env.js` - 环境配置文件(新增)
|
||||
- `insurance_admin-system/src/utils/api.js` - API工具类(修改)
|
||||
- `insurance_admin-system/src/utils/request.js` - 请求工具(修改)
|
||||
- `insurance_admin-system/src/stores/user.js` - 用户状态管理(修改)
|
||||
- `insurance_admin-system/src/views/CompletedTaskManagement.vue` - 结项管理页面(修改)
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 所有fetch调用都已改为使用封装的API工具类
|
||||
2. 环境配置文件支持多环境切换,部署时需要根据实际情况配置
|
||||
3. 请确保后端API接口已实现并测试通过
|
||||
4. 导出和下载功能需要后端返回正确的文件流和Content-Disposition头
|
||||
|
||||
Reference in New Issue
Block a user