HarmonyOS ArkTS 实战:实现一个大创项目申报管理应用

项目效果

本文使用 HarmonyOS 和 ArkTS 实现一个大创项目申报管理应用。

应用可以查看申报通知,提交项目申报,查看审核状态,项目进度,并提供成员管理、指导老师、中期检查、结项管理等完整功能。

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

运行效果

大创项目申报管理应用

功能介绍

  • 申报通知查看
  • 项目申报提交
  • 项目信息填写
  • 成员管理
  • 指导老师选择
  • 审核状态查询
  • 项目进度跟踪
  • 中期检查
  • 结项申请
  • 我的项目
  • 优秀项目展示
  • 常见问题

定义数据结构

interface Project {
  id: number;
  name: string;
  category: string; // 创新训练/创业训练/创业实践
  level: string; // 国家级/市级/校级
  leader: string;
  members: string[];
  teacher: string;
  college: string;
  description: string;
  budget: number;
  status: string; // 草稿/待审核/学院审核/学校审核/已立项/进行中/中期检查/已结项/已驳回
  progress: number;
  applyTime: string;
}

interface Notice {
  id: number;
  title: string;
  content: string;
  deadline: string;
  type: string;
}

初始化页面状态

@State private tabIndex: number = 0;

@State private notices: Notice[] = [
  { id: 1, title: '关于2026年大学生创新创业训练计划项目申报的通知', content: '各学院:为培养大学生创新精神和实践能力...', deadline: '2026-08-31', type: '申报通知' },
  { id: 2, title: '2026年大创项目中期检查通知', content: '请各项目组于9月15日前提交中期检查报告...', deadline: '2026-09-15', type: '中期检查' },
];

@State private projects: Project[] = [
  { id: 1, name: '基于HarmonyOS的校园服务平台', category: '创新训练', level: '国家级', leader: '沈同学', members: ['张同学', '李同学', '王同学'], teacher: '陈教授', college: '信息学院', description: '开发一款基于HarmonyOS的校园综合服务应用', budget: 20000, status: '进行中', progress: 60, applyTime: '2026-03-15' },
];

@State private newProjectName: string = '';
@State private newProjectDesc: string = '';
@State private newCategory: string = '创新训练';
@State private newLevel: string = '校级';
@State private nextId: number = 10;

提交申报

private submitProject(): void {
  if (!this.newProjectName || !this.newProjectDesc) return;
  
  const project: Project = {
    id: this.nextId, name: this.newProjectName, category: this.newCategory,
    level: this.newLevel, leader: '我', members: ['我'], teacher: '待分配',
    college: '信息学院', description: this.newProjectDesc, budget: 5000,
    status: '待审核', progress: 0, applyTime: new Date().toLocaleDateString()
  };
  this.projects = [project, ...this.projects];
  this.newProjectName = '';
  this.newProjectDesc = '';
  this.nextId += 1;
}

状态颜色

private getStatusColor(status: string): string {
  if (status.includes('驳回')) return '#DC2626';
  if (status.includes('审核')) return '#F59E0B';
  if (status === '已立项' || status === '进行中') return '#059669';
  if (status === '已结项') return '#7C3AED';
  return '#64748B';
}

项目卡片组件

@Builder
ProjectCard(project: Project) {
  Column({ space: 10 }) {
    Row() {
      Text(project.name)
        .fontSize(16)
        .fontWeight(FontWeight.Medium)
        .fontColor('#4C0519')
        .layoutWeight(1)
      Text(project.status)
        .fontSize(11)
        .fontColor(Color.White)
        .padding({ left: 8, right: 8, top: 3, bottom: 3 })
        .backgroundColor(this.getStatusColor(project.status))
        .borderRadius(10)
    }
    .width('100%')
    
    Row({ space: 8 }) {
      Text(project.category)
        .fontSize(11)
        .fontColor('#9F1239')
        .padding({ left: 6, right: 6, top: 2, bottom: 2 })
        .backgroundColor('#FFE4E6')
        .borderRadius(8)
      Text(project.level)
        .fontSize(11)
        .fontColor('#9F1239')
        .padding({ left: 6, right: 6, top: 2, bottom: 2 })
        .backgroundColor('#FFE4E6')
        .borderRadius(8)
      Text(`负责人:${project.leader}`)
        .fontSize(11)
        .fontColor('#9F1239')
    }
    
    Text(project.description)
      .fontSize(12)
      .fontColor('#881337')
      .maxLines(2)
      .width('100%')
    
    Progress({ value: project.progress, total: 100, type: ProgressType.Linear })
      .width('100%')
      .color('#BE123C')
      .backgroundColor('#FFE4E6')
    
    Text(`进度:${project.progress}% | 指导老师:${project.teacher} | 经费:¥${project.budget}`)
      .fontSize(11)
      .fontColor('#9F1239')
  }
  .width('100%')
  .padding(16)
  .backgroundColor('#FFF1F2')
  .borderRadius(12)
}

页面布局

build() {
  Column() {
    Text('🎯 大创项目管理')
      .fontSize(24)
      .fontWeight(FontWeight.Bold)
      .fontColor('#4C0519')
      .width('100%')
      .padding(20)
    
    // Tab
    Row({ space: 20 }) {
      Text('申报通知')
        .fontSize(16)
        .fontWeight(this.tabIndex === 0 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 0 ? '#4C0519' : '#94A3B8')
        .onClick(() => this.tabIndex = 0)
      Text('我的项目')
        .fontSize(16)
        .fontWeight(this.tabIndex === 1 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 1 ? '#4C0519' : '#94A3B8')
        .onClick(() => this.tabIndex = 1)
      Text('新建申报')
        .fontSize(16)
        .fontWeight(this.tabIndex === 2 ? FontWeight.Bold : FontWeight.Normal)
        .fontColor(this.tabIndex === 2 ? '#4C0519' : '#94A3B8')
        .onClick(() => this.tabIndex = 2)
    }
    .width('100%')
    .padding({ left: 20, right: 20 })
    
    if (this.tabIndex === 0) {
      List({ space: 12 }) {
        ForEach(this.notices, (n: Notice) => {
          ListItem() {
            Column({ space: 8 }) {
              Text(n.title)
                .fontSize(15)
                .fontWeight(FontWeight.Medium)
                .fontColor('#4C0519')
              Text(n.content)
                .fontSize(12)
                .fontColor('#9F1239')
                .maxLines(2)
              Text(`截止时间:${n.deadline}`)
                .fontSize(11)
                .fontColor('#DC2626')
            }
            .width('100%')
            .padding(16)
            .backgroundColor('#FFF1F2')
            .borderRadius(12)
          }
        })
      }
      .width('100%')
      .padding(20)
      .layoutWeight(1)
    } else if (this.tabIndex === 1) {
      List({ space: 12 }) {
        ForEach(this.projects, (p: Project) => {
          ListItem() { this.ProjectCard(p) }
        })
      }
      .width('100%')
      .padding(20)
      .layoutWeight(1)
    } else {
      Scroll() {
        Column({ space: 16 }) {
          TextInput({ text: this.newProjectName, placeholder: '项目名称' })
            .width('100%')
            .height(44)
            .backgroundColor('#FFF1F2')
            .onChange((v: string) => this.newProjectName = v)
          
          // 项目类型
          Text('项目类型')
            .fontSize(14)
            .fontWeight(FontWeight.Medium)
            .width('100%')
          Flex({ wrap: FlexWrap.Wrap }) {
            ForEach(['创新训练', '创业训练', '创业实践'], (c: string) => {
              Text(c)
                .fontSize(13)
                .fontColor(this.newCategory === c ? Color.White : '#4C0519')
                .padding({ left: 16, right: 16, top: 8, bottom: 8 })
                .backgroundColor(this.newCategory === c ? '#BE123C' : '#FFE4E6')
                .borderRadius(20)
                .margin({ right: 8, bottom: 8 })
                .onClick(() => this.newCategory = c)
            })
          }
          
          // 项目级别
          Text('申报级别')
            .fontSize(14)
            .fontWeight(FontWeight.Medium)
            .width('100%')
          Flex({ wrap: FlexWrap.Wrap }) {
            ForEach(['国家级', '市级', '校级'], (l: string) => {
              Text(l)
                .fontSize(13)
                .fontColor(this.newLevel === l ? Color.White : '#4C0519')
                .padding({ left: 16, right: 16, top: 8, bottom: 8 })
                .backgroundColor(this.newLevel === l ? '#BE123C' : '#FFE4E6')
                .borderRadius(20)
                .margin({ right: 8, bottom: 8 })
                .onClick(() => this.newLevel = l)
            })
          }
          
          TextArea({ text: this.newProjectDesc, placeholder: '项目简介(研究内容、创新点、预期成果)' })
            .width('100%')
            .height(120)
            .backgroundColor('#FFF1F2')
            .onChange((v: string) => this.newProjectDesc = v)
          
          Button('提交申报')
            .width('100%')
            .height(48)
            .fontSize(16)
            .backgroundColor('#4C0519')
            .margin({ top: 10 })
            .onClick(() => this.submitProject())
        }
        .width('100%')
        .padding(20)
      }
      .layoutWeight(1)
    }
  }
  .width('100%')
  .height('100%')
  .backgroundColor(Color.White)
}

页面设计说明

主题色采用rose-950#4C0519,深玫瑰色体现学术项目的严谨、专业。玫瑰红系卡片,进度条显示项目进展,状态标签颜色区分审核阶段。

SDK配置

API 24,compatibleSdkVersion: “6.1.1(24)”

运行项目

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

项目总结

实现了申报通知、项目申报、状态跟踪、进度管理、类型级别选择等功能。掌握了Progress进度条、表单验证、状态颜色映射、Flex标签选择等。后续可加入附件上传、成员邀请、指导老师选择、中期报告提交、结项材料、优秀项目展示等功能。

Logo

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

更多推荐