后端 + 前端:购物车详情

This commit is contained in:
YunaiV 2019-04-13 22:53:44 +08:00
parent fa5ea5dfd9
commit b2abc625d1
16 changed files with 497 additions and 144 deletions

View File

@ -67,6 +67,26 @@ export function countCart() {
}); });
} }
export function listCart() {
return request({
url: '/order-api/users/cart/list',
method: 'get',
params: {
}
});
}
export function updateCartSelected(skuIds, selected) {
return request({
url: '/order-api/users/cart/update_selected',
method: 'post',
params: {
skuIds: skuIds.join(','),
selected,
}
});
}
// 物流信息 // 物流信息
export function getLogisticsInfo(params) { export function getLogisticsInfo(params) {

View File

@ -14,7 +14,7 @@
</template> </template>
<template slot="tags"> <template slot="tags">
<p class="price" v-if="product.price!=null && product.price !== ''"> <p class="price" v-if="product.price!=null && product.price !== ''">
<span>{{product.price}}</span> <span>{{product.price / 100.00}}</span>
<!-- TODO 芋艿 暂时去掉 --> <!-- TODO 芋艿 暂时去掉 -->
<!-- <van-tag v-if="product.tags!=null" v-for="tag in product.tags" :key="tag" plain type="danger">--> <!-- <van-tag v-if="product.tags!=null" v-for="tag in product.tags" :key="tag" plain type="danger">-->
<!-- {{tag}}--> <!-- {{tag}}-->

View File

@ -3,17 +3,17 @@
<headerNav title="购物车"/> <headerNav title="购物车"/>
<van-cell value="编辑商品" class="head"> <van-cell value="编辑商品" class="head">
<template slot="title"> <template slot="title">
<van-checkbox v-model="checkedAll" >全选</van-checkbox> <van-checkbox v-model="checkedAll" @change="onSelectAll" >全选</van-checkbox>
</template> </template>
</van-cell> </van-cell>
<van-checkbox-group class="card-goods" v-model="checkedGoods"> <van-checkbox-group class="card-goods" v-model="checkedItemIds" @change="onItemSelectedChange">
<div class="promotion-group"> <div class="promotion-group">
<div v-for="(item,index) in goods" :key="index" class="card-goods__item"> <!-- <div v-for="(item,index) in goods" :key="index" class="card-goods__item">-->
<van-checkbox :name="item.id"></van-checkbox> <!-- <van-checkbox :name="item.id" />-->
<product-card :product='item' :iscard='false' > <!-- <product-card :product='item' :iscard='false' >-->
<!-- <template slot>--> <!-- <template slot>-->
<!-- <van-cell value="修改" >--> <!-- <van-cell value="修改" >-->
<!-- <template slot="title">--> <!-- <template slot="title">-->
@ -22,11 +22,20 @@
<!-- </template>--> <!-- </template>-->
<!-- </van-cell>--> <!-- </van-cell>-->
<!-- </template>--> <!-- </template>-->
</product-card> <!-- </product-card>-->
</div> <!-- </div>-->
<div v-for="(itemGroup, i) in itemGroups" class="card-goods__item">
<div class="card" v-for="(item, j) in itemGroup.items" :key="j">
<van-checkbox :key="item.id" :name="item.id" v-model="item.selected" style="position: relative;" />
<product-card :product='convertProduct(item)'/>
</div>
<div style="height:15px;"></div>
</div>
</div> </div>
<!-- <div class="promotion-group">--> <!-- <div class="promotion-group">-->
<!-- <van-cell is-link class="head">--> <!-- <van-cell is-link class="head">-->
<!-- <template slot="title">--> <!-- <template slot="title">-->
@ -38,13 +47,13 @@
<div style="height:50px;"></div> <div style="height:50px;"></div>
<van-submit-bar <van-submit-bar
:price="totalPrice" :price="fee.presentTotal"
:disabled="!checkedGoods.length" :disabled="!checkedItemIds || !checkedItemIds.length"
:button-text="submitBarText" :button-text="submitBarText"
@submit="onSubmit" @submit="onSubmit"
> >
<template slot> <template slot>
<van-checkbox v-model="checkedAll" >全选</van-checkbox> <van-checkbox v-model="checkedAll" @change="onSelectAll">全选</van-checkbox>
</template> </template>
</van-submit-bar> </van-submit-bar>
</div> </div>
@ -52,62 +61,123 @@
<script> <script>
import {listCart, updateCartSelected} from "../../api/order";
export default { export default {
components: { components: {
}, },
data() { data() {
return { return {
checkedAll:true, itemGroups: [],
checkedGoods: ['1', '2', '3'], fee: {
goods: [{ originalTotal: undefined,
id: '1', discountTotal: undefined,
title: '星巴克(Starbucks)星冰乐 轻盈香草味 咖啡饮料 281ml*6瓶礼盒装低脂减糖', postageTotal: undefined,
desc: '3.18kg/件', presentTotal: undefined,
price: '200.00', },
quantity: 1, checkedItemIds: undefined, //
picUrls: ['https://img.yzcdn.cn/public_files/2017/10/24/2f9a36046449dafb8608e99990b3c205.jpeg'], oldCheckedItemIds: undefined, // vue change
imageTag:'比加入时降5元', checkedAll: undefined, //
}, { }
id: '2',
title: '陕西蜜梨',
desc: '约600g',
price: '690.00',
quantity: 1,
picUrls: ['https://img.yzcdn.cn/public_files/2017/10/24/f6aabd6ac5521195e01e8e89ee9fc63f.jpeg'],
gift: [
{
title: "星巴克Starbucks星冰乐小熊吊饰星巴克Starbucks星冰乐小熊吊饰",
quantity: 2
},
{
title: "星巴克Starbucks星冰乐小熊吊饰星巴克Starbucks星冰乐小熊吊饰",
quantity: 1
}
]
}, {
id: '3',
title: '美国伽力果',
desc: '约680g/3个',
price: '2680.00',
quantity: 1,
picUrls: ['https://img.yzcdn.cn/public_files/2017/10/24/320454216bbe9e25c7651e1fa51b31fd.jpeg']
}]
};
}, },
computed: { computed: {
submitBarText() { submitBarText() {
const count = this.checkedGoods.length; const count = this.checkedItemIds ? this.checkedItemIds.length : 0;
return '结算' + (count ? `(${count})` : ''); return '结算' + (count ? `(${count})` : '');
}, },
totalPrice() {
return this.goods.reduce((total, item) => total + (this.checkedGoods.indexOf(item.id) !== -1 ? parseFloat(item.price): 0), 0);
},
}, },
methods: { methods: {
calCheckedItemIds() {
// debugger;
let itemIds = [];
let checkedAll = true;
for (let i in this.itemGroups) {
let items = this.itemGroups[i].items;
for (let j in items) {
if (items[j].selected) {
itemIds.push(items[j].id);
} else {
checkedAll = false;
}
}
}
// checkedItemIdsoldCheckedItemIdscheckedAll
this.checkedItemIds = itemIds;
this.oldCheckedItemIds = itemIds;
this.checkedAll = checkedAll;
},
getItemIds() {
let itemIds = [];
for (let i in this.itemGroups) {
let items = this.itemGroups[i].items;
for (let j in items) {
itemIds.push(items[j].id);
}
}
return itemIds;
},
handleData(data) {
this.itemGroups = data.itemGroups;
this.fee = data.fee;
// checkedItemIds + checkedAll
this.calCheckedItemIds();
},
onItemSelectedChange(newVal) {
if (!this.checkedItemIds) {
return;
}
// debugger;
let selected;
let diffItemIds;
if (newVal.length > this.oldCheckedItemIds.length) { //
selected = true;
let that = this;
diffItemIds = [...newVal].filter(function(val) {
return that.oldCheckedItemIds.indexOf(val) < 0; //
});
} else if (newVal.length < this.oldCheckedItemIds.length) { //
selected = false;
diffItemIds = [...this.oldCheckedItemIds].filter(function(val) {
return newVal.indexOf(val) < 0; //
});
} else {
return;
}
updateCartSelected(diffItemIds, selected).then(data => {
this.handleData(data);
})
// debugger;
},
onSelectAll(newVal) {
if (this.checkedAll === undefined) {
return;
}
updateCartSelected(this.getItemIds(), newVal).then(data => {
this.handleData(data);
})
},
onSubmit() { onSubmit() {
this.$router.push('/order') this.$router.push('/order')
},
convertProduct(item) {
// debugger;
return {
...item.spu,
quantity: item.buyQuantity,
price: item.price,
sku: {
...item,
spu: undefined,
},
selected: item.selected,
};
} }
},
mounted() {
//
listCart().then(data => {
this.handleData(data);
});
} }
}; };
</script> </script>

View File

@ -3,18 +3,20 @@ package cn.iocoder.mall.order.application.controller.users;
import cn.iocoder.common.framework.vo.CommonResult; import cn.iocoder.common.framework.vo.CommonResult;
import cn.iocoder.mall.order.api.CartService; import cn.iocoder.mall.order.api.CartService;
import cn.iocoder.mall.order.api.OrderService; import cn.iocoder.mall.order.api.OrderService;
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
import cn.iocoder.mall.order.api.bo.CartItemBO; import cn.iocoder.mall.order.api.bo.CartItemBO;
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
import cn.iocoder.mall.order.application.convert.CartConvert;
import cn.iocoder.mall.order.application.vo.UsersCartDetailVO;
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO; import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder; import cn.iocoder.mall.user.sdk.context.UserSecurityContextHolder;
import com.alibaba.dubbo.config.annotation.Reference; import com.alibaba.dubbo.config.annotation.Reference;
import org.apache.ibatis.annotations.Param; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set;
@RestController @RestController
@RequestMapping("users/cart") @RequestMapping("users/cart")
@ -26,8 +28,8 @@ public class UsersCartController {
private OrderService orderService; private OrderService orderService;
@PostMapping("add") @PostMapping("add")
public CommonResult<Integer> add(@Param("skuId") Integer skuId, public CommonResult<Integer> add(@RequestParam("skuId") Integer skuId,
@Param("quantity") Integer quantity) { @RequestParam("quantity") Integer quantity) {
// 添加到购物车 // 添加到购物车
CommonResult<Boolean> addResult = cartService.add(UserSecurityContextHolder.getContext().getUserId(), CommonResult<Boolean> addResult = cartService.add(UserSecurityContextHolder.getContext().getUserId(),
skuId, quantity); skuId, quantity);
@ -40,8 +42,8 @@ public class UsersCartController {
} }
@PostMapping("update_quantity") @PostMapping("update_quantity")
public CommonResult<Integer> updateQuantity(@Param("skuId") Integer skuId, public CommonResult<UsersCartDetailVO> updateQuantity(@RequestParam("skuId") Integer skuId, // TODO 芋艿先暂用这个 VO 等促销活动出来后做调整
@Param("quantity") Integer quantity) { @RequestParam("quantity") Integer quantity) {
// 添加到购物车 // 添加到购物车
CommonResult<Boolean> updateQuantityResult = cartService.updateQuantity(UserSecurityContextHolder.getContext().getUserId(), CommonResult<Boolean> updateQuantityResult = cartService.updateQuantity(UserSecurityContextHolder.getContext().getUserId(),
skuId, quantity); skuId, quantity);
@ -49,24 +51,22 @@ public class UsersCartController {
if (updateQuantityResult.isError()) { if (updateQuantityResult.isError()) {
return CommonResult.error(updateQuantityResult); return CommonResult.error(updateQuantityResult);
} }
// 获得目前购物车商品总数量 // 获得目前购物车明细
// TODO 芋艿需要改成价格计算 return getCartDetail();
return cartService.count(UserSecurityContextHolder.getContext().getUserId());
} }
@PostMapping("update_selected") @PostMapping("update_selected")
public CommonResult<Integer> updateSelected(@Param("skuId") Integer skuId, public CommonResult<UsersCartDetailVO> updateSelected(@RequestParam("skuIds") Set<Integer> skuIds, // TODO 芋艿先暂用这个 VO 等促销活动出来后做调整
@Param("selected") Boolean selected) { @RequestParam("selected") Boolean selected) {
// 添加到购物车 // 添加到购物车
CommonResult<Boolean> updateSelectedResult = cartService.updateSelected(UserSecurityContextHolder.getContext().getUserId(), CommonResult<Boolean> updateSelectedResult = cartService.updateSelected(UserSecurityContextHolder.getContext().getUserId(),
skuId, selected); skuIds, selected);
// 添加失败则直接返回错误 // 添加失败则直接返回错误
if (updateSelectedResult.isError()) { if (updateSelectedResult.isError()) {
return CommonResult.error(updateSelectedResult); return CommonResult.error(updateSelectedResult);
} }
// 获得目前购物车商品总数量 // 获得目前购物车明细
// TODO 芋艿需要改成价格计算 return getCartDetail();
return cartService.count(UserSecurityContextHolder.getContext().getUserId());
} }
@GetMapping("count") @GetMapping("count")
@ -75,25 +75,33 @@ public class UsersCartController {
} }
@GetMapping("/list") @GetMapping("/list")
public CommonResult<UsersOrderConfirmCreateVO> list() { public CommonResult<UsersCartDetailVO> list() { // TODO 芋艿先暂用这个 VO 等促销活动出来后做调整
// 获得购物车中所有的 return getCartDetail();
List<CartItemBO> cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), null); }
private CommonResult<UsersCartDetailVO> getCartDetail() {
// 获得购物车中选中的
List<CartItemBO> cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), null).getData();
// 购物车为空时构造空的 UsersOrderConfirmCreateVO 返回 // 购物车为空时构造空的 UsersOrderConfirmCreateVO 返回
if (cartItems.isEmpty()) { if (cartItems.isEmpty()) {
UsersOrderConfirmCreateVO result = new UsersOrderConfirmCreateVO(); UsersCartDetailVO result = new UsersCartDetailVO();
result.setItemGroups(Collections.emptyList()); result.setItemGroups(Collections.emptyList());
result.setFee(new UsersOrderConfirmCreateVO.Fee(0, 0, 0, 0)); result.setFee(new UsersCartDetailVO.Fee(0, 0, 0, 0));
return CommonResult.success(result); return CommonResult.success(result);
} }
// 购物车非空时获得具体结果 // 计算商品价格
CommonResult<CalcOrderPriceBO> calcOrderPriceResult = list0(cartItems);
return null; if (calcOrderPriceResult.isError()) {
return CommonResult.error(calcOrderPriceResult);
}
// 执行数据拼装
return CommonResult.success(CartConvert.INSTANCE.convert2(calcOrderPriceResult.getData()));
} }
@GetMapping("/confirm_create_order") @GetMapping("/confirm_create_order")
public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder() { public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder() {
// 获得购物车中选中的 // 获得购物车中选中的
List<CartItemBO> cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), true); List<CartItemBO> cartItems = cartService.list(UserSecurityContextHolder.getContext().getUserId(), true).getData();
// 购物车为空时构造空的 UsersOrderConfirmCreateVO 返回 // 购物车为空时构造空的 UsersOrderConfirmCreateVO 返回
if (cartItems.isEmpty()) { if (cartItems.isEmpty()) {
UsersOrderConfirmCreateVO result = new UsersOrderConfirmCreateVO(); UsersOrderConfirmCreateVO result = new UsersOrderConfirmCreateVO();
@ -101,9 +109,24 @@ public class UsersCartController {
result.setFee(new UsersOrderConfirmCreateVO.Fee(0, 0, 0, 0)); result.setFee(new UsersOrderConfirmCreateVO.Fee(0, 0, 0, 0));
return CommonResult.success(result); return CommonResult.success(result);
} }
// 购物车非空时获得具体结果 // 计算商品价格
// return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPriceResult.getData())); CommonResult<CalcOrderPriceBO> calcOrderPriceResult = list0(cartItems);
return null; if (calcOrderPriceResult.isError()) {
return CommonResult.error(calcOrderPriceResult);
}
// 执行数据拼装
return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPriceResult.getData()));
}
private CommonResult<CalcOrderPriceBO> list0(List<CartItemBO> cartItems) {
// 创建计算的 DTO
CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
.setItems(new ArrayList<>(cartItems.size()));
for (CartItemBO item : cartItems) {
calcOrderPriceDTO.getItems().add(new CalcOrderPriceDTO.Item(item.getSkuId(), item.getQuantity(), item.getSelected()));
}
// 执行计算
return cartService.calcOrderPrice(calcOrderPriceDTO);
} }
public CommonResult<Object> confirmOrder() { public CommonResult<Object> confirmOrder() {

View File

@ -1,6 +1,7 @@
package cn.iocoder.mall.order.application.convert; package cn.iocoder.mall.order.application.convert;
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO; import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
import cn.iocoder.mall.order.application.vo.UsersCartDetailVO;
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO; import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
@ -12,4 +13,6 @@ public interface CartConvert {
UsersOrderConfirmCreateVO convert(CalcOrderPriceBO calcOrderPriceBO); UsersOrderConfirmCreateVO convert(CalcOrderPriceBO calcOrderPriceBO);
UsersCartDetailVO convert2(CalcOrderPriceBO calcOrderPriceBO);
} }

View File

@ -1,26 +0,0 @@
package cn.iocoder.mall.order.application.vo;
public class FeeMessageVO {
/**
* 总价
*/
private Integer originalTotal;
/**
* 优惠总价
*
* 注意满多少元包邮不算在优惠中
*/
private Integer discountTotal;
/**
* 邮费
*/
private Integer postageTotal;
/**
* 最终价格
*
* 计算公式 = 总价 - 优惠总价 + 邮费
*/
private Integer presentTotal;
}

View File

@ -0,0 +1,167 @@
package cn.iocoder.mall.order.application.vo;
import cn.iocoder.mall.product.api.bo.ProductAttrAndValuePairBO;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
@ApiModel(value = "购物车明细 VO")
@Data
@Accessors(chain = true)
public class UsersCartDetailVO {
/**
* 商品分组数组
*/
private List<ItemGroup> itemGroups;
/**
* 费用
*/
private Fee fee;
/**
* 商品分组
*
* 多个商品参加同一个活动从而形成分组
*/
@Data
@Accessors(chain = true)
public static class ItemGroup {
// TODO 优惠活动
private Object activity;
/**
* 商品数组
*/
private List<Sku> items;
}
@Data
@Accessors(chain = true)
public static class Sku {
// SKU 自带信息
/**
* sku 编号
*/
private Integer id;
/**
* SPU 信息
*/
private Spu spu;
/**
* 图片地址
*/
private String picURL;
/**
* 规格值数组
*/
private List<ProductAttrAndValuePairBO> attrs; // TODO 后面改下
/**
* 价格单位
*/
private Integer price;
/**
* 库存数量
*/
private Integer quantity;
// SKU 自带信息
/**
* 购买数量
*/
private Integer buyQuantity;
/**
* 是否选中
*/
private Boolean selected;
}
@Data
@Accessors(chain = true)
public static class Spu {
/**
* SPU 编号
*/
private Integer id;
// ========== 基本信息 =========
/**
* SPU 名字
*/
private String name;
/**
* 分类编号
*/
private Integer cid;
/**
* 商品主图地址
*
* 数组以逗号分隔
*
* 建议尺寸800*800像素你可以拖拽图片调整顺序最多上传15张
*/
private List<String> picUrls;
}
/**
* 费用合计
*/
@Data
@Accessors(chain = true)
public static class Fee {
/**
* 总价
*/
private Integer originalTotal;
/**
* 优惠总价
*
* 注意满多少元包邮不算在优惠中
*/
private Integer discountTotal;
/**
* 邮费
*/
private Integer postageTotal;
/**
* 最终价格
*
* 计算公式 = 总价 - 优惠总价 + 邮费
*/
private Integer presentTotal;
public Fee() {
}
public Fee(Integer originalTotal, Integer discountTotal, Integer postageTotal, Integer presentTotal) {
this.originalTotal = originalTotal;
this.discountTotal = discountTotal;
this.postageTotal = postageTotal;
this.presentTotal = presentTotal;
}
}
/**
* 邮费信息
*/
@Data
@Accessors(chain = true)
public static class Postage {
/**
* 需要满足多少钱可以包邮单位
*/
private Integer threshold;
}
}

View File

@ -1,5 +0,0 @@
package cn.iocoder.mall.order.application.vo;
public class UsersCartItemVO {
}

View File

@ -1,11 +0,0 @@
package cn.iocoder.mall.order.application.vo;
import java.util.List;
public class UsersCartListVO {
private List<UsersCartItemVO> items;
private FeeMessageVO feeMessage;
}

View File

@ -8,6 +8,7 @@ import cn.iocoder.mall.order.api.bo.OrderCreateBO;
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO; import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
import org.springframework.lang.Nullable; import org.springframework.lang.Nullable;
import java.util.Collection;
import java.util.List; import java.util.List;
public interface CartService { public interface CartService {
@ -38,11 +39,11 @@ public interface CartService {
* 购物车更新商品是否选中 * 购物车更新商品是否选中
* *
* @param userId 用户编号 * @param userId 用户编号
* @param skuId 商品 SKU 编号 * @param skuIds 商品 SKU 编号数组
* @param selected 是否选中 * @param selected 是否选中
* @return 是否成功 * @return 是否成功
*/ */
CommonResult<Boolean> updateSelected(Integer userId, Integer skuId, Boolean selected); CommonResult<Boolean> updateSelected(Integer userId, Collection<Integer> skuIds, Boolean selected);
/** /**
* 购物车删除商品 * 购物车删除商品
@ -77,7 +78,7 @@ public interface CartService {
* @param selected 是否选中若为空则不进行筛选 * @param selected 是否选中若为空则不进行筛选
* @return 购物车中商品列表信息 * @return 购物车中商品列表信息
*/ */
List<CartItemBO> list(Integer userId, @Nullable Boolean selected); CommonResult<List<CartItemBO>> list(Integer userId, @Nullable Boolean selected);
// ========== 购物车与订单相关的逻辑 ========== // ========== 购物车与订单相关的逻辑 ==========

View File

@ -3,6 +3,8 @@ package cn.iocoder.mall.order.api.bo;
import lombok.Data; import lombok.Data;
import lombok.experimental.Accessors; import lombok.experimental.Accessors;
import java.util.Date;
/** /**
* 购物车的商品信息 DO * 购物车的商品信息 DO
*/ */
@ -10,6 +12,89 @@ import lombok.experimental.Accessors;
@Accessors(chain = true) @Accessors(chain = true)
public class CartItemBO { public class CartItemBO {
// ========= 基础字段 BEGIN =========
/**
* 编号唯一自增
*/
private Integer id;
/**
* 状态
*
* 1-正常
* 2-主动删除
* 3-下单删除
*/
private Integer status;
/**
* 是否选中
*/
private Boolean selected;
// ========= 基础字段 END =========
// ========= 买家信息 BEGIN =========
/**
* 用户编号
*/
private Integer userId;
// /**
// * 会话 key
// */
// private String nobody;
// ========= 买家信息 END =========
// ========= 商品信息 BEGIN =========
/**
* 商品 SPU 编号
*/
private Integer spuId;
/**
* 商品 SKU 编号
*/
private Integer skuId;
/**
* 商品购买数量
*/
private Integer quantity;
// TODO 冗余字段
// ========= 商品信息 END =========
// ========= 交易信息 BEGIN =========
/**
* 订单编号
*/
private Integer orderId;
/**
* 订单创建时间
*/
private Date orderCreateTime;
// ========= 交易信息 BEGIN =========
// ========= 优惠信息 BEGIN =========
// /**
// * 商品营销活动编号
// */
// private Integer activityId;
// /**
// * 商品营销活动类型
// */
// private Integer activityType;
// ========= 优惠信息 END =========
/**
* 创建时间
*/
private Date createTime;
} }

View File

@ -1,10 +1,14 @@
package cn.iocoder.mall.order.biz.convert; package cn.iocoder.mall.order.biz.convert;
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO; import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
import cn.iocoder.mall.order.api.bo.CartItemBO;
import cn.iocoder.mall.order.biz.dataobject.CartItemDO;
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO; import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
import org.mapstruct.Mapper; import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers; import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper @Mapper
public interface CartConvert { public interface CartConvert {
@ -12,4 +16,6 @@ public interface CartConvert {
CalcOrderPriceBO.Item convert(ProductSkuDetailBO sku); CalcOrderPriceBO.Item convert(ProductSkuDetailBO sku);
List<CartItemBO> convert(List<CartItemDO> items);
} }

View File

@ -21,7 +21,9 @@ public interface CartMapper {
Integer selectQuantitySumByUserIdAndStatus(@Param("userId") Integer userId, Integer selectQuantitySumByUserIdAndStatus(@Param("userId") Integer userId,
@Param("status") Integer status); @Param("status") Integer status);
// List<CartItemDO> selectListByStatus(@Param("status") Integer status); List<CartItemDO> selectByUserIdAndStatusAndSelected(@Param("userId") Integer userId,
@Param("status") Integer status,
@Param("selected") Boolean selected);
// //
// List<CartItemDO> selectListByTitleLike(@Param("title") String title, // List<CartItemDO> selectListByTitleLike(@Param("title") String title,
// @Param("offset") Integer offset, // @Param("offset") Integer offset,
@ -36,4 +38,8 @@ public interface CartMapper {
int updateQuantity(@Param("id") Integer id, int updateQuantity(@Param("id") Integer id,
@Param("quantityIncr") Integer quantityIncr); @Param("quantityIncr") Integer quantityIncr);
int updateListSelected(@Param("userId") Integer userId,
@Param("skuIds") Collection<Integer> skuIds,
@Param("selected") Boolean selected);
} }

View File

@ -44,10 +44,6 @@ public class CartItemDO extends BaseDO {
* 用户编号 * 用户编号
*/ */
private Integer userId; private Integer userId;
// /**
// * 会话 key
// */
// private String nobody;
// ========= 买家信息 END ========= // ========= 买家信息 END =========

View File

@ -114,15 +114,9 @@ public class CartServiceImpl implements CartService {
} }
@Override @Override
public CommonResult<Boolean> updateSelected(Integer userId, Integer skuId, Boolean selected) { public CommonResult<Boolean> updateSelected(Integer userId, Collection<Integer> skuIds, Boolean selected) {
// 查询 CartItemDO // 更新 CartItemDO
CartItemDO item = cartMapper.selectByUserIdAndSkuIdAndStatus(userId, skuId, CartItemStatusEnum.ENABLE.getValue()); cartMapper.updateListSelected(userId, skuIds, selected);
if (item == null) {
return ServiceExceptionUtil.error(OrderErrorCodeEnum.CARD_ITEM_NOT_FOUND.getCode());
}
// 更新 CartItemDO
CartItemDO updateCartItem = new CartItemDO().setId(item.getId()).setSelected(selected);
cartMapper.update(updateCartItem);
// 返回成功 // 返回成功
return CommonResult.success(true); return CommonResult.success(true);
} }
@ -143,8 +137,9 @@ public class CartServiceImpl implements CartService {
} }
@Override @Override
public List<CartItemBO> list(Integer userId, Boolean selected) { public CommonResult<List<CartItemBO>> list(Integer userId, Boolean selected) {
return null; List<CartItemDO> items = cartMapper.selectByUserIdAndStatusAndSelected(userId, CartItemStatusEnum.ENABLE.getValue(), selected);
return CommonResult.success(CartConvert.INSTANCE.convert(items));
} }
@Override @Override

View File

@ -38,6 +38,18 @@
LIMIT 1 LIMIT 1
</select> </select>
<select id="selectByUserIdAndStatusAndSelected" resultType="CartItemDO">
SELECT
<include refid="FIELDS" />
FROM cart_item
WHERE user_id = #{userId}
AND status = #{status}
<if test="selected != null">
AND selected = #{selected}
</if>
-- AND deleted = 0
</select>
<select id="selectQuantitySumByUserIdAndStatus" resultType="Integer"> <select id="selectQuantitySumByUserIdAndStatus" resultType="Integer">
SELECT SELECT
SUM(quantity) SUM(quantity)
@ -96,4 +108,15 @@
WHERE id = #{id} WHERE id = #{id}
</update> </update>
<update id="updateListSelected">
UPDATE cart_item
SET selected = #{selected}
WHERE user_id = #{userId}
AND sku_id IN
<foreach item="skuId" collection="skuIds" separator="," open="(" close=")" index="">
#{skuId}
</foreach>
-- AND deleted = 0
</update>
</mapper> </mapper>