首页 / 应用软件 / 实战教程,在网站中添加在线个人财务记账与预算管理小程序

实战教程,在网站中添加在线个人财务记账与预算管理小程序

实战教程:在WordPress网站中添加在线个人财务记账与预算管理小程序

引言:为什么网站需要个人财务工具?

在当今数字化时代,个人财务管理已成为许多人日常生活中的重要组成部分。随着在线消费、数字支付和远程工作的普及,人们越来越需要便捷的工具来跟踪和管理个人财务。对于网站运营者而言,在网站上集成实用的个人财务工具不仅能增加用户粘性,还能提升网站的价值和实用性。

WordPress作为全球最流行的内容管理系统,其强大的可扩展性使其成为实现此类功能的理想平台。通过代码二次开发,我们可以在WordPress网站上添加一个完整的在线个人财务记账与预算管理小程序,为用户提供实用的互联网小工具。

本教程将详细指导您如何通过WordPress代码二次开发,实现一个功能完整的个人财务管理系统,涵盖记账、预算管理、数据可视化等核心功能。

第一部分:项目规划与环境准备

1.1 功能需求分析

在开始开发之前,我们需要明确个人财务管理系统应包含的核心功能:

  1. 用户认证与数据隔离:确保每个用户只能访问自己的财务数据
  2. 收入与支出记录:支持添加、编辑、删除和分类财务记录
  3. 预算管理:允许用户设置月度/年度预算并跟踪执行情况
  4. 数据可视化:通过图表展示财务趋势和分类占比
  5. 数据导出:支持将财务数据导出为CSV或Excel格式
  6. 报表生成:自动生成月度/年度财务报告

1.2 开发环境搭建

为了进行WordPress二次开发,我们需要准备以下环境:

  1. 本地开发环境:安装XAMPP、MAMP或Local by Flywheel
  2. WordPress安装:最新版本的WordPress核心文件
  3. 代码编辑器:VS Code、Sublime Text或PHPStorm
  4. 浏览器开发者工具:用于调试前端代码

1.3 创建自定义插件

我们将通过创建自定义插件的方式实现财务管理系统,这样可以确保代码的独立性和可维护性。

在WordPress的wp-content/plugins目录下创建新文件夹personal-finance-manager,并在其中创建主插件文件:

<?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('PFM_VERSION', '1.0.0');
define('PFM_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('PFM_PLUGIN_URL', plugin_dir_url(__FILE__));

// 初始化插件
require_once PFM_PLUGIN_DIR . 'includes/class-pfm-init.php';

第二部分:数据库设计与数据模型

2.1 创建自定义数据库表

个人财务数据需要专门的数据库表来存储。我们将在插件激活时创建这些表:

// 在includes/class-pfm-db.php中
class PFM_DB {
    
    public static function create_tables() {
        global $wpdb;
        
        $charset_collate = $wpdb->get_charset_collate();
        
        // 财务记录表
        $table_name = $wpdb->prefix . 'pfm_transactions';
        
        $sql = "CREATE TABLE IF NOT EXISTS $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            user_id bigint(20) NOT NULL,
            type varchar(20) NOT NULL COMMENT 'income/expense',
            category varchar(100) NOT NULL,
            amount decimal(10,2) NOT NULL,
            description text,
            transaction_date date NOT NULL,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY user_id (user_id),
            KEY transaction_date (transaction_date),
            KEY category (category)
        ) $charset_collate;";
        
        // 预算表
        $budget_table = $wpdb->prefix . 'pfm_budgets';
        
        $budget_sql = "CREATE TABLE IF NOT EXISTS $budget_table (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            user_id bigint(20) NOT NULL,
            category varchar(100) NOT NULL,
            budget_amount decimal(10,2) NOT NULL,
            period varchar(20) NOT NULL COMMENT 'monthly/yearly',
            start_date date NOT NULL,
            end_date date,
            created_at datetime DEFAULT CURRENT_TIMESTAMP,
            PRIMARY KEY (id),
            KEY user_id (user_id),
            KEY period (period)
        ) $charset_collate;";
        
        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
        dbDelta($budget_sql);
    }
}

2.2 数据模型类

创建数据模型类来处理财务数据的CRUD操作:

// 在includes/class-pfm-transaction.php中
class PFM_Transaction {
    
    private $db;
    private $table_name;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
        $this->table_name = $wpdb->prefix . 'pfm_transactions';
    }
    
    // 添加财务记录
    public function add($user_id, $data) {
        $defaults = array(
            'type' => 'expense',
            'category' => '其他',
            'amount' => 0.00,
            'description' => '',
            'transaction_date' => current_time('Y-m-d')
        );
        
        $data = wp_parse_args($data, $defaults);
        
        return $this->db->insert(
            $this->table_name,
            array(
                'user_id' => $user_id,
                'type' => sanitize_text_field($data['type']),
                'category' => sanitize_text_field($data['category']),
                'amount' => floatval($data['amount']),
                'description' => sanitize_textarea_field($data['description']),
                'transaction_date' => sanitize_text_field($data['transaction_date'])
            ),
            array('%d', '%s', '%s', '%f', '%s', '%s')
        );
    }
    
    // 获取用户的财务记录
    public function get_user_transactions($user_id, $filters = array()) {
        $where = array('user_id = %d');
        $params = array($user_id);
        
        if (!empty($filters['type'])) {
            $where[] = 'type = %s';
            $params[] = $filters['type'];
        }
        
        if (!empty($filters['category'])) {
            $where[] = 'category = %s';
            $params[] = $filters['category'];
        }
        
        if (!empty($filters['start_date'])) {
            $where[] = 'transaction_date >= %s';
            $params[] = $filters['start_date'];
        }
        
        if (!empty($filters['end_date'])) {
            $where[] = 'transaction_date <= %s';
            $params[] = $filters['end_date'];
        }
        
        $where_clause = implode(' AND ', $where);
        
        $sql = $this->db->prepare(
            "SELECT * FROM {$this->table_name} WHERE {$where_clause} ORDER BY transaction_date DESC",
            $params
        );
        
        return $this->db->get_results($sql);
    }
    
    // 更多方法:更新、删除、统计等
}

第三部分:用户界面与前端开发

3.1 创建管理页面

在WordPress后台添加财务管理菜单项:

// 在includes/class-pfm-admin.php中
class PFM_Admin {
    
    public function __construct() {
        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('admin_enqueue_scripts', array($this, 'enqueue_admin_scripts'));
    }
    
    public function add_admin_menu() {
        add_menu_page(
            '个人财务管理',
            '财务记账',
            'read', // 所有登录用户都可以访问
            'personal-finance',
            array($this, 'render_dashboard'),
            'dashicons-chart-area',
            30
        );
        
        add_submenu_page(
            'personal-finance',
            '财务概览',
            '概览',
            'read',
            'personal-finance',
            array($this, 'render_dashboard')
        );
        
        add_submenu_page(
            'personal-finance',
            '添加记录',
            '添加记录',
            'read',
            'pfm-add-transaction',
            array($this, 'render_add_transaction_page')
        );
        
        add_submenu_page(
            'personal-finance',
            '预算管理',
            '预算管理',
            'read',
            'pfm-budgets',
            array($this, 'render_budgets_page')
        );
        
        add_submenu_page(
            'personal-finance',
            '财务报告',
            '报告',
            'read',
            'pfm-reports',
            array($this, 'render_reports_page')
        );
    }
    
    public function render_dashboard() {
        include PFM_PLUGIN_DIR . 'templates/dashboard.php';
    }
    
    // 其他页面渲染方法
}

3.2 前端模板设计

创建财务概览页面模板:

<!-- 在templates/dashboard.php中 -->
<div class="wrap pfm-dashboard">
    <h1><?php echo esc_html(get_admin_page_title()); ?></h1>
    
    <div class="pfm-stats-container">
        <div class="pfm-stat-card">
            <h3>本月收入</h3>
            <div class="pfm-stat-amount income">¥<?php echo number_format($monthly_income, 2); ?></div>
        </div>
        
        <div class="pfm-stat-card">
            <h3>本月支出</h3>
            <div class="pfm-stat-amount expense">¥<?php echo number_format($monthly_expense, 2); ?></div>
        </div>
        
        <div class="pfm-stat-card">
            <h3>本月结余</h3>
            <div class="pfm-stat-amount balance">¥<?php echo number_format($monthly_balance, 2); ?></div>
        </div>
        
        <div class="pfm-stat-card">
            <h3>预算执行率</h3>
            <div class="pfm-stat-amount"><?php echo $budget_usage; ?>%</div>
        </div>
    </div>
    
    <div class="pfm-chart-container">
        <h2>月度收支趋势</h2>
        <canvas id="pfm-monthly-trend-chart" width="400" height="200"></canvas>
    </div>
    
    <div class="pfm-recent-transactions">
        <h2>最近交易记录</h2>
        <table class="wp-list-table widefat fixed striped">
            <thead>
                <tr>
                    <th>日期</th>
                    <th>类别</th>
                    <th>类型</th>
                    <th>描述</th>
                    <th>金额</th>
                    <th>操作</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach($recent_transactions as $transaction): ?>
                <tr>
                    <td><?php echo esc_html($transaction->transaction_date); ?></td>
                    <td><?php echo esc_html($transaction->category); ?></td>
                    <td>
                        <span class="pfm-type-badge <?php echo $transaction->type; ?>">
                            <?php echo $transaction->type == 'income' ? '收入' : '支出'; ?>
                        </span>
                    </td>
                    <td><?php echo esc_html($transaction->description); ?></td>
                    <td class="amount <?php echo $transaction->type; ?>">
                        <?php echo ($transaction->type == 'income' ? '+' : '-') . number_format($transaction->amount, 2); ?>
                    </td>
                    <td>
                        <button class="button button-small edit-transaction" data-id="<?php echo $transaction->id; ?>">编辑</button>
                        <button class="button button-small delete-transaction" data-id="<?php echo $transaction->id; ?>">删除</button>
                    </td>
                </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div>
</div>

3.3 添加记录表单

创建添加财务记录的表单界面:

<!-- 在templates/add-transaction.php中 -->
<div class="wrap pfm-add-transaction">
    <h1>添加财务记录</h1>
    
    <form id="pfm-transaction-form" method="post">
        <?php wp_nonce_field('pfm_add_transaction', 'pfm_nonce'); ?>
        
        <div class="pfm-form-section">
            <h2>基本信息</h2>
            
            <div class="pfm-form-row">
                <label for="transaction-type">类型</label>
                <select id="transaction-type" name="type" required>
                    <option value="income">收入</option>
                    <option value="expense" selected>支出</option>
                </select>
            </div>
            
            <div class="pfm-form-row">
                <label for="transaction-category">类别</label>
                <select id="transaction-category" name="category" required>
                    <option value="餐饮">餐饮</option>
                    <option value="交通">交通</option>
                    <option value="购物">购物</option>
                    <option value="娱乐">娱乐</option>
                    <option value="住房">住房</option>
                    <option value="医疗">医疗</option>
                    <option value="教育">教育</option>
                    <option value="投资">投资</option>
                    <option value="工资收入">工资收入</option>
                    <option value="其他收入">其他收入</option>
                    <option value="其他">其他</option>
                </select>
                <input type="text" id="new-category" name="new_category" placeholder="或输入新类别" style="display:none;">
                <button type="button" id="add-category-btn" class="button">+</button>
            </div>
            
            <div class="pfm-form-row">
                <label for="transaction-amount">金额 (¥)</label>
                <input type="number" id="transaction-amount" name="amount" step="0.01" min="0" required>
            </div>
            
            <div class="pfm-form-row">
                <label for="transaction-date">日期</label>
                <input type="date" id="transaction-date" name="transaction_date" value="<?php echo date('Y-m-d'); ?>" required>
            </div>
        </div>
        
        <div class="pfm-form-section">
            <h2>详细信息</h2>
            
            <div class="pfm-form-row">
                <label for="transaction-description">描述</label>
                <textarea id="transaction-description" name="description" rows="3" placeholder="可选的描述信息..."></textarea>
            </div>
            
            <div class="pfm-form-row">
                <label for="transaction-tags">标签</label>
                <input type="text" id="transaction-tags" name="tags" placeholder="用逗号分隔标签">
            </div>
        </div>
        
        <div class="pfm-form-actions">
            <button type="submit" class="button button-primary">保存记录</button>
            <button type="button" id="save-and-add-another" class="button">保存并继续添加</button>
            <a href="<?php echo admin_url('admin.php?page=personal-finance'); ?>" class="button">返回概览</a>
        </div>
    </form>
</div>

第四部分:预算管理功能实现

4.1 预算数据模型

创建预算管理的数据模型类:

// 在includes/class-pfm-budget.php中
class PFM_Budget {
    
    private $db;
    private $table_name;
    
    public function __construct() {
        global $wpdb;
        $this->db = $wpdb;
        $this->table_name = $wpdb->prefix . 'pfm_budgets';
    }
    
    // 设置预算
    public function set_budget($user_id, $data) {
        $defaults = array(
            'category' => '',
            'budget_amount' => 0.00,
            'period' => 'monthly',
            'start_date' => date('Y-m-01'), // 当月第一天
            'end_date' => null
        );
        
        $data = wp_parse_args($data, $defaults);
        
        // 检查是否已存在该类别同期的预算
        $existing = $this->db->get_var($this->db->prepare(
            "SELECT id FROM {$this->table_name} 
             WHERE user_id = %d AND category = %s AND period = %s 
             AND start_date = %s",
            $user_id, $data['category'], $data['period'], $data['start_date']
        ));
        
        if ($existing) {
            // 更新现有预算
            return $this->db->update(
                $this->table_name,
                array('budget_amount' => floatval($data['budget_amount'])),
                array('id' => $existing),
                array('%f'),
                array('%d')
            );
        } else {
            // 插入新预算
            return $this->db->insert(
                $this->table_name,
                array(
                    'user_id' => $user_id,
                    'category' => sanitize_text_field($data['category']),
                    'budget_amount' => floatval($data['budget_amount']),
                    'period' => sanitize_text_field($data['period']),
                    'start_date' => sanitize_text_field($data['start_date']),
                    'end_date' => $data['end_date'] ? sanitize_text_field($data['end_date']) : null
                ),
                array('%d', '%s', '%f', '%s', '%s', '%s')
            );
        }
    }
    
    // 获取用户预算执行情况
    public function get_budget_progress($user_id, $period = 'current_month') {
        global $wpdb;
        
        // 确定日期范围
        if ($period === 'current_month') {
            $start_date = date('Y-m-01');
            $end_date = date('Y-m-t');
        } elseif ($period === 'current_year') {
            $start_date = date('Y-01-01');
            $end_date = date('Y-12-31');
        } else {
            // 自定义日期范围
            $date_range = explode('_to_', $period);
            $start_date = $date_range[0];
            $end_date = $date_range[1];
        }
        
        // 获取预算数据
        $budgets = $wpdb->get_results($wpdb->prepare(
            "SELECT category, budget_amount, period 
             FROM {$this->table_name} 
             WHERE user_id = %d 
             AND start_date <= %s 
             AND (end_date >= %s OR end_date IS NULL)",
            $user_id, $end_date, $start_date
        ));
        
        $progress_data = array();
        
        foreach ($budgets as $budget) {
            // 获取该类别在指定期间的支出总额
            $transaction_table = $wpdb->prefix . 'pfm_transactions';
            $actual_spent = $wpdb->get_var($wpdb->prepare(
                "SELECT SUM(amount) 
                 FROM {$transaction_table} 
                 WHERE user_id = %d 
                 AND category = %s 
                 AND type = 'expense' 
                 AND transaction_date BETWEEN %s AND %s",
                $user_id, $budget->category, $start_date, $end_date
            )) ?: 0;
            
            $progress_data[] = array(
                'category' => $budget->category,
                'budget_amount' => floatval($budget->budget_amount),
                'actual_spent' => floatval($actual_spent),
                'remaining' => floatval($budget->budget_amount) - floatval($actual_spent),
                'usage_percentage' => $budget->budget_amount > 0 ? 
                    (floatval($actual_spent) / floatval($budget->budget_amount)) * 100 : 0
            );
        }
        
        return $progress_data;
    }
}

4.2 预算管理界面

创建预算管理页面模板:

<!-- 在templates/budgets.php中 -->
<div class="wrap pfm-budgets">
    <h1>预算管理</h1>
    
    <div class="pfm-tabs">
        <button class="pfm-tab-button active" data-tab="current-budgets">当前预算</button>
        <button class="pfm-tab-button" data-tab="set-budget">设置预算</button>
        <button class="pfm-tab-button" data-tab="budget-history">历史预算</button>
    </div>
    
    <div id="current-budgets" class="pfm-tab-content active">
        <h2>当前预算执行情况</h2>
        
        <div class="pfm-period-selector">
            <label for="budget-period">查看期间:</label>
            <select id="budget-period">
                <option value="current_month">本月</option>
                <option value="current_year">本年</option>
                <option value="last_month">上月</option>
                <option value="last_year">去年</option>
            </select>
        </div>
        
        <div class="pfm-budget-progress-container">
            <?php foreach ($budget_progress as $item): ?>
            <div class="pfm-budget-item">
                <div class="pfm-budget-header">
                    <h3><?php echo esc_html($item['category']); ?></h3>
                    <span class="pfm-budget-amount">预算:¥<?php echo number_format($item['budget_amount'], 2); ?></span>
                </div>
                
                <div class="pfm-progress-bar-container">
                    <div class="pfm-progress-bar">
                        <div class="pfm-progress-fill" 
                             style="width: <?php echo min($item['usage_percentage'], 100); ?>%;
                                    background-color: <?php echo $item['usage_percentage'] > 90 ? '#f44336' : ($item['usage_percentage'] > 70 ? '#ff9800' : '#4CAF50'); ?>">
                        </div>
                    </div>
                    <div class="pfm-progress-text">
                        <span>已用:¥<?php echo number_format($item['actual_spent'], 2); ?></span>
                        <span>剩余:¥<?php echo number_format($item['remaining'], 2); ?></span>
                        <span>使用率:<?php echo number_format($item['usage_percentage'], 1); ?>%</span>
                    </div>
                </div>
                
                <?php if ($item['usage_percentage'] > 100): ?>
                <div class="pfm-budget-alert">
                    <span class="dashicons dashicons-warning"></span>
                    已超出预算 <?php echo number_format($item['usage_percentage'] - 100, 1); ?>%
                </div>
                <?php endif; ?>
            </div>
            <?php endforeach; ?>
        </div>
    </div>
    
    <div id="set-budget" class="pfm-tab-content">
        <h2>设置新预算</h2>
        
        <form id="pfm-budget-form" method="post">
            <?php wp_nonce_field('pfm_set_budget', 'pfm_budget_nonce'); ?>
            
            <div class="pfm-form-row">
                <label for="budget-category">预算类别</label>
                <select id="budget-category" name="category" required>
                    <option value="">选择类别</option>
                    <option value="餐饮">餐饮</option>
                    <option value="交通">交通</option>
                    <option value="购物">购物</option>
                    <option value="娱乐">娱乐</option>
                    <option value="住房">住房</option>
                    <option value="医疗">医疗</option>
                    <option value="教育">教育</option>
                    <option value="其他">其他</option>
                </select>
            </div>
            
            <div class="pfm-form-row">
                <label for="budget-amount">预算金额 (¥)</label>
                <input type="number" id="budget-amount" name="budget_amount" step="0.01" min="0" required>
            </div>
            
            <div class="pfm-form-row">
                <label for="budget-period">预算周期</label>
                <select id="budget-period" name="period" required>
                    <option value="monthly">月度预算</option>
                    <option value="yearly">年度预算</option>
                    <option value="custom">自定义周期</option>
                </select>
            </div>
            
            <div id="custom-period-fields" style="display: none;">
                <div class="pfm-form-row">
                    <label for="budget-start-date">开始日期</label>
                    <input type="date" id="budget-start-date" name="start_date">
                </div>
                
                <div class="pfm-form-row">
                    <label for="budget-end-date">结束日期</label>
                    <input type="date" id="budget-end-date" name="end_date">
                </div>
            </div>
            
            <div class="pfm-form-actions">
                <button type="submit" class="button button-primary">保存预算</button>
                <button type="reset" class="button">重置</button>
            </div>
        </form>
    </div>
</div>

第五部分:数据可视化与报表功能

5.1 图表数据接口

创建API接口提供图表数据:

// 在includes/class-pfm-api.php中
class PFM_API {
    
    public function __construct() {
        add_action('wp_ajax_pfm_get_chart_data', array($this, 'get_chart_data'));
        add_action('wp_ajax_nopriv_pfm_get_chart_data', array($this, 'require_login'));
    }
    
    public function get_chart_data() {
        // 验证用户权限
        if (!is_user_logged_in()) {
            wp_die('请先登录');
        }
        
        $user_id = get_current_user_id();
        $chart_type = sanitize_text_field($_POST['chart_type']);
        $period = sanitize_text_field($_POST['period']);
        
        switch ($chart_type) {
            case 'monthly_trend':
                $data = $this->get_monthly_trend_data($user_id, $period);
                break;
                
            case 'category_distribution':
                $data = $this->get_category_distribution_data($user_id, $period);
                break;
                
            case 'budget_vs_actual':
                $data = $this->get_budget_vs_actual_data($user_id, $period);
                break;
                
            default:
                $data = array('error' => '无效的图表类型');
        }
        
        wp_send_json_success($data);
    }
    
    private function get_monthly_trend_data($user_id, $months = 6) {
        global $wpdb;
        
        $end_date = date('Y-m-d');
        $start_date = date('Y-m-d', strtotime("-$months months"));
        
        $transaction_table = $wpdb->prefix . 'pfm_transactions';
        
        // 获取月度收入支出数据
        $results = $wpdb->get_results($wpdb->prepare(
            "SELECT 
                DATE_FORMAT(transaction_date, '%%Y-%%m') as month,
                SUM(CASE WHEN type = 'income' THEN amount ELSE 0 END) as income,
                SUM(CASE WHEN type = 'expense' THEN amount ELSE 0 END) as expense
             FROM {$transaction_table}
             WHERE user_id = %d
             AND transaction_date BETWEEN %s AND %s
             GROUP BY DATE_FORMAT(transaction_date, '%%Y-%%m')
             ORDER BY month",
            $user_id, $start_date, $end_date
        ));
        
        $labels = array();
        $income_data = array();
        $expense_data = array();
        
        foreach ($results as $row) {
            $labels[] = $row->month;
            $income_data[] = floatval($row->income);
            $expense_data[] = floatval($row->expense);
        }
        
        return array(
            'labels' => $labels,
            'datasets' => array(
                array(
                    'label' => '收入',
                    'data' => $income_data,
                    'borderColor' => '#4CAF50',
                    'backgroundColor' => 'rgba(76, 175, 80, 0.1)',
                    'fill' => true
                ),
                array(
                    'label' => '支出',
                    'data' => $expense_data,
                    'borderColor' => '#f44336',
                    'backgroundColor' => 'rgba(244, 67, 54, 0.1)',
                    'fill' => true
                )
            )
        );
    }
    
    private function get_category_distribution_data($user_id, $period = 'current_month') {
        global $wpdb;
        
        // 确定日期范围
        if ($period === 'current_month') {
            $start_date = date('Y-m-01');
            $end_date = date('Y-m-d');
        } else {
            $start_date = date('Y-01-01');
            $end_date = date('Y-12-31');
        }
        
        $transaction_table = $wpdb->prefix . 'pfm_transactions';
        
        $results = $wpdb->get_results($wpdb->prepare(
            "SELECT category, SUM(amount) as total
             FROM {$transaction_table}
             WHERE user_id = %d
             AND type = 'expense'
             AND transaction_date BETWEEN %s AND %s
             GROUP BY category
             ORDER BY total DESC",
            $user_id, $start_date, $end_date
        ));
        
        $labels = array();
        $data = array();
        $background_colors = array();
        $border_colors = array();
        
        // 预定义颜色方案
        $color_palette = array(
            '#FF6384', '#36A2EB', '#FFCE56', '#4BC0C0', 
            '#9966FF', '#FF9F40', '#8AC926', '#1982C4',
            '#6A4C93', '#F15BB5', '#00BBF9', '#00F5D4'
        );
        
        foreach ($results as $index => $row) {
            $labels[] = $row->category;
            $data[] = floatval($row->total);
            $color_index = $index % count($color_palette);
            $background_colors[] = $color_palette[$color_index] . '80'; // 添加透明度
            $border_colors[] = $color_palette[$color_index];
        }
        
        return array(
            'labels' => $labels,
            'datasets' => array(
                array(
                    'data' => $data,
                    'backgroundColor' => $background_colors,
                    'borderColor' => $border_colors,
                    'borderWidth' => 1
                )
            )
        );
    }
}

5.2 图表渲染与交互

创建JavaScript代码来渲染图表:

// 在assets/js/pfm-charts.js中
jQuery(document).ready(function($) {
    
    // 图表实例存储
    var pfmCharts = {};
    
    // 初始化月度趋势图表
    function initMonthlyTrendChart() {
        var ctx = document.getElementById('pfm-monthly-trend-chart').getContext('2d');
        
        // 获取数据
        $.ajax({
            url: pfm_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'pfm_get_chart_data',
                chart_type: 'monthly_trend',
                period: '6_months',
                nonce: pfm_ajax.nonce
            },
            success: function(response) {
                if (response.success) {
                    pfmCharts.monthlyTrend = new Chart(ctx, {
                        type: 'line',
                        data: response.data,
                        options: {
                            responsive: true,
                            maintainAspectRatio: false,
                            plugins: {
                                legend: {
                                    position: 'top',
                                },
                                tooltip: {
                                    callbacks: {
                                        label: function(context) {
                                            return context.dataset.label + ': ¥' + context.parsed.y.toFixed(2);
                                        }
                                    }
                                }
                            },
                            scales: {
                                y: {
                                    beginAtZero: true,
                                    ticks: {
                                        callback: function(value) {
                                            return '¥' + value;
                                        }
                                    }
                                }
                            }
                        }
                    });
                }
            }
        });
    }
    
    // 初始化分类分布图表
    function initCategoryDistributionChart() {
        var ctx = document.getElementById('pfm-category-chart').getContext('2d');
        
        $.ajax({
            url: pfm_ajax.ajax_url,
            type: 'POST',
            data: {
                action: 'pfm_get_chart_data',
                chart_type: 'category_distribution',
                period: 'current_month',
                nonce: pfm_ajax.nonce
            },
            success: function(response) {
                if (response.success) {
                    pfmCharts.categoryDistribution = new Chart(ctx, {
                        type: 'doughnut',
                        data: response.data,
                        options: {
                            responsive: true,
                            maintainAspectRatio: false,
                            plugins: {
                                legend: {
                                    position: 'right',
                                },
                                tooltip: {
                                    callbacks: {
                                        label: function(context) {
                                            var label = context.label || '';
                                            var value = context.parsed || 0;
                                            var total = context.dataset.data.reduce((a, b) => a + b, 0);
                                            var percentage = Math.round((value / total) * 100);
                                            return label + ': ¥' + value.toFixed(2) + ' (' + percentage + '%)';
                                        }
                                    }
                                }
                            }
                        }
                    });
                }
            }
        });
    }
    
    // 更新图表数据
    function updateChart(chartType, period) {
        if (pfmCharts[chartType]) {
            $.ajax({
                url: pfm_ajax.ajax_url,
                type: 'POST',
                data: {
                    action: 'pfm_get_chart_data',
                    chart_type: chartType,
                    period: period,
                    nonce: pfm_ajax.nonce
                },
                success: function(response) {
                    if (response.success) {
                        pfmCharts[chartType].data = response.data;
                        pfmCharts[chartType].update();
                    }
                }
            });
        }
    }
    
    // 初始化所有图表
    if ($('#pfm-monthly-trend-chart').length) {
        initMonthlyTrendChart();
    }
    
    if ($('#pfm-category-chart').length) {
        initCategoryDistributionChart();
    }
    
    // 图表控制事件
    $('.pfm-chart-controls select').on('change', function() {
        var chartType = $(this).data('chart-type');
        var period = $(this).val();
        updateChart(chartType, period);
    });
});

5.3 报表生成功能

创建报表生成功能:

// 在includes/class-pfm-reports.php中
class PFM_Reports {
    
    public function generate_monthly_report($user_id, $year, $month) {
        global $wpdb;
        
        $start_date = sprintf('%04d-%02d-01', $year, $month);
        $end_date = date('Y-m-t', strtotime($start_date));
        
        $transaction_table = $wpdb->prefix . 'pfm_transactions';
        $budget_table = $wpdb->prefix . 'pfm_budgets';
        
        // 获取月度汇总数据
        $summary = $wpdb->get_row($wpdb->prepare(
            "SELECT 
本文来自网络,不代表柔性供应链服务中心立场,转载请注明出处:https://mall.org.cn/5238.html

EXCHANGES®作者

上一篇
下一篇

为您推荐

发表回复

联系我们

联系我们

18559313275

在线咨询: QQ交谈

邮箱: vip@exchanges.center

工作时间:周一至周五,9:00-17:30,节假日休息
返回顶部