mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-11-04 20:28:44 +08:00 
			
		
		
		
	!417 支付收银台,接入支付宝的 PC、Wap、二维码、条码、App 等支付方式
Merge pull request !417 from 芋道源码/feature/dev-yunai
This commit is contained in:
		@@ -1,4 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * 占位
 | 
			
		||||
 */
 | 
			
		||||
package cn.iocoder.yudao.module.shop.controller.admin;
 | 
			
		||||
@@ -1,73 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.shop.controller.app;
 | 
			
		||||
 | 
			
		||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 | 
			
		||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayOrderNotifyReqDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.pay.api.notify.dto.PayRefundNotifyReqDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.pay.service.order.PayOrderService;
 | 
			
		||||
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
 | 
			
		||||
import cn.iocoder.yudao.module.pay.util.PaySeqUtils;
 | 
			
		||||
import cn.iocoder.yudao.module.shop.controller.app.vo.AppShopOrderCreateRespVO;
 | 
			
		||||
import io.swagger.v3.oas.annotations.tags.Tag;
 | 
			
		||||
import io.swagger.v3.oas.annotations.Operation;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.validation.annotation.Validated;
 | 
			
		||||
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.validation.Valid;
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 | 
			
		||||
import static cn.iocoder.yudao.framework.common.util.servlet.ServletUtils.getClientIP;
 | 
			
		||||
 | 
			
		||||
@Tag(name = "用户 APP - 商城订单")
 | 
			
		||||
@RestController
 | 
			
		||||
@RequestMapping("/shop/order")
 | 
			
		||||
@Validated
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class AppShopOrderController {
 | 
			
		||||
 | 
			
		||||
    @Resource
 | 
			
		||||
    private PayOrderService payOrderService;
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/create")
 | 
			
		||||
    @Operation(summary = "创建商城订单")
 | 
			
		||||
//    @PreAuthenticated // TODO 暂时不加登陆验证,前端暂时没做好
 | 
			
		||||
    public CommonResult<AppShopOrderCreateRespVO> create() {
 | 
			
		||||
        // 假装创建商城订单
 | 
			
		||||
        Long shopOrderId = System.currentTimeMillis();
 | 
			
		||||
 | 
			
		||||
        // 创建对应的支付订单
 | 
			
		||||
        PayOrderCreateReqDTO reqDTO = new PayOrderCreateReqDTO();
 | 
			
		||||
        reqDTO.setAppId(6L);
 | 
			
		||||
        reqDTO.setUserIp(getClientIP());
 | 
			
		||||
        reqDTO.setMerchantOrderId(PaySeqUtils.genMerchantOrderNo());
 | 
			
		||||
        reqDTO.setSubject("标题:" + shopOrderId);
 | 
			
		||||
        reqDTO.setBody("内容:" + shopOrderId);
 | 
			
		||||
        reqDTO.setAmount(200); // 单位:分
 | 
			
		||||
        reqDTO.setExpireTime(LocalDateTime.now().plusDays(1));
 | 
			
		||||
        Long payOrderId = payOrderService.createPayOrder(reqDTO);
 | 
			
		||||
 | 
			
		||||
        // 拼接返回
 | 
			
		||||
        return success(AppShopOrderCreateRespVO.builder().id(shopOrderId)
 | 
			
		||||
                .payOrderId(payOrderId).build());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/pay-notify")
 | 
			
		||||
    @Operation(summary = "支付回调")
 | 
			
		||||
    public CommonResult<Boolean> payNotify(@RequestBody @Valid PayOrderNotifyReqDTO reqVO) {
 | 
			
		||||
        log.info("[payNotify][回调成功]");
 | 
			
		||||
        return success(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @PostMapping("/refund-notify")
 | 
			
		||||
    @Operation(summary = "退款回调")
 | 
			
		||||
    public CommonResult<Boolean> refundNotify(@RequestBody @Valid PayRefundNotifyReqDTO reqVO) {
 | 
			
		||||
        log.info("[refundNotify][回调成功]");
 | 
			
		||||
        return success(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,20 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.module.shop.controller.app.vo;
 | 
			
		||||
 | 
			
		||||
import io.swagger.v3.oas.annotations.media.Schema;
 | 
			
		||||
import lombok.AllArgsConstructor;
 | 
			
		||||
import lombok.Builder;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
@Schema(description = "用户 APP - 商城订单创建 Response VO")
 | 
			
		||||
@Data
 | 
			
		||||
@Builder
 | 
			
		||||
@AllArgsConstructor
 | 
			
		||||
public class AppShopOrderCreateRespVO {
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "商城订单编号", required = true, example = "1024")
 | 
			
		||||
    private Long id;
 | 
			
		||||
 | 
			
		||||
    @Schema(description = "支付订单编号", required = true, example = "2048")
 | 
			
		||||
    private Long payOrderId;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -1,9 +0,0 @@
 | 
			
		||||
/**
 | 
			
		||||
 * shop 包下,我们放商城业务
 | 
			
		||||
 * 例如说:商品、订单等等
 | 
			
		||||
 * 注意,目前仅仅作为 demo 演示,对接 pay 支付系统
 | 
			
		||||
 *
 | 
			
		||||
 * 缩写:shop
 | 
			
		||||
 */
 | 
			
		||||
// TODO 芋艿:后续会迁移到 yudao-module-mall-trade 下
 | 
			
		||||
package cn.iocoder.yudao.module.shop;
 | 
			
		||||
@@ -1,11 +0,0 @@
 | 
			
		||||
package cn.iocoder.yudao.server.framework.ui.core;
 | 
			
		||||
 | 
			
		||||
import org.springframework.boot.web.servlet.error.ErrorController;
 | 
			
		||||
 | 
			
		||||
//@Controller
 | 
			
		||||
//@RequestMapping("/admin-ui/")
 | 
			
		||||
public class AdminUiController implements ErrorController {
 | 
			
		||||
 | 
			
		||||
//    public String
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -153,6 +153,7 @@ logging:
 | 
			
		||||
    cn.iocoder.yudao.module.infra.dal.mysql: debug
 | 
			
		||||
    cn.iocoder.yudao.module.infra.dal.mysql.job.JobLogMapper: INFO # 配置 JobLogMapper 的日志级别为 info
 | 
			
		||||
    cn.iocoder.yudao.module.pay.dal.mysql: debug
 | 
			
		||||
    cn.iocoder.yudao.module.pay.dal.mysql.notify.PayNotifyTaskMapper: INFO # 配置 JobLogMapper 的日志级别为 info
 | 
			
		||||
    cn.iocoder.yudao.module.system.dal.mysql: debug
 | 
			
		||||
    cn.iocoder.yudao.module.tool.dal.mysql: debug
 | 
			
		||||
    cn.iocoder.yudao.module.member.dal.mysql: debug
 | 
			
		||||
 
 | 
			
		||||
@@ -1,79 +0,0 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
 | 
			
		||||
    <title>支付测试页</title>
 | 
			
		||||
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
 | 
			
		||||
    <script src="qrcode.min.js" type="text/javascript"></script>
 | 
			
		||||
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div>点击如下按钮,发起支付宝扫码支付的测试</div>
 | 
			
		||||
<div>
 | 
			
		||||
    <button id="alipay_wap">支付宝扫码支付</button>
 | 
			
		||||
</div>
 | 
			
		||||
<div  id="qrcode"></div>
 | 
			
		||||
</body>
 | 
			
		||||
<style>
 | 
			
		||||
    #qrcode{
 | 
			
		||||
        padding-left: 20px;
 | 
			
		||||
        padding-top: 20px;
 | 
			
		||||
    }
 | 
			
		||||
</style>
 | 
			
		||||
<script>
 | 
			
		||||
    let shopOrderId = undefined;
 | 
			
		||||
    let payOrderId = undefined;
 | 
			
		||||
     let server = 'http://127.0.0.1:48080';
 | 
			
		||||
    $(function() {
 | 
			
		||||
        // 自动发起商城订单编号
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/shop/order/create",
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            success: function( result ) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('创建商城订单失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                shopOrderId = result.data.id;
 | 
			
		||||
                payOrderId = result.data.payOrderId;
 | 
			
		||||
                console.log("商城订单:" + shopOrderId)
 | 
			
		||||
                console.log("支付订单:" + payOrderId)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
    // 支付宝扫码支付
 | 
			
		||||
    $( "#alipay_wap").on( "click", function() {
 | 
			
		||||
        // 提交支付
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/pay/order/submit",
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            dataType: "json",
 | 
			
		||||
            contentType: "application/json",
 | 
			
		||||
            data: JSON.stringify({
 | 
			
		||||
                "id": payOrderId,
 | 
			
		||||
                "channelCode": 'alipay_qr'
 | 
			
		||||
            }),
 | 
			
		||||
            success: function( result ) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('提交支付订单失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                //提交支付后返回的参数
 | 
			
		||||
                let data = result.data.invokeResponse;
 | 
			
		||||
                new QRCode($("#qrcode")[0],{
 | 
			
		||||
                    text: data.qrCode, //内容
 | 
			
		||||
                    width:98, //宽度
 | 
			
		||||
                    height:98, //高度
 | 
			
		||||
                    correctLevel: 3,//二维码纠错级别
 | 
			
		||||
                    background: "#ffffff",//背景颜色
 | 
			
		||||
                    foreground: "#000000"//二维码颜色
 | 
			
		||||
                });
 | 
			
		||||
 | 
			
		||||
                console.log("data.qrCode===",data.qrCode)
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,65 +0,0 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
 | 
			
		||||
    <title>支付测试页</title>
 | 
			
		||||
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div>点击如下按钮,发起支付的测试</div>
 | 
			
		||||
<div>
 | 
			
		||||
    <button id="alipay_wap">支付宝手机网站支付</button>
 | 
			
		||||
</div>
 | 
			
		||||
<div id="dynamic_form"></div>
 | 
			
		||||
</body>
 | 
			
		||||
<script>
 | 
			
		||||
 | 
			
		||||
    let shopOrderId = undefined;
 | 
			
		||||
    let payOrderId = undefined;
 | 
			
		||||
     let server = 'http://127.0.0.1:48080';
 | 
			
		||||
    //let server = 'http://niubi.natapp1.cc';
 | 
			
		||||
 | 
			
		||||
    $(function() {
 | 
			
		||||
        // 自动发起商城订单编号
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/shop/order/create",
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            success: function( result ) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('创建商城订单失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                shopOrderId = result.data.id;
 | 
			
		||||
                payOrderId = result.data.payOrderId;
 | 
			
		||||
                console.log("商城订单:" + shopOrderId)
 | 
			
		||||
                console.log("支付订单:" + payOrderId)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $( "#alipay_wap").on( "click", function() {
 | 
			
		||||
        // 提交支付
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/pay/order/submit",
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            dataType: "json",
 | 
			
		||||
            contentType: "application/json",
 | 
			
		||||
            data: JSON.stringify({
 | 
			
		||||
                "id": payOrderId,
 | 
			
		||||
                "channelCode": 'alipay_wap'
 | 
			
		||||
            }),
 | 
			
		||||
            success: function( result ) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('提交支付订单失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                alert('点击确定,开始支付');
 | 
			
		||||
                //支付宝 手机WAP 返回表单,自动跳到支付宝支付页面
 | 
			
		||||
                let data = result.data.invokeResponse;
 | 
			
		||||
                $("#dynamic_form").html(data.body);
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
</html>
 | 
			
		||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -1,38 +0,0 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
 | 
			
		||||
    <title>社交登陆测试页</title>
 | 
			
		||||
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div>点击如下按钮,发起登陆的测试</div>
 | 
			
		||||
<div>
 | 
			
		||||
    <button id="wx_pub">微信公众号</button>
 | 
			
		||||
</div>
 | 
			
		||||
</body>
 | 
			
		||||
<script>
 | 
			
		||||
    // let server = 'http://127.0.0.1:28080';
 | 
			
		||||
    let server = 'http://192.168.1.2:48080';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // 微信公众号
 | 
			
		||||
    $( "#wx_pub").on( "click", function() {
 | 
			
		||||
        // 获得授权链接
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/social-auth-redirect?type=31&redirectUri=" +
 | 
			
		||||
                encodeURIComponent(server + '/static/social-login2.html'),  //重定向地址
 | 
			
		||||
            method: 'GET',
 | 
			
		||||
            success: function( result ) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('获得授权链接失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                // 跳转重定向
 | 
			
		||||
                document.location.href = result.data;
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
</script>
 | 
			
		||||
</html>
 | 
			
		||||
@@ -1,87 +0,0 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="UTF-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"/>
 | 
			
		||||
    <title>社交登陆测试页</title>
 | 
			
		||||
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
<div>点击如下按钮,授权登录</div>
 | 
			
		||||
<div>
 | 
			
		||||
    手机号<input id="mobile" value="15601691300"><br>
 | 
			
		||||
    手机验证码<input id="smsCode">
 | 
			
		||||
    <button id="send_sms_code">发送手机验证码</button>
 | 
			
		||||
    <br>
 | 
			
		||||
    <button id="wx_pub">微信公众号授权登录</button>
 | 
			
		||||
</div>
 | 
			
		||||
</body>
 | 
			
		||||
<script>
 | 
			
		||||
    // let server = 'http://127.0.0.1:48080';
 | 
			
		||||
    let server = 'http://192.168.1.2:48080';
 | 
			
		||||
 | 
			
		||||
    let type = 31; //登录类型 微信公众号
 | 
			
		||||
 | 
			
		||||
    // 微信公众号
 | 
			
		||||
    $("#wx_pub").on("click", function () {
 | 
			
		||||
        let code = getUrlParam("code"); // 访问授权连接后,会回调本页面地址,参数在本页面url后面
 | 
			
		||||
        let state = getUrlParam("state");
 | 
			
		||||
        console.log("获取code: " + code + ", state: " + state)
 | 
			
		||||
 | 
			
		||||
        let data = {
 | 
			
		||||
            'mobile': $('#mobile').val(),
 | 
			
		||||
            'smsCode': $('#smsCode').val(),
 | 
			
		||||
            'code': code,
 | 
			
		||||
            'state': state,
 | 
			
		||||
            'type': type
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // 调用授权登录接口
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/social-login2",
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            data: JSON.stringify(data),
 | 
			
		||||
            contentType: "application/json;charset=utf-8",
 | 
			
		||||
            dataType: "json",
 | 
			
		||||
            success: function( result ) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('调用授权登录接口失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                alert("授权登录成功, token: "+result.data.token)
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // 发送手机验证码
 | 
			
		||||
    $("#send_sms_code").on("click", function () {
 | 
			
		||||
        let data = {
 | 
			
		||||
            'mobile': $('#mobile').val(),
 | 
			
		||||
            'scene': 1 // 手机号登陆 类型
 | 
			
		||||
        }
 | 
			
		||||
        $.ajax({
 | 
			
		||||
            url: server + "/app-api/send-sms-code",
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            data: JSON.stringify(data),
 | 
			
		||||
            contentType: "application/json;charset=utf-8",
 | 
			
		||||
            dataType: "json",
 | 
			
		||||
            success: function (result) {
 | 
			
		||||
                if (result.code !== 0) {
 | 
			
		||||
                    alert('发送手机验证码失败,原因:' + result.msg)
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                alert("发送成功, 请查看日志");
 | 
			
		||||
            }
 | 
			
		||||
        })
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    //获取url中的参数
 | 
			
		||||
    function getUrlParam(name) {
 | 
			
		||||
        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象
 | 
			
		||||
        var r = window.location.search.substr(1).match(reg);  //匹配目标参数
 | 
			
		||||
        if (r != null) return unescape(r[2]);
 | 
			
		||||
        return null; //返回参数值
 | 
			
		||||
    }
 | 
			
		||||
</script>
 | 
			
		||||
</html>
 | 
			
		||||
		Reference in New Issue
	
	Block a user