Sfoglia il codice sorgente

日常学习计划

15270821319 6 mesi fa
parent
commit
d1d27f6216

+ 4 - 0
AiStudy-app/src/app/app.routes.ts

@@ -59,5 +59,9 @@ export const routes: Routes = [
     path: 'custom-teacher/:id',
     loadComponent: () => import('./components/custom-teacher-detail/custom-teacher-detail.component')
       .then(m => m.CustomTeacherDetailComponent)
+  },
+  {
+    path: 'daily-plan',
+    loadComponent: () => import('./pages/daily-plan/daily-plan.page').then(m => m.DailyPlanPage)
   }
 ];

+ 75 - 0
AiStudy-app/src/app/pages/daily-plan/daily-plan.page.html

@@ -0,0 +1,75 @@
+<ion-header>
+  <ion-toolbar>
+    <ion-buttons slot="start">
+      <ion-back-button defaultHref="/tabs/tab2"></ion-back-button>
+    </ion-buttons>
+    <ion-title>日常学习计划</ion-title>
+    <ion-buttons slot="end">
+      <ion-button (click)="addNewPlan()">
+        <ion-icon name="add-outline"></ion-icon>
+      </ion-button>
+    </ion-buttons>
+  </ion-toolbar>
+</ion-header>
+
+<ion-content class="ion-padding">
+  <!-- 日历组件 -->
+  <ion-card>
+    <ion-card-content>
+      <ion-datetime
+        [value]="selectedDate"
+        (ionChange)="onDateChange($event)"
+        presentation="date"
+        locale="zh-CN"
+        [showDefaultButtons]="false">
+      </ion-datetime>
+    </ion-card-content>
+  </ion-card>
+
+  <!-- 计划标题和进度 -->
+  <div class="date-header">
+    <h2>{{ getDateDisplay() }}</h2>
+    <div class="progress-info">
+      <span>完成进度: {{ getCompletionRate() }}</span>
+      <ion-progress-bar [value]="getProgressValue()"></ion-progress-bar>
+    </div>
+  </div>
+
+  <!-- 计划列表 -->
+  <ion-list *ngIf="dailyPlans.length > 0">
+    <ion-item-sliding *ngFor="let plan of dailyPlans">
+      <ion-item>
+        <ion-checkbox 
+          slot="start" 
+          [(ngModel)]="plan.completed"
+          (ionChange)="onPlanStatusChange(plan)">
+        </ion-checkbox>
+        <ion-label [class.completed]="plan.completed">
+          <h3>{{ plan.content }}</h3>
+          <p>{{ plan.timeSlot }}</p>
+        </ion-label>
+        <ion-note slot="end" color="medium">
+          {{ plan.duration }}分钟
+        </ion-note>
+      </ion-item>
+
+      <ion-item-options side="end">
+        <ion-item-option color="primary" (click)="editPlan(plan)">
+          <ion-icon slot="icon-only" name="create-outline"></ion-icon>
+        </ion-item-option>
+        <ion-item-option color="danger" (click)="deletePlan(plan)">
+          <ion-icon slot="icon-only" name="trash-outline"></ion-icon>
+        </ion-item-option>
+      </ion-item-options>
+    </ion-item-sliding>
+  </ion-list>
+
+  <!-- 空状态 -->
+  <div class="empty-state" *ngIf="dailyPlans.length === 0">
+    <ion-icon name="calendar-outline"></ion-icon>
+    <p>当天暂无学习计划</p>
+    <ion-button fill="clear" (click)="addNewPlan()">
+      添加计划
+    </ion-button>
+  </div>
+</ion-content> 

+ 62 - 0
AiStudy-app/src/app/pages/daily-plan/daily-plan.page.scss

@@ -0,0 +1,62 @@
+.plans-container {
+  margin-top: 16px;
+
+  .date-header {
+    margin-bottom: 16px;
+    
+    h2 {
+      margin: 0 0 12px 0;
+      font-size: 18px;
+      font-weight: 500;
+      color: var(--ion-color-dark);
+    }
+
+    .progress-info {
+      span {
+        display: block;
+        font-size: 14px;
+        color: var(--ion-color-medium);
+        margin-bottom: 4px;
+      }
+
+      ion-progress-bar {
+        height: 6px;
+        border-radius: 3px;
+        --progress-background: var(--ion-color-success);
+      }
+    }
+  }
+}
+
+ion-item {
+  --padding-start: 0;
+  --inner-padding-end: 0;
+  
+  &.completed {
+    --ion-color-base: var(--ion-color-medium);
+  }
+}
+
+.completed {
+  text-decoration: line-through;
+  color: var(--ion-color-medium);
+}
+
+.empty-state {
+  text-align: center;
+  padding: 32px 16px;
+  
+  ion-icon {
+    font-size: 48px;
+    color: var(--ion-color-medium);
+  }
+  
+  p {
+    color: var(--ion-color-medium);
+    margin: 16px 0;
+  }
+}
+
+ion-datetime {
+  width: 100%;
+} 

+ 318 - 0
AiStudy-app/src/app/pages/daily-plan/daily-plan.page.ts

@@ -0,0 +1,318 @@
+import { Component, OnInit } from '@angular/core';
+import { CommonModule, NgFor, NgIf } from '@angular/common';
+import { FormsModule } from '@angular/forms';
+import { 
+  AlertController,
+  IonHeader,
+  IonToolbar,
+  IonTitle,
+  IonContent,
+  IonButtons,
+  IonBackButton,
+  IonButton,
+  IonIcon,
+  IonCard,
+  IonCardContent,
+  IonDatetime,
+  IonList,
+  IonItem,
+  IonItemSliding,
+  IonItemOptions,
+  IonItemOption,
+  IonCheckbox,
+  IonLabel,
+  IonNote,
+  IonProgressBar,
+  ModalController
+} from '@ionic/angular/standalone';
+import { addIcons } from 'ionicons';
+import { 
+  addOutline, 
+  createOutline, 
+  trashOutline,
+  calendarOutline 
+} from 'ionicons/icons';
+import { CloudUser } from 'src/lib/ncloud';
+import { DailyPlanService } from '../../services/daily-plan.service';
+
+interface DailyPlan {
+  id: string;
+  userId: string;
+  content: string;
+  timeSlot: string;
+  duration: number;
+  completed: boolean;
+  date: string;
+  createdAt: Date;
+}
+
+@Component({
+  selector: 'app-daily-plan',
+  templateUrl: './daily-plan.page.html',
+  styleUrls: ['./daily-plan.page.scss'],
+  standalone: true,
+  imports: [
+    CommonModule,
+    FormsModule,
+    IonHeader,
+    IonToolbar,
+    IonTitle,
+    IonContent,
+    IonButtons,
+    IonBackButton,
+    IonButton,
+    IonIcon,
+    IonCard,
+    IonCardContent,
+    IonDatetime,
+    IonList,
+    IonItem,
+    IonItemSliding,
+    IonItemOptions,
+    IonItemOption,
+    IonCheckbox,
+    IonLabel,
+    IonNote,
+    IonProgressBar,
+    NgFor,
+    NgIf
+  ]
+})
+export class DailyPlanPage implements OnInit {
+  selectedDate: string = new Date().toISOString();
+  dailyPlans: DailyPlan[] = [];
+  
+  constructor(
+    private alertController: AlertController,
+    private modalController: ModalController,
+    private dailyPlanService: DailyPlanService
+  ) {
+    addIcons({
+      addOutline,
+      createOutline,
+      trashOutline,
+      calendarOutline
+    });
+  }
+
+  ngOnInit() {
+    this.loadPlans();
+  }
+
+  async loadPlans() {
+    try {
+      const currentUser = new CloudUser();
+      if (!currentUser.id) {
+        const alert = await this.alertController.create({
+          header: '提示',
+          message: '请先登录后查看学习计划',
+          buttons: ['确定']
+        });
+        await alert.present();
+        return;
+      }
+
+      this.dailyPlans = await this.dailyPlanService.getDailyPlans(this.selectedDate);
+    } catch (error) {
+      console.error('加载计划失败:', error);
+      const alert = await this.alertController.create({
+        header: '错误',
+        message: '加载失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+
+  async onDateChange(event: any) {
+    this.selectedDate = event.detail.value;
+    await this.loadPlans();
+  }
+
+  getDateDisplay(): string {
+    const date = new Date(this.selectedDate);
+    return date.toLocaleDateString('zh-CN', { 
+      year: 'numeric', 
+      month: 'long', 
+      day: 'numeric'
+    }) + ' 学习计划';
+  }
+
+  getProgressValue(): number {
+    if (!this.dailyPlans.length) return 0;
+    const completed = this.dailyPlans.filter(p => p.completed).length;
+    return completed / this.dailyPlans.length;
+  }
+
+  getCompletionRate(): string {
+    return `${Math.round(this.getProgressValue() * 100)}%`;
+  }
+
+  async addNewPlan() {
+    const alert = await this.alertController.create({
+      header: '添加学习计划',
+      inputs: [
+        {
+          name: 'content',
+          type: 'text',
+          placeholder: '学习内容'
+        },
+        {
+          name: 'timeSlot',
+          type: 'text',
+          placeholder: '时间段 (如: 09:00-10:30)'
+        },
+        {
+          name: 'duration',
+          type: 'number',
+          placeholder: '预计时长(分钟)'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '添加',
+          handler: async (data) => {
+            if (!data.content || !data.timeSlot || !data.duration) {
+              return false;
+            }
+            
+            try {
+              await this.savePlan({
+                userId: new CloudUser().id!,
+                content: data.content,
+                timeSlot: data.timeSlot,
+                duration: parseInt(data.duration),
+                completed: false,
+                date: this.selectedDate,
+                createdAt: new Date()
+              });
+              return true;
+            } catch (error) {
+              return false;
+            }
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
+
+  async editPlan(plan: DailyPlan) {
+    const alert = await this.alertController.create({
+      header: '编辑学习计划',
+      inputs: [
+        {
+          name: 'content',
+          type: 'text',
+          value: plan.content,
+          placeholder: '学习内容'
+        },
+        {
+          name: 'timeSlot',
+          type: 'text',
+          value: plan.timeSlot,
+          placeholder: '时间段'
+        },
+        {
+          name: 'duration',
+          type: 'number',
+          value: plan.duration,
+          placeholder: '预计时长(分钟)'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '保存',
+          handler: async (data) => {
+            if (!data.content || !data.timeSlot || !data.duration) {
+              return false;
+            }
+            
+            try {
+              await this.updatePlan({
+                ...plan,
+                content: data.content,
+                timeSlot: data.timeSlot,
+                duration: parseInt(data.duration)
+              });
+              return true;
+            } catch (error) {
+              return false;
+            }
+          }
+        }
+      ]
+    });
+
+    await alert.present();
+  }
+
+  async deletePlan(plan: DailyPlan) {
+    try {
+      await this.dailyPlanService.deletePlan(plan.id);
+      this.dailyPlans = this.dailyPlans.filter(p => p.id !== plan.id);
+    } catch (error) {
+      console.error('删除计划失败:', error);
+      const alert = await this.alertController.create({
+        header: '错误',
+        message: '删除失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+
+  async savePlan(plan: Omit<DailyPlan, 'id'>) {
+    try {
+      await this.dailyPlanService.createPlan(plan);
+      await this.loadPlans();
+    } catch (error) {
+      console.error('保存计划失败:', error);
+      const alert = await this.alertController.create({
+        header: '错误',
+        message: '保存失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+
+  async updatePlan(plan: DailyPlan) {
+    try {
+      await this.dailyPlanService.updatePlan(plan.id, plan);
+      await this.loadPlans();
+    } catch (error) {
+      console.error('更新计划失败:', error);
+      const alert = await this.alertController.create({
+        header: '错误',
+        message: '更新失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+
+  async onPlanStatusChange(plan: DailyPlan) {
+    try {
+      await this.dailyPlanService.updatePlanStatus(plan.id, plan.completed);
+    } catch (error) {
+      console.error('更新状态失败:', error);
+      plan.completed = !plan.completed;
+      const alert = await this.alertController.create({
+        header: '错误',
+        message: '更新失败,请重试',
+        buttons: ['确定']
+      });
+      await alert.present();
+    }
+  }
+} 

+ 134 - 0
AiStudy-app/src/app/services/daily-plan.service.ts

@@ -0,0 +1,134 @@
+import { Injectable } from '@angular/core';
+import { CloudQuery, CloudUser } from 'src/lib/ncloud';
+import Parse from 'parse';
+
+export interface DailyPlan {
+  id: string;
+  userId: string;
+  content: string;
+  timeSlot: string;
+  duration: number;
+  completed: boolean;
+  date: string;
+  createdAt: Date;
+}
+
+type DailyPlanData = {
+  [K in keyof Omit<DailyPlan, 'id'>]: DailyPlan[K];
+};
+
+@Injectable({
+  providedIn: 'root'
+})
+export class DailyPlanService {
+  private DailyPlan: any;
+
+  constructor() {
+    this.DailyPlan = Parse.Object.extend('DailyPlan');
+  }
+
+  // 获取指定日期的计划列表
+  async getDailyPlans(date: string): Promise<DailyPlan[]> {
+    try {
+      const currentUser = new CloudUser();
+      if (!currentUser.id) {
+        throw new Error('User not logged in');
+      }
+
+      // 只比较日期部分
+      const targetDate = date.split('T')[0];
+
+      const query = new Parse.Query(this.DailyPlan);
+      query.equalTo('userId', currentUser.id);
+      query.startsWith('date', targetDate); // 使用 startsWith 来匹配日期部分
+      query.addAscending('timeSlot');
+
+      const results = await query.find();
+      return results.map(plan => {
+        const id = plan.id;
+        if (!id) throw new Error('Plan id is missing');
+        
+        return {
+          id,
+          userId: plan.get('userId'),
+          content: plan.get('content'),
+          timeSlot: plan.get('timeSlot'),
+          duration: plan.get('duration'),
+          completed: plan.get('completed'),
+          date: plan.get('date'),
+          createdAt: plan.get('createdAt')
+        };
+      });
+    } catch (error) {
+      console.error('Error fetching daily plans:', error);
+      throw error;
+    }
+  }
+
+  // 创建新计划
+  async createPlan(planData: DailyPlanData): Promise<string> {
+    try {
+      const plan = new this.DailyPlan();
+      
+      // 确保日期只保存日期部分
+      const formattedData = {
+        ...planData,
+        date: planData.date.split('T')[0]
+      };
+      
+      (Object.keys(formattedData) as Array<keyof DailyPlanData>).forEach(key => {
+        plan.set(key, formattedData[key as keyof DailyPlanData]);
+      });
+
+      const result = await plan.save();
+      return result.id;
+    } catch (error) {
+      console.error('Error creating plan:', error);
+      throw error;
+    }
+  }
+
+  // 更新计划
+  async updatePlan(id: string, planData: Partial<DailyPlanData>): Promise<void> {
+    try {
+      const query = new Parse.Query(this.DailyPlan);
+      const plan = await query.get(id);
+      
+      (Object.keys(planData) as Array<keyof DailyPlanData>).forEach(key => {
+        if (key in planData) {
+          plan.set(key, planData[key]);
+        }
+      });
+
+      await plan.save();
+    } catch (error) {
+      console.error('Error updating plan:', error);
+      throw error;
+    }
+  }
+
+  // 删除计划
+  async deletePlan(id: string): Promise<void> {
+    try {
+      const query = new Parse.Query(this.DailyPlan);
+      const plan = await query.get(id);
+      await plan.destroy();
+    } catch (error) {
+      console.error('Error deleting plan:', error);
+      throw error;
+    }
+  }
+
+  // 更新计划完成状态
+  async updatePlanStatus(id: string, completed: boolean): Promise<void> {
+    try {
+      const query = new Parse.Query(this.DailyPlan);
+      const plan = await query.get(id);
+      plan.set('completed', completed);
+      await plan.save();
+    } catch (error) {
+      console.error('Error updating plan status:', error);
+      throw error;
+    }
+  }
+} 

+ 49 - 2
AiStudy-app/src/app/tab2/tab2.page.html

@@ -29,7 +29,7 @@
           <ion-card-content class="ion-text-center">
             <ion-icon name="bulb" color="warning"></ion-icon>
             <h3>长期学习规划</h3>
-            <p>定制你的专属学习计划</p>
+            <p>个性化定制学习规划</p>
           </ion-card-content>
         </ion-card>
       </ion-col>
@@ -40,7 +40,7 @@
           <ion-card-content class="ion-text-center">
             <ion-icon name="bar-chart" color="success"></ion-icon>
             <h3>学习概览</h3>
-            <p>查看学习进度</p>
+            <p>查看学习规划</p>
           </ion-card-content>
         </ion-card>
       </ion-col>
@@ -69,6 +69,53 @@
     </ion-row>
   </ion-grid>
 
+  <!-- 日常学习计划 -->
+  <ion-card class="daily-plan-card" (click)="navigateToFeature('daily-plan')">
+    <ion-card-header>
+      <div class="header-content">
+        <ion-card-title>
+          <ion-icon name="calendar" color="primary"></ion-icon>
+          日常学习计划
+        </ion-card-title>
+        <ion-button fill="clear" (click)="refreshPlans($event)">
+          <ion-icon name="refresh-outline"></ion-icon>
+        </ion-button>
+      </div>
+    </ion-card-header>
+    <ion-card-content>
+      <div class="daily-plan-preview" *ngIf="todayPlans.length > 0">
+        <div class="plan-items">
+          <ion-item-sliding *ngFor="let plan of todayPlans">
+            <ion-item lines="none">
+              <ion-checkbox 
+                slot="start" 
+                [(ngModel)]="plan.completed"
+                (ionChange)="onPlanStatusChange(plan)"
+                (click)="$event.stopPropagation()">
+              </ion-checkbox>
+              <ion-label [class.completed]="plan.completed">
+                <h3>{{plan.content}}</h3>
+                <p>{{plan.timeSlot}}</p>
+              </ion-label>
+            </ion-item>
+
+            <ion-item-options side="end">
+              <ion-item-option color="primary" (click)="editPlan(plan, $event)">
+                <ion-icon slot="icon-only" name="create-outline"></ion-icon>
+              </ion-item-option>
+              <ion-item-option color="danger" (click)="deletePlan(plan, $event)">
+                <ion-icon slot="icon-only" name="trash-outline"></ion-icon>
+              </ion-item-option>
+            </ion-item-options>
+          </ion-item-sliding>
+        </div>
+      </div>
+      <div class="empty-plan" *ngIf="todayPlans.length === 0">
+        暂无学习计划,点击添加
+      </div>
+    </ion-card-content>
+  </ion-card>
+
   <!-- 学习进度概览 -->
   <ion-card class="progress-card">
     <ion-card-header>

+ 148 - 9
AiStudy-app/src/app/tab2/tab2.page.scss

@@ -50,18 +50,17 @@
 
   ion-card-header {
     padding: 16px;
-  }
 
-  ion-card-content {
-    padding: 16px;
+    ion-card-title {
+      font-size: 16px;
+      font-weight: 500;
+      color: var(--ion-color-dark);
+      margin: 0;
+    }
   }
 
-  .progress-stats {
-    display: flex;
-    justify-content: space-between;
-    margin-top: 8px;
-    font-size: 14px;
-    color: var(--ion-color-medium);
+  ion-card-content {
+    padding: 0 16px 16px;
   }
 }
 
@@ -71,3 +70,143 @@ ion-progress-bar {
   --progress-background: var(--ion-color-primary);
   --buffer-background: rgba(var(--ion-color-primary-rgb), 0.2);
 }
+
+.daily-plan-card {
+  margin-top: 16px;
+  border-radius: 12px;
+  box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+  cursor: pointer;
+  transition: transform 0.2s;
+
+  &:active {
+    transform: scale(0.98);
+  }
+
+  ion-card-header {
+    padding: 16px;
+
+    .header-content {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      width: 100%;
+
+      ion-card-title {
+        display: flex;
+        align-items: center;
+        font-size: 16px;
+        font-weight: 500;
+        color: var(--ion-color-dark);
+        margin: 0;
+        
+        ion-icon {
+          font-size: 20px;
+          margin-right: 8px;
+        }
+      }
+
+      ion-button {
+        margin: 0;
+        --padding-start: 4px;
+        --padding-end: 4px;
+        height: 36px;
+        width: 36px;
+
+        ion-icon {
+          font-size: 18px;
+          color: var(--ion-color-medium);
+        }
+
+        &:hover {
+          ion-icon {
+            color: var(--ion-color-primary);
+          }
+        }
+      }
+    }
+  }
+
+  ion-card-content {
+    padding: 0 16px 16px;
+  }
+
+  .daily-plan-preview {
+    .plan-items {
+      .plan-item {
+        display: flex;
+        align-items: center;
+        padding: 8px 0;
+        border-bottom: 1px solid var(--ion-color-light);
+        
+        &:last-child {
+          border-bottom: none;
+        }
+        
+        ion-icon {
+          font-size: 18px;
+          margin-right: 8px;
+        }
+
+        span {
+          font-size: 14px;
+          color: var(--ion-color-dark);
+          
+          &.completed {
+            color: var(--ion-color-medium);
+            text-decoration: line-through;
+          }
+        }
+      }
+    }
+
+    .plan-summary {
+      color: var(--ion-color-medium);
+      font-size: 14px;
+      margin-top: 8px;
+      text-align: right;
+    }
+  }
+
+  .empty-plan {
+    text-align: center;
+    color: var(--ion-color-medium);
+    font-size: 14px;
+    padding: 12px 0;
+  }
+
+  .plan-items {
+    ion-item {
+      --padding-start: 0;
+      --inner-padding-end: 0;
+      
+      &.completed {
+        --ion-color-base: var(--ion-color-medium);
+      }
+
+      ion-label {
+        h3 {
+          font-size: 14px;
+          margin-bottom: 4px;
+        }
+        
+        p {
+          font-size: 12px;
+          color: var(--ion-color-medium);
+        }
+
+        &.completed {
+          text-decoration: line-through;
+          color: var(--ion-color-medium);
+        }
+      }
+    }
+  }
+}
+
+.progress-stats {
+  display: flex;
+  justify-content: space-between;
+  margin-top: 8px;
+  color: var(--ion-color-medium);
+  font-size: 14px;
+}

+ 164 - 9
AiStudy-app/src/app/tab2/tab2.page.ts

@@ -1,5 +1,6 @@
 import { Component, OnInit } from '@angular/core';
 import { Router } from '@angular/router';
+import { CommonModule, NgFor, NgIf, DatePipe } from '@angular/common';
 import { 
   IonHeader, 
   IonToolbar, 
@@ -16,9 +17,14 @@ import {
   IonItem,
   IonLabel,
   IonBadge,
-  IonProgressBar
+  IonProgressBar,
+  IonItemSliding,
+  IonItemOptions,
+  IonItemOption,
+  IonCheckbox,
+  AlertController,
+  IonButton
 } from '@ionic/angular/standalone';
-import { NgIf } from '@angular/common';
 import { addIcons } from 'ionicons';
 import { 
   notifications, 
@@ -26,8 +32,14 @@ import {
   barChart, 
   people, 
   star,
-  heart  // 添加 heart 图标
+  heart,
+  calendar,
+  checkmarkCircle,
+  ellipseOutline,
+  refreshOutline
 } from 'ionicons/icons';
+import { DailyPlanService, DailyPlan } from '../services/daily-plan.service';
+import { FormsModule } from '@angular/forms';
 
 interface Notification {
   id: number;
@@ -41,6 +53,7 @@ interface Notification {
   styleUrls: ['tab2.page.scss'],
   standalone: true,
   imports: [
+    CommonModule,
     IonHeader, 
     IonToolbar, 
     IonTitle, 
@@ -57,23 +70,40 @@ interface Notification {
     IonLabel,
     IonBadge,
     IonProgressBar,
-    NgIf
+    NgFor,
+    NgIf,
+    DatePipe,
+    IonItemSliding,
+    IonItemOptions,
+    IonItemOption,
+    IonCheckbox,
+    FormsModule,
+    IonButton
   ]
 })
 export class Tab2Page implements OnInit {
   notifications: Notification[] = [];
-  dailyProgress: number = 0.65; // 示例进度
-  completedTasks: number = 13;
-  totalTasks: number = 20;
+  dailyProgress: number = 0;
+  completedTasks: number = 0;
+  totalTasks: number = 0;
+  todayPlans: DailyPlan[] = [];
 
-  constructor(private router: Router) {
+  constructor(
+    private router: Router,
+    private dailyPlanService: DailyPlanService,
+    private alertController: AlertController
+  ) {
     addIcons({ 
       notifications, 
       bulb, 
       barChart, 
       people, 
       star,
-      heart  // 添加 heart 图标
+      heart,
+      calendar,
+      checkmarkCircle,
+      ellipseOutline,
+      refreshOutline
     });
   }
 
@@ -86,6 +116,29 @@ export class Tab2Page implements OnInit {
         date: new Date()
       }
     ];
+    this.loadTodayPlans();
+  }
+
+  async loadTodayPlans() {
+    try {
+      // 获取今天的日期,格式化为 ISO 字符串的日期部分
+      const today = new Date().toISOString();
+      this.todayPlans = await this.dailyPlanService.getDailyPlans(today);
+      
+      // 更新进度
+      if (this.todayPlans.length > 0) {
+        const completed = this.todayPlans.filter(plan => plan.completed).length;
+        this.completedTasks = completed;
+        this.totalTasks = this.todayPlans.length;
+        this.dailyProgress = completed / this.todayPlans.length;
+      } else {
+        this.completedTasks = 0;
+        this.totalTasks = 0;
+        this.dailyProgress = 0;
+      }
+    } catch (error) {
+      console.error('加载今日计划失败:', error);
+    }
   }
 
   navigateToFeature(feature: string) {
@@ -105,8 +158,110 @@ export class Tab2Page implements OnInit {
       case 'favorites':
         this.router.navigate(['/tabs/favorite-exercises']);
         break;
+      case 'daily-plan':
+        this.router.navigate(['/daily-plan']);
+        break;
       default:
         console.log(`Navigating to ${feature}`);
     }
   }
+
+  async onPlanStatusChange(plan: DailyPlan) {
+    try {
+      await this.dailyPlanService.updatePlanStatus(plan.id, plan.completed);
+      // 更新进度
+      const completed = this.todayPlans.filter(p => p.completed).length;
+      this.completedTasks = completed;
+      this.dailyProgress = completed / this.todayPlans.length;
+    } catch (error) {
+      console.error('更新状态失败:', error);
+      plan.completed = !plan.completed; // 恢复原状态
+    }
+  }
+
+  async editPlan(plan: DailyPlan, event: Event) {
+    event.stopPropagation(); // 阻止事件冒泡
+    const alert = await this.alertController.create({
+      header: '编辑学习计划',
+      inputs: [
+        {
+          name: 'content',
+          type: 'text',
+          value: plan.content,
+          placeholder: '学习内容'
+        },
+        {
+          name: 'timeSlot',
+          type: 'text',
+          value: plan.timeSlot,
+          placeholder: '时间段'
+        },
+        {
+          name: 'duration',
+          type: 'number',
+          value: plan.duration,
+          placeholder: '预计时长(分钟)'
+        }
+      ],
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '保存',
+          handler: async (data) => {
+            if (!data.content || !data.timeSlot || !data.duration) {
+              return false;
+            }
+            try {
+              await this.dailyPlanService.updatePlan(plan.id, {
+                ...plan,
+                content: data.content,
+                timeSlot: data.timeSlot,
+                duration: parseInt(data.duration)
+              });
+              await this.loadTodayPlans(); // 重新加载计划列表
+              return true;
+            } catch (error) {
+              return false;
+            }
+          }
+        }
+      ]
+    });
+    await alert.present();
+  }
+
+  async deletePlan(plan: DailyPlan, event: Event) {
+    event.stopPropagation(); // 阻止事件冒泡
+    const alert = await this.alertController.create({
+      header: '确认删除',
+      message: '确定要删除这个学习计划吗?',
+      buttons: [
+        {
+          text: '取消',
+          role: 'cancel'
+        },
+        {
+          text: '删除',
+          handler: async () => {
+            try {
+              await this.dailyPlanService.deletePlan(plan.id);
+              await this.loadTodayPlans(); // 重新加载计划列表
+              return true;
+            } catch (error) {
+              return false;
+            }
+          }
+        }
+      ]
+    });
+    await alert.present();
+  }
+
+  async refreshPlans(event: Event) {
+    event.stopPropagation(); // 阻止事件冒泡,避免触发卡片的点击事件
+    await this.loadTodayPlans();
+  }
 }