后端:商品确认下单的信息 api 接口,后续需要结合促销,完善这个接口。
This commit is contained in:
parent
50d8ec33ee
commit
4300ce141d
@ -21,6 +21,17 @@ export function cancelOrder(id) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getConfirmCreateOrder(skuId, quantity) {
|
||||||
|
return request({
|
||||||
|
url: '/order-api/users/order/confirm_create_order',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
skuId,
|
||||||
|
quantity,
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function createOrder(params) {
|
export function createOrder(params) {
|
||||||
return request({
|
return request({
|
||||||
headers: {
|
headers: {
|
||||||
|
@ -8,17 +8,22 @@
|
|||||||
style="background:#fff"
|
style="background:#fff"
|
||||||
>
|
>
|
||||||
<template slot="thumb">
|
<template slot="thumb">
|
||||||
<img :src="product.picUrl"/>
|
<!-- TODO 芋艿 暂时去掉,等会就恢复 -->
|
||||||
<p v-if="product.imageTag!=null&&product.imageTag!=''" class="image_tag">{{product.imageTag}}</p>
|
<!-- <img :src="product.picUrls[0]"/>-->
|
||||||
|
<!-- TODO 芋艿 暂时去掉 -->
|
||||||
|
<!-- <p v-if="product.imageTag!=null&&product.imageTag!=''" class="image_tag">{{product.imageTag}}</p>-->
|
||||||
</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}}</span>
|
||||||
<van-tag v-if="product.tags!=null" v-for="tag in product.tags" :key="tag" plain type="danger">
|
<!-- TODO 芋艿 暂时去掉 -->
|
||||||
{{tag}}
|
<!-- <van-tag v-if="product.tags!=null" v-for="tag in product.tags" :key="tag" plain type="danger">-->
|
||||||
</van-tag>
|
<!-- {{tag}}-->
|
||||||
|
<!-- </van-tag>-->
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<van-stepper v-if="iscard" v-model="product.quantity" :max="product.max" :min="product.min"/>
|
<!-- TODO 芋艿 暂时去掉 -->
|
||||||
|
<!-- <van-stepper v-if="iscard" v-model="product.quantity" :max="product.max" :min="product.min"/>-->
|
||||||
</template>
|
</template>
|
||||||
</van-card>
|
</van-card>
|
||||||
<!-- TODO 芋艿,暂时去掉赠品 -->
|
<!-- TODO 芋艿,暂时去掉赠品 -->
|
||||||
|
@ -17,9 +17,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</van-cell>
|
</van-cell>
|
||||||
<div style="height:15px;"></div>
|
<div style="height:15px;"></div>
|
||||||
|
|
||||||
<div class="card" v-for="(product,i) in products" :key="i">
|
<div class="card" v-for="(product,i) in products" :key="i">
|
||||||
<product-card :product='product'/>
|
<product-card :product='product'/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="height:15px;"></div>
|
<div style="height:15px;"></div>
|
||||||
<van-cell-group>
|
<van-cell-group>
|
||||||
<van-field
|
<van-field
|
||||||
@ -37,10 +39,10 @@
|
|||||||
|
|
||||||
<div style="height:15px;"></div>
|
<div style="height:15px;"></div>
|
||||||
<van-cell-group class="total">
|
<van-cell-group class="total">
|
||||||
<van-cell title="商品总额" value="9.99"/>
|
<van-cell title="商品总额" :value="fee.originalTotal"/>
|
||||||
<van-cell title="运费" value="+ 0.00"/>
|
<van-cell title="运费" :value="+ fee.postageTotal"/>
|
||||||
<van-cell title="折扣" value="- 5.00"/>
|
<van-cell title="折扣" :value="- fee.discountTotal"/>
|
||||||
<van-cell title="实付金额" value="4.99" style="font-weight: 700;"/>
|
<van-cell title="实付金额" :value="fee.presentTotal" style="font-weight: 700;"/>
|
||||||
</van-cell-group>
|
</van-cell-group>
|
||||||
|
|
||||||
<div style="height:50px;"></div>
|
<div style="height:50px;"></div>
|
||||||
@ -56,7 +58,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|
||||||
import {createOrder} from '../../api/order';
|
import {createOrder, getConfirmCreateOrder} from '../../api/order';
|
||||||
import {GetDefaultAddress} from '../../api/user';
|
import {GetDefaultAddress} from '../../api/user';
|
||||||
import orderStore from '../../store/order'
|
import orderStore from '../../store/order'
|
||||||
import eventBus from '../eventBus';
|
import eventBus from '../eventBus';
|
||||||
@ -64,10 +66,25 @@
|
|||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
from: 'direct_order', // 目前有两个来源。direct_order:直接下单; card: 购物车下单。
|
||||||
|
|
||||||
|
// 如下两个参数,在直接下单时使用
|
||||||
|
skuId: this.$route.query.skuId,
|
||||||
|
quantity: this.$route.query.quantity,
|
||||||
|
|
||||||
type: "add",
|
type: "add",
|
||||||
addressData: {
|
addressData: {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
itemGroups: [],
|
||||||
|
fee: {
|
||||||
|
originalTotal: undefined,
|
||||||
|
discountTotal: undefined,
|
||||||
|
postageTotal: undefined,
|
||||||
|
presentTotal: undefined,
|
||||||
|
},
|
||||||
|
|
||||||
products: [
|
products: [
|
||||||
{
|
{
|
||||||
imageURL:
|
imageURL:
|
||||||
@ -124,6 +141,9 @@
|
|||||||
remark,
|
remark,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
convertProduct() {
|
||||||
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
mounted: function() {
|
mounted: function() {
|
||||||
if (this.$store.state.addressData.name) {
|
if (this.$store.state.addressData.name) {
|
||||||
@ -132,14 +152,25 @@
|
|||||||
this.type = 'add';
|
this.type = 'add';
|
||||||
}
|
}
|
||||||
this.addressData = this.$store.state.addressData;
|
this.addressData = this.$store.state.addressData;
|
||||||
|
|
||||||
|
// 加载商品信息
|
||||||
|
if (this.from === 'direct_order') {
|
||||||
|
getConfirmCreateOrder(this.skuId, this.quantity).then(data => {
|
||||||
|
this.itemGroups = data.itemGroups;
|
||||||
|
this.fee = data.fee;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
// 加载地址
|
||||||
GetDefaultAddress().then((result) => {
|
GetDefaultAddress().then((result) => {
|
||||||
if (result) {
|
if (result) {
|
||||||
this.type = 'add1'
|
this.type = 'add1'
|
||||||
this.addressData = result
|
this.addressData = result
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
// 处理来源
|
||||||
},
|
},
|
||||||
store: orderStore,
|
store: orderStore,
|
||||||
};
|
};
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
package cn.iocoder.mall.order.application.controller.users;
|
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.OrderService;
|
import cn.iocoder.mall.order.api.OrderService;
|
||||||
|
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||||
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
||||||
import cn.iocoder.mall.order.api.bo.OrderPageBO;
|
import cn.iocoder.mall.order.api.bo.OrderPageBO;
|
||||||
|
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
|
||||||
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
|
import cn.iocoder.mall.order.api.dto.OrderCreateDTO;
|
||||||
import cn.iocoder.mall.order.api.dto.OrderQueryDTO;
|
import cn.iocoder.mall.order.api.dto.OrderQueryDTO;
|
||||||
|
import cn.iocoder.mall.order.application.convert.CartConvert;
|
||||||
import cn.iocoder.mall.order.application.convert.OrderConvertAPP;
|
import cn.iocoder.mall.order.application.convert.OrderConvertAPP;
|
||||||
import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
|
import cn.iocoder.mall.order.application.po.user.OrderCreatePO;
|
||||||
|
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 org.springframework.beans.factory.annotation.Autowired;
|
import com.alibaba.dubbo.config.annotation.Reference;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单API(users)
|
* 订单API(users)
|
||||||
*
|
*
|
||||||
@ -23,8 +30,10 @@ import org.springframework.web.bind.annotation.*;
|
|||||||
@RequestMapping("users/order")
|
@RequestMapping("users/order")
|
||||||
public class UsersOrderController {
|
public class UsersOrderController {
|
||||||
|
|
||||||
@Autowired
|
@Reference(validation = "true")
|
||||||
private OrderService orderService;
|
private OrderService orderService;
|
||||||
|
@Reference(validation = "true")
|
||||||
|
private CartService cartService;
|
||||||
|
|
||||||
@GetMapping("order_page")
|
@GetMapping("order_page")
|
||||||
public CommonResult<OrderPageBO> getOrderPage(@Validated OrderQueryDTO orderQueryDTO) {
|
public CommonResult<OrderPageBO> getOrderPage(@Validated OrderQueryDTO orderQueryDTO) {
|
||||||
@ -40,4 +49,19 @@ public class UsersOrderController {
|
|||||||
orderCreateDTO.setUserId(userId);
|
orderCreateDTO.setUserId(userId);
|
||||||
return orderService.createOrder(orderCreateDTO);
|
return orderService.createOrder(orderCreateDTO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/confirm_create_order")
|
||||||
|
public CommonResult<UsersOrderConfirmCreateVO> getConfirmCreateOrder(@RequestParam("skuId") Integer skuId,
|
||||||
|
@RequestParam("quantity") Integer quantity) {
|
||||||
|
// 创建 CalcOrderPriceDTO 对象,并执行价格计算
|
||||||
|
CalcOrderPriceDTO calcOrderPriceDTO = new CalcOrderPriceDTO()
|
||||||
|
.setItems(Collections.singletonList(new CalcOrderPriceDTO.Item(skuId, quantity, true)));
|
||||||
|
CommonResult<CalcOrderPriceBO> calcOrderPriceResult = cartService.calcOrderPrice(calcOrderPriceDTO);
|
||||||
|
if (calcOrderPriceResult.isError()) {
|
||||||
|
return CommonResult.error(calcOrderPriceResult);
|
||||||
|
}
|
||||||
|
// 执行数据拼装
|
||||||
|
return CommonResult.success(CartConvert.INSTANCE.convert(calcOrderPriceResult.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package cn.iocoder.mall.order.application.convert;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||||
|
import cn.iocoder.mall.order.application.vo.UsersOrderConfirmCreateVO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CartConvert {
|
||||||
|
|
||||||
|
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
|
||||||
|
|
||||||
|
UsersOrderConfirmCreateVO convert(CalcOrderPriceBO calcOrderPriceBO);
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,152 @@
|
|||||||
|
package cn.iocoder.mall.order.application.vo;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.product.api.bo.ProductAttrAndValuePairBO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class UsersOrderConfirmCreateVO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品分组数组
|
||||||
|
*/
|
||||||
|
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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@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;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 邮费信息
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public static class Postage {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 需要满足多少钱,可以包邮。单位:分
|
||||||
|
*/
|
||||||
|
private Integer threshold;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -16,8 +16,13 @@
|
|||||||
<groupId>cn.iocoder.mall</groupId>
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
<artifactId>common-framework</artifactId>
|
<artifactId>common-framework</artifactId>
|
||||||
<version>1.0-SNAPSHOT</version>
|
<version>1.0-SNAPSHOT</version>
|
||||||
<scope>compile</scope>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.iocoder.mall</groupId>
|
||||||
|
<artifactId>product-service-api</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>javax.validation</groupId>
|
<groupId>javax.validation</groupId>
|
||||||
<artifactId>validation-api</artifactId>
|
<artifactId>validation-api</artifactId>
|
||||||
@ -34,5 +39,6 @@
|
|||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
@ -1,9 +1,11 @@
|
|||||||
package cn.iocoder.mall.order.api;
|
package cn.iocoder.mall.order.api;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||||
import cn.iocoder.mall.order.api.bo.CartBO;
|
import cn.iocoder.mall.order.api.bo.CartBO;
|
||||||
import cn.iocoder.mall.order.api.bo.CartItemBO;
|
import cn.iocoder.mall.order.api.bo.CartItemBO;
|
||||||
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
||||||
|
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -78,6 +80,14 @@ public interface CartService {
|
|||||||
|
|
||||||
// ========== 购物车与订单相关的逻辑 ==========
|
// ========== 购物车与订单相关的逻辑 ==========
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 计算订单金额,返回计算结果
|
||||||
|
*
|
||||||
|
* @param calcOrderPriceDTO 计算订单金额 DTO
|
||||||
|
* @return 计算订单金额结果
|
||||||
|
*/
|
||||||
|
CommonResult<CalcOrderPriceBO> calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得购物车明细
|
* 获得购物车明细
|
||||||
*
|
*
|
||||||
|
@ -38,14 +38,6 @@ public interface OrderService {
|
|||||||
*/
|
*/
|
||||||
CommonResult<OrderRecipientBO> getOrderRecipientBO(Integer orderId);
|
CommonResult<OrderRecipientBO> getOrderRecipientBO(Integer orderId);
|
||||||
|
|
||||||
/**
|
|
||||||
* 计算订单金额,返回计算结果
|
|
||||||
*
|
|
||||||
* @param calcOrderPriceDTO 计算订单金额 DTO
|
|
||||||
* @return 计算订单金额结果
|
|
||||||
*/
|
|
||||||
CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 订单 - 创建
|
* 订单 - 创建
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.mall.order.api.bo;
|
package cn.iocoder.mall.order.api.bo;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
@ -45,10 +46,16 @@ public class CalcOrderPriceBO {
|
|||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
public static class Item {
|
public static class Item extends ProductSkuDetailBO { // TODO 芋艿,此处先偷懒继承
|
||||||
|
|
||||||
// TODO 信息要相当完整
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 是否选中
|
||||||
|
*/
|
||||||
|
private Boolean selected;
|
||||||
|
/**
|
||||||
|
* 购买数量
|
||||||
|
*/
|
||||||
|
private Integer buyQuantity;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -80,6 +87,15 @@ public class CalcOrderPriceBO {
|
|||||||
*/
|
*/
|
||||||
private Integer presentTotal;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,7 @@ public enum OrderErrorCodeEnum {
|
|||||||
|
|
||||||
// order item
|
// order item
|
||||||
ORDER_ITEM_ONLY_ONE(1008000004, "订单Item只有一个!"),
|
ORDER_ITEM_ONLY_ONE(1008000004, "订单Item只有一个!"),
|
||||||
|
ORDER_ITEM_SOME_NOT_EXISTS(-1, "有不存在的商品"), // TODO 芋艿 后面改下错误码
|
||||||
|
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -15,11 +15,11 @@ public class CalcOrderPriceDTO {
|
|||||||
/**
|
/**
|
||||||
* 商品数组
|
* 商品数组
|
||||||
*/
|
*/
|
||||||
private List<Integer> items;
|
private List<Item> items;
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
private static class Item {
|
public static class Item {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SKU 编号
|
* SKU 编号
|
||||||
@ -36,6 +36,14 @@ public class CalcOrderPriceDTO {
|
|||||||
*/
|
*/
|
||||||
private Boolean selected;
|
private Boolean selected;
|
||||||
|
|
||||||
|
public Item() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public Item(Integer skuId, Integer quantity, Boolean selected) {
|
||||||
|
this.skuId = skuId;
|
||||||
|
this.quantity = quantity;
|
||||||
|
this.selected = selected;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
package cn.iocoder.mall.order.biz.convert;
|
||||||
|
|
||||||
|
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||||
|
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||||
|
import org.mapstruct.Mapper;
|
||||||
|
import org.mapstruct.factory.Mappers;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface CartConvert {
|
||||||
|
|
||||||
|
CartConvert INSTANCE = Mappers.getMapper(CartConvert.class);
|
||||||
|
|
||||||
|
CalcOrderPriceBO.Item convert(ProductSkuDetailBO sku);
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ package cn.iocoder.mall.order.biz.mock;
|
|||||||
|
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||||
|
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
||||||
@ -17,8 +18,9 @@ import java.util.List;
|
|||||||
* @time 2019-03-24 15:24
|
* @time 2019-03-24 15:24
|
||||||
*/
|
*/
|
||||||
public class ProductSpuServiceMock implements ProductSpuService {
|
public class ProductSpuServiceMock implements ProductSpuService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductSpuDetailBO> getProductSpu(Integer id) {
|
public CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,4 +48,10 @@ public class ProductSpuServiceMock implements ProductSpuService {
|
|||||||
public CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids) {
|
public CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<List<ProductSkuDetailBO>> getProductSkuDetailList(Collection<Integer> ids) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package cn.iocoder.mall.order.biz.service;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
||||||
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
|
import cn.iocoder.mall.order.api.CartService;
|
||||||
|
import cn.iocoder.mall.order.api.bo.CalcOrderPriceBO;
|
||||||
|
import cn.iocoder.mall.order.api.bo.CartBO;
|
||||||
|
import cn.iocoder.mall.order.api.bo.CartItemBO;
|
||||||
|
import cn.iocoder.mall.order.api.bo.OrderCreateBO;
|
||||||
|
import cn.iocoder.mall.order.api.constant.OrderErrorCodeEnum;
|
||||||
|
import cn.iocoder.mall.order.api.dto.CalcOrderPriceDTO;
|
||||||
|
import cn.iocoder.mall.order.biz.convert.CartConvert;
|
||||||
|
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||||
|
import cn.iocoder.mall.product.api.bo.ProductSkuDetailBO;
|
||||||
|
import com.alibaba.dubbo.config.annotation.Reference;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 购物车服务 Service 实现类
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@com.alibaba.dubbo.config.annotation.Service(validation = "true")
|
||||||
|
public class CartServiceImpl implements CartService {
|
||||||
|
|
||||||
|
@Reference(validation = "true")
|
||||||
|
private ProductSpuService productSpuService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> add(Integer userId, Integer skuId, Integer quantity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> updateQuantity(Integer userId, Integer skuId, Integer quantity) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> updateSelected(Integer userId, Integer skuId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> delete(Integer userId, List<Integer> skuIds) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Boolean> deleteAll(Integer userId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<Integer> count(Integer userId, String nobody, Integer shopId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<CartItemBO> list(Integer userId, Boolean selected) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<CalcOrderPriceBO> calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO) {
|
||||||
|
// 校验商品都存在
|
||||||
|
Map<Integer, CalcOrderPriceDTO.Item> calcOrderItemMap = calcOrderPriceDTO.getItems().stream()
|
||||||
|
.collect(Collectors.toMap(CalcOrderPriceDTO.Item::getSkuId, item -> item));
|
||||||
|
List<ProductSkuDetailBO> skus = productSpuService.getProductSkuDetailList(calcOrderItemMap.keySet()).getData();
|
||||||
|
if (skus.size() != calcOrderPriceDTO.getItems().size()) {
|
||||||
|
return ServiceExceptionUtil.error(OrderErrorCodeEnum.ORDER_ITEM_SOME_NOT_EXISTS.getCode());
|
||||||
|
}
|
||||||
|
// TODO 库存相关
|
||||||
|
// TODO 获得促销活动
|
||||||
|
// TODO 处理促销相关信息
|
||||||
|
// 拼装结果
|
||||||
|
CalcOrderPriceBO calcOrderPriceBO = new CalcOrderPriceBO();
|
||||||
|
// 1. 商品分组
|
||||||
|
CalcOrderPriceBO.ItemGroup itemGroup0 = new CalcOrderPriceBO.ItemGroup()
|
||||||
|
.setItems(new ArrayList<>());
|
||||||
|
for (ProductSkuDetailBO sku : skus) {
|
||||||
|
CalcOrderPriceBO.Item item = CartConvert.INSTANCE.convert(sku);
|
||||||
|
// 将是否选中,购物数量,复制到 item 中
|
||||||
|
CalcOrderPriceDTO.Item calcOrderItem = calcOrderItemMap.get(sku.getId());
|
||||||
|
item.setSelected(calcOrderItem.getSelected());
|
||||||
|
item.setBuyQuantity(calcOrderItem.getQuantity());
|
||||||
|
// 添加到 itemGroup 中
|
||||||
|
itemGroup0.getItems().add(item);
|
||||||
|
}
|
||||||
|
calcOrderPriceBO.setItemGroups(Collections.singletonList(itemGroup0));
|
||||||
|
// 2. 计算价格
|
||||||
|
CalcOrderPriceBO.Fee fee = new CalcOrderPriceBO.Fee(0, 0, 0, 0);
|
||||||
|
for (CalcOrderPriceBO.ItemGroup itemGroup : calcOrderPriceBO.getItemGroups()) {
|
||||||
|
int originalTotal = 0;
|
||||||
|
for (CalcOrderPriceBO.Item item : itemGroup.getItems()) {
|
||||||
|
if (!item.getSelected()) { // 未选中,则不计算到其中
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
originalTotal += item.getPrice() * item.getBuyQuantity();
|
||||||
|
}
|
||||||
|
fee.setOriginalTotal(fee.getOriginalTotal() + originalTotal);
|
||||||
|
fee.setPresentTotal(fee.getOriginalTotal()); // TODO 芋艿,后续要计算优惠价格
|
||||||
|
}
|
||||||
|
calcOrderPriceBO.setFee(fee);
|
||||||
|
// 返回
|
||||||
|
return CommonResult.success(calcOrderPriceBO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<CartBO> details(Integer userId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<OrderCreateBO> createOrder(Integer userId) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -157,11 +157,6 @@ public class OrderServiceImpl implements OrderService {
|
|||||||
return CommonResult.success(orderRecipientBO);
|
return CommonResult.success(orderRecipientBO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public CalcOrderPriceBO calcOrderPrice(CalcOrderPriceDTO calcOrderPriceDTO) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public CommonResult<OrderCreateBO> createOrder(OrderCreateDTO orderCreateDTO) {
|
public CommonResult<OrderCreateBO> createOrder(OrderCreateDTO orderCreateDTO) {
|
||||||
|
@ -123,7 +123,7 @@ public class AdminsProductSpuController {
|
|||||||
@ApiOperation("商品 SPU 明细")
|
@ApiOperation("商品 SPU 明细")
|
||||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||||
public CommonResult<AdminsProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
public CommonResult<AdminsProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
||||||
return ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpu(id));
|
return ProductSpuConvert.INSTANCE.convert(productSpuService.getProductSpuDetail(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> List<T> parseSkus(String skuStr, Class<T> clazz) {
|
private <T> List<T> parseSkus(String skuStr, Class<T> clazz) {
|
||||||
|
@ -29,7 +29,7 @@ public class UsersProductSpuController {
|
|||||||
@ApiOperation("商品 SPU 明细")
|
@ApiOperation("商品 SPU 明细")
|
||||||
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
@ApiImplicitParam(name = "id", value = "SPU 编号", required = true, example = "100")
|
||||||
public CommonResult<UsersProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
public CommonResult<UsersProductSpuDetailVO> info(@RequestParam("id") Integer id) {
|
||||||
return ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpu(id));
|
return ProductSpuConvert.INSTANCE.convert4(productSpuService.getProductSpuDetail(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package cn.iocoder.mall.product.api;
|
package cn.iocoder.mall.product.api;
|
||||||
|
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
import cn.iocoder.mall.product.api.bo.*;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuAddDTO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuPageDTO;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSpuUpdateDTO;
|
||||||
@ -13,7 +11,13 @@ import java.util.List;
|
|||||||
|
|
||||||
public interface ProductSpuService {
|
public interface ProductSpuService {
|
||||||
|
|
||||||
CommonResult<ProductSpuDetailBO> getProductSpu(Integer id);
|
CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id);
|
||||||
|
|
||||||
|
CommonResult<ProductSpuPageBO> getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
|
||||||
|
|
||||||
|
CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids);
|
||||||
|
|
||||||
|
CommonResult<List<ProductSkuDetailBO>> getProductSkuDetailList(Collection<Integer> ids);
|
||||||
|
|
||||||
CommonResult<ProductSpuDetailBO> addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO);
|
CommonResult<ProductSpuDetailBO> addProductSpu(Integer adminId, ProductSpuAddDTO productSpuAddDTO);
|
||||||
|
|
||||||
@ -21,8 +25,4 @@ public interface ProductSpuService {
|
|||||||
|
|
||||||
CommonResult<Boolean> updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
|
CommonResult<Boolean> updateProductSpuSort(Integer adminId, Integer spuId, Integer sort);
|
||||||
|
|
||||||
CommonResult<ProductSpuPageBO> getProductSpuPage(ProductSpuPageDTO productSpuPageDTO);
|
|
||||||
|
|
||||||
CommonResult<List<ProductSpuBO>> getProductSpuList(Collection<Integer> ids);
|
|
||||||
|
|
||||||
}
|
}
|
@ -7,7 +7,7 @@ import java.io.Serializable;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 商品 Sku 明细 BO
|
* 商品 Sku 明细 BO(包括 Spu 明细)
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@ -18,9 +18,9 @@ public class ProductSkuDetailBO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer id;
|
private Integer id;
|
||||||
/**
|
/**
|
||||||
* 商品编号
|
* SPU 信息
|
||||||
*/
|
*/
|
||||||
private Integer spuId;
|
private Spu spu;
|
||||||
/**
|
/**
|
||||||
* 图片地址
|
* 图片地址
|
||||||
*/
|
*/
|
||||||
@ -38,4 +38,54 @@ public class ProductSkuDetailBO implements Serializable {
|
|||||||
*/
|
*/
|
||||||
private Integer quantity;
|
private Integer quantity;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public static class Spu implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SPU 编号
|
||||||
|
*/
|
||||||
|
private Integer id;
|
||||||
|
|
||||||
|
// ========== 基本信息 =========
|
||||||
|
/**
|
||||||
|
* SPU 名字
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
/**
|
||||||
|
* 卖点
|
||||||
|
*/
|
||||||
|
private String sellPoint;
|
||||||
|
/**
|
||||||
|
* 描述
|
||||||
|
*/
|
||||||
|
private String description;
|
||||||
|
/**
|
||||||
|
* 分类编号
|
||||||
|
*/
|
||||||
|
private Integer cid;
|
||||||
|
/**
|
||||||
|
* 商品主图地址
|
||||||
|
*
|
||||||
|
* 数组,以逗号分隔
|
||||||
|
*
|
||||||
|
* 建议尺寸:800*800像素,你可以拖拽图片调整顺序,最多上传15张
|
||||||
|
*/
|
||||||
|
private List<String> picUrls;
|
||||||
|
|
||||||
|
// ========== 其他信息 =========
|
||||||
|
/**
|
||||||
|
* 是否上架商品(是否可见)。
|
||||||
|
*
|
||||||
|
* true 为已上架
|
||||||
|
* false 为已下架
|
||||||
|
*/
|
||||||
|
private Boolean visible;
|
||||||
|
/**
|
||||||
|
* 排序字段
|
||||||
|
*/
|
||||||
|
private Integer sort;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -62,6 +62,40 @@ public class ProductSpuDetailBO implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* SKU 数组
|
* SKU 数组
|
||||||
*/
|
*/
|
||||||
private List<ProductSkuDetailBO> skus;
|
private List<Sku> skus;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 商品 Sku 明细 BO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public static class Sku implements Serializable {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* sku 编号
|
||||||
|
*/
|
||||||
|
private Integer id;
|
||||||
|
/**
|
||||||
|
* 商品编号
|
||||||
|
*/
|
||||||
|
private Integer spuId;
|
||||||
|
/**
|
||||||
|
* 图片地址
|
||||||
|
*/
|
||||||
|
private String picURL;
|
||||||
|
/**
|
||||||
|
* 规格值数组
|
||||||
|
*/
|
||||||
|
private List<ProductAttrAndValuePairBO> attrs;
|
||||||
|
/**
|
||||||
|
* 价格,单位:分
|
||||||
|
*/
|
||||||
|
private Integer price;
|
||||||
|
/**
|
||||||
|
* 库存数量
|
||||||
|
*/
|
||||||
|
private Integer quantity;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -58,10 +58,20 @@ public interface ProductSpuConvert {
|
|||||||
})
|
})
|
||||||
ProductSpuDetailBO convert2(ProductSpuDO spu);
|
ProductSpuDetailBO convert2(ProductSpuDO spu);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(source = "picUrls", target = "picUrls", ignore = true)
|
||||||
|
})
|
||||||
|
ProductSkuDetailBO.Spu convert3(ProductSpuDO spu);
|
||||||
|
|
||||||
@Mappings({
|
@Mappings({
|
||||||
@Mapping(source = "attrs", target = "attrs", ignore = true)
|
@Mapping(source = "attrs", target = "attrs", ignore = true)
|
||||||
})
|
})
|
||||||
ProductSkuDetailBO convert2(ProductSkuDO sku);
|
ProductSpuDetailBO.Sku convert2(ProductSkuDO sku);
|
||||||
|
|
||||||
|
@Mappings({
|
||||||
|
@Mapping(source = "attrs", target = "attrs", ignore = true)
|
||||||
|
})
|
||||||
|
ProductSkuDetailBO convert3(ProductSkuDO sku);
|
||||||
|
|
||||||
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
|
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
|
||||||
default ProductSpuDetailBO convert2(ProductSpuDO spu, List<ProductSkuDO> skus, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
default ProductSpuDetailBO convert2(ProductSpuDO spu, List<ProductSkuDO> skus, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
||||||
@ -74,7 +84,7 @@ public interface ProductSpuConvert {
|
|||||||
spuDetail.setSkus(new ArrayList<>());
|
spuDetail.setSkus(new ArrayList<>());
|
||||||
skus.forEach(sku -> {
|
skus.forEach(sku -> {
|
||||||
// 创建 ProductSpuDetailBO 对象
|
// 创建 ProductSpuDetailBO 对象
|
||||||
ProductSkuDetailBO skuDetail = ProductSpuConvert.this.convert2(sku)
|
ProductSpuDetailBO.Sku skuDetail = ProductSpuConvert.this.convert2(sku)
|
||||||
.setAttrs(new ArrayList<>());
|
.setAttrs(new ArrayList<>());
|
||||||
spuDetail.getSkus().add(skuDetail);
|
spuDetail.getSkus().add(skuDetail);
|
||||||
// 设置 ProductSpuDetailBO 的 attrs 规格属性
|
// 设置 ProductSpuDetailBO 的 attrs 规格属性
|
||||||
@ -85,6 +95,30 @@ public interface ProductSpuConvert {
|
|||||||
return spuDetail;
|
return spuDetail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Mappings({}) // TODO 芋艿,后续细看下 mapstruct 的 API ,优化这块
|
||||||
|
default List<ProductSkuDetailBO> convert3(List<ProductSkuDO> skus, List<ProductSpuDO> spus, List<ProductAttrAndValuePairBO> productAttrDetailBOs) {
|
||||||
|
// 创建 ProductAttrDetailBO 的映射。其中,KEY 为 ProductAttrDetailBO.attrValueId ,即规格值的编号
|
||||||
|
Map<Integer, ProductAttrAndValuePairBO> productAttrDetailBOMap = productAttrDetailBOs.stream().collect(
|
||||||
|
Collectors.toMap(ProductAttrAndValuePairBO::getAttrValueId, productAttrDetailBO -> productAttrDetailBO));
|
||||||
|
// 创建 ProductSpuDO 的映射
|
||||||
|
Map<Integer, ProductSkuDetailBO.Spu> spuMap = spus.stream().collect(
|
||||||
|
Collectors.toMap(ProductSpuDO::getId, spu -> ProductSpuConvert.this.convert3(spu).setPicUrls(StringUtil.split(spu.getPicUrls(), ","))));
|
||||||
|
// 拼装结果
|
||||||
|
List<ProductSkuDetailBO> spuDetailList = new ArrayList<>(skus.size());
|
||||||
|
for (ProductSkuDO sku : skus) {
|
||||||
|
// 创建 ProductSkuDetailBO 对象
|
||||||
|
ProductSkuDetailBO skuDetail = ProductSpuConvert.this.convert3(sku)
|
||||||
|
.setAttrs(new ArrayList<>())
|
||||||
|
.setSpu(spuMap.get(sku.getSpuId()));
|
||||||
|
spuDetailList.add(skuDetail);
|
||||||
|
// 设置 ProductSpuDetailBO 的 attrs 规格属性
|
||||||
|
List<String> attrs = StringUtil.split(sku.getAttrs(), ",");
|
||||||
|
attrs.forEach(attr -> skuDetail.getAttrs().add(productAttrDetailBOMap.get(Integer.valueOf(attr))));
|
||||||
|
}
|
||||||
|
// 返回
|
||||||
|
return spuDetailList;
|
||||||
|
}
|
||||||
|
|
||||||
@Named("translatePicUrlsFromString")
|
@Named("translatePicUrlsFromString")
|
||||||
default List<String> translatePicUrlsFromString(String picUrls) {
|
default List<String> translatePicUrlsFromString(String picUrls) {
|
||||||
return StringUtil.split(picUrls, ",");
|
return StringUtil.split(picUrls, ",");
|
||||||
|
@ -4,6 +4,7 @@ import cn.iocoder.mall.product.dataobject.ProductSkuDO;
|
|||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Repository
|
@Repository
|
||||||
@ -11,6 +12,8 @@ public interface ProductSkuMapper {
|
|||||||
|
|
||||||
ProductSkuDO selectById(Integer id);
|
ProductSkuDO selectById(Integer id);
|
||||||
|
|
||||||
|
List<ProductSkuDO> selectByIds(@Param("ids") Collection<Integer> ids);
|
||||||
|
|
||||||
List<ProductSkuDO> selectListBySpuIdAndStatus(@Param("spuId") Integer spuId,
|
List<ProductSkuDO> selectListBySpuIdAndStatus(@Param("spuId") Integer spuId,
|
||||||
@Param("status") Integer status);
|
@Param("status") Integer status);
|
||||||
|
|
||||||
|
@ -6,10 +6,7 @@ import cn.iocoder.common.framework.util.ServiceExceptionUtil;
|
|||||||
import cn.iocoder.common.framework.util.StringUtil;
|
import cn.iocoder.common.framework.util.StringUtil;
|
||||||
import cn.iocoder.common.framework.vo.CommonResult;
|
import cn.iocoder.common.framework.vo.CommonResult;
|
||||||
import cn.iocoder.mall.product.api.ProductSpuService;
|
import cn.iocoder.mall.product.api.ProductSpuService;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductAttrAndValuePairBO;
|
import cn.iocoder.mall.product.api.bo.*;
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuBO;
|
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuDetailBO;
|
|
||||||
import cn.iocoder.mall.product.api.bo.ProductSpuPageBO;
|
|
||||||
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
|
import cn.iocoder.mall.product.api.constant.ProductErrorCodeEnum;
|
||||||
import cn.iocoder.mall.product.api.constant.ProductSpuConstants;
|
import cn.iocoder.mall.product.api.constant.ProductSpuConstants;
|
||||||
import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
|
import cn.iocoder.mall.product.api.dto.ProductSkuAddOrUpdateDTO;
|
||||||
@ -44,14 +41,14 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
private ProductAttrServiceImpl productAttrService;
|
private ProductAttrServiceImpl productAttrService;
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
// public ProductSpuBO getProductSpu(Integer id) {
|
// public ProductSpuBO getProductSpuDetail(Integer id) {
|
||||||
// ProductSpuDO productSpuDO = productSpuMapper.selectById(id);
|
// ProductSpuDO productSpuDO = productSpuMapper.selectById(id);
|
||||||
// // 转换成 BO
|
// // 转换成 BO
|
||||||
// return ProductSpuConvert.INSTANCE.convert(productSpuDO);
|
// return ProductSpuConvert.INSTANCE.convert(productSpuDO);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommonResult<ProductSpuDetailBO> getProductSpu(Integer id) {
|
public CommonResult<ProductSpuDetailBO> getProductSpuDetail(Integer id) {
|
||||||
// 校验商品 spu 存在
|
// 校验商品 spu 存在
|
||||||
ProductSpuDO spu = productSpuMapper.selectById(id);
|
ProductSpuDO spu = productSpuMapper.selectById(id);
|
||||||
if (spu == null) {
|
if (spu == null) {
|
||||||
@ -64,9 +61,6 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||||
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||||
false); // 读取规格时,不考虑规格是否被禁用
|
false); // 读取规格时,不考虑规格是否被禁用
|
||||||
if (validAttrResult.isError()) {
|
|
||||||
return CommonResult.error(validAttrResult);
|
|
||||||
}
|
|
||||||
// 返回成功
|
// 返回成功
|
||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData()));
|
return CommonResult.success(ProductSpuConvert.INSTANCE.convert2(spu, skus, validAttrResult.getData()));
|
||||||
}
|
}
|
||||||
@ -219,6 +213,27 @@ public class ProductSpuServiceImpl implements ProductSpuService {
|
|||||||
return CommonResult.success(ProductSpuConvert.INSTANCE.convert(spus));
|
return CommonResult.success(ProductSpuConvert.INSTANCE.convert(spus));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommonResult<List<ProductSkuDetailBO>> getProductSkuDetailList(Collection<Integer> ids) {
|
||||||
|
// 查询 SKU 数组
|
||||||
|
List<ProductSkuDO> skus = productSkuMapper.selectByIds(ids);
|
||||||
|
if (skus.isEmpty()) {
|
||||||
|
return CommonResult.success(Collections.emptyList());
|
||||||
|
}
|
||||||
|
// 查询 SPU 数组
|
||||||
|
List<ProductSpuDO> spus = productSpuMapper.selectByIds(skus.stream().map(ProductSkuDO::getSpuId).collect(Collectors.toSet()));
|
||||||
|
if (spus.isEmpty()) {
|
||||||
|
return CommonResult.success(Collections.emptyList());
|
||||||
|
}
|
||||||
|
// 获得规格
|
||||||
|
Set<Integer> productAttrValueIds = new HashSet<>();
|
||||||
|
skus.forEach(sku -> productAttrValueIds.addAll(StringUtil.splitToInt(sku.getAttrs(), ",")));
|
||||||
|
CommonResult<List<ProductAttrAndValuePairBO>> validAttrResult = productAttrService.validProductAttrAndValue(productAttrValueIds,
|
||||||
|
false); // 读取规格时,不考虑规格是否被禁用
|
||||||
|
// 返回成功
|
||||||
|
return CommonResult.success(ProductSpuConvert.INSTANCE.convert3(skus, spus, validAttrResult.getData()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验 sku 是否合法
|
* 校验 sku 是否合法
|
||||||
*
|
*
|
||||||
|
@ -12,7 +12,18 @@
|
|||||||
<include refid="FIELDS" />
|
<include refid="FIELDS" />
|
||||||
FROM product_sku
|
FROM product_sku
|
||||||
WHERE id = #{id}
|
WHERE id = #{id}
|
||||||
AND delete = 0
|
AND deleted = 0
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="selectByIds" resultType="ProductSkuDO">
|
||||||
|
SELECT
|
||||||
|
<include refid="FIELDS" />
|
||||||
|
FROM product_sku
|
||||||
|
WHERE id IN
|
||||||
|
<foreach item="id" collection="ids" separator="," open="(" close=")" index="">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
AND deleted = 0
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
<insert id="insertList" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
|
||||||
|
@ -93,9 +93,6 @@
|
|||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
<configuration>
|
|
||||||
<fork>true</fork>
|
|
||||||
</configuration>
|
|
||||||
</plugin>
|
</plugin>
|
||||||
|
|
||||||
</plugins>
|
</plugins>
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package cn.iocoder.mall.promotion.api.constant;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 推广活动类型枚举
|
||||||
|
*/
|
||||||
|
public enum PromotionActivityTypeEnum {
|
||||||
|
|
||||||
|
LIMIT_DISCOUNT(1, "限时折扣"),
|
||||||
|
MEET_REDUCE(2, "满减送"),
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型值
|
||||||
|
*/
|
||||||
|
private final Integer value;
|
||||||
|
/**
|
||||||
|
* 类型名
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
PromotionActivityTypeEnum(Integer value, String name) {
|
||||||
|
this.value = value;
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package cn.iocoder.mall.promotion.biz.dataobject;
|
||||||
|
|
||||||
|
import cn.iocoder.common.framework.dataobject.BaseDO;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.experimental.Accessors;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 促销活动 DO
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Accessors(chain = true)
|
||||||
|
public class PromotionActivityDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 活动编号
|
||||||
|
*/
|
||||||
|
private Integer id;
|
||||||
|
/**
|
||||||
|
* 活动标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 活动类型
|
||||||
|
*/
|
||||||
|
private Integer type;
|
||||||
|
|
||||||
|
}
|
@ -58,7 +58,7 @@ public class ProductRecommendServiceImpl implements ProductRecommendService {
|
|||||||
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "推荐类型必须是新品(1)或热卖(2)"); // TODO 有点搓
|
return CommonResult.error(SysErrorCodeEnum.VALIDATION_REQUEST_PARAM_ERROR.getCode(), "推荐类型必须是新品(1)或热卖(2)"); // TODO 有点搓
|
||||||
}
|
}
|
||||||
// 校验商品不存在
|
// 校验商品不存在
|
||||||
if (productSpuService.getProductSpu(productRecommendAddDTO.getProductSpuId()) == null) {
|
if (productSpuService.getProductSpuDetail(productRecommendAddDTO.getProductSpuId()) == null) {
|
||||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
|
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
|
||||||
}
|
}
|
||||||
// 校验商品是否已经推荐
|
// 校验商品是否已经推荐
|
||||||
@ -84,7 +84,7 @@ public class ProductRecommendServiceImpl implements ProductRecommendService {
|
|||||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
|
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_NOT_EXISTS.getCode());
|
||||||
}
|
}
|
||||||
// 校验商品不存在
|
// 校验商品不存在
|
||||||
if (productSpuService.getProductSpu(productRecommendUpdateDTO.getProductSpuId()) == null) {
|
if (productSpuService.getProductSpuDetail(productRecommendUpdateDTO.getProductSpuId()) == null) {
|
||||||
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
|
return ServiceExceptionUtil.error(PromotionErrorCodeEnum.PRODUCT_RECOMMEND_PRODUCT_NOT_EXISTS.getCode());
|
||||||
}
|
}
|
||||||
// 校验商品是否已经推荐
|
// 校验商品是否已经推荐
|
||||||
|
Loading…
Reference in New Issue
Block a user