【共创季稿事节】毕业季·鸿蒙同行:我用鸿蒙做毕设,也做了一个帮毕业生做毕设的鸿蒙应用

【共创季稿事节】毕业季·鸿蒙同行:我用鸿蒙做毕设,也做了一个帮毕业生做毕设的鸿蒙应用

本文参与方向:方向3-毕业季-毕业生在毕业设计中使用鸿蒙技术的作品分享

我的毕业设计是一款鸿蒙应用,而它的主题,恰恰是"帮毕业生管理毕设全流程"。本文完整记录这款「鸿蒙毕设伴侣 GraduAssist」从构思、架构、AI 接入到手机与鸿蒙 PC 双端运行的全过程,也记录我从一个连 ArkTS 都不会的学生,成长为鸿蒙开发者的这段路。

一、写在前面:一个毕业生的自白

我是一名 2026 届计算机专业的应届毕业生。半年前,当我需要确定毕业设计选题时,摆在面前的有很多"稳妥"的选择——一个 Web 后台、一个安卓 App、一个小程序。但我最终选了一条当时看起来更"冒险"的路:用 HarmonyOS 从零做一款原生应用

原因有两个。其一,鸿蒙生态正在快速崛起,作为一个即将走向就业市场的学生,我想赌一个更有前景的方向;其二,说实话,我想做点不一样的东西,让我的毕设在答辩现场能被记住。

但真正动手时,我立刻慌了。我发现自己被两件事同时压着:一边要学一门全新的技术(ArkTS/ArkUI 我完全没接触过),一边要应付毕设本身那一整套让人头大的流程——开题报告、文献综述、实验、论文初稿、查重降重、答辩 PPT……每一项都有 deadline,散落在导师的微信、学院的通知、教务系统里,我经常记了这个忘了那个。

有天深夜赶开题报告时,我突然想到:我既然要用鸿蒙做一个毕设作品,为什么不干脆做一个"帮毕业生管理毕设"的应用?这样一来,我的毕设作品本身,就成了我这段毕业季经历的最佳注脚——用我正在学的鸿蒙技术,解决我正在经历的毕业焦虑。

这个想法让我兴奋。于是有了这款应用——鸿蒙毕设伴侣 GraduAssist。它把毕设进度看板、AI 论文助手、答辩演练、以及我自己的鸿蒙学习成长记录,整合在一个应用里。

它全程在华为 MateBook Pro(鸿蒙 PC)上开发,同时适配手机端运行。先看一眼它跑在鸿蒙 PC 上的样子——这是毕设看板页:

窗口化运行在鸿蒙 PC 桌面,我毕设的六个阶段一目了然:开题、文献已完成,"完成鸿蒙应用核心功能开发"还剩 3 天(正是我写这篇文章时的真实状态),后面的初稿、查重、答辩依次排开。总进度 33%——是的,写这篇文章时我的毕设也才刚过三分之一,我们一起加油。

下面,我完整拆解这款应用是怎么一步步做出来的,也顺带聊聊我作为一个鸿蒙新手,踩过的坑和学到的东西。

二、需求梳理:一个毕业生真正需要什么

在写代码前,我先以"用户"(也就是我自己)的身份,列出了毕业季最痛的几个需求:

  1. 毕设进度会失控——那么多阶段、那么多 deadline,需要一个地方统一管理、提醒。
  2. 论文写作太痛苦——摘要不够学术、大纲没思路、文献读不完、查重率过高,如果有个"AI 导师"帮忙就好了。
  3. 答辩心里没底——不知道评委会问什么,临场容易慌,需要提前演练。
  4. 学习没有正反馈——学鸿蒙的过程很孤独,如果能记录自己的成长和认证进度,会更有动力。

这四个需求,正好对应了应用的四个 Tab:看板、论文、答辩、成长。需求驱动设计,这是我从这个项目学到的第一课——先想清楚"给谁用、解决什么问题",再动手写代码,比一上来就堆功能靠谱得多。

三、技术选型与架构:新手也要讲究分层

3.1 为什么是 HarmonyOS + ArkTS

选 HarmonyOS 是毕设的前提,但深入之后我真切感受到它的几个好处:

  • 声明式 UI(ArkUI)开发效率很高,Column/Row/@State这套写起来直观,对新手友好;
  • 一次开发、多端部署——同一套代码能同时跑在手机和鸿蒙 PC 上,这对我这个"在 PC 上开发、想在手机上演示"的场景太合适了;
  • ArkTS 的强类型——虽然一开始被它的严格搞得很痛苦,但后来发现它逼着我把代码写规范,反而少了很多运行时 bug。

3.2 架构分层

作为新手,我最初的代码是"面条式"的——所有逻辑塞在一个页面文件里。写到第二个功能就乱得改不动了。痛定思痛,我重构成清晰的四层:

entry/src/main/ets/ ├── entryability/ 应用入口(生命周期、窗口、安全区) ├── common/ 通用层(主题、AI 配置、时间工具) ├── model/ 数据与服务层(数据模型、持久化、AI 服务) └── pages/ UI 层(四个功能页 + 主壳)

具体文件:

├── common/ │ ├── Theme.ets 深蓝学术科技风主题(颜色/圆角常量) │ ├── AIConfig.ets 模型服务配置 + 论文导师系统提示词 │ └── TimeUtil.ets deadline 天数计算、阶段配色 ├── model/ │ ├── GraduStore.ets 数据模型 + 持久化(毕设/成长/认证) │ └── AIService.ets AI 服务:多轮对话 + 单轮任务 └── pages/ ├── Index.ets 四 Tab 主壳 ├── BoardTab.ets 毕设看板 ├── PaperTab.ets AI 论文助手 ├── DefenseTab.ets 答辩演练 └── GrowthTab.ets 我的成长

分层的核心是"单一职责":UI 层只管展示,不碰网络;所有 AI 交互收敛在AIService;所有数据读写收敛在GraduStore;配置和工具函数集中在common。这样即使是新手,改起来也不容易出错——想改提示词就去AIConfig,想调 UI 就去对应的Tab,互不干扰。这是我学到的第二课:好的架构,是新手对抗复杂度的最好武器。

四、功能一:毕设看板——把失控的 deadline 管起来

看板是这个应用的地基,也是我用得最勤的功能。它要解决"进度失控"的痛点,核心是三件事:总进度可视化、任务清单管理、deadline 倒计时

4.1 数据模型

先定义毕设阶段任务的结构。作为学过的第一课,我给每个模型都写了显式interface(ArkTS 强制要求,否则报arkts-no-untyped-obj-literals):

exportinterfaceMilestone{id:string;stage:string;// 阶段:开题/文献/实验/初稿/查重/答辩title:string;dueTime:number;// 截止时间戳 msdone:boolean;}exportconstSTAGES:string[]=['开题','文献','实验','初稿','查重','答辩'];

这里有个体验上的小心思:应用首次运行时,我会注入一套示例任务(我自己毕设的真实阶段),让用户打开就能看到一个填充好的看板,而不是空荡荡的界面:

staticasynclistMilestones():Promise<Milestone[]>{constraw=awaitGraduStore.store.get(KEY_MILESTONES,'')asstring;if(raw===''){// 首次运行constseed=demoMilestones();// 注入示例数据awaitGraduStore.saveMilestones(seed);returnseed;}constarr=JSON.parse(raw)asMilestone[];returnarr.sort((a,b)=>a.dueTime-b.dueTime);// 按 deadline 排序}

4.2 deadline 倒计时引擎

"还剩几天"这个信息对毕业生太重要了。我在TimeUtil里写了一套计算逻辑,把时间戳转成人性化的文案和颜色:

exportfunctiondueText(due:number,done:boolean):string{if(done){return'已完成';}constn=daysLeft(due);if(n<0){return'已逾期 '+(-n)+' 天';}if(n===0){return'今天截止';}if(n===1){return'明天截止';}return'还剩 '+n+' 天';}exportfunctiondueColor(due:number,done:boolean):string{if(done){returnC.ok;}// 绿色constn=daysLeft(due);if(n<0){returnC.danger;}// 逾期红if(n<=3){returnC.gold;}// 临近黄returnC.textSub;// 常规灰}

于是逾期的任务标红、三天内的标黄——一眼就知道哪个火烧眉毛了。这种"用颜色传递紧迫感"的设计,比单纯列个日期有用得多。

4.3 进度可视化与交互

看板顶部是一张渐变进度卡,用Progress组件展示完成比例,并把最近的 deadline 单独拎出来提醒。任务列表支持点击勾选完成(带删除线动画)、右侧删除、底部弹窗新增。这些都是基础的@State驱动 UI:

asynctoggle(id:string):Promise<void>{this.list=awaitGraduStore.toggleMilestone(id);// 更新并刷新}

一个新手容易踩的坑:更新数组后,要让 ArkUI 重渲染,ForEach的键值要能反映变化。我把键设成m.id + m.done,这样勾选状态一变,对应项就会重绘。

五、功能二:AI 论文助手——给自己请一位 24 小时导师

这是整个应用技术含量最高、也是我最得意的部分。论文写作的痛苦,AI 能极大缓解——但前提是把提示词设计好,让 AI 真正像个导师

5.1 把大模型定位成"毕设导师"

我在系统提示词里给 AI 设定了明确的人设:

staticreadonlysystemPrompt:string='你是一位资深的毕业设计指导老师,熟悉论文写作、答辩流程与学术规范。'+'请用专业、条理清晰、鼓励性的中文,帮助毕业生完成论文润色、大纲生成、'+'答辩问题预测等任务。回答要具体、可操作,避免空泛。';

“资深指导老师”“专业、鼓励性”“具体、可操作”——这些词决定了 AI 回复的语气和质量。给模型一个清晰的角色,是提示工程里性价比最高的技巧。

5.2 任务模板:降低使用门槛

论文助手提供四个预设任务:润色摘要、生成大纲、文献要点、降重建议。每个任务背后是一个提示词模板,用户只要选任务、贴内容,剩下的交给模板:

privatetasks:QuickTask[]=[{label:'润色摘要',tpl:'请帮我润色下面这段论文摘要,使其更学术、流畅、精炼,并指出改进点:\n{X}'},{label:'生成大纲',tpl:'我的毕业设计题目/主题是:{X}。请帮我生成一份详细的论文章节大纲(含各章要点)。'},{label:'文献要点',tpl:'请提炼下面这段文献内容的核心观点、方法与结论,用要点列出:\n{X}'},{label:'降重建议',tpl:'下面这段文字疑似重复率偏高,请在保持原意的前提下改写降重,并给出修改说明:\n{X}'}];

发送时用用户输入替换模板里的{X}

constprompt=this.messages.length===0?this.tasks[this.activeTask].tpl.replace('{X}',raw)// 首轮:套模板:raw;// 后续:自由追问

这个设计的妙处在于:用户不用自己写提示词,选个任务就行;同时首轮之后还能自由追问,形成多轮对话。下图是我用"生成大纲"功能,输入毕设主题后 AI 给出的完整章节大纲:

再看"润色摘要"——我把一段口语化的摘要丢给它,它不仅润色成了学术表达,还用表格列出了每一处改进点和优化策略:

顺带一提:AI 润色时可能会"帮"你加上一些量化数据(如复用率、时延),这些数据一定要自己核实,不能直接写进论文——这是学术规范,AI 只是助手,不能代替真实实验。这一点我在应用的说明里也特意提醒了。

5.3 统一的 AI 服务封装

论文助手、答辩预测、答辩点评三处都要调大模型,我把它抽成统一的AIService,提供多轮chat和单轮task两个方法:

exportclassAIService{/** 多轮对话 */staticasyncchat(history:ChatMessage[]):Promise<string>{constmessages:ChatMessage[]=[{role:'system',content:AIConfig.systemPrompt}];for(constmofhistory){messages.push(m);}// ... 发请求、解析、异常兜底}/** 单轮任务:便捷封装 */staticasynctask(prompt:string):Promise<string>{returnAIService.chat([{role:'user',content:prompt}]);}}

网络请求用鸿蒙@kit.NetworkKit的 http 模块,OpenAI 兼容协议,readTimeout给到 40 秒(论文类回复较长)。任何失败都返回友好中文提示,绝不让界面卡死:

try{constresp=awaitclient.request(AIConfig.endpoint,{/* ... */});if(resp.responseCode!==200){return`(请求失败:${resp.responseCode}`;}consttext=AIService.parse(`${resp.result}`);returntext!==''?text:'(助手暂无返回,请重试)';}catch(e){return'(网络异常)请检查连接后重试';}finally{client.destroy();// 新手易忘:一定要释放}

六、功能三:答辩演练——让 AI 当我的模拟评委

答辩是毕业季最让人紧张的一关。我最怕的是"被问到没准备的问题当场卡壳"。所以我设计了这个功能:输入毕设题目 → AI 预测评委可能问的问题 → 我逐题作答 → AI 点评我的回答

6.1 预测答辩问题

关键在于让 AI 站在"评委"视角出题,并且只输出问题列表,方便我解析成一条条卡片:

constprompt=`我的毕业设计题目是「${this.topic.trim()}」。`+`请站在答辩评委角度,预测 5 个最可能被问到的答辩问题。`+`只输出问题列表,每行一个问题,用数字编号,不要额外说明。`;

拿到回复后,解析层要处理各种编号格式(1.1、Q1:……),我用正则统一剥离行首编号:

privateparseQuestions(text:string):string[]{constlines=text.split('\n');constout:string[]=[];for(constrawoflines){constline=raw.trim();if(line===''){continue;}constcleaned=line.replace(/^[Qq]?\s*\d+\s*[\.\、\:\))\.]?\s*/,'').trim();if(cleaned!==''){out.push(cleaned);}}returnout.slice(0,8);}

这又是一次"驯服大模型输出"的实践——即使我要求它只给列表,它偶尔还是会加编号或空行,解析层必须容错。下图是我输入"基于 HarmonyOS 的智慧生活助手应用设计与实现"后,AI 预测的 5 个答辩问题:

不得不说,AI 出的问题相当专业——“为什么选 HarmonyOS 而非 Android/iOS”“分布式能力做了哪些落地”“如何保障隐私安全”“是否完成真机验证”——这些几乎就是答辩现场评委的高频提问。看到这些问题,我心里对答辩的底气一下就足了。

6.2 作答与 AI 点评

每个问题下有"练习作答",我写下回答后提交,AI 会以评委身份点评(优点、不足、改进建议,控制在 150 字内):

constprompt=`答辩问题:${this.questions[i]}\n`+`学生的回答:${this.answer.trim()}\n`+`请作为答辩评委,简要点评这个回答(优点、不足、改进建议),控制在 150 字内。`;

这就形成了一个"出题 → 作答 → 点评"的完整闭环,相当于把答辩现场提前搬到了自己的电脑上反复演练。

七、功能四:我的成长——记录从学生到开发者的路

如果说前三个 Tab 解决的是"事",那第四个 Tab「成长」承载的是"人"——我这段从零学鸿蒙的心路历程。它有三块内容:认证备考清单、学习里程碑时间线、模型配置。

7.1 认证备考清单

学鸿蒙绕不开认证。我把 HarmonyOS 应用开发者认证的关键考点做成一个可勾选的清单,掌握一项勾一项:

functiondemoCert():CertItem[]{return[{id:'c1',name:'HarmonyOS 应用开发者基础认证',done:true},{id:'c2',name:'HarmonyOS 应用开发者高级认证',done:false},{id:'c3',name:'ArkTS 语言与 ArkUI 框架',done:true},{id:'c4',name:'Stage 模型与 Ability 生命周期',done:false},{id:'c5',name:'分布式与一多能力',done:false}];}

看着"已掌握 2/5"慢慢往上涨,是很实在的正反馈。

7.2 学习里程碑时间线

这一块对我意义特殊。我用一条竖向时间线,记录了自己学鸿蒙的关键节点:

  • 2026.06.01 —— 开始学习 ArkTS 与 ArkUI,跑通第一个 Hello World
  • 2026.06.16 —— 掌握了 @State/@Prop 状态管理,能写多页面应用
  • 2026.07.01 —— 成功接入大模型 API,做出了 AI 对话功能

时间线用Circle节点 +Divider连线实现:

Column(){Circle({width:10,height:10}).fill(C.primary)if(i<this.growth.length-1){Divider().vertical(true).color(C.stroke).strokeWidth(2).height(30)}}

一个多月,从连 ArkTS 语法都看不懂,到能独立做出一个接入 AI 的四页应用——把这些节点记录下来,我才真切感受到自己的成长。这也是应用名"鸿蒙同行者"的含义:这段路,应用陪我一起走过。下图是成长页在鸿蒙 PC 上的样子:

顶部紫色渐变卡"从学生到鸿蒙开发者的成长之路",下面是认证清单和里程碑时间线——这一页,我把它当成自己毕业季的一份纪念。

八、一次开发,两端运行:手机 + 鸿蒙 PC

这是我这个作品最想强调的技术点,也是最契合鸿蒙特色的地方——同一套 ArkTS 代码,同时跑在鸿蒙 PC 和手机上,无需修改。

8.1 声明支持的设备

module.json5里声明设备类型,把 PC(2in1)和手机都纳入:

"deviceTypes": ["phone", "tablet", "2in1"]

8.2 弹性布局是多端适配的根基

能做到一套代码跑两端,靠的是全程弹性布局——宽度用layoutWeight、百分比、Flex自动换行,绝不写死像素。安全区(手机刘海 / PC 窗口边框)统一在入口计算、全局共享:

consttop=win.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM);constbottom=win.getWindowAvoidArea(window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR);AppStorage.setOrCreate('safeTop',px2vp(top.topRect.height));AppStorage.setOrCreate('safeBottom',px2vp(bottom.bottomRect.height));

前面所有页面都用@StorageProp('safeTop')读取安全区来避让,这套逻辑在手机和 PC 上都成立。

8.3 两端各有所长

同样的应用,在两端有不同的使用场景,体验各有千秋。

鸿蒙 PC 端:适合"坐下来认真处理"的场景——写论文时,我把应用开在电脑一侧,用物理键盘往论文助手里贴大段文字、改摘要,效率远高于手机。大屏也让看板的六个阶段、答辩的多个问题一览无余。

手机端:适合"随时查看、随手记录"的场景——躺床上刷一眼看板还剩几天 deadline,或者突然想到一个学习心得,掏出手机在成长页记一笔。

下面是应用跑在手机模拟器(Mate 80 Pro,HarmonyOS 6.1.0)上的样子。先看毕设看板——同样的代码,在手机竖屏上自动适配成紧凑的单列布局:

再看成长页在手机上的表现,认证清单和时间线依然清晰:

从鸿蒙 PC 大屏到手机竖屏,我没有为任何一端单独写界面——这就是"一次开发、多端部署"的威力。对一个人力有限的毕业生来说,这个特性意味着我能用一份精力,交付一个覆盖多设备的完整作品,这在答辩时也是一个很有说服力的亮点。

九、开发环境与真机调试

整个项目用 DevEco Studio 开发。我的目标设备里既有鸿蒙 PC 真机HUAWEI MateBook Pro,也有手机模拟器Mate 80 Pro,随时切换验证多端表现:

从设备下拉列表能看到鸿蒙生态覆盖之广——从穿戴、手机、平板到 MateBook Pro,SDK 已经到了 HarmonyOS 6.1.0。作为学生,能接触到这么完整的一套开发工具链和真机环境,我觉得很幸运。选中设备直接 Run,几百毫秒就构建完成,应用就跑起来了。

十、我踩过的坑(新手血泪)

作为一个鸿蒙新手,这个项目让我踩了不少坑,记录下来给同样起步的同学参考:

坑一:ArkTS 的强类型。这是最先给我"下马威"的。所有对象字面量必须有显式interface,不然编译报arkts-no-untyped-obj-literals。我一开始随手写{ role: 'user', content: x }就报错,后来老老实实给每个结构都定义了interfaceChatMessageMilestoneCertItem……)。习惯之后,反而觉得代码更清晰、bug 更少。

坑二:@State数组不刷新。增删任务后界面不更新,卡了我半天。后来才知道要this.list = this.list.slice()做浅拷贝赋值,或者让ForEach的键能反映数据变化(我用m.id + m.done)。

坑三:大模型输出不听话。让它"只输出编号问题列表",它偶尔还是加空行、加说明。解决靠解析层用正则容错,绝不能假设模型 100% 听话。

坑四:网络超时。论文润色、大纲生成的回复很长,默认超时不够,要把readTimeout调到 40 秒。

坑五:忘了client.destroy()http 客户端用完不释放会泄漏,我在finally里统一销毁。

坑六:多端安全区。一开始只考虑了手机刘海,在鸿蒙 PC 上标题被窗口边框挡住。后来统一用getWindowAvoidArea计算,两端都正常了。

这些坑,每一个当时都让我抓狂,但填完之后,我对鸿蒙开发的理解就深了一层。踩坑,其实就是成长本身。

十一、总结:作品即成长

回头看这个项目,它对我的意义远超一个毕业设计的分数。

从技术上,我完整走通了一款现代 AI 应用的全流程:声明式 UI、状态管理、本地持久化、大模型接入、提示工程、多端适配。我从一个连 ArkTS 都不认识的学生,变成了一个能独立做出接入 AI、覆盖手机与鸿蒙 PC 双端应用的开发者。

从意义上,这个作品是我毕业季的一面镜子——它管理着我的毕设进度,辅导着我的论文,陪练着我的答辩,也记录着我学鸿蒙的每一步。我用鸿蒙做了一个帮自己度过毕业季的工具,而做这个工具的过程,本身就是我毕业季最重要的收获。

如果你也是一名即将或正在做毕设的同学,我想把这段经历里最真实的三点建议留给你:

  1. 别怕选新技术。鸿蒙对新手很友好,官方文档、认证课程、社区都很完善。选一个有前景的方向,本身就是给自己的未来加分。
  2. 让你的作品和你自己产生联系。我做"毕设伴侣",是因为我正需要它。当作品解决的是你真实的痛点,你会有源源不断的动力,答辩时也讲得出真情实感。
  3. 记录你的成长。哪怕就像我在应用里做的那样,简单记几行"今天跑通了 Hello World"。回头看时,这些记录会告诉你:你真的走了很远。

毕业季,鸿蒙同行。愿每一位正在为毕设焦头烂额的同学,都能顺利上岸,也都能在鸿蒙这条路上,找到属于自己的成长。

如果你对这个项目、对鸿蒙开发有任何问题,欢迎交流——我们都是这条路上的同行者。