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]
<TypicalCaseDetailContent caseData={selectedCase} caseType={selectedCaseType} />
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测试
- [ ] 验证查询条件布局符合需求
- [ ] 验证案例类型切换流畅
- [ ] 验证详情弹窗样式正常
- [ ] 验证响应式设计不受影响
- [ ] 验证在不同数据量下的显示效果
实施计划
开发顺序
- Phase 2: 先重构查询条件布局(视觉变化明显)
- Phase 3: 实现筛选数据API集成(联动效果)
- Phase 4: 实现列表数据API集成(核心功能)
- Phase 5: 实现详情数据API集成(核心功能)
- Phase 6: 重构详情组件分类展示(核心功能)
- Phase 7: 样式微调
- Phase 8: 全面测试
关键检查点
- ✅ 查询条件布局是否符合需求
- ✅ 案例类型切换联动是否正常
- ✅ API调用参数构建是否正确
- ✅ 数据字段映射是否准确
- ✅ 详情分类展示是否正确
- ✅ 错误处理是否完整
风险缓解措施
技术风险
- API数据格式不匹配:提前验证所有API返回字段,准备字段映射表
- 日期格式不统一:统一使用formatDate函数处理
- 筛选数据结构复杂:逐个API测试,确认数据结构
- 详情字段缺失:添加字段存在性检查,避免渲染错误
质量保证
- 分阶段测试,确保每个功能点独立验证
- 保留现有功能作为基准对比
- 充分的异常场景测试
验收标准检查清单
- [ ] 查询条件布局符合需求
- [ ] 移除纠纷发生时间和案例类型卡片
- [ ] 案例类型切换联动正常
- [ ] 首次加载判决文书列表
- [ ] 点击查询调用正确API
- [ ] 列表数据字段映射正确
- [ ] 日期格式化正确
- [ ] 点击案例调用正确详情API
- [ ] 调解案例详情展示正确
- [ ] 判决文书详情展示正确
- [ ] Loading状态正常工作
- [ ] 错误处理机制完善
- [ ] 分页功能正常工作