织梦点赞功能如何二次开发

系统自带字段说明

织梦文章表dede_archives中已有点赞相关字段:

goodpost:好评数(赞)
badpost:差评数(踩)
scores:综合评分

但系统自带的点赞入口在/plus/feedback.php中,需要登录才能操作,且交互体验较差。要做独立的点赞按钮(无需登录、点击即赞、动画反馈),需要二次开发。

数据库改造

1. 新建点赞记录表

用于防重复点赞,记录每个IP对每篇文章的点赞行为:

CREATE TABLE `dede_zan_log` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `aid` int(11) NOT NULL COMMENT '文章ID',
  `ip` varchar(50) NOT NULL COMMENT '用户IP',
  `addtime` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `aid_ip` (`aid`,`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

2. 确认archives表字段

检查dede_archives表中goodpost字段存在且默认值为0:

ALTER TABLE `dede_archives` MODIFY `goodpost` int(11) DEFAULT 0;

后端AJAX接口开发

新建/plus/zan.php处理点赞请求:

require_once(dirname(__FILE__).'/../include/common.inc.php');
$aid=intval($_POST['aid']);
$ip=GetIP();

// 防刷:检查该IP是否已对本文点赞
$row=$dsql->GetOne("SELECT id FROM dede_zan_log WHERE aid=$aid AND ip='$ip'");
if($row){
    echo json_encode(array('code'=>1,'msg'=>'您已点赞过'));
    exit;
}

// 开启事务
$dsql->ExecuteNoneQuery("UPDATE dede_archives SET goodpost=goodpost+1 WHERE id=$aid");
$dsql->ExecuteNoneQuery("INSERT INTO dede_zan_log(aid,ip,addtime) VALUES($aid,'$ip',".time().")");

// 返回最新点赞数
$row=$dsql->GetOne("SELECT goodpost FROM dede_archives WHERE id=$aid");
echo json_encode(array('code'=>0,'msg'=>'成功','count'=>$row['goodpost']));

前端按钮与交互

在文章模板article_article.htm中合适位置插入点赞按钮:

<button class="like-btn" data-aid="{dede:field.id/}">
 <span class="like-icon"></span>
 <span class="like-text">赞 <b>{dede:field.goodpost/}</b></span>
</button>

CSS样式(纯CSS心形图标):

.like-btn{display:inline-flex;align-items:center;gap:8px;border:1px solid #0891b2;
  background:#fff;color:#0891b2;padding:8px 20px;border-radius:24px;cursor:pointer}
.like-icon{width:16px;height:16px;background:#0891b2;
  clip-path:polygon(50% 100%,0 35%,15% 15%,50% 35%,85% 15%,100% 35%);transition:transform .3s}
.like-btn.liked .like-icon{background:#dc2626;transform:scale(1.3)}
.like-btn.liked{background:#fef2f2;color:#dc2626}

JS逻辑:

$('.like-btn').click(function(){
    var btn=$(this);
    if(btn.hasClass('liked')) return;
    $.post('/plus/zan.php',{aid:btn.data('aid')},function(res){
        if(res.code==0){
            btn.addClass('liked');
            btn.find('b').text(res.count);
        }else{
            alert(res.msg);
        }
    },'json');
});

防刷机制加强

IP限制的局限

单纯IP限制在NAT网络下会误伤同一局域网用户。建议结合Cookie辅助判断:

// 设置已赞Cookie,7天有效
setcookie('zan_'.$aid, 1, time()+86400*7, '/');

接口层先检查Cookie,再查数据库,减少DB查询压力。

频率限制

对同一IP每秒点赞次数做限制,超过3次返回拒绝:

$cacheKey='zan_rate_'.$ip;
if($dsql->GetOne("SELECT COUNT(*) c FROM dede_zan_log WHERE ip='$ip' AND addtime>".(time()-1))['c']>=3){
    die(json_encode(array('code'=>2,'msg'=>'操作太频繁')));
}

会员点赞积分奖励

若希望登录会员点赞可获得积分,可在接口中判断登录态:

if($cfg_ml->IsLogin()){
    $dsql->ExecuteNoneQuery("UPDATE dede_member SET scores=scores+1 WHERE mid={$cfg_ml->M_ID}");
    JoinMemberScore(1, '点赞奖励', $cfg_ml->M_ID);
}
点赞积分不宜过高,建议1-2分,否则会被刷分。同时设置每日点赞积分上限(如10次封顶)。

上线建议

发布前用压测工具模拟高并发点赞请求,确认dede_zan_log表的aid_ip联合索引生效,避免全表扫描。运营层面可在后台增加"点赞排行榜"页面,展示热门文章,激励用户参与互动,提升站点活跃度。