Obsidan 日记、记账与自动同步
创建于 2022-06-02
更新于 2023-10-27
科技
Obsidian

前言

以前一直在用微软的 OneNote 作为笔记软件,进行资料收集和文件整理,后来在经理了一次 OneDrive 误删文件倒是 OneNote 整个笔记本丢失以后,就对这些云端方案不是很感兴趣了。于是在搜寻本地化的解决方案,网上推荐最多是 notionobsidian,调研了一番以后,选择了全面开源并免费的 obsidian 作为知识管理工具,同时也作为日常随笔记录的工具。并且基于 markdown 的写作,也方便快速通过 hexo 将内容转换为博文进行发布。

一、安装与插件

1.1 安装

Obsidian 的安装非常简单,参考 电脑重装纪实,直接一条 winget install Obsidian.Obsidian 命令即可安装。

1.2 需求分析与插件选择

Obsidian 支持第三方插件,并且在软件中内置了社区插件检索,在选项-第三方插件中,关闭安全模式即可使用 Obsidian 庞大的第三方插件库。

本人在日常记录方面有如下几个需求:

  1. 支持快速检索:格式统一,分类自由,创建便利,方便检索。
  2. 支持账单统计:方便高效的记录每一笔收支,方便控制消费欲望,避免盲目消费。
  3. 多端记录同步:台式机、笔记本、手机、平板等设备可以互相同步。

Obsidian 本身自带的日记、ZK 卡片功能就可以快速构建笔记,而其他功能大部分都可以找到满足需求的社区插件,总结列表如下:

  1. (官方)日记插件:满足日记的快速生成,同时利用模板可以统计格式。
  2. (官方)ZK 卡片插件:快速生成临时笔记,记录偶然的想法。
  3. (社区)Templater 插件:模板增强插件,提供了强大的语法支持,更方便在文档创建时规整格式。
  4. (社区)Calendar 插件:增强日历功能,在侧面板中提供日历视图,快速定位日记,同时支持周记的生成,进一步归纳总结思路。
  5. (社区)Checklist 插件:在侧面板中提供任务清单视图,可以快速检索未完成的任务。
  6. (社区)Dataview 插件:提供强大的数据查询功能,利用其提供的语法,可以快速整理计算每日账单总额。
  7. (社区)Remotely Save 插件:提供远程存储和同步。

1.3 插件配置

  1. Templater 插件:

    1. 首先构建一个用于存放模板的目录,由于目录管理默认安装字符排序,所以推荐直接在目录前加上数字,我这里选择 0-模板 作为模板目录。

    2. 将插件的 Syntax HighlightingAutomatic jump to cursorTrigger Templater on new file creation 三个功能全部激活。

    3. 记账、日记、周记、ZK 卡片总共四个模板,具体代码如下,可以根据需求进行加减。

      1. 记账模板(转账通过一笔支出一笔收入实现)
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<%* //判断模板应用模式 if(tp.config.run_mode==0){ //如果通过新建笔记应用模板,则将笔记存放到指定位置 tp.file.move("/2-日记/2.1-账单/"+tp.date.now("YYYYMMDDHHmmss")) } //账单类型(清账用于管理账户余额) const bill_type=[ "支出", "收入", "清账" ] //消费账户(根据需求设置消费所使用的账户) const bill_account=[ "微信", "支付宝", "其他" ] //消费渠道(根据需求设置消费渠道) const bill_source = [ "线下支付", "在线支付", "淘宝", "京东" ] //消费类型(根据需求设置消费类型) const expense_type=[ "食品酒水", "日常用品", "学习进修", "衣服饰品", "数码产品", "行车交通", "交流通讯", "寝室住宿", "休闲娱乐", "人情往来", "医疗保险", "转账", "其他" ] //收入类型(根据需求设置收入类型) const income_type=[ "工资", "转账", "生活费", "红包" ] //首先选择账单类型 billType= await tp.system.suggester(bill_type, bill_type,false,'请选择账单类型') //随后根据不同类型选择不同记录过程 //支出 if (billType == bill_type[0]) { billAccount = await tp.system.suggester(bill_account, bill_account,false,'请选择消费账户') billSource = await tp.system.suggester(bill_source, bill_source,false,'请选择消费渠道') type = await tp.system.suggester(expense_type,expense_type,false,'请选择账单类型') goods = await tp.system.prompt("请输入账单内容") price = await tp.system.prompt("请输入价格") date = await tp.system.prompt("请输入账单日期",tp.date.now("YYYY-MM-DD")) } //收入 if (billType == bill_type[1]) { billAccount = await tp.system.suggester(bill_account, bill_account,false,'请选择入账账户') billSource = await tp.system.suggester(bill_source, bill_source,false,'请选择入账资金来源') type = await tp.system.suggester(income_type,income_type,false,'请选择收入类型') goods = await tp.system.prompt("请输入入账明细") price = await tp.system.prompt("请输入入账金额") date = await tp.system.prompt("请输入入账日期",tp.date.now("YYYY-MM-DD")) } //清账 if (billType == bill_type[2]) { billAccount = await tp.system.suggester(bill_account, bill_account,false,'请选择清账账户') billSource = "手动输入" type = "资金清账" goods = "清账" price = await tp.system.prompt("请输入目前账户金额") date = await tp.system.prompt("请输入清账日期",tp.date.now("YYYY-MM-DD")) } -%> --- tags: - 账单 date: <% date %> goods: - <% goods %><% tp.file.cursor(0) %> type: <% type %> price: <% price %> billSource: <% billSource %> billAccount: <% billAccount %> billType: <% billType %> --- [[<% tp.date.now("YYYY-MM-DD ddd", 0, date, "YYYY-MM-DD") %>]]
code
1
2. 日记模板(在生成模板的同时,链接到前一天后一天以及当周周报)
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
--- title: tiger 的生活小记 (<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD ddd") %>) author: tiger categories: - 生活 location: - 地点 locations: weather: - 天气 tags: - 日记 date: <% tp.date.now("YYYY-MM-DD ddd") %> --- <<[[<% tp.date.now("gggg-[W]ww", 0, tp.file.title, "YYYY-MM-DD ddd") %>|每周总结]]>> << [[<% tp.date.now("YYYY-MM-DD ddd", -1, tp.file.title, "YYYY-MM-DD ddd") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 1, tp.file.title, "YYYY-MM-DD ddd") %>]] >> ## 生活记录 ### 上午`(06:00-13:00)` ### 下午`(13:00-18:00)` ### 晚上`(18:00-24:00)` ### 熬夜`(24:00-06:00)` ## 学习记录 ## 待办事项 #todo - [ ] ## ZK 卡片 ```dataviewjs const data = dv.pages('"7-ZK 卡片"') //查询 ZK 卡片目录下的笔记 .where( b => dv.equal(b.date.split(" ")[0],"<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD ddd") %>"))//过滤出当天卡片 const tableData = data.sort(b => b.date,'desc') //按日期倒序 .map(b => [b.file.link, b.title,b.date]) //取出主要字段 dv.table(["笔记", "标题","创建时间"], tableData) //收入表格 ``` ## 日常收支 ```dataviewjs const data = dv.pages('"2-日记/2.1-账单"') //查询账单目录下的笔记 .where(b=> dv.equal(b.date,dv.date("<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "YYYY-MM-DD ddd") %>")))//过滤出当天账单 const indata = data.where(b => dv.equal(b.billType,"收入")) const outdata = data.where(b => dv.equal(b.billType,"支出")) const intableData = indata.sort(b => b.date,'desc') //按日期倒序 .map(b => [b.file.link, b.billSource,b.billAccount, b.type, b.date, b.goods, b.price]) //取出主要字段 const outtableData = outdata.sort(b => b.date,'desc') //按日期倒序 .map(b => [b.file.link, b.billSource,b.billAccount, b.type, b.date, b.goods, b.price]) //取出主要字段 var totalout = 0 var totalin =0 // 统计收入总计 for(let price of indata.price.array()) { totalin += price } // 统计消费总计 for(let price of outdata.price.array()) { totalout += price } dv.header(3, "汇总") const a='账单数量:'+ data.length //账单数量 const b='消费汇总:¥'+ Math.round(totalout*100-totalin*100)/100 //收支总计 var num= data.length var sum=Math.round(totalin*100-totalout*100)/100 dv.table(["账单数量", "结余汇总¥"], dv.array([[[num],[sum]]])) //收入表格 if(totalout>0){ dv.header(4, "支出明细") const c='支出总计:¥'+ Math.round(totalout*100)/100 //消费总计 dv.list([c]) dv.table(["笔记", "来源","账户", "类型","日期", "商品", "价格¥"], outtableData) //支出表格 } if(totalin>0){ dv.header(4, "收入明细") const d='收入总计:¥'+ Math.round(totalin*100)/100 //收入总计 dv.list([d]) dv.table(["笔记", "来源","账户", "类型","日期", "商品", "价格¥"], intableData) //收入表格 } ```
code
1
3. 周记模板(汇总当周收支,并连接每天的日记)
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
--- title: tiger 的生活小记 (<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %> - <% tp.date.now("YYYY-MM-DD", 6, tp.file.title, "gggg-[W]ww") %>) author: tiger categories: - 生活 tags: - 周记 --- << [[<% tp.date.now("YYYY-MM-DD ddd", 0, tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 1, tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 2, tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 3, tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 4, tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 5, tp.file.title, "gggg-[W]ww") %>]] | [[<% tp.date.now("YYYY-MM-DD ddd", 6, tp.file.title, "gggg-[W]ww") %>]]>> ## 每周总结 ```dataviewjs const data = dv.pages('"7-ZK 卡片"') //查询 ZK 卡片目录下的笔记 .where(b=> dv.date(b.date.split(" ")[0]) >= dv.date("<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>"))//过滤出当周卡片 .where(b=> dv.date(b.date.split(" ")[0]) <= dv.date("<% tp.date.now("YYYY-MM-DD", 6, tp.file.title, "gggg-[W]ww") %>"))//过滤出当周卡片 dv.header(3, "卡片汇总") const tableData = data.sort(b => b.date,'desc') //按日期倒序 .map(b => [b.file.link, b.title,b.date]) //取出主要字段 dv.table(["笔记", "标题","创建时间"], tableData) //收入表格 ``` ```dataviewjs const data = dv.pages('"2-日记/2.1-账单"') //查询账单目录下的笔记 .where(b=> b.date >= dv.date("<% tp.date.now("YYYY-MM-DD", 0, tp.file.title, "gggg-[W]ww") %>"))//过滤出当周账单 .where(b=> b.date <= dv.date("<% tp.date.now("YYYY-MM-DD", 6, tp.file.title, "gggg-[W]ww") %>"))//过滤出当周账单 const indata = data.where(b => dv.equal(b.billType,"收入")) const outdata = data.where(b => dv.equal(b.billType,"支出")) const intableData = indata.sort(b => b.date,'desc') //按日期倒序 .map(b => [b.file.link, b.billSource,b.billAccount, b.type, b.date, b.goods, b.price]) //取出主要字段 const outtableData = outdata.sort(b => b.date,'desc') //按日期倒序 .map(b => [b.file.link, b.billSource,b.billAccount, b.type, b.date, b.goods, b.price]) //取出主要字段 var totalout = 0 var totalin =0 // 统计收入总计 for(let price of indata.price.array()) { totalin += price } // 统计消费总计 for(let price of outdata.price.array()) { totalout += price } dv.header(3, "汇总") const a='账单数量:'+ data.length //账单数量 const b='消费汇总:¥'+ Math.round(totalout*100-totalin*100)/100 //收支总计 var num= data.length var sum=Math.round(totalin*100-totalout*100)/100 dv.table(["账单数量", "结余汇总¥"], dv.array([[[num],[sum]]])) //收入表格 if(totalout>0){ dv.header(4, "支出明细") const c='支出总计:¥'+ Math.round(totalout*100)/100 //消费总计 dv.list([c]) dv.table(["笔记", "来源","账户", "类型","日期", "商品", "价格¥"], outtableData) //支出表格 } if(totalin>0){ dv.header(4, "收入明细") const d='收入总计:¥'+ Math.round(totalin*100)/100 //收入总计 dv.list([d]) dv.table(["笔记", "来源","账户", "类型","日期", "商品", "价格¥"], intableData) //收入表格 } ```
code
1
4. ZK 模板
js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
--- title: <% title = await tp.system.prompt("请输入卡片标题") %> aliases: [<% title %>] author: tiger tags: - date: '<% tp.date.now("YYYY-MM-DD HH:MM:SS",0,tp.file.title,"YYYYMMDDHHMMSS") %>' <%tp.file.rename(tp.date.now("YYYYMMDD-",0,tp.file.title,"YYYYMMDDHHMMSS") +title)%> --- << [[<% tp.date.now("YYYY-MM-DD ddd") %>]] >> ## <% title %> ## 参考 -
  1. 日记插件:
    1. 将日期格式改为 YYYY-MM-DD ddd。前一节的日记模板通过读取文件名称获取日期,需要时间格式在语法上一直,本文将时间格式设置为 2022-06-05 周日
    2. 设置新日记保存目录,本文将其设置为 2-日记,前一节账单目录为 /2-日记/2.1-账单/
    3. 根据模板名称,设置日记模板位置,本文为 0-模板/日记模板
  2. ZK 卡片插件:
    1. 设置新卡片保存目录,本文将其设置为 7-ZK卡片
    2. 根据模板名称,设置 ZK 卡片模板位置,本文为 0-模板/ZK模板
    3. 设置 ZK 卡 ID 格式,本文将其设置为 YYYYMMDDHHMMSS。参考样例 20220605160629,精确到秒防止连续创建导致卡片重名。
  3. Calendar 插件:
    1. 设置每周开始时间,默认为周一。
    2. 打开 Show week number,方便建立周报。
    3. Weekly Note Settings 中:
      1. Weekly note format 设置为 gggg-[W]ww。参考样例为 2022-W23
      2. Weekly note template 设置为 0-模板/周记模板
      3. Weekly note folder 设置为 2-日记
  4. Checklist 插件:
    1. 根据需求,在 Tag name 中添加检索用的 tag,默认只有 todo,可以再添加一个中文的 待办事项
  5. Dataview 插件:
    1. 打开 Enable JavaScript Queries
    2. Date Format 设置为 yyyy-MM-dd,参考样例为 2022-06-05
    3. Date + Time Format 设置为 yyyy-MM-dd t,参考样例为 2022-06-05 16:47
  6. Remotely Save 插件:(本文使用 webdav 作为远程存储方式,以下以坚果云为例)
    1. 注册 坚果云 账户,登录后,在安全选项页面中,添加应用,获取对应密码。坚果云默认的 WebDAV 地址为 https://dav.jianguoyun.com/dav/
    2. 在插件的 WebDav 设置中,对应填写 服务器地址用户名密码,随后检查连接是否可用。
    3. 在插件的基本设置中,修改运行条件,本文设置为 启动后30s运行一次每30分钟 运行一次。

二、运行

2.1 日记功能

Obsidian 主页面右侧找到日记插件界面,点击每日日期或左侧周数,即可创建对应笔记。

日历插件

2.2 todo 列表

Obsidian 主页面右侧找到 Tode list 插件界面,快速确定每个任务完成情况。

todolist

2.3 可视化

Obsidian 的关系图谱页面中,可以清晰的看到每笔日记的关联关系。

关系图谱

三、总结

目前 Obsidian 完美的满足了我对应全部文档数据的掌控欲,终究还是将数据存在本地比较安心。后续 Obsidian 还有许多有意思的功能值得分享,比如文本导出 PDFWord,地理地图,整合 zotero 等。

参考

本文作者: 有次元袋的 tiger
本文链接: https://www.superheaoz.top/2022/06/57091/
版权声明: 本站点所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 我的个人天地