网页 & 移动应用 支付宝 支付功能

首先进入支付宝沙箱页面注册

支付宝支付有关软件在此下载,本人整理好了

一:注册

1.注册之后进入选择文档==》网页&移动应用
在这里插入图片描述
2.选择开发工具==》 沙箱环境
在这里插入图片描述
3.选择研发服务
在这里插入图片描述
4.必看部分非常重要,在下面AlipayConfig类中写代码要使用
在这里插入图片描述
5.可以使用app登录以下的商家账号和买家账号
在这里插入图片描述
6.app端下载
在这里插入图片描述

  1. 效果1:
    在这里插入图片描述
    效果2:
    在这里插入图片描述
    二:使用

1.下载版本
在这里插入图片描述

2.解压文件找到AlipayConfig类

package com.alipay.config;

import java.io.FileWriter;
import java.io.IOException;

/* *
 *类名:AlipayConfig
 *功能:基础配置类
 *详细:设置帐户有关信息及返回路径
 *修改日期:2017-04-05
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 */

public class AlipayConfig {
	
//↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

	// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
	public static String app_id = "";
	
	// 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "";
	
	// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "";

	// 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String notify_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/notify_url.jsp";

	// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
	public static String return_url = "http://工程公网访问地址/alipay.trade.page.pay-JAVA-UTF-8/return_url.jsp";

	// 签名方式
	public static String sign_type = "RSA2";
	
	// 字符编码格式
	public static String charset = "utf-8";
	
	// 支付宝网关
	public static String gatewayUrl = "https://openapi.alipay.com/gateway.do";
	
	// 支付宝网关
	public static String log_path = "C:\\";


//↑↑↑↑↑↑↑↑↑↑请在这里配置您的基本信息↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

    /** 
     * 写日志,方便测试(看网站需求,也可以改成把记录存入数据库)
     * @param sWord 要写入日志里的文本内容
     */
    public static void logResult(String sWord) {
        FileWriter writer = null;
        try {
            writer = new FileWriter(log_path + "alipay_log_" + System.currentTimeMillis()+".txt");
            writer.write(sWord);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}


开始配置文件
在这里插入图片描述
使用支付宝开放平台开发助手生成密钥和公钥
在这里插入图片描述
先登录然后赋值公钥
在这里插入图片描述
找到网页是密钥设置在这里插入图片描述
选择公钥 然后粘贴保存
在这里插入图片描述
在这里插入图片描述
将公钥粘贴到key中
在这里插入图片描述

将私钥粘贴到key中在这里插入图片描述使用natapp生成服务器异步通知页面路径

首先注册一个账号

选择购买隧道 ==》免费隧道
在这里插入图片描述
在这里插入图片描述
成功
在这里插入图片描述
开始下载客户端
在这里插入图片描述
选择Windows 64
在这里插入图片描述
解压文件 创建natapp.bat文件
在这里插入图片描述
给文件加start natapp -authtoken=9ab6b9040a624f40
在这里插入图片描述
双击打开nataapp.bat 下图为成功
在这里插入图片描述
将地址复制到服务器异步通知页面路径
注意http://gjarg2.natappfree.cc 此为免费版路径 每次启动都会更改 要记得更换
在这里插入图片描述
找到网关释放该请求
在这里插入图片描述
三:整合项目

支付订单有关数据库表和字段

1.支付宝支付的依赖

       <!-- 支付宝支付的依赖  https://mvnrepository.com/artifact/com.alipay.sdk/alipay-sdk-java -->
        <dependency>
            <groupId>com.alipay.sdk</groupId>
            <artifactId>alipay-sdk-java</artifactId>
            <version>4.13.33.ALL</version>
        </dependency>

2.配置 AlipayConfig 类

package com.jq.config;
import java.io.FileWriter;
import java.io.IOException;

/* *
 *类名:AlipayConfig
 *功能:基础配置类
 *详细:设置帐户有关信息及返回路径
 *修改日期:2017-04-05
 *说明:
 *以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
 *该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
 */

public class AlipayConfig {

    //↓↓↓↓↓↓↓↓↓↓请在这里配置您的基本信息↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

    // 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
    public static String app_id = "2021000117641553";

    // 商户私钥,您的PKCS8格式RSA2私钥
    public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCtbUu37tgpqUZnBE2WKcRDo+oCZLHsq7slN/Jjq4ETTpdeK7p8/J6gEDo/wP9cXPRlfRhT+GYE+hFyEMh8JEtu9L+mSnmvhYJi4QCy+cQfYEynNl5+7B3FhJ76z9Zq8kWiz+cybyzD+BTzcywDRS06EiFpZRkGCz/hGwSJcKn5kXtu8RJDrUKsbacqae9ww1qBcT9zY32GYSzK/g4ytV1wnlKIcaRzxUPRtwgVOjJvqh+bVV4+lmdoRPynFbbwdjOL8WFBUvO3sv2t3uHECh9MKsmOS74NhBcwl8nGclN4b4/asqmJdGBegewdETLUAzOEsCUGsI32fBnHyWnBwTblAgMBAAECggEAE2RFMyvhv8bNuHcitce1ylppsBrSSkRpiJ/Y2owywpXnFwCMua0Fj6BA4yARbaJ3MWHrdngv8B6GFNsLj9X/GUkEpPNu59Fl4uiFy31iEKAT8h6CMm70ZUGPBTx4HT05zBqzH1CPENqMfSxDn5n8lKGyWraTNbnMSr9aooOWffE3TTRwJ+meX1DS5LDsIz7nx/aNFdb0VHWdCnYxuXCQ8QOjTl1z62SmaMgoEGRyuYFHUS7Jp2zJlO56Mcf3+AAShm+XeUnmGT35Y26OFWdRrWAGYPUufAmNJAQYO5lEOge0qNwU3ddsAHC1ruvp+yEFRa9zJi2ezGVaiX6paHlQAQKBgQDdzrgXgdAapL+W0bjLKj++QakwacvkBIMAOWluBHjjZM3bsG7JTy1+YicGg8/EcNUBdxaHzdz2JTYAuxzRoDMJumln/1FwowyMxRPkMGQI4m+ClS9E+P9BNmpPqNgm9RL22il8JW17A1veRndri5l8aanw1YbZh0wfgYmmabjARQKBgQDIKVCMNlfn/1LgpJN9ANF6eNpT6iZWCMlwwhir7m+JpD+LdH2+4uVnEAgmuBrzGPagSpmReOI18/b6y3o7ZKmkj4A4qwp6BxfQ//3NXlwO+479KDfhj8Q8WbccOPBCMnStqd9V2PpBTvdydme4gQqt7ZWLwDpMraUdh1M5l6iWIQKBgQCrPl6oX2NwPoNgCDhYOh0OYRkjNHriZo1RDgIUm0VNodTA6J0PtJ5V9adVg0xTyBzbTbrKTChsrNvdgphESx88QnwAe4C/qlIVGE48HRQOO+uFcHIXGPnQuhcnux5uLUVf6ZyfqTG2CCjUGak3EYcFI3q9Yc0Dgk5GALdqEDM/1QKBgDg32ma3MLN5c+aicsZOP4e9f9zHzCKn7yQbb+CCZJNtLWfWvSarBbGPwCpX1UHoBgT5Tu6b3DU5I2pHUjpySG9u2p2P9K5XZaoO7FMNKKAQqZWTATb6MSyeKh7kIx8Emt7X8mFjQs6rBjcA6Jraq4w0SadpwzYcI18KziZD4VbhAoGAFrizjviJlPu93j/AfsE7pgBl3EsMkHB4/3F3WrNriUuERmOOKiIy6mbWIxtVqYlGZ+hI/9CE8PoBLjqtNdExS68PG0WfjL/Eq6MQvFfO2VTQKJgciLEPaj1oOWw4wzRN3vw+iB2YLG2J3KbtCLBzugxihZu1dZxbLy36PlCaED0=";

    // 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
    public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAruFzlL7B30I4tWuOepqFjlIB6U6I/zZGM39EtG2dMP1MFZh0PHpSZckZerqOsl5yPolEUxES3Hfq7odLijlMCCwPp8nPEJEJ2fH6B0YGuPcdM1PPRcPX0aJpWE826f/feJlwrHQi4VP3UjOca/ot4stP4VlR847Ygssjv1NS6H7iQ583nHqCCR8KHG5nrPIE3T4WK8s0XsIqRByhHl4jmBTz4msBjNav2BO8aeEX3O/sGzFJbgXKm5Dqit+GNa0WoIdiCShxsiBVSSdXLuO458NigonTN4Pqll1DEdtwkCsrNgK8B+KmdH9kpyGg/IN8Tu1lH6bSmnBnhuq9KQhZEQIDAQAB";

    // 服务器异步通知页面路径  需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    //j-order/aliypay/notity 服务名/aliypay控制器/notity方法
    // 注意http://gjarg2.natappfree.cc 此为免费版每次启动都会更改 要记得更换   
    public static String notify_url = "http://gjarg2.natappfree.cc/j-order/aliypay/notity";

    // 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
    //支付成功后跳转的页面
    public static String return_url = "http://localhost:8080/#/AliypaySuccess";

    // 签名方式
    public static String sign_type = "RSA2";

    // 字符编码格式
    public static String charset = "utf-8";

    // 支付宝网关
    public static String gatewayUrl = "https://openapi.alipaydev.com/gateway.do";

}

3.创建AliypayController 控制器

package com.jq.pay;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jq.config.AlipayConfig;
import com.jq.order.model.OmsOrder;
import com.jq.order.model.OmsOrderOperateHistory;
import com.jq.order.service.OmsOrderOperateHistoryService;
import com.jq.order.service.OmsOrderService;
import com.jq.result.ResultCode;
import com.jq.result.ResultObj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

@RestController
@RequestMapping("aliypay")
public class AliypayController {


    @Autowired
    private OmsOrderService omsOrderService;

    @Autowired
    private OmsOrderOperateHistoryService omsOrderOperateHistoryService;

    //获取支付页面
    @GetMapping("{orderNo}")
    public ResultObj toAliPay(@PathVariable("orderNo") String orderNo) throws AlipayApiException {
        QueryWrapper<OmsOrder>queryWrapper=new QueryWrapper<>();
        //查询订单号是否一致
        queryWrapper.eq("order_sn",orderNo);
        //订单来源:0->PC订单;1->app订单
        queryWrapper.eq("status",0);
        OmsOrder order = omsOrderService.getOne(queryWrapper);
        if(order==null){
            return  ResultObj.error(ResultCode.ORDER_NULL);
        }

        //获得初始化的AlipayClient
        AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);

        //设置请求参数
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl(AlipayConfig.return_url);
        alipayRequest.setNotifyUrl(AlipayConfig.notify_url);

        //商户订单号,商户网站订单系统中唯一订单号,必填
        String out_trade_no = orderNo;
        //付款金额,必填
        String total_amount = order.getTotalAmount().toString();
        //订单名称,必填
        String subject = "美美家居";
        //商品描述,可空
        String body = "感谢您对本店的支持,好评有返现哦";

        //该订单允许的最晚付款时间,逾期关闭交易  取值范围 : 1m-15d m-分钟 h-小时 d一天
        //注:该参数不支持小数 如1.5h 可转为90m
        //1c -当天(无论交易是否关闭在0点都会关闭)

        String timeout_express = "1c";

        alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
                + "\"total_amount\":\""+ total_amount +"\","
                + "\"subject\":\""+ subject +"\","
                + "\"body\":\""+ body +"\","
                + "\"timeout_express\":\""+ timeout_express +"\","
                + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");


        //请求  //获取支付页面
        String result = alipayClient.pageExecute(alipayRequest).getBody();

        //输出
        return ResultObj.success(result);
    }


    //支付宝异步回调方法
    @RequestMapping("notity")
    public String notityOrder(HttpServletRequest request) throws AlipayApiException, UnsupportedEncodingException {
        //获取支付宝POST过来反馈信息
        Map<String,String> params = new HashMap<String,String>();
        Map<String,String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决,这段代码在出现乱码时使用
           /* valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");*/
            params.put(name, valueStr);
        }

        boolean signVerified = AlipaySignature.rsaCheckV1(params, AlipayConfig.alipay_public_key, AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

        //——请在这里编写您的程序(以下代码仅作参考)——

	/* 实际验证过程建议商户务必添加以下校验:
	1、需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号,
	2、判断total_amount是否确实为该订单的实际金额(即商户订单创建时的金额),
	3、校验通知中的seller_id(或者seller_email) 是否为out_trade_no这笔单据的对应的操作方(有的时候,一个商户可能有多个seller_id/seller_email)
	4、验证app_id是否为该商户本身。
	*/
        if(signVerified) {//验证成功
            //商户订单号
            String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

            //支付宝交易号
            String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");

            //交易状态
            String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8");

            if(trade_status.equals("TRADE_FINISHED")){
                //判断该笔订单是否在商户网站中已经做过处理
                //如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序
                //如果有做过处理,不执行商户的业务程序

                //注意:
                //退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知
                System.out.println("交易完成");
            }else if (trade_status.equals("TRADE_SUCCESS")){
                QueryWrapper<OmsOrder>queryWrapper=new QueryWrapper<>();
                //查询订单号是否一致
                queryWrapper.eq("order_sn",out_trade_no);
                //订单来源:0->PC订单;1->app订单
                queryWrapper.eq("status",0);
                OmsOrder order = omsOrderService.getOne(queryWrapper);
                if(order==null){

                    //修改订单表

                    //订单来源:0->PC订单;1->app订单
                    order.setStatus(1);
                    //支付方式:0->未支付;1->支付宝;2->微信
                    order.setPayType(2);
                    //支付时间
                    order.setPaymentTime(new Date());
                    omsOrderService.updateById(order);

                    //新增操作
                    OmsOrderOperateHistory history =new OmsOrderOperateHistory();
                    history.setOrderStatus(1);
                    history.setOrderId(order.getId());
                    history.setCreateTime(new Date());
                    omsOrderOperateHistoryService.save(history);

                }else {
                    return "fail";
                }

                System.out.println("支付成功");
            }

           return "success";

        }else {//验证失败
            return "fail";

            //调试用,写文本函数记录程序运行情况是否正常
            //String sWord = AlipaySignature.getSignCheckContentV1(params);
            //AlipayConfig.logResult(sWord);
        }

    }


}

4.创建统一返回值 ResultObj 类

package com.jq.result;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ResultObj {

    // 状态码
    private Integer code;

    // 信息
    private String msg;

    // 数据
    private Object data;

    public ResultObj(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static ResultObj success(){
        return new ResultObj(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg());
    }

    public static ResultObj success(Object data){
        return new ResultObj(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg(), data);
    }

    public static ResultObj error(ResultCode resultCode){
        return new ResultObj(resultCode.getCode(), resultCode.getMsg(),null);
    }
    public static ResultObj error(){
        return new ResultObj(ResultCode.ERROR.getCode(),ResultCode.ERROR.getMsg());
    }

    public static ResultObj error(ResultCode resultCode,Object data){
        return new ResultObj(resultCode.getCode(), resultCode.getMsg(),data);
    }

}

4.创建统一返回值code枚举类

package com.jq.result;


public enum ResultCode {

    SUCCESS(200,"操作成功"),
    ERROR(500,"操作失败"),
    USERNAME_PASSWORD_ISNULL(1001,"用户名或密码为空"),
    USER_NOEXIST(1002,"用户不存在"),
    PASSWORD_ERROR(1003,"密码错误"),
    TOKEN_ERROR(1004,"身份过期,请重新登录"),
    NO_PERMISSION(403,"没有权限访问该方法"),
    PHONE_NULL(1005,"手机号为空"),
    GET_CODE_ERROR(1006,"获取验证码失败"),
    PHONE_CODE_ISBULL(1007,"手机号码或验证码不能为空"),
    CODE_ERROR(1008,"验证码错误"),
    PHONE_CODE_TIMEOUT(1009,"手机号码不正确或验证码过期"),
    LOGIN_ERROR(1010,"登录失败请重新登录"),
    ORDELIST_ERROR(1011,"获取订单信息失败"),
    unders_tock(1012,"商品库存不足"),
    ORDER_NULL(1012,"订单不存在")
    ;

    private Integer code;
    private String msg;

    ResultCode(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}

5.vue订单前端代码

在这里插入图片描述
选择支付宝按钮点击结算进入支付宝结算页面

发请求主要代码:
在这里插入图片描述
全文:

<template>
    <div>
      <!--引入头部-->
      <home-head></home-head>

      <!--详情-->

      <div class="layui-container house-usershop">

       <!-- 收货人信息-->
        <el-card class="box-card" shadow="never" style="margin-top: 50px">
          <div slot="header" class="clearfix">
            <span>收货人信息</span>
            <el-button style="float: right; padding: 3px 0" type="text" @click="openAddress">新增收货地址</el-button>
          </div>
          <div>
            <ul>
              <li class="liStyle" @mouseover="yishang" @mouseleave="yikai" >
                <el-button size="small" class="btnStyle" >{{seleteAddress.name}}</el-button>
                <!--收货人名称-->
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{seleteAddress.name}}
                <!--收货人省-->
                &nbsp;&nbsp;{{seleteAddress.province}}
                <!--收货人市-->
                &nbsp;&nbsp;{{seleteAddress.city}}
                <!--收货人县-->
                &nbsp;&nbsp;{{seleteAddress.region}}
                <!--收货人街道-->
                &nbsp;&nbsp;{{seleteAddress.detailAddress}}
                <!--收货人手机号-->
                &nbsp;&nbsp;{{seleteAddress.phoneNumber}}
                <!--收货人默认地址-->
                &nbsp;&nbsp;<el-button size="mini" type="info" v-show="buttonStatus&&seleteAddress.defaultStatus==1">{{seleteAddress.defaultStatus==0?null:"默认地址"}}</el-button>

                <div style="float: right" v-show="checkLinkStatus">
                  <el-link type="primary" class="linkStyle" :underline="false" @click="editAddress(seleteAddress.id)">编辑</el-link>
                </div>
              </li>
            </ul><br>
            <!--更多地址-->
            <ul v-for="(address,index) in morAddressList">
              <li class="liStyle" @mouseover="mouseover(index)" @mouseleave="mouseleave" >
                <el-button size="small" class="btnStyle2" @click="checkAddress(address)">{{address.name}}</el-button>
                <!--收货人名称-->
                &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{{address.name}}
                <!--收货人省-->
                &nbsp;&nbsp;{{address.province}}
                <!--收货人市-->
                &nbsp;&nbsp;{{address.city}}
                <!--收货人县-->
                &nbsp;&nbsp;{{address.region}}
                <!--收货人街道-->
                &nbsp;&nbsp;{{address.detailAddress}}
                <!--收货人手机号-->
                &nbsp;&nbsp;{{address.phoneNumber}}
                <!--收货人默认地址-->
                &nbsp;&nbsp;<el-button size="mini" type="info"  v-show="buttonStatus&&address.defaultStatus==1">{{address.defaultStatus==0?null:"默认地址"}}</el-button>

                <div style="float: right" v-show="linkStatus&&index==current">
                  <el-link type="primary" class="linkStyle" :underline="false" @click="editDefaultStatus(address.id)">设为默认地址</el-link>&nbsp;&nbsp;
                  <el-link type="primary" class="linkStyle" :underline="false" @click="editAddress(address.id)">编辑</el-link>&nbsp;&nbsp;
                  <el-link type="primary" class="linkStyle" :underline="false" @click="delAddress(address.id)">删除</el-link>
                </div>
              </li><br/>
            </ul><br/>
            <br>
            <el-link :underline="false" @click="getMoreAddress">更多地址<i :class="openStyle"></i></el-link>


          </div>
        </el-card>

        <!-- 收货人信息-->
        <el-card class="box-card" shadow="never" style="margin-top: 50px">
          <div slot="header" class="clearfix">
            <span>支付方式</span>
          </div>
          <div>
            <el-radio size="small" v-model="payType" border label="1">微信支付</el-radio>
            <el-radio size="small" v-model="payType" border label="2">支付宝支付</el-radio>
          </div>
        </el-card>

        <!-- 送货清单-->
        <el-card class="box-card" shadow="never" style="margin-top: 50px">
          <div slot="header" class="clearfix">
            <span>送货清单</span>
          </div>
            <div class="house-usershop">
              <el-table :header-cell-style="{'background-color':'#f5f5f5'}"
                        ref="multipleTable" :data="tableData" tooltip-effect="dark">

                <el-table-column label="商品" width="300">
                  <template slot-scope="scope">
                    <div>
                      <div style="float: left">
                        <img :src="scope.row.pic" width="80">
                      </div>
                      <div style="float:left;word-wrap:break-word; overflow:hidden;width: 180px;">
                        {{scope.row.productName}}
                      </div>
                    </div>
                  </template>
                </el-table-column>

                <el-table-column label="规格">
                  <template slot-scope="scope">
                    <h3 v-for="attr in getSku(scope.row.sku)">&nbsp;&nbsp;{{attr.value}}</h3>
                  </template>
                </el-table-column>

                <el-table-column prop="price" label="单价">
                  <template slot-scope="scope">{{scope.row.price}}</template>
                </el-table-column>

                <el-table-column  label="数量">
                  <template slot-scope="scope">
                    {{scope.row.buyCount}}
                  </template>
                </el-table-column>

                <el-table-column prop="subtotal" label="小计" show-overflow-tooltip>
                </el-table-column>

                <el-table-column label="货物状态">
                  <template slot-scope="scope">
                    <font style="margin-left: 40px;color: #c9c9c9" v-if="scope.row.buyCount < scope.row.stock">有货</font>
                    <font style="margin-left: 40px;color: red" v-else>无货</font>
                  </template>
                </el-table-column>

              </el-table>

              <div class="house-usershop-table-num">
                <span>已选{{checkCount}}</span>
                <p id="total">合计:<span>{{totalMoney}}</span></p>
                <div id="toCope">
                  <p>应付:<big>{{totalMoney}}</big></p>
                  <span>满减¥20,包邮</span>
                </div>
                <button class="layui-btn" @click="ClearingOrder">结算</button>
              </div>
            </div>
        </el-card>

      </div>

      <!--========================================添加的模块============================-->
      <el-dialog  v-dialog-drag :visible.sync="editVisible">
        <el-form :model="addForm" :rules="rules" ref="addForm" label-width="120px">
          <el-form-item label="所在地区:" prop="value">
            <el-cascader
              v-model="addForm.value"
              :options="options"
              ></el-cascader>
          </el-form-item>
          <el-form-item label="收货人:" prop="name">
            <el-input v-model="addForm.name"></el-input>
          </el-form-item>
          <el-form-item label="手机号码:" prop="phoneNumber">
            <el-input
              v-model="addForm.phoneNumber" type="number"
              oninput="value=value.replace(/[^\d]/g,'')"
            ></el-input>
          </el-form-item>
          <el-form-item label="邮政编码:" prop="postCode">
            <el-input v-model.number="addForm.postCode"
                      type="number"
                      oninput="value=value.replace(/[^\d]/g,'')"
            ></el-input>
          </el-form-item>
          <el-form-item label="详细地址:" prop="detailAddress">
            <el-input v-model.number="addForm.detailAddress"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmim('addForm')">提交</el-button>
            <el-button @click="resetForm('addForm')">取消</el-button>
          </el-form-item>
        </el-form>
      </el-dialog>




      <div class="house-footer" style="margin-top: 85px">
        <div class="layui-container">
          <div class="intro">
            <span class="first"><i class="layui-icon layui-icon-house-shield"></i>7天无理由退换货</span>
            <span class="second"><i class="layui-icon layui-icon-house-car"></i>99元全场包邮</span>
            <span class="third"><i class="layui-icon layui-icon-house-diamond"></i>100%品质保证</span>
            <span class="last"><i class="layui-icon layui-icon-house-tel"></i>客服400-2888-966</span>
          </div>
          <div class="about">
      <span class="layui-breadcrumb" lay-separator="|">
        <a href="about.html">关于我们</a>
        <a href="about.html">帮助中心</a>
        <a href="about.html">售后服务</a>
        <a href="about.html">配送服务</a>
        <a href="about.html">关于货源</a>
      </span>
            <p>家居商城版权所有 &copy; 2012-2020</p>
          </div>
        </div>
      </div>

    </div>
</template>

<script>



  import {queryAddressList,saveAddress,toAlipay,getAddressList,delAddress,createOrder,seleteAddressById,editDefaultStatus,buyProductList} from "../../api/Order/order";
  //引入头部
  import HomeHead from "../head/HomeHead"
    export default {
        name: "Order",
      components:{HomeHead},
      data(){
          return{
            editVisible: false,//弹框默认关闭
            addForm: {
              "id":null,
              "name":"", // 收货人名称
              "phoneNumber":"", // 收货人手机号
              defaultStatus:0,//是否为默认
              "postCode":"",//邮政编码
              "province":"",//省份/直辖市
              "city":"",//城市
              "region":"",//区
              "detailAddress":"",//详细地址(街道),
               value:[], //选中的地区
            },
            options:[],//所有的地区
            addressList:[],//用户地址数据
            seleteAddress:{},//选中的地址
            openStatus:false,//操作更多地址按钮状态
            morAddressList:[],//更多的地址列表
            openStyle:"el-icon-caret-bottom",//更多的地址按钮样式
            linkStatus:false,//编辑按钮的状态
            buttonStatus:false,//默认地址按钮的状态
            current:0,
            checkLinkStatus:false,
            payType:1,//支付方式
            //应付
            totalMoney:0,
            //件数
            checkCount:0,
            tableData:[],//要购买的商品
            rules: {
              name: [
                { required: true, message: '请输入收货人名称', trigger: 'blur' },
                { min: 2, max: 6, message: '长度在 2 到 6 个汉字', trigger: 'blur' }
              ],
              phoneNumber: [
                { required: true, message: '请输入收货人手机号码', trigger: 'blur' },
                { pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: '请输入11有效手机号码', trigger: 'blur' }
              ],
              postCode: [
                { required: true, message: '请输入邮政编码', trigger: 'blur' },
                { pattern: /^[1-9][0-9]{5}$/, message: '请输入6位邮政编码', trigger: 'blur' }

              ],
              value: [
                { type: 'array', required: true, message: '请至少选择一个活动性质', trigger: 'blur' }
              ],
              detailAddress: [
                { required: true, message: '请填写详细地址', trigger: 'blur' }
              ]
            },
          }
      },
      methods:{
          //打开添加弹框
        openAddress(){
           this.editVisible=true;
          //清空表单数据
          for (var key in this.addForm){
            this.addForm[key] = null
          }

        },
        queryAddressList(){
          //获取地区数据
          queryAddressList().then(res=>{
            if(res.data.code==200){
              this.options=res.data.data;
            }else {
              this.$message.error("获取地区数据失败")
            }
          })
        },
        //新增收货人地址
        onSubmim(addForm){
          this.$refs.addForm.validate((valid) => {
            if (valid) {
              let data=this.addForm.value;
              //给省份/直辖市赋值
              this.addForm.province = data[0];
              //给城市赋值
              this.addForm.city = data[1];
              //给区赋值
              this.addForm.region = data[2];

              //新增收货地址数据
              saveAddress(this.addForm).then(res=>{
                //成功刷新页面
                if(res.data.code==200){
                  //关闭新增弹框
                  this.editVisible=false;
                  //刷新页面
                  this.getMoreAddress();
                  this.getAddressList();
                }else {
                  this.$message.error("新增收货地址")
                }

              })
            } else {
              return false;
            }
          });
        },
        //取消
        resetForm(addForm) {
          this.$refs[addForm].resetFields();
          this.editVisible = false
        },
        //获取用户地址数据
        getAddressList(){
          getAddressList().then(res=>{
            //设置默认地址按钮状态
            this.buttonStatus =true ;

            let data = res.data.data;
            this.addressList = data;
            data.forEach(address=>{
              if(address.defaultStatus==1){
                this.seleteAddress = address;
                return ;
              }
            })
          })
        },
        //获取更多地址
        getMoreAddress(){
          this.openStatus=! this.openStatus;
          if(this.openStatus){
            this.openStyle="el-icon-caret-top";
            this.addressList.forEach(address=>{
              if(address.id != this.seleteAddress.id){
                  this.morAddressList.push(address);
              }
            })
          }else {
            this.morAddressList = [];
            this.openStyle="el-icon-caret-bottom";
          }

        },
        //修改用户地址
        editAddress(id){
          //回显
          seleteAddressById(id).then(response => {
            this.editVisible = true;
            this.addForm = response.data.data;

            //回显地址
            let data =[];
            data[0] = this.addForm.province;
            data[1] = this.addForm.city;
            data[2] = this.addForm.region;
            this.addForm.value=data;

            this.openStatus=true;

          }).catch(res => {
            this.$message.error("获取数据失败");
          })

        },
        //删除用户地址
        delAddress(id){
          delAddress(id).then(res=>{
            //成功刷新页面
            if(res.data.code==200){

              this.getMoreAddress();
              this.getAddressList();
            }else {
              this.$message.error("删除用户地址失败")
            }

          })
        },
        //切换地址
        checkAddress(address){
          this.seleteAddress = address;
          this.getMoreAddress();
        },
        //修改默认地址
        editDefaultStatus(id){
          editDefaultStatus(id).then(res=>{
            //成功刷新页面
            if(res.data.code==200){
              //刷新页面
              this.getMoreAddress();
              this.getAddressList();
            }else {
              this.$message.error("修改用户默认地址失败")
            }

          })
        },
        //鼠标移入移出事件
        mouseover(index){
          this.linkStatus =true;
          this.current = index;
        },
        mouseleave(){
          this.linkStatus = false;
          this.current = null;

        },
        yishang(){
          this.checkLinkStatus = true;
        },
        yikai(){
          this.checkLinkStatus =false;
        },
        //要购买的商品
        buyProductList(){
          buyProductList().then(res=>{
            this.tableData=res.data.data;
            let data=this.tableData;
            data.forEach(row=>{
              this.totalMoney+=row.subtotal;//一个商品的小计价格
              this.checkCount+=1;//选中的商品个数
            })

          })

        },
        // 颜色和容量
        getSku(sku){
          return JSON.parse(sku);
        },

        //结算订单
        ClearingOrder(){
          let addressId = this.seleteAddress.id;
          let payType = this.payType;
          let skeCode = "";

          for (let i = 0; i < this.tableData.length; i++) {
            skeCode = skeCode+","+this.tableData[i].skuCode;
          }
          //传参
          let params={
            addressId:addressId,
            payType:payType,
            skeCode:skeCode
          }

          //发起请求
          createOrder(params).then(res=>{
            alert(payType)
            if(res.data.code==200){

              if(payType==2){
                //获取支付页面
                toAlipay(res.data.data).then(result=>{
                  if(result.data.code==200){
                    //跳转支付页面
                    document.querySelector("body").innerHTML = result.data.data;
                    document.forms[0].submit();
                      }
                })
              }


            }else if(res.data.code==1012){
              //库存不足
              let unstock=res.data.data;
              let productName = "";
              unstock.forEach(unstock=>{
                productName+=unstock.productName+",";
              })
              this.$message.warning("购买商品中的【"+productName.substring(0,productName.length-1)+"】库存不足!")
            }else {
              this.$message.error(res.data.msg);
            }
          })
        }
      },
      created() {
          //初始化
       this.getAddressList();
       this.queryAddressList();
        //要购买的商品
        this.buyProductList();
      },
    }
</script>

<style scoped>
/*
  el-input去掉自带上下箭头
*/
  /deep/
  input::-webkit-inner-spin-button {
    -webkit-appearance: none !important;
  }



.liStyle{
  font-size: 12px;
  line-height: 30px;

  background-color: #FFFFFF;/*默认白色*/

}

.liStyle:hover{
  background-color: 	#fbf6f0;/*移上时改变颜色*/

}

.btnStyle{
  border: 2px solid #e4393c;
  padding: 4px 10px;
  float: left;
  height: 30px;
  width: 120px;
  text-align: center;
  margin: 0px;
  cursor: pointer;
}
.btnStyle2{
  padding: 4px 10px;
  float: left;
  height: 30px;
  width: 120px;
  text-align: center;
  margin: 0px;
  cursor: pointer;
}
.linkStyle{
  font-size: 12px;
}
.el-table th.gutter{
  display: table-cell!important;
}

</style>

请求.js

import request from '../../utils/request';
//获取地区数据
export const queryAddressList = () => {
    return request({
      url: '/j-order/address/',
      method: 'get',
    });
};
//新增收货人数据
export const saveAddress = addForm => {
    return request({
      url: '/j-order/address/',
      method: 'put',
      data:addForm
    });
};
//获取用户地址数据
export const getAddressList = () => {
    return request({
      url: '/j-order/address/area/',
      method: 'get',
    });
};
//删除用户地址数据
export const delAddress = id => {
    return request({
      url: '/j-order/address/'+id,
      method: 'delete',
    });
};
//修改默认地址
export const editDefaultStatus = id => {
    return request({
      url: '/j-order/address/editDefaultStatus/'+id,
      method: 'post',
    });
};
//回显用户地址数据
export const seleteAddressById = id => {
    return request({
      url: '/j-order/address/seleteAddressById/'+id,
      method: 'get',
    });
};

//结算要购买的商品
export const buyProductList = () => {
    return request({
      url: '/jq-cart/cart/buy/',
      method: 'get',
    });
};

//结算订单
export const createOrder = params => {
    return request({
      url: '/j-order/order/',
      method: 'post',
      params:params
    });
};

//获取支付页面
export const toAlipay = params => {
    return request({
      url: '/j-order/aliypay/'+params,
      method: 'get',
    });
};



创建支付成功跳转的页面

在这里插入图片描述

在路由引入

import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/views/Login/Login'
import ProductList from '@/views/Product/ProductList'
import ProductDetail from '@/views/Product/ProductDetail'
import Cart from '@/views/Cart/Cart'
import Order from '@/views/Order/Order'
import AliypaySuccess from '@/views/Order/AliypaySuccess'

Vue.use(Router)

export default new Router({
  routes: [
    //登录
    {
      path: '/',
      name: 'Login',
      component: Login
    } ,
    //商品
    {
      path: '/ProductList',
      name: 'ProductList',
      component: ProductList
    },
    //商品sku
    {
      path: '/ProductDetail',
      name: 'ProductDetail',
      component: ProductDetail
    },
    //购物车
    {
      path: '/Cart',
      name: 'Cart',
      component: Cart
    },
    //购物车结算
    {
      path: '/Order',
      name: 'Order',
      component: Order
    },
    //获取支付页面
    {
      path: '/AliypaySuccess',
      name: 'AliypaySuccess',
      component: AliypaySuccess
    }
  ]
})

四:展示
展示1.
在这里插入图片描述
展示2.
在这里插入图片描述
展示3.
在这里插入图片描述
展示4.
在这里插入图片描述
展示5.
在这里插入图片描述
展示6.
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jq1223

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值