news 2026/5/8 1:01:44

【江鸟中原】集光鸿蒙项目开发

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【江鸟中原】集光鸿蒙项目开发

集光 - 智能笔记应用

📱 应用简介

集光是一款专为HarmonyOS生态设计的智能笔记应用,提供安全、高效、美观的笔记管理体验。应用集成了华为账号服务,支持多种笔记编辑功能,让您的创意和想法得到完美记录。

✨ 核心特性

🔐 安全可靠

  • 生物识别解锁:支持指纹、面部识别等生物认证
  • 手势密码:自定义手势密码保护隐私内容
  • 应用锁:为整个应用提供额外的安全保护

📝 强大编辑

  • 富文本编辑:支持文字样式、颜色、大小等格式设置
  • 多媒体支持:插入图片、截图,丰富笔记内容
  • 智能排版:自动优化文本布局,提升阅读体验

🗂️ 智能管理

  • 分类管理:创建、编辑、删除笔记分类
  • 搜索功能:快速定位所需笔记内容
  • 多种视图:列表视图和卡片视图自由切换
  • 排序方式:按创建时间、修改时间灵活排序

🌙 个性化体验

  • 夜间模式:护眼模式,适合夜间使用
  • 主题切换:支持明暗主题自动切换
  • 多选操作:批量管理笔记,提高效率

🏗️ 技术架构

模块化设计

集光 ├── 主应用模块 (product/phone) ├── 公共组件 (components) │ ├── 应用密码设置 (secretlock) │ ├── 富文本编辑器 (richeditor) │ ├── 用户登录 (login) │ ├── 意见反馈 (feed_back) │ └── 应用更新检测 (check_app_update) └── 公共工具 (common) ├── 数据源管理 (datasource) └── 工具类库 (utils)

核心技术

  • HarmonyOS 5.0+:原生HarmonyOS应用开发
  • ArkTS:现代化的应用开发语言
  • Stage模型:新一代应用开发模型

🚀 快速开始

环境要求

  • DevEco Studio 5.0.3 Release 及以上
  • HarmonyOS SDK 5.0.3 Release 及以上
  • 支持设备:华为手机(包括双折叠和阔折叠)
  • 系统版本:HarmonyOS 5.0.3(15) 及以上

安装配置

  1. 克隆项目

    gitclone[项目地址]cdJiGaung
  2. 配置华为账号服务

    • 在AppGallery Connect创建应用
    • 配置Client ID到product/phone/src/main/module.json5
    • 申请quickLoginMobilePhone权限
  3. 应用签名

    • 进行手工签名配置
    • 添加证书公钥指纹
  4. 运行应用

    • 连接调试设备
    • 选择"Run > Run ‘phone’“或"Run > Debug ‘phone’”

📱 主要功能

首页功能

  • 笔记展示:支持列表和卡片两种展示模式
  • 分类管理:创建、编辑、删除笔记分类
  • 搜索笔记:快速查找笔记内容
  • 多选操作:长按多选,批量管理
  • 排序功能:按时间排序,方便查找

笔记编辑

  • 富文本编辑:支持文字格式、颜色、大小设置
  • 图片插入:支持本地图片和截图插入
  • 撤销重做:操作历史记录,支持撤销重做
  • 内容分享:支持笔记内容分享到其他应用
  • 自动保存:实时保存,防止内容丢失

个人中心

  • 用户信息:华为账号一键登录,头像昵称管理
  • 回收站:删除笔记恢复,彻底删除功能
  • 隐私设置:生物识别、手势密码等安全设置
  • 应用设置:夜间模式、通知设置、版本检测
  • 意见反馈:问题反馈,帮助改进应用

🔧 开发指南

组件使用

如需单独使用某个组件,请参考对应组件的使用指导:

组件描述使用指导
secretlock应用密码设置使用指导
richeditor富文本编辑器使用指导
login用户登录使用指导
feed_back意见反馈使用指导

自定义开发

  • 修改AppScope/app.json5中的bundleName
  • 调整AppScope/resources/base/element/string.json中的应用名称
  • 根据需要修改主题色彩和样式

🧩 系统设计与实现说明

本节面向希望深入学习和二开的开发者,按“从需求到实现”的顺序介绍集光的整体架构、核心业务流程以及关键模块的实现思路。

1. 整体架构概览

  • UIAbility 入口层

    • EntryAbility.ets作为应用入口,负责:
      • 初始化主题控制器ThemeController,同步系统深浅色模式;
      • 初始化窗口尺寸,写入AppStorage,供 UI 自适配(含折叠屏断点适配WindowUtil.registerBreakPoint);
      • 初始化数据库:调用DatabaseManager.instance.initDatabase()创建和迁移数据表;
      • 配置状态栏、导航栏、通知授权等系统级能力。
  • 页面与导航层

    • MainPage.ets作为主页面,使用Tabs + Navigation构建四个核心 Tab:
      • PictureView:图片集
      • NotesView:笔记集(本项目核心)
      • ToDoView:待办集
      • MineView:我的
    • 通过NavPathStack实现页面栈导航(如从NotesView跳转到EditNotes)。
  • 业务页面层

    • NotesView.ets:笔记列表页,负责分类筛选、多选操作、置顶、排序等;
    • EditNotes.ets:笔记编辑页,集成富文本编辑器、背景色、分享/复制等能力;
    • 其它如EditCategory.etsSearchPage.ets等负责辅助业务。
  • 组件与服务层

    • 公共组件在components/下:
      • richeditor:富文本编辑器组件与相关数据模型;
      • secretlock:手势锁、应用锁逻辑;
      • login:华为账号登录;
      • feed_back:意见反馈;
      • check_app_update:检查应用更新。
    • 公共工具在common/
      • datasource:数据库访问、实体与服务NoteService/CategoryService等;
      • utilsGlobalInfoModelAppUtilWindowUtil等工具与全局状态。
  • 数据存储层

    • 使用@ohos.data.relationalStore构建notes.db
    • DatabaseManager.ets负责数据库初始化、迁移和默认数据插入。

整体上可理解为:

UIAbility(入口) → MainPage(Tab 容器) → 各业务页面(Notes / EditNotes 等) → 业务服务层(NoteService / CategoryService) → DatabaseManager(RdbStore)

2. 数据模型与数据库设计

数据库通过DatabaseManager管理,使用 RDB 存储数据:

  • 数据库配置

    • 名称:notes.db
    • 安全级别:SecurityLevel.S1
  • 主要表结构

    • categories表(分类):
      • id TEXT PRIMARY KEY:分类 ID(含特殊 ID:-1= 全部笔记,-2= 未分类笔记);
      • name TEXT:分类名称;
      • totalCount INTEGER:该分类下笔记数量,用于快速展示计数。
    • notes表(笔记):
      • id TEXT PRIMARY KEY:笔记 ID;
      • title TEXT:标题;
      • categoryId TEXT:所属分类 ID;
      • content TEXT:纯文本内容;
      • styledContent TEXT:富文本内容(通过StyleSerializer序列化的 JSON 字符串);
      • description TEXT:用于卡片预览的摘要;
      • createTime / updateTime TEXT:创建/更新时间;
      • isPinned INTEGER:是否置顶;
      • backgroundColor TEXT:笔记卡片/详情背景颜色;
      • importance INTEGER:重要度等级;
      • isDeleted INTEGER:是否进入回收站。
  • 自动迁移逻辑

    • DatabaseManager.migrateDatabase()使用PRAGMA table_info(notes)查询列信息;
    • 若缺少某个列(如isPinned/backgroundColor/importance/styledContent/isDeleted),则通过ALTER TABLE动态新增;
    • 这样既支持老版本平滑升级,又避免手工 SQL 迁移出错。
  • 默认分类初始化

    • initDefaultCategories()保证:
      • 若不存在id = '-1',则插入“全部笔记”;
      • 若不存在id = '-2',则插入“未分类笔记”。

关键实现示例(节选自DatabaseManager.ets):

exportclassDatabaseManager{privatestatic_instance:DatabaseManager;privaterdbStore:relationalStore.RdbStore|null=null;privatereadonlySTORE_CONFIG:relationalStore.StoreConfig={name:'notes.db',securityLevel:relationalStore.SecurityLevel.S1};asyncinitDatabase():Promise<void>{constcontext=getContext(this);this.rdbStore=awaitrelationalStore.getRdbStore(context,this.STORE_CONFIG);awaitthis.createTables();awaitthis.migrateDatabase();}privateasynccreateTables():Promise<void>{if(!this.rdbStore)return;constcategoryTableSql=`CREATE TABLE IF NOT EXISTS categories ( id TEXT PRIMARY KEY, name TEXT NOT NULL, totalCount INTEGER DEFAULT 0 )`;constnoteTableSql=`CREATE TABLE IF NOT EXISTS notes ( id TEXT PRIMARY KEY, title TEXT, categoryId TEXT, content TEXT, styledContent TEXT, description TEXT, createTime TEXT, updateTime TEXT, isPinned INTEGER DEFAULT 0, backgroundColor TEXT DEFAULT "#fefefe", importance INTEGER DEFAULT 0, isDeleted INTEGER DEFAULT 0, FOREIGN KEY (categoryId) REFERENCES categories (id) )`;awaitthis.rdbStore.executeSql(categoryTableSql);awaitthis.rdbStore.executeSql(noteTableSql);awaitthis.migrateDatabase();awaitthis.initDefaultCategories();}privateasyncmigrateDatabase():Promise<void>{if(!this.rdbStore)return;constresultSet=awaitthis.rdbStore.querySql('PRAGMA table_info(notes)');lethasIsPinnedColumn=false;// 省略其它列检查...if(resultSet&&resultSet.rowCount>0){while(awaitresultSet.goToNextRow()){constcolumnName=awaitresultSet.getString(1);if(columnName==='isPinned'){hasIsPinnedColumn=true;}// 根据实际名称检查 backgroundColor / importance / styledContent / isDeleted 等}}if(!hasIsPinnedColumn){awaitthis.rdbStore.executeSql('ALTER TABLE notes ADD COLUMN isPinned INTEGER DEFAULT 0');}// 同理为其它字段做 ALTER TABLE}privateasyncinitDefaultCategories():Promise<void>{if(!this.rdbStore)return;constallNotesCountResult=awaitthis.rdbStore.querySql('SELECT COUNT(*) as count FROM categories WHERE id = ?',['-1']);// 若不存在“全部笔记”,则插入默认分类// ...}}

3. 首页与笔记列表(NotesView)实现思路

3.1 MainPage:Tab 容器
  • 使用Tabs+TabContent实现四个子页面:图片集、笔记集、待办集、我的;
  • 自定义tabBarBuilder绘制底部图标和文字;
  • 通过curIndex控制当前选中 Tab;
  • 使用GlobalInfoModel与各页面共享刷新方法,例如:
    • 当切换到“笔记集”Tab 时,调用globalInfo.refreshNotesView()强制 NotesView 刷新数据;
    • 当切换到“图片集”Tab 时,调用globalInfo.refreshPictureView()刷新图片数据。

这种设计的好处是:Tab 之间无需强耦合,统一通过GlobalInfoModel进行“跨页面刷新”通信。

3.2 NotesView:笔记列表核心逻辑

NotesView.ets是笔记模块的核心列表页面,主要职责:

  • 业务服务依赖

    • NoteService:提供笔记增删改查;
    • CategoryService:管理分类与计数;
    • SortController:管理排序字段与顺序;
    • NoteSearchController:管理搜索关键字与结果;
    • SelectedController:管理多选状态;
    • SettingController:应用设置相关(如通知授权)。
  • 本地状态管理

    • @Local noteList: Note[]:当前列表中的笔记;
    • @Local dataList: LazyDataSource<Note>:用于懒加载/瀑布流展示的数据源;
    • @Local categoryList: Array<Category>:分类列表;
    • @Local showListType: SHOW_METHOD_ENUM:列表/卡片等展示方式。
  • 生命周期逻辑(aboutToAppear)

    • 重置多选状态:selectedController.recoverInitState()
    • 若开启手势锁,则跳转至DrawLock页面;
    • 重置搜索关键字,获取默认分类getFirstCategory()
    • 根据当前分类、排序、搜索条件获取笔记:noteService.getNoteList(...)
    • 初始化所有笔记的选中状态:noteService.initSelectedState()
    • 遍历所有分类并统计每个分类的笔记数量:refreshAllCategoryNoteCounts
    • 调用updateDataList()同步noteListdataList
    • refreshNotesView方法挂到GlobalInfoModel,供外部刷新调用。
  • 刷新逻辑(refreshData)

    • 重新读取当前分类下笔记并更新noteList
    • 若不在多选模式,重置选中状态;
    • 调用forceRefreshUI()清空并重建dataList,通过notifyDataChange触发 UI 刷新;
    • 重新统计分类计数,保证分类弹窗中的数量与实际一致。
  • 多选与置顶等交互

    • 通过SelectedController记录选中 ID 集合与计数;
    • 长按进入多选模式:handleLangPress
    • “全选”、“取消全选”、批量删除/移动/置顶都基于selectedIds实现。

关键实现示例

MainPage:Tab 切换与跨页面刷新(节选自MainPage.ets

@Entry @ComponentV2 struct MainPage{@Local curIndex:number=0;@Provider('appPathStack')appPathStack:NavPathStack=newNavPathStack();@Local globalInfo:GlobalInfoModel=AppStorageV2.connect<GlobalInfoModel>(GlobalInfoModel,()=>newGlobalInfoModel())!;build(){Navigation(this.appPathStack){Column(){Tabs({barPosition:BarPosition.End,index:this.curIndex}){TabContent(){PictureView();}.tabBar(this.tabBarBuilder(0));TabContent(){NotesView();}.tabBar(this.tabBarBuilder(1));TabContent(){ToDoView();}.tabBar(this.tabBarBuilder(2));TabContent(){MineView();}.tabBar(this.tabBarBuilder(3));}.onChange((index:number)=>{this.curIndex=index;if(index===1&&this.globalInfo.refreshNotesView){setTimeout(()=>this.globalInfo.refreshNotesView&&this.globalInfo.refreshNotesView(),100);}if(index===0&&this.globalInfo.refreshPictureView){setTimeout(()=>this.globalInfo.refreshPictureView&&this.globalInfo.refreshPictureView(),100);}})}}}}

NotesView:初始化与刷新逻辑(节选自NotesView.ets

@ComponentV2exportstruct NotesView{noteService:NoteService=NoteService.instance;categoryService:CategoryService=CategoryService.instance;// ... 省略其它依赖@Local noteList:Note[]=[];@Local dataList:LazyDataSource<Note>=newLazyDataSource();asyncaboutToAppear():Promise<void>{this.selectedController.recoverInitState();if(this.secretLock.gesture){constparams:Record<string,Object>={'fromEntrance':true,'appPathStack':this.appPathStack};this.appPathStack.pushPathByName('DrawLock',params);}this.noteSearchController.searchKeyword='';this.currentCategory=awaitthis.categoryService.getFirstCategory();this.noteList=awaitthis.noteService.getNoteList(this.currentCategory.id,this.sortController.sortBy,this.noteSearchController.searchKeyword);this.noteService.initSelectedState();constallNotes=awaitthis.noteService.getNoteList('-1');constcategoryNotesMap=newMap<string,Note[]>();for(constcategoryofawaitthis.categoryService.getCategoryList()){if(category.id!=='-1'){constcategoryNotes=awaitthis.noteService.getNoteList(category.id);categoryNotesMap.set(category.id,categoryNotes);}}awaitthis.categoryService.refreshAllCategoryNoteCounts(allNotes,categoryNotesMap);this.categoryList=awaitthis.categoryService.getCategoryList();this.updateDataList();this.updateNoteCount();this.syncSelectedState();this.globalInfo.refreshNotesView=this.refreshData.bind(this);}asyncrefreshData():Promise<void>{this.noteList=awaitthis.noteService.getNoteList(this.currentCategory.id,this.sortController.sortBy,this.noteSearchController.searchKeyword);if(!this.selectedController.isCtrl){this.noteService.initSelectedState();}this.forceRefreshUI();this.updateNoteCount();this.syncSelectedState();}privateforceRefreshUI():void{this.dataList.clear();this.dataList.notifyDataChange(0);setTimeout(()=>{this.noteList.forEach((item:Note)=>this.dataList.pushData(item));this.dataList.notifyDataChange(0);},0);}}

4. 笔记编辑(EditNotes + 富文本编辑器)实现思路

4.1 富文本编辑器组件
  • 富文本编辑器封装在components/richeditor中,对外通过Index.ets提供:

    • RichEditorController:编辑器控制器,负责光标、选区、历史记录(撤销/重做)和当前样式状态;
    • RichEditorArea:真正的富文本输入区域组件;
    • Note/LazyDataSource<Note>等数据模型;
    • StyleSerializer:负责将样式(加粗、斜体、下划线、阴影、对齐方式等)序列化到字符串,并在读取时反序列化回枚举和结构体。
  • 样式持久化:

    • 编辑器内部维护MutableStyledString,记录每段文本的样式;
    • 保存时将MutableStyledString通过StyleSerializer转为 JSON 字符串,存入notes.styledContent
    • 读取时反序列化回MutableStyledString,然后调用RichEditorController.restoreStateFromStyledString恢复光标位置、当前样式按钮状态等。
4.2 EditNotes 页面结构

EditNotes.ets是笔记编辑的核心页面,关键成员包括:

  • 核心依赖

    • RichEditorController:单例控制器,跨页面持有编辑状态;
    • SnapShotController:用于对当前笔记区域截图分享;
    • NoteService:保存/更新笔记数据;
    • ThemeController:感知深浅色模式;
    • GlobalInfoModel:用于在保存笔记后通知NotesView刷新数据。
  • 本地状态

    • @Local currentNote: Note:当前正在编辑的笔记对象;
    • @Local noteTitle: string:标题输入内容;
    • @Local selectedBackgroundColor: string:当前笔记背景色;
    • @Local lightModeColors[] / darkModeColors[]:深浅色模式下可选背景色列表;
    • @Local isEditNote: boolean:标记是“新建”还是“编辑已有笔记”。
  • 键盘与主题适配

    • aboutToAppear中将KeyboardAvoidMode设置为RESIZE_WITH_CARET,避免软键盘遮挡输入区域;
    • 根据ThemeController.currentColorMode设置默认背景色;
    • 启动定时器轮询主题变化,若系统从浅色切到深色,会自动切换一组更适合阅读的背景色。
  • 工具栏与更多操作

    • toolBar()中提供:撤销/重做/保存 等基础操作;
    • moreFunctionMenu()中提供:
      • 分享:通过SnapShotController.onceSnapshot()截图当前笔记区域;
      • 复制:通过UnifiedData + SystemPasteboard将富文本转为纯文本复制到系统剪贴板。
  • 保存流程(简化版)

    1. 用户点击工具栏中的“保存”图标;
    2. 调用saveNote()
      • 将编辑器中的内容序列化为content/styledContent/description
      • 若为新笔记,生成idcreateTime并插入数据库;
      • 若为编辑已有笔记,更新数据库记录(包括description,确保列表卡片实时更新摘要);
    3. 保存成功后:
      • 关闭键盘与编辑状态:controller.stopEditing()
      • RichEditorController.showMoreFunction设置为true,显示更多功能菜单;
      • 通知NotesView刷新列表;
      • 结束编辑状态并返回。

关键实现示例(节选自EditNotes.ets

@ComponentV2 struct EditNotes{richEditorController:RichEditorController=RichEditorController.instance;noteService:NoteService=NoteService.instance;@Local currentNote:Note=newNote(newMutableStyledString(''));@Local noteTitle:string='';@Local isEditNote:boolean=false;@Local selectedBackgroundColor:string='#fefefe';asyncsaveNote():Promise<boolean>{letstyledString=this.richEditorController.controller.getStyledString();letcontent=styledString.getString();// 新建且内容和标题都为空时不保存if(content===''&&this.noteTitle===''){returnthis.isEditNote?false:true;}if(this.isEditNote){this.currentNote.updateContent(styledString,this.noteTitle,undefined,this.selectedBackgroundColor);awaitthis.noteService.updateNote(this.currentNote);}else{this.currentNote.title=this.noteTitle;this.currentNote.styledString=styledString;this.currentNote.description=styledString.getString();this.currentNote.backgroundColor=this.selectedBackgroundColor;awaitthis.noteService.addNote(this.currentNote);this.isEditNote=true;}if(this.globalInfo&&this.globalInfo.refreshNotesView){this.globalInfo.refreshNotesView();}returntrue;}build(){NavDestination(){Column(){RichEditorArea({noteTitle:this.currentNote.title,noteContent:this.currentNote.styledString,snapShotController:this.snapShotController,titleChange:(title:string)=>{this.noteTitle=title;}})}.backgroundColor(this.selectedBackgroundColor);}.menus(this.toolBar());}}

5. 安全与隐私(SecretLock 等)

  • SecretLock组件负责应用级安全:

    • 手势密码解锁:在进入NotesView时,如果检测到已设置手势密码,则通过appPathStack.pushPathByName('DrawLock', params)先进入手势解锁页面;
    • 解锁成功后才允许继续访问笔记内容。
  • 生物识别解锁(指纹/人脸)也可以与secretlock联动,在应用启动或从后台回到前台时进行校验。

6. 典型业务流程串联

6.1 应用启动 → 显示主页
  1. 系统启动EntryAbility
  2. onCreate中初始化主题、数据库;
  3. onWindowStageCreate中:
    • 注册折叠屏断点;
    • 设置状态栏/导航栏属性;
    • windowStage.loadContent('pages/MainPage')加载MainPage
  4. MainPage构建 Tabs,默认显示第一个 Tab(图片集),用户可切换到“笔记集”。
6.2 进入笔记列表 NotesView
  1. 用户点击“笔记集”Tab,curIndex = 1
  2. NotesView.aboutToAppear执行:
    • 若开启手势锁,则跳转到手势解锁页面;
    • 加载当前分类下的笔记列表;
    • 同步分类计数;
    • 初始化dataList,触发 UI 渲染;
    • refreshNotesView注册到全局,便于其它页面保存后刷新列表。
6.3 新建 / 编辑笔记
  1. NotesView点击“新建笔记”或笔记卡片,导航到EditNotes
  2. EditNotes.aboutToAppear:配置键盘避让、主题模式、背景色等;
  3. 用户使用富文本工具栏编辑内容(加粗、斜体、下划线、阴影、对齐方式等);
  4. 点击“保存”:
    • 将样式序列化为styledContent
    • 写入/更新notes表中的记录;
    • 通知NotesView刷新列表;
    • 结束编辑状态并返回。

7. 二开与扩展建议

如果你希望在本项目基础上做二次开发,可以参考以下思路:

  • 增加字段

    • notes表中新增字段(例如标签、提醒时间等);
    • DatabaseManager.migrateDatabase()中按现有模式检测并ALTER TABLE,保持向后兼容;
    • Note模型与NoteService中补充对应字段的读写逻辑。
  • 扩展富文本能力

    • richeditor组件中增加新的样式(例如高亮、引用块等);
    • 更新StyleSerializer的序列化/反序列化逻辑;
    • EditNotes的工具栏中增加对应的按钮和交互。
  • 增加云同步/多端能力

    • NoteService层增加与云端的同步逻辑(基于华为云或自建服务);
    • 建议保持本地 RDB 为“真源”,云端做备份与协同,避免弱网络导致编辑卡顿。
  • 自定义安全策略

    • 扩展secretlock支持更多解锁策略(如时间锁、地理位置锁等);
    • EntryAbility.onForeground/NotesView.aboutToAppear中按需插入校验逻辑。

通过阅读本节并结合对应的源码文件(EntryAbility.etsMainPage.etsNotesView.etsEditNotes.etsDatabaseManager.etscomponents/richeditor等),你可以较为系统地掌握集光项目的整体设计思路,并在此基础上快速完成功能扩展或二次开发。

📄 开源协议

本项目采用 Apache 2.0 开源协议,欢迎贡献代码和提出建议。


集光- 让记录更智能,让创意更闪耀 ✨

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

【GraphQL + PHP 文档革命】:为什么大厂都在用Schema驱动文档?

第一章&#xff1a;GraphQL PHP 接口文档的现状与挑战在现代 Web 开发中&#xff0c;API 文档的清晰性与可维护性直接影响前后端协作效率。当使用 PHP 构建后端服务并引入 GraphQL 作为查询语言时&#xff0c;传统的 RESTful 文档工具&#xff08;如 Swagger/OpenAPI&#xff…

作者头像 李华
网站建设 2026/5/3 6:19:40

为什么你的服务还不支持HTTP/3?(深度剖析协议兼容性三大瓶颈)

第一章&#xff1a;为什么你的服务还不支持HTTP/3&#xff1f;HTTP/3 作为下一代互联网传输协议&#xff0c;正在被越来越多的主流服务采用。它基于 QUIC 协议&#xff0c;解决了 HTTP/2 在多路复用中仍存在的队头阻塞问题&#xff0c;并将传输层从 TCP 迁移到 UDP&#xff0c;…

作者头像 李华
网站建设 2026/5/1 6:04:10

leetcode155 最小栈(Java)

思路&#xff1a;创建两个栈&#xff0c;一个用来“正常进出”&#xff0c;另一个记录“当前最小值”一、关于 “方法名重复会不会冲突”原因是&#xff1a;MinStack 类中的 push/pop 是自定义方法&#xff0c;而 stack1/stack2 是类内部的 Stack 对象 —— 二者属于不同的 “作…

作者头像 李华
网站建设 2026/5/1 6:08:03

BI 到底是什么,看看这篇文章怎么说

随着数据价值得到了认可&#xff0c;数据开始成为个人、企业乃至国家的重要战略资产&#xff0c;但数据资产不能直接产生价值&#xff0c;而是需要通过数据分析、数据可视化等数据处理手段将数据转化为信息和知识&#xff0c;才能进行资产的价值化&#xff0c;这时候商业智能BI…

作者头像 李华
网站建设 2026/5/1 7:19:59

《Flutter 工程化实践:从项目结构到 CI/CD 全链路落地》

引言随着 Flutter 在企业级应用中的普及&#xff0c;单纯掌握 UI 开发已远远不够。一个高质量的 Flutter 项目&#xff0c;需要具备清晰的架构分层、规范的代码风格、完善的测试体系、自动化的构建流程以及高效的团队协作机制。然而&#xff0c;许多团队在将 Flutter 从“Demo”…

作者头像 李华
网站建设 2026/5/1 7:07:52

吊舱激光测距模块概述

吊舱的激光测距模块是实现目标精确定位的核心。它通过发射激光并接收从目标反射的回波&#xff0c;利用时间差计算距离&#xff0c;其性能直接影响整个系统的可靠性。下面的表格整理了该模块的几个关键技术要点&#xff1a;模块如何运行&#xff1a;与吊舱系统深度协同激光测距…

作者头像 李华