文章目录[隐藏]
WordPress文创IP的柔性授权与分成插件开发教程
引言:文创IP授权管理的数字化需求
在数字内容创作蓬勃发展的今天,文创IP(知识产权)的价值日益凸显。无论是插画师、作家、设计师还是内容创作者,都需要一种有效的方式来管理他们的作品授权和收益分成。WordPress作为全球最流行的内容管理系统,为文创IP的数字化管理提供了理想平台。
传统的IP授权管理往往依赖人工合同和手动结算,这种方式效率低下且容易出错。本文将介绍如何开发一个WordPress插件,实现文创IP的柔性授权与自动分成功能,帮助创作者更高效地管理他们的知识产权。
插件功能规划与架构设计
核心功能模块
我们的插件将包含以下核心功能:
- IP作品管理:创建、编辑和展示文创作品
- 授权类型管理:支持多种授权模式(独家、非独家、时限授权等)
- 分成规则配置:灵活设置不同参与方的收益比例
- 授权合同生成:自动生成标准化授权协议
- 支付集成:支持多种支付方式
- 数据统计:销售数据、分成报表等
数据库设计
/**
* 创建插件所需的数据表
* 这段代码应该放在插件的激活钩子中
*/
function ip_royalty_plugin_activate() {
global $wpdb;
$charset_collate = $wpdb->get_charset_collate();
// IP作品表
$table_name = $wpdb->prefix . 'ip_works';
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id mediumint(9) NOT NULL AUTO_INCREMENT,
title varchar(200) NOT NULL,
description text,
creator_id bigint(20) NOT NULL,
thumbnail_url varchar(500),
base_price decimal(10,2) DEFAULT 0.00,
status varchar(20) DEFAULT 'active',
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id)
) $charset_collate;";
// 授权类型表
$table_name = $wpdb->prefix . 'ip_license_types';
$sql .= "CREATE TABLE IF NOT EXISTS " . $wpdb->prefix . "ip_license_types (
id mediumint(9) NOT NULL AUTO_INCREMENT,
work_id mediumint(9) NOT NULL,
name varchar(100) NOT NULL,
description text,
price_multiplier decimal(5,2) DEFAULT 1.00,
duration_days int DEFAULT NULL,
allowed_usage text,
PRIMARY KEY (id),
FOREIGN KEY (work_id) REFERENCES " . $wpdb->prefix . "ip_works(id) ON DELETE CASCADE
) $charset_collate;";
// 分成规则表
$table_name = $wpdb->prefix . 'ip_royalty_rules';
$sql .= "CREATE TABLE IF NOT EXISTS " . $wpdb->prefix . "ip_royalty_rules (
id mediumint(9) NOT NULL AUTO_INCREMENT,
work_id mediumint(9) NOT NULL,
recipient_type varchar(50) NOT NULL,
recipient_id bigint(20) NOT NULL,
percentage decimal(5,2) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (work_id) REFERENCES " . $wpdb->prefix . "ip_works(id) ON DELETE CASCADE
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
register_activation_hook(__FILE__, 'ip_royalty_plugin_activate');
核心功能实现
1. IP作品管理模块
/**
* IP作品管理类
* 处理文创作品的CRUD操作
*/
class IP_Work_Manager {
/**
* 添加新作品
* @param array $work_data 作品数据
* @return int|false 成功返回作品ID,失败返回false
*/
public static function add_work($work_data) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_works';
$defaults = array(
'creator_id' => get_current_user_id(),
'status' => 'draft',
'created_at' => current_time('mysql')
);
$work_data = wp_parse_args($work_data, $defaults);
// 数据验证
if (empty($work_data['title'])) {
return new WP_Error('empty_title', '作品标题不能为空');
}
if ($work_data['base_price'] < 0) {
return new WP_Error('invalid_price', '价格不能为负数');
}
$result = $wpdb->insert($table_name, $work_data);
if ($result === false) {
return false;
}
return $wpdb->insert_id;
}
/**
* 获取用户的所有作品
* @param int $user_id 用户ID
* @return array 作品列表
*/
public static function get_user_works($user_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_works';
$query = $wpdb->prepare(
"SELECT * FROM $table_name WHERE creator_id = %d ORDER BY created_at DESC",
$user_id
);
return $wpdb->get_results($query);
}
/**
* 更新作品信息
* @param int $work_id 作品ID
* @param array $data 更新数据
* @return bool 是否成功
*/
public static function update_work($work_id, $data) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_works';
return $wpdb->update(
$table_name,
$data,
array('id' => $work_id)
);
}
}
2. 柔性授权管理系统
/**
* 授权管理类
* 处理不同类型的授权配置
*/
class IP_License_Manager {
/**
* 创建授权类型
* @param int $work_id 作品ID
* @param array $license_data 授权数据
* @return int|false 授权类型ID
*/
public static function create_license_type($work_id, $license_data) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_license_types';
$defaults = array(
'work_id' => $work_id,
'price_multiplier' => 1.0,
'duration_days' => NULL
);
$license_data = wp_parse_args($license_data, $defaults);
// 验证作品是否存在
$work = IP_Work_Manager::get_work($work_id);
if (!$work) {
return new WP_Error('work_not_found', '指定的作品不存在');
}
$result = $wpdb->insert($table_name, $license_data);
if ($result === false) {
return false;
}
return $wpdb->insert_id;
}
/**
* 计算授权价格
* @param int $work_id 作品ID
* @param int $license_type_id 授权类型ID
* @return float 计算后的价格
*/
public static function calculate_license_price($work_id, $license_type_id) {
global $wpdb;
// 获取作品基础价格
$work_table = $wpdb->prefix . 'ip_works';
$work = $wpdb->get_row($wpdb->prepare(
"SELECT base_price FROM $work_table WHERE id = %d",
$work_id
));
if (!$work) {
return 0;
}
// 获取授权类型倍率
$license_table = $wpdb->prefix . 'ip_license_types';
$license = $wpdb->get_row($wpdb->prepare(
"SELECT price_multiplier FROM $license_table WHERE id = %d AND work_id = %d",
$license_type_id,
$work_id
));
if (!$license) {
return $work->base_price;
}
return $work->base_price * $license->price_multiplier;
}
/**
* 生成授权合同
* @param int $work_id 作品ID
* @param int $license_type_id 授权类型ID
* @param int $buyer_id 购买者ID
* @return string 合同内容
*/
public static function generate_license_agreement($work_id, $license_type_id, $buyer_id) {
global $wpdb;
// 获取作品信息
$work_table = $wpdb->prefix . 'ip_works';
$work = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $work_table WHERE id = %d",
$work_id
));
// 获取授权类型信息
$license_table = $wpdb->prefix . 'ip_license_types';
$license = $wpdb->get_row($wpdb->prepare(
"SELECT * FROM $license_table WHERE id = %d",
$license_type_id
));
// 获取用户信息
$buyer = get_userdata($buyer_id);
$creator = get_userdata($work->creator_id);
// 生成合同模板
$agreement = "
<h2>文创作品授权协议</h2>
<p><strong>协议编号:</strong>IP-" . date('Ymd') . "-{$work_id}-{$license_type_id}</p>
<p><strong>签订日期:</strong>" . date('Y年m月d日') . "</p>
<h3>一、授权作品信息</h3>
<p>作品名称:{$work->title}</p>
<p>作品描述:{$work->description}</p>
<p>创作者:{$creator->display_name}</p>
<h3>二、授权条款</h3>
<p>授权类型:{$license->name}</p>
<p>授权描述:{$license->description}</p>
<p>使用范围:{$license->allowed_usage}</p>
" . ($license->duration_days ? "<p>授权期限:{$license->duration_days}天</p>" : "<p>授权期限:永久</p>") . "
<h3>三、双方权利义务</h3>
<p>1. 创作者保证拥有作品的完整知识产权</p>
<p>2. 购买者需在授权范围内使用作品</p>
<p>3. 未经允许不得将授权转售或转授权</p>
<h3>四、签字确认</h3>
<p>创作者:___________________</p>
<p>购买者:{$buyer->display_name}</p>
";
return $agreement;
}
}
3. 智能分成系统
/**
* 分成管理类
* 处理收益分配逻辑
*/
class IP_Royalty_Manager {
/**
* 添加分成规则
* @param int $work_id 作品ID
* @param string $recipient_type 接收者类型(creator, collaborator, platform)
* @param int $recipient_id 接收者ID
* @param float $percentage 分成百分比
* @return int|false 规则ID
*/
public static function add_royalty_rule($work_id, $recipient_type, $recipient_id, $percentage) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_royalty_rules';
// 验证百分比总和不超过100%
$total_percentage = self::get_total_percentage($work_id);
if ($total_percentage + $percentage > 100) {
return new WP_Error('percentage_exceeded', '分成比例总和不能超过100%');
}
$rule_data = array(
'work_id' => $work_id,
'recipient_type' => $recipient_type,
'recipient_id' => $recipient_id,
'percentage' => $percentage
);
$result = $wpdb->insert($table_name, $rule_data);
if ($result === false) {
return false;
}
return $wpdb->insert_id;
}
/**
* 计算分成
* @param int $work_id 作品ID
* @param float $total_amount 总金额
* @return array 分成明细
*/
public static function calculate_royalties($work_id, $total_amount) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_royalty_rules';
$rules = $wpdb->get_results($wpdb->prepare(
"SELECT * FROM $table_name WHERE work_id = %d",
$work_id
));
$royalties = array();
$remaining_amount = $total_amount;
foreach ($rules as $rule) {
$amount = $total_amount * ($rule->percentage / 100);
$royalties[] = array(
'recipient_type' => $rule->recipient_type,
'recipient_id' => $rule->recipient_id,
'percentage' => $rule->percentage,
'amount' => round($amount, 2)
);
$remaining_amount -= $amount;
}
// 如果有剩余金额(由于四舍五入),分配给创作者
if ($remaining_amount > 0) {
$royalties[] = array(
'recipient_type' => 'creator',
'recipient_id' => self::get_work_creator($work_id),
'percentage' => 0,
'amount' => round($remaining_amount, 2),
'note' => '四舍五入调整'
);
}
return $royalties;
}
/**
* 执行分成支付
* @param int $transaction_id 交易ID
* @param array $royalties 分成明细
* @return bool 是否成功
*/
public static function distribute_royalties($transaction_id, $royalties) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_royalty_distributions';
foreach ($royalties as $royalty) {
$distribution_data = array(
'transaction_id' => $transaction_id,
'recipient_type' => $royalty['recipient_type'],
'recipient_id' => $royalty['recipient_id'],
'amount' => $royalty['amount'],
'status' => 'pending',
'distributed_at' => current_time('mysql')
);
$wpdb->insert($table_name, $distribution_data);
// 这里可以集成支付接口,实际转账给接收者
// 例如:支付宝、微信支付、PayPal等
self::process_payment(
$royalty['recipient_id'],
$royalty['amount'],
"文创作品分成 - 交易ID: {$transaction_id}"
);
}
return true;
}
/**
* 获取作品创作者ID
* @param int $work_id 作品ID
* @return int 创作者ID
*/
private static function get_work_creator($work_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_works';
$creator_id = $wpdb->get_var($wpdb->prepare(
"SELECT creator_id FROM $table_name WHERE id = %d",
$work_id
));
return $creator_id ?: 0;
}
/**
* 获取作品分成比例总和
* @param int $work_id 作品ID
* @return float 比例总和
*/
private static function get_total_percentage($work_id) {
global $wpdb;
$table_name = $wpdb->prefix . 'ip_royalty_rules';
$total = $wpdb->get_var($wpdb->prepare(
"SELECT SUM(percentage) FROM $table_name WHERE work_id = %d",
$work_id
));
return $total ?: 0;
}
}
前端界面与用户体验
创建用户工作区
/**
* 前端用户界面
* 提供用户友好的作品管理和授权界面
*/
class IP_Frontend_Interface {
/**
* 初始化前端界面
*/
public static function init() {
// 添加快捷码
add_shortcode('ip_workspace', array(__CLASS__, 'render_workspace'));
add_shortcode('ip_marketplace', array(__CLASS__, 'render_marketplace'));
// 添加前端样式和脚本
add_action('wp_enqueue_scripts', array(__CLASS__, 'enqueue_assets'));
}
/**
* 加载前端资源
*/
public static function enqueue_assets() {
wp_enqueue_style(
'ip-frontend-style',
plugins_url('css/frontend.css', __FILE__),
array(),
'1.0.0'
);
wp_enqueue_script(
'ip-frontend-script',
plugins_url('js/frontend.js', __FILE__),
array('jquery'),
'1.0.0',
true
);
// 传递AJAX URL到前端
wp_localize_script('ip-frontend-script', 'ip_ajax', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('ip_frontend_nonce')
));
}
/**
* 渲染用户工作区
* @return string HTML内容
*/
public static function render_workspace() {
// 检查用户是否登录
if (!is_user_logged_in()) {
return '<div class="ip-notice">请先登录以管理您的文创作品</div>';
}
get_current_user_id();
$output = '<div class="ip-workspace">';
// 标签页导航
$output .= '<div class="ip-tabs">';
$output .= '<button class="ip-tab active" data-tab="my-works">我的作品</button>';
$output .= '<button class="ip-tab" data-tab="add-work">添加新作品</button>';
$output .= '<button class="ip-tab" data-tab="sales-stats">销售统计</button>';
$output .= '<button class="ip-tab" data-tab="royalty-settings">分成设置</button>';
$output .= '</div>';
// 我的作品标签页
$output .= '<div id="my-works" class="ip-tab-content active">';
$works = IP_Work_Manager::get_user_works($user_id);
if (empty($works)) {
$output .= '<div class="ip-empty-state">您还没有添加任何作品</div>';
} else {
$output .= '<div class="ip-works-grid">';
foreach ($works as $work) {
$output .= self::render_work_card($work);
}
$output .= '</div>';
}
$output .= '</div>';
// 添加作品表单
$output .= '<div id="add-work" class="ip-tab-content">';
$output .= self::render_add_work_form();
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* 渲染作品卡片
* @param object $work 作品对象
* @return string HTML卡片
*/
private static function render_work_card($work) {
$edit_url = add_query_arg(array('edit_work' => $work->id));
$sales_url = add_query_arg(array('tab' => 'sales-stats', 'work_id' => $work->id));
$output = '<div class="ip-work-card">';
$output .= '<div class="ip-work-thumbnail">';
if ($work->thumbnail_url) {
$output .= '<img src="' . esc_url($work->thumbnail_url) . '" alt="' . esc_attr($work->title) . '">';
} else {
$output .= '<div class="ip-work-thumbnail-placeholder">暂无图片</div>';
}
$output .= '</div>';
$output .= '<div class="ip-work-info">';
$output .= '<h3>' . esc_html($work->title) . '</h3>';
$output .= '<p class="ip-work-description">' . wp_trim_words($work->description, 20) . '</p>';
$output .= '<p class="ip-work-price">基础价格: ¥' . number_format($work->base_price, 2) . '</p>';
$output .= '<p class="ip-work-status">状态: ' . self::get_status_badge($work->status) . '</p>';
$output .= '<div class="ip-work-actions">';
$output .= '<a href="' . esc_url($edit_url) . '" class="ip-btn ip-btn-edit">编辑</a>';
$output .= '<a href="' . esc_url($sales_url) . '" class="ip-btn ip-btn-stats">销售数据</a>';
$output .= '</div>';
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* 渲染添加作品表单
* @return string HTML表单
*/
private static function render_add_work_form() {
$output = '<form id="ip-add-work-form" class="ip-form">';
$output .= '<div class="ip-form-group">';
$output .= '<label for="work-title">作品标题 *</label>';
$output .= '<input type="text" id="work-title" name="work_title" required>';
$output .= '</div>';
$output .= '<div class="ip-form-group">';
$output .= '<label for="work-description">作品描述</label>';
$output .= '<textarea id="work-description" name="work_description" rows="4"></textarea>';
$output .= '</div>';
$output .= '<div class="ip-form-group">';
$output .= '<label for="work-thumbnail">封面图片URL</label>';
$output .= '<input type="url" id="work-thumbnail" name="work_thumbnail">';
$output .= '</div>';
$output .= '<div class="ip-form-group">';
$output .= '<label for="base-price">基础授权价格 (¥)</label>';
$output .= '<input type="number" id="base-price" name="base_price" min="0" step="0.01" value="0">';
$output .= '</div>';
$output .= '<div class="ip-form-group">';
$output .= '<label for="work-status">初始状态</label>';
$output .= '<select id="work-status" name="work_status">';
$output .= '<option value="draft">草稿</option>';
$output .= '<option value="active">立即上架</option>';
$output .= '<option value="pending">待审核</option>';
$output .= '</select>';
$output .= '</div>';
$output .= '<button type="submit" class="ip-btn ip-btn-primary">添加作品</button>';
$output .= '</form>';
return $output;
}
/**
* 获取状态徽章
* @param string $status 状态
* @return string HTML徽章
*/
private static function get_status_badge($status) {
$status_labels = array(
'draft' => array('label' => '草稿', 'class' => 'ip-status-draft'),
'active' => array('label' => '上架中', 'class' => 'ip-status-active'),
'pending' => array('label' => '审核中', 'class' => 'ip-status-pending'),
'sold_out' => array('label' => '已售罄', 'class' => 'ip-status-sold-out')
);
if (isset($status_labels[$status])) {
return '<span class="ip-status-badge ' . $status_labels[$status]['class'] . '">' .
$status_labels[$status]['label'] . '</span>';
}
return '<span class="ip-status-badge">' . $status . '</span>';
}
}
## 支付集成与安全处理
### 支付网关集成
/**
- 支付处理类
- 集成多种支付方式
*/
class IP_Payment_Processor {
/**
* 初始化支付处理器
*/
public static function init() {
// 注册支付网关
add_filter('ip_payment_gateways', array(__CLASS__, 'register_gateways'));
// 处理支付回调
add_action('init', array(__CLASS__, 'handle_payment_callback'));
}
/**
* 注册支付网关
* @param array $gateways 现有网关
* @return array 扩展后的网关
*/
public static function register_gateways($gateways) {
$gateways['alipay'] = array(
'name' => '支付宝',
'class' => 'IP_Alipay_Gateway',
'enabled' => true
);
$gateways['wechat'] = array(
'name' => '微信支付',
'class' => 'IP_Wechat_Gateway',
'enabled' => true
);
$gateways['paypal'] = array(
'name' => 'PayPal',
'class' => 'IP_Paypal_Gateway',
'enabled' => true
);
return $gateways;
}
/**
* 创建支付订单
* @param int $work_id 作品ID
* @param int $license_type_id 授权类型ID
* @param int $buyer_id 购买者ID
* @param string $gateway 支付网关
* @return array 支付信息
*/
public static function create_payment($work_id, $license_type_id, $buyer_id, $gateway = 'alipay') {
global $wpdb;
// 计算总金额
$total_amount = IP_License_Manager::calculate_license_price($work_id, $license_type_id);
// 创建交易记录
$transaction_data = array(
'work_id' => $work_id,
'license_type_id' => $license_type_id,
'buyer_id' => $buyer_id,
'total_amount' => $total_amount,
'gateway' => $gateway,
'status' => 'pending',
'created_at' => current_time('mysql'),
'transaction_id' => self::generate_transaction_id()
);
$transactions_table = $wpdb->prefix . 'ip_transactions';
$wpdb->insert($transactions_table, $transaction_data);
$transaction_id = $wpdb->insert_id;
// 根据选择的网关创建支付
$gateway_class = self::get_gateway_class($gateway);
if ($gateway_class && class_exists($gateway_class)) {
$payment_url = $gateway_class::create_payment($transaction_id, $total_amount);
return array(
'success' => true,
'transaction_id' => $transaction_id,
'payment_url' => $payment_url,
'qr_code' => $gateway_class::generate_qr_code($payment_url)
);
}
return array(
'success' => false,
'error' => '支付网关不可用'
);
}
/**
* 处理支付回调
*/
public static function handle_payment_callback() {
if (!isset($_GET['ip_payment_callback'])) {
return;
}
$gateway = sanitize_text_field($_GET['gateway']);
$transaction_id = intval($_GET['transaction_id']);
// 验证回调签名
if (!self::verify_callback_signature($gateway)) {
wp_die('签名验证失败', '支付错误', 403);
}
// 更新交易状态
self::update_transaction_status($transaction_id, 'completed');
// 执行分成
self::process_royalty_distribution($transaction_id);
// 生成授权证书
self::generate_license_certificate($transaction_id);
// 重定向到成功页面
wp_redirect(add_query_arg(array(
'payment' => 'success',
'transaction_id' => $transaction_id
), home_url('/ip-payment-success/')));
exit;
}
/**
* 生成交易ID
* @return string 交易ID
*/
private static function generate_transaction_id() {
return 'IP' . date('YmdHis') . str_pad(mt_rand(1, 9999), 4, '0', STR_PAD_LEFT);
}
/**
* 获取网关类名
* @param string $gateway 网关标识
* @return string|null 类名
*/
private static function get_gateway_class($gateway) {
$gateways = apply_filters('ip_payment_gateways', array());
if (isset($gateways[$gateway])) {
return $gateways[$gateway]['class'];
}
return null;
}
}
/**
- 支付宝支付网关
*/
class IP_Alipay_Gateway {
/**
* 创建支付宝支付
* @param int $transaction_id 交易ID
* @param float $amount 金额
* @return string 支付URL
*/
public static function create_payment($transaction_id, $amount) {
$alipay_config = get_option('ip_alipay_settings', array());
// 这里应集成支付宝SDK
// 以下为示例代码
$params = array(
'app_id' => $alipay_config['app_id'],
'method' => 'alipay.trade.page.pay',
'charset' => 'utf-8',
'sign_type' => 'RSA2',
'timestamp' => date('Y-m-d H:i:s'),
'version' => '1.0',
'biz_content' => json_encode(array(
'out_trade_no' => $transaction_id,
'product_code' => 'FAST_INSTANT_TRADE_PAY',
'total_amount' => $amount,
'subject' => '文创作品授权购买',
'body' => '文创IP授权交易'
))
);
// 生成签名
$params['sign'] = self::generate_signature($params, $alipay_config['private_key']);
return 'https://openapi.alipay.com/gateway.do?' . http_build_query($params);
}
/**
* 生成支付二维码
* @param string $payment_url 支付URL
* @return string 二维码图片URL
*/
public static function generate_qr_code($payment_url) {
// 使用第三方服务生成二维码
$qr_code_url = 'https://api.qrserver.com/v1/create-qr-code/?size=200x200&data=' . urlencode($payment_url);
return $qr_code_url;
}
/**
* 生成签名
* @param array $params 参数
* @param string $private_key 私钥
* @return string 签名
*/
private static function generate_signature($params, $private_key) {
// 实际开发中应使用支付宝SDK的签名方法
ksort($params);
$sign_string = '';
foreach ($params as $key => $value) {
if ($key != 'sign' && $value !== '') {
$sign_string .= $key . '=' . $value . '&';
}
}
$sign_string = rtrim($sign_string, '&');
$private_key = "-----BEGIN RSA PRIVATE KEY-----n" .
wordwrap($private_key, 64, "n", true) .
"n-----END RSA PRIVATE KEY-----";
$signature = '';
openssl_sign($sign_string, $signature, $private_key, OPENSSL_ALGO_SHA256);
return base64_encode($signature);
}
}
## 数据统计与报表系统
/**
- 数据统计类
- 提供销售数据和分成报表
*/
class IP_Statistics {
/**
* 获取作品销售统计
* @param int $work_id 作品ID
* @param string $period 统计周期(day, week, month, year)
* @return array 统计数据
*/
public static function get_work_statistics($work_id, $period = 'month') {
global $wpdb;
$transactions_table = $wpdb->prefix . 'ip_transactions';
$date_condition = self::get_date_condition($period);
$query = $wpdb->prepare(
"SELECT
COUNT(*) as total_sales,
SUM(total_amount) as total_revenue,
AVG(total_amount) as average_price,
DATE(created_at) as sale_date
FROM $transactions_table
WHERE work_id = %d
AND status = 'completed'
$date_condition
GROUP BY DATE(created_at)
ORDER BY sale_date DESC",
$work_id
);
$results = $wpdb->get_results($query);
// 计算分成数据
$royalty_data = self::get_royalty_statistics($work_id, $period);
return array(
'sales_data' => $results,
'royalty_data' => $royalty_data,
'summary' => self::calculate_summary($results)
);
}
/**
* 获取分成统计
* @param int $work_id 作品ID
* @param string $period 统计周期
* @return array 分成数据
*/
private static function get_royalty_statistics($work_id, $period) {
global $wpdb;
$distributions_table = $wpdb->prefix . 'ip_royalty_distributions';
$transactions_table = $wpdb->prefix . 'ip_transactions';
$date_condition = self::get_date_condition($period, 'd.distributed_at');
$query = $wpdb->prepare(
"SELECT
d.recipient_type,
d.recipient_id,
SUM(d.amount) as total_amount,
COUNT(DISTINCT d.transaction_id) as transaction_count
FROM $distributions_table d
INNER JOIN $transactions_table t ON d.transaction_id = t.id
WHERE t.work_id = %d
AND d.status = 'completed'
$date_condition
GROUP BY d.recipient_type, d.recipient_id
ORDER BY total_amount DESC",
$work_id
);
return $wpdb->get_results($query);
}
/**
* 生成日期条件
* @param string $period 周期
* @param string $date_column 日期列名
* @return string SQL条件
*/
private static function get_date_condition($period, $date_column = 'created_at') {
$conditions = array(
'day' => "AND $date_column >= CURDATE()",
'week' => "AND $date_column >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)",
'month' => "AND $date_column >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)",
'year' => "AND $date_column >= DATE_SUB(CURDATE(), INTERVAL 365 DAY)",
'all' => ""
);
return isset($conditions[$period]) ? $conditions[$period] : $conditions['month'];
}
/**
* 计算统计摘要
* @param array $data 销售数据
