• 【开源】SpringBoot框架开发用户画像活动推荐系统


    在这里插入图片描述



    一、摘要

    1.1 项目介绍

    基于JAVA+Vue+SpringBoot+MySQL的用户画像活动推荐系统,使用了协同推荐算法,包含了标签管理、活动档案、活动收藏、活动报名、活动留言模块,还包含系统自带的用户管理、部门管理、角色管理、菜单管理、日志管理、数据字典管理、文件管理、图表展示等基础模块,用户画像活动推荐系统基于角色的访问控制,给活动管理员、普通用户使用,可将权限精确到按钮级别,您可以自定义角色并分配权限,系统适合设计精确的权限约束需求。

    1.2 项目录屏


    二、功能模块

    系统平台设计包括系统网络配置、数据库选择、软件平台选择和硬件平台选择。该推荐系统前端使用了Vue.JS,采用MVVM的思想双向绑定界面和数据;后端采用了Java的框架SpringBoot,使用MyBatis整合MySQL数据库。

    在这里插入图片描述

    基于用户画像的活动推荐系统的功能性需求主要包含数据中心模块、兴趣标签模块、活动档案模块、活动报名模块、活动留言模块这五大模块,系统是基于浏览器运行的web管理后端,其中各个模块详细说明如下。

    2.1 数据中心模块

    数据中心模块包含了基于用户画像的活动推荐系统的系统基础配置,如登录用户的管理、运营公司组织架构的管理、用户菜单权限的管理、系统日志的管理、公用文件云盘的管理。
    其中登录用户管理模块,由管理员负责运维工作,管理员可以对登录用户进行增加、删除、修改、查询操作。
    组织架构,指的是高校的组织架构,该模块适用于管理这些组织架构的部门层级和教师的部门归属情况。
    用户菜单权限管理模块,用于管理不同权限的用户,拥有哪些具体的菜单权限。
    系统日志的管理,用于维护用户登入系统的记录,方便定位追踪用户的操作情况。
    公用云盘管理模块,用于统一化维护基于用户画像的活动推荐系统中的图片,如合同签订文件、合同照片等等。

    2.2 兴趣标签模块

    兴趣标签是对用户进行活动推荐的标准,不同的用户可以有不同的兴趣标签,所以需要对兴趣标签进行维护,兴趣标签的数据包括标签名称、标签状态、排序值、备注、创建人、创建时间、更新人、更新时间,管理员可以新增、删除、编辑和条件查询兴趣标签数据,用户可以查询管理员发布的兴趣标签数据。

    2.3 活动档案模块

    活动是活动推荐系统的核心实体,需要建立活动档案模块对管理员发布的活动进行管理,活动的字段包括活动标题、活动介绍、活动地点、活动时间、创建人、创建时间、更新人、更新时间,管理员可以新增、删除、编辑和条件查询活动数据,用户可以查询管理员发布的活动数据。

    2.4 活动报名模块

    有了活动数据之后,用户就可以选择活动进行报名,进入页面后各种活动会呈现在用户面前,用户可以搜索活动,用户可以选择活动参加,活动报名的数据包括报名人、活动名称、报名日期、报名状态、创建人、创建时间、更新人、更新时间,管理员可以新增、删除、编辑和条件查询活动报名数据,用户可以申请活动报名,和查询我的历史活动报名信息。

    2.5 活动留言模块

    在使用基于用户画像的活动推荐系统中,用户可能会有一些问题需要咨询,所以建立了活动留言模块,活动留言数据包括留言人、留言内容、留言时间、状态、备注、回复人、回复内容、回复时间,用户可以发起活动留言,管理员可以对用户的留言进行回复和删除操作。


    三、系统设计

    3.1 用例设计

    在这里插入图片描述

    3.2 业务流程设计

    在这里插入图片描述

    3.3 数据流程设计

    在这里插入图片描述
    在这里插入图片描述

    3.4 E-R图设计

    在这里插入图片描述


    四、系统展示

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述


    五、核心代码

    5.1 查询兴趣标签

    @RequestMapping(value = "/getByPage", method = RequestMethod.GET)
    @ApiOperation(value = "查询兴趣标签")
    public Result<IPage<Label>> getByPage(@ModelAttribute Label label ,@ModelAttribute PageVo page){
        QueryWrapper<Label> qw = new QueryWrapper<>();
        if(!ZwzNullUtils.isNull(label.getTitle())) {
            qw.like("title",label.getTitle());
        }
        if(!ZwzNullUtils.isNull(label.getContent())) {
            qw.like("content",label.getContent());
        }
        IPage<Label> data = iLabelService.page(PageUtil.initMpPage(page),qw);
        return new ResultUtil<IPage<Label>>().setData(data);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5.2 查询活动推荐

    @RequestMapping(value = "/getByPage", method = RequestMethod.GET)
    @ApiOperation(value = "查询活动")
    public Result<IPage<Activity>> getByPage(@ModelAttribute Activity activity ,@ModelAttribute PageVo page){
        /**
            * 接受前端传来的参数,开始模拟搜索
            */
        QueryWrapper<Activity> qw = new QueryWrapper<>();
        /**
            * 获取当前登录的用户对象
            */
        User currUser = securityUtil.getCurrUser();
        if(ZwzNullUtils.isNull(currUser.getLabel())) {
            currUser.setLabel("");
        }
        /**
            * 分析用户的兴趣标签
            */
        String[] labelList = currUser.getLabel().split(",");
        if(!ZwzNullUtils.isNull(activity.getTitle())) {
            qw.like("title",activity.getTitle());
        }
        if(!ZwzNullUtils.isNull(activity.getContent())) {
            qw.like("content",activity.getContent());
        }
        if(!ZwzNullUtils.isNull(activity.getStatus())) {
            qw.eq("status",activity.getStatus());
        }
        /**
            * 查询系统全部的活动留言数据
            */
        List<Message> messageList = iMessageService.list();
        /**
            * 查询系统全部的活动预定数据
            */
        List<ActivityOrder> orderList = iActivityOrderService.list();
        IPage<Activity> data = iActivityService.page(PageUtil.initMpPage(page),qw);
        for (Activity vo : data.getRecords()) {
            /**
                * 判断登录用户是否预定了这个活动
                */
            QueryWrapper<ActivityOrder> orderQw = new QueryWrapper<>();
            orderQw.eq("act_id",vo.getId());
            orderQw.eq("user_id",currUser.getId());
            vo.setOrderFlag(iActivityOrderService.count(orderQw));
            /**
                * 判断收藏
                */
            QueryWrapper<Collect> coQw = new QueryWrapper<>();
            coQw.eq("user_id",currUser.getId());
            coQw.eq("act_id",vo.getId());
            vo.setCoFlag(iCollectService.count(coQw));
            Long likeNumber = 0L;
            /**
                * 自己喜爱的活动,一个标签加十分
                */
            for (String s : labelList) {
                if(vo.getLabel().indexOf(s) > -1) {
                    likeNumber += 10L;
                }
            }
            /**
                * 他人预定,每次加三分
                */
            for (ActivityOrder activityOrder : orderList) {
                if(Objects.equals(activityOrder.getActId(),vo.getId())) {
                    likeNumber += 3L;
                }
            }
            /**
                * 被别人留言,每次加两分
                */
            for (Message message : messageList) {
                if(message.getContent().indexOf(vo.getTitle()) > -1) {
                    likeNumber += 2L;
                }
            }
            vo.setLikeLevel(likeNumber);
        }
        /**
            * 最后对即将返回的活动数据,针对加权分值降序排序
            */
        Collections.sort(data.getRecords(), new Comparator<Activity>() {
            @Override
            public int compare(Activity o1, Activity o2) {
                return o2.getLikeLevel().compareTo(o1.getLikeLevel());
            }
        });
        /**
            * 返回给前端
            */
        return new ResultUtil<IPage<Activity>>().setData(data);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    5.3 新增活动报名

    @RequestMapping(value = "/addOne", method = RequestMethod.GET)
    @ApiOperation(value = "新增单条活动报名")
    public Result<ActivityOrder> addOne(@RequestParam String id){
        Activity activity = iActivityService.getById(id);
        if(activity == null) {
            return ResultUtil.error("活动不存在");
        }
        User currUser = securityUtil.getCurrUser();
        QueryWrapper<ActivityOrder> qw = new QueryWrapper<>();
        qw.eq("act_id",id);
        qw.eq("user_id",currUser.getId());
        iActivityOrderService.remove(qw);
        ActivityOrder order = new ActivityOrder();
        order.setActId(activity.getId());
        order.setTitle(activity.getTitle());
        order.setContent(activity.getContent());
        order.setAddress(activity.getAddress());
        order.setTime(activity.getTime());
        order.setUserId(currUser.getId());
        order.setUserName(currUser.getNickname());
        iActivityOrderService.saveOrUpdate(order);
        return ResultUtil.success();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5.4 新增活动收藏

    @RequestMapping(value = "/addOne", method = RequestMethod.GET)
    @ApiOperation(value = "新增收藏")
    public Result<Object> addOne(@RequestParam String id){
        Activity a = iActivityService.getById(id);
        if(a == null) {
            return ResultUtil.error("活动不存在");
        }
        User currUser = securityUtil.getCurrUser();
        QueryWrapper<Collect> coQw = new QueryWrapper<>();
        coQw.eq("user_id",currUser.getId());
        coQw.eq("act_id",a.getId());
        long coCount = iCollectService.count(coQw);
        if(coCount < 1) {
            Collect c = new Collect();
            c.setUserId(currUser.getId());
            c.setUserName(currUser.getNickname());
            c.setActId(a.getId());
            c.setActTitle(a.getTitle());
            c.setTime(DateUtil.now());
            iCollectService.saveOrUpdate(c);
        }
        return ResultUtil.success();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    5.5 新增活动留言

    @RequestMapping(value = "/insert", method = RequestMethod.POST)
    @ApiOperation(value = "新增活动留言")
    public Result<Message> insert(Message message){
        Activity activity = iActivityService.getById(message.getActId());
        if(activity == null) {
            return ResultUtil.error("活动不存在");
        }
        message.setActTitle(activity.getTitle());
        User currUser = securityUtil.getCurrUser();
        message.setUserId(currUser.getId());
        message.setUserName(currUser.getNickname());
        message.setTime(DateUtil.now());
        message.setReplyContent("");
        message.setReplyName("");
        message.setReplyId("");
        message.setReplyTime("");
        iMessageService.saveOrUpdate(message);
        return new ResultUtil<Message>().setData(message);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    六、免责说明

    • 本项目仅供个人学习使用,商用授权请联系博主,否则后果自负。
    • 博主拥有本软件构建后的应用系统全部内容所有权及独立的知识产权,拥有最终解释权。
    • 如有问题,欢迎在仓库 Issue 留言,看到后会第一时间回复,相关意见会酌情考虑,但没有一定被采纳的承诺或保证。

    下载本系统代码或使用本系统的用户,必须同意以下内容,否则请勿下载!

    1. 出于自愿而使用/开发本软件,了解使用本软件的风险,且同意自己承担使用本软件的风险。
    2. 利用本软件构建的网站的任何信息内容以及导致的任何版权纠纷和法律争议及后果和博主无关,博主对此不承担任何责任。
    3. 在任何情况下,对于因使用或无法使用本软件而导致的任何难以合理预估的损失(包括但不仅限于商业利润损失、业务中断与业务信息丢失),博主概不承担任何责任。
    4. 必须了解使用本软件的风险,博主不承诺提供一对一的技术支持、使用担保,也不承担任何因本软件而产生的难以预料的问题的相关责任。

    在这里插入图片描述

  • 相关阅读:
    一点一点学习C++之笔记005
    洛谷P1406 方格填数 题解
    计算机毕业设计之java+ssm某地区精准扶贫网站
    爱玛电动车:不止有时尚设计,更有领先的引擎动力科技
    代码随想录算法训练营第55天|392. 判断子序列,115.不同的子序列
    计算器(c++基础)
    centos8安装jenkins,gitee+webHook配置
    Tomcat 的部署和优化
    【Canvas】js用Canvas绘制阴阳太极图动画效果
    机器学习--决策树(sklearn)
  • 原文地址:https://blog.csdn.net/askf01/article/details/136480017