首页 / 教程文章 / WordPress小批量定制插件实现尾料管理与利用的教程

WordPress小批量定制插件实现尾料管理与利用的教程

本教程针对制造业、手工艺品等小批量生产中的尾料管理难题,提出基于WordPress的轻量级定制插件解决方案。该插件通过数字化方式记录材料类型、数量、尺寸及状态,建立尾料信息库与使用记录表,并提供管理界面供用户添加、查看与编辑。同时支持智能匹配生产需求,帮助提高材料利用率,减少资源浪费,实现低成本、高效率的尾料管理与利用。

WordPress小批量定制插件实现尾料管理与利用的教程

概述:尾料管理的挑战与解决方案

在制造业、手工艺品生产和定制加工行业中,尾料管理一直是个棘手问题。这些剩余材料虽然数量不多,但长期积累会造成资源浪费和成本增加。传统的人工记录方式效率低下且容易出错,而大型ERP系统又过于复杂昂贵。本教程将指导您开发一个轻量级WordPress插件,专门解决小批量生产中的尾料管理问题。

通过这个定制插件,您可以将尾料信息数字化,跟踪材料类型、数量、尺寸和状态,并智能匹配新的生产需求,最大化材料利用率,减少浪费,节约成本。

环境准备与插件基础结构

首先,我们需要创建插件的基本文件结构。在WordPress的wp-content/plugins/目录下创建一个新文件夹scrap-material-manager

<?php
/**
 * Plugin Name: 尾料管理与利用系统
 * Plugin URI:  https://yourwebsite.com/
 * Description: 用于小批量生产中的尾料跟踪、管理和利用
 * Version:     1.0.0
 * Author:      您的名称
 * License:     GPL v2 or later
 * Text Domain: scrap-material-manager
 */

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

// 定义插件常量
define('SMM_VERSION', '1.0.0');
define('SMM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SMM_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
add_action('init', 'smm_init_plugin');

function smm_init_plugin() {
    // 加载文本域用于国际化
    load_plugin_textdomain('scrap-material-manager', false, dirname(plugin_basename(__FILE__)) . '/languages');
    
    // 创建数据库表
    smm_create_database_tables();
    
    // 注册管理菜单
    if (is_admin()) {
        add_action('admin_menu', 'smm_register_admin_menus');
    }
}
?>

数据库设计与表结构

尾料管理需要存储材料的基本信息、库存状态和使用记录。我们创建两个主要数据表:一个用于存储尾料信息,另一个用于记录使用历史。

<?php
// 创建数据库表
function smm_create_database_tables() {
    global $wpdb;
    
    $charset_collate = $wpdb->get_charset_collate();
    $table_name_materials = $wpdb->prefix . 'smm_materials';
    $table_name_usage = $wpdb->prefix . 'smm_material_usage';
    
    // 检查表是否存在,避免重复创建
    $materials_table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name_materials'") === $table_name_materials;
    $usage_table_exists = $wpdb->get_var("SHOW TABLES LIKE '$table_name_usage'") === $table_name_usage;
    
    if (!$materials_table_exists) {
        $sql_materials = "CREATE TABLE $table_name_materials (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            material_name varchar(100) NOT NULL,
            material_type varchar(50) NOT NULL,
            quantity decimal(10,2) NOT NULL,
            unit varchar(20) NOT NULL,
            width decimal(10,2) DEFAULT NULL,
            height decimal(10,2) DEFAULT NULL,
            length decimal(10,2) DEFAULT NULL,
            color varchar(30) DEFAULT NULL,
            location varchar(100) DEFAULT NULL,
            status varchar(20) DEFAULT 'available',
            purchase_date date DEFAULT NULL,
            notes text,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY status_idx (status),
            KEY material_type_idx (material_type)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql_materials);
    }
    
    if (!$usage_table_exists) {
        $sql_usage = "CREATE TABLE $table_name_usage (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            material_id mediumint(9) NOT NULL,
            used_quantity decimal(10,2) NOT NULL,
            project_name varchar(150) NOT NULL,
            project_id varchar(50) DEFAULT NULL,
            used_by varchar(100) DEFAULT NULL,
            usage_date date NOT NULL,
            notes text,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY material_id_idx (material_id),
            KEY usage_date_idx (usage_date),
            FOREIGN KEY (material_id) REFERENCES $table_name_materials(id) ON DELETE CASCADE
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql_usage);
    }
}

// 插件卸载时清理数据库(可选)
register_uninstall_hook(__FILE__, 'smm_uninstall_plugin');

function smm_uninstall_plugin() {
    global $wpdb;
    
    // 如果需要在卸载时删除表,取消下面的注释
    /*
    $table_name_materials = $wpdb->prefix . 'smm_materials';
    $table_name_usage = $wpdb->prefix . 'smm_material_usage';
    
    $wpdb->query("DROP TABLE IF EXISTS $table_name_usage");
    $wpdb->query("DROP TABLE IF EXISTS $table_name_materials");
    */
}
?>

管理界面与功能实现

接下来,我们创建管理界面,让用户可以添加、查看和编辑尾料信息。

<?php
// 注册管理菜单
function smm_register_admin_menus() {
    // 主菜单
    add_menu_page(
        '尾料管理系统',           // 页面标题
        '尾料管理',               // 菜单标题
        'manage_options',         // 权限要求
        'scrap-material-manager', // 菜单slug
        'smm_dashboard_page',     // 回调函数
        'dashicons-database',     // 图标
        30                        // 菜单位置
    );
    
    // 子菜单
    add_submenu_page(
        'scrap-material-manager',
        '尾料库存',
        '尾料库存',
        'manage_options',
        'smm-materials',
        'smm_materials_page'
    );
    
    add_submenu_page(
        'scrap-material-manager',
        '添加新尾料',
        '添加新尾料',
        'manage_options',
        'smm-add-material',
        'smm_add_material_page'
    );
    
    add_submenu_page(
        'scrap-material-manager',
        '使用记录',
        '使用记录',
        'manage_options',
        'smm-usage-history',
        'smm_usage_history_page'
    );
    
    add_submenu_page(
        'scrap-material-manager',
        '智能匹配',
        '智能匹配',
        'manage_options',
        'smm-smart-match',
        'smm_smart_match_page'
    );
}

// 仪表板页面
function smm_dashboard_page() {
    ?>
    <div class="wrap">
        <h1>尾料管理系统仪表板</h1>
        
        <div class="smm-dashboard-stats">
            <?php
            global $wpdb;
            $table_name = $wpdb->prefix . 'smm_materials';
            
            // 获取统计信息
            $total_materials = $wpdb->get_var("SELECT COUNT(*) FROM $table_name");
            $available_materials = $wpdb->get_var("SELECT COUNT(*) FROM $table_name WHERE status = 'available'");
            $used_materials = $wpdb->get_var("SELECT COUNT(*) FROM $table_name WHERE status = 'used'");
            $total_quantity = $wpdb->get_var("SELECT SUM(quantity) FROM $table_name WHERE status = 'available'");
            
            // 按类型统计
            $materials_by_type = $wpdb->get_results("
                SELECT material_type, COUNT(*) as count, SUM(quantity) as total_quantity 
                FROM $table_name 
                WHERE status = 'available' 
                GROUP BY material_type
            ");
            ?>
            
            <div class="smm-stat-cards">
                <div class="smm-stat-card">
                    <h3>总尾料种类</h3>
                    <p class="stat-number"><?php echo esc_html($total_materials); ?></p>
                </div>
                
                <div class="smm-stat-card">
                    <h3>可用尾料</h3>
                    <p class="stat-number"><?php echo esc_html($available_materials); ?></p>
                </div>
                
                <div class="smm-stat-card">
                    <h3>已用尾料</h3>
                    <p class="stat-number"><?php echo esc_html($used_materials); ?></p>
                </div>
                
                <div class="smm-stat-card">
                    <h3>可用总量</h3>
                    <p class="stat-number"><?php echo esc_html(number_format($total_quantity, 2)); ?></p>
                </div>
            </div>
            
            <h2>按类型统计</h2>
            <table class="wp-list-table widefat fixed striped">
                <thead>
                    <tr>
                        <th>材料类型</th>
                        <th>种类数量</th>
                        <th>总数量</th>
                    </tr>
                </thead>
                <tbody>
                    <?php foreach ($materials_by_type as $type): ?>
                    <tr>
                        <td><?php echo esc_html($type->material_type); ?></td>
                        <td><?php echo esc_html($type->count); ?></td>
                        <td><?php echo esc_html(number_format($type->total_quantity, 2)); ?></td>
                    </tr>
                    <?php endforeach; ?>
                </tbody>
            </table>
        </div>
    </div>
    
    <style>
    .smm-stat-cards {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
        gap: 20px;
        margin: 20px 0;
    }
    
    .smm-stat-card {
        background: #fff;
        border: 1px solid #ccd0d4;
        border-radius: 4px;
        padding: 20px;
        text-align: center;
        box-shadow: 0 1px 3px rgba(0,0,0,0.1);
    }
    
    .smm-stat-card h3 {
        margin-top: 0;
        color: #555;
        font-size: 14px;
        text-transform: uppercase;
    }
    
    .smm-stat-card .stat-number {
        font-size: 32px;
        font-weight: bold;
        color: #0073aa;
        margin: 10px 0;
    }
    </style>
    <?php
}

// 添加新尾料页面
function smm_add_material_page() {
    // 处理表单提交
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['smm_add_material'])) {
        $result = smm_process_add_material($_POST);
        
        if ($result['success']) {
            echo '<div class="notice notice-success"><p>' . esc_html($result['message']) . '</p></div>';
        } else {
            echo '<div class="notice notice-error"><p>' . esc_html($result['message']) . '</p></div>';
        }
    }
    ?>
    
    <div class="wrap">
        <h1>添加新尾料</h1>
        
        <form method="post" action="">
            <?php wp_nonce_field('smm_add_material_action', 'smm_add_material_nonce'); ?>
            
            <table class="form-table">
                <tr>
                    <th scope="row"><label for="material_name">材料名称 *</label></th>
                    <td><input type="text" id="material_name" name="material_name" required class="regular-text"></td>
                </tr>
                
                <tr>
                    <th scope="row"><label for="material_type">材料类型 *</label></th>
                    <td>
                        <select id="material_type" name="material_type" required>
                            <option value="">选择类型</option>
                            <option value="木材">木材</option>
                            <option value="金属">金属</option>
                            <option value="塑料">塑料</option>
                            <option value="布料">布料</option>
                            <option value="皮革">皮革</option>
                            <option value="其他">其他</option>
                        </select>
                        <input type="text" id="custom_material_type" name="custom_material_type" placeholder="或输入自定义类型" class="regular-text" style="margin-left: 10px; display: none;">
                    </td>
                </tr>
                
                <tr>
                    <th scope="row"><label for="quantity">数量 *</label></th>
                    <td>
                        <input type="number" id="quantity" name="quantity" step="0.01" min="0" required>
                        <select id="unit" name="unit" style="margin-left: 10px;">
                            <option value="米">米</option>
                            <option value="千克">千克</option>
                            <option value="平方米">平方米</option>
                            <option value="件">件</option>
                            <option value="其他">其他</option>
                        </select>
                        <input type="text" id="custom_unit" name="custom_unit" placeholder="自定义单位" class="regular-text" style="margin-left: 10px; display: none;">
                    </td>
                </tr>
                
                <tr>
                    <th scope="row"><label>尺寸 (可选)</label></th>
                    <td>
                        长: <input type="number" name="length" step="0.01" min="0" style="width: 80px;"> 厘米
                        宽: <input type="number" name="width" step="0.01" min="0" style="width: 80px; margin-left: 10px;"> 厘米
                        高: <input type="number" name="height" step="0.01" min="0" style="width: 80px; margin-left: 10px;"> 厘米
                    </td>
                </tr>
                
                <tr>
                    <th scope="row"><label for="color">颜色 (可选)</label></th>
                    <td><input type="text" id="color" name="color" class="regular-text"></td>
                </tr>
                
                <tr>
                    <th scope="row"><label for="location">存放位置</label></th>
                    <td><input type="text" id="location" name="location" class="regular-text"></td>
                </tr>
                
                <tr>
                    <th scope="row"><label for="notes">备注</label></th>
                    <td><textarea id="notes" name="notes" rows="3" class="large-text"></textarea></td>
                </tr>
            </table>
            
            <p class="submit">
                <input type="submit" name="smm_add_material" class="button button-primary" value="添加尾料">
            </p>
        </form>
    </div>
    
    <script>
    jQuery(document).ready(function($) {
        // 显示/隐藏自定义材料类型输入框
        $('#material_type').change(function() {
            if ($(this).val() === '其他') {
                $('#custom_material_type').show().focus();
            } else {
                $('#custom_material_type').hide();
            }
        });
        
        // 显示/隐藏自定义单位输入框
        $('#unit').change(function() {
            if ($(this).val() === '其他') {
                $('#custom_unit').show().focus();
            } else {
                $('#custom_unit').hide();
            }
        });
    });
    </script>
    <?php
}

// 处理添加尾料表单
function smm_process_add_material($data) {
    // 验证nonce
    if (!isset($data['smm_add_material_nonce']) || 
        !wp_verify_nonce($data['smm_add_material_nonce'], 'smm_add_material_action')) {
        return ['success' => false, 'message' => '安全验证失败'];
    }
    
    // 验证权限
    if (!current_user_can('manage_options')) {
        return ['success' => false, 'message' => '权限不足'];
    }
    
    global $wpdb;
    $table_name = $wpdb->prefix . 'smm_materials';
    
    // 准备数据
    $material_type = sanitize_text_field($data['material_type']);
    if ($material_type === '其他' && !empty($data['custom_material_type'])) {
        $material_type = sanitize_text_field($data['custom_material_type']);
    }
    
    $unit = sanitize_text_field($data['unit']);
    if ($unit === '其他' && !empty($data['custom_unit'])) {
        $unit = sanitize_text_field($data['custom_unit']);
    }
    
    $insert_data = [
        'material_name' => sanitize_text_field($data['material_name']),
        'material_type' => $material_type,
        'quantity' => floatval($data['quantity']),
        'unit' => $unit,
        'width' => !empty($data['width']) ? floatval($data['width']) : NULL,
        'height' => !empty($data['height']) ? floatval($data['height']) : NULL,
        'length' => !empty($data['length']) ? floatval($data['length']) : NULL,
        'color' => !empty($data['color']) ? sanitize_text_field($data['color']) : NULL,
        'location' => !empty($data['location']) ? sanitize_text_field($data['location']) : NULL,
        'notes' => !empty($data['notes']) ? sanitize_textarea_field($data['notes']) : NULL,
        'status' => 'available'
    ];
    
    // 插入数据库
    $result = $wpdb->insert($table_name, $insert_data);
    
    if ($result) {

_id];

} else {
    return ['success' => false, 'message' => '添加失败:' . $wpdb->last_error];
}

}
?>


## 尾料库存管理界面

现在创建尾料库存列表页面,显示所有尾料并支持搜索、筛选和操作。

<?php
// 尾料库存页面
function smm_materials_page() {

global $wpdb;
$table_name = $wpdb->prefix . 'smm_materials';

// 处理操作(删除、标记为已用等)
if (isset($_GET['action']) && isset($_GET['id'])) {
    $id = intval($_GET['id']);
    $nonce = isset($_GET['_wpnonce']) ? $_GET['_wpnonce'] : '';
    
    if ($_GET['action'] === 'delete' && wp_verify_nonce($nonce, 'delete_material_' . $id)) {
        $wpdb->delete($table_name, ['id' => $id]);
        echo '<div class="notice notice-success"><p>尾料已删除</p></div>';
    } elseif ($_GET['action'] === 'mark_used' && wp_verify_nonce($nonce, 'mark_used_' . $id)) {
        $wpdb->update($table_name, ['status' => 'used'], ['id' => $id]);
        echo '<div class="notice notice-success"><p>尾料已标记为已使用</p></div>';
    } elseif ($_GET['action'] === 'mark_available' && wp_verify_nonce($nonce, 'mark_available_' . $id)) {
        $wpdb->update($table_name, ['status' => 'available'], ['id' => $id]);
        echo '<div class="notice notice-success"><p>尾料已标记为可用</p></div>';
    }
}

// 构建查询
$where = [];
$query_params = [];

// 搜索功能
if (!empty($_GET['s'])) {
    $search = sanitize_text_field($_GET['s']);
    $where[] = "(material_name LIKE %s OR material_type LIKE %s OR color LIKE %s OR location LIKE %s)";
    $like = '%' . $wpdb->esc_like($search) . '%';
    $query_params = array_merge($query_params, [$like, $like, $like, $like]);
}

// 状态筛选
if (!empty($_GET['status']) && in_array($_GET['status'], ['available', 'used'])) {
    $where[] = "status = %s";
    $query_params[] = $_GET['status'];
}

// 类型筛选
if (!empty($_GET['type'])) {
    $where[] = "material_type = %s";
    $query_params[] = sanitize_text_field($_GET['type']);
}

// 构建WHERE子句
$where_sql = '';
if (!empty($where)) {
    $where_sql = 'WHERE ' . implode(' AND ', $where);
}

// 获取材料类型用于筛选
$material_types = $wpdb->get_col("SELECT DISTINCT material_type FROM $table_name ORDER BY material_type");

// 分页设置
$items_per_page = 20;
$current_page = isset($_GET['paged']) ? max(1, intval($_GET['paged'])) : 1;
$offset = ($current_page - 1) * $items_per_page;

// 获取总数
$count_query = "SELECT COUNT(*) FROM $table_name $where_sql";
if (!empty($query_params)) {
    $count_query = $wpdb->prepare($count_query, $query_params);
}
$total_items = $wpdb->get_var($count_query);
$total_pages = ceil($total_items / $items_per_page);

// 获取数据
$query = "SELECT * FROM $table_name $where_sql ORDER BY created_at DESC LIMIT %d OFFSET %d";
$query_params_page = $query_params;
$query_params_page[] = $items_per_page;
$query_params_page[] = $offset;

$materials = $wpdb->get_results($wpdb->prepare($query, $query_params_page));
?>

<div class="wrap">
    <h1>尾料库存</h1>
    
    <!-- 搜索和筛选表单 -->
    <div class="smm-filters">
        <form method="get" action="">
            <input type="hidden" name="page" value="smm-materials">
            
            <div class="tablenav top">
                <div class="alignleft actions">
                    <!-- 搜索框 -->
                    <input type="text" name="s" value="<?php echo isset($_GET['s']) ? esc_attr($_GET['s']) : ''; ?>" placeholder="搜索材料名称、类型、颜色或位置">
                    
                    <!-- 状态筛选 -->
                    <select name="status">
                        <option value="">所有状态</option>
                        <option value="available" <?php selected(isset($_GET['status']) && $_GET['status'] === 'available'); ?>>可用</option>
                        <option value="used" <?php selected(isset($_GET['status']) && $_GET['status'] === 'used'); ?>>已用</option>
                    </select>
                    
                    <!-- 类型筛选 -->
                    <select name="type">
                        <option value="">所有类型</option>
                        <?php foreach ($material_types as $type): ?>
                        <option value="<?php echo esc_attr($type); ?>" <?php selected(isset($_GET['type']) && $_GET['type'] === $type); ?>>
                            <?php echo esc_html($type); ?>
                        </option>
                        <?php endforeach; ?>
                    </select>
                    
                    <input type="submit" class="button" value="筛选">
                    
                    <?php if (!empty($_GET['s']) || !empty($_GET['status']) || !empty($_GET['type'])): ?>
                    <a href="?page=smm-materials" class="button">清除筛选</a>
                    <?php endif; ?>
                </div>
                
                <div class="alignright">
                    <a href="?page=smm-add-material" class="button button-primary">添加新尾料</a>
                </div>
            </div>
        </form>
    </div>
    
    <!-- 材料列表表格 -->
    <table class="wp-list-table widefat fixed striped">
        <thead>
            <tr>
                <th>ID</th>
                <th>材料名称</th>
                <th>类型</th>
                <th>数量</th>
                <th>尺寸</th>
                <th>颜色</th>
                <th>位置</th>
                <th>状态</th>
                <th>添加日期</th>
                <th>操作</th>
            </tr>
        </thead>
        <tbody>
            <?php if (empty($materials)): ?>
            <tr>
                <td colspan="10" style="text-align: center;">未找到尾料记录</td>
            </tr>
            <?php else: ?>
            <?php foreach ($materials as $material): ?>
            <tr>
                <td><?php echo esc_html($material->id); ?></td>
                <td>
                    <strong><?php echo esc_html($material->material_name); ?></strong>
                    <?php if (!empty($material->notes)): ?>
                    <br><small><?php echo esc_html(substr($material->notes, 0, 50)); ?>...</small>
                    <?php endif; ?>
                </td>
                <td><?php echo esc_html($material->material_type); ?></td>
                <td><?php echo esc_html(number_format($material->quantity, 2)); ?> <?php echo esc_html($material->unit); ?></td>
                <td>
                    <?php if ($material->length || $material->width || $material->height): ?>
                    <?php 
                    $dimensions = [];
                    if ($material->length) $dimensions[] = '长: ' . $material->length . 'cm';
                    if ($material->width) $dimensions[] = '宽: ' . $material->width . 'cm';
                    if ($material->height) $dimensions[] = '高: ' . $material->height . 'cm';
                    echo esc_html(implode(', ', $dimensions));
                    ?>
                    <?php else: ?>
                    -
                    <?php endif; ?>
                </td>
                <td><?php echo esc_html($material->color ?: '-'); ?></td>
                <td><?php echo esc_html($material->location ?: '-'); ?></td>
                <td>
                    <span class="smm-status smm-status-<?php echo esc_attr($material->status); ?>">
                        <?php echo $material->status === 'available' ? '可用' : '已用'; ?>
                    </span>
                </td>
                <td><?php echo esc_html(date('Y-m-d', strtotime($material->created_at))); ?></td>
                <td>
                    <div class="row-actions">
                        <a href="?page=smm-add-material&edit=<?php echo esc_attr($material->id); ?>">编辑</a> | 
                        
                        <?php if ($material->status === 'available'): ?>
                        <a href="?page=smm-materials&action=mark_used&id=<?php echo esc_attr($material->id); ?>&_wpnonce=<?php echo wp_create_nonce('mark_used_' . $material->id); ?>" 
                           onclick="return confirm('标记为已使用?')">标记为已用</a> | 
                        <?php else: ?>
                        <a href="?page=smm-materials&action=mark_available&id=<?php echo esc_attr($material->id); ?>&_wpnonce=<?php echo wp_create_nonce('mark_available_' . $material->id); ?>" 
                           onclick="return confirm('标记为可用?')">标记为可用</a> | 
                        <?php endif; ?>
                        
                        <a href="?page=smm-usage-history&material_id=<?php echo esc_attr($material->id); ?>">使用记录</a> | 
                        
                        <a href="?page=smm-materials&action=delete&id=<?php echo esc_attr($material->id); ?>&_wpnonce=<?php echo wp_create_nonce('delete_material_' . $material->id); ?>" 
                           class="delete" onclick="return confirm('确定删除这条记录?')">删除</a>
                    </div>
                </td>
            </tr>
            <?php endforeach; ?>
            <?php endif; ?>
        </tbody>
    </table>
    
    <!-- 分页 -->
    <div class="tablenav bottom">
        <div class="tablenav-pages">
            <?php
            $page_links = paginate_links([
                'base' => add_query_arg('paged', '%#%'),
                'format' => '',
                'prev_text' => '&laquo;',
                'next_text' => '&raquo;',
                'total' => $total_pages,
                'current' => $current_page,
            ]);
            
            if ($page_links) {
                echo '<span class="displaying-num">' . sprintf('显示 %d 条中的 %d-%d 条', $total_items, $offset + 1, min($offset + $items_per_page, $total_items)) . '</span>';
                echo '<span class="pagination-links">' . $page_links . '</span>';
            }
            ?>
        </div>
    </div>
</div>

<style>
.smm-status {
    padding: 3px 8px;
    border-radius: 3px;
    font-size: 12px;
    font-weight: bold;
}

.smm-status-available {
    background-color: #d4edda;
    color: #155724;
}

.smm-status-used {
    background-color: #f8d7da;
    color: #721c24;
}

.row-actions {
    font-size: 12px;
    color: #ddd;
}

.row-actions a {
    color: #0073aa;
    text-decoration: none;
}

.row-actions a:hover {
    color: #00a0d2;
    text-decoration: underline;
}

.row-actions .delete {
    color: #a00;
}

.row-actions .delete:hover {
    color: #dc3232;
}
</style>
<?php

}
?>


## 智能匹配功能实现

智能匹配是尾料利用的核心功能,可以根据项目需求自动推荐合适的尾料。

<?php
// 智能匹配页面
function smm_smart_match_page() {

global $wpdb;
$table_name = $wpdb->prefix . 'smm_materials';

$matched_materials = [];

// 处理匹配请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['smm_find_match'])) {
    $requirements = [
        'material_type' => sanitize_text_field($_POST['material_type']),
        'min_quantity' => floatval($_POST['min_quantity']),
        'unit' => sanitize_text_field($_POST['unit']),
        'max_width' => !empty($_POST['max_width']) ? floatval($_POST['max_width']) : null,
        'max_length' => !empty($_POST['max_length']) ? floatval($_POST['max_length']) : null,
        'color' => !empty($_POST['color']) ? sanitize_text_field($_POST['color']) : null,
    ];
    
    // 构建匹配查询
    $query = "SELECT * FROM $table_name WHERE status = 'available'";
    $query_params = [];
    
    // 材料类型匹配
    if (!empty($requirements['material_type'])) {
        $query .= " AND material_type = %s";
        $query_params[] = $requirements['material_type'];
    }
    
    // 数量匹配(至少满足最小需求)
    if ($requirements['min_quantity'] > 0) {
        $query .= " AND quantity >= %f";
        $query_params[] = $requirements['min_quantity'];
    }
    
    // 单位转换(简化版,实际应用中可能需要更复杂的转换逻辑)
    // 这里假设相同单位直接比较
    
    // 尺寸匹配
    if ($requirements['max_width'] > 0) {
        $query .= " AND (width IS NULL OR width <= %f)";
        $query_params[] = $requirements['max_width'];
    }
    
    if ($requirements['max_length'] > 0) {
        $query .= " AND (length IS NULL OR length <= %f)";
        $query_params[] = $requirements['max_length'];
    }
    
    // 颜色匹配(模糊匹配)
    if (!empty($requirements['color'])) {
        $query .= " AND (color LIKE %s OR color IS NULL)";
        $query_params[] = '%' . $wpdb->esc_like($requirements['color']) . '%';
    }
    
    $query .= " ORDER BY 
        CASE WHEN color LIKE %s THEN 0 ELSE 1 END, -- 颜色完全匹配优先
        quantity DESC, -- 数量多的优先
        created_at ASC -- 先入库的先使用
    ";
    
    $query_params[] = $requirements['color'];
    
    // 执行查询
    if (!empty($query_params)) {
        $matched_materials = $wpdb->get_results($wpdb->prepare($query, $query_params));
    } else {
        $matched_materials = $wpdb->get_results($query);
    }
}

// 获取所有材料类型用于下拉选择
$material_types = $wpdb->get_col("SELECT DISTINCT material_type FROM $table_name WHERE status = 'available' ORDER BY material_type");
?>

<div class="wrap">
    <h1>智能尾料匹配</h1>
    
    <div class="smm-smart-match-container">
        <div class="smm-requirements-form">
            <h2>项目需求</h2>
            <form method="post" action="">
                <table class="form-table">
                    <tr>
                        <th scope="row"><label for="match_material_type">材料类型</label></th>
                        <td>
                            <select id="match_material_type" name="material_type">
                                <option value="">任何类型</option>
                                <?php foreach ($material_types as $type): ?>
                                <option value="<?php echo esc_attr($type); ?>" <?php selected(isset($_POST['material_type']) && $_POST['material_type'] === $type); ?>>
                                    <?php echo esc_html($type); ?>
                                </option>
                                <?php endforeach; ?>
                            </select>
                        </td>
                    </tr>
                    
                    <tr>
                        <th scope="row"><label for="min_quantity">最小数量</label></th>
                        <td>
                            <input type="number" id="min_quantity" name="min_quantity" step="0.01" min="0" 
                                   value="<?php echo isset($_POST['min_quantity']) ? esc_attr($_POST['min_quantity']) : ''; ?>">
                            <select name="unit" style="margin-left: 10px;">
                                <option value="米" <?php selected(isset($_POST['unit']) && $_POST['unit'] === '米'); ?>>米</option>
                                <option value="千克" <?php selected(isset($_POST['unit']) && $_POST['unit'] === '千克'); ?>>千克</option>
                                <option value="平方米" <?php selected(isset($_POST['unit']) && $_POST['unit'] === '平方米'); ?>>平方米</option>
                                <option value="件" <?php selected(isset($_POST['unit']) && $_POST['unit'] === '件'); ?>>件</option>
                            </select>
                        </td>
                    </tr>
                    
                    <tr>
                        <th scope="row"><label>最大尺寸限制 (可选)</label></th>
                        <td>
                            长: <input type="number" name="max_length" step="0.01" min="0" 
                                     value="<?php echo isset($_POST['max_length']) ? esc_
本文来自网络投稿,不代表本站点的立场,转载请注明出处:https://www.gongxiangcang.com/6599.html

溯源库®作者

漳州柔性供应链服务有限公司 小批量订单定制化服务商( 投稿邮箱:vip@jiaochengku.com)
上一篇
下一篇

为您推荐

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@suyuanku.com

工作时间:周一至周五,9:00-17:30,节假日休息
关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部