目录
后端实现:JavaBean
步骤一:页面加载成功,查询已经勾选商品
async mounted() {
// 查询收获人地址
this.getAddressFn()
//2 查询需要购买的物品
let { data : cart } = await this.$request.getCart()
this.cart = cart.data.filter( g => {
//return true 数据返回,return false 数据被忽略
return g.checked;
});
},
步骤二:展示商品基本信息
<tbody>
<tr v-for="(goods,index) in cart" :key="index">
<td class="col1">
<a href=""><img :src="goods.midlogo" alt="" /></a>
<strong><a href="">{{goods.goods_name}}</a></strong>
</td>
<td class="col2">
<span style="display: block;" v-for="(value,key,index) in JSON.parse(JSON.parse(goods.spec_info).id_txt)"
:key="index">{{key}}:{{value}}</span>
</td>
<td class="col3">¥<span>{{ (goods.price/100).toFixed(2) }}</span> </td>
<td class="col4">{{goods.count}}</td>
<td class="col5"><span>¥{{ (goods.price / 100 * goods.count).toFixed(2) }}</span></td>
</tr>
</tbody>
步骤三:展示商品概述信息
步骤四:使用计算属性显示总价格
computed: {
totalPrice : function(){ //计算总价格
//所有小计的和
let sum = 0 ;
this.cart.forEach( g => {
sum += (g.price * g.count);
});
return (sum/100).toFixed(2);
}
},
POST http://localhost:10010/order-service/orders
{
"address_id": 1,
"post_method": "",
"pay_method ": "",
"invoice": {}
}
PUT http://localhost:10010/web-service/sku/goods/2600242?count=1
OrderVo:用于封装请求数据
OrderGoods:订单详情封装对象
Order:订单表封装对象
OrderVo:用于封装请求数据
package com.czxy.changgou4.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.Map;
/**
*
*/
@Data
public class OrderVo {
//收货人地址ID
@JsonProperty("address_id")
private Integer addressId;
//送货方式
@JsonProperty("post_method")
private Integer postMethod;
//支付方式
@JsonProperty("pay_method")
private Integer payMethod;
//发票
private Map<Object,Object> invoice;
}
OrderGoods:订单详情封装对象
package com.czxy.changgou4.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.core.annotation.Order;
import java.io.Serializable;
/**
*
*/
@TableName("tb_order_good")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class OrderGoods implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
@TableField(value ="sn")
private Long sn;
@TableField(exist = false)
private Order order;
@TableField(value ="sku_id")
private Integer skuId;
@TableField(exist = false)
private Sku sku;
@TableField(value ="spu_id")
private Integer spuId;
//购买数量
@TableField(value ="number")
private Integer number;
//规格列表
@TableField(value ="spec_list")
private String specList;
//商品名称
@TableField(value ="sku_name")
private String skuName;
@TableField(value ="url")
private String logo;
//价格
@TableField(value ="price")
private Double price;
}
Order:订单表封装对象
package com.czxy.changgou4.pojo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
/**
* @author 桐叔
* @email liangtong@itcast.cn
*/
@TableName("tb_order")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order implements Serializable {
//订单序列号
@TableField(value ="sn")
//转换JSON时,将Long转换String,解决精度丢失问题
@JsonSerialize(using= ToStringSerializer.class)
private Long sn;
@TableField(value ="created_at")
private Date createdAt;
@TableField(value ="updated_at")
private Date updatedAt;
//收货人姓名
@TableField(value ="shr_name")
private String shrName;
//收货人手机
@TableField(value ="shr_mobile")
private String shrMobile;
//收货人省份
@TableField(value ="shr_province")
private String shrProvince;
//收货人城市
@TableField(value ="shr_city")
private String shrCity;
//收货人地区
@TableField(value ="shr_area")
private String shrArea;
//收货人详情地址
@TableField(value ="shr_address")
private String shrAddress;
//订单状态,0:未支付、1:已支付、等待发货、2:已发货、等待收货 3:已收货、等待评论 4:已结束 5:申请售后
@TableField(value ="status")
private Integer status;
//支付时间
@TableField(value ="pay_time")
private String payTime;
//发货时间
@TableField(value ="post_time")
private String postTime;
//用户ID
@TableField(value ="user_id")
private Integer userId;
@TableField(exist = false)
private User user;
//订单总价
@TableField(value ="total_price")
private Double totalPrice;
}
需求:在web服务中,更新sku的库存
步骤一:修改service,完成更新操作
/**
* 更新
* @param skuid
* @param count
*/
public void updateSkuNum(Integer skuid, Integer count);
步骤二:编写service实现类
@Override
public void updateSkuNum(Integer skuid, Integer count) {
// 查询
Sku sku = baseMapper.selectById(skuid);
// 修改数据
sku.setStock( sku.getStock() - count);
// 更新
baseMapper.updateById(sku);
}
步骤三:编写controller
/**
* 更新
* @param skuid
* @param count
* @return
*/
@PutMapping("/goods/{skuid}")
public BaseResult updateSkuNum(@PathVariable("skuid") Integer skuid , @RequestParam("count") Integer count){
skuService.updateSkuNum(skuid , count);
return BaseResult.ok("更新成功");
}
步骤一:雪花算法工具类
package com.czxy.changgou4.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
@Data
@ConfigurationProperties(prefix = "sc.worker")
public class IdWorkerProperties {
private long workerId;// 当前机器id
private long datacenterId;// 序列号
}
package com.czxy.changgou4.config;
import com.czxy.changgou4.utils.IdWorker;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableConfigurationProperties(IdWorkerProperties.class)
public class IdWorkerConfig {
@Bean
public IdWorker idWorker(IdWorkerProperties prop) {
return new IdWorker(prop.getWorkerId(), prop.getDatacenterId());
}
}
步骤二:编写SkuFeign,远程更新库存数量
package com.czxy.changgou4.feign;
import com.czxy.changgou4.vo.BaseResult;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestParam;
@FeignClient(value = "web-service",path = "/sku")
public interface SkuFeign {
@PutMapping("/goods/{skuid}")
public BaseResult updateSkuNum(@PathVariable("skuid") Integer skuid , @RequestParam("count") Integer count);
}
步骤三:编写mapper
package com.czxy.changgou4.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.czxy.changgou4.pojo.OrderGoods;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface OrderGoodsMapper extends BaseMapper<OrderGoods> {
}
package com.czxy.changgou4.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.czxy.changgou4.pojo.Order;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface OrderMapper extends BaseMapper<Order> {
}
步骤四:编写service接口
package com.czxy.changgou4.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.czxy.changgou4.pojo.Order;
import com.czxy.changgou4.pojo.User;
import com.czxy.changgou4.vo.CartVo;
import com.czxy.changgou4.vo.OrderVo;
import java.util.List;
public interface OrderService extends IService<Order> {
/**
*
* @param user
* @param orderVo
* @return
*/
public Long createOrder(User user , OrderVo orderVo);
}
步骤五:编写service实现类
package com.czxy.changgou4.service.impl;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.czxy.changgou4.cart.Cart;
import com.czxy.changgou4.cart.CartItem;
import com.czxy.changgou4.feign.SkuFeign;
import com.czxy.changgou4.mapper.AddressMapper;
import com.czxy.changgou4.mapper.OrderGoodsMapper;
import com.czxy.changgou4.mapper.OrderMapper;
import com.czxy.changgou4.pojo.Address;
import com.czxy.changgou4.pojo.Order;
import com.czxy.changgou4.pojo.OrderGoods;
import com.czxy.changgou4.pojo.User;
import com.czxy.changgou4.service.OrderService;
import com.czxy.changgou4.utils.IdWorker;
import com.czxy.changgou4.vo.CartVo;
import com.czxy.changgou4.vo.OrderVo;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.*;
@Service
@Transactional
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {
@Resource
private IdWorker idWorker;
@Resource
private AddressMapper addressMapper;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Resource
private OrderMapper orderMapper;
@Resource
private OrderGoodsMapper orderGoodsMapper;
@Resource
private SkuFeign skuFeign;
public Long createOrder(User user , OrderVo orderVo) {
//1 生成订单
Order order = new Order();
//1.1 设置订单号
// 生成orderId
long sn = idWorker.nextId();
order.setSn(sn);
//1.2 设置用户信息
order.setUserId(user.getId());
//1.3 设置地址信息
// 获得前台传输过来的收货地址和收货人信息,生成订单,保存到数据库
Address address = addressMapper.selectById(orderVo.getAddressId());
order.setShrName(address.getShrName());
order.setShrMobile(address.getShrMobile());
order.setShrProvince(address.getShrProvince());
order.setShrCity(address.getShrCity());
order.setShrArea(address.getShrArea());
order.setShrAddress(address.getShrAddress());
//1.4 设置状态:创建订单的时候,默认情况是未支付状态
order.setStatus(0);
order.setCreatedAt(new Date());
//2 获得购物车:从redis获得当前用户对应的购物车
String key = "cart" + user.getId();
String cartJsonStr = stringRedisTemplate.opsForValue().get(key);
Cart cart = JSON.parseObject(cartJsonStr, Cart.class);
//1.5 设置总价格
order.setTotalPrice(cart.getTotal());
//1.6 保存订单
orderMapper.insert(order);
//3 保存购物车中已经勾选的商品信息
// 3.1 遍历购物项
Iterator<CartItem> it = cart.getData().values().iterator();
while (it.hasNext()) {
CartItem cartItem = it.next();
if (cartItem.getChecked()) {
// 3.2 将购物车中商品的信息赋值给OrderGoods
OrderGoods orderGoods = new OrderGoods();
orderGoods.setSn(idWorker.nextId());
orderGoods.setSkuId(cartItem.getSkuid());
orderGoods.setSpuId(cartItem.getSpuid());
orderGoods.setNumber(cartItem.getCount());
orderGoods.setSpecList(cartItem.getSpecInfo());
orderGoods.setSkuName(cartItem.getGoodsName());
orderGoods.setLogo(cartItem.getMidlogo());
orderGoods.setPrice(cartItem.getPrice());
// 3.3 保存购物车中的商品信息
orderGoodsMapper.insert(orderGoods);
// 3.4 购物车中移除该商品
it.remove();
// 3.5 远程调用方法,将该商品的数量减少
skuFeign.updateSkuNum(cartItem.getSkuid(), cartItem.getCount());
}
}
//3.6 更新redis购物车
stringRedisTemplate.opsForValue().set(key, JSON.toJSONString(cart));
//4 返回sn
return sn;
}
}
步骤五:编写controller
package com.czxy.changgou4.controller;
import com.czxy.changgou4.config.JwtProperties;
import com.czxy.changgou4.pojo.User;
import com.czxy.changgou4.service.OrderService;
import com.czxy.changgou4.utils.JwtUtils;
import com.czxy.changgou4.vo.BaseResult;
import com.czxy.changgou4.vo.OrderVo;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/orders")
public class OrderController {
@Resource
private OrderService orderService;
@Resource
private HttpServletRequest request;
@Resource
private JwtProperties jwtProperties;
@PostMapping
public BaseResult createOrder(@RequestBody OrderVo orderVo) {
//1 获得用户信息
// 1.1 获得token
String token = request.getHeader("Authorization");
// 1.2 解析token
User loginUser = null;
try {
loginUser = JwtUtils.getObjectFromToken(token, jwtProperties.getPublicKey(),User.class);
} catch (Exception e) {
return BaseResult.error("token失效或未登录");
}
Long sn = this.orderService.createOrder(loginUser , orderVo);
//将Long转换成字符串,否则丢失数据精度
return BaseResult.ok("订单创建成功").append("sn", sn + "");
}
}
步骤一:修改api.js,编写添加订单函数
addOrder : ( orderVo ) => {
return axios.post("/order-service/orders", orderVo )
},
步骤二:给“提交订单”按钮绑定点击事件
<a href="" @click.prevent="addOrderFn"><span>提交订单</span></a>
步骤三:添加订单操作
async addOrderFn (){
//准备数据
let order = {
address_id: this.selectAddressId,
// post_method:"送货方式",
// pay_method:"支付方式",
// invoice:{
// type:"发票类型",
// company:"单位"
// }
}
//发送ajax
let { data } = await this.$request.addOrder( order )
if( data.code == 20000 ){
//成功,跳转到 flow3.html页面,参数为订单编号
this.$router.push('flow3?sn=' + data.other.sn)
} else {
alert( data.message );
}
}
步骤四:成功提交后