先上效果图:

具体功能:
- 自动统计时间进度
- 自动统计关联文档中的任务数量,并显示任务进度。任务进度设置了判断条件,若文档中没有任务项,则显示“无任务”(任务数为 0 的时候模板会报错,但是能渲染出“无任务”,错误提醒显示分母为零,但是我已经设置了条件判断,不知道为什么还是会报错 😂。本人代码小白,有没有大佬帮忙修复一下这个 BUG)
- 状态栏根据计划时间和任务进度设置了:筹备中(计划时间列为空)、未开始(当天日期早于开始时间)、进行中(当天日期位于开始和结束日期之间)、冲刺中(当天日期和结束日期天数差小于 5 天或任务进度大于 80%)、已完成(任务进度 100%)以及过期(当天时间超过截止日期且任务进度小于 100%)
推荐结合 F 大佬的 F“s 工具箱使用动态数据库功能通过标签将任务文档自动汇总进数据库中。
模板文件:
模板代码:
时间进度列:
.action{$startTime := .计划时间}
.action{$endTime := .计划时间_end}
.action{$totalDuration := 0}
.action{$elapsedDuration := 0}
.action{$percentage := 0.0}
.action{$color := "rgb(45,164,78)"}
.action{$remainingText := ""}
.action{if and (not (eq $startTime nil)) (not (eq $endTime nil))}
.action{$nowdate := now}
.action{$endTimeParsed := $endTime}
.action{$startTimeParsed := $startTime}
.action{if and (ne $startTimeParsed nil) (ne $endTimeParsed nil)}
.action{$totalDuration = $endTimeParsed.Sub $startTimeParsed}
.action{$elapsedDuration = $nowdate.Sub $startTimeParsed}
.action{$totalDurationHours := divf $totalDuration.Hours 1}
.action{if gt $totalDurationHours 0.0}
.action{$percentage = (mulf (divf (div $elapsedDuration.Hours 1) $totalDurationHours) 100.0)}
.action{$daysLeft := divf ($endTimeParsed.Sub $nowdate).Hours 24}
.action{if eq 0 $startTimeParsed.Minute $startTimeParsed.Hour $endTimeParsed.Minute $endTimeParsed.Hour }
.action{$daysLeft = ceil (divf ($endTimeParsed.Sub $nowdate).Hours 24)}
.action{end}
.action{if gt $daysLeft 0.0}
.action{$remainingText = printf "还剩%.0f天" $daysLeft}
.action{else if eq $daysLeft 0.0}
.action{$remainingText = "当天"}
.action{else}
.action{$remainingText = printf "已过%.0f天" (subf 0.0 $daysLeft)}
.action{end}
.action{end}
.action{end}
.action{end}
.action{$colorGradient_triggerPercentage := list 90.0 70.0 50.0 20.0 0.0}
.action{$colorGradient_baseColor := list "#f94144" "#FF6E34" "#ffcc00" "#2DA44E" "#2571BF"}
.action{range $index, $element := $colorGradient_triggerPercentage}
.action{if ge $percentage (index $colorGradient_triggerPercentage $index)}
.action{$color = index $colorGradient_baseColor $index}
.action{break}
.action{end}
.action{end}
<span style="background-color: rgba(175,184,193,0.2); width: 100%; display: inline-block;height: 12px;border-radius: 6px;align-self: center;overflow: hidden; position: relative;">
<!-- 深灰色到浅灰色的渐变背景层 -->
<span style="
width: .action{$percentage}%;
height: 100%;
background-image: linear-gradient(0deg, #3a3742 0%, #6a6772 100%); /* 深灰色到浅灰色的渐变 */
display: block;
"></span>
<!-- 数字层(显示剩余天数) -->
<span style="
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 10px;
line-height: 12px;
color: white;
text-shadow: 0 0 2px rgba(0,0,0,0.5);
">
<span style="font-weight: bold;">.action{$remainingText}</span>
</span>
</span>
任务进度列:
.action{$todo:=queryBlocks "select * from blocks where root_id in (select root_id from blocks where id='?') and type='i' and subtype='t'" .id}
.action{$all:=len $todo} <!-- 先取长度 -->
.action{if eq $all 0}
<span style="background-color: rgba(175,184,193,0.2);" data-type='tag'>无任务</span>
.action{else if ne $all 0}
.action{$readytodo:=queryBlocks "select * from blocks where root_id in (select root_id from blocks where id='?') and type='i' and subtype='t' and markdown like '%[x]%'" .id}
.action{$readyall:=len $readytodo}
.action{$d:=div (mul $readyall 100) $all} <!-- 直接用数字 -->
<span style="background-color:rgba(175,184,193,0.2);width:100%;display:inline-block;height:12px;border-radius:6px;position:relative;overflow:hidden;">
<span style="width: .action{$d}%;height:100%;background-image:linear-gradient(0deg,#2f3f3a 0%,#5e7a75 100%);display:block;"></span>
<span style="position:absolute;top:0;left:0;width:100%;text-align:center;font-size:10px;line-height:12px;color:white;text-shadow:0 0 2px rgba(0,0,0,0.5);">
<span style="font-weight:bold;">.action{floor $d}</span>%
</span>
</span>
.action{end}
状态列:
.action{$startTime := .计划时间}
.action{$endTime := .计划时间_end}
.action{$today:= (now | date "2006-01-02")}
.action{$nowdate:=(toDate "2006-01-02" $today)}
.action{$delta1 :=(div ($startTime.Sub $nowdate).Hours 24)}
.action{$delta2 :=(div ($endTime.Sub $nowdate).Hours 24)}
.action{$todo:=queryBlocks " select * from blocks where root_id in (select root_id from blocks where id='?') and type='i' and subtype='t' " .id}
.action{$all:=$todo | len}
.action{$readytodo:=queryBlocks " select * from blocks where root_id in (select root_id from blocks where id='?') and type='i' and subtype='t' and markdown like '%[x]%%' " .id}
.action{$readyall:=$readytodo | len}
.action{$a:=index $readyall}
.action{$b:=index $all}
.action{$c:= mul $a 100}
.action{$d:= div $c $b}
.action{$a := randInt 1 13}
.action{if empty .计划时间}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">筹备中</span>
.action{else if gt $delta1 0}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">未开始</span>
.action{else if and (le $delta1 0) (ge $delta2 0) (ne $a $b)}
.action{if or (le $delta2 5) (ge $d 80)}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">冲刺中</span>
.action{else if and (le $delta1 0) (gt $delta2 5) (lt $d 80)}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">进行中</span>
.action{end}
.action{else if and (le $delta1 0) (ge $delta2 0) (eq $a $b)}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">已完成</span>
.action{else if and (ne $a $b) (lt $delta1 0) (lt $delta2 0)}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">过期</span>
.action{end}
分类列:
.action{ $blocks := queryBlocks "select * from blocks where id='?'" .id}
.action{ if not (empty $blocks) }
.action{ $tag := (first $blocks).Tag | replace "#" "" }
.action{$a := randInt 1 13}
<span class="b3-chip" style="background-color:var(--b3-font-background.action{$a});color:var(--b3-font-color.action{$a})">.action{$tag}</span>
.action{ end }
分类列其实就是我将文档的标签单独提取了出来,并设置了一下标签颜色。
因为我使用动态数据库动态查询将带有 OKR 和任务标签的文档都汇总到数据库中,这样通过多维表格单独筛选 OKR 文档和任务文档,就能够直观的看到任务和 OKR 的进度情况。

欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于