文章目录
-
- 在电子商务运营中,成本核算是至关重要的环节。对于使用WordPress搭建的电商网站,特别是处理小批量定制产品的商家,实时核算成本能帮助您更精准地定价、控制利润。本教程将指导您开发一个WordPress插件,实现小批量定制产品的成本实时核算功能。
- 我们的插件将实现以下核心功能: 在商品编辑页面添加成本核算字段 根据用户选择的定制选项实时计算成本 在前端产品页面显示实时成本估算 管理员后台查看成本分析报告
- 首先,我们创建插件的基本文件结构: wp-content/plugins/cost-calculator/ ├── cost-calculator.php ├── includes/ │ ├── admin/ │ │ ├── class-admin-settings.php │ │ └── class-product-metabox.php │ ├── frontend/ │ │ ├── class-frontend-display.php │ │ └── class-ajax-handler.php │ └── class-cost-calculator.php ├── assets/ │ ├── css/ │ │ └── style.css │ └── js/ │ └── script.js └── README.md
- <?php /** * Plugin Name: 小批量定制成本核算器 * Plugin URI: https://yourwebsite.com/ * Description: 为WordPress小批量定制产品提供实时成本核算功能 * Version: 1.0.0 * Author: 您的名称 * License: GPL v2 or later * Text Domain: cost-calculator */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('COST_CALCULATOR_VERSION', '1.0.0'); define('COST_CALCULATOR_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('COST_CALCULATOR_PLUGIN_URL', plugin_dir_url(__FILE__)); // 自动加载类文件 spl_autoload_register(function ($class_name) { $prefix = 'Cost_Calculator_'; $base_dir = COST_CALCULATOR_PLUGIN_DIR . 'includes/'; // 检查类是否使用我们的命名空间前缀 $len = strlen($prefix); if (strncmp($prefix, $class_name, $len) !== 0) { return; } // 获取相对类名 $relative_class = substr($class_name, $len); // 将命名空间分隔符替换为目录分隔符 $file = $base_dir . str_replace('_', '/', $relative_class) . '.php'; // 如果文件存在,则加载它 if (file_exists($file)) { require $file; } }); // 初始化插件 function cost_calculator_init() { // 检查WooCommerce是否激活 if (!class_exists('WooCommerce')) { add_action('admin_notices', function() { echo '<div class="notice notice-error"><p>'; echo __('成本核算插件需要WooCommerce支持,请先安装并激活WooCommerce插件。', 'cost-calculator'); echo '</p></div>'; }); return; } // 初始化主类 $plugin = new Cost_Calculator_Main(); $plugin->run(); } add_action('plugins_loaded', 'cost_calculator_init'); // 插件激活时的操作 register_activation_hook(__FILE__, 'cost_calculator_activate'); function cost_calculator_activate() { // 创建必要的数据库表 global $wpdb; $charset_collate = $wpdb->get_charset_collate(); $table_name = $wpdb->prefix . 'cost_calculator_logs'; $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id mediumint(9) NOT NULL AUTO_INCREMENT, product_id mediumint(9) NOT NULL, base_cost decimal(10,2) NOT NULL, material_cost decimal(10,2) NOT NULL, labor_cost decimal(10,2) NOT NULL, additional_cost decimal(10,2) NOT NULL, total_cost decimal(10,2) NOT NULL, quantity int(11) NOT NULL, calculated_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); // 设置默认选项 add_option('cost_calculator_version', COST_CALCULATOR_VERSION); add_option('cost_calculator_profit_margin', '30'); // 默认利润率30% } // 插件停用时的清理操作 register_deactivation_hook(__FILE__, 'cost_calculator_deactivate'); function cost_calculator_deactivate() { // 清理临时数据,保留日志表 delete_option('cost_calculator_temp_data'); } ?>
- <?php // includes/admin/class-product-metabox.php class Cost_Calculator_Product_Metabox { public function __construct() { add_action('add_meta_boxes', array($this, 'add_cost_metabox')); add_action('save_post_product', array($this, 'save_cost_data')); } // 添加成本核算元数据框 public function add_cost_metabox() { add_meta_box( 'cost_calculator_metabox', __('成本核算设置', 'cost-calculator'), array($this, 'render_metabox'), 'product', 'side', 'high' ); } // 渲染元数据框内容 public function render_metabox($post) { // 添加安全验证 wp_nonce_field('cost_calculator_save_data', 'cost_calculator_nonce'); // 获取现有值 $base_cost = get_post_meta($post->ID, '_base_cost', true); $material_options = get_post_meta($post->ID, '_material_options', true); $labor_cost_per_unit = get_post_meta($post->ID, '_labor_cost_per_unit', true); // 解析材料选项 $materials = $material_options ? json_decode($material_options, true) : array(); ?> <div class="cost-calculator-fields"> <p> <label for="base_cost"><?php _e('基础成本 (元):', 'cost-calculator'); ?></label> <input type="number" step="0.01" min="0" id="base_cost" name="base_cost" value="<?php echo esc_attr($base_cost); ?>" style="width: 100%;"> </p> <p> <label for="labor_cost_per_unit"><?php _e('单位人工成本 (元):', 'cost-calculator'); ?></label> <input type="number" step="0.01" min="0" id="labor_cost_per_unit" name="labor_cost_per_unit" value="<?php echo esc_attr($labor_cost_per_unit); ?>" style="width: 100%;"> </p> <hr> <h4><?php _e('材料选项', 'cost-calculator'); ?></h4> <div id="material-options-container"> <?php if (!empty($materials)): ?> <?php foreach ($materials as $index => $material): ?> <div class="material-option"> <input type="text" name="material_names[]" value="<?php echo esc_attr($material['name']); ?>" placeholder="材料名称" style="width: 48%;"> <input type="number" step="0.01" min="0" name="material_costs[]" value="<?php echo esc_attr($material['cost']); ?>" placeholder="成本" style="width: 48%;"> </div> <?php endforeach; ?> <?php else: ?> <div class="material-option"> <input type="text" name="material_names[]" placeholder="材料名称" style="width: 48%;"> <input type="number" step="0.01" min="0" name="material_costs[]" placeholder="成本" style="width: 48%;"> </div> <?php endif; ?> </div> <button type="button" id="add-material-option" class="button"> <?php _e('添加材料选项', 'cost-calculator'); ?> </button> <script> jQuery(document).ready(function($) { $('#add-material-option').click(function() { $('#material-options-container').append( '<div class="material-option" style="margin-top: 5px;">' + '<input type="text" name="material_names[]" placeholder="材料名称" style="width: 48%;">' + '<input type="number" step="0.01" min="0" name="material_costs[]" placeholder="成本" style="width: 48%;">' + '</div>' ); }); }); </script> </div> <?php } // 保存成本数据 public function save_cost_data($post_id) { // 检查非ce、自动保存和用户权限 if (!isset($_POST['cost_calculator_nonce']) || !wp_verify_nonce($_POST['cost_calculator_nonce'], 'cost_calculator_save_data') || defined('DOING_AUTOSAVE') && DOING_AUTOSAVE || !current_user_can('edit_post', $post_id)) { return; } // 保存基础成本 if (isset($_POST['base_cost'])) { update_post_meta($post_id, '_base_cost', sanitize_text_field($_POST['base_cost'])); } // 保存人工成本 if (isset($_POST['labor_cost_per_unit'])) { update_post_meta($post_id, '_labor_cost_per_unit', sanitize_text_field($_POST['labor_cost_per_unit'])); } // 保存材料选项 if (isset($_POST['material_names']) && isset($_POST['material_costs'])) { $materials = array(); $names = $_POST['material_names']; $costs = $_POST['material_costs']; for ($i = 0; $i < count($names); $i++) { if (!empty($names[$i]) && !empty($costs[$i])) { $materials[] = array( 'name' => sanitize_text_field($names[$i]), 'cost' => floatval($costs[$i]) ); } } update_post_meta($post_id, '_material_options', json_encode($materials)); } } } ?>
- <?php // includes/frontend/class-frontend-display.php class Cost_Calculator_Frontend_Display { public function __construct() { add_action('woocommerce_before_add_to_cart_button', array($this, 'display_cost_calculator')); add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts')); } // 在前端产品页面显示成本计算器 public function display_cost_calculator() { global $product; if (!$product || !$product->is_type('simple')) { return; } $product_id = $product->get_id(); $base_cost = get_post_meta($product_id, '_base_cost', true); $labor_cost = get_post_meta($product_id, '_labor_cost_per_unit', true); $material_options = get_post_meta($product_id, '_material_options', true); $materials = $material_options ? json_decode($material_options, true) : array(); if (empty($base_cost) && empty($labor_cost) && empty($materials)) { return; } ?> <div class="cost-calculator-container" style="margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px;"> <h3><?php _e('成本估算器', 'cost-calculator'); ?></h3> <div class="calculator-fields"> <!-- 数量选择 --> <div class="form-row"> <label for="quantity"><?php _e('数量:', 'cost-calculator'); ?></label> <input type="number" id="cost-quantity" name="cost_quantity" min="1" max="100" value="1" style="width: 80px;"> </div> <!-- 材料选择 --> <?php if (!empty($materials)): ?> <div class="form-row"> <label for="material-select"><?php _e('选择材料:', 'cost-calculator'); ?></label> <select id="material-select" name="cost_material" style="width: 200px;"> <option value="0"><?php _e('-- 请选择 --', 'cost-calculator'); ?></option> <?php foreach ($materials as $index => $material): ?> <option value="<?php echo esc_attr($material['cost']); ?>" data-index="<?php echo $index; ?>"> <?php echo esc_html($material['name']); ?> (<?php echo wc_price($material['cost']); ?>) </option> <?php endforeach; ?> </select> </div> <?php endif; ?> <!-- 额外成本 --> <div class="form-row"> <label for="additional-cost"><?php _e('额外成本 (元):', 'cost-calculator'); ?></label> <input type="number" id="additional-cost" name="additional_cost" step="0.01" min="0" value="0" style="width: 100px;"> <small><?php _e('如包装、特殊处理等', 'cost-calculator'); ?></small> </div> <!-- 计算结果 --> <div class="cost-result" style="margin-top: 15px; padding: 10px; background-color: #f8f9fa; border-radius: 3px;"> <h4><?php _e('成本估算结果:', 'cost-calculator'); ?></h4> <div id="cost-breakdown"> <p><?php _e('请选择选项以查看成本估算', 'cost-calculator'); ?></p> </div> <div id="total-cost" style="font-weight: bold; font-size: 1.2em; color: #d35400;"></div> </div> <!-- 隐藏字段存储产品数据 --> <input type="hidden" id="product-base-cost" value="<?php echo esc_attr($base_cost); ?>"> <input type="hidden" id="product-labor-cost" value="<?php echo esc_attr($labor_cost); ?>"> </div> </div> <script type="text/javascript"> jQuery(document).ready(function($) { // 获取利润率设置 var profitMargin = <?php echo get_option('cost_calculator_profit_margin', '30'); ?>; // 计算成本函数 function calculateCost() { var quantity = parseInt($('#cost-quantity').val()) || 1; var baseCost = parseFloat($('#product-base-cost').val()) || 0; var laborCost = parseFloat($('#product-labor-cost').val()) || 0; var materialCost = parseFloat($('#material-select').val()) || 0; var additionalCost = parseFloat($('#additional-cost').val()) || 0; // 计算各项成本 var totalBaseCost = baseCost * quantity; var totalLaborCost = laborCost * quantity; var totalMaterialCost = materialCost * quantity; var totalAdditionalCost = additionalCost; // 总成本 var totalCost = totalBaseCost + totalLaborCost + totalMaterialCost + totalAdditionalCost; // 建议售价(包含利润) var suggestedPrice = totalCost * (1 + profitMargin / 100); // 更新显示 $('#cost-breakdown').html( '<p>基础成本: ' + totalBaseCost.toFixed(2) + ' 元</p>' + '<p>人工成本: ' + totalLaborCost.toFixed(2) + ' 元</p>' + '<p>材料成本: ' + totalMaterialCost.toFixed(2) + ' 元</p>' + '<p>额外成本: ' + totalAdditionalCost.toFixed(2) + ' 元</p>' ); $('#total-cost').html( '总成本: ' + totalCost.toFixed(2) + ' 元<br>' + '建议售价 (利润率 ' + profitMargin + '%): ' + suggestedPrice.toFixed(2) + ' 元' ); // 保存计算记录到数据库 saveCostCalculation({ product_id: <?php echo $product_id; ?>, base_cost: baseCost, labor_cost: laborCost, material_cost: materialCost, additional_cost: additionalCost, total_cost: totalCost, quantity: quantity }); } // 保存计算记录到数据库 function saveCostCalculation(data) { $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action: 'save_cost_calculation', nonce: '<?php echo wp_create_nonce('cost_calculator_ajax'); ?>', calculation_data: data } }); } // 绑定事件监听 // 页面加载时计算一次 calculateCost(); }); </script> <?php } // 加载前端脚本和样式 public function enqueue_scripts() { if (is_product()) { wp_enqueue_style( 'cost-calculator-frontend', COST_CALCULATOR_PLUGIN_URL . 'assets/css/style.css', array(), COST_CALCULATOR_VERSION ); wp_enqueue_script( 'cost-calculator-frontend', COST_CALCULATOR_PLUGIN_URL . 'assets/js/script.js', array('jquery'), COST_CALCULATOR_VERSION, true ); // 传递数据到JavaScript wp_localize_script('cost-calculator-frontend', 'costCalculator', array( 'ajax_url' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce('cost_calculator_frontend') )); } } }?> ## AJAX处理程序 <?php// includes/frontend/class-ajax-handler.php class Cost_Calculator_Ajax_Handler { public function __construct() { add_action('wp_ajax_save_cost_calculation', array($this, 'save_calculation')); add_action('wp_ajax_nopriv_save_cost_calculation', array($this, 'save_calculation')); add_action('wp_ajax_get_cost_report', array($this, 'get_cost_report')); } // 保存成本计算记录 public function save_calculation() { // 验证nonce if (!wp_verify_nonce($_POST['nonce'], 'cost_calculator_ajax')) { wp_die('安全验证失败'); } global $wpdb; $table_name = $wpdb->prefix . 'cost_calculator_logs'; $data = $_POST['calculation_data']; $wpdb->insert( $table_name, array( 'product_id' => intval($data['product_id']), 'base_cost' => floatval($data['base_cost']), 'material_cost' => floatval($data['material_cost']), 'labor_cost' => floatval($data['labor_cost']), 'additional_cost' => floatval($data['additional_cost']), 'total_cost' => floatval($data['total_cost']), 'quantity' => intval($data['quantity']) ), array('%d', '%f', '%f', '%f', '%f', '%f', '%d') ); wp_send_json_success(array('message' => '计算记录已保存')); } // 获取成本报告 public function get_cost_report() { // 验证用户权限 if (!current_user_can('manage_options')) { wp_die('权限不足'); } global $wpdb; $table_name = $wpdb->prefix . 'cost_calculator_logs'; $start_date = isset($_POST['start_date']) ? sanitize_text_field($_POST['start_date']) : date('Y-m-01'); $end_date = isset($_POST['end_date']) ? sanitize_text_field($_POST['end_date']) : date('Y-m-d'); $results = $wpdb->get_results($wpdb->prepare( "SELECT p.post_title as product_name, COUNT(l.id) as calculation_count, AVG(l.total_cost) as avg_cost, SUM(l.total_cost) as total_cost_sum, AVG(l.quantity) as avg_quantity FROM {$table_name} l LEFT JOIN {$wpdb->posts} p ON l.product_id = p.ID WHERE DATE(l.calculated_at) BETWEEN %s AND %s GROUP BY l.product_id ORDER BY calculation_count DESC", $start_date, $end_date )); wp_send_json_success($results); } }?> ## 主控制器类 <?php// includes/class-cost-calculator.php class Cost_Calculator_Main { private $admin_settings; private $product_metabox; private $frontend_display; private $ajax_handler; public function __construct() { // 初始化各个组件 $this->admin_settings = new Cost_Calculator_Admin_Settings(); $this->product_metabox = new Cost_Calculator_Product_Metabox(); $this->frontend_display = new Cost_Calculator_Frontend_Display(); $this->ajax_handler = new Cost_Calculator_Ajax_Handler(); } public function run() { // 注册短代码 add_shortcode('cost_calculator_report', array($this, 'render_report_shortcode')); // 添加管理菜单 add_action('admin_menu', array($this, 'add_admin_menu')); } // 添加管理菜单 public function add_admin_menu() { add_menu_page( __('成本核算', 'cost-calculator'), __('成本核算', 'cost-calculator'), 'manage_options', 'cost-calculator', array($this, 'render_admin_page'), 'dashicons-calculator', 30 ); add_submenu_page( 'cost-calculator', __('成本报告', 'cost-calculator'), __('成本报告', 'cost-calculator'), 'manage_options', 'cost-calculator-reports', array($this, 'render_reports_page') ); } // 渲染管理页面 public function render_admin_page() { ?> <div class="wrap"> <h1><?php _e('成本核算设置', 'cost-calculator'); ?></h1> <form method="post" action="options.php"> <?php settings_fields('cost_calculator_settings'); do_settings_sections('cost_calculator_settings'); submit_button(); ?> </form> <div class="cost-calculator-stats"> <h2><?php _e('统计概览', 'cost-calculator'); ?></h2> <?php global $wpdb; $table_name = $wpdb->prefix . 'cost_calculator_logs'; $total_calculations = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}"); $today_calculations = $wpdb->get_var($wpdb->prepare( "SELECT COUNT(*) FROM {$table_name} WHERE DATE(calculated_at) = %s", date('Y-m-d') )); echo '<p>' . sprintf(__('总计算次数: %d', 'cost-calculator'), $total_calculations) . '</p>'; echo '<p>' . sprintf(__('今日计算次数: %d', 'cost-calculator'), $today_calculations) . '</p>'; ?> </div> </div> <?php } // 渲染报告页面 public function render_reports_page() { ?> <div class="wrap"> <h1><?php _e('成本分析报告', 'cost-calculator'); ?></h1> <div class="report-filters"> <form method="post" id="cost-report-form"> <label for="start_date"><?php _e('开始日期:', 'cost-calculator'); ?></label> <input type="date" id="start_date" name="start_date" value="<?php echo date('Y-m-01'); ?>"> <label for="end_date"><?php _e('结束日期:', 'cost-calculator'); ?></label> <input type="date" id="end_date" name="end_date" value="<?php echo date('Y-m-d'); ?>"> <button type="button" id="generate-report" class="button button-primary"> <?php _e('生成报告', 'cost-calculator'); ?> </button> </form> </div> <div id="report-results" style="margin-top: 20px;"> <table class="wp-list-table widefat fixed striped"> <thead> <tr> <th><?php _e('产品名称', 'cost-calculator'); ?></th> <th><?php _e('计算次数', 'cost-calculator'); ?></th> <th><?php _e('平均成本', 'cost-calculator'); ?></th> <th><?php _e('成本总额', 'cost-calculator'); ?></th> <th><?php _e('平均数量', 'cost-calculator'); ?></th> </tr> </thead> <tbody id="report-data"> <!-- 报告数据将通过AJAX加载 --> </tbody> </table> </div> <script> jQuery(document).ready(function($) { $('#generate-report').click(function() { var formData = $('#cost-report-form').serialize(); $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action: 'get_cost_report', ...formData }, success: function(response) { if (response.success) { var html = ''; $.each(response.data, function(index, item) { html += '<tr>' + '<td>' + (item.product_name || '未命名产品') + '</td>' + '<td>' + item.calculation_count + '</td>' + '<td>' + parseFloat(item.avg_cost).toFixed(2) + ' 元</td>' + '<td>' + parseFloat(item.total_cost_sum).toFixed(2) + ' 元</td>' + '<td>' + parseFloat(item.avg_quantity).toFixed(1) + '</td>' + '</tr>'; }); $('#report-data').html(html); } } }); }); // 页面加载时自动生成报告 $('#generate-report').click(); }); </script> </div> <?php } // 短代码:显示成本报告 public function render_report_shortcode($atts) { if (!current_user_can('manage_options')) { return '<p>' . __('您没有查看报告的权限。', 'cost-calculator') . '</p>'; } ob_start(); $this->render_reports_page(); return ob_get_clean(); } }?> ## 管理设置类 <?php// includes/admin/class-admin-settings.php class Cost_Calculator_Admin_Settings { public function __construct() { add_action('admin_init', array($this, 'register_settings')); } // 注册设置 public function register_settings() { register_setting( 'cost_calculator_settings', 'cost_calculator_profit_margin', array( 'type' => 'number', 'sanitize_callback' => array($this, 'sanitize_profit_margin'), 'default' => '30' ) ); add_settings_section( 'cost_calculator_main_section', __('主要设置', 'cost-calculator'), array($this, 'render_section_callback'), 'cost_calculator_settings' ); add_settings_field( 'profit_margin_field', __('默认利润率 (%)', 'cost-calculator'), array($this, 'render_profit_margin_field'), 'cost_calculator_settings', 'cost_calculator_main_section' ); } // 渲染设置部分 public function render_section_callback() { echo '<p>' . __('配置成本核算插件的基本设置。', 'cost-calculator') . '</p>'; } // 渲染利润率字段 public function render_profit_margin_field() { $value = get_option('cost_calculator_profit_margin', '30'); echo '<input type="number" name="cost_calculator_profit_margin" value="' . esc_attr($value) . '" min="0" max="100" step="0.1">'; echo '<p class="description">' . __('用于计算建议售价的利润率百分比。', 'cost-calculator') . '</p>'; } // 验证利润率输入 public function sanitize_profit_margin($input) { $value = floatval($input); if ($value < 0 || $value > 100) { add_settings_error( 'cost_calculator_profit_margin', 'invalid_profit_margin', __('利润率必须在0-100%之间。', 'cost-calculator') ); return get_option('cost_calculator_profit_margin'); } return $value; } }?> ## 前端样式文件 / assets/css/style.css / .cost-calculator-container { background-color: #f9f9f9; border-left: 4px solid #0073aa; } .cost-calculator-container h3 { margin-top: 0; color: #23282d; } .cost-calculator-container .form-row { margin-bottom: 15px; } .cost-calculator-container label { display: block; margin-bottom: 5px; font-weight: 600; } .cost-calculator-container input[type="number"],.cost-calculator-container select { padding: 8px; border: 1px solid #ddd; border-radius: 3px; } .cost-calculator-container .material-option { margin-bottom: 5px; display: flex; gap: 4%; } .cost-result { border-top: 2px solid #0073aa; }
- margin-top: 10px; padding-top: 10px; border-top: 1px dashed #ccc; } / 响应式设计 /@media (max-width: 768px) { .cost-calculator-container .form-row { display: flex; flex-direction: column; } .cost-calculator-container input, .cost-calculator-container select { width: 100% !important; } } ## 部署和使用说明 ### 安装步骤 1. **创建插件目录**:将上述所有文件按照结构保存到 `wp-content/plugins/cost-calculator/` 目录 2. **激活插件**:在WordPress后台的插件页面找到"小批量定制成本核算器"并激活 3. **配置设置**:进入"成本核算"设置页面,配置默认利润率 ### 使用方法 1. **产品设置**: - 编辑产品时,在侧边栏找到"成本核算设置"元数据框 - 输入基础成本、单位人工成本 - 添加材料选项及其成本 2. **前端使用**: - 客户在产品页面可以看到成本计算器 - 选择数量、材料等选项,实时查看成本估算 - 系统会自动保存计算记录 3. **查看报告**: - 管理员可以在"成本核算 → 成本报告"页面查看分析报告 - 使用短代码 `[cost_calculator_report]` 在任何页面显示报告 ### 扩展建议 1. **批量导入**:添加CSV导入功能,批量设置产品成本 2. **供应商管理**:集成供应商价格,自动更新材料成本 3. **高级报告**:添加图表可视化,导出PDF报告功能 4. **邮件通知**:当成本超过阈值时发送通知 ## 总结 本教程详细介绍了如何开发一个完整的WordPress成本核算插件。通过这个插件,小批量定制产品商家可以: 1. 精确核算每个定制订单的成本 2. 实时调整定价策略 3. 分析不同材料和数量的成本影响 4. 优化生产流程和采购决策 插件采用模块化设计,便于后续扩展和维护。您可以根据具体业务需求添加更多功能,如集成第三方API获取实时材料价格、添加折扣计算、生成报价单等。
在电子商务运营中,成本核算是至关重要的环节。对于使用WordPress搭建的电商网站,特别是处理小批量定制产品的商家,实时核算成本能帮助您更精准地定价、控制利润。本教程将指导您开发一个WordPress插件,实现小批量定制产品的成本实时核算功能。
我们的插件将实现以下核心功能:
- 在商品编辑页面添加成本核算字段
- 根据用户选择的定制选项实时计算成本
- 在前端产品页面显示实时成本估算
- 管理员后台查看成本分析报告
首先,我们创建插件的基本文件结构:
wp-content/plugins/cost-calculator/
├── cost-calculator.php
├── includes/
│ ├── admin/
│ │ ├── class-admin-settings.php
│ │ └── class-product-metabox.php
│ ├── frontend/
│ │ ├── class-frontend-display.php
│ │ └── class-ajax-handler.php
│ └── class-cost-calculator.php
├── assets/
│ ├── css/
│ │ └── style.css
│ └── js/
│ └── script.js
└── README.md
<?php
/**
* Plugin Name: 小批量定制成本核算器
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress小批量定制产品提供实时成本核算功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: cost-calculator
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('COST_CALCULATOR_VERSION', '1.0.0');
define('COST_CALCULATOR_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('COST_CALCULATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
// 自动加载类文件
spl_autoload_register(function ($class_name) {
$prefix = 'Cost_Calculator_';
$base_dir = COST_CALCULATOR_PLUGIN_DIR . 'includes/';
// 检查类是否使用我们的命名空间前缀
$len = strlen($prefix);
if (strncmp($prefix, $class_name, $len) !== 0) {
return;
}
// 获取相对类名
$relative_class = substr($class_name, $len);
// 将命名空间分隔符替换为目录分隔符
$file = $base_dir . str_replace('_', '/', $relative_class) . '.php';
// 如果文件存在,则加载它
if (file_exists($file)) {
require $file;
}
});
// 初始化插件
function cost_calculator_init() {
// 检查WooCommerce是否激活
if (!class_exists('WooCommerce')) {
add_action('admin_notices', function() {
echo '<div class="notice notice-error"><p>';
echo __('成本核算插件需要WooCommerce支持,请先安装并激活WooCommerce插件。', 'cost-calculator');
echo '</p></div>';
});
return;
}
// 初始化主类
$plugin = new Cost_Calculator_Main();
$plugin->run();
}
add_action('plugins_loaded', 'cost_calculator_init');
// 插件激活时的操作
register_activation_hook(__FILE__, 'cost_calculator_activate');
function cost_calculator_activate() {
// 创建必要的数据库表
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'cost_calculator_logs';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
product_id mediumint(9) NOT NULL,
base_cost decimal(10,2) NOT NULL,
material_cost decimal(10,2) NOT NULL,
labor_cost decimal(10,2) NOT NULL,
additional_cost decimal(10,2) NOT NULL,
total_cost decimal(10,2) NOT NULL,
quantity int(11) NOT NULL,
calculated_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 设置默认选项
add_option('cost_calculator_version', COST_CALCULATOR_VERSION);
add_option('cost_calculator_profit_margin', '30'); // 默认利润率30%
}
// 插件停用时的清理操作
register_deactivation_hook(__FILE__, 'cost_calculator_deactivate');
function cost_calculator_deactivate() {
// 清理临时数据,保留日志表
delete_option('cost_calculator_temp_data');
}
?>
<?php
/**
* Plugin Name: 小批量定制成本核算器
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress小批量定制产品提供实时成本核算功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: cost-calculator
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('COST_CALCULATOR_VERSION', '1.0.0');
define('COST_CALCULATOR_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('COST_CALCULATOR_PLUGIN_URL', plugin_dir_url(__FILE__));
// 自动加载类文件
spl_autoload_register(function ($class_name) {
$prefix = 'Cost_Calculator_';
$base_dir = COST_CALCULATOR_PLUGIN_DIR . 'includes/';
// 检查类是否使用我们的命名空间前缀
$len = strlen($prefix);
if (strncmp($prefix, $class_name, $len) !== 0) {
return;
}
// 获取相对类名
$relative_class = substr($class_name, $len);
// 将命名空间分隔符替换为目录分隔符
$file = $base_dir . str_replace('_', '/', $relative_class) . '.php';
// 如果文件存在,则加载它
if (file_exists($file)) {
require $file;
}
});
// 初始化插件
function cost_calculator_init() {
// 检查WooCommerce是否激活
if (!class_exists('WooCommerce')) {
add_action('admin_notices', function() {
echo '<div class="notice notice-error"><p>';
echo __('成本核算插件需要WooCommerce支持,请先安装并激活WooCommerce插件。', 'cost-calculator');
echo '</p></div>';
});
return;
}
// 初始化主类
$plugin = new Cost_Calculator_Main();
$plugin->run();
}
add_action('plugins_loaded', 'cost_calculator_init');
// 插件激活时的操作
register_activation_hook(__FILE__, 'cost_calculator_activate');
function cost_calculator_activate() {
// 创建必要的数据库表
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'cost_calculator_logs';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
product_id mediumint(9) NOT NULL,
base_cost decimal(10,2) NOT NULL,
material_cost decimal(10,2) NOT NULL,
labor_cost decimal(10,2) NOT NULL,
additional_cost decimal(10,2) NOT NULL,
total_cost decimal(10,2) NOT NULL,
quantity int(11) NOT NULL,
calculated_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
// 设置默认选项
add_option('cost_calculator_version', COST_CALCULATOR_VERSION);
add_option('cost_calculator_profit_margin', '30'); // 默认利润率30%
}
// 插件停用时的清理操作
register_deactivation_hook(__FILE__, 'cost_calculator_deactivate');
function cost_calculator_deactivate() {
// 清理临时数据,保留日志表
delete_option('cost_calculator_temp_data');
}
?>
<?php
// includes/admin/class-product-metabox.php
class Cost_Calculator_Product_Metabox {
public function __construct() {
add_action('add_meta_boxes', array($this, 'add_cost_metabox'));
add_action('save_post_product', array($this, 'save_cost_data'));
}
// 添加成本核算元数据框
public function add_cost_metabox() {
add_meta_box(
'cost_calculator_metabox',
__('成本核算设置', 'cost-calculator'),
array($this, 'render_metabox'),
'product',
'side',
'high'
);
}
// 渲染元数据框内容
public function render_metabox($post) {
// 添加安全验证
wp_nonce_field('cost_calculator_save_data', 'cost_calculator_nonce');
// 获取现有值
$base_cost = get_post_meta($post->ID, '_base_cost', true);
$material_options = get_post_meta($post->ID, '_material_options', true);
$labor_cost_per_unit = get_post_meta($post->ID, '_labor_cost_per_unit', true);
// 解析材料选项
$materials = $material_options ? json_decode($material_options, true) : array();
?>
<div class="cost-calculator-fields">
<p>
<label for="base_cost"><?php _e('基础成本 (元):', 'cost-calculator'); ?></label>
<input type="number" step="0.01" min="0" id="base_cost"
name="base_cost" value="<?php echo esc_attr($base_cost); ?>"
style="width: 100%;">
</p>
<p>
<label for="labor_cost_per_unit"><?php _e('单位人工成本 (元):', 'cost-calculator'); ?></label>
<input type="number" step="0.01" min="0" id="labor_cost_per_unit"
name="labor_cost_per_unit" value="<?php echo esc_attr($labor_cost_per_unit); ?>"
style="width: 100%;">
</p>
<hr>
<h4><?php _e('材料选项', 'cost-calculator'); ?></h4>
<div id="material-options-container">
<?php if (!empty($materials)): ?>
<?php foreach ($materials as $index => $material): ?>
<div class="material-option">
<input type="text" name="material_names[]"
value="<?php echo esc_attr($material['name']); ?>"
placeholder="材料名称" style="width: 48%;">
<input type="number" step="0.01" min="0"
name="material_costs[]"
value="<?php echo esc_attr($material['cost']); ?>"
placeholder="成本" style="width: 48%;">
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="material-option">
<input type="text" name="material_names[]"
placeholder="材料名称" style="width: 48%;">
<input type="number" step="0.01" min="0"
name="material_costs[]"
placeholder="成本" style="width: 48%;">
</div>
<?php endif; ?>
</div>
<button type="button" id="add-material-option" class="button">
<?php _e('添加材料选项', 'cost-calculator'); ?>
</button>
<script>
jQuery(document).ready(function($) {
$('#add-material-option').click(function() {
$('#material-options-container').append(
'<div class="material-option" style="margin-top: 5px;">' +
'<input type="text" name="material_names[]" placeholder="材料名称" style="width: 48%;">' +
'<input type="number" step="0.01" min="0" name="material_costs[]" placeholder="成本" style="width: 48%;">' +
'</div>'
);
});
});
</script>
</div>
<?php
}
// 保存成本数据
public function save_cost_data($post_id) {
// 检查非ce、自动保存和用户权限
if (!isset($_POST['cost_calculator_nonce']) ||
!wp_verify_nonce($_POST['cost_calculator_nonce'], 'cost_calculator_save_data') ||
defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||
!current_user_can('edit_post', $post_id)) {
return;
}
// 保存基础成本
if (isset($_POST['base_cost'])) {
update_post_meta($post_id, '_base_cost', sanitize_text_field($_POST['base_cost']));
}
// 保存人工成本
if (isset($_POST['labor_cost_per_unit'])) {
update_post_meta($post_id, '_labor_cost_per_unit',
sanitize_text_field($_POST['labor_cost_per_unit']));
}
// 保存材料选项
if (isset($_POST['material_names']) && isset($_POST['material_costs'])) {
$materials = array();
$names = $_POST['material_names'];
$costs = $_POST['material_costs'];
for ($i = 0; $i < count($names); $i++) {
if (!empty($names[$i]) && !empty($costs[$i])) {
$materials[] = array(
'name' => sanitize_text_field($names[$i]),
'cost' => floatval($costs[$i])
);
}
}
update_post_meta($post_id, '_material_options', json_encode($materials));
}
}
}
?>
<?php
// includes/admin/class-product-metabox.php
class Cost_Calculator_Product_Metabox {
public function __construct() {
add_action('add_meta_boxes', array($this, 'add_cost_metabox'));
add_action('save_post_product', array($this, 'save_cost_data'));
}
// 添加成本核算元数据框
public function add_cost_metabox() {
add_meta_box(
'cost_calculator_metabox',
__('成本核算设置', 'cost-calculator'),
array($this, 'render_metabox'),
'product',
'side',
'high'
);
}
// 渲染元数据框内容
public function render_metabox($post) {
// 添加安全验证
wp_nonce_field('cost_calculator_save_data', 'cost_calculator_nonce');
// 获取现有值
$base_cost = get_post_meta($post->ID, '_base_cost', true);
$material_options = get_post_meta($post->ID, '_material_options', true);
$labor_cost_per_unit = get_post_meta($post->ID, '_labor_cost_per_unit', true);
// 解析材料选项
$materials = $material_options ? json_decode($material_options, true) : array();
?>
<div class="cost-calculator-fields">
<p>
<label for="base_cost"><?php _e('基础成本 (元):', 'cost-calculator'); ?></label>
<input type="number" step="0.01" min="0" id="base_cost"
name="base_cost" value="<?php echo esc_attr($base_cost); ?>"
style="width: 100%;">
</p>
<p>
<label for="labor_cost_per_unit"><?php _e('单位人工成本 (元):', 'cost-calculator'); ?></label>
<input type="number" step="0.01" min="0" id="labor_cost_per_unit"
name="labor_cost_per_unit" value="<?php echo esc_attr($labor_cost_per_unit); ?>"
style="width: 100%;">
</p>
<hr>
<h4><?php _e('材料选项', 'cost-calculator'); ?></h4>
<div id="material-options-container">
<?php if (!empty($materials)): ?>
<?php foreach ($materials as $index => $material): ?>
<div class="material-option">
<input type="text" name="material_names[]"
value="<?php echo esc_attr($material['name']); ?>"
placeholder="材料名称" style="width: 48%;">
<input type="number" step="0.01" min="0"
name="material_costs[]"
value="<?php echo esc_attr($material['cost']); ?>"
placeholder="成本" style="width: 48%;">
</div>
<?php endforeach; ?>
<?php else: ?>
<div class="material-option">
<input type="text" name="material_names[]"
placeholder="材料名称" style="width: 48%;">
<input type="number" step="0.01" min="0"
name="material_costs[]"
placeholder="成本" style="width: 48%;">
</div>
<?php endif; ?>
</div>
<button type="button" id="add-material-option" class="button">
<?php _e('添加材料选项', 'cost-calculator'); ?>
</button>
<script>
jQuery(document).ready(function($) {
$('#add-material-option').click(function() {
$('#material-options-container').append(
'<div class="material-option" style="margin-top: 5px;">' +
'<input type="text" name="material_names[]" placeholder="材料名称" style="width: 48%;">' +
'<input type="number" step="0.01" min="0" name="material_costs[]" placeholder="成本" style="width: 48%;">' +
'</div>'
);
});
});
</script>
</div>
<?php
}
// 保存成本数据
public function save_cost_data($post_id) {
// 检查非ce、自动保存和用户权限
if (!isset($_POST['cost_calculator_nonce']) ||
!wp_verify_nonce($_POST['cost_calculator_nonce'], 'cost_calculator_save_data') ||
defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ||
!current_user_can('edit_post', $post_id)) {
return;
}
// 保存基础成本
if (isset($_POST['base_cost'])) {
update_post_meta($post_id, '_base_cost', sanitize_text_field($_POST['base_cost']));
}
// 保存人工成本
if (isset($_POST['labor_cost_per_unit'])) {
update_post_meta($post_id, '_labor_cost_per_unit',
sanitize_text_field($_POST['labor_cost_per_unit']));
}
// 保存材料选项
if (isset($_POST['material_names']) && isset($_POST['material_costs'])) {
$materials = array();
$names = $_POST['material_names'];
$costs = $_POST['material_costs'];
for ($i = 0; $i < count($names); $i++) {
if (!empty($names[$i]) && !empty($costs[$i])) {
$materials[] = array(
'name' => sanitize_text_field($names[$i]),
'cost' => floatval($costs[$i])
);
}
}
update_post_meta($post_id, '_material_options', json_encode($materials));
}
}
}
?>
<?php
// includes/frontend/class-frontend-display.php
class Cost_Calculator_Frontend_Display {
public function __construct() {
add_action('woocommerce_before_add_to_cart_button', array($this, 'display_cost_calculator'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
}
// 在前端产品页面显示成本计算器
public function display_cost_calculator() {
global $product;
if (!$product || !$product->is_type('simple')) {
return;
}
$product_id = $product->get_id();
$base_cost = get_post_meta($product_id, '_base_cost', true);
$labor_cost = get_post_meta($product_id, '_labor_cost_per_unit', true);
$material_options = get_post_meta($product_id, '_material_options', true);
$materials = $material_options ? json_decode($material_options, true) : array();
if (empty($base_cost) && empty($labor_cost) && empty($materials)) {
return;
}
?>
<div class="cost-calculator-container" style="margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px;">
<h3><?php _e('成本估算器', 'cost-calculator'); ?></h3>
<div class="calculator-fields">
<!-- 数量选择 -->
<div class="form-row">
<label for="quantity"><?php _e('数量:', 'cost-calculator'); ?></label>
<input type="number" id="cost-quantity" name="cost_quantity"
min="1" max="100" value="1" style="width: 80px;">
</div>
<!-- 材料选择 -->
<?php if (!empty($materials)): ?>
<div class="form-row">
<label for="material-select"><?php _e('选择材料:', 'cost-calculator'); ?></label>
<select id="material-select" name="cost_material" style="width: 200px;">
<option value="0"><?php _e('-- 请选择 --', 'cost-calculator'); ?></option>
<?php foreach ($materials as $index => $material): ?>
<option value="<?php echo esc_attr($material['cost']); ?>"
data-index="<?php echo $index; ?>">
<?php echo esc_html($material['name']); ?>
(<?php echo wc_price($material['cost']); ?>)
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<!-- 额外成本 -->
<div class="form-row">
<label for="additional-cost"><?php _e('额外成本 (元):', 'cost-calculator'); ?></label>
<input type="number" id="additional-cost" name="additional_cost"
step="0.01" min="0" value="0" style="width: 100px;">
<small><?php _e('如包装、特殊处理等', 'cost-calculator'); ?></small>
</div>
<!-- 计算结果 -->
<div class="cost-result" style="margin-top: 15px; padding: 10px; background-color: #f8f9fa; border-radius: 3px;">
<h4><?php _e('成本估算结果:', 'cost-calculator'); ?></h4>
<div id="cost-breakdown">
<p><?php _e('请选择选项以查看成本估算', 'cost-calculator'); ?></p>
</div>
<div id="total-cost" style="font-weight: bold; font-size: 1.2em; color: #d35400;"></div>
</div>
<!-- 隐藏字段存储产品数据 -->
<input type="hidden" id="product-base-cost" value="<?php echo esc_attr($base_cost); ?>">
<input type="hidden" id="product-labor-cost" value="<?php echo esc_attr($labor_cost); ?>">
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// 获取利润率设置
var profitMargin = <?php echo get_option('cost_calculator_profit_margin', '30'); ?>;
// 计算成本函数
function calculateCost() {
var quantity = parseInt($('#cost-quantity').val()) || 1;
var baseCost = parseFloat($('#product-base-cost').val()) || 0;
var laborCost = parseFloat($('#product-labor-cost').val()) || 0;
var materialCost = parseFloat($('#material-select').val()) || 0;
var additionalCost = parseFloat($('#additional-cost').val()) || 0;
// 计算各项成本
var totalBaseCost = baseCost * quantity;
var totalLaborCost = laborCost * quantity;
var totalMaterialCost = materialCost * quantity;
var totalAdditionalCost = additionalCost;
// 总成本
var totalCost = totalBaseCost + totalLaborCost + totalMaterialCost + totalAdditionalCost;
// 建议售价(包含利润)
var suggestedPrice = totalCost * (1 + profitMargin / 100);
// 更新显示
$('#cost-breakdown').html(
'<p>基础成本: ' + totalBaseCost.toFixed(2) + ' 元</p>' +
'<p>人工成本: ' + totalLaborCost.toFixed(2) + ' 元</p>' +
'<p>材料成本: ' + totalMaterialCost.toFixed(2) + ' 元</p>' +
'<p>额外成本: ' + totalAdditionalCost.toFixed(2) + ' 元</p>'
);
$('#total-cost').html(
'总成本: ' + totalCost.toFixed(2) + ' 元<br>' +
'建议售价 (利润率 ' + profitMargin + '%): ' + suggestedPrice.toFixed(2) + ' 元'
);
// 保存计算记录到数据库
saveCostCalculation({
product_id: <?php echo $product_id; ?>,
base_cost: baseCost,
labor_cost: laborCost,
material_cost: materialCost,
additional_cost: additionalCost,
total_cost: totalCost,
quantity: quantity
});
}
// 保存计算记录到数据库
function saveCostCalculation(data) {
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'save_cost_calculation',
nonce: '<?php echo wp_create_nonce('cost_calculator_ajax'); ?>',
calculation_data: data
}
});
}
// 绑定事件监听
// 页面加载时计算一次
calculateCost();
});
</script>
<?php
}
// 加载前端脚本和样式
public function enqueue_scripts() {
if (is_product()) {
wp_enqueue_style(
'cost-calculator-frontend',
COST_CALCULATOR_PLUGIN_URL . 'assets/css/style.css',
array(),
COST_CALCULATOR_VERSION
);
wp_enqueue_script(
'cost-calculator-frontend',
COST_CALCULATOR_PLUGIN_URL . 'assets/js/script.js',
array('jquery'),
COST_CALCULATOR_VERSION,
true
);
// 传递数据到JavaScript
wp_localize_script('cost-calculator-frontend', 'costCalculator', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('cost_calculator_frontend')
));
}
}
<?php
// includes/frontend/class-frontend-display.php
class Cost_Calculator_Frontend_Display {
public function __construct() {
add_action('woocommerce_before_add_to_cart_button', array($this, 'display_cost_calculator'));
add_action('wp_enqueue_scripts', array($this, 'enqueue_scripts'));
}
// 在前端产品页面显示成本计算器
public function display_cost_calculator() {
global $product;
if (!$product || !$product->is_type('simple')) {
return;
}
$product_id = $product->get_id();
$base_cost = get_post_meta($product_id, '_base_cost', true);
$labor_cost = get_post_meta($product_id, '_labor_cost_per_unit', true);
$material_options = get_post_meta($product_id, '_material_options', true);
$materials = $material_options ? json_decode($material_options, true) : array();
if (empty($base_cost) && empty($labor_cost) && empty($materials)) {
return;
}
?>
<div class="cost-calculator-container" style="margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px;">
<h3><?php _e('成本估算器', 'cost-calculator'); ?></h3>
<div class="calculator-fields">
<!-- 数量选择 -->
<div class="form-row">
<label for="quantity"><?php _e('数量:', 'cost-calculator'); ?></label>
<input type="number" id="cost-quantity" name="cost_quantity"
min="1" max="100" value="1" style="width: 80px;">
</div>
<!-- 材料选择 -->
<?php if (!empty($materials)): ?>
<div class="form-row">
<label for="material-select"><?php _e('选择材料:', 'cost-calculator'); ?></label>
<select id="material-select" name="cost_material" style="width: 200px;">
<option value="0"><?php _e('-- 请选择 --', 'cost-calculator'); ?></option>
<?php foreach ($materials as $index => $material): ?>
<option value="<?php echo esc_attr($material['cost']); ?>"
data-index="<?php echo $index; ?>">
<?php echo esc_html($material['name']); ?>
(<?php echo wc_price($material['cost']); ?>)
</option>
<?php endforeach; ?>
</select>
</div>
<?php endif; ?>
<!-- 额外成本 -->
<div class="form-row">
<label for="additional-cost"><?php _e('额外成本 (元):', 'cost-calculator'); ?></label>
<input type="number" id="additional-cost" name="additional_cost"
step="0.01" min="0" value="0" style="width: 100px;">
<small><?php _e('如包装、特殊处理等', 'cost-calculator'); ?></small>
</div>
<!-- 计算结果 -->
<div class="cost-result" style="margin-top: 15px; padding: 10px; background-color: #f8f9fa; border-radius: 3px;">
<h4><?php _e('成本估算结果:', 'cost-calculator'); ?></h4>
<div id="cost-breakdown">
<p><?php _e('请选择选项以查看成本估算', 'cost-calculator'); ?></p>
</div>
<div id="total-cost" style="font-weight: bold; font-size: 1.2em; color: #d35400;"></div>
</div>
<!-- 隐藏字段存储产品数据 -->
<input type="hidden" id="product-base-cost" value="<?php echo esc_attr($base_cost); ?>">
<input type="hidden" id="product-labor-cost" value="<?php echo esc_attr($labor_cost); ?>">
</div>
</div>
<script type="text/javascript">
jQuery(document).ready(function($) {
// 获取利润率设置
var profitMargin = <?php echo get_option('cost_calculator_profit_margin', '30'); ?>;
// 计算成本函数
function calculateCost() {
var quantity = parseInt($('#cost-quantity').val()) || 1;
var baseCost = parseFloat($('#product-base-cost').val()) || 0;
var laborCost = parseFloat($('#product-labor-cost').val()) || 0;
var materialCost = parseFloat($('#material-select').val()) || 0;
var additionalCost = parseFloat($('#additional-cost').val()) || 0;
// 计算各项成本
var totalBaseCost = baseCost * quantity;
var totalLaborCost = laborCost * quantity;
var totalMaterialCost = materialCost * quantity;
var totalAdditionalCost = additionalCost;
// 总成本
var totalCost = totalBaseCost + totalLaborCost + totalMaterialCost + totalAdditionalCost;
// 建议售价(包含利润)
var suggestedPrice = totalCost * (1 + profitMargin / 100);
// 更新显示
$('#cost-breakdown').html(
'<p>基础成本: ' + totalBaseCost.toFixed(2) + ' 元</p>' +
'<p>人工成本: ' + totalLaborCost.toFixed(2) + ' 元</p>' +
'<p>材料成本: ' + totalMaterialCost.toFixed(2) + ' 元</p>' +
'<p>额外成本: ' + totalAdditionalCost.toFixed(2) + ' 元</p>'
);
$('#total-cost').html(
'总成本: ' + totalCost.toFixed(2) + ' 元<br>' +
'建议售价 (利润率 ' + profitMargin + '%): ' + suggestedPrice.toFixed(2) + ' 元'
);
// 保存计算记录到数据库
saveCostCalculation({
product_id: <?php echo $product_id; ?>,
base_cost: baseCost,
labor_cost: laborCost,
material_cost: materialCost,
additional_cost: additionalCost,
total_cost: totalCost,
quantity: quantity
});
}
// 保存计算记录到数据库
function saveCostCalculation(data) {
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'save_cost_calculation',
nonce: '<?php echo wp_create_nonce('cost_calculator_ajax'); ?>',
calculation_data: data
}
});
}
// 绑定事件监听
// 页面加载时计算一次
calculateCost();
});
</script>
<?php
}
// 加载前端脚本和样式
public function enqueue_scripts() {
if (is_product()) {
wp_enqueue_style(
'cost-calculator-frontend',
COST_CALCULATOR_PLUGIN_URL . 'assets/css/style.css',
array(),
COST_CALCULATOR_VERSION
);
wp_enqueue_script(
'cost-calculator-frontend',
COST_CALCULATOR_PLUGIN_URL . 'assets/js/script.js',
array('jquery'),
COST_CALCULATOR_VERSION,
true
);
// 传递数据到JavaScript
wp_localize_script('cost-calculator-frontend', 'costCalculator', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('cost_calculator_frontend')
));
}
}
}
?>
## AJAX处理程序
<?php
// includes/frontend/class-ajax-handler.php
class Cost_Calculator_Ajax_Handler {
public function __construct() {
add_action('wp_ajax_save_cost_calculation', array($this, 'save_calculation'));
add_action('wp_ajax_nopriv_save_cost_calculation', array($this, 'save_calculation'));
add_action('wp_ajax_get_cost_report', array($this, 'get_cost_report'));
}
// 保存成本计算记录
public function save_calculation() {
// 验证nonce
if (!wp_verify_nonce($_POST['nonce'], 'cost_calculator_ajax')) {
wp_die('安全验证失败');
}
global $wpdb;
$table_name = $wpdb->prefix . 'cost_calculator_logs';
$data = $_POST['calculation_data'];
$wpdb->insert(
$table_name,
array(
'product_id' => intval($data['product_id']),
'base_cost' => floatval($data['base_cost']),
'material_cost' => floatval($data['material_cost']),
'labor_cost' => floatval($data['labor_cost']),
'additional_cost' => floatval($data['additional_cost']),
'total_cost' => floatval($data['total_cost']),
'quantity' => intval($data['quantity'])
),
array('%d', '%f', '%f', '%f', '%f', '%f', '%d')
);
wp_send_json_success(array('message' => '计算记录已保存'));
}
// 获取成本报告
public function get_cost_report() {
// 验证用户权限
if (!current_user_can('manage_options')) {
wp_die('权限不足');
}
global $wpdb;
$table_name = $wpdb->prefix . 'cost_calculator_logs';
$start_date = isset($_POST['start_date']) ? sanitize_text_field($_POST['start_date']) : date('Y-m-01');
$end_date = isset($_POST['end_date']) ? sanitize_text_field($_POST['end_date']) : date('Y-m-d');
$results = $wpdb->get_results($wpdb->prepare(
"SELECT
p.post_title as product_name,
COUNT(l.id) as calculation_count,
AVG(l.total_cost) as avg_cost,
SUM(l.total_cost) as total_cost_sum,
AVG(l.quantity) as avg_quantity
FROM {$table_name} l
LEFT JOIN {$wpdb->posts} p ON l.product_id = p.ID
WHERE DATE(l.calculated_at) BETWEEN %s AND %s
GROUP BY l.product_id
ORDER BY calculation_count DESC",
$start_date, $end_date
));
wp_send_json_success($results);
}
}
?>
## 主控制器类
<?php
// includes/class-cost-calculator.php
class Cost_Calculator_Main {
private $admin_settings;
private $product_metabox;
private $frontend_display;
private $ajax_handler;
public function __construct() {
// 初始化各个组件
$this->admin_settings = new Cost_Calculator_Admin_Settings();
$this->product_metabox = new Cost_Calculator_Product_Metabox();
$this->frontend_display = new Cost_Calculator_Frontend_Display();
$this->ajax_handler = new Cost_Calculator_Ajax_Handler();
}
public function run() {
// 注册短代码
add_shortcode('cost_calculator_report', array($this, 'render_report_shortcode'));
// 添加管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
}
// 添加管理菜单
public function add_admin_menu() {
add_menu_page(
__('成本核算', 'cost-calculator'),
__('成本核算', 'cost-calculator'),
'manage_options',
'cost-calculator',
array($this, 'render_admin_page'),
'dashicons-calculator',
30
);
add_submenu_page(
'cost-calculator',
__('成本报告', 'cost-calculator'),
__('成本报告', 'cost-calculator'),
'manage_options',
'cost-calculator-reports',
array($this, 'render_reports_page')
);
}
// 渲染管理页面
public function render_admin_page() {
?>
<div class="wrap">
<h1><?php _e('成本核算设置', 'cost-calculator'); ?></h1>
<form method="post" action="options.php">
<?php
settings_fields('cost_calculator_settings');
do_settings_sections('cost_calculator_settings');
submit_button();
?>
</form>
<div class="cost-calculator-stats">
<h2><?php _e('统计概览', 'cost-calculator'); ?></h2>
<?php
global $wpdb;
$table_name = $wpdb->prefix . 'cost_calculator_logs';
$total_calculations = $wpdb->get_var("SELECT COUNT(*) FROM {$table_name}");
$today_calculations = $wpdb->get_var($wpdb->prepare(
"SELECT COUNT(*) FROM {$table_name} WHERE DATE(calculated_at) = %s",
date('Y-m-d')
));
echo '<p>' . sprintf(__('总计算次数: %d', 'cost-calculator'), $total_calculations) . '</p>';
echo '<p>' . sprintf(__('今日计算次数: %d', 'cost-calculator'), $today_calculations) . '</p>';
?>
</div>
</div>
<?php
}
// 渲染报告页面
public function render_reports_page() {
?>
<div class="wrap">
<h1><?php _e('成本分析报告', 'cost-calculator'); ?></h1>
<div class="report-filters">
<form method="post" id="cost-report-form">
<label for="start_date"><?php _e('开始日期:', 'cost-calculator'); ?></label>
<input type="date" id="start_date" name="start_date"
value="<?php echo date('Y-m-01'); ?>">
<label for="end_date"><?php _e('结束日期:', 'cost-calculator'); ?></label>
<input type="date" id="end_date" name="end_date"
value="<?php echo date('Y-m-d'); ?>">
<button type="button" id="generate-report" class="button button-primary">
<?php _e('生成报告', 'cost-calculator'); ?>
</button>
</form>
</div>
<div id="report-results" style="margin-top: 20px;">
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th><?php _e('产品名称', 'cost-calculator'); ?></th>
<th><?php _e('计算次数', 'cost-calculator'); ?></th>
<th><?php _e('平均成本', 'cost-calculator'); ?></th>
<th><?php _e('成本总额', 'cost-calculator'); ?></th>
<th><?php _e('平均数量', 'cost-calculator'); ?></th>
</tr>
</thead>
<tbody id="report-data">
<!-- 报告数据将通过AJAX加载 -->
</tbody>
</table>
</div>
<script>
jQuery(document).ready(function($) {
$('#generate-report').click(function() {
var formData = $('#cost-report-form').serialize();
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'get_cost_report',
...formData
},
success: function(response) {
if (response.success) {
var html = '';
$.each(response.data, function(index, item) {
html += '<tr>' +
'<td>' + (item.product_name || '未命名产品') + '</td>' +
'<td>' + item.calculation_count + '</td>' +
'<td>' + parseFloat(item.avg_cost).toFixed(2) + ' 元</td>' +
'<td>' + parseFloat(item.total_cost_sum).toFixed(2) + ' 元</td>' +
'<td>' + parseFloat(item.avg_quantity).toFixed(1) + '</td>' +
'</tr>';
});
$('#report-data').html(html);
}
}
});
});
// 页面加载时自动生成报告
$('#generate-report').click();
});
</script>
</div>
<?php
}
// 短代码:显示成本报告
public function render_report_shortcode($atts) {
if (!current_user_can('manage_options')) {
return '<p>' . __('您没有查看报告的权限。', 'cost-calculator') . '</p>';
}
ob_start();
$this->render_reports_page();
return ob_get_clean();
}
}
?>
## 管理设置类
<?php
// includes/admin/class-admin-settings.php
class Cost_Calculator_Admin_Settings {
public function __construct() {
add_action('admin_init', array($this, 'register_settings'));
}
// 注册设置
public function register_settings() {
register_setting(
'cost_calculator_settings',
'cost_calculator_profit_margin',
array(
'type' => 'number',
'sanitize_callback' => array($this, 'sanitize_profit_margin'),
'default' => '30'
)
);
add_settings_section(
'cost_calculator_main_section',
__('主要设置', 'cost-calculator'),
array($this, 'render_section_callback'),
'cost_calculator_settings'
);
add_settings_field(
'profit_margin_field',
__('默认利润率 (%)', 'cost-calculator'),
array($this, 'render_profit_margin_field'),
'cost_calculator_settings',
'cost_calculator_main_section'
);
}
// 渲染设置部分
public function render_section_callback() {
echo '<p>' . __('配置成本核算插件的基本设置。', 'cost-calculator') . '</p>';
}
// 渲染利润率字段
public function render_profit_margin_field() {
$value = get_option('cost_calculator_profit_margin', '30');
echo '<input type="number" name="cost_calculator_profit_margin"
value="' . esc_attr($value) . '" min="0" max="100" step="0.1">';
echo '<p class="description">' . __('用于计算建议售价的利润率百分比。', 'cost-calculator') . '</p>';
}
// 验证利润率输入
public function sanitize_profit_margin($input) {
$value = floatval($input);
if ($value < 0 || $value > 100) {
add_settings_error(
'cost_calculator_profit_margin',
'invalid_profit_margin',
__('利润率必须在0-100%之间。', 'cost-calculator')
);
return get_option('cost_calculator_profit_margin');
}
return $value;
}
}
?>
## 前端样式文件
/ assets/css/style.css /
.cost-calculator-container {
background-color: #f9f9f9;
border-left: 4px solid #0073aa;
}
.cost-calculator-container h3 {
margin-top: 0;
color: #23282d;
}
.cost-calculator-container .form-row {
margin-bottom: 15px;
}
.cost-calculator-container label {
display: block;
margin-bottom: 5px;
font-weight: 600;
}
.cost-calculator-container input[type="number"],
.cost-calculator-container select {
padding: 8px;
border: 1px solid #ddd;
border-radius: 3px;
}
.cost-calculator-container .material-option {
margin-bottom: 5px;
display: flex;
gap: 4%;
}
.cost-result {
border-top: 2px solid #0073aa;
}
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed #ccc;
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed #ccc;
}
/ 响应式设计 /
@media (max-width: 768px) {
.cost-calculator-container .form-row {
display: flex;
flex-direction: column;
}
.cost-calculator-container input,
.cost-calculator-container select {
width: 100% !important;
}
}
## 部署和使用说明
### 安装步骤
1. **创建插件目录**:将上述所有文件按照结构保存到 `wp-content/plugins/cost-calculator/` 目录
2. **激活插件**:在WordPress后台的插件页面找到"小批量定制成本核算器"并激活
3. **配置设置**:进入"成本核算"设置页面,配置默认利润率
### 使用方法
1. **产品设置**:
- 编辑产品时,在侧边栏找到"成本核算设置"元数据框
- 输入基础成本、单位人工成本
- 添加材料选项及其成本
2. **前端使用**:
- 客户在产品页面可以看到成本计算器
- 选择数量、材料等选项,实时查看成本估算
- 系统会自动保存计算记录
3. **查看报告**:
- 管理员可以在"成本核算 → 成本报告"页面查看分析报告
- 使用短代码 `[cost_calculator_report]` 在任何页面显示报告
### 扩展建议
1. **批量导入**:添加CSV导入功能,批量设置产品成本
2. **供应商管理**:集成供应商价格,自动更新材料成本
3. **高级报告**:添加图表可视化,导出PDF报告功能
4. **邮件通知**:当成本超过阈值时发送通知
## 总结
本教程详细介绍了如何开发一个完整的WordPress成本核算插件。通过这个插件,小批量定制产品商家可以:
1. 精确核算每个定制订单的成本
2. 实时调整定价策略
3. 分析不同材料和数量的成本影响
4. 优化生产流程和采购决策
插件采用模块化设计,便于后续扩展和维护。您可以根据具体业务需求添加更多功能,如集成第三方API获取实时材料价格、添加折扣计算、生成报价单等。


