فهرست منبع

feat: Fix the bug that 'Get Log Data Block' can't get the latest logs, change it to get the latest logs from the current workflow state and convert it to text and json

赵思 2 سال پیش
والد
کامیت
dbe391a0c1

+ 1 - 8
src/components/newtab/logs/LogsHistory.vue

@@ -296,7 +296,7 @@ import Papa from 'papaparse';
 import objectPath from 'object-path';
 import { countDuration, fileSaver } from '@/utils/helper';
 import { getBlocks } from '@/utils/getSharedData';
-import { dataExportTypes } from '@/utils/shared';
+import { dataExportTypes, messageHasReferences } from '@/utils/shared';
 import dayjs from '@/lib/dayjs';
 
 const SharedCodemirror = defineAsyncComponent(() =>
@@ -363,13 +363,6 @@ const tabs = [
   { id: 'referenceData.prevBlockData', name: 'Previous block data' },
   { id: 'replacedValue', name: 'Replaced value' },
 ];
-const messageHasReferences = [
-  'no-tab',
-  'invalid-active-tab',
-  'no-match-tab',
-  'invalid-body',
-  'element-not-found',
-];
 
 const { t, te } = useI18n();
 

+ 142 - 0
src/utils/getTranslateLog.js

@@ -0,0 +1,142 @@
+import { getBlocks } from '@/utils/getSharedData';
+import dayjs from '@/lib/dayjs';
+import vueI18n from '@/lib/vueI18n';
+import { countDuration } from '@/utils/helper';
+import { messageHasReferences } from '@/utils/shared';
+
+const blocks = getBlocks();
+
+/**
+ * 转换日志
+ * @param {*} log
+ * @returns
+ */
+function translateLog(log) {
+  const copyLog = { ...log };
+  const getTranslatation = (path, def) => {
+    const params = typeof path === 'string' ? { path } : path;
+
+    return vueI18n.global.te(params.path)
+      ? vueI18n.global.t(params.path, params.params)
+      : def;
+  };
+
+  if (['finish', 'stop'].includes(log.type)) {
+    copyLog.name = vueI18n.global.t(`log.types.${log.type}`);
+  } else {
+    copyLog.name = getTranslatation(
+      `workflow.blocks.${log.name}.name`,
+      blocks[log.name].name
+    );
+  }
+
+  if (copyLog.message && messageHasReferences.includes(copyLog.message)) {
+    copyLog.messageId = `${copyLog.message}`;
+  }
+
+  copyLog.message = getTranslatation(
+    { path: `log.messages.${log.message}`, params: log },
+    log.message
+  );
+
+  return copyLog;
+}
+
+function getDataSnapshot(propsCtxData, refData) {
+  if (!propsCtxData?.dataSnapshot) return;
+
+  const data = propsCtxData.dataSnapshot;
+  const getData = (key) => {
+    const currentData = refData[key];
+    if (typeof currentData !== 'string') return currentData;
+
+    return data[currentData] ?? {};
+  };
+
+  refData.loopData = getData('loopData');
+  refData.variables = getData('variables');
+}
+
+/**
+ * 获取日志
+ * @param {*} dataType 日志数据类型
+ * @param {*} translatedLog 转换后的日志
+ * @returns
+ */
+function getLogs(dataType, translatedLog, curStateCtxData) {
+  let data = dataType === 'plain-text' ? '' : [];
+  const getItemData = {
+    'plain-text': ([
+      timestamp,
+      duration,
+      status,
+      name,
+      description,
+      message,
+      ctxData,
+    ]) => {
+      data += `${timestamp}(${countDuration(
+        0,
+        duration || 0
+      ).trim()}) - ${status} - ${name} - ${description} - ${message} - ${JSON.stringify(
+        ctxData
+      )} \n`;
+    },
+    json: ([
+      timestamp,
+      duration,
+      status,
+      name,
+      description,
+      message,
+      ctxData,
+    ]) => {
+      data.push({
+        timestamp,
+        duration: countDuration(0, duration || 0).trim(),
+        status,
+        name,
+        description,
+        message,
+        data: ctxData,
+      });
+    },
+  };
+  translatedLog.forEach((item, index) => {
+    let logData = curStateCtxData;
+    if (logData.ctxData) logData = logData.ctxData;
+
+    const itemData = logData[item.id] || null;
+    if (itemData) getDataSnapshot(curStateCtxData, itemData.referenceData);
+
+    getItemData[dataType](
+      [
+        dayjs(item.timestamp || Date.now()).format('YYYY-MM-DD HH:mm:ss'),
+        item.duration,
+        item.type.toUpperCase(),
+        item.name,
+        item.description || 'NULL',
+        item.message || 'NULL',
+        itemData,
+      ],
+      index
+    );
+  });
+  return data;
+}
+
+/**
+ * 获取日志数据
+ * @param {*} curState 当前工作流状态
+ * @param {*} dataType 日志数据类型 plain-text 和 json
+ * @returns
+ */
+export default function (curState, dataType = 'plain-text') {
+  const { logs: curStateHistory, ctxData: curStateCtxData } = curState;
+  // 经过转换后的日志
+  const translatedLog = curStateHistory.map(translateLog);
+  // 获取日志
+  const logs = getLogs(dataType, translatedLog, curStateCtxData);
+  // 获取日志
+  return logs;
+}

+ 8 - 0
src/utils/shared.js

@@ -1736,3 +1736,11 @@ export const conditionBuilder = {
     },
   },
 };
+
+export const messageHasReferences = [
+  'no-tab',
+  'invalid-active-tab',
+  'no-match-tab',
+  'invalid-body',
+  'element-not-found',
+];

+ 5 - 1
src/workflowEngine/WorkflowEngine.js

@@ -555,7 +555,11 @@ class WorkflowEngine {
       tabIds: [],
       currentBlock: [],
       name: this.workflow.name,
-      logs: this.history.slice(-5),
+      logs: this.history,
+      ctxData: {
+        ctxData: this.historyCtxData,
+        dataSnapshot: this.refDataSnapshots,
+      },
       startedTimestamp: this.startedTimestamp,
     };
 

+ 22 - 17
src/workflowEngine/blocksHandler/handlerLogData.js

@@ -1,32 +1,37 @@
-import dbLogs from '@/db/logs';
+import getTranslateLog from '@/utils/getTranslateLog';
+import { workflowState } from '../index';
 
 export async function logData({ id, data }) {
   if (!data.workflowId) {
     throw new Error('No workflow is selected');
   }
 
-  const [workflowLog] = await dbLogs.items
-    .where('workflowId')
-    .equals(data.workflowId)
-    .reverse()
-    .sortBy('endedAt');
-  let workflowLogData = null;
+  // 工作流状态数组
+  const { states } = workflowState;
+  let logs = [];
+  if (states) {
+    // 转换为数组
+    const stateValues = Object.values(Object.fromEntries(states));
+    // 当前工作流状态
+    const curWorkflowState = stateValues.find(
+      (item) => item.workflowId === data.workflowId
+    )?.state;
 
-  if (workflowLog) {
-    workflowLogData = (
-      await dbLogs.logsData.where('logId').equals(workflowLog.id).first()
-    ).data;
+    if (curWorkflowState) {
+      // 当前工作流最新日志
+      logs = getTranslateLog(curWorkflowState, 'json');
 
-    if (data.assignVariable) {
-      this.setVariable(data.variableName, workflowLogData);
-    }
-    if (data.saveData) {
-      this.addDataToColumn(data.dataColumn, workflowLogData);
+      if (data.assignVariable) {
+        this.setVariable(data.variableName, logs);
+      }
+      if (data.saveData) {
+        this.addDataToColumn(data.dataColumn, logs);
+      }
     }
   }
 
   return {
-    data: workflowLogData,
+    data: logs,
     nextBlockId: this.getBlockConnections(id),
   };
 }