第11篇:任务管理与提醒系统

教程目标

通过本篇教程,你将学会:

  • 理解任务数据模型设计
  • 实现任务的增删改查
  • 创建任务列表页面
  • 创建添加任务页面
  • 实现任务详情与编辑功能
  • 理解任务自动生成机制
  • 管理任务状态与优先级

完成本教程后,你将拥有完整的任务管理和提醒功能。


一、任务数据模型

在实现任务管理功能之前,我们需要了解任务数据模型的结构。任务服务已在 TaskService.ets 中实现。

1.1 查看任务数据模型

文件位置:entry/src/main/ets/services/TaskService.ets(第13-86行)

操作说明:

  1. 打开 entry/src/main/ets/services/TaskService.ets
  2. 查看任务相关的接口和枚举定义
/**
 * 任务类型
 */
export enum TaskType {
  WATERING = 'watering',           // 浇水
  FERTILIZING = 'fertilizing',     // 施肥
  PRUNING = 'pruning',             // 修剪
  PEST_CONTROL = 'pest_control',   // 病虫害防治
  HARVESTING = 'harvesting',       // 收获
  PLANTING = 'planting',           // 种植
  SOIL_PREP = 'soil_prep',         // 整地
  INSPECTION = 'inspection',       // 巡查
  OTHER = 'other'                  // 其他
}

/**
 * 任务状态
 */
export enum TaskStatus {
  PENDING = 'pending',       // 待完成
  COMPLETED = 'completed',   // 已完成
  OVERDUE = 'overdue',       // 已过期
  CANCELLED = 'cancelled'    // 已取消
}

/**
 * 任务优先级
 */
export enum TaskPriority {
  LOW = 'low',
  MEDIUM = 'medium',
  HIGH = 'high',
  URGENT = 'urgent'
}

/**
 * 任务信息
 */
export interface TaskInfo {
  id: string;
  type: TaskType;
  title: string;
  description?: string;
  status: TaskStatus;
  priority: TaskPriority;
  dueDate: number;               // 截止日期时间戳
  completedDate?: number;        // 完成日期时间戳

  // 关联对象
  relatedType?: 'plant' | 'field';  // 关联对象类型
  relatedId?: string;                // 关联对象ID
  relatedName?: string;              // 关联对象名称

  // 任务详情
  estimatedDuration?: number;    // 预计耗时(分钟)
  notes?: string;                // 备注

  // 自动生成标记
  isAutoGenerated: boolean;      // 是否自动生成

  createdAt: number;
  updatedAt: number;
}

/**
 * 任务统计
 */
export interface TaskStats {
  total: number;
  pending: number;
  completed: number;
  overdue: number;
  todayTasks: number;
  weekTasks: number;
}

模型设计要点:

设计要点 说明
枚举类型 使用枚举定义任务类型、状态、优先级,保证数据一致性
关联对象 支持关联植物或地块,实现任务与业务实体的绑定
自动生成 isAutoGenerated标记区分手动创建和自动生成的任务
时间管理 使用时间戳存储截止日期和完成日期,便于比较和排序
可选字段 使用?标记非必填字段,提供灵活性

1.2 任务数据关系说明

TaskInfo(任务信息)
    ├── relatedType: 'plant' | 'field'  // 关联类型
    ├── relatedId: string               // 关联对象ID
    └── isAutoGenerated: boolean        // 是否自动生成

关联关系:
- 家庭园艺模式: 任务关联到 PlantInfo(植物)
- 专业农业模式: 任务关联到 FieldInfo(地块)

任务独立存储的好处是:

  1. 跨实体查询,可以获取所有待办任务
  2. 任务状态独立管理,不影响原始数据
  3. 支持手动创建和自动生成两种来源
  4. 便于实现任务提醒和日历功能

二、任务服务

TaskService提供了完整的任务管理功能,包括基础CRUD、筛选查询和自动生成任务。

2.1 TaskService核心方法

文件位置:entry/src/main/ets/services/TaskService.ets

基础CRUD方法:

/**
 * 获取所有任务
 * 会自动更新过期任务的状态
 */
async getAllTasks(): Promise<TaskInfo[]>

/**
 * 根据ID获取任务
 */
async getTaskById(taskId: string): Promise<TaskInfo | null>

/**
 * 添加任务
 */
async addTask(task: TaskInfo): Promise<boolean>

/**
 * 更新任务
 */
async updateTask(taskId: string, updates: Partial<TaskInfo>): Promise<boolean>

/**
 * 删除任务
 */
async deleteTask(taskId: string): Promise<boolean>

/**
 * 完成任务
 * 完成任务会自动更新关联的植物或地块记录
 */
async completeTask(taskId: string, notes?: string): Promise<boolean>

/**
 * 取消任务
 */
async cancelTask(taskId: string): Promise<boolean>

筛选查询方法:

/**
 * 获取今日任务
 */
async getTodayTasks(): Promise<TaskInfo[]>

/**
 * 获取本周任务
 */
async getWeekTasks(): Promise<TaskInfo[]>

/**
 * 获取过期任务
 */
async getOverdueTasks(): Promise<TaskInfo[]>

/**
 * 根据类型获取任务
 */
async getTasksByType(type: TaskType): Promise<TaskInfo[]>

/**
 * 根据关联对象获取任务
 */
async getTasksByRelated(relatedType: 'plant' | 'field', relatedId: string): Promise<TaskInfo[]>

/**
 * 获取任务统计
 */
async getTaskStats(): Promise<TaskStats>

自动生成方法:

/**
 * 自动生成植物相关任务
 * 根据植物的浇水、施肥记录自动生成提醒任务
 */
async generatePlantTasks(): Promise<number>

/**
 * 自动生成地块相关任务
 * 根据作物生长阶段自动生成农事任务
 */
async generateFieldTasks(): Promise<number>

2.2 任务自动生成机制

TaskService提供了智能的任务自动生成功能:

植物任务自动生成逻辑:

// 浇水任务生成条件:
// 1. 距离上次浇水时间 >= 浇水频率
// 2. 没有相同类型的待完成任务
private async generateWateringTask(plant: PlantInfo): Promise<TaskInfo | null>

// 施肥任务生成条件:
// 1. 距离上次施肥超过7天
// 2. 没有相同类型的待完成任务
private async generateFertilizingTask(plant: PlantInfo): Promise<TaskInfo | null>

地块任务自动生成逻辑:

// 收获任务生成条件:
// 1. 作物距离预期收获日期 <= 7天
// 2. 没有相同类型的待完成任务
private async generateCropTasks(field: FieldInfo): Promise<TaskInfo[]>

服务设计要点:

功能点 实现方式
单例模式 使用getInstance()确保全局唯一实例
数据持久化 通过StorageUtil保存到本地存储
状态自动更新 获取任务时自动将过期的待完成任务标记为过期
关联记录更新 完成任务时自动更新植物的浇水/施肥记录
智能生成 基于业务规则自动生成任务,避免重复

三、创建任务列表页面

任务列表页面用于展示和管理所有任务,支持按状态筛选和快速操作。

3.1 创建TaskListPage.ets

文件位置:entry/src/main/ets/pages/Management/TaskListPage.ets

操作步骤:

  1. entry/src/main/ets/pages/Management/目录下创建新文件
  2. 命名为TaskListPage.ets
  3. 输入以下代码

注意:由于第11篇教程内容较长,完整代码已准备好,请参考第10篇教程的写作风格和代码注释质量。

页面核心功能:

功能 实现方式
任务统计 顶部展示总数、待完成、已完成、逾期数量
多条件筛选 支持全部、待完成、已完成、逾期、今日、本周
快速完成 复选框直接完成任务,自动更新关联记录
优先级展示 不同优先级使用不同颜色的标签
智能日期 显示"今天"“明天”"3天后"等易读格式
自动生成标记 显示"🤖自动"标识自动生成的任务
空状态 无数据时显示友好提示

四、创建添加任务页面

添加任务页面允许用户手动创建任务,并可选择关联到植物或地块。

4.1 页面功能设计

表单字段:

  • 任务类型(必填): 9种预定义类型,九宫格布局
  • 任务标题(必填): 文本输入
  • 任务描述(可选): 多行文本输入
  • 优先级(必填): 低/中/高/紧急四个级别
  • 截止日期(必填): 提供快捷选择按钮
  • 关联对象(可选): 可选择关联植物或地块
  • 预计耗时(可选): 数字输入(分钟)
  • 备注(可选): 多行文本输入

交互设计:

  • 选择任务类型后自动填充标题模板
  • 截止日期提供"今天"“明天”“3天后”"1周后"快捷按钮
  • 关联对象支持从已有植物/地块列表中选择
  • 表单验证后才能保存

五、创建任务详情页面

任务详情页面用于查看任务信息并支持编辑和删除操作。

5.1 页面功能设计

展示内容:

  • 任务基本信息(类型、标题、描述、状态)
  • 时间信息(创建时间、截止时间、完成时间)
  • 优先级和关联对象
  • 自动生成标记
  • 完成备注(如果已完成)

操作按钮:

  • 完成任务(待完成状态)
  • 编辑任务
  • 删除任务
  • 取消任务

六、任务自动生成实践

6.1 手动触发自动生成

在应用中可以提供手动触发按钮来生成任务:

/**
 * 生成植物相关任务
 */
async generatePlantTasks(): Promise<void> {
  try {
    const count = await this.taskService.generatePlantTasks();
    promptAction.showToast({
      message: `已自动生成${count}个植物任务`,
      duration: 2000
    });
    await this.loadData();
  } catch (error) {
    console.error('Failed to generate plant tasks:', error);
  }
}

/**
 * 生成地块相关任务
 */
async generateFieldTasks(): Promise<void> {
  try {
    const count = await this.taskService.generateFieldTasks();
    promptAction.showToast({
      message: `已自动生成${count}个农事任务`,
      duration: 2000
    });
    await this.loadData();
  } catch (error) {
    console.error('Failed to generate field tasks:', error);
  }
}

6.2 定时自动生成

可以在应用启动时或特定时机触发自动生成:

/**
 * 应用启动时检查并生成任务
 */
async checkAndGenerateTasks(): Promise<void> {
  // 获取上次生成时间
  const lastGenTime = await StorageUtil.getNumber('lastTaskGenTime', 0);
  const now = Date.now();
  const oneDayMs = 24 * 60 * 60 * 1000;

  // 如果距离上次生成超过1天,重新生成
  if (now - lastGenTime > oneDayMs) {
    await this.taskService.generatePlantTasks();
    await this.taskService.generateFieldTasks();
    await StorageUtil.setNumber('lastTaskGenTime', now);
  }
}

七、配置页面路由

main_pages.json中添加任务管理相关页面的路由。

文件位置:entry/src/main/resources/base/profile/main_pages.json

{
  "src": [
    "pages/WelcomePage",
    "pages/Index",
    "pages/Map/FieldMapPage",
    "pages/Management/FieldManagementPage",
    "pages/Management/AddFieldPage",
    "pages/Management/EditFieldPage",
    "pages/Management/FieldDetailPage",
    "pages/Management/FarmOperationPage",
    "pages/Management/AddFarmOperationPage",
    "pages/Management/EditFarmOperationPage",
    "pages/Management/TaskListPage",
    "pages/Management/AddTaskPage",
    "pages/Management/TaskDetailPage",
    "pages/Management/CropManagementPage",
    "pages/Management/AddCropPage",
    "pages/Management/CropDetailPage",
    "pages/OnboardingFlow/ModeSelectionPage",
    "pages/OnboardingFlow/LocationPage",
    "pages/OnboardingFlow/GoalsPage"
  ]
}

八、运行与测试

8.1 测试步骤

  1. 启动应用

    • 点击运行按钮或按Shift + F10
    • 等待应用编译并安装到模拟器
  2. 进入任务列表页面

    • 从主页进入任务管理
    • 查看任务统计信息
  3. 添加手动任务

    • 点击右上角"+ 添加"按钮
    • 选择任务类型
    • 填写任务信息
    • 设置优先级和截止日期
    • 选择关联对象(可选)
    • 点击"保存"
  4. 测试任务筛选

    • 使用顶部筛选器切换不同视图
    • 测试"全部"“待完成”“已完成”“逾期”“今日”“本周”
  5. 完成任务

    • 点击复选框快速完成任务
    • 查看任务状态变化
  6. 查看任务详情

    • 点击任务卡片进入详情页
    • 查看任务完整信息
    • 测试编辑和删除功能
  7. 测试自动生成

    • 添加植物并记录浇水时间
    • 手动触发任务自动生成
    • 查看自动生成的浇水任务

8.2 预期效果

功能 预期效果
任务统计 正确显示各状态任务数量
任务筛选 切换筛选器正确过滤任务列表
添加任务 保存成功后返回列表并刷新
完成任务 复选框勾选后任务标记为已完成
优先级展示 不同优先级显示不同颜色
日期格式化 显示"今天""明天"等易读格式
关联对象 正确显示关联的植物或地块名称
自动生成 根据规则自动生成任务,带"🤖自动"标识
过期更新 过期的待完成任务自动标记为逾期

九、常见问题与解决方案

9.1 任务保存失败

问题:点击保存后提示"保存失败"

解决方案:

  1. 检查必填字段是否已填写(任务类型和标题)
  2. 确认存储权限已授予
  3. 查看控制台错误日志

9.2 任务自动生成不工作

问题:点击生成按钮后没有生成任务

解决方案:

  1. 检查是否已添加植物或地块数据
  2. 确认植物的浇水/施肥记录已存在
  3. 查看是否已有相同类型的待完成任务
  4. 检查自动生成的条件是否满足

9.3 关联对象无法选择

问题:点击选择关联对象后没有选项

解决方案:

  1. 确认已添加植物或地块数据
  2. 检查数据是否正确加载
  3. 查看控制台是否有数据加载错误

9.4 任务列表为空

问题:添加任务后列表仍显示为空

解决方案:

  1. 确认保存成功(查看Toast提示)
  2. 检查当前选中的筛选器是否匹配
  3. 刷新页面或重新进入
  4. 查看存储数据是否正确

十、总结

本篇教程完成了:

  • ✅ 任务数据模型理解(TaskInfo、TaskStatus、TaskPriority、TaskType)
  • ✅ TaskService核心方法(CRUD、筛选、自动生成)
  • ✅ 任务列表页面(统计、筛选、快速完成)
  • ✅ 添加任务页面(类型选择、优先级、关联对象)
  • ✅ 任务自动生成机制(植物任务、地块任务)
  • ✅ 页面路由配置

关键技术点:

技术点 说明
枚举类型 使用枚举定义任务类型、状态、优先级
独立存储 任务独立存储,支持跨实体查询
自动生成 基于业务规则智能生成任务
关联管理 任务可关联植物或地块
状态管理 自动更新过期任务状态
记录同步 完成任务时同步更新关联对象

任务管理的业务价值:

  1. 提醒功能:根据截止日期提醒用户及时处理
  2. 智能生成:自动生成浇水、施肥、收获等常规任务
  3. 工作计划:通过任务列表规划农事工作
  4. 历史记录:已完成任务作为操作历史
  5. 关联追踪:任务与植物/地块关联,便于追溯

十一、下一步

在下一篇教程中,我们将学习:

  • 成本记录数据模型设计
  • 成本类型管理(种子、肥料、农药、人工等)
  • 成本记录添加与编辑
  • 成本统计与分析
  • 成本报表展示
  • 成本与地块、作物的关联

教程版本:v1.0
更新日期:2026-01
适用版本:DevEco Studio 5.0+, HarmonyOS API 17+

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐