• SpringBoot+Vue+Element-UI实现协同过滤算法商品推荐系统


    文末获取源码

    开发语言:Java

    框架:springboot

    JDK版本:JDK1.8

    服务器:tomcat7

    数据库:mysql 5.7/8.0

    数据库工具:Navicat11

    开发软件:eclipse/myeclipse/idea

    Maven包:Maven3.3.9

    浏览器:谷歌浏览器

    前言介绍 

    本次设计任务是要设计一个基于协同过滤算法的商品推荐系统,通过这个系统能够满足商品推荐系统的管理功能。系统的主要包括首页,个人中心,用户管理,商品类型管理,商品信息管理,系统管理,订单管理等功能。

    管理员可以根据系统给定的账号进行登录,登录后可以进入商品推荐系统对个性化智能商品推荐所有模块进行管理。包括查看和修改自己的个人信息以及登录密码。

    该系统为每一个用户都分配了一个用户账号,用户通过账号的登录可以在系统中查看个性化智能商品推荐信息及对个人信息进行修改等功能。

    性能需求分析

    对系统的性能,从(功能、运行、界面、安全)等方面进行,下面我们逐一进行分析;

    1. 系统的功能是否完整进行分析:系统的功能,能对应设计出原始代码和算法,以表格同文字的形式进行详细介绍个人信息保证功能完整。

    2. 系统的运行是否通畅进行分析:系统的每个功能都有编写数据的关系和应对的代码,通过需求分析和可行性分析进行分析和显示系统的物理数据,保证其进行通畅。

    3. 系统的界面设计进行分析:对系统中的软件进行处理与分析的方式是由不同代码来进行的;从而使界面容易操作。

    4. 系统的安全性进行分析:这样才可以每个角色的不同对应的信息也就不同,在登录系统务必使用自己的账号,密码登录,账号与密码错误自然就登录失败了。登录成功可以对自己的信息进行操作,不能对别人的账号的信息进行查看等操作,这样自然保证系统的安全性。

    协同过滤算法简介

    协同过滤算法是一种较为著名和常用的推荐算法,它基于对用户历史行为数据的挖掘发现用户的喜好偏向,并预测用户可能喜好的产品进行推荐。也就是常见的“猜你喜欢”,和“购买了该商品的人也喜欢”等功能。它的主要实现由:

    (1)根据和你有共同喜好的人给你推荐

    (2)根据你喜欢的物品给你推荐相似物品

    (3)根据以上条件综合推荐

    (4)因此可以得出常用的协同过滤算法分为两种,基于用户的协同过滤算法(user-based collaboratIve filtering),以及基于物品的协同过滤算法(item-based collaborative filtering)。特点可以概括为“人以类聚,物以群分”,并据此进行预测和推荐。

    系统展示 

    前台页面

    商品信息推荐

    商品推荐是使用协同算法根据用户购买商品进行推荐

    商品信息

    商品资讯

    购物车

    管理员页面

    用户管理

    商品类型管理

    商品信息管理

    部分核心代码

    商品类型

    1. /**
    2. * 商品类型
    3. * 后端接口
    4. * @author
    5. * @email
    6. * @date 2022-04-17 14:24:14
    7. */
    8. @RestController
    9. @RequestMapping("/shangpinleixing")
    10. public class ShangpinleixingController {
    11. @Autowired
    12. private ShangpinleixingService shangpinleixingService;
    13. /**
    14. * 后端列表
    15. */
    16. @RequestMapping("/page")
    17. public R page(@RequestParam Map<String, Object> params,ShangpinleixingEntity shangpinleixing,
    18. HttpServletRequest request){
    19. EntityWrapper<ShangpinleixingEntity> ew = new EntityWrapper<ShangpinleixingEntity>();
    20. PageUtils page = shangpinleixingService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinleixing), params), params));
    21. return R.ok().put("data", page);
    22. }
    23. /**
    24. * 前端列表
    25. */
    26. @IgnoreAuth
    27. @RequestMapping("/list")
    28. public R list(@RequestParam Map<String, Object> params,ShangpinleixingEntity shangpinleixing,
    29. HttpServletRequest request){
    30. EntityWrapper<ShangpinleixingEntity> ew = new EntityWrapper<ShangpinleixingEntity>();
    31. PageUtils page = shangpinleixingService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinleixing), params), params));
    32. return R.ok().put("data", page);
    33. }
    34. /**
    35. * 列表
    36. */
    37. @RequestMapping("/lists")
    38. public R list( ShangpinleixingEntity shangpinleixing){
    39. EntityWrapper<ShangpinleixingEntity> ew = new EntityWrapper<ShangpinleixingEntity>();
    40. ew.allEq(MPUtil.allEQMapPre( shangpinleixing, "shangpinleixing"));
    41. return R.ok().put("data", shangpinleixingService.selectListView(ew));
    42. }
    43. /**
    44. * 查询
    45. */
    46. @RequestMapping("/query")
    47. public R query(ShangpinleixingEntity shangpinleixing){
    48. EntityWrapper< ShangpinleixingEntity> ew = new EntityWrapper< ShangpinleixingEntity>();
    49. ew.allEq(MPUtil.allEQMapPre( shangpinleixing, "shangpinleixing"));
    50. ShangpinleixingView shangpinleixingView = shangpinleixingService.selectView(ew);
    51. return R.ok("查询商品类型成功").put("data", shangpinleixingView);
    52. }
    53. /**
    54. * 后端详情
    55. */
    56. @RequestMapping("/info/{id}")
    57. public R info(@PathVariable("id") Long id){
    58. ShangpinleixingEntity shangpinleixing = shangpinleixingService.selectById(id);
    59. return R.ok().put("data", shangpinleixing);
    60. }
    61. /**
    62. * 前端详情
    63. */
    64. @IgnoreAuth
    65. @RequestMapping("/detail/{id}")
    66. public R detail(@PathVariable("id") Long id){
    67. ShangpinleixingEntity shangpinleixing = shangpinleixingService.selectById(id);
    68. return R.ok().put("data", shangpinleixing);
    69. }
    70. /**
    71. * 后端保存
    72. */
    73. @RequestMapping("/save")
    74. public R save(@RequestBody ShangpinleixingEntity shangpinleixing, HttpServletRequest request){
    75. shangpinleixing.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    76. //ValidatorUtils.validateEntity(shangpinleixing);
    77. shangpinleixingService.insert(shangpinleixing);
    78. return R.ok();
    79. }
    80. /**
    81. * 前端保存
    82. */
    83. @RequestMapping("/add")
    84. public R add(@RequestBody ShangpinleixingEntity shangpinleixing, HttpServletRequest request){
    85. shangpinleixing.setId(new Date().getTime()+new Double(Math.floor(Math.random()*1000)).longValue());
    86. //ValidatorUtils.validateEntity(shangpinleixing);
    87. shangpinleixingService.insert(shangpinleixing);
    88. return R.ok();
    89. }
    90. /**
    91. * 修改
    92. */
    93. @RequestMapping("/update")
    94. public R update(@RequestBody ShangpinleixingEntity shangpinleixing, HttpServletRequest request){
    95. //ValidatorUtils.validateEntity(shangpinleixing);
    96. shangpinleixingService.updateById(shangpinleixing);//全部更新
    97. return R.ok();
    98. }
    99. /**
    100. * 删除
    101. */
    102. @RequestMapping("/delete")
    103. public R delete(@RequestBody Long[] ids){
    104. shangpinleixingService.deleteBatchIds(Arrays.asList(ids));
    105. return R.ok();
    106. }
    107. /**
    108. * 提醒接口
    109. */
    110. @RequestMapping("/remind/{columnName}/{type}")
    111. public R remindCount(@PathVariable("columnName") String columnName, HttpServletRequest request,
    112. @PathVariable("type") String type,@RequestParam Map<String, Object> map) {
    113. map.put("column", columnName);
    114. map.put("type", type);
    115. if(type.equals("2")) {
    116. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    117. Calendar c = Calendar.getInstance();
    118. Date remindStartDate = null;
    119. Date remindEndDate = null;
    120. if(map.get("remindstart")!=null) {
    121. Integer remindStart = Integer.parseInt(map.get("remindstart").toString());
    122. c.setTime(new Date());
    123. c.add(Calendar.DAY_OF_MONTH,remindStart);
    124. remindStartDate = c.getTime();
    125. map.put("remindstart", sdf.format(remindStartDate));
    126. }
    127. if(map.get("remindend")!=null) {
    128. Integer remindEnd = Integer.parseInt(map.get("remindend").toString());
    129. c.setTime(new Date());
    130. c.add(Calendar.DAY_OF_MONTH,remindEnd);
    131. remindEndDate = c.getTime();
    132. map.put("remindend", sdf.format(remindEndDate));
    133. }
    134. }
    135. Wrapper<ShangpinleixingEntity> wrapper = new EntityWrapper<ShangpinleixingEntity>();
    136. if(map.get("remindstart")!=null) {
    137. wrapper.ge(columnName, map.get("remindstart"));
    138. }
    139. if(map.get("remindend")!=null) {
    140. wrapper.le(columnName, map.get("remindend"));
    141. }
    142. int count = shangpinleixingService.selectCount(wrapper);
    143. return R.ok().put("count", count);
    144. }
    145. }

    协同算法

    1. * 协同算法(按用户购买推荐)
    2. */
    3. @RequestMapping("/autoSort2")
    4. public R autoSort2(@RequestParam Map<String, Object> params,ShangpinxinxiEntity shangpinxinxi, HttpServletRequest request){
    5. String userId = request.getSession().getAttribute("userId").toString();
    6. String goodtypeColumn = "shangpinleixing";
    7. List<OrdersEntity> orders = ordersService.selectList(new EntityWrapper<OrdersEntity>().eq("userid", userId).eq("tablename", "shangpinxinxi").orderBy("addtime", false));
    8. List<String> goodtypes = new ArrayList<String>();
    9. Integer limit = params.get("limit")==null?10:Integer.parseInt(params.get("limit").toString());
    10. List<ShangpinxinxiEntity> shangpinxinxiList = new ArrayList<ShangpinxinxiEntity>();
    11. //去重
    12. List<OrdersEntity> ordersDist = new ArrayList<OrdersEntity>();
    13. for(OrdersEntity o1 : orders) {
    14. boolean addFlag = true;
    15. for(OrdersEntity o2 : ordersDist) {
    16. if(o1.getGoodid()==o2.getGoodid() || o1.getGoodtype().equals(o2.getGoodtype())) {
    17. addFlag = false;
    18. break;
    19. }
    20. }
    21. if(addFlag) ordersDist.add(o1);
    22. }
    23. if(ordersDist!=null && ordersDist.size()>0) {
    24. for(OrdersEntity o : ordersDist) {
    25. shangpinxinxiList.addAll(shangpinxinxiService.selectList(new EntityWrapper<ShangpinxinxiEntity>().eq(goodtypeColumn, o.getGoodtype())));
    26. }
    27. }
    28. EntityWrapper<ShangpinxinxiEntity> ew = new EntityWrapper<ShangpinxinxiEntity>();
    29. params.put("sort", "id");
    30. params.put("order", "desc");
    31. PageUtils page = shangpinxinxiService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.likeOrEq(ew, shangpinxinxi), params), params));
    32. List<ShangpinxinxiEntity> pageList = (List<ShangpinxinxiEntity>)page.getList();
    33. if(shangpinxinxiList.size()<limit) {
    34. int toAddNum = (limit-shangpinxinxiList.size())<=pageList.size()?(limit-shangpinxinxiList.size()):pageList.size();
    35. for(ShangpinxinxiEntity o1 : pageList) {
    36. boolean addFlag = true;
    37. for(ShangpinxinxiEntity o2 : shangpinxinxiList) {
    38. if(o1.getId().intValue()==o2.getId().intValue()) {
    39. addFlag = false;
    40. break;
    41. }
    42. }
    43. if(addFlag) {
    44. shangpinxinxiList.add(o1);
    45. if(--toAddNum==0) break;
    46. }
    47. }
    48. } else if(shangpinxinxiList.size()>limit) {
    49. shangpinxinxiList = shangpinxinxiList.subList(0, limit);
    50. }
    51. page.setList(shangpinxinxiList);
    52. return R.ok().put("data", page);
    53. }
    54. }

    登录

    1. /**
    2. * 登录相关
    3. */
    4. @RequestMapping("users")
    5. @RestController
    6. public class UserController{
    7. @Autowired
    8. private UserService userService;
    9. @Autowired
    10. private TokenService tokenService;
    11. /**
    12. * 登录
    13. */
    14. @IgnoreAuth
    15. @PostMapping(value = "/login")
    16. public R login(String username, String password, String captcha, HttpServletRequest request) {
    17. UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username));
    18. if(user==null || !user.getPassword().equals(password)) {
    19. return R.error("账号或密码不正确");
    20. }
    21. String token = tokenService.generateToken(user.getId(),username, "users", user.getRole());
    22. return R.ok().put("token", token);
    23. }
    24. /**
    25. * 注册
    26. */
    27. @IgnoreAuth
    28. @PostMapping(value = "/register")
    29. public R register(@RequestBody UserEntity user){
    30. // ValidatorUtils.validateEntity(user);
    31. if(userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername())) !=null) {
    32. return R.error("用户已存在");
    33. }
    34. userService.insert(user);
    35. return R.ok();
    36. }
    37. /**
    38. * 退出
    39. */
    40. @GetMapping(value = "logout")
    41. public R logout(HttpServletRequest request) {
    42. request.getSession().invalidate();
    43. return R.ok("退出成功");
    44. }
    45. /**
    46. * 密码重置
    47. */
    48. @IgnoreAuth
    49. @RequestMapping(value = "/resetPass")
    50. public R resetPass(String username, HttpServletRequest request){
    51. UserEntity user = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", username));
    52. if(user==null) {
    53. return R.error("账号不存在");
    54. }
    55. user.setPassword("123456");
    56. userService.update(user,null);
    57. return R.ok("密码已重置为:123456");
    58. }
    59. /**
    60. * 列表
    61. */
    62. @RequestMapping("/page")
    63. public R page(@RequestParam Map<String, Object> params,UserEntity user){
    64. EntityWrapper<UserEntity> ew = new EntityWrapper<UserEntity>();
    65. PageUtils page = userService.queryPage(params, MPUtil.sort(MPUtil.between(MPUtil.allLike(ew, user), params), params));
    66. return R.ok().put("data", page);
    67. }
    68. /**
    69. * 列表
    70. */
    71. @RequestMapping("/list")
    72. public R list( UserEntity user){
    73. EntityWrapper<UserEntity> ew = new EntityWrapper<UserEntity>();
    74. ew.allEq(MPUtil.allEQMapPre( user, "user"));
    75. return R.ok().put("data", userService.selectListView(ew));
    76. }
    77. /**
    78. * 信息
    79. */
    80. @RequestMapping("/info/{id}")
    81. public R info(@PathVariable("id") String id){
    82. UserEntity user = userService.selectById(id);
    83. return R.ok().put("data", user);
    84. }
    85. /**
    86. * 获取用户的session用户信息
    87. */
    88. @RequestMapping("/session")
    89. public R getCurrUser(HttpServletRequest request){
    90. Long id = (Long)request.getSession().getAttribute("userId");
    91. UserEntity user = userService.selectById(id);
    92. return R.ok().put("data", user);
    93. }
    94. /**
    95. * 保存
    96. */
    97. @PostMapping("/save")
    98. public R save(@RequestBody UserEntity user){
    99. // ValidatorUtils.validateEntity(user);
    100. if(userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername())) !=null) {
    101. return R.error("用户已存在");
    102. }
    103. userService.insert(user);
    104. return R.ok();
    105. }
    106. /**
    107. * 修改
    108. */
    109. @RequestMapping("/update")
    110. public R update(@RequestBody UserEntity user){
    111. // ValidatorUtils.validateEntity(user);
    112. UserEntity u = userService.selectOne(new EntityWrapper<UserEntity>().eq("username", user.getUsername()));
    113. if(u!=null && u.getId()!=user.getId() && u.getUsername().equals(user.getUsername())) {
    114. return R.error("用户名已存在。");
    115. }
    116. userService.updateById(user);//全部更新
    117. return R.ok();
    118. }
    119. /**
    120. * 删除
    121. */
    122. @RequestMapping("/delete")
    123. public R delete(@RequestBody Long[] ids){
    124. userService.deleteBatchIds(Arrays.asList(ids));
    125. return R.ok();
    126. }
    127. }

    上传文件

    1. * 上传文件
    2. */
    3. @RequestMapping("/upload")
    4. public R upload(@RequestParam("file") MultipartFile file,String type) throws Exception {
    5. if (file.isEmpty()) {
    6. throw new EIException("上传文件不能为空");
    7. }
    8. String fileExt = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1);
    9. File path = new File(ResourceUtils.getURL("classpath:static").getPath());
    10. if(!path.exists()) {
    11. path = new File("");
    12. }
    13. File upload = new File(path.getAbsolutePath(),"/upload/");
    14. if(!upload.exists()) {
    15. upload.mkdirs();
    16. }
    17. String fileName = new Date().getTime()+"."+fileExt;
    18. File dest = new File(upload.getAbsolutePath()+"/"+fileName);
    19. file.transferTo(dest);
    20. /**
    21. * 如果使用idea或者eclipse重启项目,发现之前上传的图片或者文件丢失,将下面一行代码注释打开
    22. * 请将以下的"D:\\springbootq33sd\\src\\main\\resources\\static\\upload"替换成你本地项目的upload路径,
    23. * 并且项目路径不能存在中文、空格等特殊字符
    24. */
    25. // FileUtils.copyFile(dest, new File("D:\\springbootq33sd\\src\\main\\resources\\static\\upload"+"/"+fileName)); /**修改了路径以后请将该行最前面的//注释去掉**/
    26. if(StringUtils.isNotBlank(type) && type.equals("1")) {
    27. ConfigEntity configEntity = configService.selectOne(new EntityWrapper<ConfigEntity>().eq("name", "faceFile"));
    28. if(configEntity==null) {
    29. configEntity = new ConfigEntity();
    30. configEntity.setName("faceFile");
    31. configEntity.setValue(fileName);
    32. } else {
    33. configEntity.setValue(fileName);
    34. }
    35. configService.insertOrUpdate(configEntity);
    36. }
    37. return R.ok().put("file", fileName);
    38. }
    39. /**
    40. * 下载文件
    41. */
    42. @IgnoreAuth
    43. @RequestMapping("/download")
    44. public ResponseEntity<byte[]> download(@RequestParam String fileName) {
    45. try {
    46. File path = new File(ResourceUtils.getURL("classpath:static").getPath());
    47. if(!path.exists()) {
    48. path = new File("");
    49. }
    50. File upload = new File(path.getAbsolutePath(),"/upload/");
    51. if(!upload.exists()) {
    52. upload.mkdirs();
    53. }
    54. File file = new File(upload.getAbsolutePath()+"/"+fileName);
    55. if(file.exists()){
    56. /*if(!fileService.canRead(file, SessionManager.getSessionUser())){
    57. getResponse().sendError(403);
    58. }*/
    59. HttpHeaders headers = new HttpHeaders();
    60. headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    61. headers.setContentDispositionFormData("attachment", fileName);
    62. return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
    63. }
    64. } catch (IOException e) {
    65. e.printStackTrace();
    66. }
    67. return new ResponseEntity<byte[]>(HttpStatus.INTERNAL_SERVER_ERROR);
    68. }
    69. }

  • 相关阅读:
    位运算常用技巧以及练习
    spring5.0 源码解析(day05) initMessageSource();
    Abbkine 细胞侵袭分析试剂盒,简单方便,快速检测
    English note 2
    Qt是什么?
    【软考】4.2 关系代数
    报错IDEA Terminated with exit code 1
    07——golang标识符、关键字、命名规则
    【图像】焦距与景深的关系
    matlab符号函数
  • 原文地址:https://blog.csdn.net/m0_49113107/article/details/126546679