织梦列表页点赞功能如何实现?

99ANYc3cd6
预计阅读时长 36 分钟
位置: 首页 织梦建站 正文

在列表页通过 JavaScript 获取文章ID,然后调用一个专门处理点赞请求的Ajax接口,这个接口由一个独立的PHP文件来处理,完成数据库的更新操作。

织梦列表页的点赞功能
(图片来源网络,侵删)

下面是详细的步骤,分为两种常见的实现方式:


为每篇文章添加独立的点赞按钮(推荐)

这种方式最直观,用户可以对列表页中的任意一篇文章进行点赞。

第1步:准备数据库表

我们需要一个专门的表来存储点赞数据,或者直接在文章表(dede_archives)中增加字段。

方案A:直接在文章表增加字段(简单)

织梦列表页的点赞功能
(图片来源网络,侵删)
  1. 登录你的phpMyAdmin。
  2. 选择织梦数据库。
  3. 找到 dede_archives 表(或你自定义的文章表)。
  4. 点击“结构” -> “添加字段”。
  5. 添加一个新字段:
    • 字段名: likes
    • 类型: int(10)
    • 属性: UNSIGNED (无符号)
    • 默认值: 0
    • 注释: 点赞数

方案B:建立独立的点赞记录表(更规范)

这种方式可以记录每个用户对每篇文章的点赞,防止重复点赞。

  1. 在数据库中执行以下SQL语句创建一个新表:
    CREATE TABLE `dede_likes` (
      `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
      `aid` int(10) unsigned NOT NULL COMMENT '文章ID',
      `ip` varchar(20) NOT NULL COMMENT '点赞IP',
      `addtime` int(10) unsigned NOT NULL COMMENT '点赞时间',
      PRIMARY KEY (`id`),
      UNIQUE KEY `uk_aid_ip` (`aid`,`ip`) -- 防止同一IP对同一篇文章重复点赞
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COMMENT='点赞记录表';
  2. dede_archives 表中也添加一个 likes 字段来记录总点赞数(同方案A)。

第2步:创建点赞处理程序(Ajax接口)

这是核心的后端逻辑。

  1. 在网站根目录下创建一个新文件,命名为 like.php

    织梦列表页的点赞功能
    (图片来源网络,侵删)
  2. 将以下代码复制到 like.php 中:

    <?php
    /**
     * 织梦列表页点赞处理程序
     * @author Your Name
     */
    // 引入织梦核心文件,确保数据库连接正常
    // define('DEDEADMIN', str_replace("\\", '/', dirname(__FILE__)));
    require_once (dirname(__FILE__) . "/include/common.inc.php");
    // 设置响应头为JSON格式
    header('Content-Type: application/json; charset=utf-8');
    // 1. 接收前端传来的参数
    $articleId = isset($_POST['aid']) ? intval($_POST['aid']) : 0;
    // 2. 参数校验
    if (empty($articleId)) {
        echo json_encode(['code' => 400, 'msg' => '文章ID无效']);
        exit;
    }
    // 获取当前用户的IP地址
    $ip = GetIP();
    // --- 根据你选择的数据库方案,选择下面的代码块 ---
    // 方案A:直接在文章表更新(不防止重复点赞)
    $updateQuery = "UPDATE `dede_archives` SET `likes` = `likes` + 1 WHERE `id` = {$articleId}";
    $result = $dsql->ExecuteNoneQuery($updateQuery);
    if ($result) {
        echo json_encode(['code' => 200, 'msg' => '点赞成功!']);
    } else {
        echo json_encode(['code' => 500, 'msg' => '点赞失败,请稍后再试。']);
    }
    /*
    // 方案B:通过独立记录表实现(防止重复点赞)
    // 先检查是否已经点过赞
    $checkQuery = "SELECT COUNT(*) FROM `dede_likes` WHERE `aid` = {$articleId} AND `ip` = '{$ip}'";
    $hasLiked = $dsql->GetOne($checkQuery);
    if ($hasLiked['COUNT(*)'] > 0) {
        echo json_encode(['code' => 403, 'msg' => '您已经点过赞了!']);
        exit;
    }
    // 开启事务,保证数据一致性
    $dsql->ExecuteNoneQuery('START TRANSACTION');
    // 1. 在点赞记录表中插入一条记录
    $insertQuery = "INSERT INTO `dede_likes` (`aid`, `ip`, `addtime`) VALUES ({$articleId}, '{$ip}', " . time() . ")";
    $insertResult = $dsql->ExecuteNoneQuery($insertQuery);
    // 2. 在文章表中更新点赞数
    $updateQuery = "UPDATE `dede_archives` SET `likes` = `likes` + 1 WHERE `id` = {$articleId}";
    $updateResult = $dsql->ExecuteNoneQuery($updateQuery);
    // 判断两个操作是否都成功
    if ($insertResult && $updateResult) {
        $dsql->ExecuteNoneQuery('COMMIT'); // 提交事务
        echo json_encode(['code' => 200, 'msg' => '点赞成功!']);
    } else {
        $dsql->ExecuteNoneQuery('ROLLBACK'); // 回滚事务
        echo json_encode(['code' => 500, 'msg' => '点赞失败,请稍后再试。']);
    }
    */
    exit;
    ?>

第3步:修改列表页模板文件

  1. 找到你的列表页模板文件,通常位于 /templets/default/list_*.htm (list_article.htm)。

  2. 在循环文章的 {dede:list} 标签内部,你需要添加一个点赞按钮和显示点赞数的元素。

    {dede:list pagesize='10'}
    <li>
        <!-- 原有的文章标题链接 -->
        <a href="[field:arcurl/]">[field:title/]</a>
        <!-- 新增的点赞区域 -->
        <div class="like-area">
            <!-- 点赞按钮 -->
            <button class="like-btn" data-aid="[field:id/]">
                <span class="like-icon">👍</span>
                <span class="like-text">赞</span>
            </button>
            <!-- 显示点赞数 -->
            <span class="like-count">[field:likes/]</span>
        </div>
    </li>
    {/dede:list}

第4步:添加CSS样式(可选)

在模板文件的 <head> 部分或外部的CSS文件中,添加一些样式让按钮更好看。

.like-area {
    display: inline-block;
    margin-left: 15px;
    font-size: 12px;
    color: #666;
}
.like-btn {
    background: none;
    border: 1px solid #ccc;
    border-radius: 3px;
    padding: 2px 8px;
    cursor: pointer;
    transition: all 0.2s;
}
.like-btn:hover {
    background-color: #f0f0f0;
    border-color: #999;
}
.like-btn.liked {
    background-color: #ff6b6b;
    color: white;
    border-color: #ff6b6b;
}
.like-count {
    margin-left: 5px;
}

第5步:编写JavaScript代码(核心交互)

在列表页模板的底部,</body> 标签之前,添加以下JavaScript代码。

<script>
document.addEventListener('DOMContentLoaded', function() {
    // 获取所有的点赞按钮
    const likeButtons = document.querySelectorAll('.like-btn');
    likeButtons.forEach(button => {
        button.addEventListener('click', function() {
            // 获取文章ID
            const articleId = this.getAttribute('data-aid');
            // 获取显示点赞数的元素
            const likeCountElement = this.parentElement.querySelector('.like-count');
            // 禁用按钮,防止重复点击
            this.disabled = true;
            this.classList.add('liked');
            this.querySelector('.like-text').textContent = '已赞';
            // 使用 Fetch API 发送 POST 请求到 like.php
            fetch('like.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'aid=' + articleId
            })
            .then(response => response.json())
            .then(data => {
                if (data.code === 200) {
                    // 点赞成功,更新点赞数
                    // 注意:这里直接从后端获取最新值是最准确的,但为了简单,我们先前端+1
                    // 更好的做法是让 like.php 返回新的点赞数
                    let currentCount = parseInt(likeCountElement.textContent);
                    likeCountElement.textContent = currentCount + 1;
                } else if (data.code === 403) {
                    // 如果已经点过赞,恢复按钮状态
                    alert(data.msg);
                    this.disabled = false;
                    this.classList.remove('liked');
                    this.querySelector('.like-text').textContent = '赞';
                } else {
                    // 点赞失败,恢复按钮状态
                    alert(data.msg);
                    this.disabled = false;
                    this.classList.remove('liked');
                    this.querySelector('.like-text').textContent = '赞';
                }
            })
            .catch(error => {
                console.error('Error:', error);
                alert('网络请求失败,请稍后再试。');
                this.disabled = false;
                this.classList.remove('liked');
                this.querySelector('.like-text').textContent = '赞';
            });
        });
    });
});
</script>

在列表页顶部添加一个“点赞当前列表”的按钮

这种方式适用于用户想对整个列表(比如一个专题)进行点赞。

步骤与方式一类似,但有细微差别:

  1. 数据库和PHP文件 (like.php)

    • 这部分与方式一完全相同,你不需要做任何修改。
  2. 列表页模板

    • 将点赞按钮放在 {dede:list} 循环外面,例如在列表标题旁边。
    <h2 class="list-title">文章列表</h2>
    <div class="list-like-area">
        <button class="list-like-btn">👍 点赞本专题</button>
        <span class="list-like-count">总点赞: <span id="total-likes">0</span></span>
    </div>
    <ul>
        {dede:list pagesize='10'}
        <li>
            <a href="[field:arcurl/]">[field:title/]</a>
        </li>
        {/dede:list}
    </ul>
  3. JavaScript代码

    • 只需要获取一个按钮,并且不需要 data-aid 属性。
    <script>
    document.addEventListener('DOMContentLoaded', function() {
        const listLikeBtn = document.querySelector('.list-like-btn');
        listLikeBtn.addEventListener('click', function() {
            // 对于列表点赞,aid可以写死为一个特定值,或者由后端判断
            // 这里我们传一个特殊的aid,-1,在like.php里做特殊处理
            const specialAid = -1; // 代表整个列表的点赞
            this.disabled = true;
            this.textContent = '已赞';
            fetch('like.php', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded',
                },
                body: 'aid=' + specialAid
            })
            .then(response => response.json())
            .then(data => {
                if (data.code === 200) {
                    // 更新总点赞数
                    const totalLikesElement = document.getElementById('total-likes');
                    let currentCount = parseInt(totalLikesElement.textContent);
                    totalLikesElement.textContent = currentCount + 1;
                } else {
                    alert(data.msg);
                    this.disabled = false;
                    this.textContent = '👍 点赞本专题';
                }
            })
            .catch(error => {
                console.error('Error:', error);
                alert('网络请求失败,请稍后再试。');
                this.disabled = false;
                this.textContent = '👍 点赞本专题';
            });
        });
    });
    </script>

    注意:如果你选择方式二,需要修改 like.php,让它能识别 aid = -1 这个特殊值,并执行相应的逻辑(比如更新一个专门记录“总点赞数”的字段或表)。

步骤 操作 说明
数据库 dede_archives 表添加 likes 字段 存储每篇文章的点赞数
后端接口 创建 like.php 接收 aid,处理点赞逻辑,更新数据库
前端模板 修改 list_*.htm {dede:list} 循环内或外添加点赞按钮和显示元素
样式 添加CSS 美化点赞按钮和布局
交互 编写JavaScript 监听按钮点击,发送Ajax请求,并更新页面显示

推荐使用方式一,因为它功能更完整,用户体验更好,方式二可以作为补充,用于特定场景。

请根据你的实际需求选择合适的方案,并仔细检查每一步的代码,特别是数据库表名和字段名,确保与你的织梦系统一致。

-- 展开阅读全文 --
头像
织梦为何不自动提取缩略图?
« 上一篇 02-20
织梦友情链接调用方法与代码详解
下一篇 » 02-20

相关文章

取消
微信二维码
支付宝二维码

目录[+]