第23篇:智能推荐系统
📚 本篇导读
智能推荐是现代农业应用的核心功能之一,通过分析地块特征、气候条件、节气时令等多维度数据,为农户提供科学的种植建议和农事指导。本篇教程将实现一个完整的智能推荐系统,涵盖作物推荐、农事推荐、智能决策等功能。
本篇将实现:
- 🌱 作物种植推荐(基于气候、地块、节气)
- 📅 农事操作推荐(基于作物生长周期)
- 🤖 智能决策建议(基于数据分析)
- 🌾 节气农事指导(二十四节气推荐)
- 📊 产量预测分析(基于历史数据)
🎯 学习目标
完成本篇教程后,你将掌握:
- 如何设计智能推荐算法
- 如何整合多维度数据进行推荐
- 如何实现基于规则的推荐引擎
- 如何展示推荐结果
- 推荐系统的实际应用场景
一、智能推荐系统架构
1.1 系统架构设计
智能推荐系统
├── 数据采集层
│ ├── 地块数据(面积、土壤、灌溉)
│ ├── 气候数据(温度、降雨、湿度)
│ ├── 节气数据(二十四节气)
│ └── 历史数据(种植记录、产量)
│
├── 推荐引擎层
│ ├── 作物推荐引擎
│ │ ├── 气候匹配算法
│ │ ├── 地块适配算法
│ │ └── 节气推荐算法
│ │
│ ├── 农事推荐引擎
│ │ ├── 生长周期分析
│ │ ├── 农事时机判断
│ │ └── 操作优先级排序
│ │
│ └── 智能决策引擎
│ ├── 产量预测模型
│ ├── 风险评估模型
│ └── 优化建议生成
│
└── 展示层
├── 推荐卡片展示
├── 详细说明页面
└── 操作引导界面
1.2 推荐维度
| 推荐类型 | 数据来源 | 推荐依据 |
|---|---|---|
| 作物推荐 | 气候、地块、节气 | 温度、降雨、土壤类型、季节 |
| 农事推荐 | 作物生长数据 | 生长天数、生长阶段、天气 |
| 智能决策 | 历史数据、实时数据 | 产量预测、风险评估、优化建议 |
| 节气指导 | 二十四节气 | 传统农事经验、节气特点 |
1.3 核心服务类
本教程涉及以下核心服务:
PlantRecommendationService- 作物推荐服务SolarTermService- 节气服务SmartDecisionPage- 智能决策页面FieldService- 地块服务WeatherService- 天气服务
二、PlantRecommendationService 作物推荐服务
2.1 数据模型设计
文件位置 :entry/src/main/ets/services/PlantRecommendationService.ets
typescript
/**
* 作物推荐信息接口
*/
export interface PlantRecommendation {
plantName: string; // 植物名称
plantType: string; // 植物类型
reason: string; // 推荐理由
difficulty: string; // 种植难度
growthPeriod: string; // 生长周期
icon: string; // 图标
suitableTemp: string; // 适宜温度
waterNeeds: string; // 水分需求
}
/**
* 推荐模式枚举
*/
export enum RecommendationMode {
HOME_GARDENING = 'HOME_GARDENING', // 家庭园艺模式
PROFESSIONAL_AGRICULTURE = 'PROFESSIONAL_AGRICULTURE' // 专业农业模式
}
2.2 服务类实现
typescript
export class PlantRecommendationService {
private static instance: PlantRecommendationService;
private locationClimateService: LocationClimateService;
private constructor() {
this.locationClimateService = LocationClimateService.getInstance();
}
public static getInstance(): PlantRecommendationService {
if (!PlantRecommendationService.instance) {
PlantRecommendationService.instance = new PlantRecommendationService();
}
return PlantRecommendationService.instance;
}
/**
* 根据位置信息推荐植物
* @param location 位置信息
* @param mode 推荐模式
*/
public getRecommendationsByLocation(
location: LocationInfo,
mode: RecommendationMode = RecommendationMode.HOME_GARDENING
): PlantRecommendation[] {
// 获取气候数据
const climateInfo = this.findClimateInfoByLocation(location);
if (climateInfo) {
return this.getRecommendationsByClimate(climateInfo, mode);
}
// 如果没有找到精确的气候数据,根据省份推荐
return this.getRecommendationsByProvince(location.province, mode);
}
}
2.3 基于气候的推荐算法
专业农业模式推荐
typescript
/**
* 专业农业模式推荐 - 推荐大田作物和经济作物
*/
private getProfessionalAgricultureRecommendations(climate: TownInfo): PlantRecommendation[] {
const recommendations: PlantRecommendation[] = [];
const temp = climate.avgTemperature;
const rainfall = climate.annualRainfall;
// 温带作物(10-20℃)
if (temp >= 10 && temp <= 20) {
if (rainfall >= 800) {
recommendations.push({
plantName: '小麦',
plantType: '粮食作物',
reason: `当地年均温度${temp}℃,降雨量${rainfall}mm,适合小麦规模种植`,
difficulty: '中等',
growthPeriod: '8-10个月',
icon: '🌾',
suitableTemp: '12-22℃',
waterNeeds: '中等'
});
recommendations.push({
plantName: '玉米',
plantType: '粮食作物',
reason: `温暖湿润,玉米产量高,经济效益好`,
difficulty: '简单',
growthPeriod: '4-5个月',
icon: '🌽',
suitableTemp: '15-27℃',
waterNeeds: '中等'
});
}
recommendations.push({
plantName: '马铃薯',
plantType: '经济作物',
reason: `凉爽气候,马铃薯适应性强,市场需求大`,
difficulty: '简单',
growthPeriod: '3-4个月',
icon: '🥔',
suitableTemp: '15-25℃',
waterNeeds: '中等'
});
}
// 亚热带作物(15-25℃)
if (temp >= 15 && temp <= 25) {
if (rainfall >= 1000) {
recommendations.push({
plantName: '水稻',
plantType: '粮食作物',
reason: `温暖多雨,水稻是主要粮食作物,产量稳定`,
difficulty: '中等',
growthPeriod: '4-6个月',
icon: '🌾',
suitableTemp: '20-30℃',
waterNeeds: '高'
});
}
recommendations.push({
plantName: '大豆',
plantType: '经济作物',
reason: `温暖气候,大豆营养丰富,市场价值高`,
difficulty: '简单',
growthPeriod: '3-4个月',
icon: '🫘',
suitableTemp: '20-28℃',
waterNeeds: '中等'
});
recommendations.push({
plantName: '花生',
plantType: '经济作物',
reason: `适宜温度,花生经济效益好,耐旱性强`,
difficulty: '简单',
growthPeriod: '4-5个月',
icon: '🥜',
suitableTemp: '20-30℃',
waterNeeds: '中等'
});
}
// 热带作物(>20℃)
if (temp > 20 && rainfall >= 1500) {
recommendations.push({
plantName: '甘蔗',
plantType: '经济作物',
reason: `高温多雨,甘蔗产量高,制糖原料`,
difficulty: '中等',
growthPeriod: '12-18个月',
icon: '🎋',
suitableTemp: '25-32℃',
waterNeeds: '高'
});
recommendations.push({
plantName: '香蕉',
plantType: '水果',
reason: `热带气候,香蕉生长快,经济价值高`,
difficulty: '中等',
growthPeriod: '10-12个月',
icon: '🍌',
suitableTemp: '24-32℃',
waterNeeds: '高'
});
}
return recommendations.slice(0, 6);
}
推荐逻辑说明:
- 温度匹配:根据年均温度推荐适宜作物
- 降雨量考虑:高降雨地区推荐水稻等喜水作物
- 经济效益:优先推荐市场价值高的作物
- 种植难度:标注难度等级,便于农户选择
2.4 季节性推荐
typescript
/**
* 获取当前季节推荐
* @param mode 推荐模式
*/
public getSeasonalRecommendations(
mode: RecommendationMode = RecommendationMode.HOME_GARDENING
): PlantRecommendation[] {
const month = new Date().getMonth() + 1; // 1-12
const recommendations: PlantRecommendation[] = [];
// 春季(3-5月)
if (month >= 3 && month <= 5) {
recommendations.push(
{
plantName: '番茄',
plantType: '蔬菜',
reason: '春季播种,夏季收获',
difficulty: '简单',
growthPeriod: '3-4个月',
icon: '🍅',
suitableTemp: '15-28℃',
waterNeeds: '中等'
},
{
plantName: '黄瓜',
plantType: '蔬菜',
reason: '春播夏收,生长快',
difficulty: '简单',
growthPeriod: '2-3个月',
icon: '🥒',
suitableTemp: '18-32℃',
waterNeeds: '较高'
}
);
}
// 夏季(6-8月)
if (month >= 6 && month <= 8) {
recommendations.push(
{
plantName: '空心菜',
plantType: '蔬菜',
reason: '耐热速生,夏季主打蔬菜',
difficulty: '简单',
growthPeriod: '1-2个月',
icon: '🥬',
suitableTemp: '25-35℃',
waterNeeds: '高'
},
{
plantName: '丝瓜',
plantType: '蔬菜',
reason: '夏季种植,产量高',
difficulty: '简单',
growthPeriod: '2-3个月',
icon: '🥒',
suitableTemp: '20-30℃',
waterNeeds: '中等'
}
);
}
// 秋季(9-11月)
if (month >= 9 && month <= 11) {
recommendations.push(
{
plantName: '白菜',
plantType: '蔬菜',
reason: '秋季种植,冬季收获',
difficulty: '简单',
growthPeriod: '2-3个月',
icon: '🥬',
suitableTemp: '10-22℃',
waterNeeds: '中等'
},
{
plantName: '萝卜',
plantType: '蔬菜',
reason: '秋播冬收,营养丰富',
difficulty: '简单',
growthPeriod: '2-3个月',
icon: '🥕',
suitableTemp: '15-25℃',
waterNeeds: '中等'
}
);
}
// 冬季(12-2月)
if (month === 12 || month <= 2) {
recommendations.push(
{
plantName: '菠菜',
plantType: '蔬菜',
reason: '耐寒蔬菜,冬季可种',
difficulty: '简单',
growthPeriod: '1-2个月',
icon: '🥬',
suitableTemp: '5-20℃',
waterNeeds: '中等'
},
{
plantName: '大蒜',
plantType: '蔬菜',
reason: '秋冬种植,春季收获',
difficulty: '简单',
growthPeriod: '6-8个月',
icon: '🧄',
suitableTemp: '12-25℃',
waterNeeds: '较低'
}
);
}
return recommendations;
}
三、SolarTermService 节气推荐服务
3.1 节气数据模型
文件位置 :entry/src/main/ets/services/SolarTermService.ets
typescript
export interface SolarTermRecommendation {
solarTerm: string; // 节气名称
period: string; // 时间段
temperature: string; // 温度特点
poem: string; // 代表诗词
poemAuthor: string; // 诗词作者
vegetables: string[]; // 推荐蔬菜
fruits: string[]; // 推荐水果
grains: string[]; // 推荐粮食作物
flowers: string[]; // 推荐花卉
precautions: string[]; // 注意事项
farmWork: string[]; // 农事活动
}
3.2 获取当前节气
typescript
export class SolarTermService {
private static instance: SolarTermService;
public static getInstance(): SolarTermService {
if (!SolarTermService.instance) {
SolarTermService.instance = new SolarTermService();
}
return SolarTermService.instance;
}
/**
* 获取当前节气
*/
public getCurrentSolarTerm(): string {
const now = new Date();
const month = now.getMonth() + 1;
const day = now.getDate();
// 简化的节气判断(基于公历日期)
if (month === 1) {
if (day < 6) return '小寒';
if (day < 20) return '大寒';
return '立春';
} else if (month === 2) {
if (day < 4) return '立春';
if (day < 19) return '雨水';
return '惊蛰';
} else if (month === 3) {
if (day < 6) return '惊蛰';
if (day < 21) return '春分';
return '清明';
} else if (month === 4) {
if (day < 5) return '清明';
if (day < 20) return '谷雨';
return '立夏';
}
// ... 其他月份判断
return '立春';
}
/**
* 获取节气种植推荐
*/
public getSolarTermRecommendation(solarTerm?: string): SolarTermRecommendation {
const term = solarTerm || this.getCurrentSolarTerm();
const recommendations = this.getAllRecommendations();
return recommendations[term] || recommendations['立春'];
}
}
3.3 节气推荐数据示例
typescript
/**
* 获取所有节气推荐数据
*/
private getAllRecommendations(): Record<string, SolarTermRecommendation> {
return {
'立春': {
solarTerm: '立春',
period: '2月3-5日',
temperature: '气温回升,万物复苏',
poem: '律回岁晚冰霜少,春到人间草木知',
poemAuthor: '张栻',
vegetables: ['菠菜', '生菜', '芹菜', '香菜', '小白菜'],
fruits: ['草莓', '枇杷'],
grains: ['春小麦', '春玉米', '早稻'],
flowers: ['迎春花', '水仙', '梅花'],
precautions: [
'注意倒春寒,做好防寒措施',
'及时清理田间杂草',
'检查灌溉设施'
],
farmWork: [
'整地施肥,准备春耕',
'修剪果树,清理枯枝',
'播种耐寒蔬菜',
'检查农机具'
]
},
'雨水': {
solarTerm: '雨水',
period: '2月18-20日',
temperature: '降雨增多,气温回升',
poem: '好雨知时节,当春乃发生',
poemAuthor: '杜甫',
vegetables: ['豌豆', '蚕豆', '韭菜', '茼蒿'],
fruits: ['草莓', '樱桃'],
grains: ['春小麦', '春玉米'],
flowers: ['桃花', '杏花', '梨花'],
precautions: [
'注意排水防涝',
'预防倒春寒',
'加强田间管理'
],
farmWork: [
'春耕备耕',
'播种春季作物',
'果树嫁接',
'追施返青肥'
]
},
'清明': {
solarTerm: '清明',
period: '4月4-6日',
temperature: '气温适宜,雨水充沛',
poem: '清明时节雨纷纷,路上行人欲断魂',
poemAuthor: '杜牧',
vegetables: ['黄瓜', '番茄', '茄子', '辣椒', '豆角'],
fruits: ['樱桃', '草莓', '桑葚'],
grains: ['早稻', '春玉米', '大豆'],
flowers: ['牡丹', '芍药', '杜鹃'],
precautions: [
'注意病虫害防治',
'及时中耕除草',
'做好排水工作'
],
farmWork: [
'播种春季蔬菜',
'移栽秧苗',
'果树授粉',
'茶叶采摘'
]
},
'芒种': {
solarTerm: '芒种',
period: '6月5-7日',
temperature: '气温升高,雨量充沛',
poem: '时雨及芒种,四野皆插秧',
poemAuthor: '陆游',
vegetables: ['空心菜', '苋菜', '丝瓜', '冬瓜'],
fruits: ['西瓜', '荔枝', '杨梅'],
grains: ['晚稻', '夏玉米', '大豆'],
flowers: ['荷花', '栀子花', '茉莉'],
precautions: [
'抢收抢种,不误农时',
'注意防暑降温',
'加强田间管理'
],
farmWork: [
'收获小麦',
'插秧种稻',
'播种夏季作物',
'果树疏果'
]
}
// ... 其他节气数据
};
}
节气推荐特点:
- 结合传统农事经验
- 考虑节气气候特点
- 提供具体农事指导
- 包含文化元素(诗词)
四、智能决策系统
4.1 SmartDecisionPage 页面设计
文件位置 :entry/src/main/ets/pages/Services/SmartDecisionPage.ets
typescript
interface DecisionItem {
title: string;
content: string;
priority: string; // high/medium/low
icon: string;
category: string;
}
@Entry
@ComponentV2
export struct SmartDecisionPage {
@Local decisions: DecisionItem[] = [];
@Local selectedCategory: string = '全部';
@Local isLoading: boolean = true;
private fieldService = FieldService.getInstance();
private weatherService = WeatherService.getInstance();
// 决策类别
private categories: string[] = [
'全部', '产量预测', '种植建议',
'灌溉决策', '施肥方案', '病虫害预警', '收获时机'
];
async aboutToAppear(): Promise<void> {
await this.loadData();
}
async loadData(): Promise<void> {
try {
await this.generateDecisions();
this.isLoading = false;
} catch (error) {
console.error('Failed to load decisions:', error);
this.isLoading = false;
}
}
}
4.2 决策生成算法
typescript
/**
* 生成智能决策建议
*/
async generateDecisions(): Promise<void> {
const decisions: DecisionItem[] = [];
// 1. 基于天气的决策
const weather = await this.weatherService.getCurrentWeather();
if (weather) {
// 高温灌溉提醒
if (weather.temperature > 30) {
decisions.push({
title: '高温灌溉提醒',
content: `当前温度较高(${weather.temperature}°C),建议在清晨或傍晚进行灌溉,避免高温时段`,
priority: 'high',
icon: '💧',
category: '灌溉决策'
});
}
// 高湿度预警
if (weather.humidity > 80) {
decisions.push({
title: '高湿度预警',
content: `当前湿度较高(${weather.humidity}%),注意病虫害防治,保持田间通风`,
priority: 'medium',
icon: '🌧️',
category: '病虫害预警'
});
}
}
// 2. 基于地块数据的决策
const fields = await this.fieldService.getAllFields();
for (const field of fields) {
if (field.currentCrop) {
const growthDays = Math.floor(
(Date.now() - field.currentCrop.plantingDate) / (24 * 60 * 60 * 1000)
);
// 产量预测
if (growthDays > 20) {
const predictedYield = this.calculateYieldPrediction(
field.area,
field.currentCrop.cropName,
growthDays
);
decisions.push({
title: `${field.name} 产量预测`,
content: `${field.currentCrop.cropName}当前生长${growthDays}天,预计总产量约${predictedYield.total}公斤,亩产${predictedYield.perMu}公斤`,
priority: 'medium',
icon: '📊',
category: '产量预测'
});
}
// 收获时机建议
if (field.currentCrop.expectedHarvestDate &&
field.currentCrop.expectedHarvestDate - Date.now() < 7 * 24 * 60 * 60 * 1000) {
decisions.push({
title: `${field.name} 即将收获`,
content: `${field.currentCrop.cropName}种植已${growthDays}天,预计在一周内可以收获`,
priority: 'high',
icon: '🌾',
category: '收获时机'
});
}
// 施肥建议
if (growthDays >= 30 && growthDays <= 40) {
decisions.push({
title: `${field.name} 追肥建议`,
content: `${field.currentCrop.cropName}进入营养生长旺盛期,建议进行追肥`,
priority: 'medium',
icon: '🌿',
category: '施肥方案'
});
}
}
}
// 3. 添加默认建议
if (decisions.length === 0) {
decisions.push({
title: '定期巡查',
content: '建议每周至少巡查一次田地,及时发现和处理问题',
priority: 'low',
icon: '👨🌾',
category: '种植建议'
});
}
this.decisions = decisions;
}
4.3 产量预测算法
typescript
/**
* 计算产量预测
*/
private calculateYieldPrediction(
area: number,
cropName: string,
growthDays: number
): { total: number; perMu: number } {
// 基础亩产数据(公斤/亩)
const baseYieldPerMu: Record<string, number> = {
'小麦': 400,
'水稻': 500,
'玉米': 450,
'大豆': 200,
'花生': 300,
'马铃薯': 1500,
'番茄': 3000,
'黄瓜': 2500,
'白菜': 2000
};
// 获取基础亩产
let perMu = baseYieldPerMu[cropName] || 300;
// 根据生长天数调整(生长周期越接近完成,预测越准确)
const growthFactor = Math.min(growthDays / 100, 1.0);
perMu = perMu * growthFactor;
// 计算总产量
const total = Math.round(perMu * area);
perMu = Math.round(perMu);
return { total, perMu };
}
预测逻辑说明:
- 基础数据:使用作物平均亩产作为基准
- 生长因子:根据生长天数调整预测值
- 面积计算:总产量 = 亩产 × 面积
- 动态调整:可根据实际情况优化算法
五、推荐结果展示
5.1 决策卡片组件
typescript
@Builder
buildDecisionCard(decision: DecisionItem) {
Column({ space: 12 }) {
// 头部:图标和标题
Row({ space: 12 }) {
Text(decision.icon)
.fontSize(32)
Column({ space: 4 }) {
Text(decision.title)
.fontSize(16)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
Text(decision.category)
.fontSize(12)
.fontColor($r('app.color.text_tertiary'))
}
.alignItems(HorizontalAlign.Start)
.layoutWeight(1)
// 优先级标签
Text(this.getPriorityLabel(decision.priority))
.fontSize(11)
.fontColor(this.getPriorityColor(decision.priority))
.padding({ left: 8, right: 8, top: 4, bottom: 4 })
.backgroundColor(this.getPriorityBgColor(decision.priority))
.borderRadius(10)
}
.width('100%')
// 内容
Text(decision.content)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
.lineHeight(22)
.width('100%')
// 操作按钮
Row({ space: 8 }) {
Button('查看详情')
.height(36)
.fontSize(14)
.layoutWeight(1)
.backgroundColor($r('app.color.card_background'))
.fontColor($r('app.color.primary_professional'))
.onClick(() => {
this.showDecisionDetail(decision);
})
Button('标记完成')
.height(36)
.fontSize(14)
.layoutWeight(1)
.backgroundColor($r('app.color.primary_professional'))
.onClick(() => {
this.markAsCompleted(decision);
})
}
.width('100%')
}
.width('100%')
.padding(16)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.shadow({ radius: 4, color: $r('app.color.shadow_light'), offsetY: 2 })
}
/**
* 获取优先级标签
*/
private getPriorityLabel(priority: string): string {
const labels: Record<string, string> = {
'high': '紧急',
'medium': '重要',
'low': '一般'
};
return labels[priority] || '一般';
}
/**
* 获取优先级颜色
*/
private getPriorityColor(priority: string): string {
const colors: Record<string, string> = {
'high': '#F5222D',
'medium': '#FA8C16',
'low': '#52C41A'
};
return colors[priority] || '#52C41A';
}
/**
* 获取优先级背景色
*/
private getPriorityBgColor(priority: string): string {
const bgColors: Record<string, string> = {
'high': '#FFF1F0',
'medium': '#FFF7E6',
'low': '#F6FFED'
};
return bgColors[priority] || '#F6FFED';
}
5.2 类别筛选器
typescript
@Builder
buildCategoryFilter() {
Scroll() {
Row({ space: 8 }) {
ForEach(this.categories, (category: string) => {
Text(category)
.fontSize(14)
.fontColor(this.selectedCategory === category ?
Color.White : $r('app.color.text_primary'))
.padding({ left: 16, right: 16, top: 8, bottom: 8 })
.backgroundColor(this.selectedCategory === category ?
$r('app.color.primary_professional') : $r('app.color.card_background'))
.borderRadius(16)
.onClick(() => {
this.selectedCategory = category;
})
})
}
.padding({ left: 16, right: 16, top: 16 })
}
.scrollable(ScrollDirection.Horizontal)
.scrollBar(BarState.Off)
.width('100%')
.margin({ bottom: 16 })
}
/**
* 获取筛选后的决策
*/
private getFilteredDecisions(): DecisionItem[] {
if (this.selectedCategory === '全部') {
return this.decisions;
}
return this.decisions.filter(d => d.category === this.selectedCategory);
}
六、推荐系统集成
6.1 在服务页面集成推荐
文件位置 :entry/src/main/ets/pages/Services/ServicesPage.ets
typescript
@Entry
@ComponentV2
export struct ServicesPage {
@Local recommendations: PlantRecommendation[] = [];
@Local currentSolarTerm: string = '';
private plantRecommendationService = PlantRecommendationService.getInstance();
private solarTermService = SolarTermService.getInstance();
async aboutToAppear(): Promise<void> {
await this.loadRecommendations();
}
async loadRecommendations(): Promise<void> {
// 获取季节推荐
this.recommendations = this.plantRecommendationService.getSeasonalRecommendations(
RecommendationMode.PROFESSIONAL_AGRICULTURE
);
// 获取当前节气
this.currentSolarTerm = this.solarTermService.getCurrentSolarTerm();
}
build() {
Column() {
// 推荐卡片
this.buildRecommendationSection()
// 服务功能列表
this.buildServiceList()
}
.width('100%')
.height('100%')
}
@Builder
buildRecommendationSection() {
Column({ space: 12 }) {
Row() {
Text('🌱 智能推荐')
.fontSize(18)
.fontWeight(FontWeight.Bold)
.layoutWeight(1)
Text('查看更多 >')
.fontSize(14)
.fontColor($r('app.color.primary_professional'))
.onClick(() => {
router.pushUrl({
url: 'pages/Services/SmartDecisionPage'
});
})
}
.width('100%')
.padding({ left: 16, right: 16 })
// 当前节气
Row({ space: 8 }) {
Text('📅')
.fontSize(20)
Text(`当前节气:${this.currentSolarTerm}`)
.fontSize(14)
.fontColor($r('app.color.text_secondary'))
}
.width('100%')
.padding({ left: 16, right: 16 })
// 推荐列表
Scroll() {
Row({ space: 12 }) {
ForEach(this.recommendations.slice(0, 3), (item: PlantRecommendation) => {
this.buildRecommendationCard(item)
})
}
.padding({ left: 16, right: 16 })
}
.scrollable(ScrollDirection.Horizontal)
.scrollBar(BarState.Off)
.width('100%')
}
.width('100%')
.padding({ top: 16, bottom: 16 })
.backgroundColor($r('app.color.background'))
}
@Builder
buildRecommendationCard(item: PlantRecommendation) {
Column({ space: 8 }) {
Text(item.icon)
.fontSize(40)
Text(item.plantName)
.fontSize(15)
.fontWeight(FontWeight.Bold)
.fontColor($r('app.color.text_primary'))
Text(item.plantType)
.fontSize(12)
.fontColor($r('app.color.text_tertiary'))
Text(item.growthPeriod)
.fontSize(11)
.fontColor($r('app.color.text_secondary'))
.padding({ left: 8, right: 8, top: 3, bottom: 3 })
.backgroundColor($r('app.color.background'))
.borderRadius(10)
}
.width(120)
.padding(12)
.backgroundColor($r('app.color.card_background'))
.borderRadius(12)
.onClick(() => {
this.showRecommendationDetail(item);
})
}
}
6.2 推荐详情对话框
typescript
/**
* 显示推荐详情
*/
private showRecommendationDetail(item: PlantRecommendation): void {
AlertDialog.show({
title: `${item.icon} ${item.plantName}`,
message: `
类型:${item.plantType}
难度:${item.difficulty}
周期:${item.growthPeriod}
温度:${item.suitableTemp}
水分:${item.waterNeeds}
推荐理由:
${item.reason}
`,
primaryButton: {
value: '添加到种植计划',
action: () => {
this.addToPlantingPlan(item);
}
},
secondaryButton: {
value: '关闭',
action: () => {}
}
});
}
/**
* 添加到种植计划
*/
private async addToPlantingPlan(item: PlantRecommendation): Promise<void> {
// 跳转到添加作物页面,预填充推荐信息
router.pushUrl({
url: 'pages/Management/AddCropPage',
params: {
recommendedCrop: item.plantName,
cropType: item.plantType
}
});
}
七、实操练习
练习1:添加基于地块的推荐
任务:根据地块特征(土壤、灌溉、面积)推荐合适作物
提示:
- 在
PlantRecommendationService中添加getRecommendationsByField方法 - 考虑土壤类型、灌溉条件、地块面积
- 返回最适合的3-5个作物
参考代码:
typescript
/**
* 根据地块特征推荐作物
*/
public getRecommendationsByField(field: FieldInfo): PlantRecommendation[] {
const recommendations: PlantRecommendation[] = [];
// 根据土壤类型推荐
if (field.soilType === '黑土') {
recommendations.push({
plantName: '玉米',
plantType: '粮食作物',
reason: '黑土肥沃,适合玉米生长',
difficulty: '简单',
growthPeriod: '4-5个月',
icon: '🌽',
suitableTemp: '15-27℃',
waterNeeds: '中等'
});
}
// 根据灌溉条件推荐
if (field.irrigation === IrrigationSystem.DRIP) {
recommendations.push({
plantName: '番茄',
plantType: '蔬菜',
reason: '滴灌系统适合番茄精细化管理',
difficulty: '简单',
growthPeriod: '3-4个月',
icon: '🍅',
suitableTemp: '15-28℃',
waterNeeds: '中等'
});
}
return recommendations;
}
练习2:添加历史数据分析
任务:基于历史种植记录,推荐表现良好的作物
提示:
- 分析历史产量数据
- 计算作物成功率
- 推荐高产、稳定的作物
参考代码:
typescript
/**
* 基于历史数据推荐
*/
public async getRecommendationsByHistory(): Promise<PlantRecommendation[]> {
const fields = await this.fieldService.getAllFields();
const cropStats: Map<string, { count: number; avgYield: number }> = new Map();
// 统计历史数据
for (const field of fields) {
if (field.currentCrop) {
const cropName = field.currentCrop.cropName;
const stats = cropStats.get(cropName) || { count: 0, avgYield: 0 };
stats.count++;
// 这里可以添加实际产量统计
cropStats.set(cropName, stats);
}
}
// 推荐种植次数多的作物
const recommendations: PlantRecommendation[] = [];
cropStats.forEach((stats, cropName) => {
if (stats.count >= 2) {
recommendations.push({
plantName: cropName,
plantType: '经验作物',
reason: `您已成功种植${stats.count}次,经验丰富`,
difficulty: '简单',
growthPeriod: '根据作物而定',
icon: '🌾',
suitableTemp: '根据作物而定',
waterNeeds: '中等'
});
}
});
return recommendations;
}
练习3:添加市场价格推荐
任务:结合市场价格,推荐经济效益好的作物
提示:
- 维护作物市场价格数据
- 计算预期收益
- 推荐高收益作物
八、常见问题
问题1:推荐结果不准确
原因:
- 数据不完整或不准确
- 推荐算法过于简单
- 未考虑地域差异
解决方案:
typescript
// 添加数据验证
public getRecommendationsByLocation(
location: LocationInfo,
mode: RecommendationMode
): PlantRecommendation[] {
// 验证位置信息
if (!location || !location.province) {
console.warn('Invalid location info, using default recommendations');
return this.getDefaultRecommendations(mode);
}
// 获取气候数据
const climateInfo = this.findClimateInfoByLocation(location);
if (!climateInfo) {
console.warn(`No climate data for ${location.province}, using province-based recommendations`);
return this.getRecommendationsByProvince(location.province, mode);
}
return this.getRecommendationsByClimate(climateInfo, mode);
}
/**
* 获取默认推荐
*/
private getDefaultRecommendations(mode: RecommendationMode): PlantRecommendation[] {
// 返回适应性强的作物
return [
{
plantName: '小葱',
plantType: '蔬菜',
reason: '适应性强,四季可种',
difficulty: '简单',
growthPeriod: '1-2个月',
icon: '🧅',
suitableTemp: '12-28℃',
waterNeeds: '中等'
}
];
}
问题2:节气判断不准确
原因:
- 简化的节气计算方法
- 未考虑闰年
- 公历与农历转换误差
解决方案:
typescript
/**
* 精确计算节气(使用天文算法)
*/
public getAccurateSolarTerm(): string {
const now = new Date();
const year = now.getFullYear();
// 使用寿星天文历算法计算节气
// 这里简化处理,实际应用可以使用专业的农历库
const solarTermDates = this.calculateSolarTermDates(year);
for (const [term, date] of Object.entries(solarTermDates)) {
if (now >= date && now < this.getNextTermDate(term, solarTermDates)) {
return term;
}
}
return '立春';
}
问题3:产量预测偏差大
原因:
- 使用固定的基础数据
- 未考虑实际种植条件
- 缺少历史数据支持
解决方案:
typescript
/**
* 改进的产量预测算法
*/
private calculateYieldPrediction(
area: number,
cropName: string,
growthDays: number,
field: FieldInfo
): { total: number; perMu: number } {
// 基础亩产
let perMu = this.getBaseYield(cropName);
// 土壤因子(0.8-1.2)
const soilFactor = this.getSoilFactor(field.soilType);
perMu *= soilFactor;
// 灌溉因子(0.9-1.1)
const irrigationFactor = this.getIrrigationFactor(field.irrigation);
perMu *= irrigationFactor;
// 生长因子(0-1.0)
const growthFactor = Math.min(growthDays / this.getOptimalGrowthDays(cropName), 1.0);
perMu *= growthFactor;
// 天气因子(基于历史天气数据)
const weatherFactor = await this.getWeatherFactor(field.id);
perMu *= weatherFactor;
const total = Math.round(perMu * area);
perMu = Math.round(perMu);
return { total, perMu };
}
/**
* 获取土壤因子
*/
private getSoilFactor(soilType: string): number {
const factors: Record<string, number> = {
'黑土': 1.2,
'黄土': 1.0,
'红土': 0.9,
'沙土': 0.8
};
return factors[soilType] || 1.0;
}
/**
* 获取灌溉因子
*/
private getIrrigationFactor(irrigation: IrrigationSystem): number {
const factors: Record<string, number> = {
[IrrigationSystem.DRIP]: 1.1,
[IrrigationSystem.SPRINKLER]: 1.05,
[IrrigationSystem.FURROW]: 1.0,
[IrrigationSystem.NONE]: 0.9
};
return factors[irrigation] || 1.0;
}
九、功能扩展建议
1. 机器学习推荐
功能描述:
- 使用机器学习算法优化推荐
- 基于用户行为学习偏好
- 持续优化推荐准确度
实现思路:
typescript
/**
* 基于机器学习的推荐(概念示例)
*/
class MLRecommendationEngine {
private userPreferences: Map<string, number> = new Map();
/**
* 记录用户选择
*/
recordUserChoice(cropName: string, accepted: boolean): void {
const score = this.userPreferences.get(cropName) || 0;
this.userPreferences.set(cropName, score + (accepted ? 1 : -1));
}
/**
* 获取个性化推荐
*/
getPersonalizedRecommendations(
baseRecommendations: PlantRecommendation[]
): PlantRecommendation[] {
// 根据用户偏好排序
return baseRecommendations.sort((a, b) => {
const scoreA = this.userPreferences.get(a.plantName) || 0;
const scoreB = this.userPreferences.get(b.plantName) || 0;
return scoreB - scoreA;
});
}
}
2. 协同过滤推荐
功能描述:
- 基于相似用户的选择推荐
- "种植这个作物的用户还种植了..."
- 社区推荐功能
实现思路:
typescript
/**
* 协同过滤推荐
*/
class CollaborativeFiltering {
/**
* 获取相似用户推荐
*/
async getSimilarUsersRecommendations(
userId: string
): Promise<PlantRecommendation[]> {
// 1. 找到相似用户
const similarUsers = await this.findSimilarUsers(userId);
// 2. 统计他们的种植选择
const cropCounts: Map<string, number> = new Map();
for (const user of similarUsers) {
const crops = await this.getUserCrops(user.id);
crops.forEach(crop => {
cropCounts.set(crop, (cropCounts.get(crop) || 0) + 1);
});
}
// 3. 推荐热门作物
const recommendations: PlantRecommendation[] = [];
cropCounts.forEach((count, cropName) => {
if (count >= 3) {
recommendations.push(this.getCropRecommendation(cropName, count));
}
});
return recommendations;
}
}
3. 实时市场价格集成
功能描述:
- 集成农产品市场价格API
- 实时更新价格信息
- 推荐高收益作物
实现思路:
typescript
/**
* 市场价格服务
*/
class MarketPriceService {
/**
* 获取作物市场价格
*/
async getCropPrice(cropName: string): Promise<number> {
// 调用市场价格API
const response = await fetch(`https://api.example.com/price/${cropName}`);
const data = await response.json();
return data.price;
}
/**
* 计算预期收益
*/
async calculateExpectedRevenue(
cropName: string,
area: number,
yieldPerMu: number
): Promise<number> {
const price = await this.getCropPrice(cropName);
const totalYield = area * yieldPerMu;
return totalYield * price;
}
/**
* 推荐高收益作物
*/
async getHighRevenueRecommendations(
area: number
): Promise<PlantRecommendation[]> {
const crops = ['小麦', '玉米', '大豆', '花生'];
const recommendations: Array<PlantRecommendation & { revenue: number }> = [];
for (const crop of crops) {
const yieldPerMu = this.getAverageYield(crop);
const revenue = await this.calculateExpectedRevenue(crop, area, yieldPerMu);
recommendations.push({
plantName: crop,
plantType: '经济作物',
reason: `预期收益:¥${revenue}`,
difficulty: '中等',
growthPeriod: '根据作物而定',
icon: '💰',
suitableTemp: '根据作物而定',
waterNeeds: '中等',
revenue
});
}
// 按收益排序
return recommendations.sort((a, b) => b.revenue - a.revenue);
}
}
4. 风险评估系统
功能描述:
- 评估种植风险
- 预警极端天气影响
- 提供风险规避建议
实现思路:
typescript
/**
* 风险评估服务
*/
class RiskAssessmentService {
/**
* 评估种植风险
*/
async assessPlantingRisk(
cropName: string,
field: FieldInfo
): Promise<{ level: string; factors: string[] }> {
const riskFactors: string[] = [];
let riskScore = 0;
// 气候风险
const weather = await this.weatherService.getForecast(7);
if (weather.some(w => w.temperature > 35)) {
riskFactors.push('未来一周有高温天气');
riskScore += 2;
}
// 病虫害风险
if (this.isPestSeason(cropName)) {
riskFactors.push('当前是病虫害高发期');
riskScore += 1;
}
// 市场风险
const priceVolatility = await this.getPriceVolatility(cropName);
if (priceVolatility > 0.3) {
riskFactors.push('市场价格波动较大');
riskScore += 1;
}
// 确定风险等级
let level = '低';
if (riskScore >= 3) level = '高';
else if (riskScore >= 2) level = '中';
return { level, factors: riskFactors };
}
}
十、本篇总结
10.1 核心知识点
本篇教程完整实现了智能推荐系统,涵盖以下核心内容:
-
推荐算法设计
- 基于气候的推荐算法
- 基于季节的推荐算法
- 基于节气的推荐算法
- 基于地块的推荐算法
-
数据整合
- 气候数据
- 地块数据
- 节气数据
- 历史数据
-
智能决策
- 产量预测模型
- 农事时机判断
- 风险评估
- 优化建议生成
-
UI展示
- 推荐卡片设计
- 类别筛选
- 详情展示
- 交互优化
10.2 技术要点
- ✅ 多维度推荐:整合气候、地块、节气等多维度数据
- ✅ 规则引擎:基于规则的推荐算法实现
- ✅ 数据分析:产量预测、风险评估等分析功能
- ✅ 用户体验:直观的推荐展示和交互设计
- ✅ 可扩展性:易于添加新的推荐维度和算法
10.3 实际应用价值
智能推荐系统解决了以下实际问题:
- 降低决策难度:为农户提供科学的种植建议
- 提高种植成功率:推荐适合当地的作物
- 优化资源配置:根据地块特征合理安排种植
- 提升经济效益:推荐高产、高收益作物
- 传承农事经验:结合节气等传统农事智慧
10.4 下一篇预告
第24篇:学习中心 - 课程体系设计
下一篇将实现学习中心功能,包括:
- 📚 课程分类体系设计
- 📖 课程列表展示
- 🎓 学习进度管理
- 🏆 学习成就系统
- 📝 学习笔记功能
附录:完整代码文件清单
服务层
entry/src/main/ets/services/PlantRecommendationService.ets- 作物推荐服务entry/src/main/ets/services/SolarTermService.ets- 节气服务entry/src/main/ets/services/LocationClimateService.ets- 气候服务
页面层
entry/src/main/ets/pages/Services/SmartDecisionPage.ets- 智能决策页面entry/src/main/ets/pages/Services/ServicesPage.ets- 服务页面