文章目录
-
- 在文创产业蓬勃发展的今天,许多创作者面临资金筹集和供应链管理的双重挑战。本教程将指导您开发一个WordPress插件,实现文创项目的柔性众筹功能,并自动对接供应链系统。 核心功能需求: 项目创建与管理:创作者可以发布文创项目,设置众筹目标和期限 柔性众筹支持:支持多种众筹模式(全有或全无、灵活众筹) 供应链对接:根据众筹结果自动向供应链系统发送订单数据 支付集成:支持多种支付方式 进度追踪:支持众筹者和创作者追踪项目进展
- 首先,我们需要创建插件的基本结构。在WordPress的wp-content/plugins/目录下创建新文件夹cultural-crowdfunding-supply。 <?php /** * Plugin Name: 文创项目柔性众筹与供应链对接插件 * Plugin URI: https://yourwebsite.com/ * Description: 为文创项目提供柔性众筹功能并与供应链系统对接 * Version: 1.0.0 * Author: 您的名称 * License: GPL v2 or later * Text Domain: cultural-crowdfunding */ // 防止直接访问 if (!defined('ABSPATH')) { exit; } // 定义插件常量 define('CCS_PLUGIN_DIR', plugin_dir_path(__FILE__)); define('CCS_PLUGIN_URL', plugin_dir_url(__FILE__)); define('CCS_VERSION', '1.0.0'); // 初始化插件 class CulturalCrowdfundingSupply { private static $instance = null; 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_plugin')); register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin')); // 初始化 add_action('init', array($this, 'init')); // 管理菜单 add_action('admin_menu', array($this, 'add_admin_menu')); // 加载文本域 add_action('plugins_loaded', array($this, 'load_textdomain')); } public function activate_plugin() { // 创建必要的数据库表 $this->create_tables(); // 设置默认选项 $this->set_default_options(); // 刷新重写规则 flush_rewrite_rules(); } public function deactivate_plugin() { // 清理临时数据 // 注意:不删除用户数据 flush_rewrite_rules(); } public function load_textdomain() { load_plugin_textdomain('cultural-crowdfunding', false, dirname(plugin_basename(__FILE__)) . '/languages'); } public function init() { // 注册自定义文章类型 $this->register_post_types(); // 注册短代码 $this->register_shortcodes(); } // 其他方法将在后续部分实现 } // 启动插件 CulturalCrowdfundingSupply::get_instance(); ?>
- 我们需要创建数据库表来存储项目、众筹订单和供应链信息。 <?php // 在CulturalCrowdfundingSupply类中添加以下方法 private function create_tables() { global $wpdb; $charset_collate = $wpdb->get_charset_collate(); // 项目表 $table_projects = $wpdb->prefix . 'ccs_projects'; $table_orders = $wpdb->prefix . 'ccs_orders'; $table_supply_chain = $wpdb->prefix . 'ccs_supply_chain'; // SQL语句 $sql_projects = "CREATE TABLE IF NOT EXISTS $table_projects ( id bigint(20) NOT NULL AUTO_INCREMENT, post_id bigint(20) NOT NULL, creator_id bigint(20) NOT NULL, funding_goal decimal(10,2) NOT NULL, funds_raised decimal(10,2) DEFAULT 0.00, backers_count int(11) DEFAULT 0, start_date datetime NOT NULL, end_date datetime NOT NULL, funding_type enum('fixed','flexible') DEFAULT 'fixed', status enum('draft','active','successful','failed','canceled') DEFAULT 'draft', supply_chain_status enum('pending','ordered','producing','shipped','delivered') DEFAULT 'pending', created_at datetime DEFAULT CURRENT_TIMESTAMP, updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY post_id (post_id), KEY creator_id (creator_id), KEY status (status) ) $charset_collate;"; $sql_orders = "CREATE TABLE IF NOT EXISTS $table_orders ( id bigint(20) NOT NULL AUTO_INCREMENT, project_id bigint(20) NOT NULL, user_id bigint(20) NOT NULL, amount decimal(10,2) NOT NULL, reward_tier varchar(100) DEFAULT NULL, payment_status enum('pending','completed','refunded','failed') DEFAULT 'pending', payment_method varchar(50) DEFAULT NULL, transaction_id varchar(100) DEFAULT NULL, shipping_address text, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY project_id (project_id), KEY user_id (user_id), KEY payment_status (payment_status) ) $charset_collate;"; $sql_supply_chain = "CREATE TABLE IF NOT EXISTS $table_supply_chain ( id bigint(20) NOT NULL AUTO_INCREMENT, project_id bigint(20) NOT NULL, supplier_name varchar(200) NOT NULL, product_details text NOT NULL, quantity int(11) NOT NULL, unit_cost decimal(10,2) NOT NULL, total_cost decimal(10,2) NOT NULL, order_date datetime DEFAULT NULL, estimated_delivery date DEFAULT NULL, actual_delivery date DEFAULT NULL, status enum('pending','ordered','confirmed','shipped','received') DEFAULT 'pending', notes text, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), KEY project_id (project_id), KEY status (status) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql_projects); dbDelta($sql_orders); dbDelta($sql_supply_chain); } private function set_default_options() { $default_options = array( 'ccs_currency' => 'CNY', 'ccs_currency_symbol' => '¥', 'ccs_payment_methods' => array('alipay', 'wechat'), 'ccs_default_funding_days' => 30, 'ccs_supply_chain_api_url' => '', 'ccs_supply_chain_api_key' => '', 'ccs_min_funding_goal' => 1000, 'ccs_max_funding_goal' => 1000000, ); foreach ($default_options as $key => $value) { if (get_option($key) === false) { update_option($key, $value); } } } ?>
- 接下来,我们创建文创项目的自定义文章类型和管理界面。 <?php // 在CulturalCrowdfundingSupply类中添加以下方法 private function register_post_types() { // 注册文创项目自定义文章类型 $labels = array( 'name' => __('文创项目', 'cultural-crowdfunding'), 'singular_name' => __('文创项目', 'cultural-crowdfunding'), 'menu_name' => __('文创众筹', 'cultural-crowdfunding'), 'add_new' => __('添加新项目', 'cultural-crowdfunding'), 'add_new_item' => __('添加新文创项目', 'cultural-crowdfunding'), 'edit_item' => __('编辑文创项目', 'cultural-crowdfunding'), 'new_item' => __('新文创项目', 'cultural-crowdfunding'), 'view_item' => __('查看文创项目', 'cultural-crowdfunding'), 'search_items' => __('搜索文创项目', 'cultural-crowdfunding'), 'not_found' => __('未找到文创项目', 'cultural-crowdfunding'), 'not_found_in_trash' => __('回收站中无文创项目', 'cultural-crowdfunding'), ); $args = array( 'labels' => $labels, 'public' => true, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'query_var' => true, 'rewrite' => array('slug' => 'cultural-project'), 'capability_type' => 'post', 'has_archive' => true, 'hierarchical' => false, 'menu_position' => 30, 'menu_icon' => 'dashicons-palmtree', 'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'comments'), 'show_in_rest' => true, ); register_post_type('cultural_project', $args); // 注册项目分类 $tax_labels = array( 'name' => __('项目分类', 'cultural-crowdfunding'), 'singular_name' => __('分类', 'cultural-crowdfunding'), 'search_items' => __('搜索分类', 'cultural-crowdfunding'), 'all_items' => __('所有分类', 'cultural-crowdfunding'), 'parent_item' => __('父分类', 'cultural-crowdfunding'), 'parent_item_colon' => __('父分类:', 'cultural-crowdfunding'), 'edit_item' => __('编辑分类', 'cultural-crowdfunding'), 'update_item' => __('更新分类', 'cultural-crowdfunding'), 'add_new_item' => __('添加新分类', 'cultural-crowdfunding'), 'new_item_name' => __('新分类名称', 'cultural-crowdfunding'), 'menu_name' => __('项目分类', 'cultural-crowdfunding'), ); $tax_args = array( 'hierarchical' => true, 'labels' => $tax_labels, 'show_ui' => true, 'show_admin_column' => true, 'query_var' => true, 'rewrite' => array('slug' => 'project-category'), 'show_in_rest' => true, ); register_taxonomy('project_category', array('cultural_project'), $tax_args); } // 添加项目元数据框 public function add_project_metaboxes() { add_meta_box( 'ccs_project_details', __('项目众筹详情', 'cultural-crowdfunding'), array($this, 'render_project_metabox'), 'cultural_project', 'normal', 'high' ); add_meta_box( 'ccs_reward_tiers', __('回报设置', 'cultural-crowdfunding'), array($this, 'render_rewards_metabox'), 'cultural_project', 'normal', 'high' ); add_meta_box( 'ccs_supply_chain', __('供应链信息', 'cultural-crowdfunding'), array($this, 'render_supply_chain_metabox'), 'cultural_project', 'side', 'default' ); } public function render_project_metabox($post) { // 添加nonce字段用于安全验证 wp_nonce_field('ccs_save_project_data', 'ccs_project_meta_nonce'); // 获取现有值 $funding_goal = get_post_meta($post->ID, '_funding_goal', true); $funds_raised = get_post_meta($post->ID, '_funds_raised', true) ?: 0; $funding_type = get_post_meta($post->ID, '_funding_type', true) ?: 'fixed'; $start_date = get_post_meta($post->ID, '_start_date', true); $end_date = get_post_meta($post->ID, '_end_date', true); $backers_count = get_post_meta($post->ID, '_backers_count', true) ?: 0; // 计算进度百分比 $progress = 0; if ($funding_goal > 0) { $progress = min(100, round(($funds_raised / $funding_goal) * 100, 2)); } ?> <div class="ccs-metabox-container"> <div class="ccs-form-row"> <label for="funding_goal"><?php _e('众筹目标金额', 'cultural-crowdfunding'); ?></label> <input type="number" id="funding_goal" name="funding_goal" value="<?php echo esc_attr($funding_goal); ?>" min="0" step="0.01" required> <span class="description"><?php echo get_option('ccs_currency_symbol', '¥'); ?></span> </div> <div class="ccs-form-row"> <label for="funding_type"><?php _e('众筹类型', 'cultural-crowdfunding'); ?></label> <select id="funding_type" name="funding_type"> <option value="fixed" <?php selected($funding_type, 'fixed'); ?>> <?php _e('固定型(达到目标才成功)', 'cultural-crowdfunding'); ?> </option> <option value="flexible" <?php selected($funding_type, 'flexible'); ?>> <?php _e('灵活型(无论是否达标都获得资金)', 'cultural-crowdfunding'); ?> </option> </select> </div> <div class="ccs-form-row"> <label for="start_date"><?php _e('开始日期', 'cultural-crowdfunding'); ?></label> <input type="date" id="start_date" name="start_date" value="<?php echo esc_attr($start_date); ?>" required> </div> <div class="ccs-form-row"> <label for="end_date"><?php _e('结束日期', 'cultural-crowdfunding'); ?></label> <input type="date" id="end_date" name="end_date" value="<?php echo esc_attr($end_date); ?>" required> </div> <?php if ($funds_raised > 0): ?> <div class="ccs-progress-section"> <h4><?php _e('众筹进度', 'cultural-crowdfunding'); ?></h4> <div class="ccs-progress-bar"> <div class="ccs-progress-fill" style="width: <?php echo $progress; ?>%;"></div> </div> <p> <?php printf( __('已筹集 %s%s,达到目标的 %s%%,已有 %d 位支持者', 'cultural-crowdfunding'), get_option('ccs_currency_symbol', '¥'), number_format($funds_raised, 2), $progress, $backers_count ); ?> </p> </div> <?php endif; ?> </div> <?php } // 保存元数据 public function save_project_meta($post_id) { // 安全检查 if (!isset($_POST['ccs_project_meta_nonce']) || !wp_verify_nonce($_POST['ccs_project_meta_nonce'], 'ccs_save_project_data')) { return; } // 检查自动保存 if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) { return; } // 检查用户权限 if (!current_user_can('edit_post', $post_id)) { return; } // 保存字段 $fields = array( 'funding_goal', 'funding_type', 'start_date', 'end_date' ); foreach ($fields as $field) { if (isset($_POST[$field])) { update_post_meta($post_id, '_' . $field, sanitize_text_field($_POST[$field])); } } // 如果是新项目,在数据库表中创建记录 if (get_post_meta($post_id, '_project_db_id', true) == '') { $this->create_project_db_record($post_id); } } private function create_project_db_record($post_id) { global $wpdb; $project_data = array( 'post_id' => $post_id, 'creator_id' => get_current_user_id(), 'funding_goal' => get_post_meta($post_id, '_funding_goal', true), 'start_date' => get_post_meta($post_id, '_start_date', true), 'end_date' => get_post_meta($post_id, '_end_date', true), 'funding_type' => get_post_meta($post_id, '_funding_type', true), 'status' => 'draft' ); $wpdb->insert($wpdb->prefix . 'ccs_projects', $project_data); $project_id = $wpdb->insert_id; update_post_meta($post_id, '_project_db_id', $project_id); } ?>
- 现在实现前端众筹功能和支付处理。 <?php // 在CulturalCrowdfundingSupply类中添加以下方法 private function register_shortcodes() { 短代码 add_shortcode('ccs_project_display', array($this, 'project_display_shortcode')); // 支持项目表单 add_shortcode('ccs_back_project', array($this, 'back_project_shortcode')); // 项目列表 add_shortcode('ccs_project_list', array($this, 'project_list_shortcode')); } public function project_display_shortcode($atts) { global $post; $atts = shortcode_atts(array( 'id' => $post->ID, ), $atts, 'ccs_project_display'); $project_id = intval($atts['id']); $project_post = get_post($project_id); if (!$project_post || $project_post->post_type !== 'cultural_project') { return '<p>' . __('项目不存在', 'cultural-crowdfunding') . '</p>'; } // 获取项目数据 $funding_goal = get_post_meta($project_id, '_funding_goal', true); $funds_raised = get_post_meta($project_id, '_funds_raised', true) ?: 0; $backers_count = get_post_meta($project_id, '_backers_count', true) ?: 0; $start_date = get_post_meta($project_id, '_start_date', true); $end_date = get_post_meta($project_id, '_end_date', true); $funding_type = get_post_meta($project_id, '_funding_type', true); // 计算剩余时间和进度 $current_time = current_time('timestamp'); $end_timestamp = strtotime($end_date); $days_left = max(0, floor(($end_timestamp - $current_time) / (60 * 60 * 24))); $progress = 0; if ($funding_goal > 0) { $progress = min(100, round(($funds_raised / $funding_goal) * 100, 2)); } ob_start(); ?> <div class="ccs-project-display"> <div class="ccs-project-header"> <h2><?php echo esc_html($project_post->post_title); ?></h2> <div class="ccs-project-meta"> <span class="ccs-creator"> <?php _e('创作者:', 'cultural-crowdfunding'); ?> <?php echo get_the_author_meta('display_name', $project_post->post_author); ?> </span> <span class="ccs-category"> <?php echo get_the_term_list($project_id, 'project_category', '', ', '); ?> </span> </div> </div> <div class="ccs-project-content"> <div class="ccs-main-content"> <?php echo apply_filters('the_content', $project_post->post_content); ?> </div> <div class="ccs-sidebar"> <div class="ccs-funding-stats"> <div class="ccs-stat-item"> <span class="ccs-stat-value"><?php echo get_option('ccs_currency_symbol', '¥') . number_format($funds_raised, 2); ?></span> <span class="ccs-stat-label"><?php _e('已筹集', 'cultural-crowdfunding'); ?></span> </div> <div class="ccs-stat-item"> <span class="ccs-stat-value"><?php echo $progress; ?>%</span> <span class="ccs-stat-label"><?php _e('达成进度', 'cultural-crowdfunding'); ?></span> </div> <div class="ccs-stat-item"> <span class="ccs-stat-value"><?php echo $backers_count; ?></span> <span class="ccs-stat-label"><?php _e('支持者', 'cultural-crowdfunding'); ?></span> </div> <div class="ccs-stat-item"> <span class="ccs-stat-value"><?php echo $days_left; ?></span> <span class="ccs-stat-label"><?php _e('剩余天数', 'cultural-crowdfunding'); ?></span> </div> </div> <div class="ccs-progress-bar-container"> <div class="ccs-progress-bar"> <div class="ccs-progress-fill" style="width: <?php echo $progress; ?>%;"></div> </div> <div class="ccs-progress-text"> <?php printf( __('目标: %s%s', 'cultural-crowdfunding'), get_option('ccs_currency_symbol', '¥'), number_format($funding_goal, 2) ); ?> </div> </div> <div class="ccs-action-buttons"> <button class="ccs-back-project-btn" data-project-id="<?php echo $project_id; ?>"> <?php _e('支持此项目', 'cultural-crowdfunding'); ?> </button> <button class="ccs-share-project-btn"> <?php _e('分享项目', 'cultural-crowdfunding'); ?> </button> </div> <?php // 显示回报选项 $this->display_reward_tiers($project_id); ?> </div> </div> </div> <script> jQuery(document).ready(function($) { $('.ccs-back-project-btn').on('click', function() { var projectId = $(this).data('project-id'); $('html, body').animate({ scrollTop: $('#ccs-back-form-' + projectId).offset().top - 100 }, 500); }); }); </script> <?php return ob_get_clean(); } private function display_reward_tiers($project_id) { $rewards = get_post_meta($project_id, '_reward_tiers', true); if (empty($rewards) || !is_array($rewards)) { return; } ?> <div class="ccs-reward-tiers"> <h3><?php _e('选择回报', 'cultural-crowdfunding'); ?></h3> <?php foreach ($rewards as $index => $reward): ?> <?php if (!empty($reward['title'])): ?> <div class="ccs-reward-tier"> <div class="ccs-reward-header"> <h4><?php echo esc_html($reward['title']); ?></h4> <span class="ccs-reward-price"> <?php echo get_option('ccs_currency_symbol', '¥') . number_format($reward['amount'], 2); ?> </span> </div> <p class="ccs-reward-description"><?php echo esc_html($reward['description']); ?></p> <div class="ccs-reward-meta"> <span class="ccs-backers-count"> <?php printf(__('已有 %d 人选择', 'cultural-crowdfunding'), $reward['backers_count'] ?? 0); ?> </span> <?php if (!empty($reward['estimated_delivery'])): ?> <span class="ccs-delivery-date"> <?php printf(__('预计发货: %s', 'cultural-crowdfunding'), $reward['estimated_delivery']); ?> </span> <?php endif; ?> </div> <button class="ccs-select-reward-btn" data-project-id="<?php echo $project_id; ?>" data-reward-index="<?php echo $index; ?>"> <?php _e('选择此回报', 'cultural-crowdfunding'); ?> </button> </div> <?php endif; ?> <?php endforeach; ?> </div> <?php } public function back_project_shortcode($atts) { $atts = shortcode_atts(array( 'project_id' => 0, ), $atts, 'ccs_back_project'); $project_id = intval($atts['project_id']); if (!$project_id) { global $post; $project_id = $post->ID; } ob_start(); ?> <div id="ccs-back-form-<?php echo $project_id; ?>" class="ccs-back-project-form"> <h3><?php _e('支持此项目', 'cultural-crowdfunding'); ?></h3> <form id="ccs-back-form-<?php echo $project_id; ?>-form" class="ccs-back-form"> <?php wp_nonce_field('ccs_back_project_' . $project_id, 'ccs_back_nonce'); ?> <input type="hidden" name="project_id" value="<?php echo $project_id; ?>"> <div class="ccs-form-group"> <label for="backer_amount"><?php _e('支持金额', 'cultural-crowdfunding'); ?></label> <div class="ccs-amount-input"> <span class="ccs-currency-symbol"><?php echo get_option('ccs_currency_symbol', '¥'); ?></span> <input type="number" id="backer_amount" name="amount" min="1" step="0.01" required placeholder="<?php _e('输入支持金额', 'cultural-crowdfunding'); ?>"> </div> </div> <div class="ccs-form-group"> <label for="reward_tier"><?php _e('选择回报', 'cultural-crowdfunding'); ?></label> <select id="reward_tier" name="reward_tier"> <option value=""><?php _e('无需回报,单纯支持', 'cultural-crowdfunding'); ?></option> <?php $rewards = get_post_meta($project_id, '_reward_tiers', true); if (is_array($rewards)) { foreach ($rewards as $index => $reward) { if (!empty($reward['title'])) { echo '<option value="' . $index . '">' . esc_html($reward['title']) . ' - ' . get_option('ccs_currency_symbol', '¥') . number_format($reward['amount'], 2) . '</option>'; } } } ?> </select> </div> <div class="ccs-form-group"> <label for="backer_message"><?php _e('留言 (可选)', 'cultural-crowdfunding'); ?></label> <textarea id="backer_message" name="message" rows="3" placeholder="<?php _e('给创作者留言...', 'cultural-crowdfunding'); ?>"></textarea> </div> <div class="ccs-form-group"> <label for="payment_method"><?php _e('支付方式', 'cultural-crowdfunding'); ?></label> <select id="payment_method" name="payment_method" required> <?php $payment_methods = get_option('ccs_payment_methods', array('alipay', 'wechat')); foreach ($payment_methods as $method) { $method_name = $this->get_payment_method_name($method); echo '<option value="' . $method . '">' . $method_name . '</option>'; } ?> </select> </div> <div class="ccs-form-group"> <label> <input type="checkbox" name="agree_terms" required> <?php _e('我同意相关条款和条件', 'cultural-crowdfunding'); ?> </label> </div> <button type="submit" class="ccs-submit-back-btn"> <?php _e('确认支持', 'cultural-crowdfunding'); ?> </button> </form> <div id="ccs-payment-qrcode-<?php echo $project_id; ?>" class="ccs-payment-qrcode" style="display: none;"> <h4><?php _e('请扫码支付', 'cultural-crowdfunding'); ?></h4> <div class="ccs-qrcode-container"></div> <p class="ccs-payment-instructions"></p> </div> </div> <script> jQuery(document).ready(function($) { $('#ccs-back-form-<?php echo $project_id; ?>-form').on('submit', function(e) { e.preventDefault(); var formData = $(this).serialize(); $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action: 'ccs_process_backing', form_data: formData }, beforeSend: function() { $('.ccs-submit-back-btn').prop('disabled', true).text('<?php _e("处理中...", "cultural-crowdfunding"); ?>'); }, success: function(response) { if (response.success) { if (response.data.payment_url) { // 跳转到支付页面 window.location.href = response.data.payment_url; } else if (response.data.qrcode) { // 显示二维码 $('#ccs-payment-qrcode-<?php echo $project_id; ?> .ccs-qrcode-container').html(response.data.qrcode); $('#ccs-payment-qrcode-<?php echo $project_id; ?> .ccs-payment-instructions').text(response.data.instructions); $('#ccs-payment-qrcode-<?php echo $project_id; ?>').show(); } } else { alert(response.data.message); $('.ccs-submit-back-btn').prop('disabled', false).text('<?php _e("确认支持", "cultural-crowdfunding"); ?>'); } } }); }); }); </script> <?php return ob_get_clean(); } // 处理支持请求的AJAX回调public function ajax_process_backing() { check_ajax_referer('ccs_back_project_' . $_POST['project_id'], 'ccs_back_nonce'); $project_id = intval($_POST['project_id']); $amount = floatval($_POST['amount']); $user_id = get_current_user_id(); // 验证数据 if ($amount <= 0) { wp_send_json_error(array('message' => __('金额无效', 'cultural-crowdfunding'))); } // 创建订单记录 $order_data = array( 'project_id' => $project_id, 'user_id' => $user_id, 'amount' => $amount, 'reward_tier' => sanitize_text_field($_POST['reward_tier']), 'payment_method' => sanitize_text_field($_POST['payment_method']), 'payment_status' => 'pending' ); global $wpdb; $wpdb->insert($wpdb->prefix . 'ccs_orders', $order_data); $order_id = $wpdb->insert_id; // 生成支付数据 $payment_data = $this->generate_payment($order_id, $amount, $_POST['payment_method']); wp_send_json_success($payment_data); } private function generate_payment($order_id, $amount, $payment_method) { // 这里应该集成实际的支付网关 // 以下为示例代码 $payment_data = array(); switch ($payment_method) { case 'alipay': // 支付宝支付 $payment_data['payment_url'] = $this->generate_alipay_url($order_id, $amount); break; case 'wechat': // 微信支付 - 生成二维码 $payment_data['qrcode'] = '<img src="' . $this->generate_wechat_qrcode($order_id, $amount) . '" alt="微信支付二维码">'; $payment_data['instructions'] = __('请使用微信扫描二维码完成支付', 'cultural-crowdfunding'); break; default: // 其他支付方式 break; } return $payment_data; } private function generate_alipay_url($order_id, $amount) { // 实际开发中应调用支付宝API // 这里返回示例URL return add_query_arg(array( 'order_id' => $order_id, 'amount' => $amount, 'return_url' => home_url('/payment-success/') ), home_url('/process-payment/alipay/')); } private function generate_wechat_qrcode($order_id, $amount) { // 实际开发中应调用微信支付API // 这里返回示例二维码图片URL return 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' . urlencode(home_url('/process-payment/wechat/?order_id=' . $order_id)); } private function get_payment_method_name($method) { $names = array( 'alipay' => __('支付宝', 'cultural-crowdfunding'), 'wechat' => __('微信支付', 'cultural-crowdfunding'), 'bank' => __('银行转账', 'cultural-crowdfunding'), 'paypal' => __('PayPal', 'cultural-crowdfunding'), ); return isset($names[$method]) ? $names[$method] : ucfirst($method); }?> ## 六、供应链对接系统 实现供应链系统的对接功能。 <?php// 在CulturalCrowdfundingSupply类中添加以下方法 public function render_supply_chain_metabox($post) { $project_db_id = get_post_meta($post->ID, '_project_db_id', true); $supply_chain_status = get_post_meta($post->ID, '_supply_chain_status', true) ?: 'pending'; ?> <div class="ccs-supply-chain-info"> <div class="ccs-form-row"> <label for="supply_chain_status"><?php _e('供应链状态', 'cultural-crowdfunding'); ?></label> <select id="supply_chain_status" name="supply_chain_status"> <option value="pending" <?php selected($supply_chain_status, 'pending'); ?>> <?php _e('待处理', 'cultural-crowdfunding'); ?> </
在文创产业蓬勃发展的今天,许多创作者面临资金筹集和供应链管理的双重挑战。本教程将指导您开发一个WordPress插件,实现文创项目的柔性众筹功能,并自动对接供应链系统。
核心功能需求:
- 项目创建与管理:创作者可以发布文创项目,设置众筹目标和期限
- 柔性众筹支持:支持多种众筹模式(全有或全无、灵活众筹)
- 供应链对接:根据众筹结果自动向供应链系统发送订单数据
- 支付集成:支持多种支付方式
- 进度追踪:支持众筹者和创作者追踪项目进展
首先,我们需要创建插件的基本结构。在WordPress的wp-content/plugins/目录下创建新文件夹cultural-crowdfunding-supply。
<?php
/**
* Plugin Name: 文创项目柔性众筹与供应链对接插件
* Plugin URI: https://yourwebsite.com/
* Description: 为文创项目提供柔性众筹功能并与供应链系统对接
* Version: 1.0.0
* Author: 您的名称
* License: GPL v2 or later
* Text Domain: cultural-crowdfunding
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
// 定义插件常量
define('CCS_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('CCS_PLUGIN_URL', plugin_dir_url(__FILE__));
define('CCS_VERSION', '1.0.0');
// 初始化插件
class CulturalCrowdfundingSupply {
private static $instance = null;
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_plugin'));
register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin'));
// 初始化
add_action('init', array($this, 'init'));
// 管理菜单
add_action('admin_menu', array($this, 'add_admin_menu'));
// 加载文本域
add_action('plugins_loaded', array($this, 'load_textdomain'));
}
public function activate_plugin() {
// 创建必要的数据库表
$this->create_tables();
// 设置默认选项
$this->set_default_options();
// 刷新重写规则
flush_rewrite_rules();
}
public function deactivate_plugin() {
// 清理临时数据
// 注意:不删除用户数据
flush_rewrite_rules();
}
public function load_textdomain() {
load_plugin_textdomain('cultural-crowdfunding', false, dirname(plugin_basename(__FILE__)) . '/languages');
}
public function init() {
// 注册自定义文章类型
$this->register_post_types();
// 注册短代码
$this->register_shortcodes();
}
// 其他方法将在后续部分实现
}
// 启动插件
CulturalCrowdfundingSupply::get_instance();
?>
我们需要创建数据库表来存储项目、众筹订单和供应链信息。
<?php
// 在CulturalCrowdfundingSupply类中添加以下方法
private function create_tables() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// 项目表
$table_projects = $wpdb->prefix . 'ccs_projects';
$table_orders = $wpdb->prefix . 'ccs_orders';
$table_supply_chain = $wpdb->prefix . 'ccs_supply_chain';
// SQL语句
$sql_projects = "CREATE TABLE IF NOT EXISTS $table_projects (
id bigint(20) NOT NULL AUTO_INCREMENT,
post_id bigint(20) NOT NULL,
creator_id bigint(20) NOT NULL,
funding_goal decimal(10,2) NOT NULL,
funds_raised decimal(10,2) DEFAULT 0.00,
backers_count int(11) DEFAULT 0,
start_date datetime NOT NULL,
end_date datetime NOT NULL,
funding_type enum('fixed','flexible') DEFAULT 'fixed',
status enum('draft','active','successful','failed','canceled') DEFAULT 'draft',
supply_chain_status enum('pending','ordered','producing','shipped','delivered') DEFAULT 'pending',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY post_id (post_id),
KEY creator_id (creator_id),
KEY status (status)
) $charset_collate;";
$sql_orders = "CREATE TABLE IF NOT EXISTS $table_orders (
id bigint(20) NOT NULL AUTO_INCREMENT,
project_id bigint(20) NOT NULL,
user_id bigint(20) NOT NULL,
amount decimal(10,2) NOT NULL,
reward_tier varchar(100) DEFAULT NULL,
payment_status enum('pending','completed','refunded','failed') DEFAULT 'pending',
payment_method varchar(50) DEFAULT NULL,
transaction_id varchar(100) DEFAULT NULL,
shipping_address text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY project_id (project_id),
KEY user_id (user_id),
KEY payment_status (payment_status)
) $charset_collate;";
$sql_supply_chain = "CREATE TABLE IF NOT EXISTS $table_supply_chain (
id bigint(20) NOT NULL AUTO_INCREMENT,
project_id bigint(20) NOT NULL,
supplier_name varchar(200) NOT NULL,
product_details text NOT NULL,
quantity int(11) NOT NULL,
unit_cost decimal(10,2) NOT NULL,
total_cost decimal(10,2) NOT NULL,
order_date datetime DEFAULT NULL,
estimated_delivery date DEFAULT NULL,
actual_delivery date DEFAULT NULL,
status enum('pending','ordered','confirmed','shipped','received') DEFAULT 'pending',
notes text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY project_id (project_id),
KEY status (status)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_projects);
dbDelta($sql_orders);
dbDelta($sql_supply_chain);
}
private function set_default_options() {
$default_options = array(
'ccs_currency' => 'CNY',
'ccs_currency_symbol' => '¥',
'ccs_payment_methods' => array('alipay', 'wechat'),
'ccs_default_funding_days' => 30,
'ccs_supply_chain_api_url' => '',
'ccs_supply_chain_api_key' => '',
'ccs_min_funding_goal' => 1000,
'ccs_max_funding_goal' => 1000000,
);
foreach ($default_options as $key => $value) {
if (get_option($key) === false) {
update_option($key, $value);
}
}
}
?>
接下来,我们创建文创项目的自定义文章类型和管理界面。
<?php
// 在CulturalCrowdfundingSupply类中添加以下方法
private function register_post_types() {
// 注册文创项目自定义文章类型
$labels = array(
'name' => __('文创项目', 'cultural-crowdfunding'),
'singular_name' => __('文创项目', 'cultural-crowdfunding'),
'menu_name' => __('文创众筹', 'cultural-crowdfunding'),
'add_new' => __('添加新项目', 'cultural-crowdfunding'),
'add_new_item' => __('添加新文创项目', 'cultural-crowdfunding'),
'edit_item' => __('编辑文创项目', 'cultural-crowdfunding'),
'new_item' => __('新文创项目', 'cultural-crowdfunding'),
'view_item' => __('查看文创项目', 'cultural-crowdfunding'),
'search_items' => __('搜索文创项目', 'cultural-crowdfunding'),
'not_found' => __('未找到文创项目', 'cultural-crowdfunding'),
'not_found_in_trash' => __('回收站中无文创项目', 'cultural-crowdfunding'),
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array('slug' => 'cultural-project'),
'capability_type' => 'post',
'has_archive' => true,
'hierarchical' => false,
'menu_position' => 30,
'menu_icon' => 'dashicons-palmtree',
'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'comments'),
'show_in_rest' => true,
);
register_post_type('cultural_project', $args);
// 注册项目分类
$tax_labels = array(
'name' => __('项目分类', 'cultural-crowdfunding'),
'singular_name' => __('分类', 'cultural-crowdfunding'),
'search_items' => __('搜索分类', 'cultural-crowdfunding'),
'all_items' => __('所有分类', 'cultural-crowdfunding'),
'parent_item' => __('父分类', 'cultural-crowdfunding'),
'parent_item_colon' => __('父分类:', 'cultural-crowdfunding'),
'edit_item' => __('编辑分类', 'cultural-crowdfunding'),
'update_item' => __('更新分类', 'cultural-crowdfunding'),
'add_new_item' => __('添加新分类', 'cultural-crowdfunding'),
'new_item_name' => __('新分类名称', 'cultural-crowdfunding'),
'menu_name' => __('项目分类', 'cultural-crowdfunding'),
);
$tax_args = array(
'hierarchical' => true,
'labels' => $tax_labels,
'show_ui' => true,
'show_admin_column' => true,
'query_var' => true,
'rewrite' => array('slug' => 'project-category'),
'show_in_rest' => true,
);
register_taxonomy('project_category', array('cultural_project'), $tax_args);
}
// 添加项目元数据框
public function add_project_metaboxes() {
add_meta_box(
'ccs_project_details',
__('项目众筹详情', 'cultural-crowdfunding'),
array($this, 'render_project_metabox'),
'cultural_project',
'normal',
'high'
);
add_meta_box(
'ccs_reward_tiers',
__('回报设置', 'cultural-crowdfunding'),
array($this, 'render_rewards_metabox'),
'cultural_project',
'normal',
'high'
);
add_meta_box(
'ccs_supply_chain',
__('供应链信息', 'cultural-crowdfunding'),
array($this, 'render_supply_chain_metabox'),
'cultural_project',
'side',
'default'
);
}
public function render_project_metabox($post) {
// 添加nonce字段用于安全验证
wp_nonce_field('ccs_save_project_data', 'ccs_project_meta_nonce');
// 获取现有值
$funding_goal = get_post_meta($post->ID, '_funding_goal', true);
$funds_raised = get_post_meta($post->ID, '_funds_raised', true) ?: 0;
$funding_type = get_post_meta($post->ID, '_funding_type', true) ?: 'fixed';
$start_date = get_post_meta($post->ID, '_start_date', true);
$end_date = get_post_meta($post->ID, '_end_date', true);
$backers_count = get_post_meta($post->ID, '_backers_count', true) ?: 0;
// 计算进度百分比
$progress = 0;
if ($funding_goal > 0) {
$progress = min(100, round(($funds_raised / $funding_goal) * 100, 2));
}
?>
<div class="ccs-metabox-container">
<div class="ccs-form-row">
<label for="funding_goal"><?php _e('众筹目标金额', 'cultural-crowdfunding'); ?></label>
<input type="number" id="funding_goal" name="funding_goal"
value="<?php echo esc_attr($funding_goal); ?>"
min="0" step="0.01" required>
<span class="description"><?php echo get_option('ccs_currency_symbol', '¥'); ?></span>
</div>
<div class="ccs-form-row">
<label for="funding_type"><?php _e('众筹类型', 'cultural-crowdfunding'); ?></label>
<select id="funding_type" name="funding_type">
<option value="fixed" <?php selected($funding_type, 'fixed'); ?>>
<?php _e('固定型(达到目标才成功)', 'cultural-crowdfunding'); ?>
</option>
<option value="flexible" <?php selected($funding_type, 'flexible'); ?>>
<?php _e('灵活型(无论是否达标都获得资金)', 'cultural-crowdfunding'); ?>
</option>
</select>
</div>
<div class="ccs-form-row">
<label for="start_date"><?php _e('开始日期', 'cultural-crowdfunding'); ?></label>
<input type="date" id="start_date" name="start_date"
value="<?php echo esc_attr($start_date); ?>" required>
</div>
<div class="ccs-form-row">
<label for="end_date"><?php _e('结束日期', 'cultural-crowdfunding'); ?></label>
<input type="date" id="end_date" name="end_date"
value="<?php echo esc_attr($end_date); ?>" required>
</div>
<?php if ($funds_raised > 0): ?>
<div class="ccs-progress-section">
<h4><?php _e('众筹进度', 'cultural-crowdfunding'); ?></h4>
<div class="ccs-progress-bar">
<div class="ccs-progress-fill" style="width: <?php echo $progress; ?>%;"></div>
</div>
<p>
<?php printf(
__('已筹集 %s%s,达到目标的 %s%%,已有 %d 位支持者', 'cultural-crowdfunding'),
get_option('ccs_currency_symbol', '¥'),
number_format($funds_raised, 2),
$progress,
$backers_count
); ?>
</p>
</div>
<?php endif; ?>
</div>
<?php
}
// 保存元数据
public function save_project_meta($post_id) {
// 安全检查
if (!isset($_POST['ccs_project_meta_nonce']) ||
!wp_verify_nonce($_POST['ccs_project_meta_nonce'], 'ccs_save_project_data')) {
return;
}
// 检查自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// 检查用户权限
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存字段
$fields = array(
'funding_goal',
'funding_type',
'start_date',
'end_date'
);
foreach ($fields as $field) {
if (isset($_POST[$field])) {
update_post_meta($post_id, '_' . $field, sanitize_text_field($_POST[$field]));
}
}
// 如果是新项目,在数据库表中创建记录
if (get_post_meta($post_id, '_project_db_id', true) == '') {
$this->create_project_db_record($post_id);
}
}
private function create_project_db_record($post_id) {
global $wpdb;
$project_data = array(
'post_id' => $post_id,
'creator_id' => get_current_user_id(),
'funding_goal' => get_post_meta($post_id, '_funding_goal', true),
'start_date' => get_post_meta($post_id, '_start_date', true),
'end_date' => get_post_meta($post_id, '_end_date', true),
'funding_type' => get_post_meta($post_id, '_funding_type', true),
'status' => 'draft'
);
$wpdb->insert($wpdb->prefix . 'ccs_projects', $project_data);
$project_id = $wpdb->insert_id;
update_post_meta($post_id, '_project_db_id', $project_id);
}
?>
现在实现前端众筹功能和支付处理。
<?php
// 在CulturalCrowdfundingSupply类中添加以下方法
private function register_shortcodes() {
短代码
add_shortcode('ccs_project_display', array($this, 'project_display_shortcode'));
// 支持项目表单
add_shortcode('ccs_back_project', array($this, 'back_project_shortcode'));
// 项目列表
add_shortcode('ccs_project_list', array($this, 'project_list_shortcode'));
}
public function project_display_shortcode($atts) {
global $post;
$atts = shortcode_atts(array(
'id' => $post->ID,
), $atts, 'ccs_project_display');
$project_id = intval($atts['id']);
$project_post = get_post($project_id);
if (!$project_post || $project_post->post_type !== 'cultural_project') {
return '<p>' . __('项目不存在', 'cultural-crowdfunding') . '</p>';
}
// 获取项目数据
$funding_goal = get_post_meta($project_id, '_funding_goal', true);
$funds_raised = get_post_meta($project_id, '_funds_raised', true) ?: 0;
$backers_count = get_post_meta($project_id, '_backers_count', true) ?: 0;
$start_date = get_post_meta($project_id, '_start_date', true);
$end_date = get_post_meta($project_id, '_end_date', true);
$funding_type = get_post_meta($project_id, '_funding_type', true);
// 计算剩余时间和进度
$current_time = current_time('timestamp');
$end_timestamp = strtotime($end_date);
$days_left = max(0, floor(($end_timestamp - $current_time) / (60 * 60 * 24)));
$progress = 0;
if ($funding_goal > 0) {
$progress = min(100, round(($funds_raised / $funding_goal) * 100, 2));
}
ob_start();
?>
<div class="ccs-project-display">
<div class="ccs-project-header">
<h2><?php echo esc_html($project_post->post_title); ?></h2>
<div class="ccs-project-meta">
<span class="ccs-creator">
<?php _e('创作者:', 'cultural-crowdfunding'); ?>
<?php echo get_the_author_meta('display_name', $project_post->post_author); ?>
</span>
<span class="ccs-category">
<?php echo get_the_term_list($project_id, 'project_category', '', ', '); ?>
</span>
</div>
</div>
<div class="ccs-project-content">
<div class="ccs-main-content">
<?php echo apply_filters('the_content', $project_post->post_content); ?>
</div>
<div class="ccs-sidebar">
<div class="ccs-funding-stats">
<div class="ccs-stat-item">
<span class="ccs-stat-value"><?php echo get_option('ccs_currency_symbol', '¥') . number_format($funds_raised, 2); ?></span>
<span class="ccs-stat-label"><?php _e('已筹集', 'cultural-crowdfunding'); ?></span>
</div>
<div class="ccs-stat-item">
<span class="ccs-stat-value"><?php echo $progress; ?>%</span>
<span class="ccs-stat-label"><?php _e('达成进度', 'cultural-crowdfunding'); ?></span>
</div>
<div class="ccs-stat-item">
<span class="ccs-stat-value"><?php echo $backers_count; ?></span>
<span class="ccs-stat-label"><?php _e('支持者', 'cultural-crowdfunding'); ?></span>
</div>
<div class="ccs-stat-item">
<span class="ccs-stat-value"><?php echo $days_left; ?></span>
<span class="ccs-stat-label"><?php _e('剩余天数', 'cultural-crowdfunding'); ?></span>
</div>
</div>
<div class="ccs-progress-bar-container">
<div class="ccs-progress-bar">
<div class="ccs-progress-fill" style="width: <?php echo $progress; ?>%;"></div>
</div>
<div class="ccs-progress-text">
<?php printf(
__('目标: %s%s', 'cultural-crowdfunding'),
get_option('ccs_currency_symbol', '¥'),
number_format($funding_goal, 2)
); ?>
</div>
</div>
<div class="ccs-action-buttons">
<button class="ccs-back-project-btn" data-project-id="<?php echo $project_id; ?>">
<?php _e('支持此项目', 'cultural-crowdfunding'); ?>
</button>
<button class="ccs-share-project-btn">
<?php _e('分享项目', 'cultural-crowdfunding'); ?>
</button>
</div>
<?php
// 显示回报选项
$this->display_reward_tiers($project_id);
?>
</div>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('.ccs-back-project-btn').on('click', function() {
var projectId = $(this).data('project-id');
$('html, body').animate({
scrollTop: $('#ccs-back-form-' + projectId).offset().top - 100
}, 500);
});
});
</script>
<?php
return ob_get_clean();
}
private function display_reward_tiers($project_id) {
$rewards = get_post_meta($project_id, '_reward_tiers', true);
if (empty($rewards) || !is_array($rewards)) {
return;
}
?>
<div class="ccs-reward-tiers">
<h3><?php _e('选择回报', 'cultural-crowdfunding'); ?></h3>
<?php foreach ($rewards as $index => $reward): ?>
<?php if (!empty($reward['title'])): ?>
<div class="ccs-reward-tier">
<div class="ccs-reward-header">
<h4><?php echo esc_html($reward['title']); ?></h4>
<span class="ccs-reward-price">
<?php echo get_option('ccs_currency_symbol', '¥') . number_format($reward['amount'], 2); ?>
</span>
</div>
<p class="ccs-reward-description"><?php echo esc_html($reward['description']); ?></p>
<div class="ccs-reward-meta">
<span class="ccs-backers-count">
<?php printf(__('已有 %d 人选择', 'cultural-crowdfunding'), $reward['backers_count'] ?? 0); ?>
</span>
<?php if (!empty($reward['estimated_delivery'])): ?>
<span class="ccs-delivery-date">
<?php printf(__('预计发货: %s', 'cultural-crowdfunding'), $reward['estimated_delivery']); ?>
</span>
<?php endif; ?>
</div>
<button class="ccs-select-reward-btn"
data-project-id="<?php echo $project_id; ?>"
data-reward-index="<?php echo $index; ?>">
<?php _e('选择此回报', 'cultural-crowdfunding'); ?>
</button>
</div>
<?php endif; ?>
<?php endforeach; ?>
</div>
<?php
}
public function back_project_shortcode($atts) {
$atts = shortcode_atts(array(
'project_id' => 0,
), $atts, 'ccs_back_project');
$project_id = intval($atts['project_id']);
if (!$project_id) {
global $post;
$project_id = $post->ID;
}
ob_start();
?>
<div id="ccs-back-form-<?php echo $project_id; ?>" class="ccs-back-project-form">
<h3><?php _e('支持此项目', 'cultural-crowdfunding'); ?></h3>
<form id="ccs-back-form-<?php echo $project_id; ?>-form" class="ccs-back-form">
<?php wp_nonce_field('ccs_back_project_' . $project_id, 'ccs_back_nonce'); ?>
<input type="hidden" name="project_id" value="<?php echo $project_id; ?>">
<div class="ccs-form-group">
<label for="backer_amount"><?php _e('支持金额', 'cultural-crowdfunding'); ?></label>
<div class="ccs-amount-input">
<span class="ccs-currency-symbol"><?php echo get_option('ccs_currency_symbol', '¥'); ?></span>
<input type="number" id="backer_amount" name="amount"
min="1" step="0.01" required
placeholder="<?php _e('输入支持金额', 'cultural-crowdfunding'); ?>">
</div>
</div>
<div class="ccs-form-group">
<label for="reward_tier"><?php _e('选择回报', 'cultural-crowdfunding'); ?></label>
<select id="reward_tier" name="reward_tier">
<option value=""><?php _e('无需回报,单纯支持', 'cultural-crowdfunding'); ?></option>
<?php
$rewards = get_post_meta($project_id, '_reward_tiers', true);
if (is_array($rewards)) {
foreach ($rewards as $index => $reward) {
if (!empty($reward['title'])) {
echo '<option value="' . $index . '">' .
esc_html($reward['title']) . ' - ' .
get_option('ccs_currency_symbol', '¥') .
number_format($reward['amount'], 2) .
'</option>';
}
}
}
?>
</select>
</div>
<div class="ccs-form-group">
<label for="backer_message"><?php _e('留言 (可选)', 'cultural-crowdfunding'); ?></label>
<textarea id="backer_message" name="message" rows="3"
placeholder="<?php _e('给创作者留言...', 'cultural-crowdfunding'); ?>"></textarea>
</div>
<div class="ccs-form-group">
<label for="payment_method"><?php _e('支付方式', 'cultural-crowdfunding'); ?></label>
<select id="payment_method" name="payment_method" required>
<?php
$payment_methods = get_option('ccs_payment_methods', array('alipay', 'wechat'));
foreach ($payment_methods as $method) {
$method_name = $this->get_payment_method_name($method);
echo '<option value="' . $method . '">' . $method_name . '</option>';
}
?>
</select>
</div>
<div class="ccs-form-group">
<label>
<input type="checkbox" name="agree_terms" required>
<?php _e('我同意相关条款和条件', 'cultural-crowdfunding'); ?>
</label>
</div>
<button type="submit" class="ccs-submit-back-btn">
<?php _e('确认支持', 'cultural-crowdfunding'); ?>
</button>
</form>
<div id="ccs-payment-qrcode-<?php echo $project_id; ?>" class="ccs-payment-qrcode" style="display: none;">
<h4><?php _e('请扫码支付', 'cultural-crowdfunding'); ?></h4>
<div class="ccs-qrcode-container"></div>
<p class="ccs-payment-instructions"></p>
</div>
</div>
<script>
jQuery(document).ready(function($) {
$('#ccs-back-form-<?php echo $project_id; ?>-form').on('submit', function(e) {
e.preventDefault();
var formData = $(this).serialize();
$.ajax({
url: '<?php echo admin_url('admin-ajax.php'); ?>',
type: 'POST',
data: {
action: 'ccs_process_backing',
form_data: formData
},
beforeSend: function() {
$('.ccs-submit-back-btn').prop('disabled', true).text('<?php _e("处理中...", "cultural-crowdfunding"); ?>');
},
success: function(response) {
if (response.success) {
if (response.data.payment_url) {
// 跳转到支付页面
window.location.href = response.data.payment_url;
} else if (response.data.qrcode) {
// 显示二维码
$('#ccs-payment-qrcode-<?php echo $project_id; ?> .ccs-qrcode-container').html(response.data.qrcode);
$('#ccs-payment-qrcode-<?php echo $project_id; ?> .ccs-payment-instructions').text(response.data.instructions);
$('#ccs-payment-qrcode-<?php echo $project_id; ?>').show();
}
} else {
alert(response.data.message);
$('.ccs-submit-back-btn').prop('disabled', false).text('<?php _e("确认支持", "cultural-crowdfunding"); ?>');
}
}
});
});
});
</script>
<?php
return ob_get_clean();
}
// 处理支持请求的AJAX回调
public function ajax_process_backing() {
check_ajax_referer('ccs_back_project_' . $_POST['project_id'], 'ccs_back_nonce');
$project_id = intval($_POST['project_id']);
$amount = floatval($_POST['amount']);
$user_id = get_current_user_id();
// 验证数据
if ($amount <= 0) {
wp_send_json_error(array('message' => __('金额无效', 'cultural-crowdfunding')));
}
// 创建订单记录
$order_data = array(
'project_id' => $project_id,
'user_id' => $user_id,
'amount' => $amount,
'reward_tier' => sanitize_text_field($_POST['reward_tier']),
'payment_method' => sanitize_text_field($_POST['payment_method']),
'payment_status' => 'pending'
);
global $wpdb;
$wpdb->insert($wpdb->prefix . 'ccs_orders', $order_data);
$order_id = $wpdb->insert_id;
// 生成支付数据
$payment_data = $this->generate_payment($order_id, $amount, $_POST['payment_method']);
wp_send_json_success($payment_data);
}
private function generate_payment($order_id, $amount, $payment_method) {
// 这里应该集成实际的支付网关
// 以下为示例代码
$payment_data = array();
switch ($payment_method) {
case 'alipay':
// 支付宝支付
$payment_data['payment_url'] = $this->generate_alipay_url($order_id, $amount);
break;
case 'wechat':
// 微信支付 - 生成二维码
$payment_data['qrcode'] = '<img src="' . $this->generate_wechat_qrcode($order_id, $amount) . '" alt="微信支付二维码">';
$payment_data['instructions'] = __('请使用微信扫描二维码完成支付', 'cultural-crowdfunding');
break;
default:
// 其他支付方式
break;
}
return $payment_data;
}
private function generate_alipay_url($order_id, $amount) {
// 实际开发中应调用支付宝API
// 这里返回示例URL
return add_query_arg(array(
'order_id' => $order_id,
'amount' => $amount,
'return_url' => home_url('/payment-success/')
), home_url('/process-payment/alipay/'));
}
private function generate_wechat_qrcode($order_id, $amount) {
// 实际开发中应调用微信支付API
// 这里返回示例二维码图片URL
return 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' .
urlencode(home_url('/process-payment/wechat/?order_id=' . $order_id));
}
private function get_payment_method_name($method) {
$names = array(
'alipay' => __('支付宝', 'cultural-crowdfunding'),
'wechat' => __('微信支付', 'cultural-crowdfunding'),
'bank' => __('银行转账', 'cultural-crowdfunding'),
'paypal' => __('PayPal', 'cultural-crowdfunding'),
);
return isset($names[$method]) ? $names[$method] : ucfirst($method);
}
?>
## 六、供应链对接系统
实现供应链系统的对接功能。
<?php
// 在CulturalCrowdfundingSupply类中添加以下方法
public function render_supply_chain_metabox($post) {
$project_db_id = get_post_meta($post->ID, '_project_db_id', true);
$supply_chain_status = get_post_meta($post->ID, '_supply_chain_status', true) ?: 'pending';
?>
<div class="ccs-supply-chain-info">
<div class="ccs-form-row">
<label for="supply_chain_status"><?php _e('供应链状态', 'cultural-crowdfunding'); ?></label>
<select id="supply_chain_status" name="supply_chain_status">
<option value="pending" <?php selected($supply_chain_status, 'pending'); ?>>
<?php _e('待处理', 'cultural-crowdfunding'); ?>
</


