文章目录[隐藏]
WordPress小批量定制插件实现智能报价与核价的开发教程
引言:为什么需要智能报价与核价系统?
在当今竞争激烈的电商环境中,定制化产品服务越来越受欢迎。对于WordPress网站来说,如果能够为访客提供即时、准确的定制产品报价,将大大提升用户体验和转化率。本教程将指导您开发一个轻量级但功能完整的智能报价与核价插件,适用于小批量定制产品的定价需求。
通过本插件,您的WordPress网站可以:
- 根据用户选择的定制选项自动计算价格
- 实时显示报价变化
- 验证用户选择的组合是否可行
- 生成详细的报价单供用户下载或发送
插件基础结构
首先,我们需要创建插件的基本文件结构:
wp-content/plugins/smart-quote-pricer/
├── smart-quote-pricer.php # 主插件文件
├── includes/
│ ├── class-quote-calculator.php # 报价计算类
│ ├── class-form-handler.php # 表单处理类
│ └── class-admin-settings.php # 后台设置类
├── assets/
│ ├── css/
│ │ └── frontend.css # 前端样式
│ └── js/
│ └── frontend.js # 前端交互脚本
├── templates/
│ ├── quote-form.php # 报价表单模板
│ └── quote-result.php # 报价结果模板
└── languages/ # 国际化文件
主插件文件
<?php
/**
* Plugin Name: 智能报价与核价系统
* Plugin URI: https://yourwebsite.com/
* Description: 为WordPress网站提供小批量定制产品的智能报价与核价功能
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: smart-quote-pricer
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('SQP_VERSION', '1.0.0');
define('SQP_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('SQP_PLUGIN_URL', plugin_dir_url(__FILE__));
// 自动加载类文件
spl_autoload_register(function ($class_name) {
if (strpos($class_name, 'SQP_') === 0) {
$file = SQP_PLUGIN_DIR . 'includes/class-' . strtolower(str_replace('_', '-', $class_name)) . '.php';
if (file_exists($file)) {
require_once $file;
}
}
});
// 初始化插件
class Smart_Quote_Pricer {
private static $instance = null;
private $calculator;
private $form_handler;
public static function get_instance() {
if (null === self::$instance) {
self::$instance = new self();
}
return self::$instance;
}
private function __construct() {
$this->init_hooks();
}
private function init_hooks() {
// 激活/停用钩子
register_activation_hook(__FILE__, array($this, 'activate'));
register_deactivation_hook(__FILE__, array($this, 'deactivate'));
// 初始化
add_action('plugins_loaded', array($this, 'init'));
// 加载文本域
add_action('init', array($this, 'load_textdomain'));
}
public function activate() {
// 创建必要的数据库表
$this->create_tables();
// 设置默认选项
$default_options = array(
'base_markup_percentage' => 30,
'currency_symbol' => '¥',
'min_order_quantity' => 10,
'max_order_quantity' => 1000,
);
add_option('sqp_settings', $default_options);
}
public function deactivate() {
// 清理临时数据
// 注意:这里不删除设置,以便重新激活时保留配置
}
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
$table_name = $wpdb->prefix . 'sqp_quote_history';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
session_id varchar(100) NOT NULL,
user_data text NOT NULL,
calculated_price decimal(10,2) NOT NULL,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
public function load_textdomain() {
load_plugin_textdomain('smart-quote-pricer', false, dirname(plugin_basename(__FILE__)) . '/languages/');
}
public function init() {
// 初始化核心组件
$this->calculator = new SQP_Quote_Calculator();
$this->form_handler = new SQP_Form_Handler();
// 加载前端资源
add_action('wp_enqueue_scripts', array($this, 'enqueue_frontend_assets'));
// 注册短代码
add_shortcode('smart_quote_form', array($this->form_handler, 'render_quote_form'));
// 初始化后台设置
if (is_admin()) {
new SQP_Admin_Settings();
}
}
public function enqueue_frontend_assets() {
// 前端CSS
wp_enqueue_style(
'sqp-frontend',
SQP_PLUGIN_URL . 'assets/css/frontend.css',
array(),
SQP_VERSION
);
// 前端JavaScript
wp_enqueue_script(
'sqp-frontend',
SQP_PLUGIN_URL . 'assets/js/frontend.js',
array('jquery'),
SQP_VERSION,
true
);
// 传递数据到JavaScript
wp_localize_script('sqp-frontend', 'sqp_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('sqp_ajax_nonce')
));
}
}
// 启动插件
Smart_Quote_Pricer::get_instance();
报价计算引擎
<?php
/**
* 报价计算类
* 处理所有价格计算逻辑
*/
class SQP_Quote_Calculator {
/**
* 计算定制产品价格
*
* @param array $form_data 表单数据
* @return array 计算结果
*/
public function calculate_price($form_data) {
// 获取设置
$settings = get_option('sqp_settings');
// 验证数量范围
$quantity = intval($form_data['quantity']);
$min_qty = $settings['min_order_quantity'];
$max_qty = $settings['max_order_quantity'];
if ($quantity < $min_qty || $quantity > $max_qty) {
return array(
'success' => false,
'message' => sprintf(
__('数量必须在%d到%d之间', 'smart-quote-pricer'),
$min_qty,
$max_qty
)
);
}
// 基础价格计算
$base_price = $this->calculate_base_price($form_data);
// 材料成本
$material_cost = $this->calculate_material_cost($form_data);
// 加工成本
$processing_cost = $this->calculate_processing_cost($form_data);
// 特殊工艺加成
$special_process_cost = $this->calculate_special_process_cost($form_data);
// 小批量系数(数量越少,单价越高)
$batch_factor = $this->calculate_batch_factor($quantity);
// 计算总成本
$total_cost = ($base_price + $material_cost + $processing_cost + $special_process_cost) * $batch_factor;
// 添加利润率
$markup_percentage = $settings['base_markup_percentage'];
$final_price = $total_cost * (1 + $markup_percentage / 100);
// 单价和总价
$unit_price = $final_price;
$total_price = $unit_price * $quantity;
// 返回详细计算结果
return array(
'success' => true,
'unit_price' => round($unit_price, 2),
'total_price' => round($total_price, 2),
'quantity' => $quantity,
'breakdown' => array(
'base_price' => round($base_price, 2),
'material_cost' => round($material_cost, 2),
'processing_cost' => round($processing_cost, 2),
'special_process_cost' => round($special_process_cost, 2),
'batch_factor' => round($batch_factor, 2),
'markup_percentage' => $markup_percentage
),
'currency_symbol' => $settings['currency_symbol']
);
}
/**
* 计算基础价格
*/
private function calculate_base_price($form_data) {
$base_prices = array(
'product_a' => 50.00,
'product_b' => 75.00,
'product_c' => 100.00
);
$product_type = sanitize_text_field($form_data['product_type']);
return isset($base_prices[$product_type]) ? $base_prices[$product_type] : 50.00;
}
/**
* 计算材料成本
*/
private function calculate_material_cost($form_data) {
$material_costs = array(
'material_standard' => 10.00,
'material_premium' => 25.00,
'material_luxury' => 50.00
);
$material = sanitize_text_field($form_data['material']);
return isset($material_costs[$material]) ? $material_costs[$material] : 10.00;
}
/**
* 计算加工成本
*/
private function calculate_processing_cost($form_data) {
$cost = 0;
// 尺寸加成
$size = sanitize_text_field($form_data['size']);
$size_factors = array('small' => 1.0, 'medium' => 1.2, 'large' => 1.5);
$cost += isset($size_factors[$size]) ? $size_factors[$size] * 15 : 15;
// 复杂度加成
if (isset($form_data['complex_design']) && $form_data['complex_design'] === 'yes') {
$cost += 20;
}
return $cost;
}
/**
* 计算特殊工艺成本
*/
private function calculate_special_process_cost($form_data) {
$cost = 0;
$special_processes = array(
'embroidery' => 15,
'printing' => 10,
'engraving' => 25,
'coating' => 20
);
if (isset($form_data['special_processes']) && is_array($form_data['special_processes'])) {
foreach ($form_data['special_processes'] as $process) {
if (isset($special_processes[$process])) {
$cost += $special_processes[$process];
}
}
}
return $cost;
}
/**
* 计算小批量系数
*/
private function calculate_batch_factor($quantity) {
// 数量越少,系数越高(小批量生产单价更高)
if ($quantity <= 50) return 1.5;
if ($quantity <= 100) return 1.3;
if ($quantity <= 200) return 1.2;
if ($quantity <= 500) return 1.1;
return 1.0; // 500件以上无批量加成
}
/**
* 验证选项组合是否可行
*/
public function validate_options($form_data) {
$errors = array();
// 示例验证规则
if (isset($form_data['material']) && $form_data['material'] === 'material_standard') {
if (isset($form_data['special_processes']) && in_array('engraving', $form_data['special_processes'])) {
$errors[] = __('标准材料不支持雕刻工艺', 'smart-quote-pricer');
}
}
// 尺寸限制
if (isset($form_data['size']) && $form_data['size'] === 'large') {
if (isset($form_data['product_type']) && $form_data['product_type'] === 'product_a') {
$errors[] = __('产品A不支持大尺寸', 'smart-quote-pricer');
}
}
return $errors;
}
}
前端表单与交互
<?php
/**
* 表单处理类
* 处理前端表单渲染和提交
*/
class SQP_Form_Handler {
/**
* 渲染报价表单
*/
public function render_quote_form($atts) {
ob_start();
include(SQP_PLUGIN_DIR . 'templates/quote-form.php');
return ob_get_clean();
}
/**
* 处理AJAX报价请求
*/
public function handle_ajax_quote_request() {
// 验证nonce
if (!check_ajax_referer('sqp_ajax_nonce', 'nonce', false)) {
wp_die('安全验证失败');
}
// 获取并清理表单数据
$form_data = array();
$fields = array('product_type', 'material', 'size', 'quantity', 'complex_design');
foreach ($fields as $field) {
if (isset($_POST[$field])) {
$form_data[$field] = sanitize_text_field($_POST[$field]);
}
}
// 处理多选字段
if (isset($_POST['special_processes']) && is_array($_POST['special_processes'])) {
$form_data['special_processes'] = array_map('sanitize_text_field', $_POST['special_processes']);
}
// 验证数量
$form_data['quantity'] = intval($form_data['quantity']);
if ($form_data['quantity'] <= 0) {
wp_send_json_error(array('message' => '请输入有效的数量'));
}
// 初始化计算器
$calculator = new SQP_Quote_Calculator();
// 验证选项组合
$validation_errors = $calculator->validate_options($form_data);
if (!empty($validation_errors)) {
wp_send_json_error(array(
'message' => '选项组合无效',
'errors' => $validation_errors
));
}
// 计算价格
$result = $calculator->calculate_price($form_data);
if ($result['success']) {
// 保存报价记录
$this->save_quote_history($form_data, $result);
// 返回结果
wp_send_json_success($result);
} else {
wp_send_json_error(array('message' => $result['message']));
}
}
/**
* 保存报价历史
*/
private function save_quote_history($form_data, $result) {
global $wpdb;
$table_name = $wpdb->prefix . 'sqp_quote_history';
$wpdb->insert(
$table_name,
array(
'session_id' => session_id(),
'user_data' => json_encode($form_data),
'calculated_price' => $result['total_price']
),
array('%s', '%s', '%f')
);
}
}
前端JavaScript交互
/**
* 前端交互脚本
* 处理表单交互和AJAX请求
*/
jQuery(document).ready(function($) {
// 实时计算预览
$('.sqp-quantity, .sqp-product-option').on('change input', function() {
calculatePreview();
});
// 表单提交
$('#sqp-quote-form').on('submit', function(e) {
e.preventDefault();
calculateFullQuote();
});
// 计算预览
function calculatePreview() {
var formData = {
product_type: $('input[name="product_type"]:checked').val(),
quantity: $('#sqp-quantity').val(),
material: $('#sqp-material').val()
};
// 简单预览计算(不发送到服务器)
var basePrice = getBasePrice(formData.product_type);
var quantity = parseInt(formData.quantity) || 0;
if (quantity > 0) {
var previewTotal = basePrice * quantity;
$('#sqp-preview-total').text('¥' + previewTotal.toFixed(2));
}
}
// 完整报价计算
function calculateFullQuote() {
var formData = $('#sqp-quote-form').serializeArray();
var data = {};
// 转换表单数据
$.each(formData, function() {
if (this.name.indexOf('[]') !== -1) {
var name = this.name.replace('[]', '');
if (!data[name]) {
data[name] = [];
}
data[name].push(this.value);
} else {
data[this.name] = this.value;
}
});
// 添加nonce
data.nonce = sqp_ajax.nonce;
data.action = 'sqp_calculate_quote';
// 显示加载状态
$('#sqp-submit-btn').prop('disabled', true).text('计算中...');
$('#sqp-result-container').html('<div class="sqp-loading">计算中,请稍候...</div>');
// 发送AJAX请求
$.post(sqp_ajax.ajax_url, data, function(response) {
if (response.success) {
displayQuoteResult(response.data);
} else {
displayQuoteError(response.data);
}
}).fail(function() {
displayQuoteError({message: '网络错误,请稍后重试'});
}).always(function() {
$('#sqp-submit-btn').prop('disabled', false).text('获取报价');
});
}
// 显示报价结果
function displayQuoteResult(result) {
var html = '<div class="sqp-quote-result">';
html += '<h3>报价结果</h3>';
html += '<div class="sqp-price-summary">';
html += '<p>单价: <strong>' + result.currency_symbol + result.unit_price + '</strong></p>';
html += '<p>数量: <strong>' + result.quantity + ' 件</strong></p>';
html += '<p class="sqp-total-price">总价: <strong>' + result.currency_symbol + result.total_price + '</strong></p>';
html += '</div>';
// 价格明细
html += '<div class="sqp-price-breakdown">';
html += '<h4>价格明细</h4>';
html += '<ul>';
html += '<li>基础价格: ' + result.currency_symbol + result.breakdown.base_price + '</li>';
html += '<li>材料成本: ' + result.currency_symbol + result.breakdown.material_cost + '</li>';
html += '<li>加工成本: ' + result.currency_symbol + result.breakdown.processing_cost + '</li>';
html += '<li>特殊工艺: ' + result.currency_symbol + result.breakdown.special_process_cost + '</li>';
html += '<li>小批量系数: ×' + result.breakdown.batch_factor + '</li>';
html += '<li>利润率: +' + result.breakdown.markup_percentage + '%</li>';
html += '</ul>';
html += '</div>';
// 操作按钮
html += '<div class="sqp-result-actions">';
html += '<button class="sqp-download-btn" onclick="downloadQuotePDF()">下载报价单</button>';
html += '<button class="sqp-contact-btn" onclick="contactSales()">联系销售</button>';
html += '</div>';
html += '</div>';
$('#sqp-result-container').html(html);
// 滚动到结果区域
$('html, body').animate({
scrollTop: $('#sqp-result-container').offset().top - 100
}, 500);
}
// 显示错误信息
function displayQuoteError(errorData) {
var html = '<div class="sqp-error-message">';
html += '<h4>计算失败</h4>';
html += '<p>' + errorData.message + '</p>';
if (errorData.errors && errorData.errors.length > 0) {
html += '<ul>';
errorData.errors.forEach(function(error) {
html += '<li>' + error + '</li>';
});
html += '</ul>';
}
html += '</div>';
$('#sqp-result-container').html(html);
}
// 获取基础价格(本地计算)
function getBasePrice(productType) {
var prices = {
'product_a': 50.00,
'product_b': 75.00,
'product_c': 100.00
};
return prices[productType] || 50.00;
}
});
// 下载报价单PDF
function downloadQuotePDF() {
alert('PDF下载功能需要集成PDF生成库,如TCPDF或mPDF');
// 实际实现需要调用后端生成PDF
}
// 联系销售
function contactSales() {
window.location.href = '/contact';
}
后台管理系统
<?php
/**
* 后台设置类
* 管理插件的后台设置页面
*/
class SQP_Admin_Settings {
public function __construct() {
add_action('admin_menu', array($this, 'add_admin_menu'));
add_action('admin_init', array($this, 'register_settings'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_assets'));
}
/**
* 添加管理菜单
*/
public function add_admin_menu() {
add_menu_page(
'智能报价设置',
'智能报价',
'manage_options',
'smart-quote-pricer',
array($this, 'render_settings_page'),
'dashicons-calculator',
30
);
// 子菜单:报价历史
add_submenu_page(
'smart-quote-pricer',
'报价历史',
'报价历史',
'manage_options',
'sqp-quote-history',
array($this, 'render_history_page')
);
// 子菜单:价格配置
add_submenu_page(
'smart-quote-pricer',
'价格配置',
'价格配置',
'manage_options',
'sqp-price-config',
array($this, 'render_price_config_page')
);
}
/**
* 注册设置
*/
public function register_settings() {
register_setting('sqp_settings_group', 'sqp_settings', array($this, 'sanitize_settings'));
// 基本设置部分
add_settings_section(
'sqp_basic_settings',
'基本设置',
array($this, 'render_basic_settings_section'),
'smart-quote-pricer'
);
// 价格设置部分
add_settings_section(
'sqp_price_settings',
'价格设置',
array($this, 'render_price_settings_section'),
'smart-quote-pricer'
);
// 添加设置字段
$this->add_settings_fields();
}
/**
* 添加设置字段
*/
private function add_settings_fields() {
// 货币符号
add_settings_field(
'currency_symbol',
'货币符号',
array($this, 'render_currency_field'),
'smart-quote-pricer',
'sqp_basic_settings'
);
// 基础利润率
add_settings_field(
'base_markup_percentage',
'基础利润率 (%)',
array($this, 'render_markup_field'),
'smart-quote-pricer',
'sqp_price_settings'
);
// 最小订单量
add_settings_field(
'min_order_quantity',
'最小订单量',
array($this, 'render_min_qty_field'),
'smart-quote-pricer',
'sqp_basic_settings'
);
// 最大订单量
add_settings_field(
'max_order_quantity',
'最大订单量',
array($this, 'render_max_qty_field'),
'smart-quote-pricer',
'sqp_basic_settings'
);
}
/**
* 渲染设置页面
*/
public function render_settings_page() {
if (!current_user_can('manage_options')) {
return;
}
?>
<div class="wrap">
<h1><?php echo esc_html(get_admin_page_title()); ?></h1>
<form action="options.php" method="post">
<?php
settings_fields('sqp_settings_group');
do_settings_sections('smart-quote-pricer');
submit_button('保存设置');
?>
</form>
<div class="sqp-admin-info">
<h3>使用说明</h3>
<p>1. 在文章或页面中使用短代码 <code>[smart_quote_form]</code> 显示报价表单</p>
<p>2. 确保所有价格设置符合您的成本结构</p>
<p>3. 定期检查报价历史,了解客户需求</p>
</div>
</div>
<?php
}
/**
* 渲染报价历史页面
*/
public function render_history_page() {
global $wpdb;
$table_name = $wpdb->prefix . 'sqp_quote_history';
$quotes = $wpdb->get_results(
"SELECT * FROM $table_name ORDER BY created_at DESC LIMIT 100"
);
?>
<div class="wrap">
<h1>报价历史</h1>
<table class="wp-list-table widefat fixed striped">
<thead>
<tr>
<th>ID</th>
<th>会话ID</th>
<th>总价</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<?php foreach ($quotes as $quote): ?>
<tr>
<td><?php echo $quote->id; ?></td>
<td><?php echo substr($quote->session_id, 0, 10) . '...'; ?></td>
<td><?php echo get_option('sqp_settings')['currency_symbol'] . $quote->calculated_price; ?></td>
<td><?php echo $quote->created_at; ?></td>
<td>
<button class="button button-small view-quote-details"
data-quote-id="<?php echo $quote->id; ?>">
查看详情
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<div id="sqp-quote-details-modal" style="display:none;">
<div class="modal-content">
<h3>报价详情</h3>
<div id="quote-details-content"></div>
<button class="button close-modal">关闭</button>
</div>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('.view-quote-details').on('click', function() {
var quoteId = $(this).data('quote-id');
$.ajax({
url: ajaxurl,
method: 'POST',
data: {
action: 'sqp_get_quote_details',
quote_id: quoteId,
nonce: '<?php echo wp_create_nonce('sqp_admin_nonce'); ?>'
},
success: function(response) {
if (response.success) {
$('#quote-details-content').html(response.data);
$('#sqp-quote-details-modal').show();
}
}
});
});
$('.close-modal').on('click', function() {
$('#sqp-quote-details-modal').hide();
});
});
</script>
<?php
}
/**
* 渲染价格配置页面
*/
public function render_price_config_page() {
?>
<div class="wrap">
<h1>价格配置</h1>
<div class="sqp-price-config">
<form method="post" action="options.php">
<input type="hidden" name="action" value="sqp_update_price_config">
<h3>产品基础价格</h3>
<table class="form-table">
<tr>
<th>产品A</th>
<td>
<input type="number" step="0.01" name="product_a_price"
value="50.00" class="regular-text">
</td>
</tr>
<tr>
<th>产品B</th>
<td>
<input type="number" step="0.01" name="product_b_price"
value="75.00" class="regular-text">
</td>
</tr>
<tr>
<th>产品C</th>
<td>
<input type="number" step="0.01" name="product_c_price"
value="100.00" class="regular-text">
</td>
</tr>
</table>
<h3>材料成本</h3>
<table class="form-table">
<tr>
<th>标准材料</th>
<td>
<input type="number" step="0.01" name="material_standard"
value="10.00" class="regular-text">
</td>
</tr>
<tr>
<th>高级材料</th>
<td>
<input type="number" step="0.01" name="material_premium"
value="25.00" class="regular-text">
</td>
</tr>
<tr>
<th>豪华材料</th>
<td>
<input type="number" step="0.01" name="material_luxury"
value="50.00" class="regular-text">
</td>
</tr>
</table>
<?php submit_button('更新价格配置'); ?>
</form>
</div>
</div>
<?php
}
/**
* 清理设置数据
*/
public function sanitize_settings($input) {
$sanitized = array();
$sanitized['currency_symbol'] = sanitize_text_field($input['currency_symbol']);
$sanitized['base_markup_percentage'] = floatval($input['base_markup_percentage']);
$sanitized['min_order_quantity'] = intval($input['min_order_quantity']);
$sanitized['max_order_quantity'] = intval($input['max_order_quantity']);
// 验证数据
if ($sanitized['min_order_quantity'] < 1) {
$sanitized['min_order_quantity'] = 1;
}
if ($sanitized['max_order_quantity'] < $sanitized['min_order_quantity']) {
$sanitized['max_order_quantity'] = $sanitized['min_order_quantity'] * 10;
}
return $sanitized;
}
/**
* 加载后台资源
*/
public function enqueue_admin_assets($hook) {
if (strpos($hook, 'smart-quote-pricer') === false) {
return;
}
wp_enqueue_style(
'sqp-admin',
SQP_PLUGIN_URL . 'assets/css/admin.css',
array(),
SQP_VERSION
);
}
}
前端样式设计
/* assets/css/frontend.css */
/* 报价表单样式 */
.sqp-quote-form {
background: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 8px;
padding: 30px;
margin: 20px 0;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
.sqp-form-section {
margin-bottom: 25px;
padding-bottom: 25px;
border-bottom: 1px solid #e9ecef;
}
.sqp-form-section:last-child {
border-bottom: none;
}
.sqp-form-section h3 {
color: #333;
font-size: 18px;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 2px solid #007cba;
}
.sqp-option-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
margin-bottom: 15px;
}
.sqp-option {
flex: 1;
min-width: 200px;
}
.sqp-option label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #555;
}
.sqp-option select,
.sqp-option input[type="number"] {
width: 100%;
padding: 10px;
border: 1px solid #ced4da;
border-radius: 4px;
font-size: 14px;
}
.sqp-checkbox-group {
display: flex;
flex-wrap: wrap;
gap: 15px;
}
.sqp-checkbox-item {
display: flex;
align-items: center;
gap: 8px;
}
.sqp-checkbox-item input[type="checkbox"] {
margin: 0;
}
.sqp-quantity-input {
max-width: 150px;
}
.sqp-preview {
background: #e7f5ff;
padding: 15px;
border-radius: 4px;
margin: 20px 0;
text-align: center;
}
.sqp-preview h4 {
margin: 0 0 10px 0;
color: #0056b3;
}
.sqp-preview-total {
font-size: 24px;
font-weight: bold;
color: #28a745;
}
.sqp-submit-btn {
background: #007cba;
color: white;
border: none;
padding: 12px 30px;
font-size: 16px;
border-radius: 4px;
cursor: pointer;
transition: background 0.3s;
width: 100%;
}
.sqp-submit-btn:hover {
background: #005a87;
}
.sqp-submit-btn:disabled {
background: #6c757d;
cursor: not-allowed;
}
/* 结果容器样式 */
.sqp-result-container {
margin-top: 30px;
animation: fadeIn 0.5s ease-in;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
.sqp-quote-result {
background: white;
border: 2px solid #28a745;
border-radius: 8px;
padding: 25px;
box-shadow: 0 4px 15px rgba(40, 167, 69, 0.1);
}
.sqp-price-summary {
text-align: center;
margin-bottom: 25px;
padding-bottom: 25px;
border-bottom: 2px dashed #dee2e6;
}
.sqp-price-summary p {
font-size: 18px;
margin: 10px 0;
}
.sqp-total-price {
font-size: 28px !important;
color: #28a745;
margin-top: 20px !important;
}
.sqp-price-breakdown {
background: #f8f9fa;
