生产管理系统前端 - 更新瓦力提交的产品原型到参考目录
This commit is contained in:
696
src/CUSTOM_TIME_RANGE_FEATURE.md
Normal file
696
src/CUSTOM_TIME_RANGE_FEATURE.md
Normal file
@@ -0,0 +1,696 @@
|
||||
# ✅ 作业数据分析 - 自定义时间范围功能
|
||||
|
||||
## 🎯 功能说明
|
||||
|
||||
**为作业数据分析页面添加自定义时间范围选择功能,支持精确选择开始和结束日期**
|
||||
|
||||
---
|
||||
|
||||
## 📅 功能特点
|
||||
|
||||
### 核心功能
|
||||
|
||||
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卡片显示该时段数据
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 技术实现
|
||||
|
||||
### 状态管理
|
||||
|
||||
```typescript
|
||||
// 时间范围状态
|
||||
const [timeRange, setTimeRange] = useState('last6months');
|
||||
|
||||
// 自定义日期状态
|
||||
const [customStartDate, setCustomStartDate] = useState<Date>();
|
||||
const [customEndDate, setCustomEndDate] = useState<Date>();
|
||||
const [showCustomDateRange, setShowCustomDateRange] = useState(false);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 时间范围切换处理
|
||||
|
||||
```typescript
|
||||
const handleTimeRangeChange = (value: string) => {
|
||||
setTimeRange(value);
|
||||
|
||||
if (value === 'custom') {
|
||||
// 选择自定义时,显示日期选择器
|
||||
setShowCustomDateRange(true);
|
||||
} else {
|
||||
// 选择预设时间,隐藏日期选择器
|
||||
setShowCustomDateRange(false);
|
||||
setCustomStartDate(undefined);
|
||||
setCustomEndDate(undefined);
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 开始日期选择器
|
||||
|
||||
```typescript
|
||||
<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>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 结束日期选择器(带验证)
|
||||
|
||||
```typescript
|
||||
<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>
|
||||
```
|
||||
|
||||
**验证逻辑**:
|
||||
- 如果已选择开始日期,结束日期不能早于开始日期
|
||||
- 早于开始日期的日期在日历中会被禁用(灰色不可点击)
|
||||
|
||||
---
|
||||
|
||||
### 时间跨度计算
|
||||
|
||||
```typescript
|
||||
{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>
|
||||
)}
|
||||
```
|
||||
|
||||
**计算公式**:
|
||||
```typescript
|
||||
天数 = 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日
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📊 数据筛选逻辑
|
||||
|
||||
### 预设时间范围
|
||||
|
||||
```typescript
|
||||
// 最近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);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 自定义时间范围
|
||||
|
||||
```typescript
|
||||
// 使用用户选择的开始和结束日期
|
||||
const filteredData = data.filter(item => {
|
||||
const itemDate = new Date(item.date);
|
||||
return itemDate >= customStartDate && itemDate <= customEndDate;
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## ✅ 功能验证
|
||||
|
||||
### 交互验证
|
||||
- [x] ✅ 选择"自定义时间"展开日期选择器
|
||||
- [x] ✅ 选择其他选项隐藏日期选择器
|
||||
- [x] ✅ 日期选择器中文显示
|
||||
- [x] ✅ 结束日期验证(不早于开始日期)
|
||||
|
||||
### 日期格式
|
||||
- [x] ✅ 中文年月日格式
|
||||
- [x] ✅ date-fns 日期格式化
|
||||
- [x] ✅ zhCN 中文本地化
|
||||
|
||||
### 计算验证
|
||||
- [x] ✅ 天数计算正确
|
||||
- [x] ✅ 时间跨度显示
|
||||
- [x] ✅ 实时更新提示
|
||||
|
||||
### 样式验证
|
||||
- [x] ✅ 蓝色主题统一
|
||||
- [x] ✅ 响应式布局
|
||||
- [x] ✅ 清晰的视觉层次
|
||||
|
||||
---
|
||||
|
||||
## 🔄 完整操作流程
|
||||
|
||||
### 流程图
|
||||
|
||||
```
|
||||
┌──────────────────────┐
|
||||
│ 进入作业数据分析 │
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 点击时间范围选择器 │
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 选择"自定义时间" │
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 展开日期选择面板 │
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 选择开始日期 │
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 选择结束日期 │
|
||||
│ (禁用早于开始日期)│
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 显示选择结果 │
|
||||
│ (时间段 + 天数) │
|
||||
└──────┬───────────────┘
|
||||
│
|
||||
▼
|
||||
┌──────────────────────┐
|
||||
│ 数据自动筛选 │
|
||||
│ 图表自动更新 │
|
||||
└──────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📝 代码依赖
|
||||
|
||||
### 新增依赖
|
||||
|
||||
```typescript
|
||||
// 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
|
||||
**状态**: ✅ **自定义时间范围功能已完成**
|
||||
|
||||
**核心改进**: 添加可视化日期选择器,支持精确的自定义时间范围选择!
|
||||
Reference in New Issue
Block a user