作一個CLI版的時間管理工具(六)

作一個CLI版的時間管理工具(六)

這是我參與8月更文挑戰的第7天,活動詳情查看:8月更文挑戰git

前言

上一篇文章主要闡述了生成一段時間內的報告指令:github

  • timec -or --range <startTime>_<endTime> <filename1> <filename1> .....

有時候指望直接導出的某一天,某一月,甚至某一年的數據,爲此將會拓展幾個日期相關的指令json

  • 某一天:timec -or --day [date]
  • 某一月:timec -or --month [month]
    • 將默認爲今年
  • 某一年:timec -or --year [year]
  • 某年某月:timec -or -Y [year] -M [month]
    • --month--year組合使用
    • 其中-M-Y分別是上述兩個指令的縮寫

除了這部份內容,本節也將會進入新的篇章,開始開發使用指令管理任務與事務數組

本文將會涉及任務相關的指令開發:timec task [name]markdown

本期效果

圖片

功能開發

本部分將會省略五官代碼(前幾篇文章已出現過)app

日期相關指令

具體到天

首先是指定到某一天:ide

  • 經過option註冊可選參數
  • 經過cmdObj的day屬性拿到用戶傳入的值
.option('-D, --day [date]', 'One day')
// 省略actions code
const { day } = cmdObj
複製代碼

對輸出報告的函數進行改造封裝:函數

  • 參數分別是開始時間結束時間
    • 這樣其他幾個可選參數指令也可直接複用
const output = (s, e) => {
  const outPutPath = getFilePath(cwd, `report-${outFileName}.md`)
  const json = getJSONByRange(content, s, e)
  if (json.length === 0) {
      console.log('沒有符合條件的數據');
      return
  }
  const data = outPutReport(json)
  createFile(outPutPath, data, false)
  console.log(`導出成功`);
}
複製代碼

判斷日期是否存在,存在則直接導出工具

  • 開始與結束時間都是傳入的日期
if (day) {
    return output(day, day)
}
複製代碼

具體到月

老規矩先註冊相關指令oop

.option('-M, --month [month]', 'One month')
複製代碼

若是隻有月,那麼默認年就是今年,起止時間分別是

  • nowYear-month-01
  • nowYear-month-days

插播一條技巧:如何快速獲取某年某月的天數:

  1. Date構造函數支持傳入年,月,日三個參數的函數重載
  2. 其中月是從0開始計算:"1-12"分別對應"0-11"
  3. 當日部分的參數傳入0時,表示上月最後一天的日期
  4. 此時再調用getDate方法獲取日期,則獲取到目標月份的天數

例如:2021-08月的天數:

  • new Date(2021,8,0)
  • 標識2021年9月開始的前一天日期,即2021年8月31日
  • getDate返回結果即爲31
const days = new Date(year,month,0).getDate()
複製代碼

導出邏輯以下:

  • 今年的年份經過new Date().getFullYear()獲取
if (month) {
    const year = new Date().getFullYear()
    return output(`${year}-${month}-01`, `${year}-${month}-${new Date(year, month, 0).getDate()}`)
}
複製代碼

具體到年

若是是年,那麼起止時間分別就是:

  • year-01-01
  • year-12-31

這個沒得太多說法,輕車熟路寫好

.option('-Y, --year [year]', 'One year')
// ...more code
if (year) {
    return output(`${year}-01-01`, `${year}-12-31`)
}
複製代碼

具體到某年某月

這個就是-M與-Y參數組合使用時的場景

只須要將上述兩種導出方式的邏輯作一個合併便可,邏輯簡單

if (year && month) {
    return output(`${year}-${month}-01`, `${year}-${month}-${new Date(year, month, 0).getDate()}`)
}
複製代碼

幾個日期相關的指令搞完,接着就開始整任務相關的指令

任務管理指令

指令格式以下

timec task [name]
複製代碼

name參數是可選的,有以下幾種邏輯:

  • 當name爲空時,展現全部的任務,並標記正在進行中的任務
  • 當name不存在時,將其添加進任務列表
  • 當name存在時,將其設置爲正在進行中的任務

理清邏輯後,進入開發

初始化配置文件

在項目工程的根目錄建立一個.config/record.json文件

/Users/sugar/Documents/fe-project/time-control
├── bin
├── src
├── test
├── .config
├────└──record.json
└── test2.md
複製代碼

配置文件結構以下:

{
    "recordFilepath": "",
    "tasks": [],
    "defaultTaskIdx": -1,
    "thing": {
        "name": "",
        "startTime": "2021-01-01",
        "endTime": "2021-12-31",
        "pauseTime": "2021-12-26"
    }
}
複製代碼

這裏將主要用到tasksdefaultTaskIdx兩個屬性,前者記錄全部的任務,後者記錄當前正在進行的任務

註冊指令

使用commander.command註冊指令:

  • 其中使用[]包裹的參數標識可選參數
/** * 建立任務、切換任務、查看任務列表 */
commander.command("task [name]")
    .alias('t')
    .description('check tasks/add task/checkout task')
    .action((name) => {
        // ...code 後文介紹
    })
複製代碼

配置文件的路徑

  • 經過__dirname與配置文件的相對路徑定位配置文件
const configPath = path.join(__dirname, '../.config/record.json')
複製代碼

經過require方法引入json配置文件

  • 引入的內容就是一個對象,無需調用JSON.parse進行轉換
const config = require(configPath)
複製代碼

下面就到具體的業務邏輯代碼

  • 先判斷是否傳入任務名name
    • 沒有,判斷是否有任務,有則順序打印,無則打印提示信息
  • 若是任務名不存在,則加入任務列表tasks
    • 存在,則將這個任務設置爲正在進行的任務,即更新defaultTaskIdx的值
  • 最後更新配置文件的內容
const { tasks, defaultTaskIdx } = config
const idx = tasks.findIndex(v => v === name)
if(!name){
    if(tasks.length===0){
        console.log('no tasks, you can use command add task');
        console.log('timec task [name]');
        return 
    }
    tasks.forEach((v,i)=>{
        let mark = '[ ]'
        if(i===+defaultTaskIdx){
            mark = '[*]'
        }
        console.log(mark,v);
    })
    return
}
if (idx === -1) {
    tasks.push(name)
    if(tasks.length===1){
        config.defaultTaskIdx = 0
    }
    console.log('add task success');
}else{
    config.defaultTaskIdx = idx
    console.log('now use task:',tasks[idx]);
}
writeFileSync(configPath,JSON.stringify(config))
複製代碼

這個指令就開發完了,時間倉促,代碼質量可能不會過高

TODO:後續優化

小結

到目前爲止已經支持以下指令:

圖片

這些指令都還不是最終版本,因爲時間太緊湊,設計時間也較短,後期會不斷完善

其它

因爲天天空閒時間有限,本文就先到這

若是讀者還感受意猶未盡,敬請期待後續更新,或持續關注一下倉庫的狀態

歡迎評論區提需求,交流探討

本系列會不斷的更新迭代,直至產品初代完成

相關文章
相關標籤/搜索