【OpenHarmony/HarmonyOs 】数学知识库收藏管理:标签筛选、详情弹窗与近场分享数据准备

项目类型:OpenHarmony / HarmonyOS ArkTS 数学学习应用
项目名称:数学视界
对应主题:近场快传、全场景智慧生活、隐私保护方案
关键词:ArkTS、收藏系统、知识库、标签筛选、详情弹窗、结构化数据 💖

一、为什么收藏系统不只是“加个爱心”?

在数学视界项目中,收藏系统不是简单地把某个条目标记为喜欢,而是一个个人数学知识库。

用户可以收藏:

  • 公式;
  • 知识点;
  • 趣味百科;
  • 图形方案;
  • 历史内容;
  • 自定义笔记。

这就让收藏系统具备了更大的扩展空间:

  • 本地复习;
  • 标签筛选;
  • 详情查看;
  • 编辑备注;
  • 删除整理;
  • 近场分享;
  • 备份恢复;
  • 元服务“最近收藏”入口。

所以这篇文章重点写 FavoritesPage.ets 如何把收藏做成结构化知识库。

二、收藏页面状态:分类、标签、搜索、排序

收藏页的状态比较完整:

@State selectedCategory: string = '全部'
@State categories: string[] = ['全部', '公式', '知识点', '趣味百科', '图形', '历史', '自定义']
@State allTags: string[] = ['全部', '几何', '代数', '三角', '函数', '概率', '导数', '常数', '基础', '趣味百科', '画板']
@State selectedTag: string = '全部'
@State searchKeyword: string = ''
@State sortType: string = '最新'
@State viewMode: string = 'list'
@State favorites: FavoriteItem[] = []
@State filteredFavorites: FavoriteItem[] = []

这说明收藏页支持多维度管理:

  • 按分类看;
  • 按标签看;
  • 按关键词搜;
  • 按最新/最早/名称/分类排序;
  • 列表视图和网格视图切换。

对学习应用来说,这些能力比单纯“收藏/取消收藏”更有价值。

三、FavoriteItem:收藏条目的统一结构

全局收藏类型定义在 AppState.ets

export interface FavoriteItem {
  id: string
  type: string
  title: string
  content: string
  category: string
  icon: string
  bgColor: string
  accentColor: string
  note: string
  tags: string[]
  createdAt: number
  updatedAt: number
  graphData?: string
  thumbnail?: string
}

这个结构的亮点是它能统一承载多种内容:

  • 公式:type = formula
  • 知识点:type = knowledge
  • 图形:type = graph,可带 graphData
  • 自定义笔记:type = custom

尤其是 graphData 字段,它为后续近场快传数学图形方案做了准备。分享时不一定要传图片,可以传结构化数据。

四、筛选逻辑:分类、标签、关键词组合过滤

收藏页的核心筛选逻辑如下:

private doFilter(): void {
  let result: FavoriteItem[] = this.favorites

  if (this.selectedCategory !== '全部') {
    result = result.filter((item: FavoriteItem): boolean =>
      item.category === this.selectedCategory
    )
  }

  if (this.selectedTag !== '全部' && this.selectedTag !== '') {
    result = result.filter((item: FavoriteItem): boolean =>
      item.tags.indexOf(this.selectedTag) >= 0
    )
  }

  if (this.searchKeyword.trim() !== '') {
    const kw: string = this.searchKeyword.toLowerCase()
    result = result.filter((item: FavoriteItem): boolean =>
      item.title.toLowerCase().indexOf(kw) >= 0 ||
      item.content.toLowerCase().indexOf(kw) >= 0 ||
      item.note.toLowerCase().indexOf(kw) >= 0
    )
  }

  this.filteredFavorites = result
}

这个逻辑非常适合个人知识库:

  • 想看公式:选“公式”;
  • 想看函数相关内容:选“函数”标签;
  • 想找某个关键词:直接搜索标题、内容、备注;
  • 多个条件可以叠加。

五、排序:让知识库更容易整理

收藏页支持四种排序:

if (this.sortType === '最新') {
  result.sort((a: FavoriteItem, b: FavoriteItem): number =>
    b.createdAt - a.createdAt
  )
} else if (this.sortType === '最早') {
  result.sort((a: FavoriteItem, b: FavoriteItem): number =>
    a.createdAt - b.createdAt
  )
} else if (this.sortType === '名称') {
  result.sort((a: FavoriteItem, b: FavoriteItem): number =>
    a.title.localeCompare(b.title, 'zh-CN')
  )
} else if (this.sortType === '分类') {
  result.sort((a: FavoriteItem, b: FavoriteItem): number =>
    a.category.localeCompare(b.category, 'zh-CN')
  )
}

这些排序方式对应不同学习场景:

  • 最新:复习最近收藏;
  • 最早:回顾长期积累;
  • 名称:按知识点查找;
  • 分类:整理知识结构。

六、添加收藏:自定义内容也能进入知识库

收藏页支持用户手动添加内容:

addFavorite(): void {
  if (this.addTitle.trim() === '') {
    this.showToast('⚠️ 请输入标题')
    return
  }
  if (this.addContent.trim() === '') {
    this.showToast('⚠️ 请输入公式/内容')
    return
  }

  const parsedTags: string[] =
    this.addTags.split(/[,,]/)
      .map((t: string): string => t.trim())
      .filter((t: string): boolean => t !== '')

  const newItem: FavoriteItem = {
    id: Date.now().toString(),
    type: this.addCategory === '公式' ? 'formula' : 'custom',
    title: this.addTitle.trim(),
    content: this.addContent.trim(),
    category: this.addCategory,
    icon: iconMap[this.addCategory] ?? '📝',
    note: this.addNote.trim() !== '' ? this.addNote.trim() : '用户收藏',
    tags: parsedTags,
    createdAt: Date.now(),
    updatedAt: Date.now(),
  }

  AppState.addFavorite(newItem)
}

这让收藏页不仅能接收系统内置公式、百科、画板,也能接收用户自己的笔记。

七、编辑与详情弹窗:收藏需要可维护

收藏详情弹窗展示了标题、分类、内容、备注、标签:

Text(this.selectedItem.title)
Text(this.selectedItem.category + ' · ' + this.formatDate(this.selectedItem.createdAt))
Text(this.selectedItem.content)
Text(this.selectedItem.note || '暂无备注')

标签展示:

ForEach(this.selectedItem.tags, (tag: string) => {
  Text(tag)
    .fontSize(12)
    .fontColor('#FF7A8A')
    .backgroundColor(this.getIconBg('#FFE8F0'))
    .borderRadius(10)
})

底部提供编辑和删除:

Button('✏️ 编辑')
  .onClick(() => {
    this.showDetailDialog = false
    this.openEditDialog(this.selectedItem!)
  })

Button('🗑️ 删除')
  .onClick(() => {
    this.removeFavorite(this.selectedItem!.id)
    this.showDetailDialog = false
  })

知识库不是越多越好,也需要整理。编辑和删除能力能让用户保持收藏质量。

八、近场分享:为什么结构化收藏很重要?

如果后续接入近场快传,收藏系统可以直接作为分享数据来源:

interface FavoriteSharePackage {
  version: number
  type: string
  title: string
  content: string
  category: string
  note: string
  tags: string[]
  graphData?: string
}

比如:

  • 分享一条公式;
  • 分享一篇趣味百科;
  • 分享一个图形画板方案;
  • 分享一组标签下的知识点。

结构化分享比截图更适合学习场景,因为接收方可以继续编辑、收藏和复习。

九、隐私保护:收藏默认留在本地

收藏内容可能包含用户的学习重点、错题备注、个人笔记,所以它也属于需要保护的学习数据。

当前项目的收藏管理是本地状态:

refreshFavorites(): void {
  this.favorites = AppState.favorites
  this.doFilter()
}

默认不上传、不共享、不做 AI 识图。用户主动触发分享时,再生成结构化数据包,是更稳妥的方式。

十、全场景扩展:收藏可以成为学习资产中心

收藏页后续可以扩展到多个场景:

场景 用法
元服务 展示最近收藏的公式
近场快传 分享公式卡片或图形方案
备份恢复 换机保留个人知识库
今日复习 从收藏中抽取一条知识点
学习报告 统计收藏分类分布

这说明收藏系统不是附属功能,而是学习资产中心。

十一、总结

这篇文章贴合近场快传、全场景智慧生活和隐私保护主题,重点是数学视界的收藏知识库。

核心实现包括:

  • 💖 用 FavoriteItem 统一承载公式、知识点、百科、图形和自定义内容;
  • 🧭 用分类、标签、关键词组合筛选;
  • 🔤 支持最新、最早、名称、分类排序;
  • 📖 用详情弹窗展示内容、备注和标签;
  • ✏️ 支持编辑和删除,方便维护知识库质量;
  • 📦 通过 graphData 为图形方案分享做准备;
  • 🔐 默认本地管理,用户主动触发时再分享。

对数学学习 App 来说,收藏系统的价值不只是“喜欢”。它真正承载的是用户长期积累的学习资产。🚀

img

img

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐