Files
smart-crop-ui/src/CUSTOM_TIME_RANGE_FEATURE.md

17 KiB
Raw Blame History

作业数据分析 - 自定义时间范围功能

🎯 功能说明

为作业数据分析页面添加自定义时间范围选择功能,支持精确选择开始和结束日期


📅 功能特点

核心功能

  1. 时间范围选择器

    • 最近6个月
    • 最近3个月
    • 最近1个月
    • 自定义时间
  2. 自定义日期选择

    • 开始日期选择
    • 结束日期选择
    • 日期范围验证
    • 天数统计显示
  3. 智能交互

    • 选择"自定义时间"自动展开日期选择器
    • 结束日期不能早于开始日期
    • 中文日期格式显示
    • 实时计算时间跨度

🎨 界面展示

时间范围选择器

┌────────────────────────────────────────────────────────────────┐
│  🔍 数据筛选                                                    │
├────────────────────────────────────────────────────────────────┤
│  时间范围           地块           农机           驾驶员       │
│  [自定义时间 ▼]    [全部地块 ▼]   [全部农机 ▼]   [全部 ▼]    │
└────────────────────────────────────────────────────────────────┘

自定义时间范围面板(展开后)

┌────────────────────────────────────────────────────────────────┐
│  📅 自定义时间范围                                              │
├────────────────────────────────────────────────────────────────┤
│  开始日期                        结束日期                      │
│  ┌──────────────────────┐      ┌──────────────────────┐      │
│  │ 📅 2024年09月01日 ▼  │      │ 📅 2024年10月17日 ▼  │      │
│  └──────────────────────┘      └──────────────────────┘      │
│                                                                │
│  ┌──────────────────────────────────────────────────────────┐ │
│  │ ✅ 已选择时间段2024年09月01日 至 2024年10月17日         │ │
│  │    (共 46 天)                                           │ │
│  └──────────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────────┘

日期选择器弹窗

点击日期输入框后弹出:

┌──────────────────────────┐
│     2024年10月           │
├──────────────────────────┤
│  日  一  二  三  四  五  六│
│                      1   2│
│  3   4   5   6   7   8   9│
│ 10  11  12  13  14  15  16│
│ 17  18  19  20  21  22  23│ ← 17日被选中
│ 24  25  26  27  28  29  30│
│ 31                        │
└──────────────────────────┘

💡 使用方法

步骤1: 选择"自定义时间"

操作:
1. 进入作业数据分析页面
2. 点击"时间范围"下拉框
3. 选择"自定义时间"
4. 自动展开日期选择面板

步骤2: 选择开始日期

操作:
1. 点击"开始日期"输入框
2. 在日历中选择开始日期
3. 确认选择

日期显示

未选择:[📅 选择开始日期]
已选择:[📅 2024年09月01日]

步骤3: 选择结束日期

操作:
1. 点击"结束日期"输入框
2. 在日历中选择结束日期
   (早于开始日期的日期会被禁用)
3. 确认选择

日期显示

未选择:[📅 选择结束日期]
已选择:[📅 2024年10月17日]

步骤4: 查看选择结果

选择完成后自动显示:

┌────────────────────────────────────────────┐
│ ✅ 已选择时间段:                           │
│    2024年09月01日 至 2024年10月17日        │
│    (共 46 天)                            │
└────────────────────────────────────────────┘

步骤5: 应用筛选

结果:
- 数据自动按选定时间范围筛选
- 所有图表和统计指标更新
- KPI卡片显示该时段数据

🔧 技术实现

状态管理

// 时间范围状态
const [timeRange, setTimeRange] = useState('last6months');

// 自定义日期状态
const [customStartDate, setCustomStartDate] = useState<Date>();
const [customEndDate, setCustomEndDate] = useState<Date>();
const [showCustomDateRange, setShowCustomDateRange] = useState(false);

时间范围切换处理

const handleTimeRangeChange = (value: string) => {
  setTimeRange(value);
  
  if (value === 'custom') {
    // 选择自定义时,显示日期选择器
    setShowCustomDateRange(true);
  } else {
    // 选择预设时间,隐藏日期选择器
    setShowCustomDateRange(false);
    setCustomStartDate(undefined);
    setCustomEndDate(undefined);
  }
};

开始日期选择器

<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline" className="w-full justify-start text-left">
      <CalendarIcon className="mr-2 h-4 w-4" />
      {customStartDate ? (
        format(customStartDate, 'yyyy年MM月dd日', { locale: zhCN })
      ) : (
        <span className="text-muted-foreground">选择开始日期</span>
      )}
    </Button>
  </PopoverTrigger>
  <PopoverContent className="w-auto p-0" align="start">
    <Calendar
      mode="single"
      selected={customStartDate}
      onSelect={setCustomStartDate}
      initialFocus
      locale={zhCN}
    />
  </PopoverContent>
</Popover>

结束日期选择器(带验证)

<Popover>
  <PopoverTrigger asChild>
    <Button variant="outline" className="w-full justify-start text-left">
      <CalendarIcon className="mr-2 h-4 w-4" />
      {customEndDate ? (
        format(customEndDate, 'yyyy年MM月dd日', { locale: zhCN })
      ) : (
        <span className="text-muted-foreground">选择结束日期</span>
      )}
    </Button>
  </PopoverTrigger>
  <PopoverContent className="w-auto p-0" align="start">
    <Calendar
      mode="single"
      selected={customEndDate}
      onSelect={setCustomEndDate}
      initialFocus
      locale={zhCN}
      disabled={(date) => 
        customStartDate ? date < customStartDate : false  // 禁用早于开始日期的日期
      }
    />
  </PopoverContent>
</Popover>

验证逻辑

  • 如果已选择开始日期,结束日期不能早于开始日期
  • 早于开始日期的日期在日历中会被禁用(灰色不可点击)

时间跨度计算

{customStartDate && customEndDate && (
  <div className="mt-3 p-3 bg-white rounded border border-blue-200">
    <p className="text-sm text-blue-800">
      已选择时间段:
      <strong className="mx-1">
        {format(customStartDate, 'yyyy年MM月dd日', { locale: zhCN })}
      </strong>
      
      <strong className="mx-1">
        {format(customEndDate, 'yyyy年MM月dd日', { locale: zhCN })}
      </strong>
      (共 {Math.ceil((customEndDate.getTime() - customStartDate.getTime()) / (1000 * 60 * 60 * 24))} 天)
    </p>
  </div>
)}

计算公式

天数 = Math.ceil((结束日期 - 开始日期) / (1000 * 60 * 60 * 24))

📋 时间范围选项

预设选项

选项 说明 时间跨度
最近6个月 从今天往前6个月 ~180天
最近3个月 从今天往前3个月 ~90天
最近1个月 从今天往前1个月 ~30天
自定义时间 用户自定义选择 任意

自定义时间的优势

  1. 精确控制

    • 可以精确到日
    • 选择任意时间段
    • 不受预设限制
  2. 灵活分析

    • 季度分析3个月
    • 半年分析6个月
    • 年度分析12个月
    • 特定活动周期分析
  3. 对比分析

    • 选择去年同期
    • 选择特定作业季节
    • 选择特定事件前后

🎨 界面细节

1. 日期输入框样式

未选择状态

┌──────────────────────┐
│ 📅 选择开始日期      │
└──────────────────────┘
      ↑ 灰色提示文字

已选择状态

┌──────────────────────┐
│ 📅 2024年09月01日 ▼  │
└──────────────────────┘
      ↑ 黑色正常文字

2. 日历弹窗

特点

  • 中文星期显示(日、一、二...
  • 中文月份显示2024年10月
  • 当前日期高亮
  • 选中日期蓝色背景
  • 禁用日期灰色不可点击

3. 时间段提示框

样式

  • 蓝色边框
  • 白色背景
  • 清晰的文字说明
  • 天数统计
┌────────────────────────────────────────────┐
│ ✅ 已选择时间段:                           │
│    2024年09月01日 至 2024年10月17日        │
│    (共 46 天)                            │
└────────────────────────────────────────────┘

💡 使用场景

场景1: 季度分析

需求分析第三季度7-9月的作业数据

操作:
1. 选择"自定义时间"
2. 开始日期2024年07月01日
3. 结束日期2024年09月30日
4. 查看该季度数据

结果:
- 第三季度作业面积
- 季度成本统计
- 季度效率分析

场景2: 同比分析

需求:对比今年和去年同期数据

今年数据:
- 开始2024年09月01日
- 结束2024年10月17日

去年数据:
- 开始2023年09月01日
- 结束2023年10月17日

操作:
1. 先查看今年数据
2. 记录关键指标
3. 切换到去年同期
4. 对比分析

场景3: 特定活动分析

需求:分析某次农忙季节的作业情况

操作:
1. 选择"自定义时间"
2. 开始日期:农忙开始日期
3. 结束日期:农忙结束日期
4. 分析该时段数据

示例:
- 春耕时段03月15日 - 04月30日
- 秋收时段09月15日 - 10月31日

📊 数据筛选逻辑

预设时间范围

// 最近1个月
const now = new Date();
const oneMonthAgo = new Date(now.getTime() - 30 * 24 * 60 * 60 * 1000);

// 最近3个月
const threeMonthsAgo = new Date(now.getTime() - 90 * 24 * 60 * 60 * 1000);

// 最近6个月
const sixMonthsAgo = new Date(now.getTime() - 180 * 24 * 60 * 60 * 1000);

自定义时间范围

// 使用用户选择的开始和结束日期
const filteredData = data.filter(item => {
  const itemDate = new Date(item.date);
  return itemDate >= customStartDate && itemDate <= customEndDate;
});

功能验证

交互验证

  • 选择"自定义时间"展开日期选择器
  • 选择其他选项隐藏日期选择器
  • 日期选择器中文显示
  • 结束日期验证(不早于开始日期)

日期格式

  • 中文年月日格式
  • date-fns 日期格式化
  • zhCN 中文本地化

计算验证

  • 天数计算正确
  • 时间跨度显示
  • 实时更新提示

样式验证

  • 蓝色主题统一
  • 响应式布局
  • 清晰的视觉层次

🔄 完整操作流程

流程图

┌──────────────────────┐
│  进入作业数据分析     │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  点击时间范围选择器   │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  选择"自定义时间"    │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  展开日期选择面板     │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  选择开始日期        │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  选择结束日期        │
│  (禁用早于开始日期)│
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  显示选择结果        │
│  (时间段 + 天数)   │
└──────┬───────────────┘
       │
       ▼
┌──────────────────────┐
│  数据自动筛选        │
│  图表自动更新        │
└──────────────────────┘

📝 代码依赖

新增依赖

// UI组件
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover';
import { Calendar } from '../../ui/calendar';

// 日期工具
import { format } from 'date-fns';
import { zhCN } from 'date-fns/locale';

// 图标
import { Calendar as CalendarIcon } from 'lucide-react';

使用的Shadcn组件

  1. Popover - 日期选择器弹窗
  2. Calendar - 日历组件
  3. Button - 日期输入框按钮
  4. Select - 时间范围下拉选择

🎯 用户体验提升

优势1: 直观的日期选择

传统方式:
- 手动输入日期
- 容易出错
- 格式不统一

新方式:
- ✅ 点击日历选择
- ✅ 格式自动正确
- ✅ 可视化选择

优势2: 智能验证

验证逻辑:
- 结束日期不能早于开始日期
- 禁用无效日期
- 实时提示错误

用户体验:
- ✅ 不会选择错误日期
- ✅ 即时反馈
- <20><> 减少操作错误

优势3: 清晰的反馈

选择过程中:
- 实时显示已选日期
- 中文格式易读
- 天数自动计算

完成后:
- 明确的时间段提示
- 天数统计一目了然
- 便于确认选择

🚀 后续增强

Phase 1: 快捷选择

添加常用时间段快捷按钮:

[ 本周 ] [ 本月 ] [ 本季度 ] [ 本年度 ]
[ 上周 ] [ 上月 ] [ 上季度 ] [ 去年 ]

Phase 2: 预设对比期

添加同比/环比快捷选择:

选择基准期2024年09月01日 - 2024年10月17日

自动计算:
- 去年同期2023年09月01日 - 2023年10月17日
- 上一周期2024年07月16日 - 2024年08月31日

Phase 3: 时间段模板

保存常用时间段:

我的模板:
- 春耕季03月15日 - 04月30日
- 夏管季05月01日 - 07月31日
- 秋收季09月15日 - 10月31日

一键应用模板

📚 相关文档

  • 组件文件: /components/machinery/data/OperationAnalysis.tsx
  • 日期组件: /components/ui/calendar.tsx
  • 弹窗组件: /components/ui/popover.tsx

总结

主要功能

  1. 时间范围选择 - 4种预设 + 自定义
  2. 日期选择器 - 可视化日历选择
  3. 智能验证 - 结束日期不早于开始日期
  4. 中文显示 - 完全中文本地化
  5. 天数计算 - 自动计算时间跨度

用户价值

  • 精确控制: 可以选择任意时间段
  • 易于使用: 点击日历即可选择
  • 智能验证: 避免选择错误日期
  • 直观反馈: 清晰显示选择结果

技术亮点

  • 使用 date-fns 进行日期处理
  • 中文本地化支持
  • 日期验证和禁用逻辑
  • 响应式布局设计

更新时间: 2025-10-17
版本: v1.0
状态: 自定义时间范围功能已完成

核心改进: 添加可视化日期选择器,支持精确的自定义时间范围选择!