首页 / 教程文章 / WordPress柔性供应链中的可视化工作流引擎开发教程

WordPress柔性供应链中的可视化工作流引擎开发教程

WordPress柔性供应链中的可视化工作流引擎开发教程

引言:柔性供应链与可视化工作流的融合

在当今快速变化的商业环境中,企业需要能够快速响应市场变化的柔性供应链系统。WordPress作为全球最流行的内容管理系统,其强大的扩展性和灵活性使其成为构建供应链管理平台的理想选择。本文将详细介绍如何在WordPress中开发一个可视化工作流引擎,帮助企业实现供应链流程的可视化管理和自动化控制。

系统架构设计

核心组件规划

我们的可视化工作流引擎将包含以下核心组件:

  1. 工作流设计器:基于HTML5 Canvas的可视化流程设计界面
  2. 节点库:预定义的供应链操作节点
  3. 规则引擎:流程执行逻辑处理器
  4. 数据连接器:与外部供应链系统的API集成
  5. 监控面板:实时流程执行状态监控

数据库设计

首先,我们需要设计存储工作流相关数据的数据库表结构:

<?php
/**
 * WordPress工作流引擎数据库表创建脚本
 */

global $wpdb;

// 工作流定义表
$workflow_table = $wpdb->prefix . 'supply_workflows';
$workflow_sql = "CREATE TABLE IF NOT EXISTS $workflow_table (
    id INT(11) NOT NULL AUTO_INCREMENT,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    workflow_data LONGTEXT NOT NULL,
    status ENUM('active', 'inactive', 'draft') DEFAULT 'draft',
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";

// 工作流实例表
$instance_table = $wpdb->prefix . 'workflow_instances';
$instance_sql = "CREATE TABLE IF NOT EXISTS $instance_table (
    id INT(11) NOT NULL AUTO_INCREMENT,
    workflow_id INT(11) NOT NULL,
    current_node VARCHAR(100),
    status ENUM('running', 'completed', 'failed', 'paused') DEFAULT 'running',
    input_data LONGTEXT,
    output_data LONGTEXT,
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (workflow_id) REFERENCES $workflow_table(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";

// 执行日志表
$log_table = $wpdb->prefix . 'workflow_logs';
$log_sql = "CREATE TABLE IF NOT EXISTS $log_table (
    id INT(11) NOT NULL AUTO_INCREMENT,
    instance_id INT(11) NOT NULL,
    node_id VARCHAR(100),
    action VARCHAR(255),
    message TEXT,
    log_level ENUM('info', 'warning', 'error', 'debug'),
    created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    FOREIGN KEY (instance_id) REFERENCES $instance_table(id) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;";

// 执行创建表
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($workflow_sql);
dbDelta($instance_sql);
dbDelta($log_sql);
?>

可视化工作流设计器开发

前端界面构建

我们将使用React和D3.js构建可视化工作流设计器。首先创建主要的设计器组件:

// workflow-designer.js
import React, { useState, useRef, useEffect } from 'react';
import * as d3 from 'd3';

const WorkflowDesigner = ({ workflowData, onSave }) => {
  const [nodes, setNodes] = useState(workflowData?.nodes || []);
  const [edges, setEdges] = useState(workflowData?.edges || []);
  const [selectedNode, setSelectedNode] = useState(null);
  const svgRef = useRef(null);
  
  // 预定义的供应链节点类型
  const nodeTypes = [
    { id: 'order_receive', name: '订单接收', color: '#4CAF50' },
    { id: 'inventory_check', name: '库存检查', color: '#2196F3' },
    { id: 'supplier_notify', name: '供应商通知', color: '#FF9800' },
    { id: 'quality_check', name: '质量检查', color: '#9C27B0' },
    { id: 'shipping', name: '发货处理', color: '#3F51B5' },
    { id: 'payment', name: '支付处理', color: '#009688' }
  ];
  
  // 初始化D3画布
  useEffect(() => {
    if (!svgRef.current) return;
    
    const svg = d3.select(svgRef.current);
    const width = svgRef.current.clientWidth;
    const height = svgRef.current.clientHeight;
    
    // 创建缩放行为
    const zoom = d3.zoom()
      .scaleExtent([0.1, 4])
      .on('zoom', (event) => {
        svg.select('g').attr('transform', event.transform);
      });
    
    svg.call(zoom);
    
    // 绘制节点
    const nodeGroup = svg.select('g.nodes')
      .selectAll('g.node')
      .data(nodes, d => d.id);
    
    const nodeEnter = nodeGroup.enter()
      .append('g')
      .attr('class', 'node')
      .attr('transform', d => `translate(${d.x}, ${d.y})`)
      .call(d3.drag()
        .on('start', dragStarted)
        .on('drag', dragged)
        .on('end', dragEnded));
    
    // 绘制节点矩形
    nodeEnter.append('rect')
      .attr('width', 120)
      .attr('height', 60)
      .attr('rx', 5)
      .attr('fill', d => nodeTypes.find(t => t.id === d.type)?.color || '#ccc')
      .attr('stroke', '#333')
      .attr('stroke-width', 2)
      .on('click', handleNodeClick);
    
    // 绘制节点文本
    nodeEnter.append('text')
      .attr('x', 60)
      .attr('y', 30)
      .attr('text-anchor', 'middle')
      .attr('dy', '0.3em')
      .attr('fill', 'white')
      .text(d => d.label || nodeTypes.find(t => t.id === d.type)?.name);
    
    // 绘制连接线
    const edgeGroup = svg.select('g.edges')
      .selectAll('line.edge')
      .data(edges, d => `${d.source}-${d.target}`);
    
    edgeGroup.enter()
      .append('line')
      .attr('class', 'edge')
      .attr('stroke', '#666')
      .attr('stroke-width', 2)
      .attr('marker-end', 'url(#arrowhead)');
    
    // 更新连接线位置
    edgeGroup.attr('x1', d => d.source.x + 60)
      .attr('y1', d => d.source.y + 30)
      .attr('x2', d => d.target.x + 60)
      .attr('y2', d => d.target.y + 30);
    
    // 拖拽函数
    function dragStarted(event, d) {
      d3.select(this).raise().classed('active', true);
    }
    
    function dragged(event, d) {
      d.x = event.x;
      d.y = event.y;
      d3.select(this).attr('transform', `translate(${d.x}, ${d.y})`);
      
      // 更新连接线
      svg.selectAll('line.edge')
        .filter(edge => edge.source.id === d.id || edge.target.id === d.id)
        .attr('x1', edge => edge.source.x + 60)
        .attr('y1', edge => edge.source.y + 30)
        .attr('x2', edge => edge.target.x + 60)
        .attr('y2', edge => edge.target.y + 30);
    }
    
    function dragEnded(event, d) {
      d3.select(this).classed('active', false);
      setNodes([...nodes]);
    }
    
    function handleNodeClick(event, node) {
      setSelectedNode(node);
      event.stopPropagation();
    }
    
  }, [nodes, edges]);
  
  // 添加新节点
  const addNode = (nodeType) => {
    const newNode = {
      id: `node_${Date.now()}`,
      type: nodeType.id,
      label: nodeType.name,
      x: Math.random() * 500,
      y: Math.random() * 300
    };
    setNodes([...nodes, newNode]);
  };
  
  // 保存工作流
  const saveWorkflow = () => {
    const workflow = {
      nodes,
      edges,
      version: '1.0',
      lastModified: new Date().toISOString()
    };
    onSave(workflow);
  };
  
  return (
    <div className="workflow-designer">
      <div className="designer-toolbar">
        <h3>供应链节点库</h3>
        <div className="node-palette">
          {nodeTypes.map(type => (
            <button 
              key={type.id}
              className="node-type-btn"
              style={{backgroundColor: type.color}}
              onClick={() => addNode(type)}
            >
              {type.name}
            </button>
          ))}
        </div>
        <button className="save-btn" onClick={saveWorkflow}>
          保存工作流
        </button>
      </div>
      
      <div className="designer-canvas">
        <svg ref={svgRef} width="100%" height="600">
          <defs>
            <marker 
              id="arrowhead"
              markerWidth="10" 
              markerHeight="7" 
              refX="9" 
              refY="3.5" 
              orient="auto"
            >
              <polygon points="0 0, 10 3.5, 0 7" fill="#666" />
            </marker>
          </defs>
          <g className="edges"></g>
          <g className="nodes"></g>
        </svg>
      </div>
      
      {selectedNode && (
        <div className="node-properties">
          <h4>节点属性</h4>
          <div>
            <label>节点名称:</label>
            <input 
              type="text" 
              value={selectedNode.label}
              onChange={(e) => {
                const updatedNodes = nodes.map(n => 
                  n.id === selectedNode.id 
                    ? {...n, label: e.target.value} 
                    : n
                );
                setNodes(updatedNodes);
                setSelectedNode({...selectedNode, label: e.target.value});
              }}
            />
          </div>
        </div>
      )}
    </div>
  );
};

export default WorkflowDesigner;

工作流引擎核心实现

PHP工作流执行器

<?php
/**
 * WordPress工作流引擎核心类
 */

class SupplyChainWorkflowEngine {
    
    private $workflow_id;
    private $instance_id;
    private $workflow_data;
    private $current_state;
    
    /**
     * 初始化工作流引擎
     * @param int $workflow_id 工作流ID
     */
    public function __construct($workflow_id) {
        global $wpdb;
        
        $this->workflow_id = $workflow_id;
        
        // 从数据库加载工作流定义
        $table_name = $wpdb->prefix . 'supply_workflows';
        $workflow = $wpdb->get_row(
            $wpdb->prepare("SELECT * FROM $table_name WHERE id = %d", $workflow_id)
        );
        
        if (!$workflow) {
            throw new Exception('工作流不存在');
        }
        
        $this->workflow_data = json_decode($workflow->workflow_data, true);
    }
    
    /**
     * 创建工作流实例
     * @param array $input_data 输入数据
     * @return int 实例ID
     */
    public function createInstance($input_data = []) {
        global $wpdb;
        
        $instance_table = $wpdb->prefix . 'workflow_instances';
        
        $data = [
            'workflow_id' => $this->workflow_id,
            'current_node' => $this->findStartNode(),
            'status' => 'running',
            'input_data' => json_encode($input_data),
            'created_at' => current_time('mysql')
        ];
        
        $wpdb->insert($instance_table, $data);
        $this->instance_id = $wpdb->insert_id;
        
        $this->logAction('instance_created', '工作流实例创建成功');
        
        return $this->instance_id;
    }
    
    /**
     * 执行工作流
     * @param int $instance_id 实例ID
     * @return array 执行结果
     */
    public function execute($instance_id = null) {
        if ($instance_id) {
            $this->loadInstance($instance_id);
        }
        
        if (!$this->instance_id) {
            throw new Exception('工作流实例未初始化');
        }
        
        $output_data = [];
        
        // 获取当前节点
        $current_node_id = $this->current_state['current_node'];
        
        while ($current_node_id) {
            $node = $this->getNodeById($current_node_id);
            
            if (!$node) {
                $this->updateInstanceStatus('failed');
                $this->logAction('node_not_found', "节点 {$current_node_id} 不存在", 'error');
                break;
            }
            
            // 执行节点逻辑
            try {
                $result = $this->executeNode($node);
                $output_data[$node['id']] = $result;
                
                $this->logAction(
                    'node_executed', 
                    "节点 {$node['label']} 执行成功",
                    'info',
                    $node['id']
                );
                
                // 获取下一个节点
                $next_node_id = $this->getNextNode($node, $result);
                
                if ($next_node_id) {
                    $this->updateCurrentNode($next_node_id);
                    $current_node_id = $next_node_id;
                } else {
                    // 工作流完成
                    $this->updateInstanceStatus('completed');
                    $this->logAction('workflow_completed', '工作流执行完成');
                    break;
                }
                
            } catch (Exception $e) {
                $this->updateInstanceStatus('failed');
                $this->logAction(
                    'node_execution_failed',
                    "节点 {$node['label']} 执行失败: " . $e->getMessage(),
                    'error',
                    $node['id']
                );
                break;
            }
        }
        
        // 保存输出数据
        $this->saveOutputData($output_data);
        
        return [
            'status' => $this->current_state['status'],
            'output_data' => $output_data,
            'instance_id' => $this->instance_id
        ];
    }
    
    /**
     * 执行单个节点逻辑
     * @param array $node 节点数据
     * @return mixed 执行结果
     */
    private function executeNode($node) {
        $node_type = $node['type'];
        
        switch ($node_type) {
            case 'order_receive':
                return $this->executeOrderReceive($node);
                
            case 'inventory_check':
                return $this->executeInventoryCheck($node);
                
            case 'supplier_notify':
                return $this->executeSupplierNotify($node);
                
            case 'quality_check':
                return $this->executeQualityCheck($node);
                
            case 'shipping':
                return $this->executeShipping($node);
                
            case 'payment':
                return $this->executePayment($node);
                
            default:
                throw new Exception("未知的节点类型: {$node_type}");
        }
    }
    
    /**
     * 执行订单接收节点
     */
    private function executeOrderReceive($node) {
        // 模拟订单接收逻辑
        $input_data = json_decode($this->current_state['input_data'], true);
        
        // 这里可以集成实际的订单系统API
        $order_data = [
            'order_id' => 'ORD_' . time(),
            'customer_id' => $input_data['customer_id'] ?? 'CUST001',
            'products' => $input_data['products'] ?? [],
            'total_amount' => $input_data['total_amount'] ?? 0,
            'received_at' => current_time('mysql')
        ];
        
        // 验证订单数据
        if (empty($order_data['products'])) {
            throw new Exception('订单商品不能为空');
        }
        
        return [
            'success' => true,
            'order_data' => $order_data,
            'message' => '订单接收成功'
        ];
    }
    
    /**
     * 执行库存检查节点
     */
    private function executeInventoryCheck($node) {
        global $wpdb;
        
        // 获取前一个节点的输出
        $previous_result = $this->getPreviousNodeResult($node['id']);
        $products = $previous_result['order_data']['products'] ?? [];
        
        $inventory_status = [];
        $all_in_stock = true;
        
        foreach ($products as $product) {
            // 这里可以查询实际的库存数据库
            // 模拟库存检查
            $in_stock = rand(0, 1) > 0.2; // 80%的概率有库存
            
            $inventory_status[] = [
                'product_id' => $product['id'],
                'product_name' => $product['name'],
                'in_stock' => $in_stock,
                'required_quantity' => $product['quantity'],
                'available_quantity' => $in_stock ? $product['quantity'] : 0
            ];
            
            if (!$in_stock) {
                $all_in_stock = false;
            }
        }
        
        return [
            'success' => $all_in_stock,
            'inventory_status' => $inventory_status,

所有商品库存充足' : '部分商品库存不足'

    ];
}

/**
 * 执行供应商通知节点
 */
private function executeSupplierNotify($node) {
    // 获取库存检查结果
    $inventory_result = $this->getPreviousNodeResult($node['id']);
    
    if ($inventory_result['success']) {
        return [
            'success' => true,
            'message' => '库存充足,无需通知供应商',
            'action_required' => false
        ];
    }
    
    // 识别缺货商品
    $out_of_stock_items = array_filter(
        $inventory_result['inventory_status'],
        fn($item) => !$item['in_stock']
    );
    
    // 模拟调用供应商API
    $supplier_responses = [];
    foreach ($out_of_stock_items as $item) {
        $supplier_response = $this->callSupplierAPI($item);
        $supplier_responses[] = $supplier_response;
    }
    
    $all_suppliers_responded = count(array_filter(
        $supplier_responses,
        fn($resp) => $resp['success']
    )) === count($out_of_stock_items);
    
    return [
        'success' => $all_suppliers_responded,
        'supplier_responses' => $supplier_responses,
        'message' => $all_suppliers_responded ? 
            '所有供应商已确认补货' : '部分供应商响应失败',
        'action_required' => true
    ];
}

/**
 * 调用供应商API(模拟)
 */
private function callSupplierAPI($item) {
    // 模拟API调用延迟
    usleep(100000); // 0.1秒延迟
    
    $success = rand(0, 1) > 0.3; // 70%成功率
    
    return [
        'success' => $success,
        'product_id' => $item['product_id'],
        'supplier_id' => 'SUP_' . rand(1000, 9999),
        'estimated_delivery' => $success ? 
            date('Y-m-d', strtotime('+3 days')) : null,
        'message' => $success ? 
            '补货请求已接受' : '供应商系统繁忙,请稍后重试'
    ];
}

/**
 * 获取下一个节点
 */
private function getNextNode($current_node, $execution_result) {
    $edges = $this->workflow_data['edges'] ?? [];
    
    // 查找从当前节点出发的连接线
    $outgoing_edges = array_filter(
        $edges,
        fn($edge) => $edge['source'] === $current_node['id']
    );
    
    if (empty($outgoing_edges)) {
        return null; // 没有后续节点
    }
    
    // 如果有条件分支,根据执行结果选择路径
    if (count($outgoing_edges) > 1) {
        foreach ($outgoing_edges as $edge) {
            if (isset($edge['condition'])) {
                // 评估条件表达式
                if ($this->evaluateCondition($edge['condition'], $execution_result)) {
                    return $edge['target'];
                }
            }
        }
    }
    
    // 默认返回第一个连接的目标节点
    return $outgoing_edges[0]['target'] ?? null;
}

/**
 * 评估条件表达式
 */
private function evaluateCondition($condition, $data) {
    // 简单的条件评估逻辑
    // 实际应用中可以使用更复杂的表达式引擎
    if (strpos($condition, 'success') !== false) {
        return $data['success'] ?? false;
    }
    
    if (strpos($condition, 'in_stock') !== false) {
        $all_in_stock = true;
        foreach (($data['inventory_status'] ?? []) as $item) {
            if (!$item['in_stock']) {
                $all_in_stock = false;
                break;
            }
        }
        return $all_in_stock;
    }
    
    return true; // 默认通过
}

/**
 * 记录日志
 */
private function logAction($action, $message, $level = 'info', $node_id = null) {
    global $wpdb;
    
    $log_table = $wpdb->prefix . 'workflow_logs';
    
    $wpdb->insert($log_table, [
        'instance_id' => $this->instance_id,
        'node_id' => $node_id,
        'action' => $action,
        'message' => $message,
        'log_level' => $level,
        'created_at' => current_time('mysql')
    ]);
}

/**
 * 保存工作流定义
 */
public static function saveWorkflow($name, $workflow_data, $description = '') {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'supply_workflows';
    
    return $wpdb->insert($table_name, [
        'name' => $name,
        'description' => $description,
        'workflow_data' => json_encode($workflow_data),
        'status' => 'active',
        'created_at' => current_time('mysql')
    ]);
}

}
?>


## WordPress插件集成

### 主插件文件

<?php
/**

  • Plugin Name: WordPress柔性供应链工作流引擎
  • Plugin URI: https://yourdomain.com/
  • Description: 可视化供应链工作流管理引擎
  • Version: 1.0.0
  • Author: Your Name
  • License: GPL v2 or later
    */

// 防止直接访问
if (!defined('ABSPATH')) {

exit;

}

// 定义插件常量
define('SCWE_VERSION', '1.0.0');
define('SCWE_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SCWE_PLUGIN_URL', plugin_dir_url(__FILE__));

// 自动加载类
spl_autoload_register(function ($class) {

$prefix = 'SCWE\';
$base_dir = SCWE_PLUGIN_DIR . 'includes/';

$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
    return;
}

$relative_class = substr($class, $len);
$file = $base_dir . str_replace('\', '/', $relative_class) . '.php';

if (file_exists($file)) {
    require $file;
}

});

// 初始化插件
class SupplyChainWorkflowPlugin {


private static $instance = null;

public static function get_instance() {
    if (null === self::$instance) {
        self::$instance = new self();
    }
    return self::$instance;
}

private function __construct() {
    $this->init_hooks();
}

private function init_hooks() {
    // 激活/停用钩子
    register_activation_hook(__FILE__, [$this, 'activate']);
    register_deactivation_hook(__FILE__, [$this, 'deactivate']);
    
    // 管理菜单
    add_action('admin_menu', [$this, 'add_admin_menu']);
    
    // 加载脚本和样式
    add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
    
    // REST API端点
    add_action('rest_api_init', [$this, 'register_rest_routes']);
    
    // 短代码
    add_shortcode('workflow_dashboard', [$this, 'render_dashboard_shortcode']);
}

public function activate() {
    // 创建数据库表
    require_once SCWE_PLUGIN_DIR . 'includes/class-installer.php';
    SCWEInstaller::install();
    
    // 添加默认工作流
    $this->create_default_workflows();
    
    // 设置插件版本
    update_option('scwe_version', SCWE_VERSION);
}

public function deactivate() {
    // 清理临时数据
    // 注意:不删除工作流数据,以便重新激活时可以使用
}

public function add_admin_menu() {
    add_menu_page(
        '供应链工作流',
        '供应链工作流',
        'manage_options',
        'supply-chain-workflow',
        [$this, 'render_admin_page'],
        'dashicons-networking',
        30
    );
    
    add_submenu_page(
        'supply-chain-workflow',
        '工作流设计器',
        '工作流设计器',
        'manage_options',
        'scwe-designer',
        [$this, 'render_designer_page']
    );
    
    add_submenu_page(
        'supply-chain-workflow',
        '工作流实例',
        '工作流实例',
        'manage_options',
        'scwe-instances',
        [$this, 'render_instances_page']
    );
    
    add_submenu_page(
        'supply-chain-workflow',
        '监控面板',
        '监控面板',
        'manage_options',
        'scwe-monitor',
        [$this, 'render_monitor_page']
    );
}

public function render_admin_page() {
    ?>
    <div class="wrap">
        <h1>柔性供应链工作流引擎</h1>
        <div class="scwe-dashboard">
            <div class="scwe-stats">
                <div class="stat-card">
                    <h3>活跃工作流</h3>
                    <p class="stat-number"><?php echo $this->get_active_workflow_count(); ?></p>
                </div>
                <div class="stat-card">
                    <h3>运行中实例</h3>
                    <p class="stat-number"><?php echo $this->get_running_instances_count(); ?></p>
                </div>
                <div class="stat-card">
                    <h3>今日完成</h3>
                    <p class="stat-number"><?php echo $this->get_today_completed_count(); ?></p>
                </div>
            </div>
            
            <div class="scwe-quick-actions">
                <h2>快速开始</h2>
                <a href="<?php echo admin_url('admin.php?page=scwe-designer'); ?>" 
                   class="button button-primary">
                   创建新工作流
                </a>
                <a href="<?php echo admin_url('admin.php?page=scwe-instances'); ?>" 
                   class="button">
                   查看所有实例
                </a>
            </div>
            
            <div class="scwe-recent-activities">
                <h2>最近活动</h2>
                <?php $this->render_recent_activities(); ?>
            </div>
        </div>
    </div>
    <?php
}

public function render_designer_page() {
    ?>
    <div class="wrap">
        <h1>工作流设计器</h1>
        <div id="scwe-designer-root"></div>
    </div>
    
    <script type="text/javascript">
    // 传递WordPress REST API非ce到前端
    window.scweApiSettings = {
        root: '<?php echo esc_url_raw(rest_url()); ?>',
        nonce: '<?php echo wp_create_nonce('wp_rest'); ?>'
    };
    </script>
    <?php
}

public function enqueue_admin_assets($hook) {
    if (strpos($hook, 'scwe-') === false && 
        strpos($hook, 'supply-chain-workflow') === false) {
        return;
    }
    
    // 加载设计器页面资源
    if ($hook === 'toplevel_page_scwe-designer' || 
        strpos($hook, 'scwe-designer') !== false) {
        
        // React和ReactDOM
        wp_enqueue_script('react', 'https://unpkg.com/react@17/umd/react.production.min.js');
        wp_enqueue_script('react-dom', 'https://unpkg.com/react-dom@17/umd/react-dom.production.min.js');
        
        // D3.js
        wp_enqueue_script('d3', 'https://d3js.org/d3.v7.min.js');
        
        // 自定义脚本
        wp_enqueue_script(
            'scwe-designer',
            SCWE_PLUGIN_URL . 'assets/js/designer.js',
            ['react', 'react-dom', 'd3'],
            SCWE_VERSION,
            true
        );
        
        // 样式
        wp_enqueue_style(
            'scwe-designer-style',
            SCWE_PLUGIN_URL . 'assets/css/designer.css',
            [],
            SCWE_VERSION
        );
    }
    
    // 通用管理样式
    wp_enqueue_style(
        'scwe-admin-style',
        SCWE_PLUGIN_URL . 'assets/css/admin.css',
        [],
        SCWE_VERSION
    );
}

public function register_rest_routes() {
    register_rest_route('scwe/v1', '/workflows', [
        [
            'methods' => 'GET',
            'callback' => [$this, 'get_workflows'],
            'permission_callback' => [$this, 'check_permissions']
        ],
        [
            'methods' => 'POST',
            'callback' => [$this, 'create_workflow'],
            'permission_callback' => [$this, 'check_permissions']
        ]
    ]);
    
    register_rest_route('scwe/v1', '/workflows/(?P<id>d+)', [
        [
            'methods' => 'GET',
            'callback' => [$this, 'get_workflow'],
            'permission_callback' => [$this, 'check_permissions']
        ],
        [
            'methods' => 'PUT',
            'callback' => [$this, 'update_workflow'],
            'permission_callback' => [$this, 'check_permissions']
        ],
        [
            'methods' => 'DELETE',
            'callback' => [$this, 'delete_workflow'],
            'permission_callback' => [$this, 'check_permissions']
        ]
    ]);
    
    register_rest_route('scwe/v1', '/workflows/(?P<id>d+)/execute', [
        'methods' => 'POST',
        'callback' => [$this, 'execute_workflow'],
        'permission_callback' => [$this, 'check_permissions']
    ]);
    
    register_rest_route('scwe/v1', '/instances', [
        'methods' => 'GET',
        'callback' => [$this, 'get_instances'],
        'permission_callback' => [$this, 'check_permissions']
    ]);
}

public function check_permissions($request) {
    return current_user_can('manage_options');
}

public function get_workflows($request) {
    global $wpdb;
    
    $table_name = $wpdb->prefix . 'supply_workflows';
    $workflows = $wpdb->get_results("SELECT * FROM $table_name ORDER BY created_at DESC");
    
    return rest_ensure_response($workflows);
}

public function create_workflow($request) {
    $params = $request->get_json_params();
    
    $result = SupplyChainWorkflowEngine::saveWorkflow(
        sanitize_text_field($params['name']),
        $params['workflow_data'],
        sanitize_textarea_field($params['description'] ?? '')
    );
    
    if ($result) {
        return rest_ensure_response([
            'success' => true,
            'id' => $wpdb->insert_id
        ]);
    }
    
    return new WP_Error('create_failed', '创建工作流失败');
}

private function create_default_workflows() {
    // 创建默认的订单处理工作流
    $default_workflow = [
        'nodes' => [
            [
                'id' => 'start',
                'type' => 'order_receive',
                'label' => '订单接收',
                'x' => 100,
                'y' => 100
            ],
            [
                'id' => 'inventory_check',
                'type' => 'inventory_check',
                'label' => '库存检查',
                'x' => 300,
                'y' => 100
            ],
            [
                'id' => 'supplier_notify',
                'type' => 'supplier_notify',
                'label' => '供应商通知',
                'x' => 500,
                'y' => 100
            ],
            [
                'id' => 'quality_check',
                'type' => 'quality_check',
                'label' => '质量检查',
                'x' => 300,
                'y' => 250
            ],
            [
                'id' => 'shipping',
                'type' => 'shipping',
                'label' => '发货处理',
                'x' => 500,
                'y' => 250
            ],
            [
                'id' => 'payment',
                'type' => 'payment',
                'label' => '支付处理',
                'x' => 700,
                'y' => 250
            ]
        ],
        'edges' => [
            [
                'source' => 'start',
                'target' => 'inventory_check'
            ],
            [
                'source' => 'inventory_check',
                'target' => 'supplier_notify',
                'condition' => '!in_stock'
            ],
            [
                'source' => 'inventory_check',
                'target' => 'quality_check',
                'condition' => 'in_stock'
            ],
            [
                'source' => 'supplier_notify',
                'target' => 'quality_check'
            ],
            [
                'source' => 'quality_check',
                'target' => 'shipping'
            ],
            [
                'source' => 'shipping',
                'target' => 'payment'
            ]
        ]
    ];
    
    SupplyChainWorkflowEngine::saveWorkflow(
        '标准订单处理流程',
        $default_workflow,
        '默认的订单处理工作流,包含库存检查、供应商通知等环节'
    );
}

}

// 初始化插件
SupplyChainWorkflowPlugin::get_instance();
?>


## 监控与优化

### 实时监控面板

// monitor-dashboard.js
import React, { useState, useEffect } from 'react';
import { LineChart, Line, BarChart, Bar, PieChart, Pie, Cell } from 'recharts';

const

本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/6461.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部