HarmonyOs应用《日记本》开发第11篇 - DiaryModel 数据模型设计
数据模型是任何应用的基础。在日记项目中DiaryModel.ets定义了核心的数据结构和辅助函数它是 UI 层和存储层之间的桥梁。本篇将深入解析日记项目的数据模型设计。完整代码/** * 日记数据模型 *//** * 心情/天气选项接口 */exportinterfaceMoodWeatherItem{key:string;label:string;emoji:string;}exportclassDiaryItem{id:string;title:string;content:string;date:string;// 日期 YYYY-MM-DDcreateTime:number;// 创建时间戳updateTime:number;// 更新时间戳mood:string;// 心情: happy / calm / sad / excited / angryweather:string;// 天气: sunny / cloudy / rainy / snowy / overcastconstructor(id:string,title:string,content:string,date:string,createTime:number0,updateTime:number0,mood:stringcalm,weather:stringsunny){this.idid;this.titletitle;this.contentcontent;this.datedate;this.createTimecreateTime;this.updateTimeupdateTime;this.moodmood;this.weatherweather;}}/** * 心情枚举 */exportconstMoodList:MoodWeatherItem[][{key:happy,label:开心,emoji:},{key:calm,label:平静,emoji:},{key:excited,label:兴奋,emoji:},{key:sad,label:难过,emoji:},{key:angry,label:生气,emoji:},];/** * 天气枚举 */exportconstWeatherList:MoodWeatherItem[][{key:sunny,label:晴,emoji:☀️},{key:cloudy,label:多云,emoji:⛅},{key:overcast,label:阴,emoji:☁️},{key:rainy,label:雨,emoji:️},{key:snowy,label:雪,emoji:❄️},];/** * 根据key获取心情信息 */exportfunctiongetMoodByKey(key:string):MoodWeatherItem{for(letitemofMoodList){if(item.keykey){returnitem;}}returnMoodList[1];// 默认平静}/** * 根据key获取天气信息 */exportfunctiongetWeatherByKey(key:string):MoodWeatherItem{for(letitemofWeatherList){if(item.keykey){returnitem;}}returnWeatherList[0];// 默认晴}DiaryItem 类设计字段解析字段类型说明示例值idstring唯一标识diary_1721856000000_42titlestring日记标题美好的一天contentstring日记内容今天去公园散步...datestring日记日期2026-07-24createTimenumber创建时间戳1721856000000updateTimenumber更新时间戳1721856000000moodstring心情标识happyweatherstring天气标识sunny日期格式设计date:string;// 日期 YYYY-MM-DDcreateTime:number;// 创建时间戳毫秒updateTime:number;// 更新时间戳毫秒为什么日期用字符串而时间用时间戳date字符串用户选择的日记日期格式固定为YYYY-MM-DD便于显示和比较createTime/updateTime时间戳系统自动生成的时间用于排序和精确记录// 日期比较字符串即可if(item.datetoday){...}// 时间排序需要时间戳list.sort((a,b)b.updateTime-a.updateTime);构造函数的默认值设计constructor(id:string,title:string,content:string,date:string,createTime:number0,updateTime:number0,mood:stringcalm,// 默认平静weather:stringsunny// 默认晴天){// ...}默认值的选择逻辑字段默认值原因id空由存储层自动生成title允许无标题日记content允许无内容日记date由调用方设置当前日期createTime0由存储层自动设置updateTime0由存储层自动设置moodcalm平静是中性默认值weathersunny晴天是积极默认值构造函数的使用方式// 1. 新建日记在 DiaryEdit 页面constdiarynewDiaryItem(this.diaryId,// 编辑时有值新建时为空this.title.trim(),this.content.trim(),this.date,0,// createTime 由存储层设置0,// updateTime 由存储层设置this.mood,this.weather);// 2. 从 JSON 反序列化constlist:ArrayDiaryItemJSON.parse(raw);// JSON.parse 会创建普通对象但结构与 DiaryItem 一致MoodWeatherItem 接口设计接口定义exportinterfaceMoodWeatherItem{key:string;// 唯一标识label:string;// 中文标签emoji:string;// Emoji 图标}复用设计心情和天气共用同一个接口因为它们的数据结构完全一致// 心情列表exportconstMoodList:MoodWeatherItem[][{key:happy,label:开心,emoji:},{key:calm,label:平静,emoji:},{key:excited,label:兴奋,emoji:},{key:sad,label:难过,emoji:},{key:angry,label:生气,emoji:},];// 天气列表exportconstWeatherList:MoodWeatherItem[][{key:sunny,label:晴,emoji:☀️},{key:cloudy,label:多云,emoji:⛅},{key:overcast,label:阴,emoji:☁️},{key:rainy,label:雨,emoji:️},{key:snowy,label:雪,emoji:❄️},];设计优势代码复用一套接口服务两种数据UI 复用天气和心情选择器可以使用相同的渲染逻辑扩展方便新增心情或天气只需在数组中添加元素在 UI 中的使用// 天气选择器ForEach(WeatherList,(item:MoodWeatherItem){Column(){Text(item.emoji).fontSize(28)Text(item.label).fontSize(12).fontColor(this.weatheritem.key?#FF6B6B:#999)}.onClick((){this.weatheritem.key;})})// 心情选择器完全相同的结构ForEach(MoodList,(item:MoodWeatherItem){Column(){Text(item.emoji).fontSize(28)Text(item.label).fontSize(12).fontColor(this.mooditem.key?#FF6B6B:#999)}.onClick((){this.mooditem.key;})})辅助函数设计getMoodByKeyexportfunctiongetMoodByKey(key:string):MoodWeatherItem{for(letitemofMoodList){if(item.keykey){returnitem;}}returnMoodList[1];// 默认平静}使用场景根据存储的 mood 字符串值获取对应的标签和 emoji 用于显示。// 在日记卡片中显示心情 emojiText(getMoodByKey(item.mood).emoji).fontSize(18)// 在详情页显示心情标签Text(getMoodByKey(this.diary!.mood).label).fontSize(13).fontColor(#888)getWeatherByKeyexportfunctiongetWeatherByKey(key:string):MoodWeatherItem{for(letitemofWeatherList){if(item.keykey){returnitem;}}returnWeatherList[0];// 默认晴}使用场景与 getMoodByKey 类似用于天气信息的显示。// 在日记卡片中显示天气 emojiText(getWeatherByKey(item.weather).emoji).fontSize(18).margin({right:8})默认值的选择returnMoodList[1];// 默认平静returnWeatherList[0];// 默认晴为什么选择这些默认值MoodList[1]是平静——中性、安全的默认心情WeatherList[0]是晴——积极、常见的默认天气如果数据损坏或 key 不匹配至少显示一个合理的默认值。模块导出设计// 导出接口exportinterfaceMoodWeatherItem{...}// 导出类exportclassDiaryItem{...}// 导出常量exportconstMoodList:MoodWeatherItem[][...];exportconstWeatherList:MoodWeatherItem[][...];// 导出函数exportfunctiongetMoodByKey(key:string):MoodWeatherItem{...}exportfunctiongetWeatherByKey(key:string):MoodWeatherItem{...}在其他文件中的导入// Index.etsimport{DiaryItem,getMoodByKey,getWeatherByKey}from../model/DiaryModel;// DiaryEdit.etsimport{DiaryItem,MoodList,WeatherList,MoodWeatherItem}from../model/DiaryModel;// DiaryDetail.etsimport{DiaryItem,getMoodByKey,getWeatherByKey}from../model/DiaryModel;// DiaryStore.etsimport{DiaryItem}from../model/DiaryModel;按需导入每个文件只导入它需要的部分减少不必要的依赖。数据流图DiaryModel.ets ┌─────────────────────────────────────┐ │ DiaryItem (class) │ │ MoodWeatherItem (interface) │ │ MoodList / WeatherList (constants) │ │ getMoodByKey / getWeatherByKey │ └──────────────┬──────────────────────┘ │ ┌──────────┼──────────┐ │ │ │ ▼ ▼ ▼ ┌───────┐ ┌────────┐ ┌─────────┐ │ Index │ │DiaryEdit│ │DiaryDetail│ │ 显示 │ │ 编辑 │ │ 详情 │ └───────┘ └────────┘ └─────────┘ │ │ │ └──────────┼──────────┘ │ ▼ ┌─────────────┐ │ DiaryStore │ │ 存储/读取 │ └─────────────┘小结DiaryModel.ets是日记项目数据架构的核心通过合理的设计实现了清晰的类结构DiaryItem 封装了日记的所有属性接口复用MoodWeatherItem 同时服务心情和天气安全的默认值构造函数和辅助函数都提供合理默认值便捷的辅助函数getMoodByKey/getWeatherByKey 简化 UI 显示模块化导出按需导入降低耦合

相关新闻

智能专业的防作弊功能体系:在线笔试系统让招聘笔试更高效、公正

智能专业的防作弊功能体系:在线笔试系统让招聘笔试更高效、公正

在当今竞争激烈的社招校招市场中,如何确保招聘流程的公正性、高效性和安全性,成为众多企业和人力资源部门关注的焦点。考试云,作为在线考试系统的佼佼者,以其强大的功能、灵活的招聘场景应用以及丰富的客户案例,为企业…

2026/10/19 22:46:53 阅读更多 →
大型储煤棚高精度定位为什么选核芯物联蓝牙AOA?抛开参数内卷,聊聊落地优先的真实选型逻辑

大型储煤棚高精度定位为什么选核芯物联蓝牙AOA?抛开参数内卷,聊聊落地优先的真实选型逻辑

工业室内定位行业干货|能源棚库场景技术路线客观复盘 深耕工业室内定位行业多年,我们常年和全国各地能源行业集成商、工程伙伴深度交流。北方能源片区大面积、超高储煤棚场景的定位需求逐年激增,不少同行在技术路线选型时容易陷入参数误区&am…

2026/10/19 8:48:35 阅读更多 →
C++ std::divides函数对象:从除法运算符到泛型编程的核心组件

C++ std::divides函数对象:从除法运算符到泛型编程的核心组件

1. 项目概述:从“除法”到“可调用的对象”在C的日常开发中,尤其是涉及到算法、泛型编程和STL(标准模板库)的深度使用时,我们常常会遇到一个看似简单却蕴含深意的需求:如何将一个运算符,比如除法…

2026/10/15 9:49:11 阅读更多 →

最新新闻

Deepagents自动化测试实战:从断言设计到稳定性体系建设

Deepagents自动化测试实战:从断言设计到稳定性体系建设

做过AI Agent相关开发的朋友应该都有同感:写一个能跑通的代理不难,难的是让它稳定地跑完一百遍。LLM天然带有随机性,同样的输入,今天输出这个结果,明天就可能换个路径,哪怕最终答案都对,中间调用…

2026/10/20 23:44:36 阅读更多 →
AirMICROSD_1000直插式存储模块:嵌入式设备灵活扩容与量产可靠性实践

AirMICROSD_1000直插式存储模块:嵌入式设备灵活扩容与量产可靠性实践

去年秋天我在做一台边缘采集设备的量产改版,原方案用的是板载eMMC,结果代工厂那边封装炉温曲线一直调不理想,整板不良率居高不下。换方案的时候,朋友递过来一块AirMICROSD_1000直插式存储扩展模块,说你先试试这个。刚开…

2026/10/20 23:44:36 阅读更多 →
电热联合调度微电网运行优化模型:MATLAB+YALMIP实现解析

电热联合调度微电网运行优化模型:MATLAB+YALMIP实现解析

做微电网运行优化,绕不开一个朴素的问题:电负荷和热负荷明明共存于同一个园区,为什么大多数优化模型只盯着“电”在算?我最近在某园区微电网项目的经济调度分析里,把基于电热联合调度的微电网运行优化模型在 MATLAB 里…

2026/10/20 23:44:36 阅读更多 →
Java实现Word与PDF全文检索:Elasticsearch 7.x文档解析、IK分词与高亮查询实战

Java实现Word与PDF全文检索:Elasticsearch 7.x文档解析、IK分词与高亮查询实战

1. 从一份合同翻找说起:为什么Word和PDF的全文检索值得单独做前阵子帮一个做企业文档管理的朋友处理一个需求,他们内部有几千份Word合同和PDF技术方案,平时找一份文件只能靠文件名,可文件名往往起得极其随意,比如“最终…

2026/10/20 23:44:36 阅读更多 →
逆向工程Agent实战:从架构设计到落地优化的完整指南

逆向工程Agent实战:从架构设计到落地优化的完整指南

1. 逆向工程 Agent 到底在做什么1.1 从一个真实需求说起去年下半年开始,我陆续接触到几个做安全研究的朋友,他们不约而同地提到同一件事:手头需要分析的二进制样本越来越多,但人手根本没变。以前一个熟练的逆向工程师一天能啃完一…

2026/10/20 23:44:36 阅读更多 →
VS Code Jupyter内核崩溃排查:Kernel died with exit code 1全链路解析

VS Code Jupyter内核崩溃排查:Kernel died with exit code 1全链路解析

1. 从一个让人抓狂的报错说起如果你在 VS Code 里用 Jupyter 跑过代码,大概率见过这个弹窗:"Kernel died with exit code 1"。它不像语法错误那样给你一行红色波浪线,也不像缺包那样告诉你ModuleNotFoundError,它就是一…

2026/10/20 23:43:35 阅读更多 →

日新闻

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

CLRC663芯片Pin-to-Pin替代实战:从评估到量产全记录

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
ESP32舵机控制指南:原理、多路驱动与避坑实战

ESP32舵机控制指南:原理、多路驱动与避坑实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →
位移法实现一阶低通滤波:单片机ADC采样降噪实战

位移法实现一阶低通滤波:单片机ADC采样降噪实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 1:01:30 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 10:02:08 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/20 9:50:45 阅读更多 →