首页 / 教程文章 / WordPress柔性供应链软件的无代码配置模块开发教程

WordPress柔性供应链软件的无代码配置模块开发教程

WordPress柔性供应链软件的无代码配置模块开发教程

引言:为什么需要无代码配置模块

在当今快速变化的商业环境中,供应链管理软件需要具备高度的灵活性和适应性。传统的供应链系统往往需要专业开发人员介入才能进行配置和调整,这导致了高昂的维护成本和漫长的响应时间。WordPress作为全球最流行的内容管理系统,其插件生态系统为开发柔性供应链解决方案提供了理想平台。

本教程将指导您如何开发一个无代码配置模块,让非技术用户能够通过直观的界面自定义供应链流程、业务规则和数据字段,而无需编写任何代码。这种模块特别适合中小型企业,它们需要专业的供应链管理功能,但缺乏专门的IT团队。

模块架构设计

核心组件规划

我们的无代码配置模块将包含以下核心组件:

  1. 可视化流程设计器 - 允许用户拖拽方式创建供应链流程
  2. 业务规则引擎 - 通过条件语句配置业务逻辑
  3. 数据模型定制器 - 动态创建和修改数据字段
  4. 权限配置系统 - 定义不同用户角色的访问权限
  5. 集成配置界面 - 配置与外部系统的连接

数据库结构设计

<?php
/**
 * 无代码配置模块数据库表结构
 * 这段代码应该放在插件激活时执行
 */

global $wpdb;
$charset_collate = $wpdb->get_charset_collate();

// 供应链流程表
$supply_chain_flows_table = $wpdb->prefix . 'sc_flows';
$flows_sql = "CREATE TABLE $supply_chain_flows_table (
    id mediumint(9) NOT NULL AUTO_INCREMENT,
    name varchar(100) NOT NULL,
    description text,
    flow_data longtext NOT NULL, -- 存储JSON格式的流程配置
    status varchar(20) DEFAULT 'active',
    created_by bigint(20) NOT NULL,
    created_at datetime DEFAULT CURRENT_TIMESTAMP,
    updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
) $charset_collate;";

// 业务规则表
$business_rules_table = $wpdb->prefix . 'sc_rules';
$rules_sql = "CREATE TABLE $business_rules_table (
    id mediumint(9) NOT NULL AUTO_INCREMENT,
    rule_name varchar(100) NOT NULL,
    rule_type varchar(50) NOT NULL, -- 规则类型:validation, automation, notification等
    conditions longtext NOT NULL, -- JSON格式的条件配置
    actions longtext NOT NULL, -- JSON格式的动作配置
    target_flow_id mediumint(9), -- 关联的流程ID
    priority int DEFAULT 10,
    is_active tinyint(1) DEFAULT 1,
    PRIMARY KEY (id),
    FOREIGN KEY (target_flow_id) REFERENCES $supply_chain_flows_table(id) ON DELETE CASCADE
) $charset_collate;";

// 自定义字段表
$custom_fields_table = $wpdb->prefix . 'sc_fields';
$fields_sql = "CREATE TABLE $custom_fields_table (
    id mediumint(9) NOT NULL AUTO_INCREMENT,
    entity_type varchar(50) NOT NULL, -- 实体类型:product, order, supplier等
    field_name varchar(100) NOT NULL,
    field_label varchar(100) NOT NULL,
    field_type varchar(50) NOT NULL, -- 字段类型:text, number, date, select等
    field_options text, -- JSON格式的选项(用于下拉框等)
    is_required tinyint(1) DEFAULT 0,
    display_order int DEFAULT 0,
    created_at datetime DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (id)
) $charset_collate;";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($flows_sql);
dbDelta($rules_sql);
dbDelta($fields_sql);
?>

可视化流程设计器开发

前端界面实现

可视化流程设计器是无代码配置模块的核心。我们将使用JavaScript流程图库(如jsPlumb或GoJS)来创建拖拽式界面。

/**
 * 供应链流程设计器前端代码
 * 使用jsPlumb库创建可拖拽的节点和连接
 */

class FlowDesigner {
    constructor(containerId) {
        this.container = document.getElementById(containerId);
        this.nodes = [];
        this.connections = [];
        this.initJsPlumb();
        this.initToolbox();
        this.bindEvents();
    }
    
    initJsPlumb() {
        // 初始化jsPlumb实例
        this.jsPlumbInstance = jsPlumb.getInstance({
            Container: this.container,
            Connector: ["Flowchart", { stub: 40, cornerRadius: 5 }],
            PaintStyle: { stroke: "#456", strokeWidth: 2 },
            EndpointStyle: { radius: 7, fill: "#456" },
            ConnectionOverlays: [
                ["Arrow", { location: 1, width: 12, length: 12 }]
            ]
        });
        
        // 设置可拖拽
        this.jsPlumbInstance.draggable(this.container.querySelectorAll('.flow-node'));
    }
    
    initToolbox() {
        // 创建节点工具箱
        const nodeTypes = [
            { type: 'start', label: '开始', icon: '▶' },
            { type: 'task', label: '任务', icon: '□' },
            { type: 'decision', label: '决策', icon: '◇' },
            { type: 'delay', label: '延迟', icon: '⏱' },
            { type: 'end', label: '结束', icon: '■' }
        ];
        
        const toolbox = document.createElement('div');
        toolbox.className = 'flow-toolbox';
        
        nodeTypes.forEach(nodeType => {
            const nodeElement = document.createElement('div');
            nodeElement.className = 'toolbox-node';
            nodeElement.dataset.type = nodeType.type;
            nodeElement.innerHTML = `<span class="node-icon">${nodeType.icon}</span> ${nodeType.label}`;
            toolbox.appendChild(nodeElement);
        });
        
        document.querySelector('.designer-wrapper').prepend(toolbox);
    }
    
    bindEvents() {
        // 工具箱节点拖拽事件
        document.querySelectorAll('.toolbox-node').forEach(node => {
            node.addEventListener('dragstart', (e) => {
                e.dataTransfer.setData('text/plain', e.target.dataset.type);
            });
        });
        
        // 设计区域放置事件
        this.container.addEventListener('drop', (e) => {
            e.preventDefault();
            const nodeType = e.dataTransfer.getData('text/plain');
            const rect = this.container.getBoundingClientRect();
            const x = e.clientX - rect.left;
            const y = e.clientY - rect.top;
            
            this.addNode(nodeType, x, y);
        });
        
        this.container.addEventListener('dragover', (e) => e.preventDefault());
    }
    
    addNode(type, x, y) {
        const nodeId = `node_${Date.now()}`;
        const node = document.createElement('div');
        node.id = nodeId;
        node.className = `flow-node ${type}-node`;
        node.style.left = `${x}px`;
        node.style.top = `${y}px`;
        
        // 根据节点类型设置内容
        const nodeContents = {
            'start': '<div class="node-content">开始</div>',
            'task': '<div class="node-content" contenteditable="true">新任务</div>',
            'decision': '<div class="node-content" contenteditable="true">决策点</div>',
            'delay': '<div class="node-content" contenteditable="true">延迟</div>',
            'end': '<div class="node-content">结束</div>'
        };
        
        node.innerHTML = nodeContents[type];
        this.container.appendChild(node);
        
        // 使新节点可拖拽
        this.jsPlumbInstance.draggable(node);
        
        // 添加端点
        if (type !== 'end') {
            this.jsPlumbInstance.addEndpoint(nodeId, {
                anchor: "Bottom",
                isSource: true,
                isTarget: false
            });
        }
        
        if (type !== 'start') {
            this.jsPlumbInstance.addEndpoint(nodeId, {
                anchor: "Top",
                isSource: false,
                isTarget: true
            });
        }
        
        this.nodes.push({
            id: nodeId,
            type: type,
            x: x,
            y: y,
            config: {}
        });
    }
    
    saveFlow() {
        // 收集所有节点和连接数据
        const flowData = {
            nodes: this.nodes,
            connections: this.jsPlumbInstance.getAllConnections().map(conn => ({
                source: conn.sourceId,
                target: conn.targetId
            })),
            savedAt: new Date().toISOString()
        };
        
        // 保存到服务器
        fetch(ajaxurl, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
            },
            body: JSON.stringify({
                action: 'save_supply_flow',
                flow_data: flowData,
                nonce: sc_config.nonce
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                alert('流程保存成功!');
            } else {
                alert('保存失败:' + data.data);
            }
        });
    }
}

// 初始化设计器
document.addEventListener('DOMContentLoaded', () => {
    window.flowDesigner = new FlowDesigner('flow-design-area');
});

后端处理逻辑

<?php
/**
 * 流程设计器后端处理
 */

class FlowDesignerBackend {
    
    public function __construct() {
        // 注册AJAX处理函数
        add_action('wp_ajax_save_supply_flow', array($this, 'save_flow_data'));
        add_action('wp_ajax_load_supply_flow', array($this, 'load_flow_data'));
        
        // 注册管理菜单
        add_action('admin_menu', array($this, 'add_admin_menu'));
    }
    
    public function add_admin_menu() {
        add_menu_page(
            '供应链配置',
            '供应链配置',
            'manage_options',
            'supply-chain-config',
            array($this, 'render_config_page'),
            'dashicons-networking',
            30
        );
        
        add_submenu_page(
            'supply-chain-config',
            '流程设计器',
            '流程设计器',
            'manage_options',
            'flow-designer',
            array($this, 'render_flow_designer')
        );
    }
    
    public function render_flow_designer() {
        ?>
        <div class="wrap">
            <h1>供应链流程设计器</h1>
            <div class="designer-wrapper">
                <div id="flow-design-area" style="width: 100%; height: 600px; border: 1px solid #ccc; position: relative;"></div>
                <div class="designer-controls">
                    <button id="save-flow" class="button button-primary">保存流程</button>
                    <button id="reset-flow" class="button">重置</button>
                    <button id="export-flow" class="button">导出</button>
                </div>
            </div>
        </div>
        
        <script>
        // 传递必要的参数给前端
        var sc_config = {
            ajaxurl: '<?php echo admin_url('admin-ajax.php'); ?>',
            nonce: '<?php echo wp_create_nonce('sc_flow_nonce'); ?>'
        };
        </script>
        <?php
    }
    
    public function save_flow_data() {
        // 验证nonce
        if (!wp_verify_nonce($_POST['nonce'], 'sc_flow_nonce')) {
            wp_die('安全验证失败');
        }
        
        // 检查用户权限
        if (!current_user_can('manage_options')) {
            wp_die('权限不足');
        }
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'sc_flows';
        
        $flow_data = json_decode(stripslashes($_POST['flow_data']), true);
        $flow_name = isset($_POST['flow_name']) ? sanitize_text_field($_POST['flow_name']) : '未命名流程';
        
        $result = $wpdb->insert(
            $table_name,
            array(
                'name' => $flow_name,
                'flow_data' => json_encode($flow_data),
                'created_by' => get_current_user_id()
            ),
            array('%s', '%s', '%d')
        );
        
        if ($result) {
            wp_send_json_success(array('message' => '流程保存成功', 'flow_id' => $wpdb->insert_id));
        } else {
            wp_send_json_error(array('message' => '保存失败:' . $wpdb->last_error));
        }
    }
    
    public function load_flow_data() {
        // 类似save_flow_data,实现流程加载逻辑
        // 这里省略具体实现
    }
}

// 初始化后端
new FlowDesignerBackend();
?>

业务规则引擎实现

规则配置界面

<?php
/**
 * 业务规则配置界面
 */

class BusinessRuleConfigurator {
    
    public function render_rule_builder() {
        ?>
        <div class="wrap">
            <h1>业务规则配置</h1>
            
            <div class="rule-builder-container">
                <div class="rule-conditions">
                    <h3>条件设置</h3>
                    <div id="condition-builder">
                        <!-- 条件构建器将通过JavaScript动态生成 -->
                    </div>
                    <button id="add-condition" class="button">添加条件</button>
                </div>
                
                <div class="rule-actions">
                    <h3>执行动作</h3>
                    <div id="action-builder">
                        <!-- 动作构建器将通过JavaScript动态生成 -->
                    </div>
                    <button id="add-action" class="button">添加动作</button>
                </div>
                
                <div class="rule-settings">
                    <h3>规则设置</h3>
                    <p>
                        <label>规则名称:</label>
                        <input type="text" id="rule-name" class="regular-text">
                    </p>
                    <p>
                        <label>规则类型:</label>
                        <select id="rule-type">
                            <option value="validation">数据验证</option>
                            <option value="automation">自动执行</option>
                            <option value="notification">通知提醒</option>
                            <option value="calculation">自动计算</option>
                        </select>
                    </p>
                    <p>
                        <label>优先级:</label>
                        <input type="number" id="rule-priority" value="10" min="1" max="100">
                    </p>
                </div>
                
                <div class="rule-controls">
                    <button id="save-rule" class="button button-primary">保存规则</button>
                    <button id="test-rule" class="button">测试规则</button>
                </div>
            </div>
        </div>
        
        <script>
        // 规则构建器前端逻辑
        document.addEventListener('DOMContentLoaded', function() {
            const ruleBuilder = new RuleBuilder();
            ruleBuilder.init();
        });
        </script>
        <?php
    }
}

// 规则执行引擎
class RuleEngine {
    
    /**
     * 执行规则
     * @param array $rule 规则配置
     * @param array $context 执行上下文(包含数据、用户等信息)
     * @return array 执行结果
     */
    public function execute_rule($rule, $context) {
        // 解析规则条件
        $conditions_met = $this->evaluate_conditions($rule['conditions'], $context);
        
        if (!$conditions_met) {
            return array(
                'success' => false,
                'message' => '条件未满足',
                'actions_executed' => 0
            );
        }
        
        // 执行动作
        $results = array();
        foreach ($rule['actions'] as $action) {
            $result = $this->execute_action($action, $context);
            $results[] = $result;
        }
        
        return array(
            'success' => true,
            'message' => '规则执行完成',
            'actions_executed' => count($results),
            'results' => $results
        );
    }
    
    /**
     * 评估条件
     */
    private function evaluate_conditions($conditions, $context) {
        // 支持多种条件类型:AND, OR, NOT
        if (!isset($conditions['type'])) {
            return false;
        }
        
        switch ($conditions['type']) {
            case 'AND':
                foreach ($conditions['conditions'] as $condition) {
                    if (!$this->evaluate_single_condition($condition, $context)) {
                        return false;
                    }
                }
                return true;
                
            case 'OR':
                foreach ($conditions['conditions'] as $condition) {
                    if ($this->evaluate_single_condition($condition, $context)) {
                        return true;
                    }
                }
                return false;
                
            case 'NOT':
                return !$this->evaluate_single_condition($conditions['condition'], $context);
                
            default:
                return $this->evaluate_single_condition($conditions, $context);
        }
    }
    
    /**
     * 评估单个条件
     */
    private function evaluate_single_condition($condition, $context) {
        $field_value = $this->get_field_value($condition['field'], $context);
        $compare_value = $condition['value'];
        
        switch ($condition['operator']) {
            case 'equals':
                return $field_value == $compare_value;
            case 'not_equals':
                return $field_value != $compare_value;
            case 'greater_than':
                return $field_value > $compare_value;
            case 'less_than':
                return $field_value < $compare_value;
            case 'contains':
                return strpos($field_value, $compare_value) !== false;
            case 'not_contains':
                return strpos($field_value, $compare_value) === false;
            case 'is_empty':
                return empty($field_value);
            case 'is_not_empty':
                return !empty($field_value);
            default:
                return false;
        }
    }
    
    /**
     * 获取字段值
     */
    private function get_field_value($field_path, $context) {

数据模型定制器开发

动态字段管理系统

<?php
/**
 * 数据模型定制器 - 动态字段管理
 */

class DataModelCustomizer {
    
    public function __construct() {
        add_action('admin_menu', array($this, 'add_admin_pages'));
        add_action('wp_ajax_save_custom_field', array($this, 'save_custom_field'));
        add_action('wp_ajax_delete_custom_field', array($this, 'delete_custom_field'));
    }
    
    public function add_admin_pages() {
        add_submenu_page(
            'supply-chain-config',
            '数据模型定制',
            '数据模型定制',
            'manage_options',
            'data-model-customizer',
            array($this, 'render_customizer_page')
        );
    }
    
    public function render_customizer_page() {
        global $wpdb;
        $table_name = $wpdb->prefix . 'sc_fields';
        
        // 获取现有字段
        $existing_fields = $wpdb->get_results(
            "SELECT * FROM $table_name ORDER BY entity_type, display_order",
            ARRAY_A
        );
        
        // 按实体类型分组
        $grouped_fields = array();
        foreach ($existing_fields as $field) {
            $grouped_fields[$field['entity_type']][] = $field;
        }
        
        ?>
        <div class="wrap">
            <h1>数据模型定制器</h1>
            
            <div class="model-customizer-container">
                <div class="entity-types-section">
                    <h2>实体类型管理</h2>
                    <div class="entity-type-list">
                        <?php
                        $entity_types = array(
                            'product' => '产品',
                            'order' => '订单',
                            'supplier' => '供应商',
                            'inventory' => '库存',
                            'customer' => '客户'
                        );
                        
                        foreach ($entity_types as $type => $label):
                        ?>
                        <div class="entity-type-card" data-entity-type="<?php echo esc_attr($type); ?>">
                            <h3><?php echo esc_html($label); ?></h3>
                            <p>字段数量: <?php echo isset($grouped_fields[$type]) ? count($grouped_fields[$type]) : 0; ?></p>
                            <button class="button manage-fields-btn" data-entity="<?php echo esc_attr($type); ?>">
                                管理字段
                            </button>
                        </div>
                        <?php endforeach; ?>
                    </div>
                </div>
                
                <div class="field-editor-section" style="display: none;">
                    <h2 id="entity-editor-title"></h2>
                    
                    <div class="field-list-container">
                        <h3>现有字段</h3>
                        <div id="field-list">
                            <!-- 字段列表将通过JavaScript动态加载 -->
                        </div>
                    </div>
                    
                    <div class="add-field-form">
                        <h3>添加新字段</h3>
                        <form id="add-field-form">
                            <input type="hidden" id="field-entity-type" name="entity_type">
                            
                            <table class="form-table">
                                <tr>
                                    <th scope="row"><label for="field-name">字段名称</label></th>
                                    <td>
                                        <input type="text" id="field-name" name="field_name" 
                                               class="regular-text" required>
                                        <p class="description">使用英文小写和下划线,如:product_color</p>
                                    </td>
                                </tr>
                                <tr>
                                    <th scope="row"><label for="field-label">显示标签</label></th>
                                    <td>
                                        <input type="text" id="field-label" name="field_label" 
                                               class="regular-text" required>
                                    </td>
                                </tr>
                                <tr>
                                    <th scope="row"><label for="field-type">字段类型</label></th>
                                    <td>
                                        <select id="field-type" name="field_type" class="regular-text">
                                            <option value="text">文本</option>
                                            <option value="textarea">多行文本</option>
                                            <option value="number">数字</option>
                                            <option value="date">日期</option>
                                            <option value="datetime">日期时间</option>
                                            <option value="select">下拉选择</option>
                                            <option value="checkbox">复选框</option>
                                            <option value="radio">单选按钮</option>
                                            <option value="file">文件上传</option>
                                            <option value="image">图片</option>
                                            <option value="color">颜色选择器</option>
                                        </select>
                                    </td>
                                </tr>
                                <tr id="options-row" style="display: none;">
                                    <th scope="row"><label for="field-options">选项</label></th>
                                    <td>
                                        <textarea id="field-options" name="field_options" 
                                                  class="large-text" rows="3" 
                                                  placeholder="每行一个选项,格式:value|label"></textarea>
                                        <p class="description">示例:red|红色<br>blue|蓝色<br>green|绿色</p>
                                    </td>
                                </tr>
                                <tr>
                                    <th scope="row"><label for="is-required">是否必填</label></th>
                                    <td>
                                        <input type="checkbox" id="is-required" name="is_required" value="1">
                                        <label for="is-required">此字段为必填项</label>
                                    </td>
                                </tr>
                                <tr>
                                    <th scope="row"><label for="display-order">显示顺序</label></th>
                                    <td>
                                        <input type="number" id="display-order" name="display_order" 
                                               value="0" min="0" max="100" class="small-text">
                                    </td>
                                </tr>
                            </table>
                            
                            <p class="submit">
                                <button type="submit" class="button button-primary">添加字段</button>
                                <button type="button" id="cancel-add-field" class="button">取消</button>
                            </p>
                        </form>
                    </div>
                </div>
            </div>
        </div>
        
        <script>
        jQuery(document).ready(function($) {
            // 显示字段类型相关的选项
            $('#field-type').change(function() {
                if ($(this).val() === 'select' || $(this).val() === 'radio') {
                    $('#options-row').show();
                } else {
                    $('#options-row').hide();
                }
            });
            
            // 管理字段按钮点击事件
            $('.manage-fields-btn').click(function() {
                var entityType = $(this).data('entity');
                var entityLabel = $(this).closest('.entity-type-card').find('h3').text();
                
                // 更新编辑器标题
                $('#entity-editor-title').text(entityLabel + ' - 字段管理');
                $('#field-entity-type').val(entityType);
                
                // 显示编辑器,隐藏实体类型列表
                $('.entity-types-section').hide();
                $('.field-editor-section').show();
                
                // 加载字段列表
                loadFields(entityType);
            });
            
            // 取消添加字段
            $('#cancel-add-field').click(function() {
                $('.entity-types-section').show();
                $('.field-editor-section').hide();
            });
            
            // 添加字段表单提交
            $('#add-field-form').submit(function(e) {
                e.preventDefault();
                
                var formData = $(this).serialize();
                
                $.post(ajaxurl, {
                    action: 'save_custom_field',
                    data: formData,
                    nonce: '<?php echo wp_create_nonce('sc_field_nonce'); ?>'
                }, function(response) {
                    if (response.success) {
                        alert('字段添加成功!');
                        loadFields($('#field-entity-type').val());
                        $('#add-field-form')[0].reset();
                    } else {
                        alert('添加失败:' + response.data);
                    }
                });
            });
            
            // 加载字段列表函数
            function loadFields(entityType) {
                $.post(ajaxurl, {
                    action: 'get_custom_fields',
                    entity_type: entityType,
                    nonce: '<?php echo wp_create_nonce('sc_field_nonce'); ?>'
                }, function(response) {
                    if (response.success) {
                        $('#field-list').html(response.data);
                    }
                });
            }
        });
        </script>
        <?php
    }
    
    public function save_custom_field() {
        // 验证nonce和权限
        if (!wp_verify_nonce($_POST['nonce'], 'sc_field_nonce') || 
            !current_user_can('manage_options')) {
            wp_die('权限不足');
        }
        
        global $wpdb;
        $table_name = $wpdb->prefix . 'sc_fields';
        
        // 准备数据
        $field_data = array(
            'entity_type' => sanitize_text_field($_POST['entity_type']),
            'field_name' => sanitize_text_field($_POST['field_name']),
            'field_label' => sanitize_text_field($_POST['field_label']),
            'field_type' => sanitize_text_field($_POST['field_type']),
            'field_options' => isset($_POST['field_options']) ? 
                sanitize_textarea_field($_POST['field_options']) : '',
            'is_required' => isset($_POST['is_required']) ? 1 : 0,
            'display_order' => intval($_POST['display_order'])
        );
        
        // 验证字段名称格式
        if (!preg_match('/^[a-z][a-z0-9_]*$/', $field_data['field_name'])) {
            wp_send_json_error('字段名称只能包含小写字母、数字和下划线,且必须以字母开头');
        }
        
        // 检查字段是否已存在
        $existing = $wpdb->get_var($wpdb->prepare(
            "SELECT COUNT(*) FROM $table_name 
             WHERE entity_type = %s AND field_name = %s",
            $field_data['entity_type'], $field_data['field_name']
        ));
        
        if ($existing > 0) {
            wp_send_json_error('该实体类型下已存在相同名称的字段');
        }
        
        // 保存到数据库
        $result = $wpdb->insert($table_name, $field_data);
        
        if ($result) {
            wp_send_json_success('字段添加成功');
        } else {
            wp_send_json_error('保存失败:' . $wpdb->last_error);
        }
    }
    
    public function delete_custom_field() {
        // 删除字段的逻辑
        // 这里省略具体实现
    }
}

new DataModelCustomizer();
?>

权限配置系统

基于角色的访问控制

<?php
/**
 * 权限配置系统 - 基于角色的访问控制
 */

class PermissionConfigurator {
    
    private $capabilities = array(
        'supply_chain' => array(
            'view_products' => '查看产品',
            'edit_products' => '编辑产品',
            'delete_products' => '删除产品',
            'view_orders' => '查看订单',
            'create_orders' => '创建订单',
            'edit_orders' => '编辑订单',
            'cancel_orders' => '取消订单',
            'view_inventory' => '查看库存',
            'update_inventory' => '更新库存',
            'view_suppliers' => '查看供应商',
            'manage_suppliers' => '管理供应商',
            'view_reports' => '查看报表',
            'export_data' => '导出数据',
            'configure_system' => '系统配置'
        )
    );
    
    public function __construct() {
        add_action('admin_menu', array($this, 'add_admin_pages'));
        add_action('wp_ajax_save_role_permissions', array($this, 'save_role_permissions'));
        
        // 初始化默认角色
        $this->init_default_roles();
    }
    
    private function init_default_roles() {
        // 添加供应链管理相关角色
        $roles = array(
            'supply_chain_manager' => array(
                'name' => '供应链经理',
                'capabilities' => array_keys($this->capabilities['supply_chain'])
            ),
            'inventory_specialist' => array(
                'name' => '库存专员',
                'capabilities' => array(
                    'view_products',
                    'view_inventory',
                    'update_inventory',
                    'view_reports'
                )
            ),
            'order_processor' => array(
                'name' => '订单处理员',
                'capabilities' => array(
                    'view_products',
                    'view_orders',
                    'create_orders',
                    'edit_orders',
                    'cancel_orders'
                )
            )
        );
        
        foreach ($roles as $role_slug => $role_data) {
            if (!get_role($role_slug)) {
                add_role($role_slug, $role_data['name']);
                
                $role = get_role($role_slug);
                foreach ($role_data['capabilities'] as $cap) {
                    $role->add_cap($cap);
                }
            }
        }
    }
    
    public function add_admin_pages() {
        add_submenu_page(
            'supply-chain-config',
            '权限配置',
            '权限配置',
            'manage_options',
            'permission-config',
            array($this, 'render_permission_page')
        );
    }
    
    public function render_permission_page() {
        // 获取所有角色(排除系统默认角色)
        $wp_roles = wp_roles();
        $roles = $wp_roles->roles;
        
        // 过滤出供应链相关角色
        $supply_chain_roles = array();
        foreach ($roles as $role_slug => $role) {
            // 检查是否有供应链相关权限
            $has_sc_cap = false;
            foreach (array_keys($this->capabilities['supply_chain']) as $cap) {
                if (isset($role['capabilities'][$cap]) && $role['capabilities'][$cap]) {
                    $has_sc_cap = true;
                    break;
                }
            }
            
            if ($has_sc_cap || in_array($role_slug, array('administrator', 'supply_chain_manager', 'inventory_specialist', 'order_processor'))) {
                $supply_chain_roles[$role_slug] = $role;
            }
        }
        
        ?>
        <div class="wrap">
            <h1>权限配置系统</h1>
            
            <div class="permission-config-container">
                <div class="role-selector">
                    <h2>选择角色</h2>
                    <select id="role-selector" class="regular-text">
                        <option value="">请选择角色</option>
                        <?php foreach ($supply_chain_roles as $role_slug => $role): ?>
                        <option value="<?php echo esc_attr($role_slug); ?>">
                            <?php echo esc_html($role['name']); ?>
                        </option>
                        <?php endforeach; ?>
                    </select>
                    
                    <button id="add-new-role" class="button">添加新角色</button>
                </div>
                
                <div class="permission-editor" style="display: none;">
                    <h2 id="role-editor-title"></h2>
                    
                    <div class="capability-groups">
                        <?php foreach ($this->capabilities as $group => $caps): ?>
                        <div class="capability-group">
                            <h3><?php echo esc_html(ucfirst($group)); ?>权限</h3>
                            <table class="wp-list-table widefat fixed striped">
                                <thead>
                                    <tr>
                                        <th width="50">启用</th>
                                        <th>权限名称</th>
                                        <th>权限描述</th>
                                    </tr>
                                </thead>
                                <tbody id="capabilities-<?php echo esc_attr($group); ?>">
                                    <!-- 权限列表将通过JavaScript动态加载 -->
                                </tbody>
                            </table>
                        </div>
                        <?php endforeach; ?>
                    </div>
                    
                    <div class="permission-controls">
                        <button id="save-permissions" class="button button-primary">保存权限</button>
                        <button id="reset-permissions" class="button">重置</button>
                        <span id="save-status" style="margin-left: 10px;"></span>
                    </div>
                </div>
            </div>
        </div>
        
        <script>
        jQuery(document).ready(function($) {
            var currentRole = '';
            var originalPermissions = {};
            
            // 角色选择器变化事件
            $('#role-selector').change(function() {
                var roleSlug = $(this).val();
                
                if (!roleSlug) {
                    $('.permission-editor').hide();
                    return;
                }
                
                currentRole = roleSlug;
                var roleName = $(this).find('option:selected').text();
                $('#role-editor-title').text('配置权限:' + roleName);
                
                // 加载权限
                loadPermissions(roleSlug);
                $('.permission-editor').show();
            });
            
            // 加载权限函数
            function loadPermissions(roleSlug) {
                $.post(ajaxurl, {
                    action: 'get_role_permissions',
                    role: roleSlug,
                    nonce: '<?php echo wp_create_nonce('sc_permission_nonce'); ?>'
                }, function(response) {
                    if (response.success) {
                        originalPermissions = response.data.permissions;
                        
                        // 渲染权限表格
                        renderCapabilities(response.data.permissions);
                    }
                });
            }
            
            // 渲染权限表格
            function renderCapabilities(permissions) {
                <?php foreach ($this->capabilities as $group => $caps): ?>
                var groupHtml = '';
                <?php foreach ($caps as $cap_slug => $cap_name): ?>
                var isChecked = permissions['<?php echo esc_js($cap_slug); ?>'] ? 'checked' : '';
                groupHtml += '<tr>' +
                    '<td><input type="checkbox" name="capabilities[]" ' +
                    'value="<?php echo esc_js($cap_slug); ?>" ' + isChecked + '></td>' +
                    '<td><?php echo esc_js($cap_slug); ?></td>' +
                    '<td><?php echo esc_js($cap_name); ?></td>' +
                    '</tr>';
                <?php endforeach; ?>
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/6124.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

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