总结汇总小工具

起因

一直以来都有每天写总结的习惯(错误日志,改的到挺少🙃),每天会记录反思并对反思的内容做了一个分类比如跟任务,情绪有关的反思就划分到**任务管理,情绪管理。**但是记录的日志划分到了每一天,回头重新看的时候太麻烦,希望相同类型的日志能够按照时间汇总到一起方便浏览查看😄。

思路

使用的笔记软件是语雀 提供了对应的开放API, 大致思路是编写日志的时候,按照设定规则去编写,在去获取对应的文章数据解析文章 结构生成目标结构的文本数据 在调用接口创建新的doc

具体实现

获取到勾选的所有文章数据,去提取对应的分类信息并转换成对象结构并按标题分组 ,在对每个分组的反思根据时间设定的规则 排序,最后在合并所有分组,并调用创建doc接口!

vue 复制代码
async function mergeDoc() {
    
    if (targetDoc.value.filter((item) => !item.children.length).length !== 1 
    || awaitMergeDocs.value.length === 0) {
        return ElMessage.error("文档选择不正确");
    }
    isLoading.value = true;
    // 得到所有的文章数据
    const docs = await getSelectedDocs(toValue(awaitMergeDocs));
   
    // 将文章转换为分类对象 
    const cryObj = docs.flatMap((doc) => matchSummary(doc))

    //根据最早最晚得到标题
    const title =  getMergeTitle(cryObj)
    
    //将分类对象进行分组 
    const cryGroup = generateGroup(cryObj)
    
    //对分类对象进行排序
    Object.keys(cryGroup).forEach((k) => cryGroup[k] = sortTime(cryGroup[k]))
   
    let newDocStr = mergeSummary(cryGroup)
 
    await createSummary(`/repos/${selectBook.value}/docs/${targetDoc.value[0].id}`, {
        slug: targetDoc.value[0].id,
        title: title,
        body: newDocStr
    })

    ElMessage.success("合并成功!")

    isLoading.value = false;
}

文本转换成分类对象

先调用handleRethinks去提取出doc里面的rethink字符串,在调用summaryGrouprethink下的二级标题以及内容转换为对象。

javascript 复制代码
// 匹配一级标题日期
const matchRegex = {
  matchTime: /^#\s\d{4}年\d{1,2}月.*?日/gm,  //提取时间
}

let docInfo = null;

// 入口函数 返回提取的本篇文章的总结对象, 一般调用至少调用三十次,
export default function main(data) {
  // 保存文章对象
  docInfo = data

  let summaryText =  data.body; //得到md文件格式
  // 表示是单元
  let isStage = data.title.includes("单元");

  const dates = summaryText.match(matchRegex.matchTime) ?? [];

  // 提取的rethinks
  let rethinks = handelRethinks(summaryText,isStage);

  const stageSummary = rethinks.flatMap((item, index) =>
    summaryGroupAdapter(isStage, item, dates[index]));

  return stageSummary;
}

function summaryGroupAdapter(isStage,str,time){
  //!不是总结
  return summaryGroup(str, time, !isStage ? "\n# rethink" : "\n## rethink");
}

//!2. 将总结转换为分类对象
function summaryGroup(str, time, startStr = "\n## rethink") {

  let source = str.replace(startStr, "")
  //!总结的分类就是三级标题
  return source.split("###").filter((item) => item !== "\n" && item).map((item) => {
    let index = item.indexOf("\n");
    return {
      group: item.slice(0, index),//标题结尾有一个换行
      content: item.slice(index).replace(`\n`,`\n   `).replace(`\n\n`,`\n\n   `),
      time:startStr ===  "\n## rethink" ? time : `# ${docInfo.title}`
    }
  })
}
// 截取反思字符串
function handelRethinks(text, isStage) {
  return isStage ? sliceRethinks(text) 
    : sliceRethinks(text, "\n# rethink", "\n# idea");
}


// 截取反思字符串 包括标题
function sliceRethinks(str, startStr = "\n## rethink", endStr = "\n## idea") {

  let results = [];

  let sourceStr = str;

  while (sourceStr.search(startStr) !== -1) {

    let startIndex = sourceStr.search(startStr);

    let endIndex = sourceStr.search(endStr);
    // 
    let rethinks = sourceStr.slice(startIndex, endIndex);

    results.push(rethinks);

    sourceStr = sourceStr.slice(endIndex + endStr.length)
  }

  return results;
}

分组并排序

先对整个数组反思对象进行分组,在调用sortTime进行排序内部先对合法的字符串进行升序,在对不合法的字符串按照一定规则**排序,**最后在合并在一起。

javascript 复制代码
// 阶段总结格式化
let stageFormat = {
    "第一阶段": 0,
    "第二阶段": 1,
    "第三阶段": 2,
    "第四阶段": 3,
    "第五阶段": 4,
    "第六阶段": 5,
    "第七阶段": 6,
    "第八阶段": 7,
    "第九阶段": 8,
    "第十阶段": 9,
    "第十一阶段": 10,
    "第十二阶段": 11,
    "第十三阶段": 12,
    "第十四阶段": 13,
    "第十五阶段": 14
}

// 对数据进行分组
export function generateGroup(cates) {

    return cates.reduce((pre, item) => {

        if (pre[item.group]) {
            pre[item.group].push(item)
        } else {
            pre[item.group] = [item]
        }
        return pre;
    }, {})
}

// 定义一个函数来转换日期格式为时间戳
export function convertDateToTimestamp(dateStr) {
    //exec匹配换成match匹配
    const dateParts = dateStr.match(/\d+/g).map(Number);
    return new Date(dateParts[0], dateParts[1] - 1, dateParts[2]).getTime();
}

// 针对数据排序的工具函数
export function sortTime(cgyData) {

    let verifyDate = /^#\s\d{4}年\d{1,2}月\d{1,2}日/gm

    let correctFormatData = cgyData.filter((cry) => cry.time.search(verifyDate) !== -1);

    let unCorrectFormatData = cgyData.filter((cry) => cry.time.search(verifyDate) === -1);
    // 按照时间进行排序
    correctFormatData.sort((a, b) => {

        let aTimeStr = extractTimeStr(a.time);

        let bTimeStr = extractTimeStr(b.time);

        return convertDateToTimestamp(aTimeStr) - convertDateToTimestamp(bTimeStr)
    })
    // 处理不规范的排序
    unCorrectFormatData = sortUnCorrectFormat(unCorrectFormatData)

    return correctFormatData.concat(unCorrectFormatData)
}
// 处理不规范格式
function sortUnCorrectFormat(cryList) {

    let newArr = new Array(cryList.length).fill(0);

    let staged = [] //暂存标题不合法数据

    cryList.forEach((cry) => {

        let time = cry.time.slice(-4);

        let stageTitle = stageFormat[time];

        if (stageTitle!== undefined) {
            newArr[stageTitle] = cry;
        } else {
            staged.push(cry);
        }
    })
    return newArr.filter((item) => item !== 0).concat(staged)
}

function sortArrayByTime(cgyData) {
//! 去掉全局和多行匹配
    let verifyDate = /^#\s\d{4}年\d{1,2}月\d{1,2}日/
    let correctFormatData = cgyData.filter((cry) => cry.time.search(verifyDate) !== -1);

    correctFormatData.sort((a, b) => {
        //!抽取复用代码
        let aTimeStr =  extractTimeStr(a.time);

        let bTimeStr =  extractTimeStr(b.time);

        return convertDateToTimestamp(aTimeStr) - convertDateToTimestamp(bTimeStr)
    });

    return correctFormatData;
}
//!抽取的单行代码
function extractTimeStr(timeStr) {
    return timeStr.split(" ").pop();
}
// 得到文章的标题
export function getMergeTitle(arr) {

    let correctFormatData = sortArrayByTime(arr)

    let firstElm = correctFormatData[0];

    let lastElm = correctFormatData[correctFormatData.length - 1];

    if (correctFormatData.length === 1) {  //只有一个值

        return extractTimeStr(firstElm.time)    
    }

    return `${extractTimeStr(firstElm.time)} - ${extractTimeStr(lastElm.time)}`;
}

合并对应文档

最后根据将排序 后的数据合并在一起,得到**汇总字符串,**根据合并后端字符串创建doc

javascript 复制代码
// 合并字符串
export function mergeSummary(groupObj) {
    let summary = ""

    Object.keys(groupObj).forEach((key) => {

        let sayCate = ""

        sayCate = groupObj[key].map((item) => `#${item.time}${item.content}`).join("")

        summary += `# ${key}\n${sayCate}`; //设置上key
    })
    return summary
}

结果

在实现了对应的ui界面逻辑(具体代码),并托管到netlify上,不得不说netlify真的强大还支持代理。

总结

拆分代码真的很重要,刚开始不注意写成一坨,后面具体拆分了一下函数以及组件。无论是扩展性,还是可读性都提高了很多!

相关推荐
zqx_711 分钟前
随记 前端框架React的初步认识
前端·react.js·前端框架
惜.己28 分钟前
javaScript基础(8个案例+代码+效果图)
开发语言·前端·javascript·vscode·css3·html5
什么鬼昵称1 小时前
Pikachu-csrf-CSRF(get)
前端·csrf
长天一色1 小时前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_2341 小时前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河1 小时前
CSS总结
前端·css
NiNg_1_2341 小时前
Vue3 Pinia持久化存储
开发语言·javascript·ecmascript
读心悦1 小时前
如何在 Axios 中封装事件中心EventEmitter
javascript·http
BigYe程普2 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
神之王楠2 小时前
如何通过js加载css和html
javascript·css·html