商品:增加商品浏览记录

This commit is contained in:
owen 2023-12-17 17:20:08 +08:00
parent 86a9c4bbf4
commit f374e778bb
16 changed files with 550 additions and 3 deletions

View File

@ -0,0 +1,22 @@
CREATE TABLE product_browse_history
(
id bigint AUTO_INCREMENT COMMENT '记录编号'
PRIMARY KEY,
user_id bigint NOT NULL COMMENT '用户编号',
spu_id bigint NOT NULL COMMENT '商品 SPU 编号',
user_deleted bit DEFAULT b'0' NOT NULL COMMENT '用户是否删除',
creator varchar(64) DEFAULT '' NULL COMMENT '创建者',
create_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL COMMENT '创建时间',
updater varchar(64) DEFAULT '' NULL COMMENT '更新者',
update_time datetime DEFAULT CURRENT_TIMESTAMP NOT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
deleted bit DEFAULT b'0' NOT NULL COMMENT '是否删除',
tenant_id bigint DEFAULT 0 NOT NULL COMMENT '租户编号'
)
COMMENT '商品浏览记录表';
CREATE INDEX idx_spuId
ON product_browse_history (spu_id);
CREATE INDEX idx_userId
ON product_browse_history (user_id);

View File

@ -0,0 +1,39 @@
package cn.iocoder.yudao.module.product.controller.admin.history;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO;
import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO;
import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 商品浏览记录")
@RestController
@RequestMapping("/product/browse-history")
@Validated
public class ProductBrowseHistoryController {
@Resource
private ProductBrowseHistoryService browseHistoryService;
@GetMapping("/page")
@Operation(summary = "获得商品浏览记录分页")
@PreAuthorize("@ss.hasPermission('product:browse-history:query')")
public CommonResult<PageResult<ProductBrowseHistoryRespVO>> getBrowseHistoryPage(@Valid ProductBrowseHistoryPageReqVO pageReqVO) {
PageResult<ProductBrowseHistoryDO> pageResult = browseHistoryService.getBrowseHistoryPage(pageReqVO);
return success(BeanUtils.toBean(pageResult, ProductBrowseHistoryRespVO.class));
}
}

View File

@ -0,0 +1,33 @@
package cn.iocoder.yudao.module.product.controller.admin.history.vo;
import cn.iocoder.yudao.framework.common.pojo.SortablePageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "管理后台 - 商品浏览记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class ProductBrowseHistoryPageReqVO extends SortablePageParam {
@Schema(description = "用户编号", example = "4314")
private Long userId;
@Schema(description = "用户是否删除", example = "false")
private Boolean userDeleted;
@Schema(description = "商品 SPU 编号", example = "42")
private Long spuId;
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,34 @@
package cn.iocoder.yudao.module.product.controller.admin.history.vo;
import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(description = "管理后台 - 商品浏览记录 Response VO")
@Data
@ExcelIgnoreUnannotated
public class ProductBrowseHistoryRespVO {
@Schema(description = "记录编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "26055")
@ExcelProperty("记录编号")
private Long id;
@Schema(description = "用户编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "4314")
@ExcelProperty("用户编号")
private Long userId;
@Schema(description = "用户是否删除", example = "false")
private Boolean userDeleted;
@Schema(description = "商品 SPU 编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "42")
@ExcelProperty("商品 SPU 编号")
private Long spuId;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
@ExcelProperty("创建时间")
private LocalDateTime createTime;
}

View File

@ -0,0 +1,90 @@
package cn.iocoder.yudao.module.product.controller.app.history;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.security.core.annotations.PreAuthenticated;
import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.history.vo.AppProductBrowseHistoryDeleteReqVO;
import cn.iocoder.yudao.module.product.controller.app.history.vo.AppProductBrowseHistoryPageReqVO;
import cn.iocoder.yudao.module.product.controller.app.history.vo.AppProductBrowseHistoryRespVO;
import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
@Tag(name = "用户 APP - 商品浏览记录")
@RestController
@RequestMapping("/product/browse-history")
public class AppProductBrowseHistoryController {
@Resource
private ProductBrowseHistoryService productBrowseHistoryService;
@Resource
private ProductSpuService productSpuService;
@DeleteMapping(value = "/delete")
@Operation(summary = "删除商品浏览记录")
@PreAuthenticated
public CommonResult<Boolean> deleteBrowseHistory(@RequestBody @Valid AppProductBrowseHistoryDeleteReqVO reqVO) {
productBrowseHistoryService.hideUserBrowseHistory(getLoginUserId(), reqVO.getSpuIds());
return success(Boolean.TRUE);
}
@DeleteMapping(value = "/clean")
@Operation(summary = "清空商品浏览记录")
@PreAuthenticated
public CommonResult<Boolean> cleanBrowseHistory() {
productBrowseHistoryService.hideUserBrowseHistory(getLoginUserId(), null);
return success(Boolean.TRUE);
}
@GetMapping(value = "/get-count")
@Operation(summary = "获得商品浏览记录数量")
@PreAuthenticated
public CommonResult<Long> getBrowseHistoryCount() {
return success(productBrowseHistoryService.getBrowseHistoryCount(getLoginUserId(), false));
}
@GetMapping(value = "/page")
@Operation(summary = "获得商品浏览记录分页")
@PreAuthenticated
public CommonResult<PageResult<AppProductBrowseHistoryRespVO>> getBrowseHistoryPage(AppProductBrowseHistoryPageReqVO reqVO) {
ProductBrowseHistoryPageReqVO pageReqVO = BeanUtils.toBean(reqVO, ProductBrowseHistoryPageReqVO.class);
pageReqVO.setUserId(getLoginUserId());
// 排除用户已删除的隐藏的
pageReqVO.setUserDeleted(false);
PageResult<ProductBrowseHistoryDO> pageResult = productBrowseHistoryService.getBrowseHistoryPage(pageReqVO);
if (CollUtil.isEmpty(pageResult.getList())) {
return success(PageResult.empty());
}
// 得到商品 spu 信息
Set<Long> spuIds = convertSet(pageResult.getList(), ProductBrowseHistoryDO::getSpuId);
Map<Long, ProductSpuDO> spuMap = convertMap(productSpuService.getSpuList(spuIds), ProductSpuDO::getId);
// 转换 VO 结果
PageResult<AppProductBrowseHistoryRespVO> result = BeanUtils.toBean(pageResult, AppProductBrowseHistoryRespVO.class,
vo -> Optional.ofNullable(spuMap.get(vo.getSpuId())).ifPresent(spu -> {
vo.setSpuName(spu.getName());
vo.setPicUrl(spu.getPicUrl());
}));
return success(result);
}
}

View File

@ -0,0 +1,19 @@
package cn.iocoder.yudao.module.product.controller.app.history.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import lombok.Data;
import java.util.List;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 APP - 删除商品浏览记录的 Request VO")
@Data
public class AppProductBrowseHistoryDeleteReqVO {
@Schema(description = "商品 SPU 编号数组", requiredMode = REQUIRED, example = "29502")
@NotEmpty(message = "商品 SPU 编号数组不能为空")
private List<Long> spuIds;
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.product.controller.app.history.vo;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;
import org.springframework.format.annotation.DateTimeFormat;
import java.time.LocalDateTime;
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@Schema(description = "用户 APP - 商品浏览记录分页 Request VO")
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class AppProductBrowseHistoryPageReqVO extends PageParam {
@Schema(description = "创建时间")
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime;
}

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.product.controller.app.history.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;
@Schema(description = "用户 App - 商品浏览记录 Response VO")
@Data
public class AppProductBrowseHistoryRespVO {
@Schema(description = "编号", requiredMode = REQUIRED, example = "1")
private Long id;
@Schema(description = "商品 SPU 编号", requiredMode = REQUIRED, example = "29502")
private Long spuId;
// ========== 商品相关字段 ==========
@Schema(description = "商品 SPU 名称", example = "赵六")
private String spuName;
@Schema(description = "商品封面图", example = "https://domain/pic.png")
private String picUrl;
@Schema(description = "商品单价", example = "100")
private Integer price;
}

View File

@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.product.convert.spu.ProductSpuConvert;
import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO;
import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO; import cn.iocoder.yudao.module.product.dal.dataobject.spu.ProductSpuDO;
import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum; import cn.iocoder.yudao.module.product.enums.spu.ProductSpuStatusEnum;
import cn.iocoder.yudao.module.product.service.history.ProductBrowseHistoryService;
import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; import cn.iocoder.yudao.module.product.service.sku.ProductSkuService;
import cn.iocoder.yudao.module.product.service.spu.ProductSpuService; import cn.iocoder.yudao.module.product.service.spu.ProductSpuService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -48,6 +49,8 @@ public class AppProductSpuController {
private ProductSpuService productSpuService; private ProductSpuService productSpuService;
@Resource @Resource
private ProductSkuService productSkuService; private ProductSkuService productSkuService;
@Resource
private ProductBrowseHistoryService productBrowseHistoryService;
@Resource @Resource
private MemberLevelApi memberLevelApi; private MemberLevelApi memberLevelApi;
@ -122,6 +125,11 @@ public class AppProductSpuController {
throw exception(SPU_NOT_ENABLE); throw exception(SPU_NOT_ENABLE);
} }
// 增加浏览量
productSpuService.updateBrowseCount(id, 1);
// 保存浏览记录
productBrowseHistoryService.createBrowseHistory(getLoginUserId(), id);
// 拼接返回 // 拼接返回
List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId()); List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
AppProductSpuDetailRespVO detailVO = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus); AppProductSpuDetailRespVO detailVO = ProductSpuConvert.INSTANCE.convertForGetSpuDetail(spu, skus);

View File

@ -0,0 +1,42 @@
package cn.iocoder.yudao.module.product.dal.dataobject.history;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.KeySequence;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.*;
/**
* 商品浏览记录 DO
*
* @author owen
*/
@TableName("product_browse_history")
@KeySequence("product_browse_history_seq") // 用于 OraclePostgreSQLKingbaseDB2H2 数据库的主键自增如果是 MySQL 等数据库可不写
@Data
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ProductBrowseHistoryDO extends BaseDO {
/**
* 记录编号
*/
@TableId
private Long id;
/**
* 商品 SPU 编号
*/
private Long spuId;
/**
* 用户编号
*/
private Long userId;
/**
* 用户是否删除
*/
private Boolean userDeleted;
}

View File

@ -0,0 +1,52 @@
package cn.iocoder.yudao.module.product.dal.mysql.history;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.annotations.Mapper;
import java.util.Collection;
/**
* 商品浏览记录 Mapper
*
* @author owen
*/
@Mapper
public interface ProductBrowseHistoryMapper extends BaseMapperX<ProductBrowseHistoryDO> {
default PageResult<ProductBrowseHistoryDO> selectPage(ProductBrowseHistoryPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<ProductBrowseHistoryDO>()
.eqIfPresent(ProductBrowseHistoryDO::getUserId, reqVO.getUserId())
.eqIfPresent(ProductBrowseHistoryDO::getUserDeleted, reqVO.getUserDeleted())
.eqIfPresent(ProductBrowseHistoryDO::getSpuId, reqVO.getSpuId())
.betweenIfPresent(ProductBrowseHistoryDO::getCreateTime, reqVO.getCreateTime())
.orderByDesc(ProductBrowseHistoryDO::getId));
}
default void updateUserDeletedByUserId(Long userId, Collection<Long> spuIds, Boolean userDeleted) {
update(new LambdaUpdateWrapper<ProductBrowseHistoryDO>()
.eq(ProductBrowseHistoryDO::getUserId, userId)
.in(CollUtil.isNotEmpty(spuIds), ProductBrowseHistoryDO::getSpuId, spuIds)
.set(ProductBrowseHistoryDO::getUserDeleted, userDeleted));
}
default Long selectCountByUserIdAndUserDeleted(Long userId, Boolean userDeleted) {
return selectCount(new LambdaQueryWrapperX<ProductBrowseHistoryDO>()
.eq(ProductBrowseHistoryDO::getUserId, userId)
.eqIfPresent(ProductBrowseHistoryDO::getUserDeleted, userDeleted));
}
default Page<ProductBrowseHistoryDO> selectPageByUserIdOrderByCreateTimeAsc(Long userId) {
Page<ProductBrowseHistoryDO> page = Page.of(0, 1);
return selectPage(page, new LambdaQueryWrapperX<ProductBrowseHistoryDO>()
.eqIfPresent(ProductBrowseHistoryDO::getUserId, userId)
.orderByAsc(ProductBrowseHistoryDO::getCreateTime));
}
}

View File

@ -71,7 +71,7 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
query.eq(ProductSpuDO::getRecommendBenefit, true); query.eq(ProductSpuDO::getRecommendBenefit, true);
} else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_BEST)) { } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_BEST)) {
query.eq(ProductSpuDO::getRecommendBest, true); query.eq(ProductSpuDO::getRecommendBest, true);
} else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_NEW)) { } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_NEW)) {
query.eq(ProductSpuDO::getRecommendNew, true); query.eq(ProductSpuDO::getRecommendNew, true);
} else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) { } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
query.eq(ProductSpuDO::getRecommendGood, true); query.eq(ProductSpuDO::getRecommendGood, true);
@ -141,8 +141,8 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
/** /**
* 添加后台 Tab 选项的查询条件 * 添加后台 Tab 选项的查询条件
* *
* @param tabType 标签类型 * @param tabType 标签类型
* @param query 查询条件 * @param query 查询条件
*/ */
static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> query) { static void appendTabQuery(Integer tabType, LambdaQueryWrapperX<ProductSpuDO> query) {
// 出售中商品 // 出售中商品
@ -169,4 +169,17 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
} }
} }
/**
* 更新商品 SPU 浏览量
*
* @param id 商品 SPU 编号
* @param incrCount 增加的数量
*/
default void updateBrowseCount(Long id, int incrCount) {
LambdaUpdateWrapper<ProductSpuDO> updateWrapper = new LambdaUpdateWrapper<ProductSpuDO>()
.setSql(" browse_count = browse_count +" + incrCount)
.eq(ProductSpuDO::getId, id);
update(null, updateWrapper);
}
} }

View File

@ -0,0 +1,58 @@
package cn.iocoder.yudao.module.product.service.history;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO;
import java.util.Collection;
/**
* 商品浏览记录 Service 接口
*
* @author owen
*/
public interface ProductBrowseHistoryService {
/**
* 创建商品浏览记录
*
* @param userId 用户编号
* @param spuId SPU 编号
* @return 编号
*/
Long createBrowseHistory(Long userId, Long spuId);
/**
* 隐藏用户商品浏览记录
*
* @param userId 用户编号
* @param spuId SPU 编号
*/
void hideUserBrowseHistory(Long userId, Collection<Long> spuId);
/**
* 获得商品浏览记录
*
* @param id 编号
* @return 商品浏览记录
*/
ProductBrowseHistoryDO getBrowseHistory(Long id);
/**
* 获取用户记录数量
*
* @param userId 用户编号
* @param userDeleted 用户是否删除
* @return 数量
*/
Long getBrowseHistoryCount(Long userId, Boolean userDeleted);
/**
* 获得商品浏览记录分页
*
* @param pageReqVO 分页查询
* @return 商品浏览记录分页
*/
PageResult<ProductBrowseHistoryDO> getBrowseHistoryPage(ProductBrowseHistoryPageReqVO pageReqVO);
}

View File

@ -0,0 +1,72 @@
package cn.iocoder.yudao.module.product.service.history;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.product.controller.admin.history.vo.ProductBrowseHistoryPageReqVO;
import cn.iocoder.yudao.module.product.dal.dataobject.history.ProductBrowseHistoryDO;
import cn.iocoder.yudao.module.product.dal.mysql.history.ProductBrowseHistoryMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import java.util.Collection;
/**
* 商品浏览记录 Service 实现类
*
* @author owen
*/
@Service
@Validated
public class ProductBrowseHistoryServiceImpl implements ProductBrowseHistoryService {
private static final int USER_STORE_MAXIMUM = 100;
@Resource
private ProductBrowseHistoryMapper browseHistoryMapper;
@Override
public Long createBrowseHistory(Long userId, Long spuId) {
// 情况一同一个商品只保留最新的一条记录
ProductBrowseHistoryDO historyDO = browseHistoryMapper.selectOne(ProductBrowseHistoryDO::getUserId, userId, ProductBrowseHistoryDO::getSpuId, spuId);
if (historyDO != null) {
browseHistoryMapper.deleteById(historyDO);
} else {
// 情况二限制每个用户的浏览记录的条数
Page<ProductBrowseHistoryDO> pageResult = browseHistoryMapper.selectPageByUserIdOrderByCreateTimeAsc(userId);
if (pageResult.getTotal() >= USER_STORE_MAXIMUM) {
// 删除最早的一条
browseHistoryMapper.deleteById(CollUtil.getFirst(pageResult.getRecords()));
}
}
// 插入
ProductBrowseHistoryDO browseHistory = new ProductBrowseHistoryDO()
.setUserId(userId)
.setSpuId(spuId);
browseHistoryMapper.insert(browseHistory);
// 返回
return browseHistory.getId();
}
@Override
public void hideUserBrowseHistory(Long userId, Collection<Long> spuIds) {
browseHistoryMapper.updateUserDeletedByUserId(userId, spuIds, true);
}
@Override
public ProductBrowseHistoryDO getBrowseHistory(Long id) {
return browseHistoryMapper.selectById(id);
}
@Override
public Long getBrowseHistoryCount(Long userId, Boolean userDeleted) {
return browseHistoryMapper.selectCountByUserIdAndUserDeleted(userId, userDeleted);
}
@Override
public PageResult<ProductBrowseHistoryDO> getBrowseHistoryPage(ProductBrowseHistoryPageReqVO pageReqVO) {
return browseHistoryMapper.selectPage(pageReqVO);
}
}

View File

@ -148,4 +148,12 @@ public interface ProductSpuService {
*/ */
List<ProductSpuDO> validateSpuList(Collection<Long> ids); List<ProductSpuDO> validateSpuList(Collection<Long> ids);
/**
* 更新商品 SPU 浏览量
*
* @param id 商品 SPU 编号
* @param incrCount 增加的数量
*/
void updateBrowseCount(Long id, int incrCount);
} }

View File

@ -157,6 +157,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
return list; return list;
} }
@Override
public void updateBrowseCount(Long id, int incrCount) {
productSpuMapper.updateBrowseCount(id , incrCount);
}
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteSpu(Long id) { public void deleteSpu(Long id) {