资源容量规划:

高级

这是一个自动化工作流,包含 17 个节点。主要使用 If、Code、Jira、Gmail、GoogleSheets 等节点。 监控Jira中的团队容量,并在超配时发送警报

前置要求
  • Google 账号和 Gmail API 凭证
  • Google Sheets API 凭证

分类

未分类
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "RRgZgaqK8c05uX4J",
  "meta": {
    "instanceId": "8443f10082278c46aa5cf3acf8ff0f70061a2c58bce76efac814b16290845177",
    "templateCredsSetupCompleted": true
  },
  "name": "资源容量规划:",
  "tags": [],
  "nodes": [
    {
      "id": "73e34959-f752-4bb0-a55a-73282abadde5",
      "name": "当点击\"执行工作流\"时",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -560,
        -16
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "13f023dd-3654-4e19-9e68-f6be0d8aec06",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1152,
        64
      ],
      "parameters": {
        "width": 352,
        "height": 480,
        "content": "## 📧 向经理发送超分配警报"
      },
      "typeVersion": 1
    },
    {
      "id": "08cb35a9-0612-494b-bf9d-c3436b845d10",
      "name": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -688
      ],
      "parameters": {
        "width": 288,
        "height": 560,
        "content": "## 📢 生成超分配警报报告"
      },
      "typeVersion": 1
    },
    {
      "id": "79868a06-b2cf-4e68-b4ab-8b49fd6c5983",
      "name": "便签 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        128
      ],
      "parameters": {
        "height": 496,
        "content": "## ⚠️ 检测超分配团队成员"
      },
      "typeVersion": 1
    },
    {
      "id": "1fb0b12d-4aee-4ad0-80d5-90470013b097",
      "name": "便签 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        384,
        -816
      ],
      "parameters": {
        "height": 592,
        "content": "## 📈 记录容量数据到跟踪表格"
      },
      "typeVersion": 1
    },
    {
      "id": "60bcfb26-5e75-4f78-96c6-4ce964030bfe",
      "name": "便签 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        128,
        -704
      ],
      "parameters": {
        "height": 656,
        "content": "## 📊 计算团队成员利用率"
      },
      "typeVersion": 1
    },
    {
      "id": "ea3a99a2-8388-400a-8835-e879e3952a84",
      "name": "便签 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        32,
        448
      ],
      "parameters": {
        "height": 576,
        "content": "## 📊 记录查询失败到错误表格"
      },
      "typeVersion": 1
    },
    {
      "id": "ece752c2-40d2-4e9b-b21c-62c6d3ddfb51",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -160,
        -528
      ],
      "parameters": {
        "height": 480,
        "content": "## ✅ 验证成功检索的问题"
      },
      "typeVersion": 1
    },
    {
      "id": "a44b5a35-d244-466c-8ef9-6ce5c155e655",
      "name": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -352,
        192
      ],
      "parameters": {
        "height": 464,
        "content": "## 📋 获取活跃Jira问题"
      },
      "typeVersion": 1
    },
    {
      "id": "da294676-ddf2-4411-82d1-cdfa2b64cb5b",
      "name": "Jira获取问题节点",
      "type": "n8n-nodes-base.jira",
      "position": [
        -304,
        -16
      ],
      "parameters": {
        "options": {
          "jql": "=statusCategory != Done AND status = \"In Progress\"\n"
        },
        "operation": "getAll"
      },
      "credentials": {
        "jiraSoftwareCloudApi": {
          "id": "199LdjjU3PhhL8xb",
          "name": "saurabh jira"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "5fdb6740-8798-43a0-bd92-bfe826ef6595",
      "name": "数据验证",
      "type": "n8n-nodes-base.if",
      "position": [
        -80,
        -16
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "ef3f0536-f084-4c2b-9bf6-7cd172f90035",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $input.all().length > 0 }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "2b109593-2b1e-4fb3-a4c4-b6bf9c228842",
      "name": "容量计算器",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        -32
      ],
      "parameters": {
        "jsCode": "// In n8n, when \"Run Once for All Items\" is selected, use $input.all()\nconst items = $input.all();\n\nif (items.length === 0) {\n  return { json: { message: \"No issues found.\" } };\n}\n\n// Define a dictionary to store capacity data for each user\nconst userCapacity = {};\n\n// Loop through all items (each item is a Jira issue)\nitems.forEach(item => {\n  const issue = item.json;\n  \n  // Get assignee name\n  const assignee = issue.fields?.assignee?.displayName || 'Unassigned';\n  \n  // Get time spent in seconds\n  const timeSpent = issue.fields?.timespent || 0;\n  \n  // Convert timeSpent from seconds to hours\n  const hoursSpent = timeSpent / 3600;\n  \n  // Add the time spent to the user's total\n  if (!userCapacity[assignee]) {\n    userCapacity[assignee] = 0;\n  }\n  userCapacity[assignee] += hoursSpent;\n});\n\n// Now calculate utilization and flag over-allocated users\nconst utilizationData = [];\nconst maxCapacity = 8; // max available hours per day\n\nfor (let assignee in userCapacity) {\n  const totalHours = userCapacity[assignee];\n  const utilizationPercentage = (totalHours / maxCapacity) * 100;\n  \n  utilizationData.push({\n    assignee: assignee,\n    totalHours: parseFloat(totalHours.toFixed(2)),\n    utilizationPercentage: parseFloat(utilizationPercentage.toFixed(2)),\n    status: utilizationPercentage > 100 ? 'Overallocated' : 'OK'\n  });\n}\n\n// Return each user as a separate item for easier processing downstream\nreturn utilizationData.map(data => ({ json: data }));"
      },
      "typeVersion": 2
    },
    {
      "id": "30b80dd9-8b7e-4c08-adc7-4437a1119a18",
      "name": "记录容量数据到跟踪表格",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        464,
        -208
      ],
      "parameters": {
        "columns": {
          "value": {
            "Status": "={{ $json.status }}",
            "Assignee": "={{ $json.assignee }}",
            "Total Hours": "={{ $json.totalHours }}",
            "Utilization %": "={{ $json.utilizationPercentage }}"
          },
          "schema": [
            {
              "id": "Timestamp",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Timestamp",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Assignee",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Assignee",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Total Hours",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Total Hours",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Utilization %",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Utilization %",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Status",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Status",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1334183067,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y/edit#gid=1334183067",
          "cachedResultName": "Team Capacity Tracking"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y/edit?usp=drivesdk",
          "cachedResultName": "Interviewer Brief Pack "
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "kpPEOLCGn963qpoh",
          "name": "automations@techdome.ai"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "4303fbf4-2489-47d3-82d1-ce0633da1364",
      "name": "超分配检查",
      "type": "n8n-nodes-base.if",
      "position": [
        688,
        -32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "321c8920-d8a6-4f87-9faf-f082a037a8c6",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "={{ $json.status }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a915efc1-9f5f-4a28-b7c5-273737ce07fb",
      "name": "警报报告生成器",
      "type": "n8n-nodes-base.code",
      "position": [
        1008,
        -112
      ],
      "parameters": {
        "jsCode": "// Aggregate all over-allocated users into one report\nconst items = $input.all();\n\nif (items.length === 0) {\n  return [{ json: { \n    subject: \"✅ Team Capacity Report - All Clear\",\n    message: \"No team members are currently over-allocated.\",\n    hasIssues: false\n  }}];\n}\n\n// Create report lines for each over-allocated person\nlet reportLines = items.map(item => \n  `• ${item.json.assignee}: ${item.json.totalHours}h logged (${item.json.utilizationPercentage}% capacity)`\n);\n\nconst message = `⚠️ TEAM OVER-ALLOCATION ALERT\\n\\n` +\n  `The following team members are over-allocated:\\n\\n` +\n  `${reportLines.join('\\n')}\\n\\n` +\n  `Recommended Action: Please review workload distribution and consider:\\n` +\n  `- Moving lower priority tasks to next sprint\\n` +\n  `- Redistributing work to available team members\\n` +\n  `- Extending deadlines if necessary\\n\\n` +\n  `Report generated: ${new Date().toLocaleString()}`;\n\nreturn [{ json: {\n  subject: `⚠️ Team Over-Allocation Alert - ${items.length} Member(s)`,\n  message: message,\n  overallocatedCount: items.length,\n  hasIssues: true,\n  details: items.map(i => i.json)\n}}];"
      },
      "typeVersion": 2
    },
    {
      "id": "4624c013-7758-4fdf-b879-a90d86a706e0",
      "name": "发送超分配警报给经理",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1264,
        -112
      ],
      "parameters": {
        "toList": [
          "=newscctv22@gmail.com"
        ],
        "message": "={{ $json.message }}",
        "subject": "={{ $json.subject }}",
        "resource": "message",
        "additionalFields": {
          "ccList": []
        }
      },
      "credentials": {
        "gmailOAuth2": {
          "id": "gEIaWCTvGfYjMSb3",
          "name": "Gmail credentials"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "cd15b637-c0c3-4024-ae2c-55bd2262ea9e",
      "name": "记录查询失败到错误表格",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        96,
        272
      ],
      "parameters": {
        "columns": {
          "value": {},
          "schema": [
            {
              "id": "error_id",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "error_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "error",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "error",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [
            "error_id"
          ],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1338537721,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y/edit#gid=1338537721",
          "cachedResultName": "error log sheet"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Uldk_4BxWbdZTDZxFUeohIfeBmGHHqVEl9Ogb0l6R8Y/edit?usp=drivesdk",
          "cachedResultName": "Interviewer Brief Pack "
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "kpPEOLCGn963qpoh",
          "name": "automations@techdome.ai"
        }
      },
      "typeVersion": 4.6
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "aa6260ed-46d9-4e9a-bd42-e1f6fcc713e2",
  "connections": {
    "Data Validation": {
      "main": [
        [
          {
            "node": "Capacity Calculator",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Log Query Failures to Error Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Capacity Calculator": {
      "main": [
        [
          {
            "node": "Over-Allocation Check",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log Capacity Data to Tracking Sheet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Jira Get Issues Node": {
      "main": [
        [
          {
            "node": "Data Validation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Over-Allocation Check": {
      "main": [
        [
          {
            "node": "Alert Report Generator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Alert Report Generator": {
      "main": [
        [
          {
            "node": "Send Over-Allocation Alert to Manager",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Capacity Data to Tracking Sheet": {
      "main": [
        [
          {
            "node": "Over-Allocation Check",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "Jira Get Issues Node",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

这是一个高级难度的通用自动化工作流。适合高级用户,包含 16+ 个节点的复杂工作流

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量17
分类-
节点类型7
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
Rahul Joshi

Rahul Joshi

@rahul08

Rahul Joshi is a seasoned technology leader specializing in the n8n automation tool and AI-driven workflow automation. With deep expertise in building open-source workflow automation and self-hosted automation platforms, he helps organizations eliminate manual processes through intelligent n8n ai agent automation solutions.

外部链接
在 n8n.io 上查看 →

分享此工作流