mirror of
https://gitee.com/huangge1199_admin/vue-pro.git
synced 2024-11-26 01:01:52 +08:00
商品:增加商品浏览记录
This commit is contained in:
parent
86a9c4bbf4
commit
f374e778bb
22
sql/mysql/optinal/product_browse_history.sql
Normal file
22
sql/mysql/optinal/product_browse_history.sql
Normal 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);
|
||||||
|
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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;
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
@ -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") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 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;
|
||||||
|
|
||||||
|
}
|
@ -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));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -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);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user