订单服务:订单流程

news2024/9/24 5:33:08

订单流程

订单流程是指从订单产生到完成整个流转的过程,从而行程了一套标准流程规则。而不同的产品类型或业务类型在系统中的流程会千差万别,比如上面提到的线上实物订单和虚拟订单的流程,线上实物订单与 O2O 订单等,所以需要根据不同的类型进行构建订单流程。不管类型如何订单都包括正向流程和逆向流程,对应的场景就是购买商品和退换货流程,正向流程就是一个正常的网购步骤:

订单生成–>支付订单–>卖家发货–>确认收货–>交易成功。而每个步骤的背后,订单是如何在多系统之间交互流转的,可概括如下图

1、订单创建与支付

(1) 、订单创建前需要预览订单,选择收货信息等

(2) 、订单创建需要锁定库存,库存有才可创建,否则不能创建

(3) 、订单创建后超时未支付需要解锁库存

(4) 、支付成功后,需要进行拆单,根据商品打包方式,所在仓库,物流等进行拆单

(5) 、支付的每笔流水都需要记录,以待查账

(6) 、订单创建,支付成功等状态都需要给 MQ 发送消息,方便其他系统感知订阅

2、逆向流程

(1) 、修改订单,用户没有提交订单,可以对订单一些信息进行修改,比如配送信息, 优惠信息,及其他一些订单可修改范围的内容,此时只需对数据进行变更即可。

(2) 、订单取消,用户主动取消订单和用户超时未支付,两种情况下订单都会取消订

单,而超时情况是系统自动关闭订单,所以在订单支付的响应机制上面要做支付的限时处理,尤其是在前面说的下单减库存的情形下面,可以保证快速的释放库存。 另外需要需要处理的是促销优惠中使用的优惠券,权益等视平台规则,进行相应补 回给用户。

(3) 、退款,在待发货订单状态下取消订单时,分为缺货退款和用户申请退款。如果是 全部退款则订单更新为关闭状态,若只是做部分退款则订单仍需进行进行,同时生 成一条退款的售后订单,走退款流程。退款金额需原路返回用户的账户。

(4) 、发货后的退款,发生在仓储货物配送,在配送过程中商品遗失,用户拒收,用户收货后对商品不满意,这样情况下用户发起退款的售后诉求后,需要商户进行退款的审核,双方达成一致后,系统更新退款状态,对订单进行退款操作,金额原路返回用户的账户,同时关闭原订单数据。仅退款情况下暂不考虑仓库系统变化。如果发生双方协调不一致情况下,可以申请平台客服介入。在退款订单商户不处理的情况下,系统需要做限期判断,比如 5 天商户不处理,退款单自动变更同意退款。

OrderWebConfiguration

@Configuration
public class OrderWebConfiguration implements WebMvcConfigurer {

    @Autowired
    LoginUserInterceptor loginUserInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginUserInterceptor).addPathPatterns("/***");
    }
}

GuliFeignConfig

public class GuliFeignConfig {

    @Bean
    public RequestInterceptor requestInterceptor(){

        return  new RequestInterceptor() {
            @Override
            public void apply(RequestTemplate template) {
                ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
                HttpServletRequest request = attributes.getRequest();
                //同步请求头数据
                String cookie = request.getHeader("Cookie");
                template.header("Cookie",cookie);
                System.out.println("feign运程之前先进行构造");

            }
        };
    }
}

LoginUserInterceptor

 

@Component
public class LoginUserInterceptor implements HandlerInterceptor {

    public static  ThreadLocal<MemberResponseVo> loginUser=new ThreadLocal<>();

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        MemberResponseVo attribute = (MemberResponseVo) request.getSession().getAttribute(AuthServerConstant.LOGIN_USER);
        if(attribute!=null){

            loginUser.set(attribute);

            return  true;
        }else{
            request.getSession().setAttribute("msg","请先进行登录");
            response.sendRedirect("http://auth.gulimall.com/login.html");
            return false;
        }
    }
}

OrderConfirmVo

public class OrderConfirmVo {

    @Setter @Getter
    List<MemberAddressVo> address;

    @Setter @Getter
    List<OrderItemVo> items;

    @Setter @Getter
    Integer integration;



    public Integer getCount(){
        Integer i=0;
        if(items!=null){
            for (OrderItemVo item : items) {
                i+=item.getCount();
            }
        }
        return i;
    }
    //防重令牌
    @Setter @Getter
    String orderToken;

    @Setter @Getter
    Map<Long,Boolean> stocks;

    BigDecimal total;

    public BigDecimal getTotal() {
        BigDecimal sum = new BigDecimal("0");
        if(items!=null){
        for (OrderItemVo item : items) {

                BigDecimal multiply = item.getPrice().multiply(new BigDecimal(item.getCount().toString()));
               sum= sum.add(multiply) ;
            }
        }
        total=sum;
        return sum;
    }

    BigDecimal payPrice;

    public BigDecimal getPayPrice() {
        payPrice= getTotal();
      return getTotal();
    }
}

 

confirmOrder()

    @Override
    public OrderConfirmVo confirmOrder() {

        RequestAttributes attributes = RequestContextHolder.getRequestAttributes();
        OrderConfirmVo confirmVo = new OrderConfirmVo();
        MemberResponseVo memberResponseVo = LoginUserInterceptor.loginUser.get();
        CompletableFuture<Void> getAddressFuture = CompletableFuture.runAsync(() -> {
            //1.运程查询所有的收货地址
            RequestContextHolder.setRequestAttributes(attributes);
            List<MemberAddressVo> address = memberFeignService.getAddress(memberResponseVo.getId());
            confirmVo.setAddress(address);
        }, executor);

        CompletableFuture<Void> cartFuture = CompletableFuture.runAsync(() -> {
            //2.运程查询购物车所有选中的购物项
            RequestContextHolder.setRequestAttributes(attributes);

            List<OrderItemVo> items = cartFeignService.getCurrentUserCartItems();
            confirmVo.setItems(items);
        }, executor).thenRunAsync(()->{
            List<OrderItemVo> items = confirmVo.getItems();
            List<Long> collect = items.stream().map(item -> item.getSkuId()).collect(Collectors.toList());
            R hashStock = wmsFeignService.getSkuHashStock(collect);
            List<SkuStockVo> data = hashStock.getData(new TypeReference<List<SkuStockVo>>() {
            });
            if(data!=null){
                Map<Long, Boolean> map = data.stream().collect(Collectors.toMap(SkuStockVo::getSkuId, SkuStockVo::getHasStock));
                confirmVo.setStocks(map);
            }
        },executor);

        //3.查询用户积分
            Integer integration = memberResponseVo.getIntegration();
            confirmVo.setIntegration(integration);


        //其他数据自动调用
        //todo 防重令牌

        try {
            CompletableFuture.allOf(cartFuture,getAddressFuture).get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        return confirmVo;
    }

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[Datawhale][CS224W]图机器学习(三)

目录一、简介与准备二、教程2.1 下载安装2.2 创建图2.2.1 常用图创建&#xff08;自定义图创建&#xff09;1.创建图对象2.添加图节点3.创建连接2.2.2 经典图结构1.全连接无向图2.全连接有向图3.环状图4.梯状图5.线性串珠图6.星状图7.轮辐图8.二项树2.2.3 栅格图1.二维矩形栅格…

如何修改 类名::静态变量?

好久没更新了&#xff0c;其中经历了备战省赛&#xff0c;重装电脑&#xff0c;换服务器&#xff0c;重新搭建博客等一系列事&#xff0c;受到许多技术大牛的指点&#xff0c;而且新人太厉害了&#xff0c;卷卷卷&#xff01; Geek Challenge 2021有一道BabyPOP&#xff0c;这…

vue写一个翻页的时间插件

读秒效果有一个从上向下的翻页效果 效果图 clock代码 <template><div class"dateClock"><div class"todayClass"><p class"datep">{{dateToday}}</p><span style"float:right;font-size:16px">…

基于 VPX 总线的工件台运动控制系统研究与开发-DSP+FPGA硬件架构(一)

作为光刻机核心单元之一&#xff0c;超精密工件台主要负责实现快速扫描、上下片、精密定位、调平调焦等功能。目前&#xff0c;较为成熟的方案大多采用 VME 并行总线架构来建立超精密工件台控制系统&#xff0c;由于随着系统性能要求的提升&#xff0c;VME 总线以及相应的处理器…

最大连续子列和

给定一个数组&#xff0c;求它的最大连续子列和。这个问题有四种解法。 1、暴力循环(O(n^3))分析这个问题&#xff0c;既然是子列&#xff0c;那么它最长为n&#xff0c;最短为1。要想求和我们一般需要知道这个子列的左端下标和右端下标&#xff0c;再求这个子列的和。最简单的…

深入浅出带你学习Nginx中间件常见漏洞

前言 上篇文章总结了APACHE中间件的常见漏洞&#xff0c;本文介绍一个同样很常用的中间件——nginx&#xff0c;本文会讲解关于nginx中间件的常见漏洞利用方式与危害&#xff0c;下面展开来给大家讲解。 Nginx是什么&#xff1f; 在讲漏洞之前我们需要先知道什么是nginx,简单…

《SQL基础》11. 索引

SQL - 索引索引概述结构B-TreeBTreeHash思考分类语法SQL性能分析SQL执行频率慢查询日志profile详情explain执行计划索引失效情况范围查询索引列运算字符串不加引号模糊查询or连接条件数据分布影响使用规则最左前缀法则SQL提示覆盖索引前缀索引设计原则索引 概述 索引&#xf…

linux安装minio,注册服务实现开机自启动

一、安装1.创建安装目录mkdir -p /usr/local/soft/minio2.下载文件cd /usr/local/soft/miniowget -q http://dl.minio.org.cn/server/minio/release/linux-amd64/minio3.新建数据存储目录mkdir -p /home/minio/data4.授予可执行权限chmod x minio5.设置账号密码export MINIO_AC…

yolov8代码梳理 训练自己的数据 最终版

1.总结一下 最开始为了检测不规则的麻包袋&#xff0c;所以采用了目标检测。yolov3&#xff0c;fasterrcnn&#xff0c;ssd。这种矩形框还是可以用。后面检测的物体变成了规则的纸箱&#xff0c;我们还用目标检测发现&#xff0c;没有旋转角度&#xff0c;因为箱子的摆放不是正…

深度学习算法面试常问问题(三)

pooling层是如何进行反向传播的&#xff1f; average pooling&#xff1a; 在前向传播中&#xff0c;就是把一个patch的值取平均传递给下一层的一个像素。因此&#xff0c;在反向传播中&#xff0c;就是把某个像素的值平均分成n份 分配给上一层。 max pooling&#xff1a; 在前…

一文教你如何编写高效的接口测试,别再浪费时间了

目录 前言 1、什么是接口测试 2、为什么要做接口测试 3、接口测试的范围 4、接口测试的重点 5、测试原则 总结 前言 在所有的开发测试中&#xff0c;接口测试是必不可少的一项。有效且覆盖完整的接口测试&#xff0c;不仅能保障新功能的开发质量&#xff0c;还能让开发在…

PMP项目管理未来的发展与趋势

什么是项目管理&#xff1f;关于项目管理的解释主要是基于国际项目管理三大体系不同的解释及本领域权威专家的解释。 项目管理就是以项目为对象的系统管理方法&#xff0c;通过一个临时性的、专门的柔性组织&#xff0c;对项目进行高效率的计划、组织、指导和控制&#xff0c;以…

深度学习术语解释:backbone、head、neck,etc

backbone&#xff1a;翻译为主干网络的意思&#xff0c;既然说是主干网络&#xff0c;就代表其是网络的一部分&#xff0c;那么是哪部分呢&#xff1f;这个主干网络大多时候指的是提取特征的网络&#xff0c;其作用就是提取图片中的信息&#xff0c;共后面的网络使用。这些网络…

深入浅出带你学习利用session.upload_progress进行文件包含

前言 该思路是很久之前在CTF比赛中学习到的&#xff0c;可以简单理解为利用session.upload_progress来进行文件竞争从而达到上传文件进行文件包含或者命令执行的目的&#xff0c;可能大部分人会不理解&#xff0c;我们下面我们展开来讲。 基础知识 session.upload_progress …

Java并发编程面试题——线程安全(原子性、可见性、有序性)

文章目录一、原子性高频问题1.1 Java中如何实现线程安全?1.2 CAS底层实现1.3 CAS的常见问题1.4 四种引用类型 ThreadLocal的问题&#xff1f;二、可见性高频问题2.1 Java的内存模型2.2 保证可见性的方式2.3 volatile修饰引用数据类型2.4 有了MESI协议&#xff0c;为啥还有vol…

2022年全国职业院校技能大赛网络安全竞赛A模块(2)

2022年全国职业院校技能大赛&#xff08;中职组&#xff09; 网络安全竞赛试题 &#xff08;2&#xff09; 目录 2022年全国职业院校技能大赛&#xff08;中职组&#xff09; 网络安全竞赛试题 &#xff08;2&#xff09; 模块A 基础设施设置与安全加固 A-1任务一 登录安…

ChatGPT引爆资本狂潮,AI大战升级版打响!谷歌紧急上线对标竞品,微软测试AI搜索引擎,百度宣国产版定档,谁才是最后的赢家?

文 BFT机器人 如果你迄今为止还没有听说过ChatGPT&#xff0c;那就已经彻彻底底被人工智能的新时代甩到身后了。 如果说去年年底ChatGPT刚推出的时候&#xff0c;大多数网友对其的态度还是认为它和Clubhouse一样仅会是昙花一现的话&#xff0c;那么2个月时间过去&#xff0c;C…

【Ubuntu换源教程】不同Ubuntu系统版本换清华源

今天在新电脑上装了虚拟机VMware Workstation Pro 16&#xff0c;在虚拟机上安装了Ubuntu20.04系统。 在做Ubuntu20.04系统换源的时候&#xff0c;发现源要和Ubuntu的版本匹配&#xff0c;之前一直不知道&#xff0c;一直都是盲目换源&#xff0c;版本如果不匹配的话&#xff…

【日常】矩阵正态分布参数检验问题

最近给凯爹做的一个苦力活&#xff0c;统计检验这个东西说实话也挺有趣&#xff0c;跟算法设计一样&#xff0c;好的检验真的是挺难设计的&#xff0c;就有近似算法的那种感觉&#xff0c;检验很难保证size和power都很理想&#xff0c;所以就要做tradeoff&#xff0c;感觉这个假…

DPR-34 AC22V【双位置继电器】

系列型号&#xff1a; DPR-20双位置继电器&#xff1b;DPR-31双位置继电器&#xff1b; DPR-32双位置继电器&#xff1b;DPR-33双位置继电器&#xff1b; DPR-34双位置继电器&#xff1b;DPR-35双位置继电器&#xff1b; DPR-11双位置继电器&#xff1b;DPR-12双位置继电器&…