当前位置: 首页 > wzjs >正文

新开网站做内贸业务员好做杭州建设工程信用平台

新开网站做内贸业务员好做,杭州建设工程信用平台,检测网站安全,wordpress做动态页面文章目录 AI书签管理工具开发全记录(十五):TUI基本逻辑实现与数据展示1.前言 📝2.核心要点分析2.1 核心分析2.2 解决方案 3. 程序流程3.1 用户交互流程 3.功能实现3.1 书签分类渲染3.2 书签分类渲染3.3 书签描述渲染3.3 搜索功能实…

文章目录

  • AI书签管理工具开发全记录(十五):TUI基本逻辑实现与数据展示
    • 1.前言 📝
    • 2.核心要点分析
      • 2.1 核心分析
      • 2.2 解决方案
    • 3. 程序流程
      • 3.1 用户交互流程
    • 3.功能实现
      • 3.1 书签分类渲染
      • 3.2 书签分类渲染
      • 3.3 书签描述渲染
      • 3.3 搜索功能实现
      • 3.4 事件绑定
      • 3.5 启动时渲染分类
    • 4.演示

AI书签管理工具开发全记录(十五):TUI基本逻辑实现与数据展示

1.前言 📝

在上一篇文章中,我们完善了TUI的基本功能框架,增加了焦点切换功能。并且增加了日志显示功能支持。本文将聚焦于书签数据的页面展示。

2.核心要点分析

2.1 核心分析

categoryList    *tview.List
bookmarkList    *tview.List

categoryList和bookmarkList都是tview.List。
AddItem定义如下:

func (l *List) AddItem(mainText, secondaryText string, shortcut rune, selected func()) *List {l.InsertItem(-1, mainText, secondaryText, shortcut, selected)return l
}

这意味着我们只能存储一级分类标题,和二级分类标题。无法存放id之类的数据,更别说更多的自定义数据。

2.2 解决方案

将当前分类数据完整信息进行存储,后续通过选中的index判断当前选中的数据项。

// 存储分类信息 按index存储
categoryCache map[int]models.Category
// 存储书签信息 按index存储
bookmarkCache map[int]models.Bookmark

每次进行渲染分类时,除了需要清空列表数据,还需要重建分类信息缓存。

// 清空分类列表
t.categoryList.Clear()
t.categoryCache = make(map[int]models.Category)

3. 程序流程

3.1 用户交互流程

焦点变化
左箭头
右箭头
Ctrl+F
Ctrl+R
ESC或q
Enter
更新焦点索引
向左切换焦点
向右切换焦点
设置新焦点组件样式
用户按键
按键类型
激活搜索框
重置搜索
退出程序
用户输入搜索词
执行搜索
清空当前数据
查询数据库
分组匹配结果
显示分类列表
显示匹配的第一个分类的书签
显示书签详情
重置搜索状态
加载完整分类列表
显示第一个分类的书签
显示书签详情

3.功能实现

3.1 书签分类渲染

func (t *TuiView) RenderCategoryList() {// 清空分类列表t.categoryList.Clear()// 从数据库查询分类列表var categories []models.Categoryif err := t.db.Find(&categories).Error; err != nil {// 处理错误,例如记录日志或显示错误信息return}// 清空分类列表t.categoryList.Clear()t.categoryCache = make(map[int]models.Category)// 渲染分类列表到tui界面for _, category := range categories {t.categoryList.AddItem(category.Name, category.Description, 0, nil)// 存储分类信息t.categoryCache[t.categoryList.GetItemCount()-1] = category}// 如果没有分类,显示提示信息if t.categoryList.GetItemCount() == 0 {t.categoryList.AddItem("无分类", "先去添加分类吧", 0, nil)} else {t.categoryList.SetCurrentItem(0)t.RenderBookmarksView(categories[0].ID)}
}

3.2 书签分类渲染

// 添加RenderBookmarksView函数
func (t *TuiView) RenderBookmarksView(categoryID uint) {t.LogInfo("RenderBookmarksView: " + strconv.FormatUint(uint64(categoryID), 10))// 清空书签列表t.bookmarkList.Clear()t.bookmarkCache = make(map[int]models.Bookmark)// 从数据库查询指定分类的书签列表var bookmarks []models.Bookmarkif err := t.db.Where("category_id = ?", categoryID).Find(&bookmarks).Error; err != nil {// 处理错误,例如记录日志或显示错误信息return}// 渲染书签列表到tui界面for _, bookmark := range bookmarks {t.bookmarkList.AddItem(bookmark.Title, bookmark.URL, 0, nil)// 存储书签信息t.bookmarkCache[t.bookmarkList.GetItemCount()-1] = bookmark}if t.bookmarkList.GetItemCount() > 0 {t.bookmarkList.SetCurrentItem(0)t.RenderBookmarkDetail(bookmarks[0].ID)}
}

3.3 书签描述渲染

书签描述支持markdown,所以我们需要对markdown语法进行支持,更好的在终端中进行渲染。

我们需要使用到glamour
安装

go get -u "github.com/charmbracelet/glamour"

编写工具函数

package utilsimport ("fmt""github.com/charmbracelet/glamour"
)var MarkdownInstance = Markdown{}type Markdown struct {renderer *glamour.TermRenderer
}func init() {renderer, err := glamour.NewTermRenderer(glamour.WithStandardStyle("dark"),glamour.WithWordWrap(120),glamour.WithEmoji(),)if err != nil {fmt.Println(err)panic(err)}MarkdownInstance.renderer = renderer}func (c *Markdown) MarkdownRender(content string) (string, error) {out, err := c.renderer.Render(content)if err != nil {return "", err}return out, nil
}

书签描述渲染

// 完善RenderBookmarkDetail函数,调用markdown渲染
func (t *TuiView) RenderBookmarkDetail(bookmarkID uint) {// 从数据库查询书签详情var bookmark models.Bookmarkif err := t.db.First(&bookmark, bookmarkID).Error; err != nil {// 处理错误,例如记录日志或显示错误信息return}// 调用markdown渲染renderedContent, err := utils.MarkdownInstance.MarkdownRender(bookmark.Description)if err != nil {// 处理错误,例如记录日志或显示错误信息return}// 渲染书签详情到tui界面t.descriptionView.SetText(tview.TranslateANSI(renderedContent))
}

注意必须调用tview.TranslateANSI方法,否则终端会展示一堆乱码。

3.3 搜索功能实现

func (t *TuiView) SearchBookmarks(keyword string) {t.isSearching = truet.searchBox.SetText(keyword)t.bookmarkList.Clear()t.categoryList.Clear()t.categoryCache = make(map[int]models.Category)t.bookmarkCache = make(map[int]models.Bookmark)// 从数据库查询匹配的书签var bookmarks []models.Bookmarkif err := t.db.Where("title LIKE ? OR category_id IN (SELECT id FROM categories WHERE name LIKE ?)", "%"+keyword+"%", "%"+keyword+"%").Find(&bookmarks).Error; err != nil {// 处理错误,例如记录日志或显示错误信息return}// 将书签按分类分组categoryBookmarks := make(map[uint][]models.Bookmark)for _, bookmark := range bookmarks {categoryBookmarks[bookmark.CategoryID] = append(categoryBookmarks[bookmark.CategoryID], bookmark)}// 查询所有包含匹配书签的分类var categories []models.Categoryif err := t.db.Where("id IN (?)", t.db.Table("bookmarks").Select("category_id").Where("title LIKE ? OR category_id IN (SELECT id FROM categories WHERE name LIKE ?)", "%"+keyword+"%", "%"+keyword+"%")).Find(&categories).Error; err != nil {// 处理错误,例如记录日志或显示错误信息return}// 渲染分类列表到tui界面for _, category := range categories {t.categoryList.AddItem(category.Name, category.Description, 0, nil)// 存储分类信息t.categoryCache[t.categoryList.GetItemCount()-1] = category}// 如果没有匹配的分类,显示提示信息if t.categoryList.GetItemCount() == 0 {t.categoryList.AddItem("无匹配分类", "请尝试其他关键词", 0, nil)} else {// 渲染第一个分类下的书签if bookmarks, ok := categoryBookmarks[categories[0].ID]; ok {for _, bookmark := range bookmarks {t.bookmarkList.AddItem(bookmark.Title, bookmark.URL, 0, nil)// 存储书签信息t.bookmarkCache[t.bookmarkList.GetItemCount()-1] = bookmark}if t.bookmarkList.GetItemCount() > 0 {t.bookmarkList.SetCurrentItem(0)t.RenderBookmarkDetail(bookmarks[0].ID)}}t.categoryList.SetCurrentItem(0)}
}

需要注意,一定要屏蔽掉原有的书签查询逻辑,否则会造成数据异常。

3.4 事件绑定

绑定事件后,切换分类时,数据才会实时查询渲染。当搜索时,我们交由搜索函数自生处理搜索逻辑。

func (t *TuiView) BindChangeFunc() {t.categoryList.SetChangedFunc(func(index int, mainText, secondaryText string, shortcut rune) {if t.isSearching {return}// 获取当前分类列表category := t.categoryCache[index]t.LogInfo(fmt.Sprintf("category: %v", category))t.RenderBookmarksView(category.ID)})t.bookmarkList.SetChangedFunc(func(index int, mainText, secondaryText string, shortcut rune) {bookmark := t.bookmarkCache[index]t.LogInfo(fmt.Sprintf("bookmark: %v", bookmark))t.RenderBookmarkDetail(bookmark.ID)})t.searchBox.SetDoneFunc(func(key tcell.Key) {if key == tcell.KeyEnter {t.SearchBookmarks(t.searchBox.GetText())// 设置焦点到书签列表t.Focus(t.bookmarkList)} else if key == tcell.KeyF2 {t.ResetSearch()t.searchBox.SetText("")}})
}

3.5 启动时渲染分类

根据是否传入了搜索关键词来决定渲染逻辑。

// 如果搜索词不为空,直接加载搜索结果
if searchKeyword != "" {c.searchBox.SetText(searchKeyword)c.Search(searchKeyword)c.focusIndex = 1
} else {c.RenderCategoryView()
}

4.演示

aibookmark04.gif

可以快速进行书签的浏览和查询


往期系列

  • Ai书签管理工具开发全记录(一):项目总览与技术蓝图
  • Ai书签管理工具开发全记录(二):项目基础框架搭建
  • AI书签管理工具开发全记录(三):配置及数据系统设计
  • AI书签管理工具开发全记录(四):日志系统设计与实现
  • AI书签管理工具开发全记录(五):后端服务搭建与API实现
  • AI书签管理工具开发全记录(六):前端管理基础框框搭建 Vue3+Element Plus
  • AI书签管理工具开发全记录(七):页面编写与接口对接
  • AI书签管理工具开发全记录(八):Ai创建书签功能实现
  • AI书签管理工具开发全记录(九):用户端页面集成与展示
  • AI书签管理工具开发全记录(十):命令行中结合ai高效添加书签
  • AI书签管理工具开发全记录(十一):MCP集成
  • AI书签管理工具开发全记录(十二):MCP集成查询
  • AI书签管理工具开发全记录(十三):TUI基本框架搭建
  • AI书签管理工具开发全记录(十四):TUI基本界面完善

文章转载自:

http://HkP52FQB.rqhbt.cn
http://z3tXLweo.rqhbt.cn
http://26ssSL6G.rqhbt.cn
http://oZ2n0bMV.rqhbt.cn
http://NNWhGKFo.rqhbt.cn
http://QChBZIsb.rqhbt.cn
http://rgGAS8Cd.rqhbt.cn
http://KOz0gjVF.rqhbt.cn
http://ZpL8EZtS.rqhbt.cn
http://gshr9WxI.rqhbt.cn
http://fjywI10u.rqhbt.cn
http://6VMz0BGC.rqhbt.cn
http://Iwq2qMTp.rqhbt.cn
http://Xga0HGEd.rqhbt.cn
http://bJUEdvTt.rqhbt.cn
http://wxpX5PjB.rqhbt.cn
http://6EAWBLhl.rqhbt.cn
http://OYSPIdML.rqhbt.cn
http://44HtoJel.rqhbt.cn
http://hlq35W5c.rqhbt.cn
http://PBpO25JE.rqhbt.cn
http://Zoturi2i.rqhbt.cn
http://yU8ZTozl.rqhbt.cn
http://DJTKgeHr.rqhbt.cn
http://4AP99VSu.rqhbt.cn
http://g8vOdldU.rqhbt.cn
http://42TWlJ3s.rqhbt.cn
http://5HqFicoT.rqhbt.cn
http://kKLqTyfX.rqhbt.cn
http://IvQS6cjc.rqhbt.cn
http://www.dtcms.com/wzjs/766293.html

相关文章:

  • 男女做那个那个的视频网站创建公众号的步骤
  • 网站制作公司在哪里找国外营销型网站设计
  • aspcms网站栏目调用公司做网站多少钱
  • 养殖网站模版中时讯通信建设有限公司网站
  • 网站建设合同是否属于技术服务合同wap和网页的区别
  • 网站建设观点一卡2卡三卡4卡入口天堂
  • 有凡客模版怎么建设网站视频号下载软件免费
  • 免费微网站与公众号平台对接汽车网站和移动端建设方案
  • 高端网站开发设计北京icp网站备案
  • 广州皮具网站建设wordpress 模特模板
  • 中山市城乡和住房建设局网站网络营销咨询机构
  • 猪八戒网站找做微信小程序的公司logo设计logo
  • 台州网站开发外贸系统软件有哪些
  • qq在线网站代码生成网站建设人员岗位设置
  • 手机网站模板 织梦网站开发嫌工时长
  • 青岛旅游网站建设岳阳优化营商环境
  • 原创网站设计手机优化游戏性能的软件
  • wordpress适合大型网站吗浙江建设三类人员报名网站
  • 做众筹网站怎么赚钱网站设计用的技术
  • 直播网站建设费用网店运营推广中级实训
  • 企业做营销型网站奥联网站建设
  • 域名购买哪个网站最好在临沂做网站
  • 外贸网站源码是什么高端的赣州网站建设
  • 手机建站平台宛城区网站制作
  • 沈阳网站建设制作公司wordpress文章存在哪里
  • 湄洲岛网站建设cmseasy做网站简单吗
  • 哈尔滨网站建设设计手机网站模版更换技巧
  • 网站的关键词报价的网站网络运维工资一般多少
  • 网页设计网站世界杯wordpress数据库变量引用
  • 如何分析竞争对手的网站网站建设合同是否交纳印花税