mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 12:18:42 +08:00 
			
		
		
		
	Merge branch 'develop' of https://gitee.com/CrazyWorld/ruoyi-vue-pro into develop
# Conflicts: # yudao-module-mall/yudao-module-promotion-biz/src/main/java/cn/iocoder/yudao/module/promotion/controller/app/article/AppArticleController.java
This commit is contained in:
		@@ -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.spu.ProductSpuDO;
 | 
			
		||||
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.spu.ProductSpuService;
 | 
			
		||||
import io.swagger.v3.oas.annotations.Operation;
 | 
			
		||||
@@ -48,6 +49,8 @@ public class AppProductSpuController {
 | 
			
		||||
    private ProductSpuService productSpuService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private ProductSkuService productSkuService;
 | 
			
		||||
    @Resource
 | 
			
		||||
    private ProductBrowseHistoryService productBrowseHistoryService;
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private MemberLevelApi memberLevelApi;
 | 
			
		||||
@@ -122,6 +125,11 @@ public class AppProductSpuController {
 | 
			
		||||
            throw exception(SPU_NOT_ENABLE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 增加浏览量
 | 
			
		||||
        productSpuService.updateBrowseCount(id, 1);
 | 
			
		||||
        // 保存浏览记录
 | 
			
		||||
        productBrowseHistoryService.createBrowseHistory(getLoginUserId(), id);
 | 
			
		||||
 | 
			
		||||
        // 拼接返回
 | 
			
		||||
        List<ProductSkuDO> skus = productSkuService.getSkuListBySpuId(spu.getId());
 | 
			
		||||
        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, Integer pageNo, Integer pageSize) {
 | 
			
		||||
        Page<ProductBrowseHistoryDO> page = Page.of(pageNo, pageSize);
 | 
			
		||||
        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);
 | 
			
		||||
        } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_BEST)) {
 | 
			
		||||
            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);
 | 
			
		||||
        } else if (ObjUtil.equal(pageReqVO.getRecommendType(), AppProductSpuPageReqVO.RECOMMEND_TYPE_GOOD)) {
 | 
			
		||||
            query.eq(ProductSpuDO::getRecommendGood, true);
 | 
			
		||||
@@ -141,8 +141,8 @@ public interface ProductSpuMapper extends BaseMapperX<ProductSpuDO> {
 | 
			
		||||
    /**
 | 
			
		||||
     * 添加后台 Tab 选项的查询条件
 | 
			
		||||
     *
 | 
			
		||||
     * @param tabType      标签类型
 | 
			
		||||
     * @param query 查询条件
 | 
			
		||||
     * @param tabType 标签类型
 | 
			
		||||
     * @param 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,77 @@
 | 
			
		||||
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) {
 | 
			
		||||
        // 用户未登录时不记录
 | 
			
		||||
        if (userId == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 情况一:同一个商品,只保留最新的一条记录
 | 
			
		||||
        ProductBrowseHistoryDO historyDO = browseHistoryMapper.selectOne(ProductBrowseHistoryDO::getUserId, userId, ProductBrowseHistoryDO::getSpuId, spuId);
 | 
			
		||||
        if (historyDO != null) {
 | 
			
		||||
            browseHistoryMapper.deleteById(historyDO);
 | 
			
		||||
        } else {
 | 
			
		||||
            // 情况二:限制每个用户的浏览记录的条数(只查一条最早地记录、记录总数)
 | 
			
		||||
            Page<ProductBrowseHistoryDO> pageResult = browseHistoryMapper.selectPageByUserIdOrderByCreateTimeAsc(userId, 1, 1);
 | 
			
		||||
            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);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新商品 SPU 浏览量
 | 
			
		||||
     *
 | 
			
		||||
     * @param id        商品 SPU 编号
 | 
			
		||||
     * @param incrCount 增加的数量
 | 
			
		||||
     */
 | 
			
		||||
    void updateBrowseCount(Long id, int incrCount);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -156,6 +156,11 @@ public class ProductSpuServiceImpl implements ProductSpuService {
 | 
			
		||||
        return list;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void updateBrowseCount(Long id, int incrCount) {
 | 
			
		||||
        productSpuMapper.updateBrowseCount(id , incrCount);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void deleteSpu(Long id) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user