HarmonyOS ArkTS 实战:实现一个校友卡申请校友服务应用

项目效果

本文使用 HarmonyOS 和 ArkTS 实现一个校友卡申请校友服务应用。

应用可以申请电子校友卡,查看校友权益,预约返校,校友活动,并提供校友认证、校友通讯录、校友捐赠、就业内推等完整功能。

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

运行效果

校友卡申请校友服务应用

功能介绍

  • 电子校友卡申请
  • 校友身份认证
  • 校友权益展示
  • 返校预约
  • 校友活动报名
  • 校友通讯录
  • 校友捐赠
  • 就业内推
  • 校友新闻
  • 校友企业
  • 我的校友卡
  • 消息通知

定义数据结构

interface AlumniCard {
  id: number;
  name: string;
  studentId: string;
  college: string;
  major: string;
  graduationYear: string;
  phone: string;
  company: string;
  position: string;
  status: string; // 待认证/认证中/已认证/已驳回
  cardNo: string;
  applyTime: string;
  avatar: string;
}

interface AlumniEvent {
  id: number;
  title: string;
  time: string;
  location: string;
  type: string;
  joinedCount: number;
  isJoined: boolean;
}

interface Benefit {
  id: number;
  title: string;
  description: string;
  icon: string;
}

初始化页面状态

@State private tabIndex: number = 0;
@State private isAuthenticated: boolean = false;

@State private name: string = '';
@State private studentId: string = '';
@State private college: string = '信息科学与技术学院';
@State private major: string = '';
@State private graduationYear: string = '2026';
@State private phone: string = '';
@State private company: string = '';
@State private position: string = '';

@State private myCard: AlumniCard | null = null;

@State private benefits: Benefit[] = [
  { id: 1, title: '图书馆访问', description: '凭校友卡可进入图书馆查阅资料', icon: '📚' },
  { id: 2, title: '校园餐厅', description: '享受在校师生同等就餐价格', icon: '🍽️' },
  { id: 3, title: '体育场馆', description: '预约使用校内体育场馆设施', icon: '🏀' },
  { id: 4, title: '校友活动', description: '优先参加各类校友活动', icon: '🎉' },
  { id: 5, title: '就业服务', description: '获取校友企业内推机会', icon: '💼' },
  { id: 6, title: '继续教育', description: '校友专属培训课程优惠', icon: '🎓' },
];

@State private events: AlumniEvent[] = [
  { id: 1, title: '2026届毕业生返校日', time: '2026-10-15 09:00', location: '学校体育馆', type: '返校活动', joinedCount: 328, isJoined: false },
  { id: 2, title: '上海校友秋季交流会', time: '2026-09-20 14:00', location: '上海校友会馆', type: '交流活动', joinedCount: 156, isJoined: true },
  { id: 3, title: '校友企业专场招聘会', time: '2026-11-05 10:00', location: '大学生活动中心', type: '招聘活动', joinedCount: 89, isJoined: false },
];

@State private nextId: number = 10;

申请校友卡

private applyCard(): void {
  if (!this.name || !this.studentId || !this.major) return;
  
  this.myCard = {
    id: this.nextId, name: this.name, studentId: this.studentId,
    college: this.college, major: this.major, graduationYear: this.graduationYear,
    phone: this.phone, company: this.company, position: this.position,
    status: '认证中', cardNo: 'XYH' + Math.floor(Math.random() * 1000000).toString().padStart(6, '0'),
    applyTime: new Date().toLocaleDateString(), avatar: '👤'
  };
  this.nextId += 1;
}

报名活动

private toggleJoinEvent(eventId: number): void {
  this.events = this.events.map(e => {
    if (e.id !== eventId) return e;
    return {
      ...e,
      isJoined: !e.isJoined,
      joinedCount: e.isJoined ? e.joinedCount - 1 : e.joinedCount + 1
    };
  });
}

校友卡组件

@Builder
AlumniCardView(card: AlumniCard) {
  Column({ space: 12 }) {
    Row() {
      Text(card.avatar)
        .fontSize(40)
      Column({ space: 4 }) {
        Text(card.name)
          .fontSize(20)
          .fontWeight(FontWeight.Bold)
          .fontColor(Color.White)
        Text(`${card.college} | ${card.major}`)
          .fontSize(12)
          .fontColor('#F3E8FF')
      }
      .alignItems(HorizontalAlign.Start)
      .margin({ left: 12 })
      Blank()
      Text(card.status === '已认证' ? '✓ 已认证' : '⏳ 认证中')
        .fontSize(12)
        .fontColor(Color.White)
        .padding({ left: 10, right: 10, top: 4, bottom: 4 })
        .backgroundColor(card.status === '已认证' ? '#059669' : '#F59E0B')
        .borderRadius(12)
    }
    .width('100%')
    
    Divider().color('#A855F7')
    
    Row() {
      Column({ space: 4 }) {
        Text('校友卡号')
          .fontSize(11)
          .fontColor('#F3E8FF')
        Text(card.cardNo)
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
          .fontColor(Color.White)
      }
      .alignItems(HorizontalAlign.Start)
      Blank()
      Column({ space: 4 }) {
        Text('毕业年份')
          .fontSize(11)
          .fontColor('#F3E8FF')
        Text(card.graduationYear + '届')
          .fontSize(16)
          .fontWeight(FontWeight.Medium)
          .fontColor(Color.White)
      }
      .alignItems(HorizontalAlign.End)
    }
    .width('100%')
  }
  .width('100%')
  .padding(20)
  .backgroundColor('#701A75')
  .borderRadius(16)
  .shadow({ radius: 12, color: '#701A7540', offsetY: 4 })
}

权益卡片组件

@Builder
BenefitCard(benefit: Benefit) {
  Column({ space: 8 }) {
    Text(benefit.icon)
      .fontSize(28)
    Text(benefit.title)
      .fontSize(13)
      .fontWeight(FontWeight.Medium)
      .fontColor('#701A75')
    Text(benefit.description)
      .fontSize(10)
      .fontColor('#A855F7')
      .textAlign(TextAlign.Center)
      .maxLines(2)
  }
  .width('100%')
  .padding(12)
  .backgroundColor('#FAF5FF')
  .borderRadius(12)
}

页面布局

build() {
  Column() {
    Text('🎓 校友服务')
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
      .fontColor('#701A75')
      .width('100%')
      .padding(20)
    
    if (this.tabIndex === 0) {
      Scroll() {
        Column({ space: 20 }) {
          // 校友卡
          if (this.myCard) {
            this.AlumniCardView(this.myCard)
          } else {
            Button('申请电子校友卡')
              .width('100%')
              .height(120)
              .fontSize(18)
              .backgroundColor('#FAF5FF')
              .fontColor('#701A75')
              .borderRadius(16)
              .onClick(() => this.tabIndex = 1)
          }
          
          // 校友权益
          Text('🎁 校友权益')
            .fontSize(16)
            .fontWeight(FontWeight.Medium)
            .fontColor('#701A75')
            .width('100%')
          
          Grid() {
            ForEach(this.benefits, (b: Benefit) => {
              GridItem() { this.BenefitCard(b) }
            })
          }
          .columnsTemplate('1fr 1fr 1fr')
          .columnsGap(10)
          .rowsGap(10)
          .width('100%')
          
          // 近期活动
          Text('📅 近期活动')
            .fontSize(16)
            .fontWeight(FontWeight.Medium)
            .fontColor('#701A75')
            .width('100%')
          
          ForEach(this.events, (e: AlumniEvent) => {
            Column({ space: 8 }) {
              Row() {
                Text(e.title)
                  .fontSize(14)
                  .fontWeight(FontWeight.Medium)
                  .fontColor('#701A75')
                  .layoutWeight(1)
                Text(e.type)
                  .fontSize(10)
                  .fontColor('#A855F7')
                  .padding({ left: 6, right: 6, top: 2, bottom: 2 })
                  .backgroundColor('#F3E8FF')
                  .borderRadius(8)
              }
              Text(`🕐 ${e.time}`)
                .fontSize(11)
                .fontColor('#A855F7')
              Text(`📍 ${e.location} | ${e.joinedCount}人报名`)
                .fontSize(11)
                .fontColor('#A855F7')
              Button(e.isJoined ? '已报名' : '立即报名')
                .width('100%')
                .height(32)
                .fontSize(12)
                .backgroundColor(e.isJoined ? '#E9D5FF' : '#701A75')
                .fontColor(e.isJoined ? '#701A75' : Color.White)
                .onClick(() => this.toggleJoinEvent(e.id))
            }
            .width('100%')
            .padding(14)
            .backgroundColor('#FAF5FF')
            .borderRadius(12)
            .margin({ bottom: 10 })
          })
        }
        .width('100%')
        .padding(20)
      }
      .layoutWeight(1)
    } else if (this.tabIndex === 1) {
      Scroll() {
        Column({ space: 16 }) {
          if (this.myCard) {
            this.AlumniCardView(this.myCard)
            Text('您的校友卡正在审核中,审核通过后即可享受全部校友权益。审核时间约3-5个工作日。')
              .fontSize(13)
              .fontColor('#A855F7')
              .width('100%')
          } else {
            Text('校友卡申请')
              .fontSize(18)
              .fontWeight(FontWeight.Bold)
              .fontColor('#701A75')
              .width('100%')
            
            TextInput({ text: this.name, placeholder: '真实姓名' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
              .onChange((v: string) => this.name = v)
            
            TextInput({ text: this.studentId, placeholder: '学号' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
              .onChange((v: string) => this.studentId = v)
            
            TextInput({ text: this.major, placeholder: '专业' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
              .onChange((v: string) => this.major = v)
            
            TextInput({ text: this.graduationYear, placeholder: '毕业年份' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
            
            TextInput({ text: this.phone, placeholder: '联系电话' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
              .onChange((v: string) => this.phone = v)
            
            TextInput({ text: this.company, placeholder: '所在单位(选填)' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
            
            TextInput({ text: this.position, placeholder: '职位(选填)' })
              .width('100%')
              .height(44)
              .backgroundColor('#FAF5FF')
            
            Button('提交申请')
              .width('100%')
              .height(48)
              .fontSize(16)
              .backgroundColor('#701A75')
              .margin({ top: 10 })
              .onClick(() => this.applyCard())
          }
        }
        .width('100%')
        .padding(20)
      }
      .layoutWeight(1)
    } else {
      List({ space: 12 }) {
        ListItem() {
          Column({ space: 8 }) {
            Text('💼 校友内推')
              .fontSize(15)
              .fontWeight(FontWeight.Medium)
              .fontColor('#701A75')
            Text('已有128位校友发布内推岗位,覆盖互联网、金融、制造业等多个行业', { fontSize: 12, fontColor: '#A855F7' })
          }
          .width('100%')
          .padding(16)
          .backgroundColor('#FAF5FF')
          .borderRadius(12)
        }
        ListItem() {
          Column({ space: 8 }) {
            Text('❤️ 校友捐赠')
              .fontSize(15)
              .fontWeight(FontWeight.Medium)
              .fontColor('#701A75')
            Text('支持母校发展,捐赠金额不限,所有捐赠将用于奖学金和校园建设', { fontSize: 12, fontColor: '#A855F7' })
          }
          .width('100%')
          .padding(16)
          .backgroundColor('#FAF5FF')
          .borderRadius(12)
        }
        ListItem() {
          Column({ space: 8 }) {
            Text('🏫 返校预约')
              .fontSize(15)
              .fontWeight(FontWeight.Medium)
              .fontColor('#701A75')
            Text('预约返校参观,可申请校友讲解、食堂就餐、宿舍参观等服务', { fontSize: 12, fontColor: '#A855F7' })
          }
          .width('100%')
          .padding(16)
          .backgroundColor('#FAF5FF')
          .borderRadius(12)
        }
      }
      .width('100%')
      .padding(20)
      .layoutWeight(1)
    }
    
    // 底部Tab
    Row() {
      Column() {
        Text('🏠')
          .fontSize(20)
        Text('首页')
          .fontSize(11)
          .fontColor(this.tabIndex === 0 ? '#701A75' : '#94A3B8')
      }
      .layoutWeight(1)
      .onClick(() => this.tabIndex = 0)
      
      Column() {
        Text('💳')
          .fontSize(20)
        Text('校友卡')
          .fontSize(11)
          .fontColor(this.tabIndex === 1 ? '#701A75' : '#94A3B8')
      }
      .layoutWeight(1)
      .onClick(() => this.tabIndex = 1)
      
      Column() {
        Text('⚙️')
          .fontSize(20)
        Text('服务')
          .fontSize(11)
          .fontColor(this.tabIndex === 2 ? '#701A75' : '#94A3B8')
      }
      .layoutWeight(1)
      .onClick(() => this.tabIndex = 2)
    }
    .width('100%')
    .height(60)
    .backgroundColor(Color.White)
    .shadow({ radius: 8, color: '#701A7510', offsetY: -2 })
  }
  .width('100%')
  .height('100%')
  .backgroundColor(Color.White)
}

页面设计说明

主题色采用fuchsia-900#701A75,深洋红色体现校友的情怀、温馨、归属感。洋红色校友卡设计精美,三列网格展示权益,活动卡片报名按钮交互。

SDK配置

API 24,compatibleSdkVersion: “6.1.1(24)”

运行项目

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

项目总结

实现了校友卡申请、身份认证、权益展示、活动报名、校友服务等功能。掌握了卡片阴影效果、Grid三列布局、自定义底部Tab、状态切换等。后续可加入校友通讯录、电子校友卡二维码、校友新闻、捐赠记录、校友企业展示、返校预约表单等功能。

Logo

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

更多推荐