小熊家务帮day19-day21 订单模块2(取消订单,退款功能等)

目录

  • 1 订单退款功能
  • 1.1 需求分析
    • 1.2 接口分析
    • 1.3 退款流程分析
    • 1.4 表结构设计
    • 1.5 取消未支付订单实现
      • 1.5.1 接口开发
        • Controller层开发
        • Service层开发
      • 1.5.2 接口测试
    • 1.5 取消已支付订单实现

1 订单退款功能

1.1 需求分析

用户下单成功可以取消订单,在订单的不同状态下去取消订单其执行的逻辑是不同的:

  • 待支付状态下取消订单: 更改订单的状态为已取消。
    -订单已支付,状态为待派单时取消订单: 更改订单的状态为已关闭,请求支付服务自动退款。

用户在订单列表点击订单信息进入订单详情页面,点击“取消订单”
在这里插入图片描述
进入取消订单界面:
在这里插入图片描述
选择取消原因,点击“提交”。

1.2 接口分析

前端传入的参数:订单id、取消原因。
响应参数:无,前端根据状态码判断是否成功。
接口名称:取消订单
接口路径:PUT /orders-manager/consumer/orders/cancel
在这里插入图片描述
在这里插入图片描述

1.3 退款流程分析

根据需求分析,当订单已支付状态为派单中时取消订单后进行自动退款,此时需要调用支付服务的申请退款接口。
流程如下:
在这里插入图片描述
取消订单执行如下操作:
1、更新订单状态
待支付状态下取消订单后更新订单状态为“已取消”
派单中状态下取消订单后更新订单状态为“已关闭”
2、保存取消订单记录,记录取消的原因等信息。
3、远程调用支付服务的退款接口申请退款。

取消派单中的订单存在如下问题:
远程调用退款接口操作不放在事务方法中,避免影响数据库性能。
如果远程调用退款接口失败了将无法退款,这个怎么处理?
以上问题采用异步退款的方式来解决:
如下图:
在这里插入图片描述

1、使用数据库事务控制,保存以下数据
更新订单状态。
保存取消订单记录表,记录取消的原因等信息。
保存退款记录表。
2、事务提交后先启动一个线程请求支付服务的退款接口(为了及时退款)
3、定时任务扫描退款记录表,对未退款的记录请求支付服务进行退款,退款成功更新订单的退款状态,并删除退款记录。
说明:
第2步的作用为了第一时间申请退款,因为定时任务会有一定的延迟。
第3步的作用是由定时任务去更新退款的状态,因为调用了退款接口只是申请退款了,退款结果可能还没有拿到,通过定时任务再次请求支付服务的退款接口,拿到退款结果。

1.4 表结构设计

订单取消记录表:

create table `jzo2o-orders`.orders_canceled
(
    id             bigint                             not null comment '订单id'
        constraint `PRIMARY`
        primary key,
    canceller_id   bigint                             null comment '取消人',
    canceler_name  varchar(50)                        null comment '取消人名称',
    canceller_type int                                null comment '取消人类型,1:普通用户,4:运营人员',
    cancel_reason  varchar(50)                        null comment '取消原因',
    cancel_time    datetime                           null comment '取消时间',
    create_time    datetime default CURRENT_TIMESTAMP not null comment '创建时间',
    update_time    datetime default CURRENT_TIMESTAMP not null on update CURRENT_TIMESTAMP comment '更新时间'
)

订单退款记录表:存储 待退款的记录

create table `jzo2o-orders`.orders_refund
(
    id               bigint                             not null comment '订单id'
        constraint `PRIMARY`
        primary key,
    trading_order_no bigint                             null comment '支付服务交易单号',
    real_pay_amount  decimal(10, 2)                     null comment '实付金额',
    create_time      datetime default CURRENT_TIMESTAMP null comment '创建时间'
)

1.5 取消未支付订单实现

根据需求,取消订单需要实现两部分功能:
针对未支付订单的取消操作:

  • 修改订单的状态为已取消。
  • 保存取消订单的记录。

1.5.1 接口开发

Controller层开发
@RestController("operationOrdersController")
@Api(tags = "运营端-订单相关接口")
@RequestMapping("/operation/orders")
public class OperationOrdersController {


    @Autowired
    private IOrdersManagerService ordersManagerService;

    @PutMapping("/cancel")
    @ApiOperation("取消订单")
    public void cancel(@RequestBody OrderCancelReqDTO orderCancelReqDTO) {
        //填充数据
        OrderCancelDTO orderCancelDTO = BeanUtil.toBean(orderCancelReqDTO, OrderCancelDTO.class);
        CurrentUserInfo currentUserInfo = UserContext.currentUser();
        orderCancelDTO.setCurrentUserId(currentUserInfo.getId());
        orderCancelDTO.setCurrentUserName(currentUserInfo.getName());
        orderCancelDTO.setCurrentUserType(currentUserInfo.getUserType());
        ordersManagerService.cancel(orderCancelDTO);
    }
}

Service层开发
    /**
     * 取消订单
     * @param orderCancelDTO 取消订单模型
     */
    @Override
    public void cancel(OrderCancelDTO orderCancelDTO) {

        //判断订单是否存在
        if(ObjectUtils.isNull(this.getById(orderCancelDTO.getId()))){
            throw new CommonException("要取消的订单不存在");
        }

        Integer ordersStatus = this.getById(orderCancelDTO.getId()).getOrdersStatus();
        if(ordersStatus.equals(OrderStatusEnum.NO_PAY.getStatus())){
            //对未支付订单进行取消
            owner.cancelByNoPay(orderCancelDTO);
        }else if(ordersStatus.equals(OrderStatusEnum.DISPATCHING.getStatus())){
            //对已支付(派单中)订单进行取消

        }else{
            throw new CommonException("当前订单状态不支持取消");
        }
    }

    /**
     * 未支付状态取消订单
     */
    @Transactional(rollbackFor = Exception.class)
    public void cancelByNoPay(OrderCancelDTO orderCancelDTO){

        //添加订单取消记录
        OrdersCanceled ordersCanceled = BeanUtils.toBean(orderCancelDTO,OrdersCanceled.class);
        ordersCanceled.setCancellerId(orderCancelDTO.getCurrentUserId());
        ordersCanceled.setCancelerName(orderCancelDTO.getCurrentUserName());
        ordersCanceled.setCancellerType(orderCancelDTO.getCurrentUserType());
        ordersCanceled.setCancelTime(LocalDateTime.now());
        canceledService.save(ordersCanceled);

        //修改订单状态为已取消
        OrderUpdateStatusDTO orderUpdateStatusDTO = new OrderUpdateStatusDTO();
        //需要传入 id 原始状态 更新状态
        orderUpdateStatusDTO.setId(orderCancelDTO.getId());
        orderUpdateStatusDTO.setOriginStatus(OrderStatusEnum.NO_PAY.getStatus());
        orderUpdateStatusDTO.setTargetStatus(OrderStatusEnum.CANCELED.getStatus());
        Integer res = commonService.updateStatus(orderUpdateStatusDTO);
        if(res <= 0){
            throw new CommonException("取消订单失败");
        }

    }

1.5.2 接口测试

先弄个没支付的订单:
在这里插入图片描述
点击取消支付:
在这里插入图片描述
功能测试完成

1.5 取消已支付订单实现

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

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

相关文章

机器视觉系统-同轴光源大小选择技巧

同轴光源多用于检测光滑平面产品上的缺陷&#xff0c;同样利用上述的方法计算得出光源尺寸。 实际上&#xff0c;同轴光源可理解为没有孔的开孔面光&#xff0c;因此可等效为发光面相等的面光源&#xff0c;如下图&#xff1a; 如图所示&#xff0c;同轴光源的效果与开孔面光的…

【Labview】通过串口通信从上位机读取和写入数据

最近博主需要通过Labview的上位机控制一个温控仪表&#xff0c;主要实现在上位机读取实时温度和设定的目标温度&#xff0c;以及通过上位机设定目标温度。这里将其中遇到的问题和心得分享给大家&#xff0c;博主自己也做一个记录。 由于温控仪表采用的485通讯&#xff0c;modb…

王学岗鸿蒙开发(北向)——————(十)子组件修改父组件的内容与 动画

子组件修改父组件的内容 使用类似Android的回调&#xff0c;父组件传递给子组件一个函数 import { MyComment } from ./component/MyComment import { MyContent } from ./component/MyComtent import { MyTitleComponent } from ./component/MyTitleComponentEntry Componen…

现代x86汇编-环境安装

今天端午节&#xff0c;独自在家&#xff0c;翻阅了张银奎老师编写的《现代x86汇编语言程序设计》一书&#xff0c;前言部分说明书中示例代码都是用微软visual C工具编写并使用微软宏汇编&#xff08;著名的MASM&#xff09;编译的&#xff0c;好久没有用微软vc了&#xff0c;假…

18.2 HTTP服务器-处理函数、响应404错误

1. 处理函数 处理来自客户端的请求&#xff0c;并回之以特定的响应&#xff0c;这是处理函数的主要任务。在处理函数中&#xff0c;我们通常会完成如下工作&#xff1a; 验证请求路径 http.Request.URL.Pathhttp.NotFound(...) 当请求没有对应的处理函数时&#xff0c;返回4…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《计及电-气园区综合能源系统多重不确定性的变置信区间优化调度 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

物联网概念

物联网 物联网简介物联网体系结构物联网体系结构定义物联网体系结构设计原则物联网体系结构四层物联网体系结构感知控制层数据传输层数据处理层应用决策层 物联网关键技术感知标识技术网络与通信技术云计算技术安全技术 已有物联网相关应用架构无线传感器网络的体系结构EPC/UID…

【讲解下Chrome DevTools,什么是Chrome DevTools?】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

精神建设:为什么要学C语言以及如何学习C语言

一&#xff0c;为什么要学习C语言 学习C语言有以下几个重要原因&#xff1a; 基础性&#xff1a;C语言是一种非常基础的编程语言&#xff0c;它接近计算机硬件层面&#xff0c;让你能够更深入地理解计算机系统如何工作&#xff0c;包括内存管理、指针操作等。这对于构建坚实的…

2024年6月最新开源电视影视TVAPP原生源码和后台管理平台源码及完整教程

本套源码为本人维护更新完善半年左右的还在使用开发的源码&#xff0c;与市面上倒卖的残次品不一样&#xff0c;没有可比性&#xff0c;向下兼容安卓4.0&#xff0c;向上兼容安卓13以上TV电视系统&#xff0c; 完全无闪退&#xff0c;弹窗报错&#xff0c;卡死、异常死循环残次…

[FreeRTOS 基础知识] 任务调度 与 链表

文章目录 任务并行的概念RTOS如何实现多任务调度&#xff1f; 任务并行的概念 在生活中&#xff0c;经常出现一心多用的情况。比如你需要一边吃饭一边手机回复信息&#xff0c;这里面就存在两个任务&#xff1a;任务一、吃饭。任务二、手机回复信息。 假如你无法一心多用&…

数据仓库核心:事实表深度解析与设计指南

文章目录 1. 引言1.1基本概念1.2 事实表定义 2. 设计原则2.1 原则一&#xff1a;全面覆盖业务相关事实2.2 原则二&#xff1a;精选与业务过程紧密相关的事实2.3 原则三&#xff1a;拆分不可加事实为可加度量2.4 原则四&#xff1a;明确声明事实表的粒度2.5 原则五&#xff1a;避…

Harmony中的HAP、HAR、HSP区别

Harmony中的HAP、HAR、HSP区别 想要更加合理的开发一个企业级别的Harmony应用&#xff0c;那么就不得不提其中的HAP、HAR、HSP了。 前言 对于普通的用户来说&#xff0c;可能一个普通的应用就等于一个安装文件如安卓下的APK。但是对于Harmony应用开发工程师来讲&#xff0c;…

单田芳mp3百度网盘,单田芳评书下载百度云百度网盘

单老的评书还注重情感的表达。他善于运用声音、语气、语调等手段&#xff0c;将人物的情感刻画得淋漓尽致。无论是喜怒哀乐&#xff0c;他都能准确地把握人物的情感变化&#xff0c;并通过自己的表演将其传递给听众。这种情感的传递&#xff0c;使得听众能够更加深入地理解故事…

构建大语言模型友好型网站

以大语言模型为代表的AI 技术迅速发展&#xff0c;将会影响原有信息网络的方式。其中一个明显的趋势是通过chatGPT 对话代替搜索引擎和浏览器来获取信息。 互联网时代&#xff0c;主要是通过网站&#xff08;website&#xff09;提供信息。网站主要为人类阅读的方式构建的。主要…

Vitis HLS 学习笔记--聚合与解聚-AXI主接口

目录 1. 简介 2. 用法及语法 3. 详细解读 4. 总结 1. 简介 在使用 Vitis HLS 工具进行硬件设计时&#xff0c;如果你在接口上使用了结构体&#xff0c;工具会自动把结构体里的所有元素组合成一个整体。就像把一堆零件组装成一个玩具一样。这样做的好处是&#xff0c;数据可…

【VUE3 element时间选择器默认选择七天】

VUE3 element时间选择器默认选择七天 <el-date-pickerv-model"form.timeRange"type"datetimerange"start-placeholder"开始时间"end-placeholder"结束时间"format"YYYY-MM-DD HH:mm:ss"date-format"YYYY/MM/DD dd…

遗传算法笔记:基本工作流程

1 介绍 遗传算法有5个主要任务&#xff0c;直到找到最终的解决方案 2 举例 2.1 问题描述 比如我们有 5 个变量和约束&#xff0c;其中 X1、X2、X3、X4 和 X5 是非负整数且小于 10&#xff08;0、1、2、4、5、6、7、8、9&#xff09;我们希望找到 X1、X2、X3、X4 和 X5 的最…

背包问题—动态规划

01背包问题&#xff1a;没有物品&#xff08;元素&#xff09;只能选择1次 【模板】01背包_牛客题霸_牛客网 (nowcoder.com) #include <array> #include <cstring> #include <iostream> #include<vector> using namespace std; int n,V; int dp[1001…

OJ刷题——2086.AI=?、2087.剪花布条、KPM算法

2086.AI&#xff1f; 题目描述 Problem - 2086 运行代码 #include <iostream> #include <cstdio> using namespace std; const int N 3005; int main() {int n;double Ao, An;double num[N];while (cin>>n) {cin >> Ao>>An;for (int i 1; i…