用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的高性能和原子操作确保了点赞功能的并发处理能力和数据一致性。

相关推荐
IT_陈寒4 分钟前
Java 21虚拟线程实战:7个性能翻倍的异步重构案例与避坑指南
前端·人工智能·后端
不思念一个荒废的名字9 分钟前
【黑马JavaWeb+AI知识梳理】Web后端开发05-SpringAOP
后端
BingoGo17 分钟前
PHP True Async 最近进展以及背后的争议
后端·php
程序员码歌19 分钟前
短思考第264天,每天复盘5分钟,胜过你盲目努力1整年(2)
前端·后端·ai编程
Victor35623 分钟前
Hibernate(3)Hibernate的优点是什么?
后端
Victor35623 分钟前
Hibernate(4)什么是Hibernate的持久化类?
后端
JaguarJack26 分钟前
PHP True Async 最近进展以及背后的争议
后端·php
想不明白的过度思考者2 小时前
Spring Boot 配置文件深度解析
java·spring boot·后端
WanderInk8 小时前
刷新后点赞全变 0?别急着怪 Redis,这八成是 Long 被 JavaScript 偷偷“改号”了(一次线上复盘)
后端
吴佳浩9 小时前
Python入门指南(七) - YOLO检测API进阶实战
人工智能·后端·python