一、前置工作
1.1. 将gulimall-member
注册到nacos
spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848application:name: gulimall-member
1.2.@EnableDiscoveryClient
开启服务注册功能
1.3. 网关配置路由关系
二、完善接口
2.1. 获取分类关联的品牌
2.2. 开发顺序
Controller:处理请求,接受和校验数据Service接受controller传来的数据,进行业务处理Controller接受Service处理完的数据,封装页面指定的vo2.3. 获取分类下所有分组&关联属性
2.4. 商品新增
2.4.1. 逆向生成vo
将添加的数据在/json/json2java.html
可以生成对应JavaBean,放到vo文件夹中,最为数据传递承载。
注意:生成的数据中,涉及小数的数据double
类型改为BigDecimal
2.4.2. 保存spu基本信息
对应数据表:pms_spu_info
SpuInfoEntity infoEntity = new SpuInfoEntity();BeanUtils.copyProperties(vo, infoEntity);infoEntity.setCreateTime(new Date());infoEntity.setUpdateTime(new Date());this.saveBaseSpuInfo(infoEntity);
2.4.3. 保存Spu的描述图片
对应数据表:pms_spu_info_desc
List<String> decript = vo.getDecript();SpuInfoDescEntity descEntity = new SpuInfoDescEntity();descEntity.setSpuId(infoEntity.getId());descEntity.setDecript(String.join(",", decript));spuInfoDescService.saveSpuInfoDesc(descEntity);
2.4.4. 保存spu的图片集
对应数据表:pms_spu_images
List<String> images = vo.getImages();imagesService.saveImages(infoEntity.getId(), images);
2.4.5. 保存spu的规格参数
对应数据表:pms_product_attr_value
List<BaseAttrs> baseAttrs = vo.getBaseAttrs();List<ProductAttrValueEntity> collect = baseAttrs.stream().map(attr -> {ProductAttrValueEntity valueEntity = new ProductAttrValueEntity();valueEntity.setAttrId(attr.getAttrId());AttrEntity id = attrService.getById(attr.getAttrId());valueEntity.setAttrName(id.getAttrName());valueEntity.setAttrValue(attr.getAttrValues());valueEntity.setQuickShow(attr.getShowDesc());valueEntity.setSpuId(infoEntity.getId());return valueEntity;}).collect(Collectors.toList());attrValueService.saveProductAttr(collect);
2.4.6. 保存spu的积分信息
对应数据表:gulimall_sms->sms_spu_bounds
Bounds bounds = vo.getBounds();SpuBoundTo spuBoundTo = new SpuBoundTo();BeanUtils.copyProperties(bounds, spuBoundTo);spuBoundTo.setSpuId(infoEntity.getId());R r = couponFeignService.saveSpuBounds(spuBoundTo);if (r.getCode() != 0) {log.error("远程保存spu积分信息失败");}
2.4.7. 保存当前spu对应的所有sku信息
2.4.7.1. sku的基本信息
对应数据表:pms_sku_info
2.4.7.2. sku的图片信息
对应数据表:pms_sku_image
2.4.7.3. sku的销售属性信息
对应数据表:pms_sku_sale_attr_value
2.4.7.4. sku的优惠、满减等信息
对应数据表:gulimall_sms->sms_sku_ladder\sms_sku_full_reduction\sms_member_price
List<Skus> skus = vo.getSkus();if (skus != null && skus.size() > 0) {skus.forEach(item -> {String defaultImg = "";for (Images image : item.getImages()) {if (image.getDefaultImg() == 1) {defaultImg = image.getImgUrl();}}SkuInfoEntity skuInfoEntity = new SkuInfoEntity();BeanUtils.copyProperties(item, skuInfoEntity);skuInfoEntity.setBrandId(infoEntity.getBrandId());skuInfoEntity.setCatalogId(infoEntity.getCatalogId());skuInfoEntity.setSaleCount(0L);skuInfoEntity.setSpuId(infoEntity.getId());skuInfoEntity.setSkuDefaultImg(defaultImg);//7.1)、sku的基本信息;pms_sku_infoskuInfoService.saveSkuInfo(skuInfoEntity);Long skuId = skuInfoEntity.getSkuId();List<SkuImagesEntity> imagesEntities = item.getImages().stream().map(img -> {SkuImagesEntity skuImagesEntity = new SkuImagesEntity();skuImagesEntity.setSkuId(skuId);skuImagesEntity.setImgUrl(img.getImgUrl());skuImagesEntity.setDefaultImg(img.getDefaultImg());return skuImagesEntity;}).filter(entity -> {//返回true就是需要,false就是剔除return !StringUtils.isEmpty(entity.getImgUrl());}).collect(Collectors.toList());//7.2)、sku的图片信息;pms_sku_imageskuImagesService.saveBatch(imagesEntities);//TODO 没有图片路径的无需保存List<Attr> attr = item.getAttr();List<SkuSaleAttrValueEntity> skuSaleAttrValueEntities = attr.stream().map(a -> {SkuSaleAttrValueEntity attrValueEntity = new SkuSaleAttrValueEntity();BeanUtils.copyProperties(a, attrValueEntity);attrValueEntity.setSkuId(skuId);return attrValueEntity;}).collect(Collectors.toList());//7.3)、sku的销售属性信息:pms_sku_sale_attr_valueskuSaleAttrValueService.saveBatch(skuSaleAttrValueEntities);//7.4)、sku的优惠、满减等信息;gulimall_sms->sms_sku_ladder\sms_sku_full_reduction\sms_member_priceSkuReductionTo skuReductionTo = new SkuReductionTo();BeanUtils.copyProperties(item, skuReductionTo);skuReductionTo.setSkuId(skuId);if (skuReductionTo.getFullCount() > 0 || skuReductionTo.getFullPrice().compareTo(new BigDecimal("0")) == 1) {R r1 = couponFeignService.saveSkuReduction(skuReductionTo);if (r1.getCode() != 0) {log.error("远程保存sku优惠信息失败");}}});}
2.4.8. 调用远程服务
注意:
远程服务必须上线,放到注册中心在远程服务必须要开启服务发现和服务注册功能调用者只要在注册中心中,调用正确接口即可
2.4.8.1. 将所有需要远程调用的接口放在feign
包中
2.4.8.2. 使用@FeignClient
声明调用远程服务名称
@FeignClient("gulimall-coupon")
2.4.8.3. 调用者使用@EnableFeignClients
确定远程调用包位置
@EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign")
2.4.8.4. 注入远程调用Service
@AutowiredCouponFeignService couponFeignService;
2.4.8.5. 使用PostMapping
指定远程调用地址
/*** 1、CouponFeignService.saveSpuBounds(spuBoundTo);* 1)、@RequestBody将这个对象转为json。* 2)、找到gulimall-coupon服务,给/coupon/spubounds/save发送请求。* 将上一步转的json放在请求体位置,发送请求;* 3)、对方服务收到请求。请求体里有json数据。* (@RequestBody SpuBoundsEntity spuBounds);将请求体的json转为SpuBoundsEntity;* 只要json数据模型是兼容的。双方服务无需使用同一个to** @param spuBoundTo* @return*/@PostMapping("/coupon/spubounds/save")R saveSpuBounds(@RequestBody SpuBoundTo spuBoundTo);
2.4.8.6. 使用@RequestBody
注解将参数作为请求体传递
@PostMapping("/coupon/skufullreduction/saveinfo")R saveSkuReduction(@RequestBody SkuReductionTo skuReductionTo);
2.4.9. 注意
@TableId
如果数据库字段设成user_id
在初始生成后,在代码中会变成userId,不会设置成主键
使用**@TableId(value=“user_id”,type = IdType.AUTO)**注解
“value”:设置数据库字段值
“type”:设置主键类型、如果数据库主键设置了自增建议使用“AUTO”
type有六种类型类型,最下面三个只有插入主键为空时,才会自动填充
2.4.10. SPU检索
2.4.11. SKU检索
2.5. 项目时间格式化
在application.yml
中配置jackson
的date-format
spring:jackson:date-format: yyyy-MM-dd HH:mm:ss