首页 > 其他分享 >手撕商城体系之产商品系统

手撕商城体系之产商品系统

时间:2023-04-02 11:34:31浏览次数:38  
标签:体系 DataResponse return id 商品 之产 收藏 public 商城

继续接前文手撕商城系统架构设计与实现

本文主要讲解商城体系下产商品系统的设计。商城系统可以拆分成多个业务中台和多个应用服务。

1、产商品系统业务架构

产商品系统作为商城重要的基础信息组成部分,主要划分为产品信息和商品信息,产品信息保持最原始的产品基础属性和内容,商品信息则根据不同的售卖策略、营销价格属性或SKU进行组装而成。

因此商品源于产品而不同于产品。简单概括来说,商品是营销属性的产品。

2、产商品关键内容信息

产商品中心关键内容包括:产品信息、商品信息、目录管理、标签信息、产品字典库、产品分类、产品属性、价格版本管理、商品SKU组合。

产品信息应该包括产品基本信息,产品价格(与报价系统产品价格统一库),产品工艺术属性信息。

3、产商品系统边界

产商品系统与其他系统关系

订单系统与产商品系统调用关系

4、产商品结构模型设计

 

5、关键代码片断

@RestController
@RequestMapping("/customer-api/v1/collect")
public class GoodsCollectController {

    /**
     * 分页获取当前会员的收藏列表
     *
     * @return 收藏列表
     */
    @RestApi(module = "商品收藏-C端", name = "分页获取当前会员的收藏列表", logabled = true)
    @PostMapping("/page")
    public DataResponse<CustomizePage<GoodsCollectVO>> pageCurrentMemberGoodsCollect(@RequestBody @Valid GoodsCollectQry qry) {
        CustomizePage<MallGoodsCollectE> goodsCollectE = MallGoodsCollectE.queryInstance().pageCurrentMemberGoodsCollect(qry);
        return DataResponse.of(GoodsCollectVOConverter.convert(goodsCollectE));
    }

    /**
     * 加入收藏
     *
     * @param cmd 商品id
     * @return 收藏列表
     */
    @RestApi(module = "商品收藏-C端", name = "加入收藏", logabled = true)
    @PostMapping("/add")
    public DataResponse<Boolean> addGoodsCollect(@RequestBody @Valid AddGoodsCollectCmd cmd) {
        return DataResponse.of(MallGoodsCollectE.queryInstance().addGoodsCollect(cmd));
    }

    /**
     * 取消收藏
     *
     * @param id 收藏id
     * @return 操作结果
     */
    @RestApi(module = "商品收藏-C端", name = "取消收藏", logabled = true)
    @DeleteMapping("/{id}")
    public DataResponse<Boolean> deleteGoodsCollect(@PathVariable Long id) {
        return DataResponse.of(MallGoodsCollectE.queryInstance().deleteGoodsCollect(id));
    }

    /**
     * 根据 商品id 查询当前商品收藏情况
     *
     * @param cmd 商品id
     * @return 当前商品收藏情况
     */
    @RestApi(module = "商品收藏-C端", name = "根据 商品id 查询当前商品收藏情况", logabled = true)
    @PostMapping("/getGoodsCollect")
    public DataResponse<GetGoodsCollectVO> getGoodsCollect(@RequestBody GetGoodsCollectCmd cmd) {
        MallGoodsCollectE mallGoodsCollectE = MallGoodsCollectE.queryInstance().getGoodsCollect(cmd);
        return DataResponse.of(BeanToolkit.instance().copy(mallGoodsCollectE, GetGoodsCollectVO.class));
    }
}
@Slf4j
@Service
public class GoodsService {
    @Autowired
    private GoodsSkuRpcService goodsSkuRpcService;
    @Autowired
    private GoodsGateway goodsGateway;

    /**
     * 查询商品详情
     */
    public Map<String, SpuApiCO> mapSkuCO(List<String> skuIds) {
        if (CollUtil.isEmpty(skuIds)) {
            return Collections.emptyMap();
        }
        DataResponse<Map<String, SpuApiCO>> dataResponse = goodsSkuRpcService.mapByIds(skuIds);
        return ResponseUtil.resultValidate(dataResponse);
    }

    /**
     * 批量更新商品库存
     */
    public void updateInventory(List<UpdateInventoryDTO> dtoList) {
        goodsGateway.updateInventory(dtoList);
    }

    /**
     * 获取商品供应商集合
     */
    public Map<String, SupplierDTO> mapSupplierCO() {
        return goodsGateway.mapSupplierCO();
    }

    /**
     * 计算商品购买价格
     *
     * @param skuCO       商品信息
     * @param count       购买数量
     * @param memberLevel 会员等级
     * @param region      购买区域
     * @return 购买价格
     */
    public CalcPayPriceDTO calcPayPrice(SkuCO skuCO, Integer count, Integer memberLevel, String region) {
        //万
        BigDecimal tenThousand = BigDecimal.valueOf(10000);
        //该方法的中的价格单位为分
        //商品原价,原积分
        Long price = BigDecimalUtils.yuan2Penny(skuCO.getPrice());
        Long integral = skuCO.getIntegral();

        //需支付价格,积分,运费
        Long goodsTotalPrice = price;
        Long goodsTotalIntegral = integral;
        Long freight = 0L;

        // 1、计算会员等级差异化
        DiffPriceOption levelDifference = skuCO.getLevelDifference();
        if (levelDifference.enabled()) {
            DiffPriceTmpl.DiffPriceForLevel diffPriceForLevel = levelDifference.getTmpl().getDiffs().stream()
                    .filter(tmpl -> tmpl.getLevel().equals(memberLevel))
                    .findFirst()
                    .get();

            if (DiffPriceMode.PERCENTAGE_DISCOUNT.getValue().equals(levelDifference.getTmpl().getMode())) {
                // 1.1、结算比例调整
                Long percent = diffPriceForLevel.getPercent().multiply(BigDecimal.valueOf(100)).longValue();
                goodsTotalPrice = BigDecimal.valueOf(price * percent).divide(tenThousand, RoundingMode.HALF_UP).longValue();
                // 积分不足1取1
                BigDecimal integralDecimal = BigDecimal.valueOf(integral * percent);
                goodsTotalIntegral = integralDecimal.compareTo(tenThousand) > 0 ?
                        integralDecimal.divide(tenThousand, RoundingMode.HALF_UP).longValue()
                        : integralDecimal.divide(tenThousand, RoundingMode.UP).longValue();
            } else if (DiffPriceMode.EXTRA_PAYMENT.getValue().equals(levelDifference.getTmpl().getMode())) {
                // 1.2、需额外支付
                if (diffPriceForLevel.getExtraPrice() != null) {
                    Long extraPrice = BigDecimalUtils.yuan2Penny(diffPriceForLevel.getExtraPrice());
                    goodsTotalPrice = (price + extraPrice);
                }
                if (diffPriceForLevel.getExtraIntegral() != null) {
                    goodsTotalIntegral = (integral + diffPriceForLevel.getExtraIntegral());
                }
            } else {
                throw new ServiceException("价格结算失败");
            }
        }
        // 购物车结算时,收货地址还没选,选了再计算
        if (StringUtil.isNotEmpty(region)) {
            // 2、计算运费
            ShippingCostOption freeShippingRange = skuCO.getFreeShippingRange();
            if (freeShippingRange.enabled()) {
                UCRegionCacheCO customerRegion = MtdsBaseUCRegionCacheUtils.getUCRegionCacheCOById(region);
                Optional<ShippingCostTmpl.RegionalCost> regionalCostOptional = freeShippingRange.getTmpl().getRegionalCosts().stream()
                        .filter(tmpl -> customerRegion.getPids().contains(tmpl.getRegionId()))
                        .findFirst();

                if (regionalCostOptional.isPresent()) {
                    ShippingCostTmpl.RegionalCost regionalCost = regionalCostOptional.get();
                    // 2.1 满足包邮条件
                    if (regionalCost.getFreeEnabled() == 1 && count >= regionalCost.getFreeQty()) {
                        freight = 0L;
                    } else {
                        // 2.2 计算运费
                        if (count <= regionalCost.getBaseQty()) {
                            freight = freight + BigDecimalUtils.yuan2Penny(regionalCost.getBasePrice());
                        } else {
                            freight = freight + BigDecimalUtils.yuan2Penny(regionalCost.getBasePrice());

                            int increaseCount = (count - regionalCost.getBaseQty());
                            long extraFreight = BigDecimalUtils.yuan2Penny(regionalCost.getIncreasePrice())
                                    * increaseCount;
                            freight = freight + (extraFreight);
                        }
                    }
                }
            }
        }

        //支付金额
        Long payPrice = (goodsTotalPrice * count) + freight;
        return CalcPayPriceDTO.builder()
                .skuId(Long.valueOf(skuCO.getId()))
                .oldGoodsTotalPrice(price * count)
                .goodsTotalPrice(goodsTotalPrice * count)
                .payPrice(payPrice)
                .freight(freight)
                .oldGoodsTotalIntegral(integral * count)
                .goodsTotalIntegral(goodsTotalIntegral * count)
                .build();
    }
}
@Slf4j
@Component
public class GoodsGatewayImpl implements GoodsGateway {
    @Autowired
    private GoodsSkuRpcService goodsSkuRpcService;
    @Autowired
    private GoodsSupplierRpcService supplierRpcService;

    @Override
    public void updateInventory(List<UpdateInventoryDTO> dtoList) {
        List<SkuIncrementCmd> skuIncrementCmds = BeanToolkit.instance().copyList(dtoList, SkuIncrementCmd.class);
        Response response = goodsSkuRpcService.increment(skuIncrementCmds);
        if (!response.getStatus()) {
            throw new RpcErrorException(response.getMessage(), "商品");
        }
    }

    @Override
    public Map<String, SupplierDTO> mapSupplierCO() {
        DataResponse<List<SupplierCO>> response = supplierRpcService.listAll();
        List<SupplierCO> supplierCOS = ResponseUtil.resultValidate(response);
        if (CollUtil.isEmpty(supplierCOS)) {
            return Collections.emptyMap();
        }

        List<SupplierDTO> supplierDTOS = BeanToolkit.instance().copyList(supplierCOS, SupplierDTO.class);
        return supplierDTOS.stream().collect(Collectors.toMap(SupplierDTO::getId, Function.identity()));
    }
}

 

标签:体系,DataResponse,return,id,商品,之产,收藏,public,商城
From: https://www.cnblogs.com/cgli/p/17280122.html

相关文章

  • 盲盒商城功能讲解,盲盒商城软件开发
    盲盒商城app有哪些,盲盒商城小程序有哪些,盲盒商城软件开发多少钱,盲盒商城软件开发公司哪家好,类似魔点APP开发,类似魔点APP开发多少钱,类似魔点软件OEM开发,盲盒商城软件开发,盲盒商城小程序开发,盲盒商城app开发,盲盒商城平台搭建随着科技的不断发展,越来越多的人开始使用智能手机,......
  • 《很多反相吧友的知识体系,既没深度,也没广度》 回复
    《很多反相吧友的知识体系,既没深度,也没广度》      https://tieba.baidu.com/p/8325085511      @真Djh801   在 36 楼回复里说   “单叶红枫:回复Ehg2000:对,你说对了。迈-实验实际就只是一个验证地球上光速各向相同性的实验。而不能作......
  • 曼孚科技获ISO45001职业健康安全管理体系认证,标准化管理进入新阶段
    近日,经第三方专业认证机构全面、严苛审核,曼孚科技正式通过ISO45001职业健康安全管理体系认证,认证范围包括人工智能行业数据处理服务等领域。ISO45001职业健康安全管理体系是上世纪80年代后期,于国际上兴起的一种现代安全生产管理模式,它与ISO9001和ISO14001等管理体系一并称为后工......
  • 常见的体系认证都适用哪些企业?
    常见的体系认证都适用哪些企业?ISO9001质量管理体系01ISO9001标准是一个放之四海皆准的东西,这并不是说它有多么万能,而是因为9001是一个基础型的标准,是西方质量管理科学的精华,生产型的企业适用,服务性行业、中介公司、销售公司等也都适用,因为讲究质量都是共通的。一般来说,ISO9001标......
  • ISO三体系认证标准的相同点和不同点?
    ISO三体系认证标准的相同点和不同点?三体系标准的相同点和不同点实施ISO9001、ISO14001、ISO45001三个体系标准的相同点和不同点导读:ISO三体系是企业的万金油,各行各业的招投标都需要ISO三体系资质证书,企业如未申请ISO三体系证书,尽快申请,以备将来之需。ISO三体系认证的效益1、......
  • 容器云平台监控告警体系(三)—— 使用Prometheus Operator部署并管理Prometheus Server
    1、概述 PrometheusOperator是一种基于Kubernetes的应用程序,用于管理Prometheus实例和相关的监控组件。它是由CoreOS开发的开源工具,旨在简化Prometheus的部署和配置。容器云平台通过使用PrometheusOperator简化在Kubernetes下部署和管理Prmetheus的复杂度,其通过prome......
  • 常见的体系认证都适用哪些企业?
    常见的体系认证都适用哪些企业?ISO9001质量管理体系01ISO9001标准是一个放之四海皆准的东西,这并不是说它有多么万能,而是因为9001是一个基础型的标准,是西方质量管理科学的精华......
  • 设备维修国际体系
    苏联体系英国体系日本4.TPM设备全面维修(一个体系重点)5.来源《设备管理新模式》......
  • 神策数据:五步构建企业 CDP 全域用户关联数据体系
    企业CDP即企业客户数据平台,可以帮助企业实现全域用户数据采集和数据管理,使企业能够更加全面地洞察用户行为、深入分析用户需求,最终通过自动化营销方式为用户提供个性化体......
  • [软件体系结构/架构]零拷贝技术(Zero-copy)[转发]
    0前言近期遇到难题:1个大数据集的查询导出API,因从数据库查询后占用内存极大,每次调用将消耗近100MB的JVM内存资源。故现需考虑研究和应用零拷贝技术。如下全文摘自:看一......