news 2026/7/24 20:47:03

HarmonyOS ArkTS 实战:实现一个校园竞赛报名与项目管理应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS ArkTS 实战:实现一个校园竞赛报名与项目管理应用

HarmonyOS ArkTS 实战:校园竞赛报名与项目管理完整实现

摘要

项目难度:⭐⭐⭐ 中级实战
适用人群:有 ArkTS 基础、希望学习学习类应用开发的 HarmonyOS 开发者
开发环境:DevEco Studio Next / API 24+
代码规模:单页面约 700 行,可直接运行

通过本项目,你将掌握:

  • 进度条组件的实现与进度状态管理
  • 多模型关联的数据结构设计
  • 竞赛日历与时间轴展示技巧
  • 组队管理与成员增删逻辑
  • 项目状态流转与获奖展示

目录

  • [一、项目概述与功能架构]
    • [1.1 应用场景与项目价值]
    • [1.2 完整功能清单]
    • [1.3 技术选型说明]
  • [二、数据结构设计]
    • [2.1 团队成员模型 TeamMember]
    • [2.2 竞赛模型 Competition]
    • [2.3 项目模型 Project]
    • [2.4 设计思路说明]
  • [三、核心功能实现详解]
    • [3.1 竞赛浏览与筛选]
    • [3.2 报名竞赛与创建项目]
    • [3.3 团队成员管理]
    • [3.4 项目进度更新]
  • [四、UI 设计与交互体验]
    • [4.1 整体布局结构]
    • [4.2 主题色与视觉规范]
    • [4.3 状态视觉区分表]
  • [五、关键技术点解析]
    • [5.1 进度条的设计与实现思路]
    • [5.2 多对多关系的数据建模]
  • [六、常见问题与优化建议]
  • [七、项目总结与扩展方向]
  • [附录:运行方式]

一、项目概述与功能架构

1.1 应用场景与项目价值

学科竞赛是大学生活的重要组成部分,从"互联网+“到"挑战杯”,从数学建模到程序设计竞赛,各类竞赛为学生提供了实践锻炼和能力提升的广阔平台。然而,竞赛信息分散、组队困难、项目进度难以追踪等问题一直困扰着参赛学生。

本项目基于 HarmonyOS ArkTS 实现了一个校园竞赛报名与项目管理应用,整合了竞赛信息浏览、在线报名、组队管理、进度跟踪、作品提交、获奖记录等全流程功能,帮助学生系统化管理竞赛生涯。

项目核心价值:

  1. 信息聚合价值:集中展示各类竞赛信息,避免信息遗漏
  2. 协作效率价值:系统化的组队和项目管理,提升团队协作效率
  3. 成长记录价值:完整记录参赛历程和获奖情况,形成个人成长档案

1.2 完整功能清单

功能模块具体功能实现难度⭐
竞赛信息竞赛浏览、按类型筛选、竞赛详情、收藏竞赛⭐⭐
报名参赛在线报名、选择赛道、填写信息、报名确认⭐⭐
组队管理创建团队、添加成员、成员角色分配、人数限制⭐⭐⭐
项目管理项目创建、进度跟踪、状态更新、作品提交⭐⭐⭐
获奖记录获奖展示、证书管理、奖项统计、荣誉墙⭐⭐
辅助功能竞赛日历、报名提醒、赛程安排、数据统计⭐⭐⭐

1.3 技术选型说明

技术维度选型方案选型理由
开发语言ArkTS强类型支持,适合复杂业务逻辑和多模型关联场景
状态管理@State 装饰器单页面应用轻量方案,响应式更新及时
UI 组件ArkUI 基础组件 + 自定义进度条灵活定制,满足进度可视化需求
数据存储内存状态演示简化,生产环境建议接入云端数据库
最低版本API 24兼容主流 HarmonyOS 设备

⚠️ 注意:本项目为前端演示版本,报名、组队等操作均在本地模拟。真实竞赛系统需要对接学校教务系统或竞赛组委会后台,进行身份核验和数据同步。


二、数据结构设计

2.1 团队成员模型 TeamMember

团队成员是项目的参与者,每个人有明确的角色分工。

/** * 团队成员数据模型 * 描述参赛团队中单个成员的信息 */interfaceTeamMember{name:string;// 成员姓名studentId:string;// 学号role:string;// 角色:队长/技术/文案/设计 等}

2.2 竞赛模型 Competition

竞赛是整个系统的基础实体,包含竞赛的基本信息和报名状态。

/** * 竞赛数据模型 * 描述单个竞赛的完整信息 */interfaceCompetition{id:number;// 竞赛IDname:string;// 竞赛名称type:string;// 竞赛类型:学科类/创新创业类/文体类level:string;// 竞赛级别:校级/省级/国家级/国际级deadline:string;// 报名截止时间award:string;// 最高奖项设置description:string;// 竞赛简介organizer:string;// 主办方maxMembers:number;// 每队最大人数status:string;// 报名状态:报名中/已截止/进行中/已结束isCollected:boolean;// 是否已收藏}

2.3 项目模型 Project

项目是学生报名竞赛后产生的参赛实体,关联具体竞赛和团队成员。

/** * 参赛项目数据模型 * 记录学生参与某个竞赛的具体项目信息 */interfaceProject{id:number;// 项目IDcompetitionId:number;// 关联的竞赛IDcompetitionName:string;// 竞赛名称(冗余存储,便于展示)projectName:string;// 项目名称members:TeamMember[];// 团队成员列表progress:number;// 项目进度 0-100status:string;// 项目状态:进行中/已提交/已获奖/未获奖submitTime:string;// 提交时间award:string;// 获得奖项}

2.4 设计思路说明

为什么采用竞赛-项目分离的双层模型?

这是一个典型的一对多关系设计:

  1. 语义清晰:竞赛是"赛事",项目是"我的参赛记录",两者概念不同
  2. 灵活扩展:同一个竞赛可以报名多个项目(不同赛道),同一个项目也可能跨竞赛参赛
  3. 状态独立:竞赛的报名状态和项目的完成状态是两个维度,分开管理更清晰
  4. 数据解耦:竞赛信息是公共数据,项目是个人数据,分离后便于权限控制

关于成员角色的设计考量

角色字段采用字符串而非枚举,原因是:

  • 不同竞赛的角色分工差异很大(技术赛和商业赛角色完全不同)
  • 字符串灵活性高,用户可以自定义角色名称
  • 演示项目简化处理,生产环境可建立角色字典表

三、核心功能实现详解

3.1 页面状态初始化

/** * 页面状态变量定义 */@StateprivateprojectNameText:string='';// 新项目名称输入@StateprivatememberNameText:string='';// 新成员姓名输入@StateprivateselectedType:string='全部';// 竞赛筛选类型@StateprivatenextProjectId:number=5;// 下一个项目ID@Stateprivatecompetitions:Competition[]=[];// 竞赛列表@Stateprivateprojects:Project[]=[];// 我的项目列表

3.2 竞赛浏览与筛选

/** * 获取筛选后的竞赛列表 * 支持按类型筛选和收藏筛选 */privategetFilteredCompetitions():Competition[]{letresult=this.competitions;// 按类型筛选if(this.selectedType!=='全部'){result=result.filter(c=>c.type===this.selectedType);}// 按截止时间排序,即将截止的排在前面returnresult.sort((a,b)=>{returnnewDate(a.deadline).getTime()-newDate(b.deadline).getTime();});}/** * 切换竞赛收藏状态 * @param compId 竞赛ID */privatetoggleCollectCompetition(compId:number):void{this.competitions=this.competitions.map(c=>{if(c.id===compId){return{...c,isCollected:!c.isCollected};}returnc;});}

3.3 报名竞赛与创建项目

用户报名某个竞赛时,会自动创建一个关联的项目记录。

/** * 报名竞赛并创建项目 * @param compId 竞赛ID * @param compName 竞赛名称 */privateregisterCompetition(compId:number,compName:string):void{// 校验项目名称constprojectName=this.projectNameText.trim();if(projectName.length===0){// 生产环境增加提示return;}// 创建新项目constproject:Project={id:this.nextProjectId,competitionId:compId,competitionName:compName,projectName:projectName,members:[],progress:0,status:'进行中',submitTime:'',award:''};this.projects=[project,...this.projects];this.nextProjectId++;this.projectNameText='';}

3.4 团队成员管理

添加和移除团队成员,同时校验人数上限。

/** * 向项目添加团队成员 * @param projectId 项目ID * @param maxMembers 最大人数限制(来自竞赛配置) */privateaddTeamMember(projectId:number,maxMembers:number):void{constmemberName=this.memberNameText.trim();if(memberName.length===0)return;this.projects=this.projects.map(p=>{if(p.id===projectId){// 校验人数上限if(p.members.length>=maxMembers){// 已达人数上限,生产环境提示用户returnp;}constnewMember:TeamMember={name:memberName,studentId:'',role:'成员'};return{...p,members:[...p.members,newMember]};}returnp;});this.memberNameText='';}/** * 移除团队成员 * @param projectId 项目ID * @param memberIndex 成员索引 */privateremoveTeamMember(projectId:number,memberIndex:number):void{this.projects=this.projects.map(p=>{if(p.id===projectId){constnewMembers=p.members.filter((_,idx)=>idx!==memberIndex);return{...p,members:newMembers};}returnp;});}

3.5 项目进度更新

进度条是项目管理的核心可视化组件,支持步进更新和直接设置。

/** * 更新项目进度 * @param projectId 项目ID * @param progress 新的进度值(0-100) */privateupdateProgress(projectId:number,progress:number):void{// 进度值边界校验constvalidProgress=Math.max(0,Math.min(100,progress));this.projects=this.projects.map(p=>{if(p.id===projectId){letnewStatus=p.status;// 进度达到100%自动标记为待提交状态if(validProgress>=100&&p.status==='进行中'){newStatus='待提交';}return{...p,progress:validProgress,status:newStatus};}returnp;});}/** * 标记项目已提交 */privatesubmitProject(projectId:number):void{this.projects=this.projects.map(p=>{if(p.id===projectId){return{...p,status:'已提交',submitTime:newDate().toLocaleString(),progress:100};}returnp;});}

四、UI 设计与交互体验

4.1 整体布局结构

┌─────────────────────────┐ │ 顶部数据统计栏 │ ← 进行中/已获奖/参赛数/团队人数 ├─────────────────────────┤ │ Tab 切换栏 │ ← 竞赛大厅 / 我的项目 ├─────────────────────────┤ │ 筛选标签栏 │ ← 按类型/级别筛选 ├─────────────────────────┤ │ │ │ 列表内容区 │ ← 竞赛卡片 或 项目卡片 │ │ └─────────────────────────┘

4.2 主题色与视觉规范

主色调:亮蓝色 #3B82F6

选择亮蓝色作为主题色的设计考量:

  1. 科技感契合:蓝色是科技、创新、智慧的代表色,与学科竞赛的学术属性高度匹配
  2. 专业感传递:相比活泼的暖色调,蓝色传递理性、专业、可信赖的视觉感受
  3. 状态扩展性强:蓝色系有丰富的色阶变化,可用于进度条渐变、级别区分等场景
  4. 护眼长时间使用:竞赛准备是长时间的活动,低饱和度蓝色视觉疲劳度更低

辅助色规范:

  • 主色调:#3B82F6(亮蓝色)
  • 进度条填充:#3B82F6 → #60A5FA 渐变
  • 国家级竞赛:#EF4444(红色标签,最高优先级)
  • 省级竞赛:#F59E0B(琥珀色标签)
  • 校级竞赛:#6B7280(灰色标签)
  • 获奖高亮:#F59E0B(金色徽章)

4.3 状态视觉区分表

项目状态进度条颜色状态标签操作按钮
进行中蓝色渐变蓝色实心标签更新进度、添加成员
待提交蓝色满格蓝色闪烁标签提交作品
已提交绿色满格绿色实心标签查看详情
已获奖金色渐变金色徽章 + 奖项名查看证书
未获奖灰色满格灰色空心标签复盘总结
竞赛级别标签颜色视觉权重排序优先级
国际级深紫色最高1
国家级红色2
省级琥珀色3
校级灰色4

五、关键技术点解析

5.1 进度条的设计与实现思路

进度条是项目管理类应用的核心视觉组件,设计时需要考虑多个维度:

视觉设计三要素:

  1. 背景轨道:浅灰色背景,定义进度条的总长度和边界
  2. 填充进度:主题色渐变填充,宽度随进度值变化
  3. 进度文本:百分比数字,放在进度条右侧或内部

交互设计要点:

  • 进度变化时增加平滑过渡动画,避免生硬跳动
  • 不同阶段使用不同颜色(如0-30%起步、30-80%进行中、80-100%冲刺)
  • 关键节点(25%/50%/75%/100%)可增加里程碑标记

技术实现方案:
在 ArkUI 中,可以使用 Stack 组件叠加背景和填充,通过 width 属性控制填充比例,配合 animation 实现平滑过渡。

5.2 多对多关系的数据建模

学生和竞赛之间本质上是多对多关系:一个学生可以参加多个竞赛,一个竞赛有多个学生参加。

本项目的简化方案:
通过 Project 中间表实现关联,Project 同时持有 competitionId 和成员列表,形成"竞赛-项目-成员"的三级结构。

生产环境的标准方案:

  • 建立 User 表、Competition 表、Team 表、TeamMember 表
  • Team 关联 Competition,TeamMember 关联 Team 和 User
  • 支持一个用户加入多个团队,一个团队对应一个竞赛

这种设计虽然复杂,但支持更丰富的业务场景,如跨项目人员复用、历史队伍复用等。


六、常见问题与优化建议

踩坑点 1:进度值边界溢出

问题表现:用户连续点击增加进度,导致进度超过100%或低于0%
解决方案:更新进度时使用Math.max(0, Math.min(100, value))进行边界钳制

踩坑点 2:成员重复添加

问题表现:同一个人被多次添加到团队中
解决方案:添加前根据学号或姓名查重,重复则提示不添加

踩坑点 3:截止时间计算错误

问题表现:跨时区或日期格式问题导致倒计时不准
解决方案:统一使用时间戳存储和计算,展示层再格式化

踩坑点 4:竞赛列表排序混乱

问题表现:筛选后排序逻辑失效,已截止的竞赛排在前面
解决方案:按状态分组排序(报名中优先),同状态内按截止时间升序

优化方向

  1. 增加竞赛日历视图,以月历形式展示各竞赛时间节点
  2. 实现组队大厅功能,支持发布招人信息和寻找队伍
  3. 接入导师匹配系统,根据竞赛类型推荐指导老师
  4. 增加作品互评功能,赛前互相评审提升作品质量

七、项目总结与扩展方向

核心收获

通过完成竞赛报名与项目管理项目,你将掌握:

  • 多模型关联的数据结构设计方法
  • 进度条组件的实现与动画优化
  • 团队成员增删改的完整管理逻辑
  • 列表筛选与多维度排序的实现技巧

后续扩展功能

  • 👥组队大厅:发布招人帖,浏览队伍信息,一键申请加入
  • 👨‍🏫导师匹配:根据竞赛类型和研究方向智能推荐指导老师
  • 📝作品互评:赛前匿名互评,互相提建议共同提升
  • 赛程提醒:重要时间节点自动推送提醒,不错过截止日期
  • 🏆证书生成:获奖后自动生成电子证书,支持分享和下载
  • 📊竞赛日历:月视图展示所有竞赛安排,一目了然

运行效果

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/24 20:46:56

类中的流操作符的重载

目录 摘要&#xff1a; 一&#xff1a;理解cout的本质 二&#xff1a;<<操作符的重载 问题1&#xff1a;参数颠倒 问题2&#xff1a;无法访问私有成员变量 问题3&#xff1a;无法连续使用<< 问题4&#xff1a;最终版本 三&#xff1a;>>操作符的重载…

作者头像 李华
网站建设 2026/7/24 20:46:43

河南精密机加工工厂|10 人 SolidWorks+UG 共享云主机完整配置方案

河南本地精密机加工企业以五金精密零部件、汽车结构件、工装夹具、模具加工为主&#xff0c;研发团队一般 8–10 人&#xff0c;同时使用 SolidWorks 做零件 / 工装建模、UG 做分型与多轴刀路编程。传统一人一台工作站投入高、新旧电脑性能参差不齐、图纸分散易流失、车间电磁干…

作者头像 李华
网站建设 2026/7/24 20:45:21

宇树 G1/H1 人形机器人动作捕捉与实时模仿系统

该系统本质上不是传统的“机器人自己规划路线”&#xff0c;而是一套&#xff1a; 人体动作采集 实时遥操作 动作重定向 全身平衡控制 示教数据训练 系统&#xff0c;它要解决的核心问题不是“机器人从哪里走到哪里”&#xff0c;而是&#xff1a; 人做出一个动作后&#x…

作者头像 李华
网站建设 2026/7/24 20:43:54

统计学,是“万金油”还是“就业难”?

每年毕业季&#xff0c;“统计学找工作难吗&#xff1f;”这个问题总会萦绕在许多统计学子心头。一方面&#xff0c;大数据、人工智能的浪潮似乎让数据相关专业炙手可热&#xff1b;另一方面&#xff0c;面对市场上琳琅满目的技术岗位要求&#xff0c;许多普通学生又感到迷茫和…

作者头像 李华
网站建设 2026/7/24 20:43:45

2026企业AI Agent落地指南:从0到1实现业务价值增长(小白程序员必看)

本文详细解析了企业级AI Agent的四大进化路径&#xff0c;揭示了多数企业仅停留在浅层应用的原因。文章深入剖析了AI投入无回报的三大落地死穴&#xff1a;盲目算力消耗、数据孤岛及传统流程不兼容&#xff0c;并提供了客服营销、标准化业务闭环等优选落地场景。同时&#xff0…

作者头像 李华