HbnnMall电子商城系统介绍(功能与技术栈)

        今天在看我个人网站上的文章时,看到了曾经在2020年自己开发的电商系统。那时我已经入职小米有一段时间了,基本已经对各个业务线,各种业务知识有了系统性的了解和学习,所以想自己动手写一个电商系统,以便进一步提高自己的技术。于是趁着疫情那段特殊时期,在业余时间用了几个月的时间把系统写出来了。麻雀虽小,五脏俱全,经过自己几个月的打磨,该有的功能都有了。不过和市面上开源的比,我写的真是相形见绌,都没法供外人展示,当时也纯粹只是为了自己学习。

        当看到自己写的几万行代码时,唯一的感觉就是:这是一场酣畅淋漓的自嗨,虽无大成效但却很痛快。另外一个有意思的是我发现写golang代码会让人难以自拔。毛主席的一首四言诗写道:”与天奋斗,其乐无穷;与地奋斗,其乐无穷;与人奋斗,其乐无穷。“,我改一下:写golang,其乐无穷;写前端,其乐无穷;写代码,其乐无穷。

一、网站介绍

整个系统的架构是这样:

        上面也说了,我的初衷是学习,所以并不像很多现成的电商系统,所有东西都揉到一起写的,而是拆分出多个微服务,采用Dubbo+nacos实现服务注册和发现。

1.首页

首页实现了商品分类导航,轮播图、优惠活动、商品推荐、排行榜、每日新品等。

这块儿就是各种后端服务,聚合形成的数据。

代码示例如下:

 public List<Future<HomeFutureResult>> execute(HomePageRequest homePageRequest){
        List<HomeGeneralTask> homeGeneralTaskList = new ArrayList<>();

        //新品展示
        homeGeneralTaskList.add(new DailyNewProductTask(goodsStatService));

        //商品推荐
        RecommendRequest recommendRequest = new RecommendRequest();
        recommendRequest.setBaseReuest(homePageRequest.getBaseReuest());
        homeGeneralTaskList.add(new RecommendTask(recommendRequest,recommendService));

        //排行榜
        homeGeneralTaskList.add(new TopRankTask(goodsStatService));

        //秒杀商品列表
        homeGeneralTaskList.add(new FlashSaleActivityTask());

        //商品展播图
        homeGeneralTaskList.add(new BannerTask(goodsStatService));

        List<Future<HomeFutureResult>> homeFutureResultList = new ArrayList<>();
        for (HomeGeneralTask homeGeneralTask:homeGeneralTaskList){
            homeFutureResultList.add(homePageExecutor.submit(homeGeneralTask));
        }
        return homeFutureResultList;
    }

2、商品详情页

        商品详情页涉及到很多,功能包括:

  • 商品左侧图片轮播展示;
  • 商品属性;
  • 商品促销活动;
  • 秒杀页;
  • 标签切换;
  • 立即购买;
  • 加入购物车;
  • 商品详情介绍;
  • 商品评论;
  • 商品参数;
  • 相似商品推荐。

        这个地方我花的时间最多,作为一个后端人员,搞前端的标签切换时,挺痛苦。

        和首页类似,这个地方也是由多个后端服务组成,就是所谓的产品站,这地方是可以做数据异构的。

        代码示例如下:

 public List<Future<GoodsDetailFutureResult>> execute(GoodsDetailRequest goodsDetailRequest, GoodsDetail goodsDetail){
        List<Future<GoodsDetailFutureResult>> goodsDetailFutureResultList = new ArrayList<>();
        List<GoodsDetailGeneralTask> goodsDetailGeneralTaskList = new ArrayList<>();

        //价格库存服务
        goodsDetailGeneralTaskList.add(new GoodsPriceInventoryTask(goodsDetail,goodsPropmotionService,propInventoryService));
        //促销活动服务
        if(Optional.ofNullable(goodsDetailRequest.getIsNeedActDetailInfo()).orElse(false)){
           goodsDetailGeneralTaskList.add(new GoodsPromotionTask(goodsDetail,goodsPropmotionService));
        }
        //商品详情介绍服务
        if(Optional.ofNullable(goodsDetailRequest.getIsNeedPropDetailIntroduction()).orElse(false)){
            goodsDetailGeneralTaskList.add(new GoodsIntroductionTask(goodsDetail,goodsDetailRequest,shopGoodImgMapper,djangoUrl));
        }
        //商户信息服务
        if(goodsDetailRequest.getIsNeedMerchantInfo() != null && goodsDetailRequest.getIsNeedMerchantInfo()){
            //TODO 增加商户信息
        }
        //增加shopTag
        if(Optional.ofNullable(goodsDetailRequest.getIsNeedShopTag()).orElse(false)){
            goodsDetailGeneralTaskList.add(new GoodsTagTask(goodsDetail,goodTagService));
        }

        for (GoodsDetailGeneralTask goodsDetailGeneralTask:goodsDetailGeneralTaskList){
            goodsDetailFutureResultList.add(goodsDetailExecutor.submit(goodsDetailGeneralTask));
        }
        return goodsDetailFutureResultList;
    }

3、商品搜索

搜索这块儿我使用的是ES进行查询,写了一个定时任务,会定期全量刷新一遍,当然应该还要有一个增量更新的,只不过我没写,同步的示例代码:

简易的搜索代码:

MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name",searchRequest.getName());
        //提高搜索精度
        matchQueryBuilder = matchQueryBuilder.prefixLength(3);
        //默认是or
        matchQueryBuilder.operator(Operator.AND);
        matchQueryBuilder.minimumShouldMatch("75%");
        searchSourceBuilder.query(
                QueryBuilders.boolQuery()
                        .must(matchQueryBuilder)
                        .filter(QueryBuilders.termQuery("status",1))
        );
        searchSourceBuilder.from(searchRequest.getPageIndex() == null ? 0 : searchRequest.getPageIndex());
        searchSourceBuilder.size(searchRequest.getPageSize() == null ? 15 : searchRequest.getPageSize());
//        searchSourceBuilder.sort(new ScoreSortBuilder().order(SortOrder.DESC));
        esSearchRequest.source(searchSourceBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(esSearchRequest,RequestOptions.DEFAULT);

4、购物车列表

购物车实现购物车添加、修改、删除、全选、全部选等等。

购物车的实现都是通过Redia+lua脚本实现的。

5、结算页面

结算页是真正订单结算的页面,让用户知道要付多少钱,这里面涉及到商品,优惠、全局id号(分库分表场景需要全局唯一的订单号)、反作弊、发票、地址等多个服务。还要根据发货主体或者物权主体进行拆单。

6、支付页

订单数据已经生成,并成功写入数据表。接下来商户进行支付操作。超时的会自动取消。

由于支付都是需要企业认证,这里还没实际做支付功能,不过这个不难。

7、个人中心

个人中心包括各状态订单、我的收藏、优惠券、地址管理等等。

8、在线客服

在线客服也花了几天时间写的,使用了LayUi模板 +Python+channels实现了Websocket。

9、单点登录

实现的功能包括:

  • 支持业务系统接入实现第三方登录;
  • 登录方式包括手机验证码登录以及用户名密码登录;
  • token的申请和生成;
  • 通过token解析用户信息,并访问受限资源;
  • token的刷新。

具体可以看我之前写的文章:用户服务之实现单点登录icon-default.png?t=N7T8https://hbnnforever.cn/article/useservicessologin.html

10、秒杀服务

之前小米有个大秒系统,我觉得挺有意思,后来我就想我也整一个,就用Golang写了一个,当然,我写得没那么复杂,就是想体验一把Golang的丝滑。具体代码不展示了,先贴一个工程目录:

二、技术栈

1、Web端

采用的是Python +Django+Vue开发,部署采用Nginx+supervisor+gunicorn的方式;

2、API 网关

采用的是Springboot+Netty开发,目前已实现的功能:

  • 统一前端接口调用,支持HTTP,Dubbo协议;
  • HTTP协议至Dubbo协议的转换;
  • 统一鉴权;
  • 限流,主要借鉴sentinel的思想。

当然,可以看出来,目前实现的网关还比较弱鸡,至少还要加入熔断降级,服务编排,缓存,日志等等。而且,这市面上的API网关太多了,我纯粹是为了学习,实际中我们尽量避免造轮子。

3、后端业务层

用到的技术栈:

  • JAVA;
  • Python;
  • Golang:
  • Springboot;
  • Django;
  • Dubbo;
  • Nacos;
  • ZK;
  • Sentinel;
  • Redis;

JAVA+springboot+Dubbo+Nacos:

  • 用户账户服务;
  • 商品服务;
  • 优惠服务;
  • 库存服务;
  • 订单服务; 
  • 评论服务;
  • 清结算服务;
  • 发票服务;

用Django+channels实现的:客服服务    Websocket;

Golang:秒杀服务,用golang+Redis单独写了秒杀服务,参考小米的大秒系统;

MysqlProxy:实现读写分离+ 分库分表

Nacos+sentinel:nacos实现注册中心,服务发现,限流熔断配置发现、sentinel熔断限流。

ZK:订单号,分布式唯一ID生成

ES:商品存储,用于搜索查询。

Shardingshpere:订单分库分表,这个也纯粹是练习。

三、总结

        我开发的电商系统并不是完整的,像支付、物流、退款等都没有写,不过当时在开发的过程中,的确又学到了很多。网上也有很多开源的系统,尤其是听说那些报培训班的都有电商系统开发。虽然本人对培训班嗤之以鼻,不屑于多看他们一眼,但所谓存在的就是合理的,他们弄电商系统也侧面说明这玩意是有实战意义的,实战一段时间后还是有提高的。

        代码就不展示了,如果有对这方面感兴趣的同学可以网上找找更好的开源示例,不过我的代码可以免费私下给。

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

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

相关文章

LeetCode刷题实战1:两数之和

从今天开始加入刷题大军&#xff0c;把算法题刷爆&#xff0c;我们直接进入主题。 题目内容 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应…

经济学 生产成本 垄断

经济利润&#xff1a;收益-显性成本-隐性成本 会计利润&#xff1a;收益-显性成本 隐性成本&#xff1a;间接的机会成本 成本分为两种&#xff1a;可变成本和固定成本 可变成本&#xff1a;随着生产产品数量发生改变 固定成本 平均成本&#xff1a;每一单单位产品的成本 通…

二维码的生成、下载Java,并返回给前端展示

分析 将生成的二维码图片&#xff0c;以IO流的方式&#xff0c;通过response响应体直接返回给请求方。 第一、不需要落到我们的磁盘&#xff0c;操作在内存中完成&#xff0c;效率比较高。 第二、所有生成二维码的请求&#xff0c;都可以访问这里&#xff0c;前端直接拿img标…

vue想要突破全局样式限制又不影响别的页面样式怎么办

<!-- 用scope盖不住全局&#xff0c;随意来个class匹配私定&#xff0c;搜索关键词&#xff1a;不要随便改&#xff0c;乱打class名 --> <style> .lkajsdfjkalsfhkljashkflhaskl .el-input.el-input--default.el-input--suffix { width: 160px !important; } …

MySQL索引原理

MySQL索引原理 1、Innodb中的B树是怎么产生的呢? 背景1.1、mysql索引使用B树&#xff0c;为什么&#xff1f;1.2、主键索引图示1.3、mysql最好使用自增ID&#xff1a;为什么呢&#xff1f;1.4、高度为3的B树能存多少条数据&#xff1f;a、假设2层b、假设3层 2、索引采用什么数…

从0到1构建uniapp应用-store状态管理

背景 在 UniApp的开发中&#xff0c;状态管理的目标是确保应用数据的一致性&#xff0c;提升用户体验&#xff0c;并简化开发者的工作流程。通过合理的状态管理&#xff0c;可以有效地处理用户交互、数据同步和界面更新等问题。 此文主要用store来管理用户的登陆信息。 重要…

python--面向对象编程和类的定义,对象的创建

一、面向对象简介 1、什么是面向对象 面向对象是一种编程思想&#xff0c;把数据和对数据的多个操作方法封装在一起组成类&#xff0c;这样通过这个类创建出来的对象,就可以直接调用这些方法了。 2、面向对象相关的术语 类&#xff1a;用来描述具有相同的属性和方法的对象的…

基于深度学习的花卉检测与识别系统(网页版+YOLOv8/v7/v6/v5代码+训练数据集)

摘要&#xff1a;在本篇博客中&#xff0c;我们深入探讨了基于YOLOv8/v7/v6/v5的花卉检测与识别系统。核心上&#xff0c;我们采用了最新的YOLOv8技术&#xff0c;并整合了YOLOv7、YOLOv6、YOLOv5等先进算法&#xff0c;进行了细致的性能指标对比分析。我们详细介绍了当前国内外…

刚刚,Sora官方发布首支MV

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站ai人工智能工具 更多资源欢迎关注 AIGC&#xff0c;算是狠狠地震荡了一把音乐圈。 就在刚刚&#xff0c;OpenAI官方账号发布的一支由Sor…

哲♂学家带你用顺序表实现通讯录

实现通讯录能使我们进一步加深对顺序表的理解&#xff0c;接下来就由本哲♂学家带你手把手实现通信录。 其中需要用到顺序表的知识可以点击下面链接了解&#xff1a;http://t.csdnimg.cn/9SjGd话不多说&#xff0c;我们♂开始吧。 一、通讯录头文件声明 由于我们前面已经写过…

蓝桥杯 --- 日期问题模板

目录 1.如何判断闰年 2.如何遍历当前年份的每一天 3.如果想要输出某一年某一天到某一年某一天之间一共有多少天。 4.精确到具体周几到周几的问题分析 5.如何直接通过一层for循环枚举年月日 习题&#xff1a; 蓝桥杯竞赛特别喜欢考日期问题&#xff0c;今天给大家分享一下…

JS——判断节假日(假日包括周末,不包括调休上班的周末)

思路&#xff1a;创建两个数组&#xff0c;数组1为节假日数组&#xff0c;数组2为是周末上班日期数组。如果当前日期&#xff08;或某日期&#xff09;同时满足2个条件&#xff08;1.在节假日数组内或在周末。2.不在周末上班日期数组&#xff09;即为节假日&#xff0c;否则即为…

即将截稿 CCF-A多媒体顶会ACM MM‘24 北京时间4月9日提交摘要

会议之眼 快讯 第32届ACM MM (ACM MULTIMEDIA)即国际多媒体会议将于 2024 年 10月28 -日11月1日在澳大利亚墨尔本隆重举行&#xff01;MM是由ACM&#xff08;Association for Computing Machinery&#xff0c;计算机协会&#xff09;主办的国际性学术会议&#xff0c;是计算机…

【Java EE】Maven jar 包下载失败问题的解决方法

文章目录 1. 配置好国内的Maven源1.1配置当前项⽬setting1.2设置新项⽬的setting 2.重新下载jar包3.其他问题⭕总结 1. 配置好国内的Maven源 因为中央仓库在国外, 所以下载起来会⽐较慢, 所以咱们选择借助国内⼀些公开的远程仓库来下载资源 接下来介绍, 如何设置国内源 1.1配…

分享一款实用的太阳能充电电路(室内光照可用)

随着物联网的发展&#xff0c;很多智能电子设备都朝着低功耗方向发展&#xff0c;光能&#xff0c;风能&#xff0c;机械能等不同的自然能源都能被利用起来作为电子设备的能量来源&#xff0c;本文要分享一款太阳能充电电路。 前言 大家好&#xff0c;我又来分享电路了&#…

redis的常用基本命令与持久化

文章目录 redis的基本命令1.授权密码2.增加、覆盖、查询、删除、切换库名、移动、清空数据库 Redis持久化RDB模式主动备份自动备份RDB备份过程 AOF备份模式开启AOF备份模式执行流程 总结 redis的基本命令 1.授权密码 config set requirepass 密码设置完密码需要认证密码以后才…

OpenAI劲敌出手!Claude 3正式发布,全面超越GPT-4。Claude3模型特点和使用教程分享

已有GPT官方账号不会升级GPT4请参考&#xff1a;【国内如何用gpt4&#xff1f;如何升级gpt4&#xff1f;保姆级教程】 一、Claude震撼发布焦点分析 1.Claude震撼发布 北京时间2024年3月4日晚间&#xff0c;Anthropic&#xff0c;毫无预警地发布了最新一代大模型Claude 3&…

echarts 地图 自己圈地图 乡镇街道

这个是方式是我实在不愿意做的&#xff01; 如果有现成的最好&#xff0c;没有办法的情况下再用这个东西。 今天公司有一个项目&#xff0c;地方划分了一块区域&#xff0c;但是国家没有审核&#xff0c;但是项目里面用到了一个地图展示数据&#xff01;然后就需要我们自己把…

【深度学习】深度学习md笔记总结第3篇:TensorFlow介绍,学习目标【附代码文档】

深度学习笔记完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;深度学习课程&#xff0c;深度学习介绍要求,目标,学习目标,1.1.1 区别,学习目标,学习目标。TensorFlow介绍&#xff0c;2.4 张量学习目标,2.4.1 张量(Tensor),2.4.2 创建张量的指令,2.4.3 张量…

Java 包装类初识泛型

登神长阶 第六阶 包装类&初识泛型 目录 &#x1f600;一.包装类 &#x1f604;1.基本数据类型以及其对应的包装类 &#x1f602;2.装箱和拆箱 &#x1f607;2.1.装箱&#xff08;Boxing&#xff09; &#x1f609;2.2.拆箱&#xff08;Unboxing&#xff09; &#x…