WordPress AI摘要(代码版)

Deepseek提供支持

最近开源了一款基于Deepseek AI 大语言模型开发的wordpress自动生成摘要的插件,用于自动为文章生成简洁明了的摘要。插件支持通过短代码灵活调用,适用于博客、资讯类网站等需要快速生成内容摘要的场景。

Oak-Summary

Oak-Summary

可下载
资源版权归原作者所有,下载即表示您同意相关条款

方法:

广告
广告图片

  1. 将以上 PHP 代码保存为独立插件文件(如 deepseek-summary.php)
  2. 上传到 WordPress 插件目录并激活
  3. 无需任何设置即可在文章底部看到 “生成 AI 摘要” 按钮
  4. 点击按钮会自动调用 DeepSeek API 生成摘要并显示

特性:

  1. 基于 WordPress AJAX 架构,前后端分离
  2. 自动提取文章标题和正文内容(可通过 $content_selector 调整提取范围)
  3. 内置内容过滤(移除 URL)和长度限制(3000 字)
  4. 可定制的摘要生成参数(temperature/max_tokens)
  5. 响应式设计,适配不同屏幕尺寸
  6. 错误处理和加载状态提示

需要在 functions.php 中添加处理 AJAX 请求的钩子。WordPress 要求所有 AJAX 处理函数都必须通过 wp_ajax_(登录用户)或 wp_ajax_nopriv_(未登录用户)钩子注册。

<?php
// DeepSeek AI自动摘要工具 - AJAX处理函数
add_action('wp_ajax_get_deepseek_summary', 'handle_deepseek_summary_request');
add_action('wp_ajax_nopriv_get_deepseek_summary', 'handle_deepseek_summary_request');

function handle_deepseek_summary_request() {
    // 验证nonce
    if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'deepseek_summary_nonce')) {
        wp_send_json_error('无效的请求验证');
        wp_die();
    }
    
    // 验证文章ID
    $postId = intval($_POST['post_id']);
    if (!$postId) {
        wp_send_json_error('无效的文章ID');
        wp_die();
    }
    
    global $wpdb;
    
    // 从wp_posts表获取摘要
    $summary = $wpdb->get_var(
        $wpdb->prepare(
            "SELECT summary FROM {$wpdb->posts} WHERE ID = %d",
            $postId
        )
    );

    // 如果摘要不存在,则生成新摘要
    if (empty($summary)) {
        // 获取文章内容
        $post = get_post($postId);
        if (!$post) {
            wp_send_json_error('文章不存在');
            wp_die();
        }
        
        // DeepSeek API配置
        $apiConfig = [
            'api_key' => 'sk-e8bd206001064db9a35e724116ead537', // 替换为您的API密钥
            'model' => 'deepseek-chat',
            'temperature' => 0.3,
            'max_tokens' => 300,
            'content_length' => 2000, // 最大内容长度
            'cache_duration' => 0, // 缓存有效期(30天,单位:秒)
        ];
        
        // 提取内容
        $rawContent = $post->post_content;
        $cleanContent = strip_tags($rawContent); // 移除HTML标签
        
        // 内容预处理
        $cleanContent = preg_replace('/\s+/', ' ', $cleanContent); // 合并空格
        $cleanContent = trim($cleanContent);
        
        // 限制内容长度
        if (mb_strlen($cleanContent) > $apiConfig['content_length']) {
            $cleanContent = mb_substr($cleanContent, 0, $apiConfig['content_length']) . '...';
        }
        
        // 生成摘要
        $summary = generateDeepSeekSummary($cleanContent, $apiConfig);
        
        // 保存到wp_posts表
        $wpdb->update(
            $wpdb->posts,
            ['summary' => $summary],
            ['ID' => $postId],
            ['%s'],
            ['%d']
        );
    }
    
    wp_send_json_success($summary);
    wp_die();
}

// 确保函数存在
if (!function_exists('generateDeepSeekSummary')) {
    function generateDeepSeekSummary($content, $config) {
        // 验证内容
        if (empty($content)) return "文章内容为空,无法生成摘要";
        
        // 验证配置
        if (empty($config['api_key'])) return "缺少DeepSeek API密钥";
        
        // 构建API请求
        $apiUrl = 'https://api.deepseek.com/v1/chat/completions';
        $headers = [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $config['api_key']
        ];
        
        $data = [
            'model' => $config['model'],
            'messages' => [
                [
                    'role' => 'user',
                    'content' => "请为以下文章生成一个简洁的摘要(约50-100字):\n\n$content"
                ]
            ],
            'temperature' => $config['temperature'],
            'max_tokens' => $config['max_tokens']
        ];
        
        // 初始化cURL
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiUrl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 30秒超时
        
        // 执行请求
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        curl_close($ch);
        
        // 处理响应
        if ($httpCode !== 200) {
            return "API请求失败 (HTTP $httpCode): $error";
        }
        
        $result = json_decode($response, true);
        if (json_last_error() !== JSON_ERROR_NONE) {
            return "API响应解析失败: " . json_last_error_msg();
        }
        
        if (isset($result['choices'][0]['message']['content'])) {
            return $result['choices'][0]['message']['content'];
        } else {
            return "API返回格式异常: " . print_r($result, true);
        }
    }
}

代码保存为 PHP 文件(如deepseek-summary.php

广告
广告图片

<?php
/**
 * DeepSeek AI自动摘要工具 - 数据库存储版(异步加载)
 */

// 检查是否在文章页面
if (is_single()) {
    global $post;
    $postId = $post->ID;
    
    // 生成nonce
    $nonce = wp_create_nonce('deepseek_summary_nonce');
    
    // 输出HTML
    echo '<div class="deepseek-ai-summary">
        <div class="summary-header">
            <h3><i class="bi bi-app-indicator"></i> AI摘要</h3>
            <div class="summary-powered-by-container">
                <span class="summary-powered-by">由 DeepSeek 提供支持</span>
                <button class="summary-toggle-btn" onclick="toggleSummary(\'' . $postId . '\', this)">
                    <i class="bi bi-toggle-off"></i>
                </button>
            </div>
        </div>
        <div id="summary-content-' . $postId . '" class="summary-content hidden">
            <div class="summary-loading">
                <div class="spinner-border" role="status">
                    <span class="visually-hidden"></span>
                </div>
                <p>正在生成AI摘要,请稍候...</p>
            </div>
        </div>
    </div>';
    
    // 添加折叠/展开和AJAX请求脚本
    echo '<script>
        // 存储已加载的摘要内容
        const loadedSummaries = {};
        
        function toggleSummary(postId, button) {
            const contentId = "summary-content-" + postId;
            const content = document.getElementById(contentId);
            
            // 如果内容已加载,直接切换显示状态
            if (loadedSummaries[postId]) {
                content.innerHTML = \'<div class="summary-loaded">\'+ loadedSummaries[postId] +\'</div>\';
                content.classList.toggle("hidden");
            } else {
                // 否则先显示加载状态,然后请求摘要
                content.innerHTML = \'<div class="summary-loading">\' +
                    \'<div class="spinner-border" role="status">\' +
                    \'<span class="visually-hidden"></span></div>\' +
                    \'<p>正在生成AI摘要,请稍候...</p></div>\';
                content.classList.remove("hidden");
                
                // 发送AJAX请求
                fetch("' . admin_url('admin-ajax.php') . '", {
                    method: "POST",
                    headers: {
                        "Content-Type": "application/x-www-form-urlencoded",
                    },
                    body: "action=get_deepseek_summary&post_id=" + postId + "&nonce=' . $nonce . '",
                })
                .then(response => response.json())
                .then(data => {
                    if (data.success) {
                        // 存储并显示摘要
                        loadedSummaries[postId] = data.data;
                        content.innerHTML = \'<div class="summary-loaded">\'+ data.data +\'</div>\';
                    } else {
                        content.innerHTML = \'<div class="summary-error">\' +
                            \'<i class="bi bi-exclamation-triangle text-danger"></i> \' +
                            \'<p>摘要生成失败: \'+ (data.data || "未知错误") +\'</p></div>\';
                    }
                })
                .catch(error => {
                    console.error("Error:", error);
                    content.innerHTML = \'<div class="summary-error">\' +
                        \'<i class="bi bi-exclamation-triangle text-danger"></i> \' +
                        \'<p>摘要生成失败: 网络错误</p></div>\';
                });
            }
            
            // 更新按钮图标
            const icon = button.querySelector("i");
            if (content.classList.contains("hidden")) {
                icon.classList.remove("bi-toggle-on");
                icon.classList.add("bi-toggle-off");
            } else {
                icon.classList.remove("bi-toggle-off");
                icon.classList.add("bi-toggle-on");
            }
        }
    </script>';
}
?>

<style>
.deepseek-ai-summary {
    padding: 1.5rem;
    background-color: #f9fafb;
    border-radius: 0.5rem;
        box-shadow: -4px 2px 71px 0px #3939391a;
}

.summary-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 1rem;
    padding-bottom: 0.75rem;
    border-bottom: 1px solid #e5e7eb;
}

.summary-header h3 {
    margin: 0;
    font-size: 1.25rem;
    font-weight: 600;
    color: #1f2937;
}

.summary-powered-by-container {
    display: flex;
    align-items: center;
}

.summary-powered-by {
    font-size: 0.75rem;
    color: #6b7280;
    margin-right: 0.5rem;
}

.summary-toggle-btn {
    background: none;
    border: none;
    cursor: pointer;
    color: #0d6efd; /* Bootstrap primary color */
    transition: transform 0.3s ease;
    padding: 0.25rem;
    font-size: 1.2rem;
}

.summary-toggle-btn:hover {
    color: #0a58ca; /* Bootstrap primary hover color */
    transform: scale(1.1);
}

.summary-content {
    font-size: 0.95rem;
    line-height: 1.6;
    color: #374151;
    transition: max-height 0.3s ease-out, opacity 0.3s ease-out;
    overflow: hidden;
}

.hidden {
    max-height: 0;
    opacity: 0;
    display: none;
}

.summary-loading {
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 1rem 0;
    color: #6b7280;
}

.spinner-border {
    display: inline-block;
    width: 2rem;
    height: 2rem;
    vertical-align: text-bottom;
    border: 0.25em solid currentColor;
    border-right-color: transparent;
    border-radius: 50%;
    animation: spinner-border 0.75s linear infinite;
}

@keyframes spinner-border {
    to {
        transform: rotate(360deg);
    }
}

.summary-error {
    color: #dc3545;
    padding: 1rem 0;
}

.summary-loaded {
    padding: 1rem 0;
}
</style>
广告
广告图片
温馨提示 : 非特殊注明,否则均为©李联华的博客网原创文章,本站文章未经授权禁止任何形式转载;来自:俄亥俄州·哥伦布 ,欢迎您的访问!
文章链接:https://www.lilianhua.com/wordpress-ai-summary-code-version.html
请先登录才能参与答题
距本场结束剩 00 00 00 00
轻量应用服务器 2核2G
200M峰值带宽,适用于网站搭建、Web应用、容器环境、电商独立站等
立即前往
扫码进入
扫描二维码购买
文澜千文

文澜千文

请登录以使用此功能。

Totaste混合蔬菜味手指饼干320g 孕妇儿童磨牙棒棒形拇指饼干休闲零食品 Totaste混合蔬菜味手指饼干320g 孕妇儿童磨牙棒棒形拇指饼干休闲零食品
Loading...