黑马苍穹外卖7 用户下单+订单支付(微信小程序支付流程图)

地址簿

数据库表设计
在这里插入图片描述
就是基本增删改查,与前面的类似。

用户下单

用户点餐业务流程:
在这里插入图片描述
购物车-订单提交-订单支付-下单成功

展示购物车数据,不需要提交到后端
在这里插入图片描述
数据库设计:两个表【订单表orders,订单明细表order_detail】
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
DTO:
在这里插入图片描述
VO:
在这里插入图片描述
controller:

@RestController("UserOrderController")//作为Bean名称,避免与admin端名称重复
@RequestMapping("/user/order")
@Api(tags = "B端用户订单接口")
public class OrderController {

    @Autowired
    private OrderService orderService;

    @PostMapping("/submit")
    @ApiOperation("用户下单")
    public Result<OrderSubmitVO> submit(@RequestBody OrdersSubmitDTO submitDTO){
        return Result.success(orderService.submit(submitDTO));//传入DTO返回VO
    }

service :
@Transactional//设计几多个数据表,需要保证数据一致性,需要事务注解–保证原子性,全成功或全失败

@Transactional//事务注解 -方法执行完提交才插入
    @Override
    public OrderSubmitVO submit(OrdersSubmitDTO submitDTO) {
    //处理各种业务异常检查(地址是否为空,购物车是否为空)
        AddressBook addressBook = addressBookMapper.getById(submitDTO.getAddressBookId());
        if (addressBook == null) {
            throw new AddressBookBusinessException(MessageConstant.ADDRESS_BOOK_IS_NULL);
        }
        //检查当前用户的购物车是否为空
        Long userId = BaseContext.getCurrentId();//当前用户ID

        ShoppingCart shoppingCart = new ShoppingCart();
        shoppingCart.setUserId(userId);
        List<ShoppingCart> list = shoppingCartMapper.list(shoppingCart);
        if (list == null || list.size() == 0) {
            throw new ShoppingCartBusinessException(MessageConstant.SHOPPING_CART_IS_NULL);
        }
        //1.增加一条订单信息
        Orders orders = new Orders();
        BeanUtils.copyProperties(submitDTO, orders);
        orders.setOrderTime(LocalDateTime.now());
        orders.setPayStatus(Orders.UN_PAID);
        orders.setStatus(Orders.PENDING_PAYMENT);
        orders.setNumber(String.valueOf(System.currentTimeMillis()));
        orders.setPhone(addressBook.getPhone());
        orders.setConsignee(addressBook.getConsignee());//收货人
        orders.setUserId(userId);//用户ID

        orderMapper.insert(orders);
        //2.增加多条订单详情
        List<OrderDetail> orderDetailList = new ArrayList<>();//整个批量插入
        for (ShoppingCart cart : list) {//遍历购物车里的数据
            OrderDetail orderDetail = new OrderDetail();//订单单明细
            BeanUtils.copyProperties(cart, orderDetail);
            orderDetail.setOrderId(orders.getId());//设置当前订单明细关联的订单id
            orderDetailList.add(orderDetail);
        }

        orderDetailMapper.insertBatch(orderDetailList);

        //3.删除用户购物车
        shoppingCartMapper.deleteByUserId(userId);

        //4.封装VO对象并返回
        OrderSubmitVO orderSubmitVO = OrderSubmitVO.builder()
            .id(orders.getId())
            .orderNumber(orders.getNumber())
            .orderTime(orders.getOrderTime())
            .orderAmount(orders.getAmount())
            .build();

        return orderSubmitVO;

    }

增加1订单
mapper:

 void insert(Orders orders);

xml:出入后返回订单主键值

<insert id="insert" parameterType="Orders" useGeneratedKeys="true" keyProperty="id">
        insert into orders (number, status, user_id, address_book_id, order_time, checkout_time, pay_status, pay_method,amount, remark, phone, address, consignee, estimated_delivery_time, delivery_status,pack_amount, tableware_number, tableware_status)
        values (#{number}, #{status}, #{userId}, #{addressBookId}, #{orderTime}, #{checkoutTime}, #{payMethod},
                #{payStatus}, #{amount}, #{remark}, #{phone}, #{address}, #{consignee}, #{estimatedDeliveryTime},
                #{deliveryStatus}, #{packAmount}, #{tablewareNumber}, #{tablewareStatus})
    </insert>

批量增加订单详情:

 void insertBatch(List<OrderDetail> orderDetailList);
<insert id="insertBatch">
        insert into order_detail (name, image, order_id, dish_id, setmeal_id, dish_flavor, number, amount)
        values
        <foreach collection="orderDetailList" item="od" separator=",">
            (#{od.name},#{od.image},#{od.orderId} ,#{od.dishId},#{od.setmealId},#{od.dishFlavor},#{od.number},#{od.amount})
        </foreach>
    </insert>

订单支付(*流程)

微信支付介绍

在这里插入图片描述JSAPI下单:商户调用该接口在后台生成预支付交易单,返回表示,

微信支付准备工作

两个问题:

1.调用过程如何保证数据安全?

获取微信支付平台整证书、商户私钥文件
从微信商户平台得到两个文件

2.微信后台如何调用到商户系统?

当前商务系统的ip就是本地电脑ip这个局域网的IP,微信后跳调用不到,应该用公网IP。
获取临时域名:
cpolar.exe内网穿透生成一个临时域名。
略。

从用户发起支付订单开始看:

@PutMapping("/payment")
    @ApiOperation("订单支付")
    public Result<OrderPaymentVO> payment(@RequestBody OrdersPaymentDTO ordersPaymentDTO) throws Exception {

        //订单支付
        OrderPaymentVO orderPaymentVO = orderService.payment(ordersPaymentDTO);
        //生成预交易订单
        return Result.success(orderPaymentVO);
    }
public OrderPaymentVO payment(OrdersPaymentDTO ordersPaymentDTO) throws Exception {
        // 当前登录用户id
        Long userId = BaseContext.getCurrentId();
        User user = userMapper.getById(userId);

        //调用微信支付接口,生成预支付交易单
        JSONObject jsonObject = weChatPayUtil.pay(//***这个微信支付工具类--即调用微信支付接口
            ordersPaymentDTO.getOrderNumber(), //商户订单号
            new BigDecimal(0.01), //支付金额,单位 元
            "苍穹外卖订单", //商品描述
            user.getOpenid() //微信用户的openid
        );

        if (jsonObject.getString("code") != null && jsonObject.getString("code").equals("ORDERPAID")) {
            throw new OrderBusinessException("该订单已支付");
        }

        OrderPaymentVO vo = jsonObject.toJavaObject(OrderPaymentVO.class);
        vo.setPackageStr(jsonObject.getString("package"));

        return vo;
    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/742592.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

模组硬件通用丨模组USB电路设计指南

USB&#xff08;全称&#xff1a;Universal Serial Bus&#xff09;是一种串口总线标准&#xff0c;也是一种输入输出接口的技术规范&#xff0c;广泛应用于个人电脑和移动设备等信息通讯产品&#xff0c;并扩展至摄影器材、数字电视&#xff08;机顶盒&#xff09;、游戏机等相…

zabbix“专家坐诊”第243期问答

问题一 Q&#xff1a;zabbix监控的设备有点多了&#xff0c;想清理一下历史数据&#xff0c;官方有插件或者方法吗&#xff1f; A&#xff1a;清空数据库里history表。&#xff08;注意&#xff1a;是清空不是删除&#xff09; 问题二 Q&#xff1a;可以自定义设置数据的保存时…

用护眼灯还需要开灯吗?揭示护眼台灯四大危害原因

随着生活品质的提高&#xff0c;护眼台灯成为了许多家庭的新宠。它以使用便捷、护眼的特性深受欢迎&#xff0c;然而&#xff0c;随着护眼台灯的流行&#xff0c;市场上涌现了大量质量参差不齐的产品。在开启过程中&#xff0c;这些劣质产品可能会释放出比较微弱的光线&#xf…

EfficientNet-V1论文阅读笔记

目录 EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks摘要Introduction—简介Compound Model Scaling—混合模型缩放Problem Formulation—范式化问题&#xff08;理论基础&#xff09;Scaling Dimensions—维度缩放Compound Scaling—混合缩放 Eff…

mysql数据库的管理

MySQL数据库管理 mysql数据文件 存放在初始化时定义的datadir 该目录下放置三种后缀文件 .frm 与表相关的元数据&#xff08;meta&#xff09;&#xff0c;表结构的定义信息等。 .MYD mylSAM存储引擎专用 .MYI mylSAM存储引擎专用 MySQL语言类型 DDL&#xff08;数据定义语言…

ElementUI table的设置成Excel表格效果

实现效果代码最重要的部分 <el-table:data"Commision"border:row-style"{height: 0}":cell-style"{padding: 0 ,lineHeight: 0}":header-cell-style"{padding: 0,height: 0,ineHeight: 0}"><el-col :span"11">&…

生鲜水果行业wordpress主题

水果蔬菜wordpress外贸自建站模板 水果、脐橙、牛油果、菠萝、凤梨、鲜枣、苹果、芒果、瓜果、百香果wordpress外贸独立站模板。 https://www.jianzhanpress.com/?p3932 生鲜wordpress外贸出口网站模板 水果、蔬菜、肉蛋奶、水产、干货等生鲜产品wordpress外贸出口公司网站…

昇思25天学习打卡营第6天 | 函数式自动微分

神经网络的训练主要使用反向传播算法&#xff0c; 模型预测值&#xff08;logits&#xff09;与正确标签&#xff08;label&#xff09;送入损失函数&#xff08;loss function&#xff09;获得loss&#xff0c; 然后进行反向传播计算&#xff0c;求得梯度&#xff08;gradie…

Python Web实战:Python+Django+MySQL实现基于Web版的增删改查

项目实战 1.创建项目(sms) File->New Project->Django 稍等片刻&#xff0c;项目的目录结构如下图 项目创建后确认是否已安装Django和mysqlclient解释器&#xff0c;如何确认&#xff1f;file->Settings 如果没有请在Terminal终端输入以下命令完成安装 pip instal…

用户是如何访问网站的?

由于IP地址不方便记忆并且不能显示地址组织的名称和性质&#xff0c;人们设计出了域名&#xff0c;并通过域名系统&#xff08;DNS&#xff0c;Domain Name System&#xff09;来将域名和IP地址相互映射&#xff0c;使人更方便地访问互联网&#xff0c;而不用去记住能够被机器直…

【Docker】镜像

目录 1. 镜像拉取 2. 镜像查询 3. 镜像导出 4. 镜像上传 5. 镜像打标签 6. 镜像上推 7. 镜像删除 8. 镜像运行及修改 8.1 在registry 节点运行 mariadb 镜像&#xff0c;将宿主机 13306 端口作为容器3306 端口映射 8.2 查看容器ID 8.3 进入容器 8.4 创建数据库xd_d…

openfeign的原理 ????

1、我们使用openfeign调用远程接口就像调用本地方法一样简单。 2、支持spring mvc 注解 3、整合了更多的扩展 &#xff08;请求重试策略、超时控制、请求拦截器&#xff09; 4、open Feign是基于aop的原理&#xff0c;他会通过所加FeignClient的接口&#xff0c;自动拼接接口…

揭秘!今日头条爆款文章打造秘诀:低粉作者如何逆袭,成为流量王者?一文带你掌握!

大家好&#xff0c;我是网创有方的站长&#xff0c;今天特地对某头条作者的优质文章内容做了下分析。欢迎各位共同讨论&#xff0c;如果有什么想法的可以评论区留言或者私信讨论。下面开始咱们的正题&#xff1a; 要想文章写的好&#xff0c;那么首先要先会学习人家的优质作品…

react学习——14react生命周期图(旧)

1、生命周期图 2、单个组件 class Demo extends React.Component{//构造器constructor(props){console.log("count--constructor")super(props)this.state{count: 1}}//组件将要挂载componentWillMount(){console.log("count--componentWillMount")}//组件…

TypeError: compilation.getPathWithInfo is not a function

本地运行&#xff0c;npm run dev 正常启动&#xff0c;当修改内容后保存&#xff0c;出现报错&#xff0c;中断编译。 TypeError: compilation.getPathWithInfo is not a function 项目首次能成功运行&#xff0c;热更新时报错而中断&#xff1b; 参考网上的解决办法&#x…

linux rocky9.2系统搭建sqle数据库审核平台

文章目录 前言一、环境准备?二、开始部署前言 关于SQLE SQLE 是由上海爱可生信息技术股份有限公司 开发并开源,支持SQL审核、索引优化、事前审核、事后审核、支持标准化上线流程、原生支持 MySQL 审核且数据库类型可扩展的 SQL 审核工具。 产品特色 支持通过插件的形式扩展…

什么牌子的开放式耳机好?五大优质机型,新手必看!小白闭眼入系列

音乐技术的不断进步为耳机市场的发展有了更多的选择&#xff0c;开放式耳机成为音乐爱好者们新的一个选择。从最初的基础音质到如今的高解析度音频&#xff0c;开放式耳机经历了一次次的技术革新和升级。这类耳机以开放式不入耳的设计&#xff0c;舒适的佩戴体验著称&#xff0…

动作捕捉与数字人实训室,引领动漫专业创新发展

如今&#xff0c;随着全身动作捕捉设备在动漫行业中的应用越来越重要&#xff0c;传统的教学模式与市场需求逐渐脱节&#xff0c;原有的教学方式和思路急需进行调整。高校通过搭建动作捕捉与数字人实训室&#xff0c;可以使得教学质量和效率大大提升&#xff0c;让学生能够接触…

python-九九乘法表(对齐式1)

[题目描述] 输出九九乘法表&#xff0c;输出格式见样例。输入格式&#xff1a; 无输出格式&#xff1a; 输出乘法表&#xff0c;对齐方式见样例输出。样例输入 无样例输出 来源/分类&#xff08;难度系数&#xff1a;一星&#xff09; 完整代码展示&#xff1a; #对齐式1 a[] …

C#的无边框窗体项目模板 - 开源研究系列文章

继续整理和编写代码及博文。 这次将笔者自己整理的C#的无边框窗体项目的基本模板进行总结&#xff0c;得出了基于C#的.net framework的Winform的4个项目模板&#xff0c;这些模板具有基本的功能&#xff0c;即已经初步将代码写了&#xff0c;直接在其基础上添加业务代码即可&am…