cloud_mall-notes04

对对对

一、查询详情—getById

请求方式@GetMapping(11) 用途 方法 返回值
@GetMapping(“info”) 查询管理员信息 getById sysUser
@GetMapping(“info/{userId}”) 查询管理员详情 getById sysUser
@GetMapping(“info/{roleId}”) 查询角色详情 getById sysRole
@GetMapping(“info/{categoryId}”) 根据标识查询商品类目详情 getById category
@GetMapping(“info/{tagId}”) 根据标识查询商品分组标签详情 getById prodTag
@GetMapping(“{id}”) 根据标识查询评论详情 getById prodComm
@GetMapping(“info/{prodId}”) 查询商品详情 getById prod
@GetMapping(“info/{id}”) 查询公告详情 getById notice
@GetMapping(“info/{id}”) 查询自提点详情 getById pickAddr
@GetMapping(“info/{id}”) 根据标识查询轮播图详情 getById indexImg
@GetMapping(“addrInfo/{addrId}”) 查询收货地址详情 getById userAddr
@ApiOperation("查询xxxx详情")
@GetMapping("info/{'xxxx'Id}")
@PreAuthorize("hasAuthority('模块权限:权限:info')")
public ResponseEntity<实体类> load'xxxx'Info(@PathVariable Long 'xxxx'Id) {
    
	实体类 domain = 'xxxx'Service.getById('xxxx'Id);
    
	return ResponseEntity.ok(domain);
    
}
@Override
public 实体类 getById(Serializable id) {

    //根据标识查询xxxx详情
    实体类 domain = 'xxxx'Mapper.selectById(id);
	
	// 多表查询
    //根据id查询表1字段与表2字段关系记录list
    List<2实体类> '表2xxxx'List = '表2xxxx'Mapper.selectList(new LambdaQueryWrapper<2实体类>()
            .eq(2实体类::getRoleId, id)
    );
    
    //判断是否有值
    if (!CollectionUtils.isEmpty('表2xxxx'List) && '表2xxxx'List.size() != 0) {
        //从表1字段与表2字段关系集合中获取表2字段的id集合
        List<Long> '表2字段的id集合'List = '表2xxxx'List.stream()
                .map(2实体类::2字段的id)
                .collect(Collectors.toList());1domain.set'表2字段的id'List('2字段的id集合'List);
    }
    
    return1domain;
}

二、多条件分页查询—page

请求方式@GetMapping(9) 用途 方法 返回值
@GetMapping(“page”) 多条件分页查询管理员列表 page page
@GetMapping(“page”) 多条件分页查询角色列表 page page
@GetMapping(“page”) 多条件分页查询商品分组标签列表 page page
@GetMapping(“page”) 多条件分页查询商品规格列表 page page
@GetMapping(“page”) 多条件分页查询商品评论列表 page page
@GetMapping(“page”) 多条件分页查询商品列表 page page
@GetMapping(“page”) 多条件分页查询公告列表 page page
@GetMapping(“page”) 多条件分页查询自提点列表 page page
@GetMapping(“page”) 多条件分页查询轮播图列表 page page
@ApiOperation("多条件分页查询xxxx")
@GetMapping("page")
@PreAuthorize("hasAuthority('模块权限:权限:page')")
public ResponseEntity<Page<实体类>> load'xxxx'Page(Page<实体类> page,实体类 domain) {
    page = 'xxxx'Service.page(page,new LambdaQueryWrapper<实体类>()
    		.like(条件)
            .eq(条件)
            .orderByDesc(条件)
    );
    return ResponseEntity.ok(page);
}

三、查询集合(列表)—list

请求方式@GetMapping(17) 用途 方法 返回值
@GetMapping(“list”) 查询系统角色集合 list list
@GetMapping(“table”) 查询商品类目集合 list list
@GetMapping(“listCategory”) 查询商品一级类目集合 list list
@GetMapping(“category/categoryInfo”) 根据类目父节点查询子节点集合(微信) list list
@GetMapping(“listTagList”) 查询商品分组标签集合 list list
@GetMapping(“prodTagList”) 查询小程序商品分组标签集合(微信) list list
@GetMapping(“list”) 查询商品规格的属性列表 list list
@GetMapping(“listSpecValue/{propId}”) 查询商品属性对应的规格属性值集合 list list
@GetMapping(“topNoticeList”) 查询小程序置顶公告列表(微信) selectTopNoticeList list
@GetMapping(“noticeList”) 查询小程序所有公告列表(微信) list list
@GetMapping(“list”) 查询全国地址列表 list list
@GetMapping(“listByPid”) 根据父节点查询地区子节点集合 list list
@GetMapping(“indexImgs”) 查询小程序轮播图列表(微信小程序数据接口) list list
@GetMapping(“prods”) 查询用户收藏商品列表 selectUserCollectionProdList(userId) prodList
@GetMapping(“list”) 查询用户收货地址列表 selectUserAddrList(userId) userAddrList
@GetMapping(“prod/prodListByTagId”) 根据商品分组标签查询商品列表 selectProdListByTagId(tagId,size) prodPage
@GetMapping(“prod/pageProd”) 查询当前类目和子类目的所有商品集合 selectProdListByCategoryId(cateGoryId) prodList
@GetMapping(“info”) 查询用户购物车商品列表 selectUserCartVoInfo cartVo
@ApiOperation("查询xxxx集合")
@GetMapping("list")
@PreAuthorize("hasAuthority('模块权限:权限:list')")
public ResponseEntity<List<实体类>> load'xxxx'List() {
    
    // 1) 获取当前用户
    // String userId = AuthUtil.getLoginUserId();
    
    // 2) 根据商品分组标签查询商品列表
    // Page prodPage = new Page<>(1,size);
    
    
	List<实体类> list = 'xxxx'Service.list();
	return ResponseEntity.ok(list);
}

简单的条件构造:排序,等值查找

@Override
@CacheEvict(key = xxxConstant.xxx_LIST)
public List<实体类> list() {
    return 'xxxx'Mapper.selectList(new LambdaQueryWrapper<实体类>()
    		.eq(条件)
            .orderByDesc(条件)
    );
}

复杂的条件:page分页、远程接口调用

	@Override
    public Page<Prod> selectProdListByTagId(Long tagId, Long size) {
        Page<Prod> prodPage = new Page<>(1,size);
        //远程接口调用:根据分组标识分页查询商品与分组标签的关系
        Page<ProdTagReference> prodTagReferencePage = searchProdTagReferenceFeign.getProdTagReferencePageByTagId(tagId, size);
        //判断空值
        if (ObjectUtil.isNull(prodTagReferencePage)) {
            throw new RuntimeException("服务器开小差了");
        }
        //从商品与分组标签分页对象中获取关系集合
        List<ProdTagReference> prodTagReferenceList = prodTagReferencePage.getRecords();
        //判断是否有值
        if (CollectionUtils.isEmpty(prodTagReferenceList) || prodTagReferenceList.size() == 0) {
            return prodPage;
        }
        //从商品与分组标签的关系集合中获取商品id集合
        List<Long> prodIdList = prodTagReferenceList.stream()
                .map(ProdTagReference::getProdId)
                .collect(Collectors.toList());
        //远程接口调用:根据商品id集合查询商品对象集合
        List<Prod> prodList = searchProdFeign.getProdListByIds(prodIdList);
        if (CollectionUtils.isEmpty(prodList) || prodList.size() == 0) {
            throw new RuntimeException("服务器开小差了");
        }
        //将商品对象集合存放到商品分页对象中
        prodPage.setRecords(prodList);
        return prodPage;
    }

复杂的条件2:循环查询、远程接口

	@Override
    public CartVo selectUserCartVoInfo(String userId) {
        CartVo cartVo = new CartVo();
        //根据用户id查询购物车记录
        List<Basket> basketList = basketMapper.selectList(new LambdaQueryWrapper<Basket>()
                .eq(Basket::getUserId, userId)
                .orderByDesc(Basket::getBasketDate)
        );
        //判断用户购物车记录是否有值
        if (CollectionUtils.isEmpty(basketList) || basketList.size() == 0) {
            return cartVo;
        }

        //创建购物车店铺对象集合
        List<ShopCart> shopCartList = new ArrayList<>();

        //循环遍历购物车记录
        basketList.forEach(basket -> {
            Long basketId = basket.getBasketId();
            Integer basketCount = basket.getBasketCount();
            Long shopId = basket.getShopId();
            Long skuId = basket.getSkuId();


            //判断当前购物车商品的店铺标识是否在之前的店铺对象集合中存在
            List<ShopCart> oneShopCart = shopCartList.stream()
                    .filter(shopCart -> shopCart.getShopId().equals(shopId))
                    .collect(Collectors.toList());
            //如果oneShopCart集合有值:说明当前购物车商品条目对象所在的购物车店铺对象是存在的,否则相反
            if (CollectionUtils.isEmpty(oneShopCart) || oneShopCart.size() == 0) {
                //说明:新的购物车店铺对象
                //创建购物车店铺对象
                ShopCart shopCart = new ShopCart();
                //创建购物车商品条目对象集合
                List<CartItem> cartItemList = new ArrayList<>();
                //创建购物车商品条目对象
                CartItem cartItem = new CartItem();
                cartItem.setBasketId(basketId);
                cartItem.setBasketCount(basketCount);
                //远程接口调用:根据商品skuId查询商品sku对象
                List<Sku> skuList = basketProdFeign.getSkuListByIds(Arrays.asList(skuId));
                if (CollectionUtils.isEmpty(skuList) || skuList.size() == 0) {
                    throw new RuntimeException("服务器开小差了");
                }
                Sku sku = skuList.get(0);
                //将商品sku对象对应的属性值copy到购物车商品条目对象属性中
                BeanUtils.copyProperties(sku,cartItem);

                cartItemList.add(cartItem);
                shopCart.setShopId(shopId);
                shopCart.setShopCartItems(cartItemList);
                shopCartList.add(shopCart);
            } else {
                //说明:存在,获取之前的购物车店铺对象
                //获取之前的购物车店铺对象
                ShopCart shopCart = oneShopCart.get(0);
                //获取当前购物车记录所在的购物车店铺对象的商品条目对象集合
                List<CartItem> shopCartItems = shopCart.getShopCartItems();
                //将当前购物车记录的商品条目对象添加到之前的集合中
                //创建购物车商品条目对象
                CartItem cartItem = new CartItem();
                cartItem.setBasketId(basketId);
                cartItem.setBasketCount(basketCount);
                //远程接口调用:根据商品skuId查询商品sku对象
                List<Sku> skuList = basketProdFeign.getSkuListByIds(Arrays.asList(skuId));
                if (CollectionUtils.isEmpty(skuList) || skuList.size() == 0) {
                    throw new RuntimeException("服务器开小差了");
                }
                Sku sku = skuList.get(0);
                //将商品sku对象对应的属性值copy到购物车商品条目对象属性中
                BeanUtils.copyProperties(sku,cartItem);
                shopCartItems.add(cartItem);

                shopCart.setShopCartItems(shopCartItems);
            }
        });

        cartVo.setShopCarts(shopCartList);
        return cartVo;
    }

四、查询数量(一条、多条)—one、count、page

请求方式@GetMapping(9) 用途 方法 返回值
@GetMapping(“prodComm/prodCommData”) 根据产品标识查询商品评论总览信息(微信) selectProdCommOverview(prodId) prodCommOverview
@GetMapping(“prodComm/prodCommPageByProd”) 根据商品标识分页查询商品评论列表(微信) selectProdCommPageByProdId page
(prodId,evaluate,page)
@GetMapping(“prod/prodInfo”) 查询商品详情(包含商品sku集合)(微信) selectProdDetailInfo(prodId) prod
@GetMapping(“info/detail/{id}”) 查询公告详情(微信) getById(id) notice
@GetMapping(“isBindPhone”) 查询用户是否绑定手机号码 getOne StringUtils.hasText
@GetMapping(“count”) 查询当前用户收藏商品的数量 count count
@GetMapping(“isCollection”) 查询商品是否被用户收藏 getOne ObjectUtil.isNotNull
@GetMapping(“orderCount”) 查询用户订单状态数量 selectUserOrderStatusCount(userId) orderStatusCount
@GetMapping(“prodCount”) 查询用户购物车中商品的数量 selectUserBasketCount(userId) count

4.1 one:

@ApiOperation("查询是否xxxx")
@GetMapping("is'xxxx'")
public ResponseEntity<Boolean> loadIs'xxxx'() {
    // 获取当前用户
    String userId = AuthUtil.getLoginUserId();
    
    // 操作
    实体类 domain = 'xxxx'Service.getOne(new LambdaQueryWrapper<实体类>()
            .eq(条件)
    );
    
    return ResponseEntity.ok(StringUtils.hasText(判断是否'xxxx');
    // return ResponseEntity.ok(ObjectUtil.isNotNull(判断是否'xxxx')
}

4.2 count:

简单的:

@ApiOperation("查询xxxx的数量")
@GetMapping("count")
public ResponseEntity<Integer> load'xxxx'Count() {
    String userId = AuthUtil.getLoginUserId();
    int count = 'xxxx'Service.count(new LambdaQueryWrapper<实体类>()
            .eq(条件)
    );
    return ResponseEntity.ok(count);
}

复杂的:

@ApiOperation("查询xxxx数量")
@GetMapping("'xxxx'Count")
public ResponseEntity<实体类> load'xxxx'Count() {
    String userId = AuthUtil.getLoginUserId();
    实体类 domain = 'xxxx'Service.select'xxxx'Count(userId);
    return ResponseEntity.ok(domain);
}
@Override
public OrderStatusCount selectUserOrderStatusCount(String userId) {
    //查询待支付数量
    Integer unpay = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
            .eq(Order::getUserId, userId)
            .eq(Order::getStatus, 1)
    );

    //查询待发货数量
    Integer payed = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
            .eq(Order::getUserId, userId)
            .eq(Order::getStatus, 2)
    );

    //查询待收货数量
    Integer consignment = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
            .eq(Order::getUserId, userId)
            .eq(Order::getStatus, 3)
    );

    return OrderStatusCount.builder()
            .unPay(unpay)
            .payed(payed)
            .consignment(consignment)
            .build();
}
@Override
public Integer selectUserBasketCount(String userId) {
    List<Object> objs = basketMapper.selectObjs(new QueryWrapper<Basket>()
            .select("ifnull(sum(basket_count),0)")
            .eq("user_id", userId)
    );
    Object o = objs.get(0);
    return Integer.valueOf(o.toString());
}

4.3 page:

@ApiOperation("根据表1xxxx分页查询表2xxxx")
@GetMapping("'表2xxxx'/'表2xxxx'PageByProd")
public ResponseEntity<Page<2实体类>> load'表2xxxx'PageByProdId(Long '表1xxxx',Long evaluate,Page<'表2xxxx'实体类> page) {
    page = '表2xxxx'Service.select'表2xxxx'PageBy'表1xxxx'('表1xxxx',evaluate,page);
    return ResponseEntity.ok(page);
}
@Override
public Page<ProdComm> selectProdCommPageByProdId(Long prodId, Long evaluate, Page<ProdComm> page) {
    //根据条件分页查询商品评论
    page = prodCommMapper.selectPage(page,new LambdaQueryWrapper<ProdComm>()
            .eq(ProdComm::getProdId,prodId)
            .eq(ProdComm::getStatus,1)
            .eq(0==evaluate||1==evaluate||2==evaluate,ProdComm::getEvaluate,evaluate)
            .isNotNull(3==evaluate,ProdComm::getPics)
            .orderByDesc(ProdComm::getRecTime)
    );
    //从商品评论分页对象中获取评论记录
    List<ProdComm> prodCommList = page.getRecords();
    //判断是否有值
    if (CollectionUtils.isEmpty(prodCommList) || prodCommList.size() == 0) {
        return page;
    }
    //从评论记录集合中获取用户id
    List<String> userIdList = prodCommList.stream().map(ProdComm::getUserId).collect(Collectors.toList());
    //远程接口:根据用户id集合查询用户对象集合
    List<User> userList = prodCommUserFeign.getUserListByUserIds(userIdList);
    if (CollectionUtils.isEmpty(userList) || userList.size() == 0) {
        throw new RuntimeException("服务器开小差了");
    }
    //循环遍历评论集合
    prodCommList.forEach(prodComm -> {
        //从用户对象集合中过滤出与当前评论中的用户id一致的用户对象
        User user1 = userList.stream()
                .filter(user -> user.getUserId().equals(prodComm.getUserId()))
                .collect(Collectors.toList()).get(0);
        //获取用户昵称
        StringBuffer nickName = new StringBuffer(user1.getNickName());
        nickName.replace(1,nickName.length()-1,"***");
        prodComm.setNickName(nickName.toString());
        prodComm.setPic(user1.getPic());
    });
    return page;
}

==============================================================================================================

五、新增—save

请求方式@PostMapping(10) 用途 方法 返回值
@PostMapping 新增管理员 save
@PostMapping 新增角色 save
@PostMapping 新增商品类目 save
@PostMapping 新增商品分组标签 save
@PostMapping 新增商品规格 save
@PostMapping 新增商品 save
@PostMapping 新增公告 save
@PostMapping 新增自提点 save
@PostMapping 新增轮播图 save
@PostMapping(“addAddr”) 新增用户收货地址 save
@ApiOperation("新增xxxx")
@PostMapping
@PreAuthorize("hasAuthority('模块权限:权限:save')")
@Log(operation = "新增xxxx")
public ResponseEntity<Void> save'xxxx'(@RequestBody 实体类 domain) {
	// 获取当前用户
    //String userId = AuthUtil.getLoginUserId();
    //domain.setUserId(Long.valueof(userId));

	// 执行业务
    'xxxx'Service.save(domain);

	// 响应
    return ResponseEntity.ok().build();
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
@CacheEvict(key = xxxConstant.xxx)
public boolean save(实体类 domain) {
    // 1、补充一些信息
    //1) 时间
    domain.setCreateTime(new Date());
    domain.setUpdateTime(new Date());
    //2) 密码加密(新增用户需要)
    sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
    //3) 状态、版本号
    domain.setStatus(1);
    domain.setVersion(1);
    //4) 分类层级
    domain.setGrade(1);
    //5) 初始数量为0
    domain.setXxxCount(0L);
    
    // 2、校验和处理
	// 比如添加用户收货地址时,会判断有没有默认收获地址,没有则默认将该新增地址设置为默认收货地址
    
    // 3、将上面补充的信息,利用mybatis新增对象
    int i = 'xxxx'Mapper.insert(domain);

	// 4、如果新增这个对象,在表中的属性有多表操作
    if (i > 0) {
        // 比如新增一个用户,这个用户表和角色表还有一个用户角色表(3张表)
        // 除了操作sys_user表外,还要操作sys_user_role表
        ...
        }
    }
    return i > 0;
}

六、增与删、map、消息队列、远程调用、延迟队列、计算

请求方式@PostMapping 用途 方法 返回值
@PostMapping(“addOrCancel”) 添加或取消用户收藏商品 addOrCancelCollection(userId,prodId)
@PostMapping(“send”) 获取短信验证码 sendPhoneCode(map) “发送成功”
@PostMapping(“savePhone”) 绑定用户手机号码 savePhone(map)
@PostMapping(“confirm”) 用户订单确认页面 selectUserOrderConfirm(userId,orderConfirmParam) orderVo
@PostMapping(“submit”) 用户提交订单 submitOrder(userId,orderVo) orderNumber
@PostMapping(“totalPay”) 计算购物车中选中商品的金额 calculateCartTotalAmount(basketIdList) cartTotalAmount
@PostMapping(“changeItem”) 添加商品到购物车或修改购物车中商品数量 changeItem(basket)

6.1 addOrCancel:

@ApiOperation("添加或取消xxxx")
@PostMapping("addOrCancel")
public ResponseEntity<Void> addOrCancelxxxx(@RequestBody Long 'xxxx'Id) {
    String userId = AuthUtil.getLoginUserId();
    'xxxx'Service.addOrCancel'xxxx'(userId,'xxxx'Id);
    return ResponseEntity.ok().build();
}
@Override
public void addOrCancelCollection(String userId, Long 'xxxx'Id) {
    
    //根据用户标识和'xxxx'id查询记录
    实体类 domain = 'xxxx'Mapper.selectOne(new LambdaQueryWrapper<实体类>()
            .eq(条件userId)
            .eq(条件'xxxx'Id)
    );
    
    //判断是否有值
    if (ObjectUtil.isNull(domain)) {
        //没有:添加'xxxx'
        
        // 完整对象,添加Id,时间,版本,标识等信息
        domain = new 实体类();
        domain.setUserId(userId);
        domain.set'xxxx'Id('xxxx'Id);
        domain.setCreateTime(new Date());
        
        'xxxx'Mapper.insert(domain);
        return;
    }
    //有:取消'xxxx'
    'xxxx'Mapper.deleteById(domain.getId());
}

6.2 map对象:绑定save

@ApiOperation("绑定用户手机号码")
@PostMapping("savePhone")
public ResponseEntity<Void> savePhone(@RequestBody Map<String,Object> map) {
    
    String userId = AuthUtil.getLoginUserId();
    
    map.put("userId",userId);
    
    userService.savePhone(map);
    
    return ResponseEntity.ok().build();
}
@Override
public void savePhone(Map<String, Object> map) {
    
    //从map对象里提取需要的信息(电话,验证码,用户)
    String phone = (String) map.get("phonenum");
    String code = (String) map.get("code");
    String userId = (String) map.get("userId");
    
    //从redis中获取短信
    String redisCode = stringRedisTemplate.opsForValue().get(phone);
    
    //比较是否一致
    if (!code.equals(redisCode)) {
        throw new RuntimeException("验证码不一致");
    }
    
    User user = new User();
    user.setUserMobile(phone);
    
    userMapper.update(user,new LambdaQueryWrapper<User>()
            .eq(User::getUserId,userId)
    );

}

6.3 rabbit消息队列处理:获取

@ApiOperation("获取短信验证码")
@PostMapping("send")
public ResponseEntity<String> sendPhoneCode(@RequestBody Map<String,Object> map) {
    String userId = AuthUtil.getLoginUserId();
    map.put("useId",userId);
    sendService.sendPhoneCode(map);
    return ResponseEntity.ok("发送成功");
}
@Override
public void sendPhoneCode(Map<String, Object> map) {
    
    String phonenum = (String) map.get("phonenum");
    
    //准备参数
    // 1)生成随机数字
    String code = generateCode(4);
    
    // 2)将生成的随机数字存放到redis缓存中
    stringRedisTemplate.opsForValue().set(phonenum,code,5, TimeUnit.MINUTES);
    map.put("code",code);

    // 3)将参数转换为json格式的字符串存放到消息队列中
    rabbitTemplate.convertAndSend(QueueConstant.PHONE_CODE_QUEUE, JSON.toJSONString(map));

}

private String generateCode(int count) {
    return RandomUtil.randomNumbers(count);
}

6.4 确认confirm(远程接口调用):

@ApiOperation("用户xxxx确认页面")
@PostMapping("confirm")
public ResponseEntity<实体类> loadUser'xxxx'Confirm(@RequestBody 'Xxxx'ConfirmParam 'xxxx'ConfirmParam) {
    String userId = AuthUtil.getLoginUserId();
    实体类 domain = 'xxxx'Service.selectUser'xxxx'Confirm(userId,'xxxx'ConfirmParam);
    return ResponseEntity.ok(domain);
}

(远程接口Feign):

@FeignClient(value = "member-service")  // 调用的模块,上面那个是order-server模块
public interface OrderUserAddrFeign {

    @GetMapping("p/address/getUserDefaultAddr")
    UserAddr getUserDefaultAddr(@RequestParam String userId);
}
@FeignClient(value = "cart-service")
public interface OrderBasketFeign {

    @GetMapping("p/shopCart/getBasketListByIds")
    List<Basket> getBasketListByIds(@RequestParam List<Long> ids);

    @PostMapping("p/shopCart/deleteUserBasket")
    Boolean deleteUserBasket(@RequestBody Map<String,Object> map);
}
@FeignClient(value = "product-service")
public interface OrderProdFeign {

    @GetMapping("prod/prod/getSkuListByIds")
    List<Sku> getSkuListByIds(@RequestParam List<Long> ids);

    @PostMapping("prod/prod/updateProdAndSkuStock")
    void updateProdAndSkuStock(@RequestBody ChangeStock changeStock);
}

(远程接口实现FeignHystrix):

@Component
@Slf4j
public class OrderUserAddrFeignHystrix implements OrderUserAddrFeign {
    @Override
    public UserAddr getUserDefaultAddr(String userId) {
        log.error("查询用户默认收货地址失败");
        return null;
    }
}
@Component
@Slf4j
public class OrderBasketFeignHystrix implements OrderBasketFeign {
    @Override
    public List<Basket> getBasketListByIds(List<Long> ids) {
        log.error("根据购物车标识查询购物车对象集合失败");
        return null;
    }

    @Override
    public Boolean deleteUserBasket(Map<String, Object> map) {
        log.error("根据用户id和商品skuId删除购物车中记录失败");
        return null;
    }
}
@Component
@Slf4j
public class OrderProdFeignHystrix implements OrderProdFeign {
    @Override
    public List<Sku> getSkuListByIds(List<Long> ids) {
        log.error("根据商品skuId集合查询商品sku对象集合");
        return null;
    }

    @Override
    public void updateProdAndSkuStock(ChangeStock changeStock) {
        log.error("修改商品prod和sku库存数量失败");
    }
}

serviceimpl:

@Override
public OrderVo selectUserOrderConfirm(String userId, OrderConfirmParam orderConfirmParam) {
    OrderVo orderVo = new OrderVo();
    //远程调用:查询当前用户的默认收货地址
    UserAddr userDefaultAddr = orderUserAddrFeign.getUserDefaultAddr(userId);
    orderVo.setUserAddr(userDefaultAddr);
    //获取参数对象中的购物车id集合
    List<Long> basketIds = orderConfirmParam.getBasketIds();
    //判断是否有值
    if (CollectionUtils.isEmpty(basketIds) || basketIds.size() == 0) {
        //说明:请求来自于商品详情页面
        productToConfirm(orderVo,userId,orderConfirmParam.getOrderItem());
    } else {
        //说明:请求来自于购物车页面
        orderVo.setSource(1);
        cartToConfirm(orderVo,userId,basketIds);
    }

    return orderVo;
}

private void cartToConfirm(OrderVo orderVo, String userId, List<Long> basketIds) {
    //远程接口调用:根据购物车id集合查询购物车对象集合
    List<Basket> basketList = orderBasketFeign.getBasketListByIds(basketIds);
    if (CollectionUtils.isEmpty(basketList) || basketList.size() == 0) {
        throw new RuntimeException("服务器开小差了");
    }
    //从购物车对象集合中获取商品skuId集合
    List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
    //根据商品skuId集合查询商品sku对象集合
    List<Sku> skuList = orderProdFeign.getSkuListByIds(skuIdList);
    if (CollectionUtils.isEmpty(skuList) || skuList.size() == 0) {
        throw new RuntimeException("服务器开小差了");
    }

    List<BigDecimal> oneSkuTotalAmounts = new ArrayList<>();
    List<Integer> oneSkuCounts = new ArrayList<>();

    //根据店铺标识将购物车对象集合进行分组
    Map<Long, List<Basket>> allShopOrderMap = basketList.stream().collect(Collectors.groupingBy(Basket::getShopId));
    //创建订单店铺对象集合
    List<ShopOrder> shopOrderList = new ArrayList<>();
    //循环所有订单店铺集合
    allShopOrderMap.forEach((shopId,baskets) -> {
        //创建订单店铺对象
        ShopOrder shopOrder = new ShopOrder();
        //创建订单商品条目对象集合
        List<OrderItem> orderItemList = new ArrayList<>();
        //循环遍历当前店铺的购物车记录集合
        for(Basket basket:baskets){
            //创建订单商品条目对象
            OrderItem orderItem = new OrderItem();

            orderItem.setShopId(shopId);
            orderItem.setUserId(userId);
            orderItem.setRecTime(new Date());
            orderItem.setBasketDate(basket.getBasketDate());
            orderItem.setCommSts(0);
            //获取商品skuId
            Long skuId = basket.getSkuId();
            //从商品sku对象集合中过滤出与当前购物车记录中的商品skuId一致商品sku对象
            Sku sku1 = skuList.stream()
                    .filter(sku -> sku.getSkuId().equals(skuId))
                    .collect(Collectors.toList()).get(0);
            //将商品sku1对象属性值copy到订单商品条目对象中去
            BeanUtils.copyProperties(sku1,orderItem);
            Integer basketCount = basket.getBasketCount();
            orderItem.setProdCount(basketCount);
            oneSkuCounts.add(basketCount);
            //计算单个商品总金额
            BigDecimal oneSkuTotalAmount = sku1.getPrice().multiply(new BigDecimal(basketCount));
            oneSkuTotalAmounts.add(oneSkuTotalAmount);
            orderItem.setProductTotalAmount(oneSkuTotalAmount);

            orderItemList.add(orderItem);
        }

        shopOrder.setShopCartItemDiscounts(orderItemList);
        shopOrderList.add(shopOrder);
    });

    //计算商品总数量
    Integer allSkuCount = oneSkuCounts.stream().reduce(Integer::sum).get();
    BigDecimal allSkuTotalAmount = oneSkuTotalAmounts.stream().reduce(BigDecimal::add).get();

    orderVo.setTotalCount(allSkuCount);
    orderVo.setTotal(allSkuTotalAmount);
    orderVo.setActualTotal(allSkuTotalAmount);
    //计算运费
    if (allSkuTotalAmount.compareTo(new BigDecimal(99)) == -1) {
        orderVo.setTransfee(new BigDecimal(6));
        orderVo.setActualTotal(allSkuTotalAmount.add(new BigDecimal(6)));
    }
    orderVo.setShopCartOrders(shopOrderList);
}

private void productToConfirm(OrderVo orderVo, String userId, OrderItem orderItem) {
    //创建订单店铺对象集合
    List<ShopOrder> shopOrderList = new ArrayList<>();
    //创建订单店铺对象
    ShopOrder shopOrder = new ShopOrder();
    //创建订单商品条目对象集合
    List<OrderItem> orderItemList = new ArrayList<>();
    //补充订单商品条目对象信息
    orderItem.setUserId(userId);
    orderItem.setRecTime(new Date());
    orderItem.setCommSts(0);
    //获取商品skuId
    Long skuId = orderItem.getSkuId();
    //远程接口调用:根据商品skuId查询商品sku对象
    List<Sku> skuList = orderProdFeign.getSkuListByIds(Arrays.asList(skuId));
    if (CollectionUtils.isEmpty(skuList) || skuList.size() == 0) {
        throw new RuntimeException("服务器开小差了");
    }
    Sku sku = skuList.get(0);
    //将商品sku对象的属性值copy到商品条目对象中去
    BeanUtils.copyProperties(sku,orderItem);
    Integer prodCount = orderItem.getProdCount();
    //计算单个商品总金额
    BigDecimal oneSkuTotalAmount = sku.getPrice().multiply(new BigDecimal(prodCount));
    orderItem.setProductTotalAmount(oneSkuTotalAmount);

    orderItemList.add(orderItem);
    shopOrder.setShopCartItemDiscounts(orderItemList);
    shopOrderList.add(shopOrder);
    orderVo.setShopCartOrders(shopOrderList);
    orderVo.setTotal(oneSkuTotalAmount);
    orderVo.setActualTotal(oneSkuTotalAmount);
    orderVo.setTotalCount(prodCount);
    //计算运费
    if (oneSkuTotalAmount.compareTo(new BigDecimal(99)) == -1) {
        orderVo.setTransfee(new BigDecimal(6));
        orderVo.setActualTotal(oneSkuTotalAmount.add(new BigDecimal(6)));
    }
}

6.5 提交submit:延迟队列

@ApiOperation("用户提交订单")
@PostMapping("submit")
public ResponseEntity<String> submitOrder(@RequestBody OrderVo orderVo) {
    String userId = AuthUtil.getLoginUserId();
    String orderNumber = orderService.submitOrder(userId,orderVo);
    return ResponseEntity.ok(orderNumber);
}

serviceimpl:

/**
 * 用户提交订单:
 * 1.判断请求的来源,是否要清除购物车中的记录
 * 2.修改商品prod和sku的库存数量 -> 返回扣减商品库存数量对象
 * 3.生成订单(写数据到order和order_item表)
 * 4.写延迟队列(解决:订单超时未支付问题)
 *
 *
 * @param userId
 * @param orderVo
 * @return
 */
@Override
@Transactional(rollbackFor = RuntimeException.class)
public String submitOrder(String userId, OrderVo orderVo) {
    //获取订单请求来源
    Integer source = orderVo.getSource();
    //判断订单来源
    if (1 == source) {
        //说明:订单请求来自于购物车页面,所以我们需要将用户购买的商品从购物车中清除掉
        deleteUserCart(userId,orderVo);
    }

    //修改商品prod和sku库存数量-> 返回商品prod和sku扣减库存数量对象
    ChangeStock changeStock = changeProdAndSkuStock(orderVo);

    //生成全局唯一的订单编号:使用雪花算法
    String orderNumber = generateOrderNumber();
    //写订单(写订单表和订单商品条目表)
    writeOrder(userId,orderNumber,orderVo);
    //写延迟队列
    sendMsMsg(orderNumber,changeStock);
    return orderNumber;
}

private void sendMsMsg(String orderNumber, ChangeStock changeStock) {
    //将数据转换为json格式的字符串
    JSONObject jsonObject = new JSONObject();
    jsonObject.put("orderNumber",orderNumber);
    jsonObject.put("changeStock",changeStock);
    //将数据json对象转换为json格式的字符串存放到消息队列
    rabbitTemplate.convertAndSend(QueueConstant.ORDER_MS_QUEUE,jsonObject.toJSONString());
}

@Transactional(rollbackFor = RuntimeException.class)
public void writeOrder(String userId, String orderNumber, OrderVo orderVo) {
    StringBuffer prodNames = new StringBuffer();
    List<OrderItem> allOrderItems = new ArrayList<>();
    //获取订单店铺对象集合
    List<ShopOrder> shopOrderList = orderVo.getShopCartOrders();
    //循环遍历订单店铺对象集合
    shopOrderList.forEach(shopOrder -> {
        //获取店铺的商品条目对象集合
        List<OrderItem> orderItemList = shopOrder.getShopCartItemDiscounts();
        //循环遍历店铺订单商品条目对象集合
        orderItemList.forEach(orderItem -> {
            orderItem.setOrderNumber(orderNumber);
            prodNames.append(orderItem.getProdName()).append(",");
            allOrderItems.add(orderItem);
        });
    });
    //批量添加订单商品条目对象集合
    orderItemService.saveBatch(allOrderItems);
    //生成订单表
    Order order = new Order();
    order.setProdName(prodNames.toString());
    order.setUserId(userId);
    order.setOrderNumber(orderNumber);
    order.setTotal(orderVo.getTotal());
    order.setActualTotal(orderVo.getActualTotal());
    order.setPayType(1);
    order.setRemarks(orderVo.getRemark());
    order.setStatus(1);
    order.setFreightAmount(orderVo.getTransfee());
    order.setAddrOrderId(orderVo.getUserAddr().getAddrId());
    order.setProductNums(orderVo.getTotalCount());
    order.setCreateTime(new Date());
    order.setUpdateTime(new Date());
    order.setIsPayed(0);
    order.setDeleteStatus(0);
    order.setRefundSts(0);
    order.setReduceAmount(orderVo.getShopReduce());
    orderMapper.insert(order);
}

private String generateOrderNumber() {
    return snowflake.nextIdStr();
}

private ChangeStock changeProdAndSkuStock(OrderVo orderVo) {

    List<SkuChange> skuChangeList = new ArrayList<>();
    List<ProdChange> prodChangeList = new ArrayList<>();

    //获取订单店铺对象集合
    List<ShopOrder> shopOrderList = orderVo.getShopCartOrders();
    //循环遍历订单店铺对象集合
    shopOrderList.forEach(shopOrder -> {
        //获取店铺的订单商品条目对象集合
        List<OrderItem> orderItemList = shopOrder.getShopCartItemDiscounts();
        //循环遍历店铺订单商品条目对象集合
        orderItemList.forEach(orderItem -> {
            Integer prodCount = orderItem.getProdCount()*-1;
            Long prodId = orderItem.getProdId();
            Long skuId = orderItem.getSkuId();

            //判断当前商品条目对象的商品prodId是否已经存在于商品prod扣减库存数量对象集合中
            List<ProdChange> prodChanges = prodChangeList.stream()
                    .filter(prodChange -> prodChange.getProdId().equals(prodId))
                    .collect(Collectors.toList());
            //判断这个集合是否有值
            if (CollectionUtils.isEmpty(prodChanges) || prodChanges.size() == 0) {
                //说明:当前商品prodId是不存在于商品prod扣减库存数量对象集合中的
                SkuChange skuChange = new SkuChange(skuId, prodCount);
                ProdChange prodChange = new ProdChange(prodId, prodCount);
                skuChangeList.add(skuChange);
                prodChangeList.add(prodChange);
            } else {
                //说明:当前商品prodId是存在于商品prod扣减库存数量对象集合中的
                SkuChange skuChange = new SkuChange(skuId, prodCount);
                skuChangeList.add(skuChange);
                //获取之前的
                ProdChange prodChange = prodChanges.get(0);
                //计算商品扣减库存总数量
                int finalCount = prodChange.getCount() + prodCount;
                prodChange.setCount(finalCount);
            }
        });
    });
    //创建商品prod和sku扣减库存数量对象
    ChangeStock changeStock = new ChangeStock(prodChangeList,skuChangeList);
    //远程调用:修改商品prod和sku库存数量
    orderProdFeign.updateProdAndSkuStock(changeStock);
    return changeStock;
}

private void deleteUserCart(String userId, OrderVo orderVo) {
    List<Long> skuIdList = new ArrayList<>();
    //获取所有的订单店铺对象集合
    List<ShopOrder> shopOrderList = orderVo.getShopCartOrders();
    //循环遍历订单店铺对象集合
    shopOrderList.forEach(shopOrder -> {
        //获取订单店铺对象的订单商品条目对象集合
        List<OrderItem> orderItemList = shopOrder.getShopCartItemDiscounts();
        //循环遍历订单商品条目对象集合(目的:获取每一个订单商品对象的skuId)
        orderItemList.forEach(orderItem -> skuIdList.add(orderItem.getSkuId()));
    });
    //远程接口:删除用户购买商品在购物车中的记录
    Map<String,Object> map = new HashMap<>();
    map.put("userId",userId);
    map.put("skuIdList",skuIdList);
    if (!orderBasketFeign.deleteUserBasket(map)) {
        throw new RuntimeException("用户提交订单:删除购物车中商品失败");
    }
}

6.6 计算总额:TotalAmount

@ApiOperation("计算购物车中选中商品的金额")
@PostMapping("totalPay")
public ResponseEntity<CartTotalAmount> calculateCartTotalAmount(@RequestBody List<Long> basketIdList) {
    CartTotalAmount cartTotalAmount = basketService.calculateCartTotalAmount(basketIdList);
    return ResponseEntity.ok(cartTotalAmount);
}
@Override
public CartTotalAmount calculateCartTotalAmount(List<Long> basketIdList) {
    CartTotalAmount cartTotalAmount = new CartTotalAmount();
    //判断购物车标识集合是否有值
    if (CollectionUtils.isEmpty(basketIdList) || basketIdList.size() == 0) {
        return cartTotalAmount;
    }
    //根据购物车标识查询购物车记录
    List<Basket> basketList = basketMapper.selectBatchIds(basketIdList);
    //从购物车集合中获取商品skuId集合
    List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
    //远程调用:根据商品skuId集合查询商品sku对象集合
    List<Sku> skuList = basketProdFeign.getSkuListByIds(skuIdList);
    if (CollectionUtils.isEmpty(skuList) || skuList.size() == 0) {
        throw new RuntimeException("服务器开小差了");
    }
    List<BigDecimal> oneSkuTotalAmounts = new ArrayList<>();
    //循环遍历购物车集合
    basketList.forEach(basket -> {
        Integer basketCount = basket.getBasketCount();
        Long skuId = basket.getSkuId();
        //从商品sku对象集合中过滤出与当前购物车记录中的商品skuId一致的商品sku对象
        Sku sku1 = skuList.stream()
                .filter(sku -> sku.getSkuId().equals(skuId))
                .collect(Collectors.toList()).get(0);
        //计算单个商品总金额
        BigDecimal oneSkuTotalAmount = sku1.getPrice().multiply(new BigDecimal(basketCount));
        oneSkuTotalAmounts.add(oneSkuTotalAmount);
    });
    //计算所有单个商品总金额的和
    BigDecimal allSkuTotalAmount = oneSkuTotalAmounts.stream().reduce(BigDecimal::add).get();

    cartTotalAmount.setTotalMoney(allSkuTotalAmount);
    cartTotalAmount.setFinalMoney(allSkuTotalAmount);
    //计算运费:单笔金额满99元免运费,否则运费6元
    if (allSkuTotalAmount.compareTo(new BigDecimal(99)) == -1) {
        cartTotalAmount.setTransMoney(new BigDecimal(6));
        cartTotalAmount.setFinalMoney(allSkuTotalAmount.add(new BigDecimal(6)));
    }


    return cartTotalAmount;
}

6.7 添加与修改:change

@ApiOperation("添加商品到购物车或修改购物车中商品数量")
@PostMapping("changeItem")
public ResponseEntity<Void> changeItem(@RequestBody Basket basket) {
    String userId = AuthUtil.getLoginUserId();
    basket.setUserId(userId);
    basketService.changeItem(basket);
    return ResponseEntity.ok().build();
}
@Override
public void changeItem(Basket basket) {
    //根据用户标识和商品skuId查询购物车记录
    Basket oldBasket = basketMapper.selectOne(new LambdaQueryWrapper<Basket>()
            .eq(Basket::getUserId, basket.getUserId())
            .eq(Basket::getSkuId, basket.getSkuId())
    );
    //判断是否有值
    if (ObjectUtil.isNull(oldBasket)) {
        //新增商品到购物车
        basket.setBasketDate(new Date());
        basketMapper.insert(basket);
        return;
    }
    //修改商品在购物车中的数量
    //计算购物车中商品的数量
    int finalCount = oldBasket.getBasketCount() + basket.getBasketCount();
    oldBasket.setBasketCount(finalCount);
    basketMapper.updateById(oldBasket);
}

==============================================================================================================

七、修改—updateById

请求方式@PutMapping 用途 方法 返回值
@PutMapping 修改管理员信息 updateById
@PutMapping 修改角色信息 updateById
@PutMapping 修改商品类目信息 updateById
@PutMapping 修改商品分组标签信息 updateById
@PutMapping 修改商品规格 updateById
@PutMapping 修改商品信息 updateById
@PutMapping 修改公告信息 updateById
@PutMapping 修改自提点信息 updateById
@PutMapping 修改轮播图信息 updateById
@PutMapping 审核并回复商品评论 updateById
@PutMapping(“updateAddr”) 修改收货地址信息 updateById
@ApiOperation("修改xxxx信息")
@PutMapping
@PreAuthorize("hasAuthority('模块权限:权限:update')")
public ResponseEntity<Void> update'xxxx'(@RequestBody 实体类 domain) {
    'xxxx'Service.updateById(domain);
    return ResponseEntity.ok().build();
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
@CacheEvict(key = xxxConstant.xxx)
public boolean updateById(实体类 domain) {

    // 和save操作类似
    // 可能还要获取某些其绑定的一些关系,删除其原先集合
    
    return 'xxxx'Mapper..updateById(domain)>0;
}
请求方式@PutMapping 用途 方法 返回值
@PutMapping(“setUserInfo”) 更新用户的头像和昵称 update
@PutMapping(“defaultAddr/{addrId}”) 设置默认收货地址 updateDefaultUserAddr

==============================================================================================================

八、删除—removeByIds

请求方式@DeleteMapping 用途 方法 返回值
@DeleteMapping(“{ids}”) 批量删除管理员 removeByIds
@DeleteMapping 批量删除系统角色 removeByIds
@DeleteMapping(“{categoryId}”) 删除商品类目 removeById
@DeleteMapping(“{tagId}”) 删除商品分组标签 removeById
@DeleteMapping(“{propId}”) 删除商品规格 removeById
@DeleteMapping(“{ids}”) 批量删除商品 removeByIds
@DeleteMapping(“{id}”) 删除公告 removeById
@DeleteMapping 批量删除自提点地址 removeByIds
@DeleteMapping(“{ids}”) 批量删除轮播图 removeByIds
@DeleteMapping(“deleteAddr/{addrId}”) 删除用户收货地址 deleteUserAddr
@DeleteMapping(“deleteItem”) 删除购物车中选中的商品 removeByIds
@ApiOperation("批量删除xxxx")
@DeleteMapping("{ids}")
@PreAuthorize("hasAuthority('模块权限:权限:delete')")
public ResponseEntity<Void> delete'xxxx'(@PathVariable List<Long> ids) {
    'xxxx'Service.removeByIds(ids);
    return ResponseEntity.ok().build();
}
@Override
@Transactional(rollbackFor = RuntimeException.class)
@CacheEvict(key = xxxConstant.xxx)
public boolean removeByIds(Collection idList) {

    //删除指定表2对应的权限数据
    '表2xxxx'Mapper.delete(new LambdaQueryWrapper<表2实体类>()
            .in('表2xxxx'::getRoleId,idList)
    );
    
    return 'xxxx'Mapper.deleteBatchIds(idList)==idList.size();
}

复杂的条件:能不能删,删了之后让继承者上位

@Override
@CacheEvict(key = "#userId")
@Transactional(rollbackFor = RuntimeException.class)
public void deleteUserAddr(Long addrId, String userId) {
    //查询当前用户默认收货地址
    UserAddr userDefaultAddr = userAddrMapper.selectOne(new LambdaQueryWrapper<UserAddr>()
            .eq(UserAddr::getUserId, userId)
            .eq(UserAddr::getCommonAddr, 1)
    );
    //删除收货地址
    userAddrMapper.deleteById(addrId);
    //判断当前删除的地址是否为默认收货地址
    if (addrId == userDefaultAddr.getAddrId()) {
        //当前删除的地址为默认收货地址
        //查询当前用户的非默认收货地址
        List<UserAddr> userAddrList = userAddrMapper.selectList(new LambdaQueryWrapper<UserAddr>()
                .eq(UserAddr::getUserId, userId)
                .eq(UserAddr::getCommonAddr, 0)
                .orderByDesc(UserAddr::getCreateTime)
        );
        //判断非默认收货地址是否有值
        if (!CollectionUtils.isEmpty(userAddrList) && userAddrList.size() != 0) {
            //说明当前用户还有非默认收货地址,我们取第1个为新的默认收货地址
            UserAddr newUserDefaultAddr = userAddrList.get(0);
            newUserDefaultAddr.setCommonAddr(1);
            userAddrMapper.updateById(newUserDefaultAddr);
        }
    }
}

你可能感兴趣的:(cloud_mall,java,rabbitmq)