8
n8n 中文网amn8n.com

我的工作流 4

高级

这是一个Document Extraction, AI Summarization领域的自动化工作流,包含 18 个节点。主要使用 If, Set, Code, Gmail, HttpRequest 等节点。 使用ScrapeGraphAI监控供应商财务健康状况与多渠道风险预警

前置要求
  • Google 账号和 Gmail API 凭证
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "Iux4FRhkNeg5ZD7q",
  "meta": {
    "instanceId": "f4b0efaa33080e7774e0d9285c40c7abcd2c6f7cf1a8b901fa7106170dd4cda3"
  },
  "name": "我的工作流 4",
  "tags": [
    {
      "id": "Ewfc58AJFSGXYPhG",
      "name": "Supplier Management",
      "createdAt": "2025-08-07T10:34:09.698Z",
      "updatedAt": "2025-08-07T10:34:09.698Z"
    },
    {
      "id": "9DO8zJIiQQoWPZNg",
      "name": "Risk Assessment",
      "createdAt": "2025-08-07T10:34:09.699Z",
      "updatedAt": "2025-08-07T10:34:09.699Z"
    },
    {
      "id": "Inv61YSqTRnvNwGT",
      "name": "Financial Monitoring",
      "createdAt": "2025-08-07T10:34:09.700Z",
      "updatedAt": "2025-08-07T10:34:09.700Z"
    },
    {
      "id": "XUTtKVYhsKXMHj1B",
      "name": "Procurement Automation",
      "createdAt": "2025-08-07T10:34:09.705Z",
      "updatedAt": "2025-08-07T10:34:09.705Z"
    }
  ],
  "nodes": [
    {
      "id": "b05e5e3f-cb0a-46e0-b3fe-a306d86e658e",
      "name": "📅 每周健康检查",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        64,
        640
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks"
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "43e94dcc-6896-4b64-a298-544ead88cbde",
      "name": "📋 工作流概述",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        16,
        -144
      ],
      "parameters": {
        "color": 4,
        "width": 600,
        "height": 680,
        "content": "# 🏢 供应商财务健康监控"
      },
      "typeVersion": 1
    },
    {
      "id": "f551bb06-2af9-4cfd-a82b-565931e9045c",
      "name": "🏪 供应商数据库加载器",
      "type": "n8n-nodes-base.code",
      "position": [
        384,
        640
      ],
      "parameters": {
        "jsCode": "// Load supplier database and prepare monitoring list\nconst suppliers = [\n  {\n    id: \"SUP001\",\n    name: \"TechCorp Solutions\",\n    website: \"https://techcorp-solutions.com\",\n    category: \"Technology\",\n    contract_value: 850000,\n    criticality: \"high\",\n    last_assessment: \"2024-07-01\",\n    current_rating: \"A-\"\n  },\n  {\n    id: \"SUP002\", \n    name: \"Global Manufacturing Inc\",\n    website: \"https://globalmanufacturing.com\",\n    category: \"Manufacturing\",\n    contract_value: 1200000,\n    criticality: \"critical\",\n    last_assessment: \"2024-06-28\",\n    current_rating: \"B+\"\n  },\n  {\n    id: \"SUP003\",\n    name: \"Green Energy Partners\",\n    website: \"https://greenenergy-partners.com\",\n    category: \"Energy\",\n    contract_value: 450000,\n    criticality: \"medium\",\n    last_assessment: \"2024-07-03\",\n    current_rating: \"A\"\n  },\n  {\n    id: \"SUP004\",\n    name: \"Logistics Express Ltd\",\n    website: \"https://logistics-express.com\",\n    category: \"Logistics\",\n    contract_value: 320000,\n    criticality: \"high\",\n    last_assessment: \"2024-06-30\",\n    current_rating: \"B\"\n  },\n  {\n    id: \"SUP005\",\n    name: \"DataSafe Security\",\n    website: \"https://datasafe-security.com\",\n    category: \"Cybersecurity\",\n    contract_value: 680000,\n    criticality: \"critical\",\n    last_assessment: \"2024-07-02\",\n    current_rating: \"A-\"\n  }\n];\n\n// Filter suppliers based on criticality and last assessment date\nconst now = new Date();\nconst oneWeekAgo = new Date(now - 7 * 24 * 60 * 60 * 1000);\n\nconst suppliersToMonitor = suppliers.filter(supplier => {\n  const lastAssessment = new Date(supplier.last_assessment);\n  const daysSinceAssessment = (now - lastAssessment) / (24 * 60 * 60 * 1000);\n  \n  // Monitor critical suppliers weekly, high suppliers bi-weekly, medium monthly\n  if (supplier.criticality === 'critical') {\n    return daysSinceAssessment >= 7;\n  } else if (supplier.criticality === 'high') {\n    return daysSinceAssessment >= 14;\n  } else {\n    return daysSinceAssessment >= 30;\n  }\n});\n\n// Add monitoring metadata\nconst monitoringSession = {\n  session_id: `health_check_${Date.now()}`,\n  timestamp: now.toISOString(),\n  total_suppliers: suppliers.length,\n  suppliers_to_monitor: suppliersToMonitor.length,\n  monitoring_criteria: {\n    critical: '7 days',\n    high: '14 days', \n    medium: '30 days'\n  }\n};\n\nconsole.log(`Monitoring ${suppliersToMonitor.length} of ${suppliers.length} suppliers`);\n\n// Create individual items for each supplier to monitor\nconst outputItems = suppliersToMonitor.map(supplier => ({\n  json: {\n    ...supplier,\n    session_id: monitoringSession.session_id,\n    monitoring_timestamp: monitoringSession.timestamp,\n    days_since_last_check: Math.floor((now - new Date(supplier.last_assessment)) / (24 * 60 * 60 * 1000))\n  }\n}));\n\nreturn outputItems.length > 0 ? outputItems : [{ json: { no_suppliers_to_monitor: true, session_id: monitoringSession.session_id } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "dbcb5c56-ca7a-4929-a2c8-9cd15fb0b9c3",
      "name": "🔍 是否有需要监控的供应商?",
      "type": "n8n-nodes-base.if",
      "position": [
        704,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "has-suppliers-check",
              "operator": {
                "type": "boolean",
                "operation": "notEqual"
              },
              "leftValue": "={{ $json.no_suppliers_to_monitor }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "015005be-2084-4333-ac61-6f3d647d0cb4",
      "name": "🕷️ 公司网站爬虫",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        560
      ],
      "parameters": {
        "url": "https://api.scrapegraph.ai/v1/smartscraper",
        "options": {
          "timeout": 60000
        },
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "headerAuth",
        "bodyParameters": {
          "parameters": [
            {
              "name": "website_url",
              "value": "={{ $json.website }}"
            },
            {
              "name": "user_prompt",
              "value": "Extract financial health indicators for company {{ $json.name }}. Look for: recent financial reports, revenue trends, profit margins, debt levels, cash flow status, recent news about financial performance, any mentions of financial difficulties, layoffs, restructuring, or expansion plans. Also extract contact information and key executives."
            },
            {
              "name": "output_schema",
              "value": "{\n  \"company_name\": \"string\",\n  \"financial_highlights\": {\n    \"revenue_trend\": \"string\",\n    \"profitability\": \"string\", \n    \"debt_status\": \"string\",\n    \"cash_flow\": \"string\"\n  },\n  \"recent_news\": [\"string\"],\n  \"risk_indicators\": [\"string\"],\n  \"positive_indicators\": [\"string\"],\n  \"key_executives\": [\"string\"],\n  \"last_financial_report_date\": \"string\",\n  \"confidence_score\": \"number\"\n}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_SCRAPEGRAPH_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c91f4612-92b0-47d7-8f68-4698f9feadd9",
      "name": "📰 财经新闻爬虫",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1024,
        720
      ],
      "parameters": {
        "url": "https://api.scrapegraph.ai/v1/smartscraper",
        "options": {
          "timeout": 60000
        },
        "sendBody": true,
        "sendHeaders": true,
        "authentication": "headerAuth",
        "bodyParameters": {
          "parameters": [
            {
              "name": "website_url",
              "value": "https://www.google.com/search?q=\"{{ $json.name }}\" financial news problems issues bankruptcy debt"
            },
            {
              "name": "user_prompt",
              "value": "Search for recent financial news about {{ $json.name }}. Focus on: credit rating changes, financial troubles, bankruptcy filings, debt issues, lawsuits, regulatory problems, management changes, merger/acquisition news, major contract wins/losses, and any other significant business developments in the past 6 months."
            },
            {
              "name": "output_schema",
              "value": "{\n  \"company_name\": \"string\",\n  \"news_articles\": [\n    {\n      \"headline\": \"string\",\n      \"source\": \"string\",\n      \"date\": \"string\",\n      \"sentiment\": \"string\",\n      \"risk_level\": \"string\",\n      \"summary\": \"string\"\n    }\n  ],\n  \"overall_sentiment\": \"string\",\n  \"major_developments\": [\"string\"],\n  \"risk_flags\": [\"string\"]\n}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_SCRAPEGRAPH_API_KEY"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "938750de-64ed-4fde-806f-0bd5e615804e",
      "name": "🔬 财务健康分析器",
      "type": "n8n-nodes-base.code",
      "position": [
        1344,
        640
      ],
      "parameters": {
        "jsCode": "// Aggregate and analyze financial health data\nconst websiteData = $('Company Website Scraper').first()?.json?.result || {};\nconst newsData = $('Financial News Scraper').first()?.json?.result || {};\nconst supplierInfo = $('Supplier Database Loader').first().json;\n\n// Parse scraped data\nlet websiteAnalysis = {};\nlet newsAnalysis = {};\n\ntry {\n  websiteAnalysis = typeof websiteData === 'string' ? JSON.parse(websiteData) : websiteData;\n} catch (e) {\n  websiteAnalysis = { error: 'Failed to parse website data', raw: websiteData };\n}\n\ntry {\n  newsAnalysis = typeof newsData === 'string' ? JSON.parse(newsData) : newsData;\n} catch (e) {\n  newsAnalysis = { error: 'Failed to parse news data', raw: newsData };\n}\n\n// Calculate risk indicators\nconst riskFactors = {\n  financial_issues: [],\n  operational_risks: [],\n  market_risks: [],\n  reputational_risks: []\n};\n\n// Analyze website data for risks\nif (websiteAnalysis.financial_highlights) {\n  const highlights = websiteAnalysis.financial_highlights;\n  \n  if (highlights.revenue_trend && highlights.revenue_trend.toLowerCase().includes('declin')) {\n    riskFactors.financial_issues.push('Declining revenue trend');\n  }\n  \n  if (highlights.debt_status && (highlights.debt_status.toLowerCase().includes('high') || highlights.debt_status.toLowerCase().includes('concern'))) {\n    riskFactors.financial_issues.push('High debt levels');\n  }\n  \n  if (highlights.cash_flow && highlights.cash_flow.toLowerCase().includes('negative')) {\n    riskFactors.financial_issues.push('Negative cash flow');\n  }\n}\n\n// Add risk indicators from scraped data\nif (websiteAnalysis.risk_indicators && Array.isArray(websiteAnalysis.risk_indicators)) {\n  riskFactors.operational_risks.push(...websiteAnalysis.risk_indicators);\n}\n\n// Analyze news data for risks\nif (newsAnalysis.news_articles && Array.isArray(newsAnalysis.news_articles)) {\n  newsAnalysis.news_articles.forEach(article => {\n    if (article.sentiment === 'negative' || article.risk_level === 'high') {\n      riskFactors.reputational_risks.push(article.headline);\n    }\n  });\n}\n\nif (newsAnalysis.risk_flags && Array.isArray(newsAnalysis.risk_flags)) {\n  riskFactors.market_risks.push(...newsAnalysis.risk_flags);\n}\n\n// Calculate overall risk score (0-100, higher = more risk)\nlet riskScore = 0;\nconst totalRisks = Object.values(riskFactors).flat().length;\n\n// Base risk calculation\nriskScore += Math.min(totalRisks * 15, 60); // Up to 60 points for risk factors\n\n// Adjust based on supplier criticality\nif (supplierInfo.criticality === 'critical') {\n  riskScore += 10; // Higher scrutiny for critical suppliers\n} else if (supplierInfo.criticality === 'high') {\n  riskScore += 5;\n}\n\n// Adjust based on contract value\nif (supplierInfo.contract_value > 1000000) {\n  riskScore += 10; // Higher risk impact for large contracts\n} else if (supplierInfo.contract_value > 500000) {\n  riskScore += 5;\n}\n\n// Adjust based on confidence scores\nconst websiteConfidence = websiteAnalysis.confidence_score || 0.5;\nconst newsConfidence = newsAnalysis.overall_sentiment === 'negative' ? 0.8 : 0.6;\n\nriskScore = Math.min(riskScore * ((websiteConfidence + newsConfidence) / 2), 100);\n\n// Determine risk level\nlet riskLevel = 'low';\nif (riskScore >= 70) riskLevel = 'critical';\nelse if (riskScore >= 50) riskLevel = 'high';\nelse if (riskScore >= 30) riskLevel = 'medium';\n\n// Create comprehensive health assessment\nconst healthAssessment = {\n  supplier_id: supplierInfo.id,\n  supplier_name: supplierInfo.name,\n  assessment_date: new Date().toISOString(),\n  session_id: supplierInfo.session_id,\n  \n  // Risk Assessment\n  risk_score: Math.round(riskScore),\n  risk_level: riskLevel,\n  risk_factors: riskFactors,\n  \n  // Financial Health\n  financial_health: {\n    website_analysis: websiteAnalysis,\n    news_analysis: newsAnalysis,\n    previous_rating: supplierInfo.current_rating,\n    contract_value: supplierInfo.contract_value,\n    criticality: supplierInfo.criticality\n  },\n  \n  // Key Findings\n  key_findings: {\n    positive_indicators: websiteAnalysis.positive_indicators || [],\n    risk_indicators: Object.values(riskFactors).flat(),\n    major_developments: newsAnalysis.major_developments || [],\n    confidence_level: Math.round(((websiteConfidence + newsConfidence) / 2) * 100)\n  },\n  \n  // Action Required\n  action_required: riskScore >= 50,\n  recommended_actions: [],\n  next_review_date: new Date(Date.now() + (riskScore >= 70 ? 3 : 7) * 24 * 60 * 60 * 1000).toISOString()\n};\n\n// Generate recommended actions\nif (riskScore >= 70) {\n  healthAssessment.recommended_actions.push('Immediate supplier review meeting required');\n  healthAssessment.recommended_actions.push('Activate contingency suppliers');\n  healthAssessment.recommended_actions.push('Consider contract renegotiation');\n} else if (riskScore >= 50) {\n  healthAssessment.recommended_actions.push('Schedule supplier assessment call');\n  healthAssessment.recommended_actions.push('Review alternative supplier options');\n  healthAssessment.recommended_actions.push('Monitor weekly instead of bi-weekly');\n} else if (riskScore >= 30) {\n  healthAssessment.recommended_actions.push('Continue monitoring');\n  healthAssessment.recommended_actions.push('Request updated financial statements');\n}\n\nconsole.log(`Health assessment for ${supplierInfo.name}: Risk Score ${riskScore}, Level: ${riskLevel}`);\n\nreturn [{ json: healthAssessment }];"
      },
      "typeVersion": 2
    },
    {
      "id": "ee0fc5a1-7b18-49a6-84af-a88061572050",
      "name": "📊 高级风险评分器",
      "type": "n8n-nodes-base.code",
      "position": [
        1664,
        640
      ],
      "parameters": {
        "jsCode": "// Advanced risk scoring with industry context\nconst healthData = $input.all()[0].json;\n\n// Industry risk multipliers\nconst industryRiskMultipliers = {\n  'Technology': 1.1, // Higher volatility\n  'Manufacturing': 1.0, // Baseline\n  'Energy': 1.2, // Regulatory and market risks\n  'Logistics': 0.9, // Generally stable\n  'Cybersecurity': 1.1, // High growth but competitive\n  'Healthcare': 0.8, // Regulated but stable\n  'Financial': 1.3, // Highly regulated and volatile\n  'Retail': 1.2, // Market sensitive\n  'Construction': 1.1 // Cyclical risks\n};\n\n// Economic indicator adjustments (simulated)\nconst economicFactors = {\n  inflation_risk: 1.1,\n  interest_rate_risk: 1.05,\n  supply_chain_risk: 1.15,\n  geopolitical_risk: 1.08\n};\n\n// Calculate adjusted risk score\nlet adjustedRiskScore = healthData.risk_score;\n\n// Apply industry multiplier\nconst industryMultiplier = industryRiskMultipliers[healthData.financial_health.criticality] || 1.0;\nadjustedRiskScore *= industryMultiplier;\n\n// Apply economic factors\nObject.values(economicFactors).forEach(factor => {\n  adjustedRiskScore *= factor;\n});\n\n// Ensure score stays within 0-100 range\nadjustedRiskScore = Math.min(Math.round(adjustedRiskScore), 100);\n\n// Recalculate risk level based on adjusted score\nlet adjustedRiskLevel = 'low';\nif (adjustedRiskScore >= 75) adjustedRiskLevel = 'critical';\nelse if (adjustedRiskScore >= 55) adjustedRiskLevel = 'high';\nelse if (adjustedRiskScore >= 35) adjustedRiskLevel = 'medium';\n\n// Calculate probability of supplier failure\nlet failureProbability = 0;\nif (adjustedRiskScore >= 75) failureProbability = 0.15; // 15% chance\nelse if (adjustedRiskScore >= 55) failureProbability = 0.08; // 8% chance\nelse if (adjustedRiskScore >= 35) failureProbability = 0.03; // 3% chance\nelse failureProbability = 0.01; // 1% chance\n\n// Generate risk breakdown\nconst riskBreakdown = {\n  financial_risk: Math.round(adjustedRiskScore * 0.4), // 40% weight\n  operational_risk: Math.round(adjustedRiskScore * 0.3), // 30% weight\n  market_risk: Math.round(adjustedRiskScore * 0.2), // 20% weight\n  reputational_risk: Math.round(adjustedRiskScore * 0.1) // 10% weight\n};\n\n// Create risk scoring result\nconst riskScoringResult = {\n  ...healthData,\n  \n  // Enhanced Risk Metrics\n  risk_scoring: {\n    original_score: healthData.risk_score,\n    adjusted_score: adjustedRiskScore,\n    adjusted_level: adjustedRiskLevel,\n    industry_multiplier: industryMultiplier,\n    economic_adjustment: Object.values(economicFactors).reduce((a, b) => a * b, 1).toFixed(2),\n    failure_probability: (failureProbability * 100).toFixed(1) + '%',\n    confidence_interval: '±12%'\n  },\n  \n  // Risk Breakdown\n  risk_breakdown: riskBreakdown,\n  \n  // Updated recommendations based on adjusted score\n  enhanced_recommendations: [],\n  \n  // Scoring metadata\n  scoring_timestamp: new Date().toISOString(),\n  algorithm_version: '2.1'\n};\n\n// Enhanced recommendations based on adjusted score\nif (adjustedRiskScore >= 75) {\n  riskScoringResult.enhanced_recommendations = [\n    'URGENT: Initiate supplier exit strategy planning',\n    'Activate backup suppliers immediately',\n    'Daily monitoring required',\n    'Legal team review of contracts',\n    'CFO escalation recommended'\n  ];\n} else if (adjustedRiskScore >= 55) {\n  riskScoringResult.enhanced_recommendations = [\n    'Schedule emergency supplier review within 48 hours',\n    'Prepare alternative supplier activation',\n    'Increase monitoring to daily',\n    'Request emergency financial disclosure',\n    'Procurement director escalation'\n  ];\n} else if (adjustedRiskScore >= 35) {\n  riskScoringResult.enhanced_recommendations = [\n    'Schedule supplier health check within 1 week',\n    'Identify and qualify backup suppliers',\n    'Increase monitoring frequency',\n    'Request quarterly financial updates',\n    'Manager escalation if trends worsen'\n  ];\n} else {\n  riskScoringResult.enhanced_recommendations = [\n    'Continue standard monitoring',\n    'Annual supplier review on schedule',\n    'Maintain current relationship status'\n  ];\n}\n\n// Add trend analysis (simulated based on risk level changes)\nconst trendAnalysis = {\n  trend_direction: adjustedRiskScore > healthData.risk_score ? 'deteriorating' : 'stable',\n  trend_magnitude: Math.abs(adjustedRiskScore - healthData.risk_score),\n  trend_confidence: 'medium'\n};\n\nriskScoringResult.trend_analysis = trendAnalysis;\n\nconsole.log(`Enhanced risk scoring: ${adjustedRiskScore} (${adjustedRiskLevel}), Failure Probability: ${(failureProbability * 100).toFixed(1)}%`);\n\nreturn [{ json: riskScoringResult }];"
      },
      "typeVersion": 2
    },
    {
      "id": "7983e640-d450-436d-8801-dcd3a6cbdf5d",
      "name": "⚠️ 风险超过阈值?",
      "type": "n8n-nodes-base.if",
      "position": [
        1984,
        640
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "risk-threshold-check",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.risk_scoring.adjusted_score }}",
              "rightValue": 40
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "b0165887-742d-420c-b643-c91af43bf3a9",
      "name": "🔄 替代供应商查找器",
      "type": "n8n-nodes-base.code",
      "position": [
        2304,
        560
      ],
      "parameters": {
        "jsCode": "// Find alternative suppliers based on category and requirements\nconst riskData = $input.all()[0].json;\n\n// Extract current supplier information\nconst currentSupplier = {\n  category: extractSupplierCategory(riskData.supplier_name),\n  contract_value: riskData.financial_health.contract_value,\n  criticality: riskData.financial_health.criticality,\n  capabilities: [] // Would normally come from supplier database\n};\n\n// Alternative supplier database (in real implementation, this would be a separate database/API)\nconst alternativeSuppliers = {\n  'Technology': [\n    {\n      id: 'ALT_TECH_001',\n      name: 'InnovateTech Solutions',\n      rating: 'A',\n      capacity: 1500000,\n      lead_time: '2-3 weeks',\n      geographic_coverage: ['North America', 'Europe'],\n      certifications: ['ISO 9001', 'SOC 2'],\n      contact: 'procurement@innovatetech.com',\n      phone: '+1-555-0123',\n      risk_score: 15,\n      specialties: ['Software Development', 'Cloud Services', 'AI/ML']\n    },\n    {\n      id: 'ALT_TECH_002', \n      name: 'TechReliable Corp',\n      rating: 'A-',\n      capacity: 980000,\n      lead_time: '1-2 weeks',\n      geographic_coverage: ['North America'],\n      certifications: ['ISO 9001', 'CMMI Level 3'],\n      contact: 'sales@techreliable.com',\n      phone: '+1-555-0456',\n      risk_score: 22,\n      specialties: ['Enterprise Software', 'Data Analytics', 'Cybersecurity']\n    },\n    {\n      id: 'ALT_TECH_003',\n      name: 'NextGen Technologies',\n      rating: 'A+',\n      capacity: 2200000,\n      lead_time: '3-4 weeks',\n      geographic_coverage: ['Global'],\n      certifications: ['ISO 9001', 'SOC 2', 'ISO 27001'],\n      contact: 'enterprise@nextgentech.com',\n      phone: '+1-555-0789',\n      risk_score: 8,\n      specialties: ['Digital Transformation', 'Cloud Migration', 'DevOps']\n    }\n  ],\n  'Manufacturing': [\n    {\n      id: 'ALT_MFG_001',\n      name: 'Precision Manufacturing Group',\n      rating: 'A+',\n      capacity: 2000000,\n      lead_time: '3-4 weeks',\n      geographic_coverage: ['Global'],\n      certifications: ['ISO 9001', 'ISO 14001', 'IATF 16949'],\n      contact: 'contracts@precisionmfg.com',\n      phone: '+1-555-0789',\n      risk_score: 12,\n      specialties: ['Precision Parts', 'Automotive', 'Aerospace']\n    },\n    {\n      id: 'ALT_MFG_002',\n      name: 'Advanced Manufacturing Solutions',\n      rating: 'A',\n      capacity: 1200000,\n      lead_time: '2-3 weeks',\n      geographic_coverage: ['North America', 'Asia'],\n      certifications: ['ISO 9001', 'ISO 45001'],\n      contact: 'procurement@advancedmfg.com',\n      phone: '+1-555-0321',\n      risk_score: 18,\n      specialties: ['Industrial Equipment', 'Custom Manufacturing', 'Quality Control']\n    }\n  ],\n  'Energy': [\n    {\n      id: 'ALT_ENR_001',\n      name: 'Sustainable Energy Partners',\n      rating: 'A',\n      capacity: 800000,\n      lead_time: '4-6 weeks',\n      geographic_coverage: ['Global'],\n      certifications: ['ISO 14001', 'OHSAS 18001'],\n      contact: 'partnerships@sustainableenergy.com',\n      phone: '+1-555-0654',\n      risk_score: 20,\n      specialties: ['Renewable Energy', 'Solar Solutions', 'Energy Storage']\n    },\n    {\n      id: 'ALT_ENR_002',\n      name: 'GreenPower Systems',\n      rating: 'A-',\n      capacity: 1100000,\n      lead_time: '5-7 weeks',\n      geographic_coverage: ['North America', 'Europe'],\n      certifications: ['ISO 14001', 'ISO 50001'],\n      contact: 'business@greenpower.com',\n      phone: '+1-555-0987',\n      risk_score: 25,\n      specialties: ['Wind Energy', 'Grid Solutions', 'Energy Efficiency']\n    }\n  ],\n  'Logistics': [\n    {\n      id: 'ALT_LOG_001',\n      name: 'Global Logistics Network',\n      rating: 'A-',\n      capacity: 500000,\n      lead_time: '1 week',\n      geographic_coverage: ['Global'],\n      certifications: ['ISO 9001', 'C-TPAT'],\n      contact: 'contracts@globallogistics.com',\n      phone: '+1-555-0987',\n      risk_score: 16,\n      specialties: ['International Shipping', 'Supply Chain', 'Warehousing']\n    },\n    {\n      id: 'ALT_LOG_002',\n      name: 'FastTrack Delivery',\n      rating: 'B+',\n      capacity: 750000,\n      lead_time: '3-5 days',\n      geographic_coverage: ['North America'],\n      certifications: ['ISO 9001'],\n      contact: 'sales@fasttrackdelivery.com',\n      phone: '+1-555-0147',\n      risk_score: 28,\n      specialties: ['Express Delivery', 'Last Mile', 'E-commerce Fulfillment']\n    }\n  ],\n  'Cybersecurity': [\n    {\n      id: 'ALT_SEC_001',\n      name: 'CyberGuard Elite',\n      rating: 'A+',\n      capacity: 1000000,\n      lead_time: '1-2 weeks',\n      geographic_coverage: ['Global'],\n      certifications: ['SOC 2', 'ISO 27001', 'FedRAMP'],\n      contact: 'enterprise@cyberguard.com',\n      phone: '+1-555-0147',\n      risk_score: 10,\n      specialties: ['Threat Detection', 'Incident Response', 'Compliance']\n    },\n    {\n      id: 'ALT_SEC_002',\n      name: 'SecureShield Technologies',\n      rating: 'A',\n      capacity: 850000,\n      lead_time: '2-3 weeks',\n      geographic_coverage: ['North America', 'Europe'],\n      certifications: ['SOC 2', 'ISO 27001'],\n      contact: 'business@secureshield.com',\n      phone: '+1-555-0258',\n      risk_score: 14,\n      specialties: ['Network Security', 'Endpoint Protection', 'Security Consulting']\n    }\n  ]\n};\n\n// Function to extract supplier category from name\nfunction extractSupplierCategory(supplierName) {\n  const name = supplierName.toLowerCase();\n  \n  if (name.includes('tech') || name.includes('software') || name.includes('data') || name.includes('digital')) {\n    return 'Technology';\n  } else if (name.includes('manufacturing') || name.includes('production') || name.includes('factory')) {\n    return 'Manufacturing';\n  } else if (name.includes('energy') || name.includes('power') || name.includes('green') || name.includes('renewable')) {\n    return 'Energy';\n  } else if (name.includes('logistics') || name.includes('transport') || name.includes('delivery') || name.includes('shipping')) {\n    return 'Logistics';\n  } else if (name.includes('security') || name.includes('cyber') || name.includes('safe')) {\n    return 'Cybersecurity';\n  } else {\n    return 'Technology'; // Default fallback\n  }\n}\n\n// Get alternatives for the category\nconst availableAlternatives = alternativeSuppliers[currentSupplier.category] || [];\n\n// Filter and rank alternatives based on capacity, rating, and risk\nconst suitableAlternatives = availableAlternatives\n  .filter(alt => alt.capacity >= currentSupplier.contract_value)\n  .map(alt => ({\n    ...alt,\n    suitability_score: calculateSuitabilityScore(alt, currentSupplier),\n    transition_complexity: assessTransitionComplexity(alt, riskData)\n  }))\n  .sort((a, b) => b.suitability_score - a.suitability_score)\n  .slice(0, 3); // Top 3 alternatives\n\n// Calculate suitability score (0-100 points)\nfunction calculateSuitabilityScore(alternative, current) {\n  let score = 0;\n  \n  // Rating score (0-40 points)\n  const ratingScores = { \n    'A+': 40, \n    'A': 35, \n    'A-': 30, \n    'B+': 25, \n    'B': 20, \n    'B-': 15,\n    'C+': 10,\n    'C': 5\n  };\n  score += ratingScores[alternative.rating] || 5;\n  \n  // Capacity score (0-25 points)\n  const capacityRatio = alternative.capacity / current.contract_value;\n  if (capacityRatio >= 3) score += 25;\n  else if (capacityRatio >= 2) score += 22;\n  else if (capacityRatio >= 1.5) score += 18;\n  else if (capacityRatio >= 1.2) score += 15;\n  else if (capacityRatio >= 1) score += 10;\n  else score += 5;\n  \n  // Risk score (0-25 points) - lower risk is better\n  const riskScore = Math.max(25 - alternative.risk_score, 0);\n  score += riskScore;\n  \n  // Lead time score (0-10 points)\n  const leadTime = alternative.lead_time.toLowerCase();\n  if (leadTime.includes('day') || leadTime.includes('1 week')) score += 10;\n  else if (leadTime.includes('1') || leadTime.includes('2')) score += 8;\n  else if (leadTime.includes('3') || leadTime.includes('4')) score += 6;\n  else if (leadTime.includes('5') || leadTime.includes('6')) score += 4;\n  else score += 2;\n  \n  return Math.round(score);\n}\n\n// Assess transition complexity\nfunction assessTransitionComplexity(alternative, riskData) {\n  const factors = [];\n  let complexity = 'medium';\n  let complexityScore = 0;\n  \n  // Lead time assessment\n  const leadTime = alternative.lead_time.toLowerCase();\n  if (leadTime.includes('day') || leadTime.includes('1 week')) {\n    factors.push('Quick deployment possible');\n    complexityScore -= 2;\n  } else if (leadTime.includes('1') || leadTime.includes('2')) {\n    factors.push('Standard deployment timeframe');\n    complexityScore += 0;\n  } else if (leadTime.includes('4') || leadTime.includes('5') || leadTime.includes('6')) {\n    factors.push('Extended lead time required');\n    complexityScore += 3;\n  }\n  \n  // Contract value assessment\n  if (riskData.financial_health.contract_value > 1500000) {\n    factors.push('Very large contract transition');\n    complexityScore += 3;\n  } else if (riskData.financial_health.contract_value > 1000000) {\n    factors.push('Large contract transition');\n    complexityScore += 2;\n  } else if (riskData.financial_health.contract_value > 500000) {\n    factors.push('Medium contract transition');\n    complexityScore += 1;\n  }\n  \n  // Criticality assessment\n  if (riskData.financial_health.criticality === 'critical') {\n    factors.push('Critical supplier replacement - high stakes');\n    complexityScore += 3;\n  } else if (riskData.financial_health.criticality === 'high') {\n    factors.push('High priority supplier replacement');\n    complexityScore += 2;\n  }\n  \n  // Geographic coverage assessment\n  if (alternative.geographic_coverage.includes('Global')) {\n    factors.push('Global coverage available');\n    complexityScore -= 1;\n  } else if (alternative.geographic_coverage.length === 1) {\n    factors.push('Limited geographic coverage');\n    complexityScore += 1;\n  }\n  \n  // Determine complexity level\n  if (complexityScore <= 0) complexity = 'low';\n  else if (complexityScore <= 3) complexity = 'medium';\n  else complexity = 'high';\n  \n  return { \n    level: complexity, \n    factors: factors,\n    score: complexityScore\n  };\n}\n\n// Create transition recommendations based on risk level\nconst transitionRecommendations = [];\n\nif (riskData.risk_scoring.adjusted_score >= 75) {\n  transitionRecommendations.push('🚨 URGENT: Initiate immediate transition planning');\n  transitionRecommendations.push('🔄 Activate parallel supplier setup within 48 hours');\n  transitionRecommendations.push('📋 Emergency procurement approval required');\n  transitionRecommendations.push('👥 Daily steering committee meetings');\n  transitionRecommendations.push('📞 Legal team review of exit clauses');\n} else if (riskData.risk_scoring.adjusted_score >= 55) {\n  transitionRecommendations.push('⚡ Develop comprehensive 30-day transition plan');\n  transitionRecommendations.push('✅ Begin formal supplier qualification process');\n  transitionRecommendations.push('💼 Negotiate transition terms and SLAs');\n  transitionRecommendations.push('📊 Weekly progress reviews with stakeholders');\n  transitionRecommendations.push('🔍 Conduct detailed due diligence');\n} else if (riskData.risk_scoring.adjusted_score >= 35) {\n  transitionRecommendations.push('📋 Prepare contingency supplier plans');\n  transitionRecommendations.push('🤝 Maintain warm relationships with alternatives');\n  transitionRecommendations.push('📈 Monitor supplier performance closely');\n  transitionRecommendations.push('📅 Quarterly alternative supplier reviews');\n} else {\n  transitionRecommendations.push('✅ Continue standard supplier management');\n  transitionRecommendations.push('📊 Annual alternative supplier evaluation');\n  transitionRecommendations.push('🔄 Maintain supplier diversity strategy');\n}\n\n// Calculate transition timeline\nfunction calculateTransitionTimeline(riskScore, alternatives) {\n  if (riskScore >= 75) {\n    return {\n      immediate_actions: '24-48 hours',\n      supplier_selection: '3-5 days',\n      contract_negotiation: '1-2 weeks',\n      full_transition: '2-4 weeks',\n      total_timeline: '1 month maximum'\n    };\n  } else if (riskScore >= 55) {\n    return {\n      planning_phase: '1 week',\n      supplier_evaluation: '2 weeks',\n      contract_negotiation: '2-3 weeks',\n      phased_transition: '4-6 weeks',\n      total_timeline: '2-3 months'\n    };\n  } else {\n    return {\n      assessment_phase: '2-4 weeks',\n      market_research: '1-2 months',\n      supplier_qualification: '2-3 months',\n      planned_transition: '3-6 months',\n      total_timeline: '6-12 months'\n    };\n  }\n}\n\n// Create comprehensive alternative supplier analysis\nconst alternativeAnalysis = {\n  supplier_id: riskData.supplier_id,\n  supplier_name: riskData.supplier_name,\n  current_risk_score: riskData.risk_scoring.adjusted_score,\n  category: currentSupplier.category,\n  analysis_timestamp: new Date().toISOString(),\n  \n  // Alternative supplier metrics\n  alternatives_found: suitableAlternatives.length,\n  total_alternatives_available: availableAlternatives.length,\n  recommended_alternatives: suitableAlternatives,\n  \n  // Transition strategy\n  transition_strategy: {\n    urgency_level: riskData.risk_scoring.adjusted_score >= 75 ? 'immediate' : \n                   riskData.risk_scoring.adjusted_score >= 55 ? 'high' : 'standard',\n    timeline: calculateTransitionTimeline(riskData.risk_scoring.adjusted_score, suitableAlternatives),\n    recommendations: transitionRecommendations,\n    budget_impact_estimate: estimateBudgetImpact(riskData.financial_health.contract_value, suitableAlternatives),\n    complexity_assessment: suitableAlternatives.length > 0 ? suitableAlternatives[0].transition_complexity.level : 'unknown'\n  },\n  \n  // Action plan\n  immediate_next_steps: generateNextSteps(riskData.risk_scoring.adjusted_score, suitableAlternatives),\n  \n  // Risk mitigation analysis\n  risk_mitigation: {\n    current_single_point_failure: true,\n    proposed_diversification: suitableAlternatives.length > 1,\n    recommended_supplier_split: generateSupplierSplit(suitableAlternatives.length, riskData.risk_scoring.adjusted_score),\n    contingency_readiness: assessContingencyReadiness(suitableAlternatives),\n    fallback_options: suitableAlternatives.length\n  },\n  \n  // Quality assessment\n  alternative_quality_metrics: {\n    average_rating: calculateAverageRating(suitableAlternatives),\n    average_risk_score: calculateAverageRiskScore(suitableAlternatives),\n    certification_coverage: assessCertificationCoverage(suitableAlternatives),\n    geographic_coverage: assessGeographicCoverage(suitableAlternatives)\n  }\n};\n\n// Helper functions\nfunction estimateBudgetImpact(contractValue, alternatives) {\n  if (alternatives.length === 0) return 'No alternatives available - high cost risk';\n  \n  const avgLeadTime = alternatives.reduce((sum, alt) => {\n    const leadTimeWeeks = parseInt(alt.lead_time.match(/\\d+/)?.[0] || '2');\n    return sum + leadTimeWeeks;\n  }, 0) / alternatives.length;\n  \n  const transitionCost = contractValue * 0.05; // Assume 5% transition cost\n  const urgencyCost = contractValue * (riskData.risk_scoring.adjusted_score >= 75 ? 0.15 : 0.08);\n  \n  return {\n    estimated_transition_cost: Math.round(transitionCost),\n    urgency_premium: Math.round(urgencyCost),\n    total_estimated_impact: Math.round(transitionCost + urgencyCost),\n    cost_as_percentage: ((transitionCost + urgencyCost) / contractValue * 100).toFixed(1) + '%'\n  };\n}\n\nfunction generateNextSteps(riskScore, alternatives) {\n  const steps = [];\n  \n  if (riskScore >= 75) {\n    steps.push('🚨 Immediate: Activate crisis management team');\n    steps.push('📞 Contact top 2 alternative suppliers within 4 hours');\n    steps.push('⚡ Fast-track supplier evaluation process');\n    steps.push('📋 Prepare emergency contract templates');\n  } else if (riskScore >= 55) {\n    steps.push('📋 Schedule supplier review meeting within 24 hours');\n    steps.push('📊 Request detailed proposals from top alternatives');\n    steps.push('🔍 Conduct accelerated due diligence');\n    steps.push('💼 Begin contract term negotiations');\n  } else {\n    steps.push('📝 Update supplier contingency plans');\n    steps.push('🤝 Maintain regular contact with alternatives');\n    steps.push('📈 Monitor current supplier performance');\n    steps.push('📅 Schedule quarterly alternative reviews');\n  }\n  \n  return steps;\n}\n\nfunction generateSupplierSplit(alternativeCount, riskScore) {\n  if (alternativeCount === 0) return '100% current supplier (no alternatives available)';\n  if (alternativeCount === 1) return riskScore >= 75 ? '100% alternative' : '80% current / 20% alternative';\n  if (alternativeCount >= 2) {\n    if (riskScore >= 75) return '60% primary alternative / 40% secondary alternative';\n    if (riskScore >= 55) return '50% current / 30% primary alternative / 20% secondary alternative';\n    return '70% current / 20% primary alternative / 10% secondary alternative';\n  }\n}\n\nfunction assessContingencyReadiness(alternatives) {\n  if (alternatives.length === 0) return 'low';\n  if (alternatives.length >= 2 && alternatives[0].suitability_score >= 70) return 'high';\n  if (alternatives.length >= 1 && alternatives[0].suitability_score >= 60) return 'medium';\n  return 'low';\n}\n\nfunction calculateAverageRating(alternatives) {\n  if (alternatives.length === 0) return 'N/A';\n  const ratingValues = { 'A+': 4.0, 'A': 3.5, 'A-': 3.0, 'B+': 2.5, 'B': 2.0, 'B-': 1.5, 'C+': 1.0, 'C': 0.5 };\n  const avgValue = alternatives.reduce((sum, alt) => sum + (ratingValues[alt.rating] || 0), 0) / alternatives.length;\n  const ratingKeys = Object.keys(ratingValues);\n  return ratingKeys.find(key => Math.abs(ratingValues[key] - avgValue) < 0.25) || 'Mixed';\n}\n\nfunction calculateAverageRiskScore(alternatives) {\n  if (alternatives.length === 0) return 0;\n  return Math.round(alternatives.reduce((sum, alt) => sum + alt.risk_score, 0) / alternatives.length);\n}\n\nfunction assessCertificationCoverage(alternatives) {\n  if (alternatives.length === 0) return [];\n  const allCertifications = new Set();\n  alternatives.forEach(alt => alt.certifications.forEach(cert => allCertifications.add(cert)));\n  return Array.from(allCertifications);\n}\n\nfunction assessGeographicCoverage(alternatives) {\n  if (alternatives.length === 0) return [];\n  const allRegions = new Set();\n  alternatives.forEach(alt => alt.geographic_coverage.forEach(region => allRegions.add(region)));\n  return Array.from(allRegions);\n}\n\nconsole.log(`Alternative Supplier Analysis Complete: Found ${suitableAlternatives.length} suitable alternatives for ${currentSupplier.category} category`);\nconsole.log(`Risk Level: ${riskData.risk_scoring.adjusted_level} (${riskData.risk_scoring.adjusted_score}), Urgency: ${alternativeAnalysis.transition_strategy.urgency_level}`);\n\nreturn [{ json: { ...riskData, alternative_analysis: alternativeAnalysis } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "8d929208-fb1a-4c02-ac90-f3b997990982",
      "name": "📧 警报格式化器",
      "type": "n8n-nodes-base.set",
      "position": [
        2624,
        560
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "email-content-assignment",
              "name": "email_content",
              "type": "string",
              "value": "# 🚨 SUPPLIER RISK ALERT\n\n**Supplier:** {{ $json.supplier_name }}\n**Risk Score:** {{ $json.risk_scoring.adjusted_score }}/100 ({{ $json.risk_scoring.adjusted_level | upper }})\n**Contract Value:** ${{ $json.financial_health.contract_value | number_format }}\n**Assessment Date:** {{ $json.assessment_date | date('Y-m-d H:i') }}\n\n## Risk Summary\n- **Failure Probability:** {{ $json.risk_scoring.failure_probability }}\n- **Trend:** {{ $json.trend_analysis.trend_direction | title }}\n- **Action Required:** {{ 'YES' if $json.action_required else 'NO' }}\n\n## Key Risk Factors\n{% for category, risks in $json.risk_factors %}\n{% if risks|length > 0 %}\n**{{ category | replace('_', ' ') | title }}:**\n{% for risk in risks %}\n- {{ risk }}\n{% endfor %}\n{% endif %}\n{% endfor %}\n\n## Recommended Actions\n{% for action in $json.enhanced_recommendations %}\n- {{ action }}\n{% endfor %}\n\n{% if $json.alternative_analysis %}\n## Alternative Suppliers Available\n**{{ $json.alternative_analysis.alternatives_found }}** qualified alternatives identified:\n{% for alt in $json.alternative_analysis.recommended_alternatives %}\n- **{{ alt.name }}** (Rating: {{ alt.rating }}, Risk: {{ alt.risk_score }})\n{% endfor %}\n\n**Transition Timeline:** {{ $json.alternative_analysis.transition_strategy.estimated_timeline }}\n{% endif %}\n\n## Next Steps\n{% if $json.alternative_analysis %}\n{% for step in $json.alternative_analysis.next_steps %}\n- {{ step }}\n{% endfor %}\n{% endif %}\n\n---\n*Automated Supplier Health Monitor | Session: {{ $json.session_id }}*"
            },
            {
              "id": "alert-priority-assignment",
              "name": "alert_priority",
              "type": "string",
              "value": "={{ $json.risk_scoring.adjusted_score >= 75 ? 'critical' : $json.risk_scoring.adjusted_score >= 55 ? 'high' : 'medium' }}"
            },
            {
              "id": "recipients-assignment",
              "name": "recipients",
              "type": "string",
              "value": "={{ $json.risk_scoring.adjusted_score >= 75 ? 'cfo@company.com,procurement-director@company.com,ceo@company.com' : $json.risk_scoring.adjusted_score >= 55 ? 'procurement-director@company.com,procurement-manager@company.com' : 'procurement-manager@company.com' }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a5813052-5058-4cce-95b0-a7f95d37db79",
      "name": "📨 邮件警报发送器",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2944,
        480
      ],
      "webhookId": "8e09c545-2250-4baa-b306-dbe2ab9087b4",
      "parameters": {
        "message": "={{ $json.email_content }}",
        "options": {},
        "subject": "🚨 Supplier Risk Alert: {{ $json.supplier_name }} - {{ $json.alert_priority | upper }} Priority",
        "emailType": "text"
      },
      "typeVersion": 2.1
    },
    {
      "id": "446113a2-7b79-41a7-bbef-0ee88beb8633",
      "name": "💬 Slack警报",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2944,
        640
      ],
      "parameters": {
        "url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
        "options": {},
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "text",
              "value": "🚨 *Supplier Risk Alert*"
            },
            {
              "name": "blocks",
              "value": "[\n  {\n    \"type\": \"header\",\n    \"text\": {\n      \"type\": \"plain_text\",\n      \"text\": \"🚨 Supplier Risk Alert\"}\n  },\n  {\n    \"type\": \"section\",\n    \"fields\": [\n      {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Supplier:*\\n{{ $json.supplier_name }}\"\n      },\n      {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Risk Score:*\\n{{ $json.risk_scoring.adjusted_score }}/100 ({{ $json.risk_scoring.adjusted_level | upper }})\"\n      },\n      {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Contract Value:*\\n${{ $json.financial_health.contract_value | number_format }}\"\n      },\n      {\n        \"type\": \"mrkdwn\",\n        \"text\": \"*Failure Probability:*\\n{{ $json.risk_scoring.failure_probability }}\"\n      }\n    ]\n  },\n  {\n    \"type\": \"section\",\n    \"text\": {\n      \"type\": \"mrkdwn\",\n      \"text\": \"*Top Recommendations:*\\n{{ $json.enhanced_recommendations | slice(0, 3) | join('\\n') }}\"\n    }\n  },\n  {\n    \"type\": \"actions\",\n    \"elements\": [\n      {\n        \"type\": \"button\",\n        \"text\": {\n          \"type\": \"plain_text\",\n          \"text\": \"View Full Report\"\n        },\n        \"url\": \"https://supplier-dashboard.company.com/report/{{ $json.session_id }}\"\n      },\n      {\n        \"type\": \"button\",\n        \"text\": {\n          \"type\": \"plain_text\",\n          \"text\": \"Contact Alternatives\"\n        },\n        \"url\": \"https://supplier-dashboard.company.com/alternatives/{{ $json.supplier_id }}\"\n      }\n    ]\n  }\n]"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "896ab29d-8212-42fb-8534-d5bf78f02b58",
      "name": "🏢 采购系统更新",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3264,
        560
      ],
      "parameters": {
        "url": "https://your-company-api.com/supplier-monitoring/webhook",
        "options": {},
        "sendBody": true,
        "sendHeaders": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "event_type",
              "value": "supplier_risk_assessment"
            },
            {
              "name": "supplier_id",
              "value": "={{ $json.supplier_id }}"
            },
            {
              "name": "risk_score",
              "value": "={{ $json.risk_scoring.adjusted_score }}"
            },
            {
              "name": "risk_level",
              "value": "={{ $json.risk_scoring.adjusted_level }}"
            },
            {
              "name": "action_required",
              "value": "={{ $json.action_required }}"
            },
            {
              "name": "assessment_data",
              "value": "={{ $json | json_encode }}"
            },
            {
              "name": "timestamp",
              "value": "={{ $json.assessment_date }}"
            }
          ]
        },
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "Bearer YOUR_API_TOKEN"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4febb2a4-d066-4ff4-bcae-131b62791d4f",
      "name": "健康分析器信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        624,
        -128
      ],
      "parameters": {
        "color": 5,
        "width": 500,
        "height": 450,
        "content": "# 🔬 财务健康分析器"
      },
      "typeVersion": 1
    },
    {
      "id": "db4be14b-6d45-462a-a15b-2be6b52bda11",
      "name": "风险评分器信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1632,
        48
      ],
      "parameters": {
        "color": 6,
        "width": 500,
        "height": 482,
        "content": "# 📊 高级风险评分器"
      },
      "typeVersion": 1
    },
    {
      "id": "af6cb250-0870-40aa-89a8-32dcd5eb2ab1",
      "name": "替代查找器信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2304,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 500,
        "height": 450,
        "content": "# 🔄 替代供应商查找器"
      },
      "typeVersion": 1
    },
    {
      "id": "5035c37f-181e-497a-be2c-577f30b199a2",
      "name": "警报系统信息",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2976,
        -96
      ],
      "parameters": {
        "color": 2,
        "width": 500,
        "height": 530,
        "content": "# 📧 多渠道警报系统"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "77e3d5f7-376f-4581-8d72-5ccf722a7d8d",
  "connections": {
    "📧 Alert Formatter": {
      "main": [
        [
          {
            "node": "📨 Email Alert Sender",
            "type": "main",
            "index": 0
          },
          {
            "node": "💬 Slack Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "🏢 Procurement System Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📅 Weekly Health Check": {
      "main": [
        [
          {
            "node": "🏪 Supplier Database Loader",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📊 Advanced Risk Scorer": {
      "main": [
        [
          {
            "node": "⚠️ Risk Above Threshold?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "📰 Financial News Scraper": {
      "main": [
        [
          {
            "node": "🔬 Financial Health Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "⚠️ Risk Above Threshold?": {
      "main": [
        [
          {
            "node": "🔄 Alternative Supplier Finder",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🏪 Supplier Database Loader": {
      "main": [
        [
          {
            "node": "🔍 Has Suppliers to Monitor?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔍 Has Suppliers to Monitor?": {
      "main": [
        [
          {
            "node": "🕷️ Company Website Scraper",
            "type": "main",
            "index": 0
          },
          {
            "node": "📰 Financial News Scraper",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔬 Financial Health Analyzer": {
      "main": [
        [
          {
            "node": "📊 Advanced Risk Scorer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🕷️ Company Website Scraper": {
      "main": [
        [
          {
            "node": "🔬 Financial Health Analyzer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "🔄 Alternative Supplier Finder": {
      "main": [
        [
          {
            "node": "📧 Alert Formatter",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 文档提取, AI 摘要总结

需要付费吗?

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

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

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

外部链接
在 n8n.io 查看

分享此工作流