
每年到了三四月毕设群里就开始出现同一种焦虑题目发下来时觉得自己挑了个挺大的方向一查资料才发现班上有三个同学做的是同一套“图书管理系统”隔壁组还有人在用同一个开源商城模板改名字。更麻烦的是传统 Web 管理系统的题目老师已经看了好几年哪怕功能做得完整答辩时也很难讲出新意。如果你现在也卡在这个阶段不妨换个思路把选题放到“鸿蒙原生应用开发”这条赛道上而不是继续挤在 Vue 全家桶和 SSM 管理系统里。这篇文章要聊的项目是一个基于鸿蒙系统、使用 ArkTS 原生开发的小红书类 APP 毕设选题。它不是一个只做信息展示的简单 Demo而是把“社交笔记 电商商城 Web 后台”三类典型业务放进了一个项目里。更直白地说这套组合能同时满足几个诉求技术上有鸿蒙原生开发的内容可以讲功能上有 C 端用户端和 B 端管理端可以展示答辩时有真实场景可以演示而且源码可以拿来做二次开发和深入学习。读完这篇文章你会搞清楚这套项目应该怎么拆解、哪些技术点值得写进论文、从零开始怎么搭、运行过程中会遇到什么坑以及拿到源码之后应该怎么把它变成自己能讲清楚的东西。先说一个明确判断这类项目的价值不在于“仿小红书”这个外壳而在于它同时覆盖了鸿蒙应用的 UI 开发、状态管理、网络请求、权限申请以及 Web 后台的数据接口和数据库设计。这些内容正好对应一篇合格工程类毕设论文的核心章节也正好是当前鸿蒙开发者岗位招聘里最常考察的基础能力。1. 为什么这个选题值得做毕设撞车背后的选择逻辑毕设选题“撞车”的本质不是题目重复而是可选方向太少。大多数学校允许学生自拟题目但大家接触过的技术栈基本被框死在课堂作业范围内Java 版的管理系统、MySQL 数据库设计、HTML 页面加一点 JavaScript。于是你会发现全年级近三分之一的人在做“XX管理系统”另外三分之一在做“XX商城”剩下的人在改这两个项目的皮。老师评审时早就审美疲劳了。要跳出这种局面不是去找一个更冷门的业务场景而是换一个“技术载体”。同样是社交、电商、内容管理这套业务跑在鸿蒙原生应用里它的技术含量和展示效果是完全不一样的。鸿蒙生态这两年处于快速扩张期终端设备数量在持续增长各厂商对鸿蒙开发者的需求也在上升。对这个趋势我个人的判断是鸿蒙原生应用开发正处于人才缺口期现在把它作为毕业设计方向属于典型的“技术红利期入场”比等生态完全成熟后再学竞争要小得多。回来看这个项目的业务设计。它包含三个模块模块对应角色核心功能技术关键词鸿蒙 APP 用户端C 端用户笔记发布与浏览、点赞收藏评论、商品浏览、购物车、模拟下单ArkTS、ArkUI、状态管理、网络请求Web 管理后台管理员用户管理、笔记内容审核、商品管理、订单管理、数据统计Spring Boot、Vue、MySQL服务端接口前后端连接登录鉴权、笔记/商品/订单接口、图片上传RESTful API、JWT、文件存储这种“用户端 管理端 服务端”三段式结构在毕设里是非常完整的工程闭环。它不像单页应用那样只是前端展示也不像传统管理系统只有 CRUD 操作。它真正让评审老师眼前一亮的地方在于你的演示是从一部鸿蒙手机开始的而不是从浏览器地址栏开始的。2. 项目功能拆解与技术选型先看清全貌再动手拿到这类项目的第一步不是打开 IDE 写代码而是把功能点拆成可以验证的“需求条目”。很多同学做毕设失败不是代码能力不够而是从头到尾不清楚自己做的东西到底有哪些功能、哪些是核心、哪些是附加。推荐用一张功能清单来管理用户系统注册、登录、Token 鉴权、个人信息编辑。笔记社区图文笔记发布、首页推荐流、笔记详情、点赞、收藏、评论。互动模块关注关系、粉丝列表、消息通知可简化为未读列表。电商模块商品列表、商品详情、加入购物车、下单结算、模拟支付、订单列表。后台管理数据看板、笔记审核、用户禁用、商品上架下架、订单状态管理。公共能力图片上传、分页加载、下拉刷新、上拉加载更多、异常加载态。技术选型上这个项目天然分成客户端和服务端两条线。客户端只能选鸿蒙生态开发语言是 ArkTSUI 框架是 ArkUI开发工具是 DevEco Studio。ArkTS 是基于 TypeScript 扩展出来的语言语法上对前端同学非常友好但不建议把它当成纯前端项目来写。鸿蒙的 UI 是声明式范式页面结构写在build()方法里类似 Android Jetpack Compose 或 SwiftUI 的思路和传统 HTML 的 DOM 操作有很大区别。服务端选型则比较自由。最省事的方案是“Spring Boot MyBatis-Plus MySQL”因为网上参考资料最多、部署成本低、论文里也好写如果想体现一点新技术也可以换成“Node.js Express MongoDB”但这会让学生端和服务端的语言统一成 TypeScript 体系对前端基础好的同学更友好。这里说实话我更推荐 Spring Boot不是因为它多先进而是因为毕设评审老师通常对它最熟悉问问题也能问到点子上你反而更容易准备。关于“电商商城”部分必须提醒一点不要接真实的微信支付或支付宝支付个人开发者没资质而且不安全的支付接入容易被攻击毕设里用“模拟支付”就行。在用户点击支付后前端弹出一个模拟收银台输入任意金额确认即可完成订单服务端把订单状态从“待支付”改成“已支付”。这套流程完全够用了。3. 鸿蒙原生开发的核心概念Stage 模型和 ArkTS 必须理解到什么程度很多第一次接触鸿蒙的同学会拿开发 Android 或者开发小程序的经验去套结果在项目结构上就先懵了。鸿蒙应用从 API 9 开始全面推行 Stage 模型这和早期的 FA 模型差别很大。理解 Stage 模型是做这个项目的分水岭。Stage 模型的核心概念简单来说就是你构建的应用分为多个Module。一个工程通常有一个entry模块作为应用入口后续可以加library模块放公共代码。每个模块内部有两类关键文件module.json5模块配置描述模块名称、入口页面、权限声明。EntryAbility应用启动的主入口负责加载首页WindowStage并设置页面路由。ArkTS 代码的页面则写在ets目录下每个页面由Entry装饰器标记为可进入页面Component装饰器表示这是一个组件组件内的状态由State、Prop、Link等装饰器管理。对于一个笔记应用来说最常用的就是State—— 当你请求完数据、把数据赋值给一个State数组时页面会自动刷新不需要像小程序那样去通过setData手动触发视图更新。ArkTS 的声明式语法长这样// 一个最简单的页面组件 Entry Component struct IndexPage { State message: string 你好鸿蒙; build() { Row() { Column() { Text(this.message) .fontSize(24) .fontWeight(FontWeight.Bold) } .width(100%) } .height(100%) } }理解这个结构之后再看这个小红书类 APP 的代码就不会一头雾水。因为所有的列表、卡片、弹出框本质上都是build()里的组件树只是组件类型变得更丰富了。比如笔记卡片是Column套Image和Text购物车商品行是Row套多个Column底部 Tab 导航则可以用系统提供的Tabs组件实现。ArkTS 还有一个需要特别重视的点它是“严格模式”的 TypeScript 子集不是所有 TypeScript 语法都能用。比如不允许使用any类型、部分动态类型特性受限代码要显式声明类型。刚写完普通 TS 项目再切到 ArkTS 时会觉得很不习惯但项目大了以后反而安全。类型收得越紧越不容易出现运行到一半才报错的问题。4. 环境准备与前置条件把工程从源码变成能跑的 APP如果拿到源码第一件事不是看业务代码而是先把环境配好。很多同学卡在“代码明明一样但我的工程就是编译不过”上问题往往出在环境不一致。这里给出一个通用环境清单具体版本号要结合你下载的 DevEco Studio 和鸿蒙 SDK 实际情况环境项建议操作系统Windows 10/11 或 macOS内存至少 16GB开发工具DevEco Studio官方渠道下载最新稳定版鸿蒙 SDK安装 DevEco Studio 时按推荐安装保持默认模拟器使用 DevEco Studio 自带的 Local Emulator真机准备一部 HarmonyOS 手机开启开发者模式Node.js有的调试工具链依赖建议安装 LTS 版本后端环境JDK 17、Maven 3.6、MySQL 8.x工程导入时推荐用 DevEco Studio 的“Open”直接打开源码目录而不是新建工程后复制文件。因为鸿蒙工程包含.hvigor、build-profile.json5、oh-package.json5等多个顶层配置文件手动复制容易漏文件导致构建失败。首次打开项目后IDE 会自动同步依赖。如果同步失败优先检查网络代理和 DevEco 的在线仓库地址。同步完成后先不要直接点运行应检查一下工程里的签名配置。如果你使用真机调试需要在File - Project Structure - Signing Configs里勾选“Automatically generate signature”如果只用模拟器则不需要签名也能跑通大部分功能。后端环境相对简单。把源码里的 SQL 文件导入 MySQL例如mysql -uroot -p xiaohongshu.sql再修改服务端配置文件里的数据库账号密码和端口启动 Spring Boot 项目。后端跑起来后通过浏览器访问http://localhost:8080/api/...能返回 JSON 数据就说明环境准备完成了。最后建议同时准备一个接口调试工具比如 Apifox 或 Postman。整个项目联调阶段你会在“App 页面、后端接口、数据库”三者之间来回切换一个顺手的多接口管理工具能省下大量时间。5. 核心功能实现示例从页面到接口的完整链路为了让讲解更有实操性这一节用一个完整链路来说明笔记首页列表从数据请求到页面展示到底是怎么串起来的。这是整款 APP 的核心流程也是面试或答辩时最可能被追问的部分。5.1 底部 Tab 导航与首页页面骨架底部导航使用 ArkUI 的Tabs组件实现。首页、商城、发布、消息、我的五个 Tab本质上是五个TabContent// entry/src/main/ets/pages/MainTab.ets Entry Component struct MainTab { State currentTab: number 0; build() { Tabs({ barPosition: BarPosition.End, index: this.currentTab }) { TabContent() { HomePage() } .tabBar(this.tabBuilder(0, 首页, $r(app.media.ic_home))) TabContent() { ShopPage() } .tabBar(this.tabBuilder(1, 商城, $r(app.media.ic_shop))) TabContent() { PublishPage() } .tabBar(this.tabBuilder(2, , $r(app.media.ic_add))) TabContent() { MessagePage() } .tabBar(this.tabBuilder(3, 消息, $r(app.media.ic_msg))) TabContent() { ProfilePage() } .tabBar(this.tabBuilder(4, 我的, $r(app.media.ic_me))) } .scrollable(false) .onChange((index: number) { this.currentTab index; }) } Builder tabBuilder(index: number, title: string, icon: Resource) { Column() { Image(icon) .width(24) .height(24) Text(title) .fontSize(12) .fontColor(this.currentTab index ? #FF2442 : #999999) } .justifyContent(FlexAlign.Center) .width(100%) .height(100%) } }这里要注意Builder是 ArkUI 特有的装饰器用来抽取重复 UI 片段。它和普通函数的区别在于Builder里可以直接写 UI 组件而普通函数只能返回逻辑值。5.2 封装网络请求工具类笔记列表的数据来自后端接口客户端需要有一个统一的 HTTP 请求封装。鸿蒙 SDK 提供了ohos.net.http模块新的工程通常通过kit.NetworkKit引入// entry/src/main/ets/common/HttpUtil.ets import { http } from kit.NetworkKit; import { BusinessError } from kit.BasicServicesKit; export class HttpUtil { static getT(url: string, token?: string): PromiseT { const httpRequest http.createHttp(); return new Promise((resolve, reject) { httpRequest.request(url, { method: http.RequestMethod.GET, header: { Content-Type: application/json, Authorization: token ? Bearer ${token} : }, connectTimeout: 10000, readTimeout: 10000 }).then((response: http.HttpResponse) { if (response.responseCode 200) { const data JSON.parse(response.result as string) as T; resolve(data); } else { reject(new Error(HTTP Error: ${response.responseCode})); } httpRequest.destroy(); }).catch((error: BusinessError) { reject(error); httpRequest.destroy(); }); }); } }这个封装的关键点有两个一是把泛型T透传给业务层让每个页面只关心自己的数据结构二是调用完request之后必须destroy()释放连接否则高并发场景下会内存泄漏。后面如果要用 POST 方法可以在这个类里继续扩展postT静态方法思路完全一致。5.3 首页笔记列表拿到网络封装之后首页的逻辑就变得很清晰aboutToAppear生命周期里请求接口把返回的数组赋值给State数组页面自动渲染。// entry/src/main/ets/pages/HomePage.ets import { HttpUtil } from ../common/HttpUtil; interface NoteItem { id: number; title: string; cover: string; authorName: string; likes: number; } Entry Component struct HomePage { State noteList: NoteItem[] []; aboutToAppear(): void { this.fetchNoteList(); } async fetchNoteList(): Promisevoid { try { const data await HttpUtil.getNoteItem[](http://your-server/api/notes); this.noteList data; } catch (error) { console.error(笔记列表加载失败 JSON.stringify(error)); } } build() { List({ space: 12 }) { ForEach(this.noteList, (item: NoteItem) { ListItem() { Column() { Image(item.cover) .width(100%) .height(180) .objectFit(ImageFit.Cover) .borderRadius(12) Row() { Text(item.title) .fontSize(16) .fontWeight(FontWeight.Medium) .maxLines(2) .textOverflow({ overflow: TextOverflow.Ellipsis }) Blank() Text(${item.likes} 赞) .fontSize(13) .fontColor(#999999) } .width(100%) .margin({ top: 8 }) Text(${item.authorName}) .fontSize(12) .fontColor(#999999) .margin({ top: 4 }) } .padding(10) .backgroundColor(Color.White) .borderRadius(12) } }, (item: NoteItem) item.id.toString()) } .layoutWeight(1) .padding(12) .backgroundColor(#F5F5F5) } }ForEach的第三个参数是键值生成器这里用item.id做唯一标识能提升列表更新的性能。界面中的Blank()组件用来占满剩余空间它会把点赞数推到右侧等价于 Web 里的justify-content: space-between。5.4 权限申请为什么应用里要弹窗问用户鸿蒙应用有很多权限需要动态申请。这个小红书类 APP 在发布笔记时要选择图片、在保存登录信息时可能要写入本地存储所以权限配置是必须的。权限分为系统权限和敏感权限两类普通权限在module.json5里声明就行用户可信的敏感权限要在代码里通过abilityAccessCtrl发起申请。先看module.json5里的声明{ module: { name: entry, type: entry, requestPermissions: [ { name: ohos.permission.INTERNET }, { name: ohos.permission.READ_MEDIA }, { name: ohos.permission.CAMERA } ] } }其中ohos.permission.INTERNET是基础权限申请后应用才能访问网络READ_MEDIA是读取媒体文件的敏感权限一般在相册选择图片时触发动态弹窗申请CAMERA是摄像头权限拍笔记封面时使用。注意敏感权限不能只写在配置文件里还必须调用requestPermissionsFromUser动态发起// 在发布页面中点击“选择图片”时触发 import { abilityAccessCtrl, common } from kit.AbilityKit; import { BusinessError } from kit.BasicServicesKit; async function requestMediaPermission(context: common.UIAbilityContext): Promiseboolean { const atManager abilityAccessCtrl.createAtManager(); try { const res await atManager.requestPermissionsFromUser(context, [ohos.permission.READ_MEDIA]); return res.authResults[0] 0; } catch (error) { const err error as BusinessError; console.error(权限申请失败: ${err.code}, ${err.message}); return false; } }这里最容易踩坑的是context的获取方式。在页面组件里不能直接拿到UIAbilityContext需要从getContext(this)获取再转型成common.UIAbilityContext。很多同学照着网上代码抄结果报类型不匹配就是因为这里没有转换。5.5 Web 后端的接口示例客户端这么多请求服务端必须有对应接口。以“笔记列表”为例后端返回的就是一个标准的 RESTful JSON// 文件路径src/main/java/com/example/harmony/controller/NoteController.java RestController RequestMapping(/api/notes) public class NoteController { Resource private NoteService noteService; GetMapping public ResultListNoteVO list(RequestParam(defaultValue 1) Integer page, RequestParam(defaultValue 10) Integer size) { PageNote notePage noteService.page(new Page(page, size)); ListNoteVO voList notePage.getRecords().stream() .map(note - new NoteVO(note)) .collect(Collectors.toList()); return Result.ok(voList); } }后端接口返回的字段要和前面 ArkTS 定义的NoteItem对应上否则客户端JSON.parse后拿到的字段全是undefined。后端接口设计时建议统一返回Result包装类里面包含code、message、data三个字段。这样客户端封装HttpUtil时可以根据code判断业务成功或失败而不只是依赖 HTTP 状态码。5.6 模拟支付与订单流程电商模块最怕学生一头扎进“支付集成”的坑。毕设项目不建议接真实支付而是做模拟支付用户在确认订单页面点击“立即支付”弹出一个自定义支付面板输入任意内容后调后端订单接口把状态改为已支付。这个流程在论文里可以写成“为满足演示环境要求使用模拟支付方式完成订单闭环”老师基本都会认可因为电商标的完整订单流演示出来了技术深度也已经足够。6. 运行结果与效果验证怎么判断项目真的跑通了项目跑通不是一个“点运行不报错”就算完成了而是需要分阶段验证。建议按下面的顺序做一次完整的冒烟测试每步确认后再进行下一步。第一步后端接口验证。浏览器访问http://localhost:8080/api/notes能看到 JSON 数据。如果接口 404先看控制台日志确认 Spring Boot 是否成功启动、数据库是否连接成功。如果数据库连不上优先检查 MySQL 服务、用户名密码、端口号。第二步模拟器编译运行。在 DevEco Studio 里选择entry模块点击 Run 按钮。编译过程如果出现 HS 错误优先看错误信息里的文件路径和行号大部分是 ArkTS 类型问题。把any改掉、把缺少的 import 补上通常就能解决。第三步用户端主流程验证。用账号登录进入首页能看到笔记列表下拉刷新能加载新数据点击笔记进入详情页可以点赞和收藏进入商城页可以加入购物车并完成一个模拟订单。这里也要测试异常情况断网时页面有没有加载失败提示而不是白屏。第四步管理后台验证。打开 Web 后台登录管理员账号能看到用户数量、笔记数量、订单数量统计。把笔记列表打开审核一篇客户端刚发布的笔记并设为“不通过”回到 APP 刷新这篇笔记应该从首页消失。这个过程既验证了前后端联动也验证了“审核机制”这个功能点。第五步真机测试。如果手边有鸿蒙手机建议至少做一次真机运行。真机上http://localhost访问不到电脑上的后端服务必须改成电脑的局域网 IP并在后端允许跨域访问。这一步非常容易踩坑后面会展开说。7. 常见问题与排查思路做这种多端项目运行阶段的问题会集中在几个位置。这里把最容易遇到的 6 类问题整理成一张排查表问题现象可能原因排查方式解决方案DevEco 编译慢或卡在同步依赖首次下载 SDK/依赖仓库慢或代理设置异常查看 IDE 日志检查 ohpm 源地址配置国内镜像仓库关闭不必要的代理ArkTS 代码一直标红报错SDK API 版本和项目声明不一致或用法不同查看模块build-profile.json5中compatibleSdkVersion统一 SDK 版本按当前 API 写法修改模拟器里请求后端接口失败模拟器无法访问电脑 localhost或后端没启动在模拟器浏览器访问接口地址把请求地址改成局域网 IP如http://192.168.x.x:8080真机访问后端失败手机和电脑不在同一局域网或后端防火墙拦截ping电脑 IP测试后端接口让手机和电脑连同一 Wi-Fi放行 8080 端口列表无法刷新加载State数据变更方式错误或 ForEach 键生成器不唯一在赋值处打日志确认数据到达页面用数组整体替换不使用索引修改原生数组键值改用 id发布笔记时无法选择图片敏感权限未动态申请或没有在配置文件声明查看应用安装后的权限设置补配置READ_MEDIA走requestPermissionsFromUser流程针对第 2 条再多说一句鸿蒙 API 迭代速度比较快不同版本对模块导入路径、组件写法都有影响。如果你手里的源码是旧版 API 写的在新版 DevEco Studio 里强行编译大概率会报错。这种情况下优先保证“界面能显示、接口能调通”不一定要追求把源码升级到最新的 API。毕设的核心是把功能讲清楚技术版本只要稳定、有据可查就行。8. 最佳实践与答辩加分项8.1 工程规范让它像“认真做过的项目”很多毕设源码一看就是赶出来的最大的问题是命名混乱有页面叫Page1接口返回字段有叫a的有叫address的。建议从第一天就建立规范ArkTS 页面文件统一放在pages目录公共组件放common/components请求方法统一走HttpUtil后端包名按controller/service/mapper/entity分层。数据库表设计用下划线命名实体类用驼峰命名必要时配置 MyBatis 的map-underscore-to-camel-case。8.2 安全边界不要把毕设变成“攻击靶子”这类项目涉及用户数据必须注意安全边界。后端接口要加 Token 校验不能把所有接口都放行。用户密码不能明文存数据库用 BCrypt 加密。管理员接口和普通用户接口要区分权限。图片上传要限制文件类型和大小防止有人上传恶意脚本。这些点写进论文里本身就是很好的“安全设计”章节。还有一个容易被忽略的点不要在后端代码里把数据库密码、JWT 密钥写死。虽然毕设不会上线但答辩时老师可能会问“你这个密钥如果泄露了怎么办”。能说出来“应该放到配置中心或环境变量里”和完全没概念给老师的印象完全不同。8.3 答辩演示怎么在五分钟内讲出亮点答辩时间很短演示不要按“从头到尾操作一遍”的方式而是讲“三个关键链路”。第一链路是“用户发布笔记 → 后台审核 → APP 可见”——这个故事说明客户端和服务端是完全打通的。第二链路是“用户下单 → 模拟支付 → 订单状态变化”——这个故事说明电商流程是完整的。第三链路是“打开后台数据看板 → 展示统计图表”——这个故事说明除了增删改查项目还有数据分析能力。展示时建议提前准备一张接口调试工具截图、一张数据库 ER 图、一张 APP 页面截图。如果能在 PPT 里画出一张“鸿蒙原生开发与其他跨端方案差异对比”的表格会很加分。8.4 论文结构建议这类项目的论文结构可以参照以下框架第一章 绪论背景、国内外现状、研究意义。第二章 相关技术介绍鸿蒙系统、ArkTS、ArkUI、Spring Boot、MySQL。第三章 系统分析需求分析、可行性分析、用例图、流程图。第四章 系统设计架构设计、模块设计、数据库设计、接口设计。第五章 系统实现关键功能页面截图加核心代码讲解。第六章 系统测试功能测试、兼容性测试、性能基础测试。第七章 总结与展望成果总结、不足与改进方向。这套结构是按主流本科毕设模板走的跟项目内容高度匹配。只要代码确实是自己调的论文每一章都能写出实质内容。9. 总结与后续学习方向回到最开始的问题毕设选题撞车怎么办这个问题的答案不是找一个谁也想不到的冷门领域而是换一条更有长期价值的技术路线。基于鸿蒙系统的“社交笔记 电商商城 Web 后台”项目恰恰踩在技术趋势和普适功能的交叉点上。它的难度足够支撑一篇有质量的本科毕设又不至于让新手完全无从下手。尤其是 ArkTS 声明式 UI、Stage 模型、动态权限、网络请求、RESTful 接口这些知识点每一块都能在鸿蒙生态里对应到实际应用而不是停留在“背概念”的层面。拿到源码之后最忌讳的是一头雾水地交差。正确的做法是先花两三天把工程结构捋清楚再按“后端接口 → 数据库 → APP 端请求 → 页面渲染 → 模拟器联调”的顺序逐层跑通然后挑出三条核心链路写成自己的笔记。这样到了答辩时你不仅能演示还能回答“为什么用 Stage 模型”“网络层是怎么封装的”“权限是怎么申请的”“订单状态怎么流转”这些高频问题。源码是起点不是终点把源码变成脑子里的工程地图才是这个毕设真正值钱的地方。下一步可以继续深入的方向包括HarmonyOS 多设备适配与折叠屏布局、鸿蒙端侧数据持久化、图表可视化大屏接入、性能优化与启动耗时分析。这些方向既能在毕设基础上继续做扩展也能放进求职作品集里让这份项目经验在毕业后继续发挥价值。