基于 SpringBoot + Vue 的前后端分离游戏资讯平台

游戏资讯平台

简介

基于 SpringBoot + Vue 的前后端分离游戏资讯平台,使用 Shiro 进行权限控制,使用 JWT 作为交互 token,使用 Aspectj 进行切面编程,使用 Spring Data Jpa 方便进行数据库操作,使用 Druid 作为数据库连接池,使用 MySQL 作为数据库;前端使用 element-ui 作为组件库,使用 bootstrap-vue 进行响应式编程,使用 vue-ueditor-wrap 来作为文本编辑器,使用 vuex 来存储状态信息,使用 axios 请求后端接口数据。

功能
  • 轮播图管理
  • 游戏管理
  • 文章资讯管理
  • 用户评论管理
  • 游戏类型管理
  • 资讯类型管理
  • 用户管理
  • 游戏推荐
代码

进行推荐

package com.tidalcoast.application.util;

import com.tidalcoast.application.entity.GameInfo;
import com.tidalcoast.application.entity.NewsInfo;
import com.tidalcoast.application.entity.User;
import com.tidalcoast.application.service.ipml.GameInfoServiceImpl;
import com.tidalcoast.application.service.ipml.NewsInfoServiceImpl;
import com.tidalcoast.application.service.ipml.UserServiceImpl;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Author: tidalcoast
 * @Date: 2022/4/22 13:31
 * @Description 计算相似度
 */
@Component
public class UserCFUtil {

    class MapSortedMap implements Comparator<Map.Entry<Long, Double>> {
        //从大到小降序
        @Override
        public int compare(Map.Entry<Long, Double> o1, Map.Entry<Long, Double> o2) {
            return o2.getValue().compareTo(o1.getValue());
        }
    }

    @Resource
    private UserServiceImpl userService;

    @Resource
    private GameInfoServiceImpl gameInfoService;

    @Resource
    private NewsInfoServiceImpl newsInfoService;

//    private static Scanner scanner = new Scanner(System.in);

    //建立用户稀疏矩阵,用于用户相似度计算
    private static int[][] sparseMatrix;

    //存储每一个用户对应的不同物品总数
    private static Map<Long, Integer> userItemLength = new HashMap<>();

    //建立物品到用户的倒排表
    private static Map<Long, Set<Long>> itemUserCollection = new HashMap<>();

    //辅助存储物品的集合
    private static Set<Long> items = new HashSet<>();

    //辅助储存每一个用户的用户ID映射
    private static Map<Long, Integer> userID = new HashMap<>();

    //辅助储存每一个ID对应的用户映射
    private static Map<Integer, Long> idUser = new HashMap<>();

    /**
     * 初始化方法
     *
     * @param num 稀疏矩阵的长和宽
     */
    private static void init(int num) {
        sparseMatrix = new int[num][num];
        userItemLength = new HashMap<>();
        itemUserCollection = new HashMap<>();
        items = new HashSet<>();
        userID = new HashMap<>();
        idUser = new HashMap<>();
    }

    public List<Long> calculateFriendLike(Long userId) {
        List<Long> resultList = new ArrayList<>();
        //获取好友列表
        List<User> friendList = userService.getFriendListByUserId(userId);
        User u = userService.findUserById(userId);
        if (u == null) {
            return resultList;
        }
        friendList.add(u);
        int N = friendList.size();
        init(N);
        if (N > 1) {
            for (int i = 0; i < N; i++) {
                //获取用户Id
                Long uid = friendList.get(i).getId();
                //根据用户id获取收藏的游戏
                List<GameInfo> likeGames = gameInfoService.getAllGameInfoLikeByUserId(uid);
                Long[] user_item = new Long[likeGames.size() + 1];
                user_item[0] = uid;
                for (int x = 0; x < likeGames.size(); x++) {
                    user_item[x + 1] = likeGames.get(x).getId();
                }
                int length = user_item.length;
                userItemLength.put(user_item[0], length - 1);
                //用户ID与稀疏矩阵建立对应关系
                userID.put(user_item[0], i);
                idUser.put(i, user_item[0]);
                //userId
                System.out.println(userID.toString());
                //idUser
                System.out.println(idUser.toString());
                //建立物品--用户倒排表
                for (int j = 1; j < length; j++) {
                    if (items.contains(user_item[j])) {
                        //如果已经包含物品--用户映射,直接添加对应的用户
                        itemUserCollection.get(user_item[j]).add(user_item[0]);
                    } else {
                        //否则创建对应物品--用户集合映射
                        items.add(user_item[j]);
                        //创建物品--用户的倒排关系
                        itemUserCollection.put(user_item[j], new HashSet<>());
                        itemUserCollection.get(user_item[j]).add(user_item[0]);
                    }
                }
            }
            System.out.println(itemUserCollection.toString());
            //计算相似度矩阵【稀疏】
            Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
            for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
                Set<Long> commonUsers = setEntry.getValue();
                for (Long user_u : commonUsers) {
                    for (Long user_v : commonUsers) {
                        if (user_u.equals(user_v)) {
                            continue;
                        }
                        //计算用户u与用户v都有正反馈的物品总数
                        sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
                    }
                }
            }
            System.out.println(userItemLength.toString());
//        System.out.println("输入想要查询相似度的用户");
            //计算用户之间的相似度【余弦相似性】
            int recommendUserId = userID.get(userId);
            //存储该用户好友相似度的Map
            Map<Long, Double> degreeMap = new HashMap<>();
            for (int j = 0; j < sparseMatrix.length; j++) {
                if (j != recommendUserId) {
                    double userLikeDegree = sparseMatrix[recommendUserId][j] /
                            Math.sqrt(userItemLength.get(idUser.get(recommendUserId)) * userItemLength.get(idUser.get(j)));
                    System.out.println(idUser.get(recommendUserId) + "--" + idUser.get(j) +
                            "相似度:" + userLikeDegree);
                    degreeMap.put(idUser.get(j), userLikeDegree);
                }
            }
            //对map中的数据根据相似度进行排序
            List<Map.Entry<Long, Double>> entryList = new ArrayList<>(degreeMap.entrySet());
            entryList.sort(new MapSortedMap());
            //只返回用户id
            for (Map.Entry<Long, Double> entry : entryList) {
                if (entry.getValue() > 0.5){
                    //只推荐相似度大于0.5的好友
                    resultList.add(entry.getKey());
                }
            }
        }
        return resultList;
    }

    public List<Long> calculateInfoLike(Long userId) {
        List<Long> resultList = new ArrayList<>();
        //获取好友列表
        List<User> friendList = userService.getFriendListByUserId(userId);
        User u = userService.findUserById(userId);
        if (u == null) {
            return resultList;
        }
        friendList.add(u);
        int N = friendList.size();
        init(N);
        if (N > 1) {
            for (int i = 0; i < N; i++) {
                //获取用户Id
                Long uid = friendList.get(i).getId();
                //根据用户id获取收藏的资讯
                List<NewsInfo> likeNewsInfos = newsInfoService.getNewsInfoLikedByUserId(uid);
                Long[] user_item = new Long[likeNewsInfos.size() + 1];
                user_item[0] = uid;
                for (int x = 0; x < likeNewsInfos.size(); x++) {
                    user_item[x + 1] = likeNewsInfos.get(x).getId();
                }
                int length = user_item.length;
                userItemLength.put(user_item[0], length - 1);
                //用户ID与稀疏矩阵建立对应关系
                userID.put(user_item[0], i);
                idUser.put(i, user_item[0]);
                //userId
                System.out.println(userID.toString());
                //idUser
                System.out.println(idUser.toString());
                //建立物品--用户倒排表
                for (int j = 1; j < length; j++) {
                    if (items.contains(user_item[j])) {
                        //如果已经包含物品--用户映射,直接添加对应的用户
                        itemUserCollection.get(user_item[j]).add(user_item[0]);
                    } else {
                        //否则创建对应物品--用户集合映射
                        items.add(user_item[j]);
                        //创建物品--用户的倒排关系
                        itemUserCollection.put(user_item[j], new HashSet<>());
                        itemUserCollection.get(user_item[j]).add(user_item[0]);
                    }
                }
            }
            System.out.println(itemUserCollection.toString());
            //计算相似度矩阵【稀疏】
            Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
            for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
                Set<Long> commonUsers = setEntry.getValue();
                for (Long user_u : commonUsers) {
                    for (Long user_v : commonUsers) {
                        if (user_u.equals(user_v)) {
                            continue;
                        }
                        //计算用户u与用户v都有正反馈的物品总数
                        sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
                    }
                }
            }
            System.out.println(userItemLength.toString());

            //计算指定用户recommendUser的物品推荐度
            //存储该用户物品相似度的Map
            Map<Long, Double> degreeMap = new HashMap<>();
            for (Long item : items) {
                //遍历每一件物品
                //得到喜爱当前物品的所有用户集合
                Set<Long> users = itemUserCollection.get(item);
                if (!users.contains(userId)) {
                    double itemRecommendDegree = 0.0;
                    for (Long user : users) {
                        //推荐度计算公式
                        itemRecommendDegree += sparseMatrix[userID.get(userId)][userID.get(user)] /
                                Math.sqrt(userItemLength.get(userId) * userItemLength.get(user));
                    }
                    System.out.println("物品" + item + "对" + userId + "的相似度为" + itemRecommendDegree);
                    degreeMap.put(item, itemRecommendDegree);
                }
            }
            //对map中的数据根据相似度进行排序
            List<Map.Entry<Long, Double>> entryList = new ArrayList<>(degreeMap.entrySet());
            entryList.sort(new MapSortedMap());
            //只返回id
            for (Map.Entry<Long, Double> entry : entryList) {
                resultList.add(entry.getKey());
            }
        }

        if (resultList.size() >= 5) {
            return resultList;
        }
        //如果推荐数不足五个,则用点击量最高的资讯进行补充
        List<NewsInfo> topNews = newsInfoService.getNewsInfoOrderByClickCountsTopTen();
        for (NewsInfo n : topNews) {
            if (resultList.size() >= 5) {
                break;
            }
            if (!resultList.contains(n.getId())) {
                resultList.add(n.getId());
            }
        }
        return resultList;
    }

    public List<Long> calculateGameLike(Long userId) {
        List<Long> resultList = new ArrayList<>();
        //获取好友列表
        List<User> friendList = userService.getFriendListByUserId(userId);
        User u = userService.findUserById(userId);
        if (u == null) {
            return resultList;
        }
        friendList.add(u);
        int N = friendList.size();
        init(N);
        if (N > 1) {
            for (int i = 0; i < N; i++) {
                //获取用户Id
                Long uid = friendList.get(i).getId();
                //根据用户id获取收藏的游戏
                List<GameInfo> likeGames = gameInfoService.getAllGameInfoLikeByUserId(uid);
                Long[] user_item = new Long[likeGames.size() + 1];
                user_item[0] = uid;
                for (int x = 0; x < likeGames.size(); x++) {
                    user_item[x + 1] = likeGames.get(x).getId();
                }
                int length = user_item.length;
                userItemLength.put(user_item[0], length - 1);
                //用户ID与稀疏矩阵建立对应关系
                userID.put(user_item[0], i);
                idUser.put(i, user_item[0]);
                //userId
                System.out.println(userID.toString());
                //idUser
                System.out.println(idUser.toString());
                //建立物品--用户倒排表
                for (int j = 1; j < length; j++) {
                    if (items.contains(user_item[j])) {
                        //如果已经包含物品--用户映射,直接添加对应的用户
                        itemUserCollection.get(user_item[j]).add(user_item[0]);
                    } else {
                        //否则创建对应物品--用户集合映射
                        items.add(user_item[j]);
                        //创建物品--用户的倒排关系
                        itemUserCollection.put(user_item[j], new HashSet<>());
                        itemUserCollection.get(user_item[j]).add(user_item[0]);
                    }
                }
            }
            System.out.println(itemUserCollection.toString());
            //计算相似度矩阵【稀疏】
            Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
            for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
                Set<Long> commonUsers = setEntry.getValue();
                for (Long user_u : commonUsers) {
                    for (Long user_v : commonUsers) {
                        if (user_u.equals(user_v)) {
                            continue;
                        }
                        //计算用户u与用户v都有正反馈的物品总数
                        sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
                    }
                }
            }
            System.out.println(userItemLength.toString());

            //计算指定用户recommendUser的物品推荐度
            //存储该用户物品相似度的Map
            Map<Long, Double> degreeMap = new HashMap<>();
            for (Long item : items) {
                //遍历每一件物品
                //得到喜爱当前物品的所有用户集合
                Set<Long> users = itemUserCollection.get(item);
                if (!users.contains(userId)) {
                    double itemRecommendDegree = 0.0;
                    for (Long user : users) {
                        //推荐度计算公式
                        itemRecommendDegree += sparseMatrix[userID.get(userId)][userID.get(user)] /
                                Math.sqrt(userItemLength.get(userId) * userItemLength.get(user));
                    }
                    System.out.println("物品" + item + "对" + userId + "的相似度为" + itemRecommendDegree);
                    degreeMap.put(item, itemRecommendDegree);
                }
            }
            //对map中的数据根据相似度进行排序
            List<Map.Entry<Long, Double>> entryList = new ArrayList<>(degreeMap.entrySet());
            entryList.sort(new MapSortedMap());
            //只返回游戏id
            for (Map.Entry<Long, Double> entry : entryList) {
                resultList.add(entry.getKey());
            }
        }
        //当用户没有好友的时候,无法计算相似度进行推荐
        //如果用户有设定喜欢的游戏类型,则优先推荐喜欢类型的游戏
        if (u.getLikeGameTypeId() != null) {
            //获取所有该类型游戏
            List<GameInfo> likeTypeGames = gameInfoService.getGamesByTypeId(u.getLikeGameTypeId());
            for (GameInfo g : likeTypeGames) {
                if (!resultList.contains(g.getId())) {
                    resultList.add(g.getId());
                }
                if (resultList.size() >= 10) {
                    break;
                }
            }
        }

        if (resultList.size() >= 10) {
            return resultList;
        }
        //如果推荐数不足十个,则用评分最高的游戏进行补充
        List<GameInfo> topGames = gameInfoService.getAllGameInfoOrderByRateTopTen();
        for (GameInfo g : topGames) {
            if (resultList.size() >= 10) {
                break;
            }
            if (!resultList.contains(g.getId())) {
                resultList.add(g.getId());
            }
        }
        return resultList;
//        输出稀疏矩阵
//        for (int[] sparseMatrix1 : sparseMatrix) {
//            for (int i : sparseMatrix1) {
//                System.out.print(i + " # ");
//            }
//            System.out.println();
//        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.println("输入用户总数");
        int N = scanner.nextInt();
        //建立用户稀疏矩阵,用于用户相似度计算
        int[][] sparseMatrix = new int[N][N];
        //存储每一个用户对应的不同物品总数
        Map<Long, Integer> userItemLength = new HashMap<>();
        //建立物品到用户的倒排表
        Map<Long, Set<Long>> itemUserCollection = new HashMap<>();
        //辅助存储物品的集合
        Set<Long> items = new HashSet<>();
        //辅助储存每一个用户的用户ID映射
        Map<Long, Integer> userID = new HashMap<>();
        //辅助储存每一个ID对应的用户映射
        Map<Integer, Long> idUser = new HashMap<>();
        System.out.println("输入用户物品的映射集合 以空格间隔");
        scanner.nextLine();
        for (int i = 0; i < N; i++) {
            String[] scan_items = scanner.nextLine().split(" ");
            Long[] user_item = new Long[scan_items.length];
            for (int x = 0; x < scan_items.length; x++) {
                user_item[x] = Long.parseLong(scan_items[x]);
            }
            int length = user_item.length;
            userItemLength.put(user_item[0], length - 1);
            //用户ID与稀疏矩阵建立对应关系
            userID.put(user_item[0], i);
            idUser.put(i, user_item[0]);
            //建立物品--用户倒排表
            for (int j = 1; j < length; j++) {
                if (items.contains(user_item[j])) {
                    //如果已经包含物品--用户映射,直接添加对应的用户
                    itemUserCollection.get(user_item[j]).add(user_item[0]);
                } else {
                    //否则创建对应物品--用户集合映射
                    items.add(user_item[j]);
                    //创建物品--用户的倒排关系
                    itemUserCollection.put(user_item[j], new HashSet<>());
                    itemUserCollection.get(user_item[j]).add(user_item[0]);
                }
            }
        }
        System.out.println(itemUserCollection.toString());
        //计算相似度矩阵【稀疏】
        Set<Map.Entry<Long, Set<Long>>> entrySet = itemUserCollection.entrySet();
        for (Map.Entry<Long, Set<Long>> setEntry : entrySet) {
            Set<Long> commonUsers = setEntry.getValue();
            for (Long user_u : commonUsers) {
                for (Long user_v : commonUsers) {
                    if (user_u.equals(user_v)) {
                        continue;
                    }
                    //计算用户u与用户v都有正反馈的物品总数
                    sparseMatrix[userID.get(user_u)][userID.get(user_v)] += 1;
                }
            }
        }
        System.out.println(userItemLength.toString());
        System.out.println("输入想要查询相似度的用户");
        Long recommendUser = Long.parseLong(scanner.nextLine());
        System.out.println(userID.get(recommendUser));
        //计算用户之间的相似度【余弦相似性】
        int recommendUserId = userID.get(recommendUser);
        for (int j = 0; j < sparseMatrix.length; j++) {
            if (j != recommendUserId) {
                System.out.println(idUser.get(recommendUserId) + "--" + idUser.get(j) +
                        "相似度:" + sparseMatrix[recommendUserId][j] /
                        Math.sqrt(userItemLength.get(idUser.get(recommendUserId)) * userItemLength.get(idUser.get(j))));
            }
        }

        //计算指定用户recommendUser的物品推荐度
        for (Long item : items) {
            //遍历每一件物品
            //得到喜爱当前物品的所有用户集合
            Set<Long> users = itemUserCollection.get(item);
            if (!users.contains(recommendUser)) {
                double itemRecommendDegree = 0.0;
                for (Long user : users) {
                    //推荐度计算公式
                    itemRecommendDegree += sparseMatrix[userID.get(recommendUser)][userID.get(user)] /
                            Math.sqrt(userItemLength.get(recommendUser) * userItemLength.get(user));
                }
                System.out.println("物品" + item + "对" + recommendUser + "的相似度为" + itemRecommendDegree);
            }
        }
//        输出稀疏矩阵
        for (int[] sparseMatrix1 : sparseMatrix) {
            for (int i : sparseMatrix1) {
                System.out.print(i + " # ");
            }
            System.out.println();
        }
        //userId
        System.out.println(userID.toString());
        //idUser
        System.out.println(idUser.toString());
        scanner.close();
    }
}
示例

首页轮播

最新资讯

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第1张图片

推荐游戏

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第2张图片

热门游戏

最新游戏

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第3张图片

游戏

资讯

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第4张图片

文章
基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第5张图片

评论

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第6张图片

收藏

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第7张图片

后台管理

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第8张图片

用户信息

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第9张图片

登录

注册

基于 SpringBoot + Vue 的前后端分离游戏资讯平台_第10张图片

你可能感兴趣的:(项目,spring,boot,vue.js,游戏,毕业设计)