购物车下单

一、商品结算页

实现思路

1.购物车页面实现结算功能,主要是拿到传入后台的gids
2.跳转订单页后台,主要是拿到订单页展示数据
3.订单页前台数据展示

1、购物车页面实现结算功能

注:使用jquery动态实现结算功能,必须勾选购物车中的商品进行结算,没有勾选无法完成结算功能!!!

cart.js:

$(function(){
	/**************数量加减***************/
	$(".num .sub").click(function(){
		var num = parseInt($(this).siblings("span").text());
		if(num<=1){
			$(this).attr("disabled","disabled");
		}else{
			num--;
			$(this).siblings("span").text(num);
			//获取除了货币符号以外的数字
			var price = $(this).parents(".number").prev().text().substring(1);
			//单价和数量相乘并保留两位小数
			$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));
			jisuan();
			zg();

			//TODO 获取当前行的行索引
			let index = $(this).parents(".th").index()-1;
			//获取当前的checkbox中设置的隐藏域(包含了商品ID)
			let gid=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();
			update(num,gid);
		}
	});
	$(".num .add").click(function(){
		var num = parseInt($(this).siblings("span").text());
		if(num>=5){
			confirm("限购5件");
		}else{
			num++;
			$(this).siblings("span").text(num);
			var price = $(this).parents(".number").prev().text().substring(1);
			$(this).parents(".th").find(".sAll").text('¥'+(num*price).toFixed(2));
			jisuan();
			zg();

			//TODO 获取当前行的行索引
			let index = $(this).parents(".th").index()-1;
			//获取当前的checkbox中设置的隐藏域(包含了商品ID)
			let gid=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();
			update(num,gid);
		}
	});
	//计算总价
	function jisuan(){
		var all=0;
		var len =$(".th input[type='checkbox']:checked").length;
		if(len==0){
			$("#all").text('¥'+parseFloat(0).toFixed(2));
		}else{
			$(".th input[type='checkbox']:checked").each(function(){
				//获取小计里的数值
				var sAll = $(this).parents(".pro").siblings('.sAll').text().substring(1);
				//累加
				all+=parseFloat(sAll);
				//赋值
				$("#all").text('¥'+all.toFixed(2));
			})
		}

	}
	//计算总共几件商品
	function zg(){
		let gids = "";
		var zsl = 0;
		var index = $(".th input[type='checkbox']:checked").parents(".th").find(".num span");
		var len =index.length;
		if(len==0){
			$("#sl").text(0);
		}else{
			let gidarr = new Array();
			index.each(function(){
				zsl+=parseInt($(this).text());
				$("#sl").text(zsl);

				//TODO	获取当前行的索引
				let idx = $(this).parents(".th").index()-1;
				console.log(idx);
				//在这里需要获取当前行商品的商品ID
				gidarr.push($(".th").eq(idx).find("div:eq(0) input[type='hidden']").val());
			})
			gids = gidarr.join(",");
		}
		if($("#sl").text()>0){
			$(".count").css("background","#c10000");
			$(".count").bind("click",function () {
				location.href='/order/toOrder?gids='+gids
			})
		}else{
			$(".count").css("background","#8e8e8e");
			$(".count").unbind("click");
		}
	}
	/*****************商品全选***********************/
	$("input[type='checkbox']").on('click',function(){
		var sf = $(this).is(":checked");
		var sc= $(this).hasClass("checkAll");
		if(sf){
			if(sc){
				$("input[type='checkbox']").each(function(){
					this.checked=true;
				});
				zg();
				jisuan();
			}else{
				$(this).checked=true;
				var len = $("input[type='checkbox']:checked").length;
				var len1 = $("input").length-1;
				if(len==len1){
					$("input[type='checkbox']").each(function(){
						this.checked=true;
					});
				}
				zg();
				jisuan();
			}
		}else{
			if(sc){
				$("input[type='checkbox']").each(function(){
					this.checked=false;
				});
				zg();
				jisuan();
			}else{
				$(this).checked=false;
				var len = $(".th input[type='checkbox']:checked").length;
				var len1 = $("input").length-1;
				if(len<len1){
					$('.checkAll').attr("checked",false);
				}
				zg();
				jisuan();
			}
		}

	});
	/****************************proDetail 加入购物车*******************************/
	$(".btns .cart").click(function(){
		if($(".categ p").hasClass("on")){
			var num = parseInt($(".num span").text());
			var num1 = parseInt($(".goCart span").text());
			$(".goCart span").text(num+num1);
		}
	});

	//删除购物车商品
	$('.del').click(function(){
		//定义商品id	1,2,3,4,5,6
		let gids = "";
		//单个删除
		if($(this).parent().parent().hasClass("th")){
			$(".mask").show();
			$(".tipDel").show();
			index = $(this).parents(".th").index()-1;

			//TODO 获取当前的checkbox中设置的隐藏域(包含了商品ID)
			gids=$(".th").eq(index).find('div:eq(0) input[type=hidden]').val();

			$('.cer').click(function(){
				$(".mask").hide();
				$(".tipDel").hide();
				$(".th").eq(index).remove();
				$('.cer').off('click');
				if($(".th").length==0){
					$(".table .goOn").show();
				}

				del(gids);
			})
		}else{
			//选中多个一起删除
			if($(".th input[type='checkbox']:checked").length==0){
				$(".mask").show();
				$(".pleaseC").show();
			}
			else{
				$(".mask").show();
				$(".tipDel").show();

				let gidarr = new Array();// {1,2,3,4,5,6}
				$(".th input[type='checkbox']:checked").each(function(j){
					gidarr.push($(".th").eq(index).find('div:eq(0) input[type=hidden]').val());
					// gids += $(".th").eq(index).find('div:eq(0) input[type=hidden]').val() + ",";
				});
				gids = gidarr.join(",");

				$('.cer').click(function(){
					$(".th input[type='checkbox']:checked").each(function(j){
						index = $(this).parents('.th').index()-1;
						$(".th").eq(index).remove();
						if($(".th").length==0){
							$(".table .goOn").show();
						}
					})
					$(".mask").hide();
					$(".tipDel").hide();
					zg();
					jisuan();

					del(gids);
				})
			}
		}
	})
	$('.cancel').click(function(){
		$(".mask").hide();
		$(".tipDel").hide();
	})
	//改变商品规格
//	$(".pro dd").hover(function(){
//		var html='';
//		html='<span class="edit">修改</span>';
//		$(this).addClass("on").append(html).parents(".th").siblings(".th").find(".pro dd").removeClass("on").find('.edit').remove();
//		$(".edit").each(function(i){
//			$(this).attr("id",'edit'+i);
//			$("#edit"+i).click(function(){
//				$(".proDets").show();
//				$(".mask").show();
//				$(".changeBtn .buy").attr("data-id",i);
//			})
//		})
//	},function(){
//		$(this).removeClass("on");
//	})
//	$(".changeBtn .buy").click(function(){
//		var index = $(this).attr("data-id");
//		var result = $(".smallImg .on").find("img").attr("alt");
//		$("#edit"+index).prev().text(result);
//		$(".proDets").hide();
//		$(".mask").hide();
//		$("#edit"+index).parent("dd").removeClass("on").find(".edit").remove();
//	});
//	$(".changeBtn .cart").click(function(){
//		$(".proDets").hide();
//		$(".mask").hide();
//	})
})
//删除商品
function del(gids){
	$.post('/shopCar/delete',{
		'gids':gids
	},function(rs){
		if(rs.code!=200)
			alert(rs.msg);
		else
			location.href='/shopCar/queryShopCar';
	},'json');
}

//更新商品数量
function update(num,gid){
	$.post('/shopCar/update',{
		'gid':gid,
		'quantity':num
	},function(rs){
		if(rs.code!=200)
			alert(rs.msg);
		else
			location.href='/shopCar/queryShopCar';
	},'json');
}

测试结果,当点击结算,会跳转访问地址http://localhost:8081/order/toOrder?gids=2,22;
说明gids的值是已经拿到了;

2、跳转订单页后台

1.从session中获取购物车对象
2.筛选出要结算的订单项列表集合

OrderController.java

package com.xnx.spbootpro.controller;


import com.alipay.easysdk.factory.Factory;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.xnx.spbootpro.config.AlipayConfig;
import com.xnx.spbootpro.model.Goods;
import com.xnx.spbootpro.model.Order;
import com.xnx.spbootpro.model.User;
import com.xnx.spbootpro.model.dto.OrderDto;
import com.xnx.spbootpro.model.vo.ShopCar;
import com.xnx.spbootpro.model.vo.ShopCarItem;
import com.xnx.spbootpro.service.IOrderService;
import com.xnx.spbootpro.utils.JsonResponseBody;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 订单信息表 前端控制器
 * </p>
 *
 * @author xnx
 * @since 2022-11-08
 */
@Controller
@RequestMapping("/order")
public class OrderController {

    @RequestMapping("/toOrder")
    public ModelAndView toOrder(String gids, HttpServletRequest request,User user){
        ModelAndView mv = new ModelAndView();
//        拿到购物车中的所有商品  3
        ShopCar shopCar = getShopCar(user, request);
//        通过gids从购物车中筛选出指定的商品 2
        List<ShopCarItem> list = getGoods(shopCar,gids);
        mv.addObject("goods",list);
        mv.setViewName("order.html");
        return mv;
    }

    //        通过gids从购物车中筛选出指定的商品 2
    private List<ShopCarItem> getGoods(ShopCar shopCar, String gids) {
        List<String> gidList = Arrays.asList(gids.split(","));
        List<ShopCarItem> items = shopCar.getItems();//3个 购物车里的商品
        List<ShopCarItem> itemsNew = new ArrayList<>();//2个 购物车中要结算的商品
        for (ShopCarItem item : items) {
            if (gidList.contains(item.getGid()+"")){
                itemsNew.add(item);
            }
        }
        return itemsNew;
    }

    //    从session中获取购物车对象
    private ShopCar getShopCar(User user, HttpServletRequest request){
        HttpSession session = request.getSession();
        ShopCar shopCar = (ShopCar)session.getAttribute(user.getId()+"_shopCar");
        if (shopCar == null){
            shopCar = new ShopCar();
            session.setAttribute(user.getId()+"_shopCar",shopCar);
        }
        return shopCar;
    }

    @Autowired
    private IOrderService orderService;

    @RequestMapping("/addOrder")
    @ResponseBody
    public String addOrder(User user,
                                     HttpServletRequest req,
                                     OrderDto orderDto){
        //获取购物车
        ShopCar shopCar = this.getShopCar(user, req);
        //获取结算商品集合
        List<ShopCarItem> shopCarItems = this.getGoods(shopCar, orderDto.getGids());
        //生成订单及订单项
        orderDto.setUserId(user.getId());
        orderService.addOrder(orderDto,shopCarItems);
        //从购物车中删除已结算的商品
        shopCar.delete(orderDto.getGids());
        //跳转支付页面(下节课内容)
        AlipayConfig alipayConfig = new AlipayConfig();
        return alipayConfig.goAlipay(orderDto);
    }

    /**
     * 支付成功后回调处理订单状态,完成整个下单流程的链路
     * @param param
     * @return
     */
    @RequestMapping("/orderFinish")
    public String orderFinish(@RequestParam Map<String, String> param){
        System.out.println("异步回调开始。。。。。。");
        Boolean signVerified=false;

        try {
            System.out.println(param);
            signVerified = Factory.Payment.Common().verifyNotify(param);
            System.out.println(signVerified);
            System.out.println("out_trade_no:"+param.get("out_trade_no"));
            System.out.println("total_amount:"+param.get("total_amount"));
            System.out.println("trade_no:"+param.get("trade_no"));
            if(signVerified){
                //支付成功
                //根据订单编号修改订单状态
                //update t_xxx set xx=?,tt=? where id=?
                orderService.update(new UpdateWrapper<Order>()
                        .set("status",1)
                        .setSql("pay_date=now()")
                        .eq("oid",param.get("out_trade_no")));
                //跳转到支付成功页面
            }else{
                //支付失败
            }


        } catch (Exception e) {
            e.printStackTrace();
        }
        return "ok.html";
    }
}

3、订单页前台展示

order.html

<div class="orderR fr">
					<div class="msg">
						<h3>订单内容<a href="${ctx}/shopCar/queryShopCar" class="fr">返回购物车</a></h3>
						<#if goods??>
							<#list goods as g>
								<ul class="clearfix">
									<li class="fl">
										<img style="height: 87px;width: 87px;" src="${g.goodsImg}">
									</li>
									<li class="fl">
										<p>${g.goodsName}</p>
										<p>颜色分类:烟灰色玻璃瓶</p>
										<p>数量:${g.quantity}</p>
									</li>
									<li class="fr">¥${g.goodsPrice}</li>
								</ul>
							</#list>
						</#if>

					</div>
					<!--------tips---------------->
					<div class="tips">
						<p><span class="fl">商品金额:</span><span class="fr">¥139.8</span></p>
						<p><span class="fl">优惠金额:</span><span class="fr">¥0.00</span></p>
						<p><span class="fl">运费:</span><span class="fr">免运费</span></p>
					</div>
					<!--------tips count---------------->
					<div class="count tips">
						<p><span class="fl">合计:</span><span class="fr">¥${total}</span></p>

					</div>
					<!--<input type="button" name="" value="去支付"> -->
					<a href="javascript:void(0);" class="pay">去支付</a>
				</div>

如下图所示极为成功:
在这里插入图片描述

二、生成订单

实现思路

1.前台订单相关数据获取
2.后台进行下单操作

1、前端相关处理

1)获取收货地址、收货人以及联系电话
2)获取支付方式
3)获取快递方式

Order.html

$(function(){
    $('.pay').click(function(){
        //获取收货地址、联系人、联系电话
        let name=$('.addres').find('div.on div:eq(0)>p:eq(0)').text().trim();
        let address=$('.addres').find('div.on div:eq(1)>p:eq(0)').text();
        let phone=$('.addres').find('div.on div:eq(1)>p:eq(1)').text();
        console.log("name=%s,address=%s,phone=%s",name,address,phone);
        //获取支付方式
        let pay=$('.way').find('img.on').attr('value');
        console.log(pay);
        //获取快递方式
        let dis=$('.dis').find('span.on').text();
        console.log(dis);
        //获取勾选结算的商品ID
        let gids=$('#gids').val();
        //拼接请求参数
        let params={
            gids:gids,
            address:address,
            person:name,
            telephone:phone,
            pay:pay,
            mail:dis
        };
        console.log(params);

        $.post('/order/addOrder',params,function(rs){
            if(rs.code==200){
                location.href='/page/ok.html';
            }else{
                alert(rs.msg);
            }
        },'json');
    });
});

2、后台进行下单操作

OrderController.java
同上一点的OrderController.java
OrderServiceImpl.java:

package com.xnx.spbootpro.service.impl;

import com.xnx.spbootpro.model.Order;
import com.xnx.spbootpro.mapper.OrderMapper;
import com.xnx.spbootpro.model.OrderItem;
import com.xnx.spbootpro.model.dto.OrderDto;
import com.xnx.spbootpro.model.vo.ShopCarItem;
import com.xnx.spbootpro.service.IOrderItemService;
import com.xnx.spbootpro.service.IOrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xnx.spbootpro.utils.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 订单信息表 服务实现类
 * </p>
 *
 * @author xnx
 * @since 2022-11-08
 */
@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private IOrderItemService orderItemService;

    @Transactional
    @Override
    public void addOrder(OrderDto orderDto, List<ShopCarItem> shopCarItems) {
        //1) 生成订单ID
//        相比较于UUID的优点在于,雪花ID可以排序
        SnowFlake snowFlake = new SnowFlake(2, 3);
        Long orderId=snowFlake.nextId();
        orderDto.setOid(orderId);
        //2) 循环勾选的商品集合计算商品总价、获取商品详情集合
        //总价
        BigDecimal total=BigDecimal.valueOf(0);
        //定义商品详情集合
        List<OrderItem> orderItems=new ArrayList<>();
        OrderItem it=null;
        for (ShopCarItem shopCarItem : shopCarItems) {
            //累加小计等于总价
            total=total.add(shopCarItem.smalltotal());
            //初始化OrderItem商品详情对象
            it=new OrderItem();
//          订单项表的ooid为自增,所以不需要设置
            it.setOid(orderId);
            it.setGid(shopCarItem.getGid());
            it.setGoodsName(shopCarItem.getGoodsName());
            it.setGoodsPrice(shopCarItem.getGoodsPrice());
            it.setQuantity(shopCarItem.getQuantity());
            orderItems.add(it);
        }
        orderDto.setTotal(total);

        //1.保存订单
        orderMapper.insert(orderDto);
        //2.保存订单对应的订单项
        orderItemService.saveBatch(orderItems);
    }
}

三、沙箱支付简介

配置沙箱支付

第一步:
1)登陆支付宝:https://open.alipay.com/
2)首页找到进入管理中心 -> 开发工具推荐选择【沙箱】
3)下载安装支付宝开放平台开发助手:
https://opendocs.alipay.com/common/02kipk
4)打开本地支付宝开放平台助手 -> 密钥工具 -> 生成密钥 -> 以默认方式(RSA2和PKCS8)生成应用私钥和应用公钥
5)在沙箱应用的开发信息中选择自定义密钥生成支付宝公钥(基于应用公钥生成支付宝公钥)

第二步:配置沙箱账号(买家)并完成手动充值
https://open.alipay.com/develop/sandbox/account

第三步:下载沙箱支付宝(只支持安卓)
https://open.alipay.com/develop/sandbox/tool/alipayclint

沙箱工具 -> 支付宝客户端沙箱版 -> 请使用浏览器中的扫码功能扫描下载

注:请使用Android手机扫码下载支付宝客户端沙箱版;如需登录,请访问沙箱账号,在商家信息中获取帐密

四、沙箱支付应用

实现思路

1.完成支付宝沙箱支付功能接入
2.支付成功后变更订单状态

1、完成支付宝沙箱支付功能接入

根据官方网站开发文档进行支付宝支付接入
https://opendocs.alipay.com/common/02kg69

AlipayConfig.java:

package com.xnx.spbootpro.config;

import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.payment.page.models.AlipayTradePagePayResponse;
import com.xnx.spbootpro.model.dto.OrderDto;

/**
 * 支付宝沙箱支付
 */
/**
 * @author xnx
 * @create 2022-11-08 16:20
 */
public class AlipayConfig {
    public String goAlipay(OrderDto orderDto){
        try {
            // 1. 设置参数(全局只需设置一次)
            Factory.setOptions(aliconfig());
            // 2. 发起API调用(subject商品标题、outTradeNo订单编号、totalAmount总金额、returnUrl异步通知地址)
            AlipayTradePagePayResponse response = Factory.Payment.Page()
                    .pay(orderDto.getOid()+"",
                            orderDto.getOid()+"",
                            orderDto.getTotal().toString(),
                            "http://localhost:8081/page/ok.html");  //支付成功之后的异步通知(跳出到自己系统的哪个位置)
//                            "http://localhost:8081/order/orderFinish");
            System.out.println(response.body);
            return response.body;
        }  catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

    private Config aliconfig(){
        Config config=new Config();
        //沙箱支付宝地址
        config.gatewayHost="openapi.alipaydev.com";
        //协议https
        config.protocol="https";
        //应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
        config.appId="2021000121688520";
        //支付宝公钥
        config.alipayPublicKey="MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvUzm5DQGaq8E9C8SgKFsHru+6reHfQScSLCw3QS0E58IvFT+usscxzWsyuBTbPJndpZdMXZdjM0BLkG9usmIrx61Ot++WBan1qRhuQi0OmAVGMWKYqBcnbe8TuGd7ipplYNq544uYiHoM/pf6JaVaIlssvTolW4TA22bwnpzsVhM4583fBR4C0G42LRIyLDxAeJ504qYZ3bxil4hxxhVjDRrip/PuEvQXhhB/xQiAO52LJFPHFpf34tkzn38fCRhOYATDUSfpeqN0SdyhgEr7XiyZqHOOK/HFnjd4E5+VRpHDw/cbQr4fK07MX10BKnQiWJ7dkXTcIo6C936YifcBQIDAQAB";
        //签名方式
        config.signType="RSA2";
        //商户私钥(应用私钥),您的PKCS8格式RSA2私钥
        config.merchantPrivateKey="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDOyXz0HJ59v7XUFIJzr8rTUjG/n43AL6lTVEoaJ4su2IRUUoTcgxDCVs21OSokt4zzDCNJDDlvFCeOTNUiJXv3I6VNmk7HtuUw6u92MYOBO9ogc9xcYqDDeZWdG+GO4p+UaqfJmExK3H7QtyC9dzNGk/UCFCqEglKh8hYFXEgPXW6VzZy1H9jwEqwd3HuBwwmRG9J82wwspWL6nDQSPhMfdEa3uWKoHm2SsXPzdxPjm0nnqsE41qYZGCMrocJTbI8tVRZoDapzSRvfoVKPkwACqNWdSyI5emeyPTC3XwDtseuy8GWlPxIBbtm5fxwVQj1XXX8tpje+7LQ/fteQS5NHAgMBAAECggEACohErwJOKEV9c2HgCxhnEkBbfFEaHTHQRAhFBfQBqM8qXkkdr0WVsvBM5fAVb21R5oc1vOC8hCXYpezP5j9Wgw3zu3IilRWBsu4kaDa5ZfmwcHq2PJZhbdNhhXEIGgj868hK53+0UxPL+cF6D2xk1jFvBz4TtFAW+VylNnyuxul56UkMkhIqPwxi4EP5Sb9OooeqYhzdil9RVCdgJcD/aeTY/+gJC7xNkzDEICGS8bLziNWq/Yn1aKc4N7kOAy2M8Dpx3bzH1LLzCVcnBspuCLyodExikU8VirDdJVsoExjdU6EX6Pae34PM0TJxE4agkRMNbP5426QX4L/tNxQukQKBgQDqeLLNE/a3uwiI48IGI5aWEacBO17Iiqdz5fDNEbvf6d7qSFLyBgPxgk/HmuccpuYsLKqvCjI7lQwTfiD5NDUJ5ktHvDyhTCqzssyMw/nS2UqdUB2kq5LF5JRdMU/CNSIZuLAkxaemwNnAZqOmlDgqY1oTW0U1nFRhfjY/OxILZQKBgQDhxg/HQsW2NGCnFpsu1QBmeP24bKTwGKV0GzYKHgYs2iVSQP+ZTEH1H7GjsAPXsg4jbBFqvw7yNv/ghCUU4FzIyLI3kpyccUwi0qBJZ3q+LLB/F5T1hmpniMIluKdLIC2fBAkR7uOp+fk76YnWSurGvluUT9sdRpFN73ev4It3OwKBgDvZAwqFhfvvqYYHXIbknpM/fjk6Rj855PQYRRaS6DmHIHb8bu+HyYnjkSmJyGPv1eCApjB3kcrTiHmRQClbwg380kpFKdSh9GRZxwxHGYVQIVN2F5rokFYiuhvvckRH+6RFF/DK4rgVkX8is7LZMlzfbyZxrYC5nnAkHwSUt05hAoGBAI774Yg/aHlhKIkJTxRUv2EmZQEEhVytLzOd/BZiN2T2bsZt9bH/UpJMFTNmSLi0wjF6wnkJMQ0C+gAVkGptQTXDrOJ3DoohUqeHHw395AVGxixnIeZwzzhsqxA6pnB0m4/mfVwHH9XJQyfHWo0FezSM3/DItisPQvzJmNIg8hJ7AoGAS9epjgLLkkFku1kh2lLuvKs56kV8Gp5ZgjxtoDL2l0qfIQSuPstbQOQFB71Bm+0Y9yB2zeOFvGAFhxCxlnKwSNCUgpqvUwdl3NNyM9o3mAkjnZcCGUBoW0/y+1sdsZpmQVRSas/wbYCqAQyWVzv9aXQqmFDwwanP1/55wZ7Z+ew=";
        return config;
    }
}

order.js

$(function(){
    $('.pay').click(function(){
        //获取收货地址、联系人、联系电话
        let name=$('.addres').find('div.on div:eq(0)>p:eq(0)').text().trim();
        let address=$('.addres').find('div.on div:eq(1)>p:eq(0)').text();
        let phone=$('.addres').find('div.on div:eq(1)>p:eq(1)').text();
        console.log("name=%s,address=%s,phone=%s",name,address,phone);
        //获取支付方式
        let pay=$('.way').find('img.on').attr('value');
        console.log(pay);
        //获取快递方式
        let dis=$('.dis').find('span.on').text();
        console.log(dis);
        //获取勾选结算的商品ID
        let gids=$('#gids').val();
        //拼接请求参数
        let params={
            gids:gids,
            address:address,
            person:name,
            telephone:phone,
            pay:pay,
            mail:dis
        };
        console.log(params);

        // $.post('/order/addOrder',params,function(rs){
        //     if(rs.code==200){
        //         location.href='/page/ok.html';
        //     }else{
        //         alert(rs.msg);
        //     }
        // },'json');

        location.href='/order/addOrder?'+parseParams(params);

    });
});

/**
 * JSON转URL参数
 * @param data
 * @returns {string}
 */
function parseParams(data) {
    try {
        var tempArr = [];
        for (var i in data) {
            var key = encodeURIComponent(i);
            var value = encodeURIComponent(data[i]);
            tempArr.push(key + '=' + value);
        }
        var urlParamsStr = tempArr.join('&');
        return urlParamsStr;
    } catch (err) {
        return '';
    }
}

OrderController.java

@RequestMapping("/addOrder")
@ResponseBody
public String addOrder(User user,
								 HttpServletRequest req,
								 OrderDto orderDto){
	//获取购物车
	ShopCar shopCar = this.getShopCar(user.getId(), req);
	//获取结算商品集合
	List<ShopCarItem> shopCarItems = this.getShopCarItems(shopCar, orderDto.getGids());
	//生成订单及订单项
	orderDto.setUserId(Long.parseLong(user.getId()));
	orderService.addOrder(orderDto,shopCarItems);
	//从购物车中删除已结算的商品
	shopCar.delete(orderDto.getGids());
	//跳转支付页面(下节课内容)
	AlipayConfig alipayConfig = new AlipayConfig();
	return alipayConfig.goAlipay(orderDto);
}

2、支付成功后变更订单状态

OrderController.java代码新增如下

/**
 * 支付成功后回调处理订单状态,完成整个下单流程的链路
 * @param param
 * @return
 */
@RequestMapping("/orderFinish")
public String orderFinish(@RequestParam Map<String, String> param){
	System.out.println("异步回调开始。。。。。。");
	Boolean signVerified=false;

	try {
		System.out.println(param);
		signVerified = Factory.Payment.Common().verifyNotify(param);
		System.out.println(signVerified);
		System.out.println("out_trade_no:"+param.get("out_trade_no"));
		System.out.println("total_amount:"+param.get("total_amount"));
		System.out.println("trade_no:"+param.get("trade_no"));
		if(signVerified){
			//支付成功
			//根据订单编号修改订单状态
			//update t_xxx set xx=?,tt=? where id=?
			orderService.update(new UpdateWrapper<Order>()
					.set("status",1)
					.setSql("pay_date=now()")
					.eq("oid",param.get("out_trade_no")));
			//跳转到支付成功页面
		}else{
			//支付失败
		}


	} catch (Exception e) {
		e.printStackTrace();
	}
	return "ok.html";
}

AlipayConfig.java变更如下

public String goAlipay(OrderDto orderDto) {
	try {
		// 1. 设置参数(全局只需设置一次)
		Factory.setOptions(aliconfig());
		// 2. 发起API调用(subject商品标题、outTradeNo订单编号、totalAmount总金额、returnUrl异步通知地址)
		AlipayTradePagePayResponse response = Factory.Payment.Page()
				.pay(orderDto.getOid() + "",
						orderDto.getOid() + "",
						orderDto.getTotal().toString(),
//                            "http://localhost:8081/page/ok.html");  //支付成功之后的异步通知(跳出到自己系统的哪个位置)
						"http://localhost:8081/order/orderFinish");  //支付成功之后的异步通知(跳出到自己系统的哪个位置)
		System.out.println(response.body);
		return response.body;
	} catch (Exception e) {
		e.printStackTrace();
		throw new RuntimeException(e);
	}
}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值