HarmonyOS ArkTS 实战:实现一个校园宿舍文明评比查分应用

项目效果

本文使用 HarmonyOS 和 ArkTS 实现一个校园宿舍文明评比查分应用。

应用可以查看宿舍评分标准,查看历史评分,查寝通知,评分申诉,并提供宿舍排名、文明宿舍公示、卫生小贴士、查寝记录等完整功能。

项目使用 DevEco Studio 开发,适配 API 23 及以上版本。

运行效果

校园宿舍文明评比查分应用

功能介绍

  • 评分标准查看
  • 宿舍历史评分
  • 查寝通知
  • 评分详情
  • 评分申诉
  • 宿舍排名
  • 文明宿舍公示
  • 卫生小贴士
  • 查寝记录
  • 加分减分明细
  • 月度统计
  • 宿舍对比

定义数据结构

interface ScoreRecord {
  id: number;
  dormNumber: string;
  date: string;
  score: number;
  grade: string; // 优秀/良好/合格/不合格
  inspector: string;
  items: { name: string; score: number; maxScore: number }[];
  comment: string;
  canAppeal: boolean;
}

interface Dorm {
  number: string;
  building: string;
  floor: number;
  totalScore: number;
  averageScore: number;
  rank: number;
  isExcellent: boolean;
}

interface Appeal {
  id: number;
  recordId: number;
  reason: string;
  time: string;
  status: string; // 待处理/已通过/已驳回
  reply: string;
}

初始化页面状态

@State private tabIndex: number = 0;
@State private myDorm: string = '1号楼302';
@State private myAverageScore: number = 92.5;
@State private myRank: number = 8;

@State private records: ScoreRecord[] = [
  { id: 1, dormNumber: '1号楼302', date: '2026-07-15', score: 95, grade: '优秀', inspector: '张老师', items: [{ name: '地面整洁', score: 20, maxScore: 20 }, { name: '床铺整理', score: 19, maxScore: 20 }, { name: '物品摆放', score: 18, maxScore: 20 }, { name: '卫生间', score: 19, maxScore: 20 }, { name: '安全用电', score: 19, maxScore: 20 }], comment: '整体整洁,继续保持', canAppeal: false },
  { id: 2, dormNumber: '1号楼302', date: '2026-07-08', score: 88, grade: '良好', inspector: '李老师', items: [{ name: '地面整洁', score: 18, maxScore: 20 }, { name: '床铺整理', score: 17, maxScore: 20 }, { name: '物品摆放', score: 18, maxScore: 20 }, { name: '卫生间', score: 17, maxScore: 20 }, { name: '安全用电', score: 18, maxScore: 20 }], comment: '地面有少量杂物', canAppeal: false },
  { id: 3, dormNumber: '1号楼302', date: '2026-07-22', score: 94, grade: '优秀', inspector: '王老师', items: [{ name: '地面整洁', score: 19, maxScore: 20 }, { name: '床铺整理', score: 19, maxScore: 20 }, { name: '物品摆放', score: 19, maxScore: 20 }, { name: '卫生间', score: 18, maxScore: 20 }, { name: '安全用电', score: 19, maxScore: 20 }], comment: '进步明显,表扬', canAppeal: true },
];

@State private appeals: Appeal[] = [];
@State private nextId: number = 10;

提交申诉

private submitAppeal(recordId: number, reason: string): void {
  const appeal: Appeal = {
    id: this.nextId, recordId, reason,
    time: new Date().toLocaleDateString(), status: '待处理', reply: ''
  };
  this.appeals = [appeal, ...this.appeals];
  this.records = this.records.map(r => r.id === recordId ? { ...r, canAppeal: false } : r);
  this.nextId += 1;
}

评分等级颜色

private getGradeColor(grade: string): string {
  switch (grade) {
    case '优秀': return '#059669';
    case '良好': return '#0284C7';
    case '合格': return '#D97706';
    case '不合格': return '#DC2626';
    default: return '#64748B';
  }
}

评分记录卡片组件

@Builder
RecordCard(record: ScoreRecord) {
  Column({ space: 10 }) {
    Row() {
      Text(record.date)
        .fontSize(15)
        .fontWeight(FontWeight.Medium)
        .fontColor('#422006')
      Blank()
      Text(`${record.score}`)
        .fontSize(20)
        .fontWeight(FontWeight.Bold)
        .fontColor(this.getGradeColor(record.grade))
      Text(record.grade)
        .fontSize(12)
        .fontColor(Color.White)
        .padding({ left: 8, right: 8, top: 3, bottom: 3 })
        .backgroundColor(this.getGradeColor(record.grade))
        .borderRadius(10)
        .margin({ left: 8 })
    }
    .width('100%')
    
    Flex({ wrap: FlexWrap.Wrap }) {
      ForEach(record.items, (item: { name: string; score: number; maxScore: number }) => {
        Text(`${item.name} ${item.score}/${item.maxScore}`)
          .fontSize(11)
          .fontColor('#78350F')
          .padding({ left: 8, right: 8, top: 4, bottom: 4 })
          .backgroundColor('#FEF3C7')
          .borderRadius(8)
          .margin({ right: 6, bottom: 6 })
      })
    }
    
    Text(`评语:${record.comment}`)
      .fontSize(12)
      .fontColor('#92400E')
      .width('100%')
    
    Text(`检查人:${record.inspector}`)
      .fontSize(11)
      .fontColor('#B45309')
    
    if (record.canAppeal) {
      Button('申诉')
        .width('100%')
        .height(34)
        .fontSize(13)
        .backgroundColor('#422006')
        .margin({ top: 4 })
        .onClick(() => this.submitAppeal(record.id, '对评分有异议'))
    }
  }
  .width('100%')
  .padding(16)
  .backgroundColor('#FFFBEB')
  .borderRadius(12)
}

页面布局

build() {
  Column() {
    // 顶部宿舍信息
    Column({ space: 12 }) {
      Text(`宿舍 ${this.myDorm}`)
        .fontSize(22)
        .fontWeight(FontWeight.Bold)
        .fontColor(Color.White)
      Row({ space: 30 }) {
        Column() {
          Text(`${this.myAverageScore}`)
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor(Color.White)
          Text('平均分')
            .fontSize(12)
            .fontColor('#FEF3C7')
        }
        Column() {
          Text(`${this.myRank}`)
            .fontSize(28)
            .fontWeight(FontWeight.Bold)
            .fontColor('#FBBF24')
          Text('楼栋排名')
            .fontSize(12)
            .fontColor('#FEF3C7')
        }
        Column() {
          Text('⭐⭐⭐⭐⭐')
            .fontSize(16)
          Text('文明宿舍')
            .fontSize(12)
            .fontColor('#FEF3C7')
        }
      }
    }
    .width('100%')
    .padding(20)
    .backgroundColor('#422006')
    
    // Tab
    Row({ space: 20 }) {
      Text('查分记录')
        .fontSize(16)
        .fontWeight(this.tabIndex === 0 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 0 ? '#422006' : '#94A3B8')
        .onClick(() => this.tabIndex = 0)
      Text('评分标准')
        .fontSize(16)
        .fontWeight(this.tabIndex === 1 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 1 ? '#422006' : '#94A3B8')
        .onClick(() => this.tabIndex = 1)
      Text('我的申诉')
        .fontSize(16)
        .fontWeight(this.tabIndex === 2 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 2 ? '#422006' : '#94A3B8')
        .onClick(() => this.tabIndex = 2)
    }
    .width('100%')
    .padding({ left: 20, right: 20, top: 20 })
    
    if (this.tabIndex === 0) {
      List({ space: 12 }) {
        ForEach(this.records, (r: ScoreRecord) => {
          ListItem() { this.RecordCard(r) }
        })
      }
      .width('100%')
      .padding(20)
      .layoutWeight(1)
    } else if (this.tabIndex === 1) {
      List({ space: 10 }) {
        ListItem() {
          Column({ space: 8 }) {
            Text('一、地面整洁(20分)')
              .fontSize(14)
              .fontWeight(FontWeight.Medium)
            Text('地面干净无垃圾、无污渍,物品摆放整齐', { fontSize: 12, fontColor: '#78350F' })
          }
          .width('100%')
          .padding(14)
          .backgroundColor('#FFFBEB')
          .borderRadius(10)
        }
        ListItem() {
          Column({ space: 8 }) {
            Text('二、床铺整理(20分)')
              .fontSize(14)
              .fontWeight(FontWeight.Medium)
            Text('被子叠放整齐,床单平整,床上无杂物', { fontSize: 12, fontColor: '#78350F' })
          }
          .width('100%')
          .padding(14)
          .backgroundColor('#FFFBEB')
          .borderRadius(10)
        }
      }
      .width('100%')
      .padding(20)
      .layoutWeight(1)
    } else {
      if (this.appeals.length === 0) {
        Column() {
          Text('暂无申诉记录')
            .fontSize(14)
            .fontColor('#94A3B8')
        }
        .width('100%')
        .layoutWeight(1)
        .justifyContent(FlexAlign.Center)
      }
    }
  }
  .width('100%')
  .height('100%')
  .backgroundColor(Color.White)
}

页面设计说明

主题色采用amber-950#422006,深琥珀色体现宿舍评比的温馨、公正。顶部深色区域展示宿舍平均分和排名,评分项标签清晰,优秀绿色、良好蓝色区分。

SDK配置

API 24,compatibleSdkVersion: “6.1.1(24)”

运行项目

将代码复制到 entry/src/main/ets/pages/Index.ets 即可运行。

项目总结

实现了评分查看、评分明细、申诉、评分标准、排名统计等功能。掌握了Flex布局、状态颜色函数、多Tab切换、卡片组件等。后续可加入查寝通知推送、照片上传、月度报表、宿舍对比、卫生贴士、文明宿舍投票等功能。

Logo

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

更多推荐