mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 18:28:43 +08:00 
			
		
		
		
	!593 商品评论表增加冗余 SKU 的图片地址, 规格
Merge pull request !593 from 疯狂的世界/owen_dev
This commit is contained in:
		
							
								
								
									
										14
									
								
								sql/mysql/product_comment.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								sql/mysql/product_comment.sql
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,14 @@ | |||||||
|  | -- 1.冗余 SKU 图片地址, 规格 | ||||||
|  | alter table product_comment | ||||||
|  |     add column sku_pic_url varchar(256) not null comment '图片地址' after sku_id; | ||||||
|  |  | ||||||
|  | alter table product_comment | ||||||
|  |     add column sku_properties varchar(512) null | ||||||
|  |         comment '属性数组,JSON 格式 [{propertId: , valueId: }, {propertId: , valueId: }]' after sku_pic_url; | ||||||
|  |  | ||||||
|  | -- 2.修复已有数据 | ||||||
|  | update product_comment pc | ||||||
|  |     join product_sku ps on pc.spu_id = ps.spu_id | ||||||
|  | set pc.sku_pic_url    = ps.pic_url, | ||||||
|  |     pc.sku_properties = ps.properties | ||||||
|  | where pc.sku_id is not null; | ||||||
| @@ -5,9 +5,7 @@ import cn.iocoder.yudao.framework.common.pojo.PageResult; | |||||||
| import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*; | import cn.iocoder.yudao.module.product.controller.admin.comment.vo.*; | ||||||
| import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; | import cn.iocoder.yudao.module.product.convert.comment.ProductCommentConvert; | ||||||
| import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; | import cn.iocoder.yudao.module.product.dal.dataobject.comment.ProductCommentDO; | ||||||
| import cn.iocoder.yudao.module.product.dal.dataobject.sku.ProductSkuDO; |  | ||||||
| import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; | import cn.iocoder.yudao.module.product.service.comment.ProductCommentService; | ||||||
| import cn.iocoder.yudao.module.product.service.sku.ProductSkuService; |  | ||||||
| import io.swagger.v3.oas.annotations.Operation; | import io.swagger.v3.oas.annotations.Operation; | ||||||
| import io.swagger.v3.oas.annotations.tags.Tag; | import io.swagger.v3.oas.annotations.tags.Tag; | ||||||
| import org.springframework.security.access.prepost.PreAuthorize; | import org.springframework.security.access.prepost.PreAuthorize; | ||||||
| @@ -16,10 +14,8 @@ import org.springframework.web.bind.annotation.*; | |||||||
|  |  | ||||||
| import javax.annotation.Resource; | import javax.annotation.Resource; | ||||||
| import javax.validation.Valid; | import javax.validation.Valid; | ||||||
| import java.util.List; |  | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; | ||||||
| import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; |  | ||||||
| import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; | ||||||
|  |  | ||||||
| @Tag(name = "管理后台 - 商品评价") | @Tag(name = "管理后台 - 商品评价") | ||||||
| @@ -30,18 +26,13 @@ public class ProductCommentController { | |||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private ProductCommentService productCommentService; |     private ProductCommentService productCommentService; | ||||||
|     @Resource |  | ||||||
|     private ProductSkuService productSkuService; |  | ||||||
|  |  | ||||||
|     @GetMapping("/page") |     @GetMapping("/page") | ||||||
|     @Operation(summary = "获得商品评价分页") |     @Operation(summary = "获得商品评价分页") | ||||||
|     @PreAuthorize("@ss.hasPermission('product:comment:query')") |     @PreAuthorize("@ss.hasPermission('product:comment:query')") | ||||||
|     public CommonResult<PageResult<ProductCommentRespVO>> getCommentPage(@Valid ProductCommentPageReqVO pageVO) { |     public CommonResult<PageResult<ProductCommentRespVO>> getCommentPage(@Valid ProductCommentPageReqVO pageVO) { | ||||||
|         PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO); |         PageResult<ProductCommentDO> pageResult = productCommentService.getCommentPage(pageVO); | ||||||
|         // 拼接返回 |         return success(ProductCommentConvert.INSTANCE.convertPage2(pageResult)); | ||||||
|         List<ProductSkuDO> skuList = productSkuService.getSkuList( |  | ||||||
|                 convertSet(pageResult.getList(), ProductCommentDO::getSkuId)); |  | ||||||
|         return success(ProductCommentConvert.INSTANCE.convertPage(pageResult, skuList)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @PutMapping("/update-visible") |     @PutMapping("/update-visible") | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package cn.iocoder.yudao.module.product.convert.comment; | package cn.iocoder.yudao.module.product.convert.comment; | ||||||
|  |  | ||||||
|  | import cn.hutool.core.collection.CollUtil; | ||||||
| import cn.hutool.core.util.ObjectUtil; | import cn.hutool.core.util.ObjectUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageResult; | import cn.iocoder.yudao.framework.common.pojo.PageResult; | ||||||
| import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils; | ||||||
| @@ -91,7 +92,7 @@ public interface ProductCommentConvert { | |||||||
|  |  | ||||||
|     @Mapping(target = "scores", |     @Mapping(target = "scores", | ||||||
|             expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") |             expression = "java(convertScores(createReqDTO.getDescriptionScores(), createReqDTO.getBenefitScores()))") | ||||||
|     default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, MemberUserRespDTO user) { |     default ProductCommentDO convert(ProductCommentCreateReqDTO createReqDTO, ProductSpuDO spuDO, ProductSkuDO skuDO, MemberUserRespDTO user) { | ||||||
|         ProductCommentDO commentDO = convert(createReqDTO); |         ProductCommentDO commentDO = convert(createReqDTO); | ||||||
|         if (user != null) { |         if (user != null) { | ||||||
|             commentDO.setUserId(user.getId()); |             commentDO.setUserId(user.getId()); | ||||||
| @@ -102,6 +103,10 @@ public interface ProductCommentConvert { | |||||||
|             commentDO.setSpuId(spuDO.getId()); |             commentDO.setSpuId(spuDO.getId()); | ||||||
|             commentDO.setSpuName(spuDO.getName()); |             commentDO.setSpuName(spuDO.getName()); | ||||||
|         } |         } | ||||||
|  |         if (skuDO != null) { | ||||||
|  |             commentDO.setSkuPicUrl(skuDO.getPicUrl()); | ||||||
|  |             commentDO.setSkuProperties(skuDO.getProperties()); | ||||||
|  |         } | ||||||
|         return commentDO; |         return commentDO; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -117,27 +122,32 @@ public interface ProductCommentConvert { | |||||||
|  |  | ||||||
|     List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list); |     List<AppProductCommentRespVO> convertList02(List<ProductCommentDO> list); | ||||||
|  |  | ||||||
|     default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spu) { |     default ProductCommentDO convert(ProductCommentCreateReqVO createReq, ProductSpuDO spuDO, ProductSkuDO skuDO) { | ||||||
|         ProductCommentDO commentDO = convert(createReq); |         ProductCommentDO commentDO = convert(createReq); | ||||||
|         if (spu != null) { |         if (spuDO != null) { | ||||||
|             commentDO.setSpuId(spu.getId()).setSpuName(spu.getName()); |             commentDO.setSpuId(spuDO.getId()); | ||||||
|  |             commentDO.setSpuName(spuDO.getName()); | ||||||
|  |         } | ||||||
|  |         if (skuDO != null) { | ||||||
|  |             commentDO.setSkuPicUrl(skuDO.getPicUrl()); | ||||||
|  |             commentDO.setSkuProperties(skuDO.getProperties()); | ||||||
|         } |         } | ||||||
|         return commentDO; |         return commentDO; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     default PageResult<ProductCommentRespVO> convertPage(PageResult<ProductCommentDO> pageResult, |     default PageResult<ProductCommentRespVO> convertPage2(PageResult<ProductCommentDO> pageResult) { | ||||||
|                                                          List<ProductSkuDO> skus) { |         Map<Long, List<ProductSkuDO.Property>> propertiesMap = convertMap(pageResult.getList(), | ||||||
|  |                 ProductCommentDO::getId, | ||||||
|  |                 // 这里会有NULL异常, 需要处理一下 | ||||||
|  |                 comment -> CollUtil.emptyIfNull(comment.getSkuProperties())); | ||||||
|  |  | ||||||
|         PageResult<ProductCommentRespVO> result = convertPage(pageResult); |         PageResult<ProductCommentRespVO> result = convertPage(pageResult); | ||||||
|         // 拼接数据 |  | ||||||
|         Map<Long, ProductSkuDO> skuMap = convertMap(skus, ProductSkuDO::getId); |  | ||||||
|         for (ProductCommentRespVO vo : result.getList()) { |         for (ProductCommentRespVO vo : result.getList()) { | ||||||
|             findAndThen(skuMap, vo.getSkuId(), sku -> { |             findAndThen(propertiesMap, vo.getId(), properties -> { | ||||||
|                 String propertyNames = sku.getProperties().stream() |                 String propertyNames = properties.stream() | ||||||
|                         .map(ProductSkuDO.Property::getValueName) |                         .map(ProductSkuDO.Property::getValueName) | ||||||
|                         .filter(Objects::nonNull) |                         .filter(Objects::nonNull) | ||||||
|                         .collect(Collectors.joining(" ")); |                         .collect(Collectors.joining(" ")); | ||||||
|                 // TODO @疯狂:要不写入评论的时候,把商品图片、商品属性,都冗余进去。因为这种东西有“快照”的需求。商品后续会编辑掉 |  | ||||||
|                 vo.setSkuPicUrl(sku.getPicUrl()); |  | ||||||
|                 vo.setSpuName(vo.getSpuName() + " " + propertyNames); |                 vo.setSpuName(vo.getSpuName() + " " + propertyNames); | ||||||
|             }); |             }); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -86,6 +86,15 @@ public class ProductCommentDO extends BaseDO { | |||||||
|      * 关联 {@link ProductSkuDO#getId()} |      * 关联 {@link ProductSkuDO#getId()} | ||||||
|      */ |      */ | ||||||
|     private Long skuId; |     private Long skuId; | ||||||
|  |     /** | ||||||
|  |      * 商品 SKU 图片地址 | ||||||
|  |      */ | ||||||
|  |     private String skuPicUrl; | ||||||
|  |     /** | ||||||
|  |      * 属性数组,JSON 格式 | ||||||
|  |      */ | ||||||
|  |     @TableField(typeHandler = ProductSkuDO.PropertyTypeHandler.class) | ||||||
|  |     private List<ProductSkuDO.Property> skuProperties; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 是否可见 |      * 是否可见 | ||||||
|   | |||||||
| @@ -53,25 +53,29 @@ public class ProductCommentServiceImpl implements ProductCommentService { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void createComment(ProductCommentCreateReqVO createReqVO) { |     public void createComment(ProductCommentCreateReqVO createReqVO) { | ||||||
|         // 校验商品 |         // 校验 SKU | ||||||
|         ProductSpuDO spu = validateSpuBySkuId(createReqVO.getSkuId()); |         ProductSkuDO skuDO = validateSku(createReqVO.getSkuId()); | ||||||
|  |         // 校验 SPU | ||||||
|  |         ProductSpuDO spuDO = validateSpu(skuDO.getSpuId()); | ||||||
|  |  | ||||||
|         // 创建评论 |         // 创建评论 | ||||||
|         ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqVO, spu); |         ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqVO, spuDO, skuDO); | ||||||
|         productCommentMapper.insert(comment); |         productCommentMapper.insert(comment); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Long createComment(ProductCommentCreateReqDTO createReqDTO) { |     public Long createComment(ProductCommentCreateReqDTO createReqDTO) { | ||||||
|         // 校验商品 |         // 校验 SKU | ||||||
|         ProductSpuDO spuDO = validateSpuBySkuId(createReqDTO.getSkuId()); |         ProductSkuDO skuDO = validateSku(createReqDTO.getSkuId()); | ||||||
|  |         // 校验 SPU | ||||||
|  |         ProductSpuDO spuDO = validateSpu(skuDO.getSpuId()); | ||||||
|         // 校验评论 |         // 校验评论 | ||||||
|         validateCommentExists(createReqDTO.getUserId(), createReqDTO.getOrderId()); |         validateCommentExists(createReqDTO.getUserId(), createReqDTO.getOrderId()); | ||||||
|         // 获取用户详细信息 |         // 获取用户详细信息 | ||||||
|         MemberUserRespDTO user = memberUserApi.getUser(createReqDTO.getUserId()); |         MemberUserRespDTO user = memberUserApi.getUser(createReqDTO.getUserId()); | ||||||
|  |  | ||||||
|         // 创建评论 |         // 创建评论 | ||||||
|         ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqDTO, spuDO, user); |         ProductCommentDO comment = ProductCommentConvert.INSTANCE.convert(createReqDTO, spuDO, skuDO, user); | ||||||
|         productCommentMapper.insert(comment); |         productCommentMapper.insert(comment); | ||||||
|         return comment.getId(); |         return comment.getId(); | ||||||
|     } |     } | ||||||
| @@ -79,7 +83,7 @@ public class ProductCommentServiceImpl implements ProductCommentService { | |||||||
|     /** |     /** | ||||||
|      * 判断当前订单的当前商品用户是否评价过 |      * 判断当前订单的当前商品用户是否评价过 | ||||||
|      * |      * | ||||||
|      * @param userId 用户编号 |      * @param userId      用户编号 | ||||||
|      * @param orderItemId 订单项编号 |      * @param orderItemId 订单项编号 | ||||||
|      */ |      */ | ||||||
|     private void validateCommentExists(Long userId, Long orderItemId) { |     private void validateCommentExists(Long userId, Long orderItemId) { | ||||||
| @@ -105,13 +109,6 @@ public class ProductCommentServiceImpl implements ProductCommentService { | |||||||
|         return spu; |         return spu; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private ProductSpuDO validateSpuBySkuId(Long skuId) { |  | ||||||
|         // 通过 sku ID 拿到 spu 相关信息 |  | ||||||
|         ProductSkuDO sku = validateSku(skuId); |  | ||||||
|         // 校验 spu 如果存在返回详情 |  | ||||||
|         return validateSpu(sku.getSpuId()); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { |     public void updateCommentVisible(ProductCommentUpdateVisibleReqVO updateReqVO) { | ||||||
|         // 校验评论是否存在 |         // 校验评论是否存在 | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ import cn.hutool.core.lang.Assert; | |||||||
| import cn.hutool.core.util.IdUtil; | import cn.hutool.core.util.IdUtil; | ||||||
| import cn.hutool.core.util.ObjectUtil; | import cn.hutool.core.util.ObjectUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
|  | import cn.hutool.extra.spring.SpringUtil; | ||||||
| import cn.iocoder.yudao.framework.common.core.KeyValue; | import cn.iocoder.yudao.framework.common.core.KeyValue; | ||||||
| import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum; | ||||||
| import cn.iocoder.yudao.framework.common.enums.TerminalEnum; | import cn.iocoder.yudao.framework.common.enums.TerminalEnum; | ||||||
| @@ -13,6 +14,7 @@ import cn.iocoder.yudao.framework.common.util.json.JsonUtils; | |||||||
| import cn.iocoder.yudao.module.member.api.address.AddressApi; | import cn.iocoder.yudao.module.member.api.address.AddressApi; | ||||||
| import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | import cn.iocoder.yudao.module.member.api.address.dto.AddressRespDTO; | ||||||
| import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; | import cn.iocoder.yudao.module.member.api.level.MemberLevelApi; | ||||||
|  | import cn.iocoder.yudao.module.member.api.point.MemberPointApi; | ||||||
| import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | import cn.iocoder.yudao.module.member.api.user.MemberUserApi; | ||||||
| import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||||||
| import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | import cn.iocoder.yudao.module.member.enums.MemberExperienceBizTypeEnum; | ||||||
| @@ -110,6 +112,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | |||||||
|     private MemberUserApi memberUserApi; |     private MemberUserApi memberUserApi; | ||||||
|     @Resource |     @Resource | ||||||
|     private MemberLevelApi memberLevelApi; |     private MemberLevelApi memberLevelApi; | ||||||
|  |     @Resource | ||||||
|  |     private MemberPointApi memberPointApi; | ||||||
|  |  | ||||||
|     @Resource |     @Resource | ||||||
|     private ProductCommentApi productCommentApi; |     private ProductCommentApi productCommentApi; | ||||||
| @@ -346,9 +350,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | |||||||
|         // TODO 芋艿:OrderLog |         // TODO 芋艿:OrderLog | ||||||
|  |  | ||||||
|         // 增加用户积分 |         // 增加用户积分 | ||||||
|         addUserPointAsync(order.getUserId(), order.getPayPrice(), order.getId()); |         getSelf().addUserPointAsync(order.getUserId(), order.getPayPrice(), order.getId()); | ||||||
|         // 增加用户经验 |         // 增加用户经验 | ||||||
|         addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId()); |         getSelf().addUserExperienceAsync(order.getUserId(), order.getPayPrice(), order.getId()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -617,9 +621,9 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | |||||||
|         // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效 |         // TODO 芋艿:未来如果有分佣,需要更新相关分佣订单为已失效 | ||||||
|  |  | ||||||
|         // 扣减用户积分 |         // 扣减用户积分 | ||||||
|         reduceUserPointAsync(order.getUserId(), orderRefundPrice, afterSaleId); |         getSelf().reduceUserPointAsync(order.getUserId(), orderRefundPrice, afterSaleId); | ||||||
|         // 扣减用户经验 |         // 扣减用户经验 | ||||||
|         reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId); |         getSelf().reduceUserExperienceAsync(order.getUserId(), orderRefundPrice, afterSaleId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -667,7 +671,6 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | |||||||
|                 TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())); |                 TradeOrderItemAfterSaleStatusEnum.SUCCESS.getStatus())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // TODO @疯狂:直接 this 调用,async 不生效哈。全局搜下 getSelf(); |  | ||||||
|     @Async |     @Async | ||||||
|     protected void addUserExperienceAsync(Long userId, Integer payPrice, Long orderId) { |     protected void addUserExperienceAsync(Long userId, Integer payPrice, Long orderId) { | ||||||
|         int bizType = MemberExperienceBizTypeEnum.ORDER.getType(); |         int bizType = MemberExperienceBizTypeEnum.ORDER.getType(); | ||||||
| @@ -683,12 +686,22 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService { | |||||||
|     @Async |     @Async | ||||||
|     protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) { |     protected void addUserPointAsync(Long userId, Integer payPrice, Long orderId) { | ||||||
|         int bizType = MemberPointBizTypeEnum.ORDER_BUY.getType(); |         int bizType = MemberPointBizTypeEnum.ORDER_BUY.getType(); | ||||||
|         memberUserApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId)); |         memberPointApi.addPoint(userId, payPrice, bizType, String.valueOf(orderId)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Async |     @Async | ||||||
|     protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) { |     protected void reduceUserPointAsync(Long userId, Integer refundPrice, Long afterSaleId) { | ||||||
|         int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType(); |         int bizType = MemberPointBizTypeEnum.ORDER_CANCEL.getType(); | ||||||
|         memberUserApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); |         memberPointApi.addPoint(userId, -refundPrice, bizType, String.valueOf(afterSaleId)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 获得自身的代理对象,解决 AOP 生效问题 | ||||||
|  |      * | ||||||
|  |      * @return 自己 | ||||||
|  |      */ | ||||||
|  |     private TradeOrderUpdateServiceImpl getSelf() { | ||||||
|  |         return SpringUtil.getBean(getClass()); | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,22 @@ | |||||||
|  | package cn.iocoder.yudao.module.member.api.point; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 用户积分的 API 接口 | ||||||
|  |  * | ||||||
|  |  * @author owen | ||||||
|  |  */ | ||||||
|  | public interface MemberPointApi { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 增加用户积分 | ||||||
|  |      * | ||||||
|  |      * @param userId  用户编号 | ||||||
|  |      * @param point   积分 | ||||||
|  |      * @param bizType 业务类型 {@link MemberPointBizTypeEnum} | ||||||
|  |      * @param bizId   业务编号 | ||||||
|  |      */ | ||||||
|  |     void addPoint(Long userId, Integer point, Integer bizType, String bizId); | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -1,7 +1,6 @@ | |||||||
| package cn.iocoder.yudao.module.member.api.user; | package cn.iocoder.yudao.module.member.api.user; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||||||
| import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; |  | ||||||
|  |  | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -57,16 +56,4 @@ public interface MemberUserApi { | |||||||
|      * @return 用户信息 |      * @return 用户信息 | ||||||
|      */ |      */ | ||||||
|     MemberUserRespDTO getUserByMobile(String mobile); |     MemberUserRespDTO getUserByMobile(String mobile); | ||||||
|  |  | ||||||
|     // TODO @疯狂:是不是新的类,MemberPointApi? |  | ||||||
|     /** |  | ||||||
|      * 增加用户积分 |  | ||||||
|      * |  | ||||||
|      * @param userId  用户编号 |  | ||||||
|      * @param point   积分 |  | ||||||
|      * @param bizType 业务类型 {@link MemberPointBizTypeEnum} |  | ||||||
|      * @param bizId   业务编号 |  | ||||||
|      */ |  | ||||||
|     void addPoint(Long userId, Integer point, Integer bizType, String bizId); |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,12 +18,12 @@ public enum MemberExperienceBizTypeEnum { | |||||||
|     /** |     /** | ||||||
|      * 管理员调整、邀请新用户、下单、退单、签到、抽奖 |      * 管理员调整、邀请新用户、下单、退单、签到、抽奖 | ||||||
|      */ |      */ | ||||||
|     ADMIN(0, "管理员调整", "管理员调整获得 {} 经验", false), |     ADMIN(0, "管理员调整", "管理员调整获得 {} 经验", true), | ||||||
|     INVITE_REGISTER(1, "邀新奖励", "邀请好友获得 {} 经验", false), |     INVITE_REGISTER(1, "邀新奖励", "邀请好友获得 {} 经验", true), | ||||||
|     ORDER(2, "下单奖励", "下单获得 {} 经验", false), |     ORDER(2, "下单奖励", "下单获得 {} 经验", true), | ||||||
|     REFUND(3, "退单扣除", "退单获得 {} 经验", true), |     REFUND(3, "退单扣除", "退单获得 {} 经验", false), | ||||||
|     SIGN_IN(4, "签到奖励", "签到获得 {} 经验", false), |     SIGN_IN(4, "签到奖励", "签到获得 {} 经验", true), | ||||||
|     LOTTERY(5, "抽奖奖励", "抽奖获得 {} 经验", false), |     LOTTERY(5, "抽奖奖励", "抽奖获得 {} 经验", true), | ||||||
|     ; |     ; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -41,7 +41,7 @@ public enum MemberExperienceBizTypeEnum { | |||||||
|     /** |     /** | ||||||
|      * 是否为扣减积分 |      * 是否为扣减积分 | ||||||
|      */ |      */ | ||||||
|     private final boolean isReduce; |     private final boolean add; | ||||||
|  |  | ||||||
|     public static MemberExperienceBizTypeEnum getByType(Integer type) { |     public static MemberExperienceBizTypeEnum getByType(Integer type) { | ||||||
|         return EnumUtil.getBy(MemberExperienceBizTypeEnum.class, |         return EnumUtil.getBy(MemberExperienceBizTypeEnum.class, | ||||||
|   | |||||||
| @@ -16,9 +16,9 @@ import java.util.Objects; | |||||||
| @Getter | @Getter | ||||||
| public enum MemberPointBizTypeEnum implements IntArrayValuable { | public enum MemberPointBizTypeEnum implements IntArrayValuable { | ||||||
|  |  | ||||||
|     SIGN(1, "签到", "签到获得 {} 积分", false), |     SIGN(1, "签到", "签到获得 {} 积分", true), | ||||||
|     ORDER_BUY(10, "订单消费", "下单获得 {} 积分", false), |     ORDER_BUY(10, "订单消费", "下单获得 {} 积分", true), | ||||||
|     ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", true); // 退回积分 |     ORDER_CANCEL(11, "订单取消", "退单获得 {} 积分", false); // 退回积分 | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * 类型 |      * 类型 | ||||||
| @@ -32,11 +32,10 @@ public enum MemberPointBizTypeEnum implements IntArrayValuable { | |||||||
|      * 描述 |      * 描述 | ||||||
|      */ |      */ | ||||||
|     private final String description; |     private final String description; | ||||||
|     // TODO @疯狂:改成 add 会好点。一个是属性我们尽量不要 isXXX;另外尽量正向思维,不取反; |  | ||||||
|     /** |     /** | ||||||
|      * 是否为扣减积分 |      * 是否为扣减积分 | ||||||
|      */ |      */ | ||||||
|     private final boolean isReduce; |     private final boolean add; | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public int[] array() { |     public int[] array() { | ||||||
|   | |||||||
| @@ -0,0 +1,34 @@ | |||||||
|  | package cn.iocoder.yudao.module.member.api.point; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; | ||||||
|  | import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; | ||||||
|  | import org.springframework.stereotype.Service; | ||||||
|  | import org.springframework.validation.annotation.Validated; | ||||||
|  |  | ||||||
|  | import javax.annotation.Resource; | ||||||
|  |  | ||||||
|  | import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; | ||||||
|  | import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.POINT_RECORD_BIZ_NOT_SUPPORT; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 用户积分的 API 实现类 | ||||||
|  |  * | ||||||
|  |  * @author owen | ||||||
|  |  */ | ||||||
|  | @Service | ||||||
|  | @Validated | ||||||
|  | public class MemberPointApiImpl implements MemberPointApi { | ||||||
|  |  | ||||||
|  |     @Resource | ||||||
|  |     private MemberPointRecordService memberPointRecordService; | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void addPoint(Long userId, Integer point, Integer bizType, String bizId) { | ||||||
|  |         MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType); | ||||||
|  |         if (bizTypeEnum == null) { | ||||||
|  |             throw exception(POINT_RECORD_BIZ_NOT_SUPPORT); | ||||||
|  |         } | ||||||
|  |         memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -3,8 +3,6 @@ package cn.iocoder.yudao.module.member.api.user; | |||||||
| import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | import cn.iocoder.yudao.module.member.api.user.dto.MemberUserRespDTO; | ||||||
| import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; | import cn.iocoder.yudao.module.member.convert.user.MemberUserConvert; | ||||||
| import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | import cn.iocoder.yudao.module.member.dal.dataobject.user.MemberUserDO; | ||||||
| import cn.iocoder.yudao.module.member.enums.point.MemberPointBizTypeEnum; |  | ||||||
| import cn.iocoder.yudao.module.member.service.point.MemberPointRecordService; |  | ||||||
| import cn.iocoder.yudao.module.member.service.user.MemberUserService; | import cn.iocoder.yudao.module.member.service.user.MemberUserService; | ||||||
| import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||||
| import org.springframework.validation.annotation.Validated; | import org.springframework.validation.annotation.Validated; | ||||||
| @@ -13,9 +11,6 @@ import javax.annotation.Resource; | |||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; |  | ||||||
| import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.POINT_RECORD_BIZ_NOT_SUPPORT; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * 会员用户的 API 实现类 |  * 会员用户的 API 实现类 | ||||||
|  * |  * | ||||||
| @@ -28,9 +23,6 @@ public class MemberUserApiImpl implements MemberUserApi { | |||||||
|     @Resource |     @Resource | ||||||
|     private MemberUserService userService; |     private MemberUserService userService; | ||||||
|  |  | ||||||
|     @Resource |  | ||||||
|     private MemberPointRecordService memberPointRecordService; |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public MemberUserRespDTO getUser(Long id) { |     public MemberUserRespDTO getUser(Long id) { | ||||||
|         MemberUserDO user = userService.getUser(id); |         MemberUserDO user = userService.getUser(id); | ||||||
| @@ -52,13 +44,4 @@ public class MemberUserApiImpl implements MemberUserApi { | |||||||
|         return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile)); |         return MemberUserConvert.INSTANCE.convert2(userService.getUserByMobile(mobile)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void addPoint(Long userId, Integer point, Integer bizType, String bizId) { |  | ||||||
|         MemberPointBizTypeEnum bizTypeEnum = MemberPointBizTypeEnum.getByType(bizType); |  | ||||||
|         if (bizTypeEnum == null) { |  | ||||||
|             throw exception(POINT_RECORD_BIZ_NOT_SUPPORT); |  | ||||||
|         } |  | ||||||
|         memberPointRecordService.createPointRecord(userId, point, bizTypeEnum, bizId); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -200,7 +200,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { | |||||||
|         if (updateReqVO.getLevelId() == null) { |         if (updateReqVO.getLevelId() == null) { | ||||||
|             // 取消用户等级时,需要扣减经验 |             // 取消用户等级时,需要扣减经验 | ||||||
|             levelRecord.setExperience(-user.getExperience()); |             levelRecord.setExperience(-user.getExperience()); | ||||||
|             // TODO @疯狂:这里是不是也要设置下 setUserExperience 属性; |             levelRecord.setUserExperience(0); | ||||||
|             levelRecord.setDescription("管理员取消了等级"); |             levelRecord.setDescription("管理员取消了等级"); | ||||||
|         } else { |         } else { | ||||||
|             // 复制等级配置 |             // 复制等级配置 | ||||||
| @@ -232,7 +232,7 @@ public class MemberLevelServiceImpl implements MemberLevelService { | |||||||
|         if (experience == 0) { |         if (experience == 0) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         if (bizType.isReduce() && experience > 0) { |         if (!bizType.isAdd() && experience > 0) { | ||||||
|             experience = -experience; |             experience = -experience; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,5 @@ | |||||||
| package cn.iocoder.yudao.module.member.service.point; | package cn.iocoder.yudao.module.member.service.point; | ||||||
|  |  | ||||||
| import cn.hutool.core.util.NumberUtil; |  | ||||||
| import cn.hutool.core.util.ObjectUtil; | import cn.hutool.core.util.ObjectUtil; | ||||||
| import cn.hutool.core.util.StrUtil; | import cn.hutool.core.util.StrUtil; | ||||||
| import cn.iocoder.yudao.framework.common.pojo.PageParam; | import cn.iocoder.yudao.framework.common.pojo.PageParam; | ||||||
| @@ -75,15 +74,15 @@ public class MemberPointRecordServiceImpl implements MemberPointRecordService { | |||||||
|  |  | ||||||
|         // 1. 根据配置的比例,换算实际的积分 |         // 1. 根据配置的比例,换算实际的积分 | ||||||
|         point = point * pointConfig.getTradeGivePoint(); |         point = point * pointConfig.getTradeGivePoint(); | ||||||
|         if (bizType.isReduce() && point > 0) { |         if (!bizType.isAdd() && point > 0) { | ||||||
|             point = -point; |             point = -point; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         // 2. 增加积分记录 |         // 2. 增加积分记录 | ||||||
|         MemberUserDO user = memberUserService.getUser(userId); |         MemberUserDO user = memberUserService.getUser(userId); | ||||||
|         Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0); |         Integer userPoint = ObjectUtil.defaultIfNull(user.getPoint(), 0); | ||||||
|         // 用户变动后的积分,防止扣出负数 TODO 疯狂:积分是不是允许扣到负数。因为它是跟有钱有关的东西,不能让商家出现资金损失 |         // 用户变动后的积分 | ||||||
|         Integer totalPoint = NumberUtil.max(userPoint + point, 0); |         Integer totalPoint = userPoint + point; | ||||||
|         MemberPointRecordDO recordDO = new MemberPointRecordDO() |         MemberPointRecordDO recordDO = new MemberPointRecordDO() | ||||||
|                 .setUserId(userId) |                 .setUserId(userId) | ||||||
|                 .setBizId(bizId) |                 .setBizId(bizId) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 芋道源码
					芋道源码