# Tasks: 集成典型案例查询API数据展示 ## 任务清单 ### Phase 1: 准备工作 (0.5小时) #### Task 1.1: 分析现有代码结构 - [x] 查看CaseSearchContent.jsx组件的当前实现 - [x] 确认CaseAPIService所有方法的参数要求和返回数据结构 - [x] 分析现有mock数据结构与API返回数据的映射关系 - [x] 确认TypicalCaseDetailContent组件的props结构 #### Task 1.2: 确认API数据字段 - [x] 验证CaseAPIService.getDisputeTypes返回的dispute_type字段 - [x] 验证getYearStatistics和getMediationYearStatistics返回的year和count字段 - [x] 验证getAreaStatistics返回的area_name、count、level、children字段 - [x] 验证getCourtCases和getMediationCases返回的data数组字段 - [x] 验证getCourtCaseDetail和getMediationCaseDetail返回的详情字段 ### Phase 2: 查询条件布局重构 (1-1.5小时) #### Task 2.1: 修改CaseSearchContent组件 - 状态管理 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 导入必要的依赖:`useEffect`, `Radio`, `message` - [x] 导入CaseAPIService - [x] 添加组件内部状态: - `caseType` - 案例类型,默认'judgment' - `disputeTypeOptions` - 纠纷类型下拉选项 - `list` - 案例列表数据 - `total` - 总记录数 - `pageSize` - 每页记录数,默认10 - `selectedCaseType` - 当前选中案例的类型(用于详情弹窗) - [x] 移除不需要的状态:`caseTypeFilters` #### Task 2.2: 重构查询条件表单布局 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 移除纠纷发生时间RangePicker组件 - [x] 关键词输入框添加class `case-search-keyword-full` 使其占满第一行 - [x] 新增案例类型Radio.Group组件 - 选项:判决文书(value='judgment')、调解案例(value='mediation') - 默认选中:judgment - onChange事件切换caseType并重置disputeType - [x] 纠纷类型Select组件改为动态渲染disputeTypeOptions - [x] 调整按钮组位置到第二行 #### Task 2.3: 移除案例类型筛选卡片 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 删除案例类型filter-category整个section - [x] 保留发生时间和纠纷发生地筛选卡片 ### Phase 3: API集成 - 筛选数据加载 (1.5-2小时) #### Task 3.1: 实现纠纷类型下拉数据加载 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 创建loadDisputeTypes函数,接收caseSource参数 - [x] 调用CaseAPIService.getDisputeTypes(caseSource) - [x] 将返回的data数组映射为{label: dispute_type, value: dispute_type} - [x] 更新disputeTypeOptions状态 - [x] 添加错误处理 #### Task 3.2: 实现发生时间统计数据加载 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 创建loadYearStatistics函数 - [x] 根据caseType选择调用getYearStatistics或getMediationYearStatistics - [x] 将返回的data数组映射为{label: `${year}年`, count, checked: false, value: year} - [x] 更新yearFilters状态 - [x] 添加错误处理 #### Task 3.3: 实现纠纷发生地统计数据加载 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 创建loadAreaStatistics函数,接收caseSource参数 - [x] 调用CaseAPIService.getAreaStatistics(caseSource) - [x] 将返回的data数组映射为筛选项格式(包含children子项) - [x] 更新regionFilters状态 - [x] 添加错误处理 #### Task 3.4: 实现案例类型切换联动 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 添加useEffect监听caseType变化 - [x] 在useEffect中依次调用: - loadDisputeTypes(caseSource) - loadYearStatistics() - loadAreaStatistics(caseSource) - [x] 其中caseSource根据caseType转换:judgment → 'judgment', mediation → 'mediation' ### Phase 4: API集成 - 案例列表数据加载 (1.5-2小时) #### Task 4.1: 实现案例列表数据加载函数 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 创建loadCaseList函数,接收page参数 - [x] 从yearFilters和regionFilters中提取选中的值 - [x] 构建查询参数对象params: - page, size, keyword, caseTypeFirst(disputeType) - occurrenceYears: 多个值用逗号拼接 - regionList: 多个值用逗号拼接 - [x] 根据caseType选择调用getMediationCases或getCourtCases - [x] 更新list和total状态 - [x] 添加Loading状态管理 - [x] 添加错误处理 #### Task 4.2: 实现日期格式化函数 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 创建formatDate函数 - [x] 将日期字符串格式化为"YYYY年MM月DD日"格式 - [x] 处理无效日期情况 #### Task 4.3: 实现首次加载逻辑 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 添加useEffect在组件挂载时调用loadCaseList(1) - [x] 确保依赖数组为空,只执行一次 #### Task 4.4: 修改查询和重置按钮处理逻辑 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 修改handleSearch函数:重置到第一页,调用loadCaseList(1) - [x] 修改handleReset函数:重置所有查询条件和筛选状态 #### Task 4.5: 修改列表数据渲染逻辑 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 修改list.map渲染逻辑,根据caseType判断字段映射: - 调解案例:case_title, occur_time, que_prov_name+"/"+que_city_name, case_type_first_name, id - 判决文书:case_name, judgment_date, court, case_reason, cpws_case_info_id - [x] 所有日期字段使用formatDate函数格式化 - [x] 更新case-type-badge显示逻辑 #### Task 4.6: 修改分页处理逻辑 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 修改handlePageChange函数调用loadCaseList - [x] 更新Pagination组件的total属性使用动态total状态 - [x] 确保pageSize正确传递 ### Phase 5: API集成 - 案例详情加载 (1.5-2小时) #### Task 5.1: 修改案例点击处理逻辑 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 修改handleCaseClick函数为async函数 - [x] 根据caseType确定使用的id字段(mediation: id, judgment: cpws_case_info_id) - [x] 根据caseType选择调用getMediationCaseDetail或getCourtCaseDetail - [x] 将返回的data设置到selectedCase状态 - [x] 设置selectedCaseType状态为当前caseType - [x] 打开详情弹窗 - [x] 添加Loading和错误处理 #### Task 5.2: 修改详情弹窗标题 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 修改Modal的title,根据selectedCaseType动态显示: - mediation: "典型案例详情" - judgment: "判决文书详情" #### Task 5.3: 传递案例类型到详情组件 - [x] **文件**: `web-app/src/components/tools/CaseSearchContent.jsx` - [x] 修改TypicalCaseDetailContent组件调用,传递caseType prop - [x] `` ### Phase 6: 详情组件重构 (1.5-2小时) #### Task 6.1: 修改TypicalCaseDetailContent组件props - [x] **文件**: `web-app/src/components/tools/TypicalCaseDetailContent.jsx` - [x] 添加caseType prop接收 - [x] 根据caseType判断展示逻辑分支 #### Task 6.2: 实现调解案例详情展示 - [x] **文件**: `web-app/src/components/tools/TypicalCaseDetailContent.jsx` - [x] 当caseType='mediation'时: - 第一行:展示案件标题(caseData.case_title) - 第二行:纠纷发生时间(occur_time)、发生地点(que_prov_name+"/"+que_city_name)、纠纷类型(case_type_first_name) - 移除:调解组织字段 - 详情内容: - 案例概述:case_des - 原告诉讼请求:case_claim - 调解结果:agree_content - 其他section全部不展示 #### Task 6.3: 实现判决文书详情展示 - [x] **文件**: `web-app/src/components/tools/TypicalCaseDetailContent.jsx` - [x] 当caseType='judgment'时: - 第一行:案件标题(case_name)、案号(case_number) - 第二行:判决日期(judgment_date)、发生地点(court)、纠纷类型(case_reason) - 详情内容: - 案例概述:basic_case_info - 原告介绍:plaintiff(改名) - 被告介绍:defendant(新增) - 法院审理与判决:trial_finding - 审理经过:trial_process(改名) - 审理程序:trial_procedure(改名) - 调解结果:judgment - 案例相关法律条文:legal_basis - 移除:调解背景、双方立场section #### Task 6.4: 处理字段不存在的情况 - [x] **文件**: `web-app/src/components/tools/TypicalCaseDetailContent.jsx` - [x] 为所有字段添加存在性检查,避免undefined错误 - [x] 使用条件渲染{field && (...)}包裹section ### Phase 7: 样式调整 (0.5小时) #### Task 7.1: 添加关键词全宽样式 - [x] **文件**: `web-app/src/components/tools/TypicalCaseSearch.css` - [x] 添加`.case-search-keyword-full`样式类 - [x] 设置grid-column: 1 / -1使其占满整行 #### Task 7.2: 验证响应式布局 - [x] **文件**: `web-app/src/components/tools/TypicalCaseSearch.css` - [x] 检查媒体查询是否需要调整 - [x] 确保移动端布局正常 ### Phase 8: 测试与验证 (2小时) #### Task 8.1: 功能测试 - 查询条件 - [ ] 测试弹窗打开时默认选中判决文书 - [ ] 测试关键词输入正常 - [ ] 测试案例类型切换时纠纷类型下拉框重新加载 - [ ] 测试案例类型切换时发生时间卡片重新加载 - [ ] 测试案例类型切换时纠纷发生地卡片重新加载 - [ ] 测试纠纷类型下拉框数据正确显示 - [ ] 测试筛选卡片数据正确显示 #### Task 8.2: 功能测试 - 列表查询 - [ ] 测试首次加载调用getCourtCases API - [ ] 测试点击查询按钮(判决文书)调用getCourtCases - [ ] 测试点击查询按钮(调解案例)调用getMediationCases - [ ] 测试列表数据正确展示(判决文书字段映射) - [ ] 测试列表数据正确展示(调解案例字段映射) - [ ] 测试日期格式化为"YYYY年MM月DD日" - [ ] 测试记录总数显示API返回的total值 - [ ] 测试分页功能正常工作 #### Task 8.3: 功能测试 - 详情展示 - [ ] 测试点击调解案例时调用getMediationCaseDetail - [ ] 测试点击判决文书时调用getCourtCaseDetail - [ ] 测试调解案例详情弹窗标题为"典型案例详情" - [ ] 测试判决文书详情弹窗标题为"判决文书详情" - [ ] 测试调解案例详情字段正确显示 - [ ] 测试判决文书详情字段正确显示 - [ ] 测试调解案例详情不显示多余字段 - [ ] 测试判决文书详情不显示多余字段 #### Task 8.4: 异常场景测试 - [ ] 测试API调用失败时显示错误提示 - [ ] 测试Loading状态正确显示 - [ ] 测试无数据时显示空状态提示 - [ ] 测试筛选条件为空时的查询行为 - [ ] 测试分页到最后一页的行为 #### Task 8.5: UI/UX测试 - [ ] 验证查询条件布局符合需求 - [ ] 验证案例类型切换流畅 - [ ] 验证详情弹窗样式正常 - [ ] 验证响应式设计不受影响 - [ ] 验证在不同数据量下的显示效果 ## 实施计划 ### 开发顺序 1. Phase 2: 先重构查询条件布局(视觉变化明显) 2. Phase 3: 实现筛选数据API集成(联动效果) 3. Phase 4: 实现列表数据API集成(核心功能) 4. Phase 5: 实现详情数据API集成(核心功能) 5. Phase 6: 重构详情组件分类展示(核心功能) 6. Phase 7: 样式微调 7. Phase 8: 全面测试 ### 关键检查点 - ✅ 查询条件布局是否符合需求 - ✅ 案例类型切换联动是否正常 - ✅ API调用参数构建是否正确 - ✅ 数据字段映射是否准确 - ✅ 详情分类展示是否正确 - ✅ 错误处理是否完整 ## 风险缓解措施 ### 技术风险 - **API数据格式不匹配**:提前验证所有API返回字段,准备字段映射表 - **日期格式不统一**:统一使用formatDate函数处理 - **筛选数据结构复杂**:逐个API测试,确认数据结构 - **详情字段缺失**:添加字段存在性检查,避免渲染错误 ### 质量保证 - 分阶段测试,确保每个功能点独立验证 - 保留现有功能作为基准对比 - 充分的异常场景测试 ## 验收标准检查清单 - [ ] 查询条件布局符合需求 - [ ] 移除纠纷发生时间和案例类型卡片 - [ ] 案例类型切换联动正常 - [ ] 首次加载判决文书列表 - [ ] 点击查询调用正确API - [ ] 列表数据字段映射正确 - [ ] 日期格式化正确 - [ ] 点击案例调用正确详情API - [ ] 调解案例详情展示正确 - [ ] 判决文书详情展示正确 - [ ] Loading状态正常工作 - [ ] 错误处理机制完善 - [ ] 分页功能正常工作