用deepseek写了一个文章点赞功能

在ThinkPHP 6.1中实现点赞功能,结合Redis作为缓存和数据存储,可以有效地提高性能和并发处理能力。以下是一个基本的设计思路和代码实现示例。

设计思路

  1. 数据结构设计

    • 使用Redis的Hash结构来存储每个内容的点赞数,键名为like:content_id,字段为用户ID,值为点赞状态(1表示已点赞,0表示未点赞)。
    • 使用Redis的Set结构来存储每个用户的点赞记录,键名为user:user_id:likes,值为内容ID。
  2. 点赞操作

    • 用户点赞时,首先检查用户是否已经点赞过该内容。
    • 如果未点赞,则在Hash中增加点赞数,并在Set中记录用户的点赞。
    • 如果已点赞,则取消点赞,减少点赞数,并从Set中移除记录。
  3. 获取点赞数

    • 直接从Hash中获取某个内容的点赞数。
  4. 获取用户点赞记录

    • Set中获取某个用户的点赞记录。

代码实现

首先,确保你已经安装了predis/predis库来操作Redis。

bash 复制代码
composer require predis/predis

然后,在ThinkPHP 6.1中编写代码:

php 复制代码
<?php

namespace app\api\controller;

use app\BaseController;
use think\facade\Cache;

class Like extends BaseController
{
    // 点赞或取消点赞
    public function like()
    {
        $param = $this->request->POST();
        $contentId = $param['contentId'];
        $userId = $param['userId'];
        $redis = Cache::store('redis')->handler();
        $likeKey = "like:{$contentId}";
        $userLikeKey = "user:{$userId}:likes";

        // 检查用户是否已经点赞
        if ($redis->hget($likeKey, $userId)) {
            // 取消点赞
            $redis->hset($likeKey, $userId, 0);
            $redis->srem($userLikeKey, $contentId);
            $redis->hincrby($likeKey, 'count', -1);
        } else {
            // 点赞
            $redis->hset($likeKey, $userId, 1);
            $redis->sadd($userLikeKey, $contentId);
            $redis->hincrby($likeKey, 'count', 1);
        }

        return json(['code' => 200, 'msg' => '操作成功']);
    }

    // 获取内容的点赞数
    public function getLikeCount()
    {
        $param = $this->request->get();
        $contentId = $param['contentId'];
        $redis = Cache::store('redis')->handler();
        $likeKey = "like:{$contentId}";
        $count = $redis->hget($likeKey, 'count');

        return json(['code' => 200, 'data' => ['count' => !$count ? 0:$count]]);
    }

    // 获取用户的点赞记录
    public function getUserLikes($userId)
    {
        $redis = Cache::store('redis')->handler();
        $userLikeKey = "user:{$userId}:likes";
        $likes = $redis->smembers($userLikeKey);

        return json(['code' => 200, 'data' => ['likes' => $likes]]);
    }
}

配置Redis

config/cache.php中配置Redis:

dart 复制代码
return [
    'default' => 'redis',
    'stores'  => [
        'redis' => [
            'type'       => 'redis',
            'host'       => '127.0.0.1',
            'port'       => 6379,
            'password'   => '',
            'select'    => 0,
            'timeout'    => 0,
            'persistent' => false,
        ],
    ],
];

路由配置

route/route.php中配置路由:

css 复制代码
use think\facade\Route;

Route::post('like/like/', 'Like/like');
Route::get('like/getLikeCount/', 'Like/getLikeCount');
Route::get('like/getUserLikes/:userId', 'Like/getUserLikes');

前端页面设计

  1. 页面结构

    • 展示内容的标题和点赞数。
    • 提供一个点赞按钮,点击后可以点赞或取消点赞。
    • 展示用户的点赞记录。
  2. 样式设计

    • 使用CSS来美化页面,使按钮和内容看起来更吸引人。
    • 使用动画效果来增强用户体验。
  3. 交互设计

    • 使用JavaScript的fetch API来与后端接口进行交互。
    • 动态更新点赞数和点赞按钮的状态。

代码实现

HTML

xml 复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>点赞功能示例</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f9;
            color: #333;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
        }

        .container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
            text-align: center;
        }

        h1 {
            margin-bottom: 20px;
        }

        #likeButton {
            background-color: #007bff;
            color: white;
            border: none;
            padding: 10px 20px;
            border-radius: 5px;
            cursor: pointer;
            font-size: 16px;
            transition: background-color 0.3s ease;
        }

        #likeButton:hover {
            background-color: #0056b3;
        }
        
        ul {
            list-style-type: none;
            padding: 0;
        }

        ul li {
            background: #f8f9fa;
            margin: 5px 0;
            padding: 10px;
            border-radius: 5px;
        }
    </style>
</head>
<body>
<div class="container">
    <h1>内容标题</h1>
    <p>点赞数: <span id="likeCount">0</span></p>
    <button id="likeButton">点赞</button>
    <h2>我的点赞记录</h2>
    <ul id="userLikes"></ul>
</div>
<script>
    document.addEventListener('DOMContentLoaded', function () {
        const contentId = 1; // 假设内容ID为1
        const userId = 1; // 假设用户ID为1
        const likeButton = document.getElementById('likeButton');
        const likeCount = document.getElementById('likeCount');
        const userLikes = document.getElementById('userLikes');

        // 获取点赞数
        function fetchLikeCount() {
            const params = new URLSearchParams({
                contentId:contentId
            })
            fetch(`api/like/getLikeCount?${params.toString()}`)
                .then(response => response.json())
                .then(data => {
                    likeCount.textContent = data.data.count;
                    likeButton.textContent = data.data.count > 0 ? '取消点赞' : '点赞';
                });
        }

        // 获取用户点赞记录
        function fetchUserLikes() {
            const params = new URLSearchParams({
                userId:userId
            })
            fetch(`api/like/getUserLikes?${params.toString()}`)
                .then(response => response.json())
                .then(data => {
                    userLikes.innerHTML = data.data.likes.map(like => `<li>内容ID: ${like}</li>`).join('');
                });
        }

        // 点赞或取消点赞
        likeButton.addEventListener('click', function () {
            const headers = new Headers()
            headers.append('content-type', 'application/json')
            fetch(`api/like/like`, { method: 'POST',headers,body: JSON.stringify({ contentId: contentId, userId: userId }) })
                .then(response => response.json())
                .then(data => {
                    if (data.code === 200) {
                        fetchLikeCount();
                        fetchUserLikes();
                    }
                });
        });

        // 初始化页面
        fetchLikeCount();
        fetchUserLikes();
    });
</script>
</body>
</html>

总结

通过上述设计思路和代码实现,你可以在ThinkPHP 6.1中结合Redis实现一个高效的点赞功能。Redis的高性能和原子操作确保了点赞功能的并发处理能力和数据一致性。

相关推荐
别惹CC5 小时前
【分布式锁通关指南 08】源码剖析redisson可重入锁之释放及阻塞与非阻塞获取
redis·分布式·后端
无名之逆6 小时前
Hyperlane:Rust 生态中的轻量级高性能 HTTP 服务器库,助力现代 Web 开发
服务器·开发语言·前端·后端·http·面试·rust
江沉晚呤时6 小时前
使用 .NET Core 实现 RabbitMQ 消息队列的详细教程
开发语言·后端·c#·.netcore
jay丿6 小时前
使用 Django 的 `FileResponse` 实现文件下载与在线预览
后端·python·django
Cloud_.6 小时前
Spring Boot 集成高德地图电子围栏
java·spring boot·后端
程序员小刚6 小时前
基于SpringBoot + Vue 的心理健康系统
vue.js·spring boot·后端
尚学教辅学习资料6 小时前
基于SpringBoot+Vue的幼儿园管理系统+LW示例参考
vue.js·spring boot·后端·幼儿园管理系统
Moment6 小时前
💯 铜三铁四,我收集整理了这些大厂面试场景题 (一)
前端·后端·面试
无名之逆7 小时前
轻量级、高性能的 Rust HTTP 服务器库 —— Hyperlane
服务器·开发语言·前端·后端·http·rust
无名之逆7 小时前
探索Hyperlane:用Rust打造轻量级、高性能的Web后端框架
服务器·开发语言·前端·后端·算法·rust