Selaa lähdekoodia

feat: new tab3

lfgldr 1 viikko sitten
vanhempi
commit
a6ac06ec68

+ 42 - 52
myapp/src/app/tab3/tab3.page.html

@@ -42,6 +42,17 @@
           </ion-select>
         </ion-item>
 
+        <ion-item>
+          <ion-label>作物阶段</ion-label>
+          <ion-select formControlName="growthStage">
+            <ion-select-option value="播种期">播种期</ion-select-option>
+            <ion-select-option value="苗期">苗期</ion-select-option>
+            <ion-select-option value="生长期">生长期</ion-select-option>
+            <ion-select-option value="成熟期">成熟期</ion-select-option>
+            <ion-select-option value="收获期">收获期</ion-select-option>
+          </ion-select>
+        </ion-item>
+
         <ion-item>
           <ion-label>土壤类型</ion-label>
           <ion-select formControlName="soilType">
@@ -78,9 +89,33 @@
           <p>种植面积</p>
         </div>
         <div class="summary-item">
-          <ion-icon name="alarm" color="warning"></ion-icon>
-          <h3>{{ pendingTasks }}</h3>
-          <p>待办农事</p>
+          <ion-icon name="stats-chart" color="warning"></ion-icon>
+          <h3>{{ cropDistribution.length }}</h3>
+          <p>作物种类</p>
+        </div>
+      </div>
+    </ion-card-content>
+  </ion-card>
+
+  <!-- 作物分布 -->
+  <ion-card *ngIf="fields.length > 0" class="crops-card">
+    <ion-card-header>
+      <ion-card-title>
+        <ion-icon name="pie-chart" color="primary"></ion-icon>
+        作物分布
+      </ion-card-title>
+    </ion-card-header>
+    <ion-card-content>
+      <div class="crops-grid">
+        <div class="crop-item" *ngFor="let crop of cropDistribution">
+          <div class="crop-icon">
+            <img [src]="getCropImage(crop.name)">
+          </div>
+          <div class="crop-info">
+            <h4>{{ crop.name }}</h4>
+            <p>{{ crop.area }}亩 ({{ crop.percentage }}%)</p>
+            <ion-progress-bar [value]="crop.percentage/100" [color]="getCropColor(crop.name)"></ion-progress-bar>
+          </div>
         </div>
       </div>
     </ion-card-content>
@@ -97,14 +132,14 @@
           <h2>{{ field.name }}</h2>
           <p>{{ field.area }}亩 • {{ field.currentCrop }}</p>
           <p class="field-status">
-            <ion-badge *ngIf="field.status" [color]="getStatusColor(field.status)">
-              {{ field.status }}
+            <ion-badge [color]="getStageColor(field.growthStage)">
+              {{ field.growthStage }}
             </ion-badge>
             <span>种植 {{ field.daysPlanted }}天</span>
           </p>
         </ion-label>
         <ion-note slot="end">
-          {{ field.nextTask || '暂无农事' }}
+          {{ getStageDays(field.growthStage) }}天
         </ion-note>
       </ion-item>
       <ion-item-options side="end">
@@ -121,49 +156,4 @@
     <p>您还没有添加农田地块</p>
     <ion-button fill="outline" (click)="toggleFieldForm()">添加第一块地</ion-button>
   </div>
-
-  <!-- 农事提醒 -->
-  <ion-card class="task-card" *ngIf="fields.length > 0">
-    <ion-card-header>
-      <ion-card-title>
-        <ion-icon name="notifications" color="warning"></ion-icon>
-        近期农事提醒
-      </ion-card-title>
-    </ion-card-header>
-    <ion-card-content>
-      <ion-list>
-        <ion-item *ngFor="let task of recentTasks" (click)="viewTaskDetail(task)">
-          <ion-icon [name]="getTaskIcon(task.type)" slot="start" [color]="getTaskColor(task.type)"></ion-icon>
-          <ion-label>
-            <h3>{{ task.fieldName }}:{{ task.name }}</h3>
-            <p>{{ task.dueDate | date:'MM月dd日' }} • {{ task.notes || '暂无备注' }}</p>
-          </ion-label>
-          <ion-badge slot="end" [color]="task.urgent ? 'danger' : 'medium'">
-            {{ task.urgent ? '紧急' : '常规' }}
-          </ion-badge>
-        </ion-item>
-      </ion-list>
-    </ion-card-content>
-  </ion-card>
-
-  <!-- 生长记录 -->
-  <ion-card *ngIf="fields.length > 0">
-    <ion-card-header>
-      <ion-card-title>
-        <ion-icon name="calendar" color="primary"></ion-icon>
-        近期生长记录
-      </ion-card-title>
-    </ion-card-header>
-    <ion-card-content>
-      <div class="record-timeline">
-        <div class="record-item" *ngFor="let record of recentRecords">
-          <div class="record-date">{{ record.date | date:'MM.dd' }}</div>
-          <div class="record-content">
-            <h4>{{ record.fieldName }} {{ record.activity }}</h4>
-            <p>{{ record.notes }}</p>
-          </div>
-        </div>
-      </div>
-    </ion-card-content>
-  </ion-card>
-</ion-content>
+</ion-content>

+ 55 - 94
myapp/src/app/tab3/tab3.page.scss

@@ -51,6 +51,61 @@
   }
 }
 
+/* 作物分布卡片 */
+.crops-card {
+  margin: 15px 10px;
+  border-radius: 12px;
+
+  .crops-grid {
+    display: grid;
+    gap: 12px;
+
+    .crop-item {
+      display: flex;
+      align-items: center;
+      padding: 8px 0;
+
+      .crop-icon {
+        width: 50px;
+        height: 50px;
+        margin-right: 12px;
+        background: var(--ion-color-light-shade);
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+
+        img {
+          width: 30px;
+          height: 30px;
+          object-fit: contain;
+        }
+      }
+
+      .crop-info {
+        flex: 1;
+
+        h4 {
+          margin: 0 0 4px;
+          font-size: 0.95rem;
+        }
+
+        p {
+          margin: 0 0 4px;
+          font-size: 0.8rem;
+          color: var(--ion-color-medium);
+        }
+
+        ion-progress-bar {
+          margin-top: 4px;
+          height: 6px;
+          border-radius: 3px;
+        }
+      }
+    }
+  }
+}
+
 /* 地块列表 */
 ion-list {
   background: transparent;
@@ -115,98 +170,4 @@ ion-list {
     color: var(--ion-color-medium);
     margin-bottom: 20px;
   }
-}
-
-/* 农事提醒卡片 */
-.task-card {
-  margin: 15px 10px;
-
-  ion-item {
-    --padding-start: 0;
-    --inner-padding-end: 0;
-    --border-radius: 8px;
-    margin-bottom: 8px;
-
-    ion-icon {
-      font-size: 1.5rem;
-    }
-
-    h3 {
-      font-size: 0.95rem;
-      margin-bottom: 3px;
-    }
-
-    p {
-      font-size: 0.8rem;
-      color: var(--ion-color-medium);
-    }
-  }
-}
-
-/* 生长记录时间线 */
-.record-timeline {
-  padding-left: 20px;
-  position: relative;
-
-  &::before {
-    content: '';
-    position: absolute;
-    left: 6px;
-    top: 0;
-    bottom: 0;
-    width: 2px;
-    background: var(--ion-color-light-shade);
-  }
-
-  .record-item {
-    position: relative;
-    padding-bottom: 15px;
-
-    &::before {
-      content: '';
-      position: absolute;
-      left: -20px;
-      top: 5px;
-      width: 10px;
-      height: 10px;
-      border-radius: 50%;
-      background: var(--ion-color-primary);
-    }
-
-    .record-date {
-      font-weight: bold;
-      color: var(--ion-color-primary);
-      margin-bottom: 5px;
-    }
-
-    .record-content {
-      background: var(--ion-color-light);
-      padding: 10px;
-      border-radius: 8px;
-
-      h4 {
-        margin: 0 0 5px;
-        font-size: 0.9rem;
-      }
-
-      p {
-        margin: 0 0 8px;
-        font-size: 0.8rem;
-        color: var(--ion-color-medium);
-      }
-
-      .record-images {
-        display: flex;
-        gap: 5px;
-        overflow-x: auto;
-
-        ion-thumbnail {
-          width: 60px;
-          height: 60px;
-          border-radius: 5px;
-          overflow: hidden;
-        }
-      }
-    }
-  }
 }

+ 53 - 90
myapp/src/app/tab3/tab3.page.ts

@@ -9,32 +9,15 @@ interface FarmField {
   area: number;
   location: string;
   currentCrop: string;
+  growthStage: string;
   daysPlanted: number;
-  status?: '需灌溉' | '需施肥' | '需防治' | '正常';
-  nextTask?: string;
   soilType?: string;
 }
 
-interface FarmTask {
-  id: string;
-  fieldId: string;
-  fieldName: string;
+interface CropDistribution {
   name: string;
-  type: 'irrigation' | 'fertilization' | 'pestControl' | 'harvest';
-  dueDate: Date;
-  notes?: string;
-  urgent: boolean;
-  completed: boolean;
-}
-
-interface GrowthRecord {
-  id: string;
-  fieldId: string;
-  fieldName: string;
-  date: Date;
-  activity: string;
-  notes: string;
-  images?: string[];
+  area: number;
+  percentage: number;
 }
 
 @Component({
@@ -44,10 +27,7 @@ interface GrowthRecord {
   standalone: false,
 })
 export class Tab3Page implements OnInit {
-  fields: FarmField[] = []; // 初始化为空数组,从后端加载数据
-  tasks: FarmTask[] = [];
-  records: GrowthRecord[] = [];
-
+  fields: FarmField[] = [];
   showFieldForm = false;
   editingField: FarmField | null = null;
   fieldForm: FormGroup;
@@ -63,16 +43,16 @@ export class Tab3Page implements OnInit {
       area: ['', [Validators.required, Validators.min(0.1)]],
       location: [''],
       currentCrop: ['冬小麦', Validators.required],
+      growthStage: ['播种期', Validators.required],
       soilType: ['粘壤土']
     });
   }
 
   async ngOnInit() {
     await this.loadFields();
-    await this.initializeSampleData(); // 可选:初始化示例数据
+    await this.initializeSampleData();
   }
 
-  // 从后端加载农田数据
   async loadFields() {
     try {
       const cloudFields = await this.cloudQuery.find();
@@ -82,8 +62,8 @@ export class Tab3Page implements OnInit {
         area: field.get('area'),
         location: field.get('location'),
         currentCrop: field.get('currentCrop'),
+        growthStage: field.get('growthStage') || '播种期',
         daysPlanted: field.get('daysPlanted') || 0,
-        status: field.get('status') || '正常',
         soilType: field.get('soilType')
       }));
     } catch (error) {
@@ -91,7 +71,6 @@ export class Tab3Page implements OnInit {
     }
   }
 
-  // 保存农田到后端
   async saveField() {
     if (this.fieldForm.invalid) return;
 
@@ -99,36 +78,31 @@ export class Tab3Page implements OnInit {
     const fieldObject = new CloudObject('FarmField');
 
     if (this.editingField && this.editingField.id) {
-      // 更新现有农田
       fieldObject.id = this.editingField.id;
       fieldObject.set(fieldData);
       await fieldObject.save();
     } else {
-      // 添加新农田
       fieldObject.set({
         ...fieldData,
-        daysPlanted: 0,
-        status: '正常'
+        daysPlanted: 0
       });
       const savedField = await fieldObject.save();
 
       this.fields.push({
         id: savedField.id || '',
         daysPlanted: 0,
-        status: '正常',
         ...fieldData
       });
     }
 
-    await this.loadFields(); // 重新加载数据确保同步
+    await this.loadFields();
     this.cancelEdit();
   }
 
-  // 删除农田
   async deleteField(fieldId: string) {
     const alert = await this.alertCtrl.create({
       header: '确认删除',
-      message: '确定要删除这个农田地块吗?相关记录也将被删除',
+      message: '确定要删除这个农田地块吗?',
       buttons: [
         {
           text: '取消',
@@ -142,8 +116,6 @@ export class Tab3Page implements OnInit {
             await fieldObject.destroy();
 
             this.fields = this.fields.filter(f => f.id !== fieldId);
-            this.tasks = this.tasks.filter(t => t.fieldId !== fieldId);
-            this.records = this.records.filter(r => r.fieldId !== fieldId);
           }
         }
       ]
@@ -152,7 +124,6 @@ export class Tab3Page implements OnInit {
     await alert.present();
   }
 
-  // 初始化示例数据(可选)
   async initializeSampleData() {
     const query = new CloudQuery('FarmField');
     const existingFields = await query.find();
@@ -164,9 +135,8 @@ export class Tab3Page implements OnInit {
           area: 5.2,
           location: '农场北侧',
           currentCrop: '冬小麦',
+          growthStage: '生长期',
           daysPlanted: 45,
-          status: '需施肥',
-          nextTask: '明日追肥',
           soilType: '粘壤土'
         },
         {
@@ -174,9 +144,8 @@ export class Tab3Page implements OnInit {
           area: 3.8,
           location: '农场南侧',
           currentCrop: '春玉米',
+          growthStage: '苗期',
           daysPlanted: 22,
-          status: '正常',
-          nextTask: '下周除草',
           soilType: '砂壤土'
         }
       ];
@@ -187,33 +156,28 @@ export class Tab3Page implements OnInit {
         await fieldObject.save();
       }
 
-      // 重新加载数据
       await this.loadFields();
     }
   }
 
-
-  // 原有代码不变
-
   get totalArea(): number {
     return this.fields.reduce((sum, field) => sum + field.area, 0);
   }
 
-  get pendingTasks(): number {
-    return this.tasks.filter(t => !t.completed).length;
-  }
-
-  get recentTasks(): FarmTask[] {
-    return this.tasks
-      .filter(t => !t.completed)
-      .sort((a, b) => a.dueDate.getTime() - b.dueDate.getTime())
-      .slice(0, 3);
-  }
+  get cropDistribution(): CropDistribution[] {
+    const cropMap = new Map<string, number>();
+    
+    this.fields.forEach(field => {
+      const current = cropMap.get(field.currentCrop) || 0;
+      cropMap.set(field.currentCrop, current + field.area);
+    });
 
-  get recentRecords(): GrowthRecord[] {
-    return [...this.records]
-      .sort((a, b) => b.date.getTime() - a.date.getTime())
-      .slice(0, 4);
+    const total = this.totalArea;
+    return Array.from(cropMap.entries()).map(([name, area]) => ({
+      name,
+      area,
+      percentage: Math.round((area / total) * 100)
+    }));
   }
 
   getCropImage(crop: string): string {
@@ -226,34 +190,36 @@ export class Tab3Page implements OnInit {
     return cropImages[crop] || 'assets/images/crop-default.png';
   }
 
-  getStatusColor(status: string): string {
-    const statusColors: {[key: string]: string} = {
-      '需灌溉': 'primary',
-      '需施肥': 'warning',
-      '需防治': 'danger',
-      '正常': 'success'
+  getCropColor(crop: string): string {
+    const cropColors: {[key: string]: string} = {
+      '冬小麦': 'primary',
+      '春玉米': 'warning',
+      '水稻': 'success',
+      '大豆': 'tertiary'
     };
-    return statusColors[status] || 'medium';
+    return cropColors[crop] || 'medium';
   }
 
-  getTaskIcon(type: string): string {
-    const taskIcons: {[key: string]: string} = {
-      'irrigation': 'water',
-      'fertilization': 'nutrition',
-      'pestControl': 'bug',
-      'harvest': 'leaf'
+  getStageColor(stage: string): string {
+    const stageColors: {[key: string]: string} = {
+      '播种期': 'primary',
+      '苗期': 'success',
+      '生长期': 'warning',
+      '成熟期': 'danger',
+      '收获期': 'tertiary'
     };
-    return taskIcons[type] || 'alert-circle';
+    return stageColors[stage] || 'medium';
   }
 
-  getTaskColor(type: string): string {
-    const taskColors: {[key: string]: string} = {
-      'irrigation': 'primary',
-      'fertilization': 'warning',
-      'pestControl': 'danger',
-      'harvest': 'success'
+  getStageDays(stage: string): number {
+    const stageDays: {[key: string]: number} = {
+      '播种期': 10,
+      '苗期': 20,
+      '生长期': 30,
+      '成熟期': 15,
+      '收获期': 5
     };
-    return taskColors[type] || 'medium';
+    return stageDays[stage] || 0;
   }
 
   toggleFieldForm() {
@@ -262,6 +228,7 @@ export class Tab3Page implements OnInit {
       this.editingField = null;
       this.fieldForm.reset({
         currentCrop: '冬小麦',
+        growthStage: '播种期',
         soilType: '粘壤土'
       });
     }
@@ -274,23 +241,19 @@ export class Tab3Page implements OnInit {
       area: field.area,
       location: field.location,
       currentCrop: field.currentCrop,
+      growthStage: field.growthStage,
       soilType: field.soilType
     });
     this.showFieldForm = true;
   }
 
-
   cancelEdit() {
     this.showFieldForm = false;
     this.editingField = null;
     this.fieldForm.reset({
       currentCrop: '冬小麦',
+      growthStage: '播种期',
       soilType: '粘壤土'
     });
   }
-
-  viewTaskDetail(task: FarmTask) {
-    console.log('查看任务详情:', task);
-    // 实际应导航到任务详情页
-  }
-}
+}

+ 3 - 0
myapp/src/lib/ncloud.ts

@@ -81,6 +81,9 @@ export class CloudObject {
 
 // CloudQuery.ts
 export class CloudQuery {
+    limit(arg0: number) {
+      throw new Error('Method not implemented.');
+    }
     className: string;
     queryParams: Record<string, any> = {};