首页 / 教程文章 / 网络传媒WordPress站点柔性广告效果归因分析插件教程

网络传媒WordPress站点柔性广告效果归因分析插件教程

本教程旨在指导开发一款适用于WordPress站点的柔性广告效果归因分析插件。在数字营销中,面对多渠道广告投放和复杂的用户转化路径,准确归因各渠道贡献是优化预算的关键。插件核心功能包括:追踪多触点转化路径、支持首次点击、末次点击等多种归因模型配置、生成可视化效果报表、对接Google Analytics等第三方工具,以及自定义转化事件。教程内容涵盖从创建插件基础文件、设计数据库、编写前端追踪脚本,到实现归因模型计算和报表生成的完整开发流程。

网络传媒WordPress站点柔性广告效果归因分析插件教程

引言:广告效果归因的重要性

在数字营销时代,网络传媒站点面临着广告效果追踪与分析的挑战。广告投放渠道多样化,用户转化路径复杂,如何准确归因每个广告渠道对最终转化的贡献,成为优化广告预算分配的关键。本教程将详细介绍如何为WordPress站点开发一个柔性广告效果归因分析插件,帮助您精确追踪多触点转化路径。

插件功能概述

本插件将实现以下核心功能:

  1. 多触点广告转化路径追踪
  2. 灵活归因模型配置(首次点击、末次点击、线性归因等)
  3. 广告渠道效果可视化报表
  4. 与Google Analytics等第三方工具的数据对接
  5. 自定义转化事件定义与追踪

环境准备与插件基础结构

1. 创建插件基础文件

<?php
/**
 * Plugin Name: 柔性广告效果归因分析
 * Plugin URI: https://yourwebsite.com/
 * Description: 用于WordPress站点的多触点广告效果归因分析工具
 * Version: 1.0.0
 * Author: 您的名称
 * License: GPL v2 or later
 */

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

// 定义插件常量
define('AA_PLUGIN_PATH', plugin_dir_path(__FILE__));
define('AA_PLUGIN_URL', plugin_dir_url(__FILE__));
define('AA_VERSION', '1.0.0');

// 初始化插件
require_once AA_PLUGIN_PATH . 'includes/class-attribution-core.php';

function aa_init_plugin() {
    $plugin = new Attribution_Analysis_Core();
    $plugin->run();
}
add_action('plugins_loaded', 'aa_init_plugin');
?>

2. 创建核心类文件

<?php
// includes/class-attribution-core.php

class Attribution_Analysis_Core {
    
    public function __construct() {
        // 构造函数
    }
    
    public function run() {
        $this->setup_hooks();
        $this->init_modules();
    }
    
    private function setup_hooks() {
        // 注册激活/停用钩子
        register_activation_hook(__FILE__, array($this, 'activate_plugin'));
        register_deactivation_hook(__FILE__, array($this, 'deactivate_plugin'));
        
        // 添加管理菜单
        add_action('admin_menu', array($this, 'add_admin_menu'));
        
        // 前端追踪脚本
        add_action('wp_footer', array($this, 'add_tracking_script'));
        
        // 处理转化事件
        add_action('wp_ajax_aa_track_conversion', array($this, 'track_conversion'));
        add_action('wp_ajax_nopriv_aa_track_conversion', array($this, 'track_conversion'));
    }
    
    private function init_modules() {
        // 初始化数据库模块
        require_once AA_PLUGIN_PATH . 'includes/class-database-manager.php';
        $this->db_manager = new Attribution_Database_Manager();
        
        // 初始化归因模型模块
        require_once AA_PLUGIN_PATH . 'includes/class-attribution-models.php';
        $this->attribution_models = new Attribution_Models();
        
        // 初始化报表模块
        require_once AA_PLUGIN_PATH . 'includes/class-reports-generator.php';
        $this->reports = new Reports_Generator();
    }
    
    public function activate_plugin() {
        // 创建数据库表
        $this->db_manager->create_tables();
        
        // 设置默认选项
        $default_options = array(
            'attribution_model' => 'last_click',
            'conversion_window' => 30,
            'tracking_enabled' => true
        );
        update_option('aa_plugin_settings', $default_options);
    }
    
    public function deactivate_plugin() {
        // 清理临时数据
        // 注意:不删除历史数据,以便重新激活时保留
    }
    
    public function add_admin_menu() {
        add_menu_page(
            '广告归因分析',
            '广告归因',
            'manage_options',
            'attribution-analysis',
            array($this, 'render_admin_dashboard'),
            'dashicons-chart-line',
            30
        );
        
        // 添加子菜单
        add_submenu_page(
            'attribution-analysis',
            '归因设置',
            '设置',
            'manage_options',
            'aa-settings',
            array($this, 'render_settings_page')
        );
        
        add_submenu_page(
            'attribution-analysis',
            '转化报表',
            '报表',
            'manage_options',
            'aa-reports',
            array($this, 'render_reports_page')
        );
    }
    
    public function add_tracking_script() {
        // 前端追踪脚本将在后续部分实现
    }
    
    public function track_conversion() {
        // AJAX处理转化事件
    }
    
    public function render_admin_dashboard() {
        // 渲染管理仪表板
        include AA_PLUGIN_PATH . 'admin/views/dashboard.php';
    }
    
    public function render_settings_page() {
        // 渲染设置页面
        include AA_PLUGIN_PATH . 'admin/views/settings.php';
    }
    
    public function render_reports_page() {
        // 渲染报表页面
        include AA_PLUGIN_PATH . 'admin/views/reports.php';
    }
}
?>

数据库设计与实现

3. 数据库管理类

<?php
// includes/class-database-manager.php

class Attribution_Database_Manager {
    
    private $charset_collate;
    
    public function __construct() {
        global $wpdb;
        $this->charset_collate = $wpdb->get_charset_collate();
    }
    
    public function create_tables() {
        global $wpdb;
        
        $table_name_sessions = $wpdb->prefix . 'aa_ad_sessions';
        $table_name_conversions = $wpdb->prefix . 'aa_conversions';
        $table_name_touchpoints = $wpdb->prefix . 'aa_touchpoints';
        
        // 广告会话表
        $sql_sessions = "CREATE TABLE IF NOT EXISTS $table_name_sessions (
            session_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            visitor_id VARCHAR(32) NOT NULL,
            landing_page VARCHAR(500) NOT NULL,
            referrer VARCHAR(500),
            utm_source VARCHAR(100),
            utm_medium VARCHAR(100),
            utm_campaign VARCHAR(100),
            utm_term VARCHAR(100),
            utm_content VARCHAR(100),
            device_type VARCHAR(50),
            browser VARCHAR(100),
            ip_address VARCHAR(45),
            session_start DATETIME NOT NULL,
            session_end DATETIME,
            PRIMARY KEY (session_id),
            INDEX visitor_idx (visitor_id),
            INDEX session_start_idx (session_start)
        ) $this->charset_collate;";
        
        // 转化事件表
        $sql_conversions = "CREATE TABLE IF NOT EXISTS $table_name_conversions (
            conversion_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            visitor_id VARCHAR(32) NOT NULL,
            conversion_type VARCHAR(50) NOT NULL,
            conversion_value DECIMAL(10,2),
            conversion_data TEXT,
            conversion_time DATETIME NOT NULL,
            attributed_session_id BIGINT(20) UNSIGNED,
            attribution_model VARCHAR(50),
            PRIMARY KEY (conversion_id),
            INDEX visitor_idx (visitor_id),
            INDEX conversion_time_idx (conversion_time),
            FOREIGN KEY (attributed_session_id) REFERENCES $table_name_sessions(session_id) ON DELETE SET NULL
        ) $this->charset_collate;";
        
        // 触点路径表
        $sql_touchpoints = "CREATE TABLE IF NOT EXISTS $table_name_touchpoints (
            touchpoint_id BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT,
            visitor_id VARCHAR(32) NOT NULL,
            session_id BIGINT(20) UNSIGNED NOT NULL,
            touchpoint_order INT NOT NULL,
            touchpoint_time DATETIME NOT NULL,
            channel_group VARCHAR(100),
            channel_detail VARCHAR(200),
            interaction_type VARCHAR(50),
            cost DECIMAL(10,2) DEFAULT 0.00,
            PRIMARY KEY (touchpoint_id),
            INDEX visitor_session_idx (visitor_id, session_id),
            FOREIGN KEY (session_id) REFERENCES $table_name_sessions(session_id) ON DELETE CASCADE
        ) $this->charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql_sessions);
        dbDelta($sql_conversions);
        dbDelta($sql_touchpoints);
    }
    
    public function save_session($session_data) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'aa_ad_sessions';
        
        $wpdb->insert(
            $table_name,
            $session_data
        );
        
        return $wpdb->insert_id;
    }
    
    public function save_touchpoint($touchpoint_data) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'aa_touchpoints';
        
        $wpdb->insert(
            $table_name,
            $touchpoint_data
        );
        
        return $wpdb->insert_id;
    }
    
    public function save_conversion($conversion_data) {
        global $wpdb;
        $table_name = $wpdb->prefix . 'aa_conversions';
        
        $wpdb->insert(
            $table_name,
            $conversion_data
        );
        
        return $wpdb->insert_id;
    }
    
    public function get_conversion_path($visitor_id, $days_back = 30) {
        global $wpdb;
        
        $table_touchpoints = $wpdb->prefix . 'aa_touchpoints';
        $table_sessions = $wpdb->prefix . 'aa_ad_sessions';
        
        $query = $wpdb->prepare(
            "SELECT 
                tp.touchpoint_id,
                tp.touchpoint_order,
                tp.touchpoint_time,
                tp.channel_group,
                tp.channel_detail,
                tp.interaction_type,
                s.utm_source,
                s.utm_medium,
                s.utm_campaign
            FROM $table_touchpoints tp
            JOIN $table_sessions s ON tp.session_id = s.session_id
            WHERE tp.visitor_id = %s 
            AND tp.touchpoint_time >= DATE_SUB(NOW(), INTERVAL %d DAY)
            ORDER BY tp.touchpoint_time ASC",
            $visitor_id,
            $days_back
        );
        
        return $wpdb->get_results($query);
    }
}
?>

前端追踪脚本实现

4. JavaScript追踪代码

// assets/js/tracking.js

(function() {
    'use strict';
    
    // 生成唯一访客ID(如果不存在)
    function getVisitorId() {
        let visitorId = localStorage.getItem('aa_visitor_id');
        if (!visitorId) {
            visitorId = 'vis_' + Math.random().toString(36).substr(2, 9) + 
                       '_' + Date.now().toString(36);
            localStorage.setItem('aa_visitor_id', visitorId);
        }
        return visitorId;
    }
    
    // 获取UTM参数
    function getUTMParams() {
        const params = new URLSearchParams(window.location.search);
        return {
            source: params.get('utm_source') || '',
            medium: params.get('utm_medium') || '',
            campaign: params.get('utm_campaign') || '',
            term: params.get('utm_term') || '',
            content: params.get('utm_content') || ''
        };
    }
    
    // 获取设备信息
    function getDeviceInfo() {
        const ua = navigator.userAgent;
        let deviceType = 'desktop';
        
        if (/Mobile|Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua)) {
            deviceType = 'mobile';
        } else if (/Tablet|iPad/i.test(ua)) {
            deviceType = 'tablet';
        }
        
        return {
            deviceType: deviceType,
            browser: navigator.userAgent,
            screenResolution: screen.width + 'x' + screen.height
        };
    }
    
    // 发送追踪数据到服务器
    function sendTrackingData(data, endpoint) {
        const xhr = new XMLHttpRequest();
        xhr.open('POST', aa_tracking.ajax_url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4 && xhr.status === 200) {
                console.log('Tracking data sent successfully');
            }
        };
        
        const params = new URLSearchParams();
        params.append('action', endpoint);
        params.append('data', JSON.stringify(data));
        params.append('nonce', aa_tracking.nonce);
        
        xhr.send(params.toString());
    }
    
    // 追踪页面访问
    function trackPageView() {
        const visitorId = getVisitorId();
        const utmParams = getUTMParams();
        const deviceInfo = getDeviceInfo();
        
        const trackingData = {
            visitor_id: visitorId,
            page_url: window.location.href,
            referrer: document.referrer,
            utm_source: utmParams.source,
            utm_medium: utmParams.medium,
            utm_campaign: utmParams.campaign,
            utm_term: utmParams.term,
            utm_content: utmParams.content,
            device_type: deviceInfo.deviceType,
            browser: deviceInfo.browser,
            screen_resolution: deviceInfo.screenResolution,
            timestamp: new Date().toISOString()
        };
        
        sendTrackingData(trackingData, 'aa_track_session');
    }
    
    // 追踪转化事件
    function trackConversion(conversionType, conversionValue = 0, customData = {}) {
        const visitorId = getVisitorId();
        
        const conversionData = {
            visitor_id: visitorId,
            conversion_type: conversionType,
            conversion_value: conversionValue,
            custom_data: customData,
            page_url: window.location.href,
            timestamp: new Date().toISOString()
        };
        
        sendTrackingData(conversionData, 'aa_track_conversion');
        
        // 触发数据层事件(用于Google Tag Manager等)
        window.dataLayer = window.dataLayer || [];
        window.dataLayer.push({
            'event': 'aa_conversion',
            'conversion_type': conversionType,
            'conversion_value': conversionValue
        });
    }
    
    // 初始化追踪
    document.addEventListener('DOMContentLoaded', function() {
        // 追踪页面访问
        trackPageView();
        
        // 为转化按钮添加事件监听(示例)
        const conversionButtons = document.querySelectorAll('[data-aa-conversion]');
        conversionButtons.forEach(button => {
            button.addEventListener('click', function() {
                const conversionType = this.getAttribute('data-aa-conversion');
                const conversionValue = this.getAttribute('data-aa-value') || 0;
                
                trackConversion(conversionType, conversionValue, {
                    button_text: this.textContent,
                    button_id: this.id
                });
            });
        });
        
        // 表单提交追踪
        const trackedForms = document.querySelectorAll('form[data-aa-conversion]');
        trackedForms.forEach(form => {
            form.addEventListener('submit', function(e) {
                const conversionType = this.getAttribute('data-aa-conversion');
                const conversionValue = this.getAttribute('data-aa-value') || 0;
                
                // 可以添加表单验证逻辑
                trackConversion(conversionType, conversionValue, {
                    form_id: this.id,
                    form_action: this.action
                });
            });
        });
    });
    
    // 暴露公共API
    window.AttributionAnalytics = {
        trackConversion: trackConversion,
        getVisitorId: getVisitorId
    };
    
})();

归因模型实现

5. 归因模型计算类

<?php
// includes/class-attribution-models.php

class Attribution_Models {
    
    public function __construct() {
        // 初始化归因模型
    }
    
    /**
     * 应用归因模型分配转化价值
     * 
     * @param array $touchpoints 触点路径数组
     * @param float $conversion_value 转化价值
     * @param string $model_type 归因模型类型
     * @return array 分配后的触点价值数组
     */
    public function apply_attribution_model($touchpoints, $conversion_value, $model_type = 'last_click') {
        
        if (empty($touchpoints)) {
            return array();
        }
        
        $touchpoint_count = count($touchpoints);
        $attributed_values = array();
        
        switch ($model_type) {
            case 'last_click':
                // 末次点击归因:100%价值给最后触点
                foreach ($touchpoints as $index => $touchpoint) {
                    $attributed_values[$index] = ($index === $touchpoint_count - 1) ? 
                        $conversion_value : 0;
                }
                break;
                
            case 'first_click':
                // 首次点击归因:100%价值给首次触点
                foreach ($touchpoints as $index => $touchpoint) {
                    $attributed_values[$index] = ($index === 0) ? 
                        $conversion_value : 0;
                }
                break;
                
            case 'linear':
                // 线性归因:价值平均分配
                $value_per_touchpoint = $conversion_value / $touchpoint_count;
                foreach ($touchpoints as $index => $touchpoint) {
                    $attributed_values[$index] = $value_per_touchpoint;
                }
                break;
                
            case 'time_decay':
                // 时间衰减归因:越接近转化的触点获得越多价值
                $total_weight = 0;
                $weights = array();
                
                // 计算每个触点的时间权重(指数衰减)
                foreach ($touchpoints as $index => $touchpoint) {
                    $time_index = $index + 1; // 避免0次方

time_index); // 指数衰减因子

                $weights[$index] = $weight;
                $total_weight += $weight;
            }
            
            // 根据权重分配价值
            foreach ($touchpoints as $index => $touchpoint) {
                $attributed_values[$index] = ($weights[$index] / $total_weight) * $conversion_value;
            }
            break;
            
        case 'position_based':
            // 位置归因:首尾各40%,中间触点平分20%
            $first_last_percentage = 0.4; // 40%
            $middle_percentage = 0.2; // 20%
            
            if ($touchpoint_count === 1) {
                // 只有一个触点时获得100%
                $attributed_values[0] = $conversion_value;
            } elseif ($touchpoint_count === 2) {
                // 两个触点时各50%
                $attributed_values[0] = $conversion_value * 0.5;
                $attributed_values[1] = $conversion_value * 0.5;
            } else {
                // 三个及以上触点
                $first_last_value = $conversion_value * $first_last_percentage;
                $middle_value_total = $conversion_value * $middle_percentage;
                $middle_touchpoints = $touchpoint_count - 2;
                $middle_value_each = $middle_value_total / $middle_touchpoints;
                
                foreach ($touchpoints as $index => $touchpoint) {
                    if ($index === 0 || $index === $touchpoint_count - 1) {
                        $attributed_values[$index] = $first_last_value;
                    } else {
                        $attributed_values[$index] = $middle_value_each;
                    }
                }
            }
            break;
            
        case 'custom_algorithm':
            // 自定义算法归因(基于机器学习或业务规则)
            $attributed_values = $this->custom_attribution_algorithm($touchpoints, $conversion_value);
            break;
            
        default:
            // 默认使用末次点击
            foreach ($touchpoints as $index => $touchpoint) {
                $attributed_values[$index] = ($index === $touchpoint_count - 1) ? 
                    $conversion_value : 0;
            }
    }
    
    return $attributed_values;
}

/**
 * 自定义归因算法示例
 */
private function custom_attribution_algorithm($touchpoints, $conversion_value) {
    $attributed_values = array();
    $touchpoint_count = count($touchpoints);
    
    // 示例:基于渠道类型和互动时间的加权算法
    $total_weight = 0;
    $weights = array();
    
    foreach ($touchpoints as $index => $touchpoint) {
        $base_weight = 1.0;
        
        // 根据渠道类型调整权重
        $channel_weight = $this->get_channel_weight($touchpoint['channel_group']);
        
        // 根据时间位置调整权重(越接近转化权重越高)
        $time_weight = ($index + 1) / $touchpoint_count;
        
        // 根据互动类型调整权重
        $interaction_weight = $this->get_interaction_weight($touchpoint['interaction_type']);
        
        // 计算综合权重
        $weight = $base_weight * $channel_weight * $time_weight * $interaction_weight;
        $weights[$index] = $weight;
        $total_weight += $weight;
    }
    
    // 根据权重分配价值
    foreach ($touchpoints as $index => $touchpoint) {
        if ($total_weight > 0) {
            $attributed_values[$index] = ($weights[$index] / $total_weight) * $conversion_value;
        } else {
            $attributed_values[$index] = 0;
        }
    }
    
    return $attributed_values;
}

/**
 * 获取渠道权重
 */
private function get_channel_weight($channel_group) {
    $channel_weights = array(
        'paid_search' => 1.2,
        'display_ads' => 1.0,
        'social_media' => 1.1,
        'email' => 1.3,
        'organic_search' => 0.9,
        'direct' => 0.8,
        'referral' => 1.0
    );
    
    return isset($channel_weights[$channel_group]) ? 
           $channel_weights[$channel_group] : 1.0;
}

/**
 * 获取互动类型权重
 */
private function get_interaction_weight($interaction_type) {
    $interaction_weights = array(
        'click' => 1.0,
        'view' => 0.3,
        'engagement' => 0.7,
        'form_submit' => 1.5
    );
    
    return isset($interaction_weights[$interaction_type]) ? 
           $interaction_weights[$interaction_type] : 1.0;
}

/**
 * 批量处理转化归因
 */
public function batch_process_conversions($conversion_ids, $model_type = null) {
    global $wpdb;
    
    if (empty($model_type)) {
        $settings = get_option('aa_plugin_settings', array());
        $model_type = isset($settings['attribution_model']) ? 
                     $settings['attribution_model'] : 'last_click';
    }
    
    $table_conversions = $wpdb->prefix . 'aa_conversions';
    $table_touchpoints = $wpdb->prefix . 'aa_touchpoints';
    
    foreach ($conversion_ids as $conversion_id) {
        // 获取转化信息
        $conversion = $wpdb->get_row($wpdb->prepare(
            "SELECT * FROM $table_conversions WHERE conversion_id = %d",
            $conversion_id
        ));
        
        if (!$conversion) continue;
        
        // 获取该访客的触点路径
        $touchpoints = $wpdb->get_results($wpdb->prepare(
            "SELECT * FROM $table_touchpoints 
             WHERE visitor_id = %s 
             AND touchpoint_time <= %s
             ORDER BY touchpoint_time ASC",
            $conversion->visitor_id,
            $conversion->conversion_time
        ));
        
        if (empty($touchpoints)) continue;
        
        // 应用归因模型
        $attributed_values = $this->apply_attribution_model(
            $touchpoints,
            floatval($conversion->conversion_value),
            $model_type
        );
        
        // 更新触点表的归因价值
        foreach ($touchpoints as $index => $touchpoint) {
            $wpdb->update(
                $table_touchpoints,
                array(
                    'attributed_value' => $attributed_values[$index],
                    'attribution_model' => $model_type,
                    'attribution_time' => current_time('mysql')
                ),
                array('touchpoint_id' => $touchpoint->touchpoint_id)
            );
        }
        
        // 更新转化表的归因信息
        $wpdb->update(
            $table_conversions,
            array(
                'attribution_model' => $model_type,
                'attribution_processed' => 1
            ),
            array('conversion_id' => $conversion_id)
        );
    }
    
    return count($conversion_ids);
}

}
?>


## 数据可视化与报表系统

### 6. 报表生成类

<?php
// includes/class-reports-generator.php

class Reports_Generator {


public function __construct() {
    // 初始化报表系统
}

/**
 * 生成渠道效果报表
 */
public function generate_channel_report($start_date, $end_date, $model_type = null) {
    global $wpdb;
    
    if (empty($model_type)) {
        $settings = get_option('aa_plugin_settings', array());
        $model_type = isset($settings['attribution_model']) ? 
                     $settings['attribution_model'] : 'last_click';
    }
    
    $table_touchpoints = $wpdb->prefix . 'aa_touchpoints';
    $table_conversions = $wpdb->prefix . 'aa_conversions';
    
    $query = $wpdb->prepare(
        "SELECT 
            tp.channel_group,
            tp.channel_detail,
            COUNT(DISTINCT tp.visitor_id) as unique_visitors,
            COUNT(tp.touchpoint_id) as total_touchpoints,
            COUNT(DISTINCT c.conversion_id) as conversions,
            SUM(c.conversion_value) as total_conversion_value,
            SUM(tp.attributed_value) as attributed_value,
            AVG(tp.cost) as avg_cost
        FROM $table_touchpoints tp
        LEFT JOIN $table_conversions c ON tp.visitor_id = c.visitor_id
            AND c.conversion_time BETWEEN %s AND %s
            AND c.attribution_model = %s
        WHERE tp.touchpoint_time BETWEEN %s AND %s
            AND tp.attribution_model = %s
        GROUP BY tp.channel_group, tp.channel_detail
        ORDER BY attributed_value DESC",
        $start_date, $end_date, $model_type,
        $start_date, $end_date, $model_type
    );
    
    $results = $wpdb->get_results($query);
    
    // 计算ROI和其他指标
    foreach ($results as &$row) {
        if ($row->avg_cost > 0) {
            $row->roi = ($row->attributed_value - $row->avg_cost) / $row->avg_cost * 100;
        } else {
            $row->roi = null;
        }
        
        if ($row->total_touchpoints > 0) {
            $row->conversion_rate = ($row->conversions / $row->total_touchpoints) * 100;
        } else {
            $row->conversion_rate = 0;
        }
    }
    
    return $results;
}

/**
 * 生成转化路径分析报表
 */
public function generate_path_analysis($limit = 20) {
    global $wpdb;
    
    $table_touchpoints = $wpdb->prefix . 'aa_touchpoints';
    $table_conversions = $wpdb->prefix . 'aa_conversions';
    
    $query = $wpdb->prepare(
        "SELECT 
            c.visitor_id,
            GROUP_CONCAT(tp.channel_group ORDER BY tp.touchpoint_time ASC SEPARATOR ' > ') as path,
            COUNT(tp.touchpoint_id) as path_length,
            c.conversion_type,
            c.conversion_value,
            c.conversion_time
        FROM $table_conversions c
        JOIN $table_touchpoints tp ON c.visitor_id = tp.visitor_id
            AND tp.touchpoint_time <= c.conversion_time
        WHERE c.attribution_processed = 1
        GROUP BY c.conversion_id
        HAVING path_length > 1
        ORDER BY c.conversion_value DESC
        LIMIT %d",
        $limit
    );
    
    return $wpdb->get_results($query);
}

/**
 * 生成时间趋势报表
 */
public function generate_trend_report($period = 'daily', $days = 30) {
    global $wpdb;
    
    $table_conversions = $wpdb->prefix . 'aa_conversions';
    $table_touchpoints = $wpdb->prefix . 'aa_touchpoints';
    
    $date_format = '';
    switch ($period) {
        case 'hourly':
            $date_format = '%Y-%m-%d %H:00:00';
            break;
        case 'daily':
            $date_format = '%Y-%m-%d';
            break;
        case 'weekly':
            $date_format = '%Y-%U';
            break;
        case 'monthly':
            $date_format = '%Y-%m';
            break;
        default:
            $date_format = '%Y-%m-%d';
    }
    
    $query = $wpdb->prepare(
        "SELECT 
            DATE_FORMAT(c.conversion_time, %s) as period,
            COUNT(DISTINCT c.conversion_id) as conversions,
            SUM(c.conversion_value) as total_value,
            COUNT(DISTINCT tp.visitor_id) as engaged_visitors,
            COUNT(tp.touchpoint_id) as touchpoints
        FROM $table_conversions c
        LEFT JOIN $table_touchpoints tp ON DATE(tp.touchpoint_time) = DATE(c.conversion_time)
        WHERE c.conversion_time >= DATE_SUB(NOW(), INTERVAL %d DAY)
        GROUP BY period
        ORDER BY period ASC",
        $date_format,
        $days
    );
    
    return $wpdb->get_results($query);
}

/**
 * 生成归因模型对比报表
 */
public function generate_model_comparison($start_date, $end_date) {
    global $wpdb;
    
    $table_conversions = $wpdb->prefix . 'aa_conversions';
    
    $models = array('last_click', 'first_click', 'linear', 'time_decay', 'position_based');
    $results = array();
    
    foreach ($models as $model) {
        $query = $wpdb->prepare(
            "SELECT 
                %s as model_name,
                COUNT(DISTINCT conversion_id) as conversions,
                SUM(conversion_value) as total_value,
                AVG(conversion_value) as avg_value
            FROM $table_conversions
            WHERE conversion_time BETWEEN %s AND %s
            AND attribution_model = %s",
            $model, $start_date, $end_date, $model
        );
        
        $result = $wpdb->get_row($query);
        if ($result) {
            $results[] = $result;
        }
    }
    
    return $results;
}

/**
 * 生成数据导出(CSV格式)
 */
public function export_report_data($report_type, $params) {
    $data = array();
    
    switch ($report_type) {
        case 'channel_performance':
            $data = $this->generate_channel_report(
                $params['start_date'],
                $params['end_date'],
                $params['model_type']
            );
            $filename = 'channel-performance-' . date('Y-m-d') . '.csv';
            $headers = array('渠道组', '渠道详情', '独立访客', '总触点', '转化数', 
                           '转化总值', '归因价值', '平均成本', 'ROI', '转化率');
            break;
            
        case 'path_analysis':
            $data = $this->generate_path_analysis($params['limit']);
            $filename = 'path-analysis-' . date('Y-m-d') . '.csv';
            $headers = array('访客ID', '转化路径', '路径长度', '转化类型', 
                           '转化价值', '转化时间');
            break;
            
        case 'trend':
            $data = $this->generate_trend_report($params['period'], $params['days']);
            $filename = 'trend-report-' . date('Y-m-d') . '.csv';
            $headers = array('时间段', '转化数', '总价值', '参与访客', '触点数量');
            break;
            
        default:
            return false;
    }
    
    // 生成CSV内容
    $output = fopen('php://output', 'w');
    
    // 添加BOM头,确保Excel正确识别UTF-8
    fwrite($output, "xEFxBBxBF");
    
    // 写入表头
    fputcsv($output, $headers);
    
    // 写入数据
    foreach ($data as $row) {
        fputcsv($output, (array)$row);
    }
    
    fclose($output);
    
    // 设置HTTP头
    header('Content-Type: text/csv; charset=utf-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    
    return true;
}

}
?>


## 管理界面实现

### 7. 管理仪表板视图

<!-- admin/views/dashboard.php -->
<div class="wrap">

<h1><?php echo esc_html(get_admin_page_title()); ?></h1>

<div class="aa-dashboard-container">
    <!-- 概览卡片 -->
    <div class="aa-overview-cards">
        <div class="aa-card">
            <h3>今日转化</h3>
            <div class="aa-card-value" id="today-conversions">0</div>
            <div class="aa-card-change" id="today-change">+0%</div>
        </div>
        
        <div class="aa-card">
            <h3>本月收入</h3>
            <div class="aa-card-value" id="monthly-revenue">¥0</div>
            <div class="aa-card-change" id="monthly-change">+0%</div>
        </div>
        
        <div class="aa-card">
            <h3>平均转化价值</h3>
            <div class="aa-card-value" id="avg-conversion-value">¥0</div>
            <div class="aa-card-change" id="avg-change">+0%</div>
        </div>
        
        <div class="aa-card">
            <h3>归因完成率</h3>
            <div class="aa-card-value" id="attribution-rate">0%</div>
            <div class="aa-card-progress">
                <div class="aa-progress-bar" id="attribution-progress"></div>
            </div>
        </div>
    </div>
    
    <!-- 图表区域 -->
    <div class="aa-charts-section">
        <div class="aa-chart-container">
            <h3>渠道效果对比</h3>
            <canvas id="channel-performance-chart" width="400" height="200"></canvas>
        </div>
        
        <div class="aa-chart-container">
            <h3>转化趋势</h3>
            <canvas id="conversion-trend-chart" width="400" height="200"></canvas>
        </div>
    </div>
    
    <!-- 数据表格 -->
    <div class="aa-data-table">
        <h3>最近转化</h3>
        <table class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th>时间</th>
                    <th>访客ID</th>
                    <th>转化类型</
本文来自网络投稿,不代表本站点的立场,转载请注明出处:https://www.gongxiangcang.com/6563.html

溯源库®作者

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

为您推荐

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@suyuanku.com

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

微信扫一扫关注我们

返回顶部