You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
6.5 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.example.service;
import cn.hutool.core.util.ObjectUtil;
import com.example.common.enums.RoleEnum;
import com.example.entity.*;
import com.example.mapper.*;
import com.example.utils.TokenUtils;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.stream.Collectors;
// 功能:商品信息业务处理
@Service
public class GoodsService {
@Resource
private GoodsMapper goodsMapper;
@Resource
private CollectMapper collectMapper;
@Resource
private CartMapper cartMapper;
@Resource
private OrdersMapper ordersMapper;
@Resource
private CommentMapper commentMapper;
@Resource
private UserMapper userMapper;
// 新增商品
public void add(Goods goods) {
// 商家添加商品时自动设置商家ID
Account currentUser = TokenUtils.getCurrentUser();
if (RoleEnum.BUSINESS.name().equals(currentUser.getRole())) {
goods.setBusinessId(currentUser.getId());
}
goodsMapper.insert(goods);
}
// 根据ID删除商品
public void deleteById(Integer id) {
goodsMapper.deleteById(id);
}
// 批量删除商品
public void deleteBatch(List<Integer> ids) {
for (Integer id : ids) {
goodsMapper.deleteById(id);
}
}
// 修改商品信息
public void updateById(Goods goods) {
goodsMapper.updateById(goods);
}
// 根据ID查询商品
public Goods selectById(Integer id) {
return goodsMapper.selectById(id);
}
// 查询销量前15的商品
public List<Goods> selectTop15() {
return goodsMapper.selectTop15();
}
// 通过分类查询商品
public List<Goods> selectByTypeId(Integer id) {
return goodsMapper.selectByTypeId(id);
}
// 根据商家ID查询该商家的所有商品
public List<Goods> selectByBusinessId(Integer id) {
return goodsMapper.selectByBusinessId(id);
}
// 查询所有商品
public List<Goods> selectAll(Goods goods) {
return goodsMapper.selectAll(goods);
}
// 分页查询商品
public PageInfo<Goods> selectPage(Goods goods, Integer pageNum, Integer pageSize) {
// 权限控制:商家只能看到自己店铺的商品
Account currentUser = TokenUtils.getCurrentUser();
if (RoleEnum.BUSINESS.name().equals(currentUser.getRole())) {
goods.setBusinessId(currentUser.getId());
}
PageHelper.startPage(pageNum, pageSize);
List<Goods> list = goodsMapper.selectAll(goods);
return PageInfo.of(list);
}
// 用户首页搜索商品
public List<Goods> selectByName(String name) {
return goodsMapper.selectByName(name);
}
// 商品推荐算法
public List<Goods> recommend() {
Account currentUser = TokenUtils.getCurrentUser();
if (ObjectUtil.isEmpty(currentUser)) {
// 没有用户登录,返回空列表
return new ArrayList<>();
}
// 1. 收集所有用户行为数据
List<Collect> allCollects = collectMapper.selectAll(null); // 收藏数据
List<Cart> allCarts = cartMapper.selectAll(null); // 购物车数据
List<Orders> allOrders = ordersMapper.selectAllOKOrders(); // 已完成订单
List<Comment> allComments = commentMapper.selectAll(null); // 评论数据
List<User> allUsers = userMapper.selectAll(null); // 用户数据
List<Goods> allGoods = goodsMapper.selectAll(null); // 商品数据
// 2. 构建用户-商品关系矩阵
List<RelateDTO> data = new ArrayList<>();
for (Goods goods : allGoods) {
Integer goodsId = goods.getId();
for (User user : allUsers) {
Integer userId = user.getId();
int index = 1; // 基础权重
// 计算用户对商品的偏好程度(权重累加)
// 收藏 +1分
Optional<Collect> collectOptional = allCollects.stream()
.filter(x -> x.getGoodsId().equals(goodsId) && x.getUserId().equals(userId)).findFirst();
if (collectOptional.isPresent()) {
index += 1;
}
// 加入购物车 +2分
Optional<Cart> cartOptional = allCarts.stream()
.filter(x -> x.getGoodsId().equals(goodsId) && x.getUserId().equals(userId)).findFirst();
if (cartOptional.isPresent()) {
index += 2;
}
// 完成订单 +3分
Optional<Orders> ordersOptional = allOrders.stream()
.filter(x -> x.getGoodsId().equals(goodsId) && x.getUserId().equals(userId)).findFirst();
if (ordersOptional.isPresent()) {
index += 3;
}
// 发表评论 +2分
Optional<Comment> commentOptional = allComments.stream()
.filter(x -> x.getGoodsId().equals(goodsId) && x.getUserId().equals(userId)).findFirst();
if (commentOptional.isPresent()) {
index += 2;
}
// 如果用户与商品有交互,记录关系数据
if (index > 1) {
RelateDTO relateDTO = new RelateDTO(userId, goodsId, index);
data.add(relateDTO);
}
}
}
// 3. 使用协同过滤算法进行推荐
List<Integer> goodsIds = UserCF.recommend(currentUser.getId(), data);
// 4. 将商品ID转换为商品对象最多返回10个
List<Goods> recommendResult = goodsIds.stream()
.map(goodsId -> allGoods.stream()
.filter(x -> x.getId().equals(goodsId)).findFirst().orElse(null))
.limit(10).collect(Collectors.toList());
return recommendResult;
}
// 随机获取商品(备用推荐方案)
private List<Goods> getRandomGoods(int num) {
List<Goods> list = new ArrayList<>(num);
List<Goods> goods = goodsMapper.selectAll(null);
for (int i = 0; i < num; i++) {
int index = new Random().nextInt(goods.size());
list.add(goods.get(index));
}
return list;
}
}