基本架构 要先把基本框架搭建起来,才能够愉快的写代码
1. domain 在eshop-business
模块下新建src\main\java
的文件夹,在该文件夹下创建com.eshop.modules.business.domain
的包,在该包下创建StoreProductRelation
的实体类,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 package com.eshop.module .business.domain;import com.baomidou.mybatisplus.annotation.IdType;import com.baomidou.mybatisplus.annotation.TableId;import com.eshop.domain.BaseDomain;import io.swagger.annotations.ApiModelProperty;import lombok.*;@Getter @Setter @AllArgsConstructor @NoArgsConstructor @Builder public class StoreProductRelation extends BaseDomain { private static final long serialVersionUID = 1L ; @TableId(value = "id", type = IdType.AUTO) private Long id; @ApiModelProperty(value = "用户ID") private Long uid; @ApiModelProperty(value = "商品ID") private Long productId; @ApiModelProperty(value = "类型(收藏(collect)、点赞(like)、足迹(foot))") private String type; @ApiModelProperty(value = "某种类型的商品(普通商品、秒杀商品)") private String category; }
部分注解说明:
@Builder:为类生成相对略微复杂的构建器 API @ApiModelProperty:添加和操作属性模块的数据 2. mapper 在mapper
的包下新建ProductRelationMapper
的类,代码如下:
1 2 3 4 5 6 7 8 9 package com.eshop.module .business.mapper;import com.eshop.common.mapper.CoreMapper;import com.eshop.module .business.domain.StoreProductRelation;import org.apache.ibatis.annotations.Mapper;@Mapper public interface ProductRelationMapper extends CoreMapper <StoreProductRelation> {}
其中接口ProductRelationMapper
继承的CoreMapper
,CoreMapper
继承BaseMapper
,相当于ProductRelationMapper
继承CoreMapper
3. service 在service
的包下新建ProductRelationService
的类,代码如下:
1 2 3 4 5 6 7 package com.eshop.module .business.service;import com.eshop.common.service.BaseService;import com.eshop.module .business.domain.StoreProductRelation;public interface ProductRelationService extends BaseService <StoreProductRelation> {}
新建ProductRelationServiceImpl
的实现类,实现ProductRelationService
的接口,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.eshop.module .business.service.impl;import com.baomidou.mybatisplus.core.toolkit.Wrappers;import com.eshop.api.EshopException;import com.eshop.common.service.impl.BaseServiceImpl;import com.eshop.dozer.service.IGenerator;import com.eshop.module .business.domain.StoreProductRelation;import com.eshop.module .business.mapper.ProductRelationMapper;import com.eshop.module .business.service.ProductRelationService;import lombok.AllArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;@Slf4j @Service @AllArgsConstructor @Transactional(rollbackFor = Exception.class) public class ProductRelationServiceImpl extends BaseServiceImpl <ProductRelationMapper, StoreProductRelation> implements ProductRelationService { private final ProductRelationMapper productRelationMapper; private final IGenerator generator; }
4. controller 在com.eshop
下新建一个包,包名叫controller
,新建一个类,类名叫ProductCollectController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 package com.eshop.controller;import com.eshop.module .business.service.ProductRelationService;import io.swagger.annotations.Api;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RestController;@Slf4j @RestController @Api(value = "产品模块", tags = "商城:产品模块") @RequiredArgsConstructor(onConstructor = @__(@Autowired)) public class ProductCollectController { private final ProductRelationService productRelationService; }
部分注解说明:
@Api:用在请求的类上,表示对类的说明 @RequiredArgsConstructor:生成带有必需参数的构造函数 功能编码 1. 商品添加收藏 前端发过来的请求(使用的是post方式):http://localhost:8008/api/collect/add
看报错Request method 'POST' not supported
,不支持请求方法“POST”
开始编写controller层的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @AppLog(value = "添加收藏", type = 1) @NoRepeatSubmit @AuthCheck @PostMapping("//collect/add") @ApiModelProperty(value = "添加收藏", notes = "添加收藏") public ApiResult<Boolean> collectAdd (@Validated @RequestBody StoreProductRelationQueryParam param) { Long uid = LocalUser.getUser().getUid(); if (!NumberUtil.isNumber(param.getId())){ throw new EshopException ("参数非法" ); } productRelationService.addRroductRelation(Long.valueOf(param.getId()), uid, param.getCategory()); return ApiResult.ok(); }
部分注解说明:
@AppLog:自定义日志注解 @NoRepeatSubmit:防止重复提交自定义注解 @AuthCheck:自定义注解实现用户行为认证 @ApiModelProperty:添加和操作属性模块的数据 1.1 是否收藏 service接口:
1 2 3 4 5 6 7 Boolean isProductRelation (long productId, long uid) ;
实现该业务功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @Override public Boolean isProductRelation (long productId, long uid) { int count = productRelationMapper .selectCount(Wrappers.<StoreProductRelation>lambdaQuery() .eq(StoreProductRelation::getUid,uid) .eq(StoreProductRelation::getType,"collect" ) .eq(StoreProductRelation::getProductId,productId)); if (count > 0 ) { return true ; } return false ; }
1.2 添加收藏 service接口:
1 2 3 4 5 6 void addRroductRelation (long productId,long uid,String category) ;
实现该业务功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Override public void addRroductRelation (long productId,long uid,String category) { if (isProductRelation(productId,uid)) { throw new EshopException ("已收藏" ); } StoreProductRelation storeProductRelation = StoreProductRelation.builder() .productId(productId) .uid(uid) .type(category) .build(); productRelationMapper.insert(storeProductRelation); }
2. 商品取消收藏 前端发过来的请求(使用的是post方式):http://localhost:8008/api/collect/del
controller层:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @AppLog(value = "取消收藏", type = 1) @NoRepeatSubmit @AuthCheck @PostMapping("/collect/del") @ApiOperation(value = "取消收藏",notes = "取消收藏") public ApiResult<Boolean> collectDel (@Validated @RequestBody StoreProductRelationQueryParam param) { long uid = LocalUser.getUser().getUid(); if (!NumberUtil.isNumber(param.getId())) { throw new EshopException ("参数非法" ); } productRelationService.delRroductRelation(Long.valueOf(param.getId()), uid,param.getCategory()); return ApiResult.ok(); }
service接口:
1 2 3 4 5 6 void delRroductRelation (long productId,long uid,String category) ;
实现该业务功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @Override public void delRroductRelation (long productId,long uid,String category) { StoreProductRelation productRelation = this .lambdaQuery() .eq(StoreProductRelation::getProductId,productId) .eq(StoreProductRelation::getUid,uid) .eq(StoreProductRelation::getType,category) .one(); if (productRelation == null ) { throw new EshopException ("已取消" ); } this .removeById(productRelation.getId()); }
3. 批量删除收藏/足迹 前端发过来的请求(使用的是post方式):http://localhost:8008/api/collect/dels/{productIds}
controller层:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 @AppLog(value = "批量取消收藏", type = 1) @NoRepeatSubmit @AuthCheck @PostMapping("/collect/dels/{productIds}") @ApiOperation(value = "批量取消收藏",notes = "批量取消收藏") @Transactional(rollbackFor = Exception.class) public ApiResult<Boolean> collectDels (@PathVariable String productIds,@RequestBody StoreProductRelationQueryParam param) { long uid = LocalUser.getUser().getUid(); String[] ids = productIds.split("," ); if (ids.length > 0 ){ for (String id : ids){ productRelationService.delRroductRelation(Long.parseLong(id), uid, param.getCategory()); } }else { throw new EshopException ("参数非法" ); } return ApiResult.ok(); }
4. 获取收藏或足迹 前端发过来的请求(使用的是get方式):http://localhost:8008/api/collect/user
controller层:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @AuthCheck @GetMapping("/collect/user") @ApiImplicitParams({ @ApiImplicitParam(name = "page", value = "页码,默认为1", paramType = "query", dataType = "int"), @ApiImplicitParam(name = "limit", value = "页大小,默认为10", paramType = "query", dataType = "int"), @ApiImplicitParam(name = "type", value = "foot为足迹,collect为收藏", paramType = "query", dataType = "String") }) @ApiOperation(value = "获取收藏产品,或足迹",notes = "获取收藏产品,或足迹") public ApiResult<List<StoreProductRelationQueryVo>> collectUser (@RequestParam(value = "page",defaultValue = "1") int page, @RequestParam(value = "limit",defaultValue = "500") int limit, @RequestParam(value = "type") String type) { Long uid = LocalUser.getUser().getUid(); List<StoreProductRelationQueryVo> storeProductRelationQueryVos = productRelationService.userCollectProduct(page, limit, uid, type); return ApiResult.ok(storeProductRelationQueryVos); }
此时我们现有的实体类对象返回的数据,并不能够满足我们的需求,因此需要在vo
包下造个StoreProductRelationQueryVo
的类,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 package com.eshop.modules.business.vo;import com.eshop.serializer.DoubleSerializer;import com.fasterxml.jackson.databind.annotation.JsonSerialize;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import lombok.Data;import java.io.Serializable;import java.util.Date;@Data @ApiModel(value = "StoreProductRelationQueryVo对象", description = "商品点赞和收藏表查询参数") public class StoreProductRelationQueryVo implements Serializable { private static final long serialVersionUID = 1L ; private Long id; @ApiModelProperty(value = "用户ID") private Long uid; @ApiModelProperty(value = "商品ID") private Long productId; @ApiModelProperty(value = "类型(收藏(collect)、点赞(like))") private String type; @ApiModelProperty(value = "某种类型的商品(普通商品、秒杀商品)") private String category; @ApiModelProperty(value = "添加时间") private Date createTime; @ApiModelProperty(value = "产品图片") private String image; @ApiModelProperty(value = "是否显示") private Integer isShow; @ApiModelProperty(value = "原价") @JsonSerialize(using = DoubleSerializer.class) private Double otPrice; @ApiModelProperty(value = "父ID") private Integer pid; @ApiModelProperty(value = "产品价格") @JsonSerialize(using = DoubleSerializer.class) private Double price; @ApiModelProperty(value = "产品销量") private Integer sales; @ApiModelProperty(value = "商品名称") private String storeName; @ApiModelProperty(value = "是否开启积分兑换") private Integer isIntegral; @ApiModelProperty(value = "积分") private Integer integral; }
service层:
1 2 3 4 5 6 7 8 List<StoreProductRelationQueryVo> userCollectProduct (int page, int limit, Long uid, String type) ;
实现该业务功能:
1 2 3 4 5 6 7 8 9 10 11 12 13 @Override public List<StoreProductRelationQueryVo> userCollectProduct (int page, int limit, Long uid, String type) { Page<StoreProductRelation> pageModel = new Page <>(page, limit); List<StoreProductRelationQueryVo> list = productRelationMapper.selectRelationList(pageModel,uid,type); return list; }
因为此操作涉及到多表查询,mybatisplus并未给我们提供相关可以调用的接口,因此我们需要自己编写接口,实现我们的需求。代码如下:
1 2 3 4 5 @Select("select B.id pid,A.type as category,B.store_name as storeName,B.price,B.is_integral as isIntegral," + "B.ot_price as otPrice,B.sales,B.image,B.is_show as isShow,B.integral as integral" + " from store_product_relation A left join store_product B " + "on A.product_id = B.id where A.type=#{type} and A.uid=#{uid} and A.is_del = 0 and B.is_del = 0 order by A.create_time desc") List<StoreProductRelationQueryVo> selectRelationList (Page page, @Param("uid") Long uid, @Param("type") String type) ;
至此接口编写完毕!!
程序排错