文章目录[隐藏]
WordPress柔性供应链软件的无代码配置模块开发教程
引言:为什么需要无代码配置模块
在当今快速变化的商业环境中,供应链管理软件需要具备高度的灵活性和适应性。传统的供应链系统往往需要专业开发人员介入才能进行配置和调整,这导致了高昂的维护成本和漫长的响应时间。WordPress作为全球最流行的内容管理系统,其插件生态系统为开发柔性供应链解决方案提供了理想平台。
本教程将指导您如何开发一个无代码配置模块,让非技术用户能够通过直观的界面自定义供应链流程、业务规则和数据字段,而无需编写任何代码。这种模块特别适合中小型企业,它们需要专业的供应链管理功能,但缺乏专门的IT团队。
模块架构设计
核心组件规划
我们的无代码配置模块将包含以下核心组件:
- 可视化流程设计器 - 允许用户拖拽方式创建供应链流程
- 业务规则引擎 - 通过条件语句配置业务逻辑
- 数据模型定制器 - 动态创建和修改数据字段
- 权限配置系统 - 定义不同用户角色的访问权限
- 集成配置界面 - 配置与外部系统的连接
数据库结构设计
<?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; ?>
