You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Manufacturing Industry Pro主题下实现用户发票查看编辑删除(无插件)

无需额外插件实现My Account发票管理分步方案

1. 创建自定义数据库表存储发票信息

首先需要创建专属表来保存发票的用户关联信息、元数据和文件路径,避免和WordPress默认数据混淆。将以下代码添加到主题的functions.php文件:

function create_user_invoices_table() {
    global $wpdb;
    $table_name = $wpdb->prefix . 'user_invoices';
    $charset_collate = $wpdb->get_charset_collate();

    // 仅在表不存在时创建
    if ($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
        $sql = "CREATE TABLE $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            user_id mediumint(9) NOT NULL,
            tax_number varchar(255) NOT NULL,
            invoice_date date NOT NULL,
            invoice_number varchar(255) NOT NULL,
            invoice_amount decimal(10,2) NOT NULL,
            file_path varchar(255) NOT NULL,
            created_at datetime DEFAULT CURRENT_TIMESTAMP NOT NULL,
            updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL,
            PRIMARY KEY (id),
            KEY user_id_idx (user_id)
        ) $charset_collate;";

        require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
        dbDelta($sql);
    }
}
add_action('after_setup_theme', 'create_user_invoices_table');

代码执行一次后可注释,避免重复触发表创建逻辑。

2. 修改Contact Form 7提交逻辑,同步保存数据到数据库

调整CF7的提交钩子,将表单数据和上传文件保存到数据库,同时保留原邮件发送功能。注意替换代码中的表单ID和字段名称为你实际使用的内容:

function save_cf7_invoice_to_db($contact_form) {
    // 替换为你的CF7表单ID
    if ($contact_form->id() != 123) return;

    $submission = WPCF7_Submission::get_instance();
    if (!$submission || !is_user_logged_in()) return;

    $data = $submission->get_posted_data();
    $uploaded_files = $submission->uploaded_files();
    $user_id = get_current_user_id();
    global $wpdb;
    $table_name = $wpdb->prefix . 'user_invoices';

    // 限制用户最多5张发票
    $invoice_count = $wpdb->get_var($wpdb->prepare("SELECT COUNT(*) FROM $table_name WHERE user_id = %d", $user_id));
    if ($invoice_count >= 5) {
        $submission->set_response('最多只能上传5张发票');
        return;
    }

    // 处理文件上传
    $file_path = '';
    if (!empty($uploaded_files['invoice-file'])) {
        $temp_file = $uploaded_files['invoice-file'];
        $upload_dir = wp_upload_dir();
        $target_dir = $upload_dir['basedir'] . '/user-invoices/';
        
        // 创建存储目录
        if (!file_exists($target_dir)) {
            mkdir($target_dir, 0755, true);
        }

        $file_name = wp_unique_filename($target_dir, basename($temp_file));
        $target_path = $target_dir . $file_name;
        
        if (move_uploaded_file($temp_file, $target_path)) {
            $file_path = $upload_dir['baseurl'] . '/user-invoices/' . $file_name;
        } else {
            $submission->set_response('文件上传失败,请重试');
            return;
        }
    }

    // 写入数据库
    $wpdb->insert(
        $table_name,
        array(
            'user_id' => $user_id,
            'tax_number' => sanitize_text_field($data['tax-number']),
            'invoice_date' => sanitize_text_field($data['invoice-date']),
            'invoice_number' => sanitize_text_field($data['invoice-number']),
            'invoice_amount' => floatval($data['invoice-amount']),
            'file_path' => $file_path
        ),
        array('%d', '%s', '%s', '%s', '%f', '%s')
    );
}
add_action('wpcf7_before_send_mail', 'save_cf7_invoice_to_db');

3. 在My Account页面添加发票管理标签页

通过WooCommerce的钩子添加自定义端点和菜单,让用户能在个人中心访问发票管理页面:

// 添加菜单项到My Account导航
function add_invoices_account_menu($items) {
    $items['invoices'] = '我的发票';
    return $items;
}
add_filter('woocommerce_account_menu_items', 'add_invoices_account_menu');

// 注册自定义端点
function register_invoices_endpoint() {
    add_rewrite_endpoint('invoices', EP_ROOT | EP_PAGES);
}
add_action('init', 'register_invoices_endpoint');

// 刷新重写规则(执行一次后注释)
flush_rewrite_rules();

添加代码后,进入WordPress后台「设置→固定链接」点击保存,确保端点生效。

4. 渲染发票列表与操作页面

实现发票列表展示、查看、编辑、删除功能,添加以下代码到functions.php:

function render_invoices_management_page() {
    if (!is_user_logged_in()) {
        wp_redirect(wp_login_url());
        exit;
    }

    $user_id = get_current_user_id();
    global $wpdb;
    $table_name = $wpdb->prefix . 'user_invoices';
    $invoices = $wpdb->get_results($wpdb->prepare("SELECT * FROM $table_name WHERE user_id = %d ORDER BY created_at DESC", $user_id));

    echo '<div class="woocommerce-MyAccount-content">';
    echo '<h2>我的发票</h2>';

    // 空状态提示
    if (empty($invoices)) {
        echo '<p>暂无发票记录</p>';
    } else {
        // 发票列表表格
        echo '<table class="woocommerce-orders-table shop_table shop_table_responsive account-invoices-table">';
        echo '<thead>
                <tr>
                    <th>发票编号</th>
                    <th>开票日期</th>
                    <th>金额</th>
                    <th>税号</th>
                    <th>操作</th>
                </tr>
              </thead>';
        echo '<tbody>';
        foreach ($invoices as $invoice) {
            echo '<tr>';
            echo '<td data-title="发票编号">' . esc_html($invoice->invoice_number) . '</td>';
            echo '<td data-title="开票日期">' . date('Y-m-d', strtotime($invoice->invoice_date)) . '</td>';
            echo '<td data-title="金额">' . wc_price($invoice->invoice_amount) . '</td>';
            echo '<td data-title="税号">' . esc_html($invoice->tax_number) . '</td>';
            echo '<td data-title="操作">';
            echo '<a href="' . esc_url($invoice->file_path) . '" target="_blank" class="button button-small">查看</a> ';
            echo '<a href="' . esc_url(add_query_arg('edit_invoice', $invoice->id, wc_get_account_endpoint_url('invoices'))) . '" class="button button-small">编辑</a> ';
            echo '<a href="' . esc_url(wp_nonce_url(add_query_arg('delete_invoice', $invoice->id, wc_get_account_endpoint_url('invoices')), 'delete_invoice_' . $invoice->id)) . '" class="button button-small button-danger" onclick="return confirm(\'确定删除该发票?\')">删除</a>';
            echo '</td>';
            echo '</tr>';
        }
        echo '</tbody></table>';
    }

    // 处理编辑/删除动作
    handle_invoice_actions();

    echo '</div>';
}
add_action('woocommerce_account_invoices_endpoint', 'render_invoices_management_page');

// 处理发票编辑与删除逻辑
function handle_invoice_actions() {
    if (!is_user_logged_in()) return;
    $user_id = get_current_user_id();
    global $wpdb;
    $table_name = $wpdb->prefix . 'user_invoices';

    // 删除发票
    if (isset($_GET['delete_invoice']) && wp_verify_nonce($_GET['_wpnonce'], 'delete_invoice_' . $_GET['delete_invoice'])) {
        $invoice_id = intval($_GET['delete_invoice']);
        $invoice = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d AND user_id = %d", $invoice_id, $user_id));
        
        if ($invoice) {
            // 删除服务器文件
            $local_file_path = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $invoice->file_path);
            if (file_exists($local_file_path)) unlink($local_file_path);
            
            // 删除数据库记录
            $wpdb->delete($table_name, array('id' => $invoice_id), array('%d'));
        }
        wp_redirect(wc_get_account_endpoint_url('invoices'));
        exit;
    }

    // 编辑发票
    if (isset($_GET['edit_invoice'])) {
        $invoice_id = intval($_GET['edit_invoice']);
        $invoice = $wpdb->get_row($wpdb->prepare("SELECT * FROM $table_name WHERE id = %d AND user_id = %d", $invoice_id, $user_id));
        
        if (!$invoice) {
            wp_redirect(wc_get_account_endpoint_url('invoices'));
            exit;
        }

        // 处理表单提交
        if (isset($_POST['update_invoice']) && wp_verify_nonce($_POST['update_invoice_nonce'], 'update_invoice_' . $invoice_id)) {
            $update_data = array(
                'tax_number' => sanitize_text_field($_POST['tax-number']),
                'invoice_date' => sanitize_text_field($_POST['invoice-date']),
                'invoice_number' => sanitize_text_field($_POST['invoice-number']),
                'invoice_amount' => floatval($_POST['invoice-amount'])
            );

            // 处理文件替换
            if (!empty($_FILES['invoice-file']['tmp_name'])) {
                // 删除旧文件
                $old_local_path = str_replace(wp_upload_dir()['baseurl'], wp_upload_dir()['basedir'], $invoice->file_path);
                if (file_exists($old_local_path)) unlink($old_local_path);
                
                // 上传新文件
                $upload_dir = wp_upload_dir();
                $target_dir = $upload_dir['basedir'] . '/user-invoices/';
                $file_name = wp_unique_filename($target_dir, basename($_FILES['invoice-file']['name']));
                $target_path = $target_dir . $file_name;
                
                if (move_uploaded_file($_FILES['invoice-file']['tmp_name'], $target_path)) {
                    $update_data['file_path'] = $upload_dir['baseurl'] . '/user-invoices/' . $file_name;
                }
            }

            // 更新数据库
            $wpdb->update(
                $table_name,
                $update_data,
                array('id' => $invoice_id),
                array('%s', '%s', '%s', '%f', '%s'),
                array('%d')
            );

            wp_redirect(wc_get_account_endpoint_url('invoices'));
            exit;
        }

        // 渲染编辑表单
        echo '<h3>编辑发票</h3>';
        echo '<form method="post" enctype="multipart/form-data" class="woocommerce-form-edit-invoice">';
        wp_nonce_field('update_invoice_' . $invoice_id, 'update_invoice_nonce');
        echo '<div class="form-row">
                <label for="tax-number">税号</label>
                <input type="text" name="tax-number" id="tax-number" value="' . esc_attr($invoice->tax_number) . '" required>
              </div>';
        echo '<div class="form-row">
                <label for="invoice-date">开票日期</label>
                <input type="date" name="invoice-date" id="invoice-date" value="' . esc_attr($invoice->invoice_date) . '" required>
              </div>';
        echo '<div class="form-row">
                <label for="invoice-number">发票编号</label>
                <input type="text" name="invoice-number" id="invoice-number" value="' . esc_attr($invoice->invoice_number) . '" required>
              </div>';
        echo '<div class="form-row">
                <label for="invoice-amount">发票金额</label>
                <input type="number" step="0.01" name="invoice-amount" id="invoice-amount" value="' . esc_attr($invoice->invoice_amount) . '" required>
              </div>';
        echo '<div class="form-row">
                <label for="invoice-file">替换发票文件(可选)</label>
                <input type="file" name="invoice-file" id="invoice-file" accept=".pdf,.jpg,.jpeg,.png">
                <small>当前文件:<a href="' . esc_url($invoice->file_path) . '" target="_blank">查看</a></small>
              </div>';
        echo '<div class="form-row">
                <button type="submit" name="update_invoice" class="button">保存修改</button>
                <a href="' . esc_url(wc_get_account_endpoint_url('invoices')) . '" class="button">取消</a>
              </div>';
        echo '</form>';
    }
}

5. 样式适配(可选)

添加以下CSS到主题自定义样式中,让发票页面和主题风格统一:

.account-invoices-table {
    width: 100%;
    margin: 2em 0;
    border-collapse: collapse;
}
.account-invoices-table th, .account-invoices-table td {
    padding: 12px;
    border-bottom: 1px solid #eee;
}
.woocommerce-form-edit-invoice .form-row {
    margin-bottom: 1.5em;
}
.woocommerce-form-edit-invoice label {
    display: block;
    margin-bottom: 0.5em;
    font-weight: 600;
}
.woocommerce-form-edit-invoice input[type="text"],
.woocommerce-form-edit-invoice input[type="date"],
.woocommerce-form-edit-invoice input[type="number"] {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 4px;
}
.button-danger {
    background-color: #dc3232;
    color: #fff;
}
.button-danger:hover {
    background-color: #b92c2c;
}

注意事项

  • 所有代码建议添加到主题的functions.php,或创建一个独立的自定义插件(避免主题更新丢失代码)。
  • 操作前备份数据库和网站文件。
  • 确保服务器目录权限正确(user-invoices目录需具备写入权限)。
  • 可在CF7表单中添加额外验证规则,比如限制文件类型为PDF/图片、金额为正数等。

内容的提问来源于stack exchange,提问作者golnaz mohamadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:27:17