dede likearticleyuanli

99ANYc3cd6
预计阅读时长 21 分钟
位置: 首页 DEDE建站 正文

我们将从功能原理、核心代码、数据表结构实现步骤四个方面来彻底讲明白。

dede likearticleyuanli
(图片来源网络,侵删)

功能原理概述

DedeCMS 的点赞功能,其核心思想是“计数”“记录”

  1. 计数:每篇文章都有一个独立的点赞总数,当用户点击“赞”时,该文章的点赞数 +1
  2. 记录:为了防止用户重复点赞,系统需要记录哪些用户已经给哪些文章点过赞,这通常通过 Cookie 来实现,当用户点赞后,就在他的浏览器里设置一个 Cookie,记录下 文章ID,下次再访问该文章时,程序会先检查这个 Cookie,如果已存在,则不允许再次点赞。

工作流程图:

用户访问文章
      |
      V和点赞按钮(显示当前点赞数)
      |
      V
用户点击“赞”按钮
      |
      V
[前端JS] 发送一个Ajax请求到后端,携带文章ID
      |
      V
[后端PHP] 接收请求:
  1.  检查用户Cookie中是否已存在该文章ID的点赞记录。
  2.  如果存在,则返回“已点赞”的提示,不进行任何操作。
  3.  如果不存在,则:
        a.  更新 `dede_archives` 表中该文章的 `click`(或自定义字段)字段,值 `+1`。
        b.  在 `dede_stow`(或自定义表)中插入一条点赞记录。
        c.  在用户浏览器中设置一个 Cookie,记录该文章ID。
  4.  返回“点赞成功”的提示和最新的点赞数。
      |
      V
[前端JS] 收到响应后,更新页面上的点赞数,并将按钮变为不可点击状态(或改变样式)。

核心代码解析

一个完整的点赞功能通常涉及三个部分:前端HTML/JS、后端PHP处理程序、以及数据表。

数据表结构

DedeCMS 本身没有专门的点赞表,所以我们通常采用两种方式:

dede likearticleyuanli
(图片来源网络,侵删)

利用 click 字段(简单计数,不防重复) dede_archives 表中有一个 click 字段,通常用于记录文章的点击数,我们可以复用它来记录点赞数。

  • 优点:无需建新表,非常简单。
  • 缺点:无法防止用户重复刷新页面进行“重复点赞”。

新建 dede_likes 表(推荐,功能完整) 为了实现“防重复点赞”,我们需要一个独立的表来记录点赞行为。

CREATE TABLE `dede_likes` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID',
  `aid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '文章ID',
  `ip` varchar(20) NOT NULL DEFAULT '' COMMENT '点赞IP地址',
  `create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '点赞时间戳',
  PRIMARY KEY (`id`),
  UNIQUE KEY `aid_ip` (`aid`,`ip`) -- 关键!通过联合唯一索引确保同一IP对同一篇文章只能点赞一次
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  • 优点:功能完整,可以防止重复点赞,甚至可以扩展出“谁在什么时候点赞”的记录。
  • 缺点:需要手动创建数据表。

我们以方式二为例进行讲解,因为它更专业和实用。

前端代码 (HTML + JavaScript)

在文章模板文件 article_article.htm 中,你需要找到合适的位置放置点赞按钮和显示区域。

HTML 部分:

<!-- 在文章内容下方或合适位置添加 -->
<div class="like-box">
    <span class="like-count" id="like-count-{dede:field.id/}">0</span> 人觉得很赞
    <a href="javascript:;" class="like-btn" id="like-btn-{dede:field.id/}" data-aid="{dede:field.id/}">赞</a>
</div>
  • id="like-count-{dede:field.id/}":动态的点赞数显示区域,{dede:field.id/} 是当前文章的ID。
  • id="like-btn-{dede:field.id/}":动态的点赞按钮。
  • data-aid="{dede:field.id/}":将文章ID作为 data-aid 属性存储,方便JS获取。

JavaScript 部分 (通常放在底部或引入外部JS文件):

// 等待文档加载完成
$(document).ready(function() {
    // 为所有带有 .like-btn 类的元素绑定点击事件
    $('.like-btn').on('click', function() {
        // 获取按钮对象
        var $btn = $(this);
        // 获取文章ID
        var aid = $btn.data('aid');
        // 获取点赞数显示元素
        var $count = $('#like-count-' + aid);
        // 1. 先检查Cookie,如果已存在,则直接返回
        if (getCookie('like_' + aid)) {
            alert('您已经点过赞了!');
            return;
        }
        // 2. 发送Ajax请求到后端处理
        $.ajax({
            type: 'POST',
            url: '/plus/like.php', // 后端处理程序的路径
            data: {aid: aid},
            dataType: 'json',
            success: function(response) {
                if (response.status == 1) {
                    // 点赞成功
                    alert(response.msg);
                    // 更新页面上的点赞数
                    $count.text(response.count);
                    // 禁用按钮,防止重复点击
                    $btn.text('已赞').addClass('disabled').off('click');
                    // 设置Cookie,有效期30天
                    setCookie('like_' + aid, 1, 30);
                } else {
                    // 点赞失败(例如已点过)
                    alert(response.msg);
                }
            },
            error: function() {
                alert('请求失败,请稍后再试!');
            }
        });
    });
});
// 设置Cookie的函数
function setCookie(name, value, days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
// 获取Cookie的函数
function getCookie(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

后端处理代码 (PHP)

plus/ 目录下新建一个文件 like.php

<?php
require_once(dirname(__FILE__) . "/../include/common.inc.php");
// 定义返回给前端的数据格式
$return_data = array('status' => 0, 'msg' => '操作失败', 'count' => 0);
// 1. 获取前端传来的文章ID
$aid = isset($aid) && is_numeric($aid) ? intval($aid) : 0;
if ($aid <= 0) {
    $return_data['msg'] = '文章ID无效';
    echo json_encode($return_data);
    exit;
}
// 2. 检查Cookie,防止重复点赞
$cookie_name = 'like_' . $aid;
if (isset($_COOKIE[$cookie_name])) {
    $return_data['status'] = 0;
    $return_data['msg'] = '您已经点过赞了!';
    // 从数据库获取当前点赞数
    $row = $dsql->GetOne("SELECT likes FROM `dede_likes` WHERE `aid` = '{$aid}'");
    $return_data['count'] = $row['likes'];
    echo json_encode($return_data);
    exit;
}
// 3. 执行点赞操作(事务处理确保数据一致性)
$dsql->ExecuteNoneQuery("START TRANSACTION");
// 3.1 在 dede_likes 表中插入记录
$ip = GetIP(); // 获取用户IP地址
$now_time = time();
$rs = $dsql->ExecuteNoneQuery("INSERT INTO `dede_likes` (`aid`, `ip`, `create_time`) VALUES ('{$aid}', '{$ip}', '{$now_time}');");
if ($rs) {
    // 3.2 更新 dede_archives 表中的点赞
-- 展开阅读全文 --
头像
{dede:arclist flag=h'
« 上一篇 11-27
Dedecall调用DZ3.1精华帖,为何主页不显示?
下一篇 » 11-27

相关文章

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

目录[+]