[附源码]最新springboot线上电商|前后端分离|界面简洁

news2024/10/6 20:31:36

一. 前言

今天小编给大家带来了一款可学习,可商用的,线上电商的网站源码,支持二开,无加密。代码的后端是SpringBoot技术栈(非jsp),前端是Angular。如果您需要定制需求请找小编。

文章第六小节会贴上优秀代码案例。可以确认是不是主流编码风格。

如果您正好有此需求源码,请联系小编,回复慢不及时的话请谅解!!!

二. 视频演示

网站的截图在文章末尾给出,这里先给出我演示的网站视频:

springboot线上电商

三. 技术栈以及问题

后端技术栈:

  • JDK11
  • SpringBoot2.3.3+Hibernate
  • OAuth2
  • MySQL8
  • Maven
  • Spring Cache本地缓存
  • RestFull API
  • Swagger

前端技术栈:

  • Angular 10
  • Rxjs
  • Ngrx Store
  • Bootstrap
  • NgBootstrap
  • FontAwesome

当前问题

  1. 没有实现管理后台。(找我可以帮您实现)
  2. 支付是模拟的,并没有对接支付。(根据您的需求对接)
  3. 只支持PC端,不支持移动设备。

如果您需要定制修改源码,请联系小编。

四. 后端搭建

1. 数据库创建

创建一个数据库为 lzshop 的数据库。

脚本位置在 sql/lzshop.sql, 我们直接导入脚本:

2. 代码搭建

后端代码分为两块服务:

  • authorization_server(权限服务)
  • resource_server (主要业务逻辑实现服务)

authorization_server搭建

用idea导入authorization_server服务,找到yml配置,修改成你的数据库地址和账号密码:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      connection-timeout: 60000
      maximum-pool-size: 2
      minimum-idle: 1
      pool-name: data-source
    ## 修改成你的数据库信息
    url: jdbc:mysql://localhost:3306/lzshop?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&serverTimezone=UTC
    username: root
    password: 123456

然后找到 OauthApplication 启动类启动

resource_server搭建

用 idea导入resource_server 服务,找到yml配置,修改成你的数据库地址和账号密码:

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    hikari:
      connection-timeout: 60000
      maximum-pool-size: 2
      minimum-idle: 1
      pool-name: data-source
    ## 修改成你的数据库信息
    url: jdbc:mysql://localhost:3306/lzshop?useSSL=false&useUnicode=yes&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&serverTimezone=UTC
    username: root
    password: 123456

然后找到 BackendApplication启动类启动

五. 前端搭建

前端代码在client下面

前端是angular项目,部署教程专门搞了一篇教程部署:

老罗教知识:Angular项目创建、启动到打包部署0 赞同 · 0 评论文章

运行结果:

六. 后端技术集锦

后端采用了当前主流的技术和经典代码,毕竟优秀的代码维护起来都是相当解耦和容易的,bug也是微乎其微。这里我找几个重点代码讲解。

代码1:自定义检验注解

// ***********************某个request的请求参数******************    
    @NotBlank
    @Size(min = 3, max = 52)
    @CustomEmail   //自定义的邮件校验注解
    private String email;

// ***********************邮件校验注解******************
@Target({TYPE, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = CustomEmailValidator.class)
@Documented
public @interface CustomEmail {
    String message() default "Invalid email";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
// ***********************具体邮件校验实现******************
public class CustomEmailValidator implements ConstraintValidator<CustomEmail, String> {
    private static final String EMAIL_PATTERN = "^[a-zA-Z0-9_!#$%&’*+/=?`{|}~^.-]+@[a-zA-Z0-9.-]+$";
    private Pattern pattern;
    private Matcher matcher;
    @Override
    public boolean isValid(String email, ConstraintValidatorContext context) {
        return (validateEmail(email));
    }
    private boolean validateEmail(String email) {
        pattern = Pattern.compile(EMAIL_PATTERN);
        matcher = pattern.matcher(email);
        return matcher.matches();
    }
}

代码2:转换层(数据库实体转前端返回实体)

// ***********************一个查询用户业务实现****************** 
public UserResponse fetchUser() {
        String userName = SecurityContextHolder.getContext().getAuthentication().getName();
        if (Objects.isNull(userName)) {
            throw new AccessDeniedException("Invalid access");
        }
        Optional<User> user = userRepository.findByEmail(userName);
        if (user.isEmpty()) {
            throw new ResourceNotFoundException("User not found");
        }
       // ***********************利用用户转换器进行转换****************** 
        return userResponseConverter.apply(user.get());
    }
 // ***********************用户转换器****************** 
@Component
public class UserResponseConverter implements Function<User, UserResponse> {
    @Override
    public UserResponse apply(User user) {
       // 设置该返回的值
        UserResponse userResponse = new UserResponse();
        userResponse.setEmail(user.getEmail());
        userResponse.setFirstName(user.getFirstName());
        userResponse.setLastName(user.getLastName());
        userResponse.setAddress(user.getAddress());
        userResponse.setCity(user.getCity());
        userResponse.setState(user.getState());
        userResponse.setZip(user.getZip());
        userResponse.setPhone(user.getPhone());
        userResponse.setCountry(user.getCountry());
        userResponse.setEmailVerified(user.getEmailVerified());
        return userResponse;
    }
}

代码3:Spring事件ApplicationListener

 // ***********************忘记密码,发送邮件****************** 
@Component
public class PasswordForgotListener implements ApplicationListener<OnPasswordForgotRequestEvent> {

    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private MailConstants mailConstants;
    @Override
    public void onApplicationEvent(OnPasswordForgotRequestEvent event) {
        this.confirmRegistration(event);
    }
    private void confirmRegistration(OnPasswordForgotRequestEvent event) {
        String recipientAddress = event.getUser().getEmail();
        String subject = "\uD83D\uDD11 密码重置确认";
        String confirmationUrl = mailConstants.getHostAddress() + "/passwordResetConfirm?token=" + event.getToken();
        String message = "Hi ,\n\n请点击下面链接重置密码。";
        SimpleMailMessage email = new SimpleMailMessage();
        email.setTo(recipientAddress);
        email.setSubject(subject);
        email.setText(message + "\n\n" + confirmationUrl + "\n\n\nw/ Keyist Team");
        mailSender.send(email);
    }
}

代码4:Spring本地缓存 @Cacheable注解

    // ***********************查询关联商品的逻辑****************** 
    @Cacheable(key = "{#productCategory.name,#id}", unless = "#result.size()==0")
    public List<Product> getRelatedProducts(ProductCategory productCategory, Long id) {
        List<Product> productList = productRepository.findTop8ByProductCategoryAndIdIsNot(productCategory, id);
        if (productList.size() < 8) {
            productList.addAll(productRepository.findAllByProductCategoryIsNot(productCategory, PageRequest.of(0, 8 - productList.size())));
        }
        return productList;
    }

代码5:严格的restful api 风格

代码6:数据库层,没有任何sql和xml

@Repository 
public interface ProductRepository extends PagingAndSortingRepository<Product, Long> {
    Optional<Product> findByUrl(String url);

    List<Product> findAllByProductCategory(Pageable pageable, ProductCategory productCategory);

    List<Product> findTop8ByOrderByDateCreatedDesc();

    List<Product> findAllByNameContainingIgnoreCase(String name, Pageable pageable);

    List<Product> findTop8ByProductCategoryAndIdIsNot(ProductCategory productCategory, Long id);

    List<Product> findAllByProductCategoryIsNot(ProductCategory productCategory, Pageable pageable);
}

swagger文档

还有很多很多,我就不贴了,优秀的代码维护起来都是相当容易的,bug也是微乎其微。

七. 演示截图

首页

产品页

搜索页

商品详情

登录

购物车

购物车结算

确认支付

支付完成

订单列表

收货地址

用户信息

结尾语

我是分享好物+教程+源码的老罗,欢迎关注,后续会有更精彩的源码分享!

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

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

相关文章

Vue 数据大屏适配

1、准备俩个盒子 .dataScreen-content 盒子内容根据设计稿给的px单位进行正常的布局就行 2、盒子的CSS样式 .dataScreen-container {width: 100%;height: 100%;// 有背景图需要的样式background: url("./images/bg.png") no-repeat;background-repeat: no-repeat;b…

让采购和工程师们既爱又恨的任务——BOM

在项目研发与生产过程中&#xff0c;有一个常常让采购经理和工程师们既爱又恨的任务&#xff0c;那就是整理BBOMB。BOM作为连接设计与制造的桥梁&#xff0c;其重要性不言而喻&#xff0c;它详细列出了产品构成所需的所有零部件、材料及其规格、数量&#xff0c;是成本估算、采…

学习记录之数学表达式(6)

目录 十二、图与网络12.1 有向图12.2 元组与对象12.3 二元关系与有向图12.4 无向图12.5 有向网络12.6 作业 十三、树13.1 例子13.2 定义13.3 Java代码13.4 作业 十四、 m \mathbf{m} m叉树14.1 预备知识&#xff1a;字符串14.2 m \mathbf{m} m-叉树的定义14.3 Java代码14.4 作…

代码随想录算法训练营第20天 | 题目: 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点

代码随想录算法训练营第20天 | 题目&#xff1a; 235. 二叉搜索树的最近公共祖先 701.二叉搜索树中的插入操作 450.删除二叉搜索树中的节点 文章来源&#xff1a;代码随想录 题目名称&#xff1a; 235. 二叉搜索树的最近公共祖先 给定一个二叉搜索树, 找到该树中两个指定节点的…

【.Net】Web项目部署腾讯云

文章目录 总述前置准备docker-compose部署普通部署 参考 总述 前置准备 云服务添加端口 另有linux本身防火墙请参考&#xff1a; 【Linux】防火墙命令 需安装.Net SDK和Asp .Net Runtime 注意&#xff1a; 1、sdk也要不只是runtime 2、是Asp .Net Runtime不是.Net Runtime …

Linux socketcan应用编程

一、基本步骤 1、打开并绑定到 CAN 套接字 在执行任何操作之前&#xff0c;第一步是创建一个套接字。此函数接受三个参数 – 域/协议系列 &#xff08;PF_CAN&#xff09;、套接字类型&#xff08;原始或数据报&#xff09;和套接字协议。如果成功&#xff0c;该函数将返回文件…

游戏AI的创造思路-技术基础-tanh函数详解

又来搞事情&#xff0c;总想着把sigmoid函数替换成其他函数作为激活函数&#xff0c;或者找到更合适某一段训练的函数&#xff0c;所以今天来聊聊tanh函数&#xff08;谁让咱当年差点去了数学系&#xff0c;结果还是在数学系转过去计算机的&#xff09; 目录 3.9. tanh函数详解…

Springboot整合Redis以及业务工具类示例

docker安装Redis参考我另一篇博客Docker安装Redis及持久化 一、Get-Started 依赖 <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis --> <dependency><groupId>org.springframework.boot</groupId>…

轻松创建对象——简单工厂模式(Python实现)

1. 引言 大家好&#xff0c;又见面了&#xff01;今天我们要聊的是设计模式中的“万能钥匙”——简单工厂模式。想象一下&#xff0c;如果每次你都得亲自动手创建各种对象&#xff0c;不仅累得像个陀螺&#xff0c;还可能搞得一团糟。别怕&#xff0c;简单工厂模式来拯救你&am…

nextTick实现原理及使用场景

1.定义&#xff1a; nextTick是一个在Vue.js中常见的异步更新DOM的机制&#xff0c;它利用JavaScript的事件循环机制以及浏览器的渲染流程来实现延迟执行DOM更新操作。nextTick方法能够将回调函数延迟到下一个DOM更新循环之后执行&#xff0c;确保在DOM更新完成后执行某些操作…

【Linux系统】CUDA的安装

今天在安装环境时遇到报错&#xff1a; The detected CUDA version (10.1) mismatches the version that was used to compile PyTorch (11.8). Please make sure to use the same CUDA versions. 报错原因&#xff1a;安装的cuda版本不对应&#xff0c;我需要安装cuda的版本…

宠物空气净化器哪个品牌性价比高?宠物空气净器Top3品牌推荐

养猫确实给家庭带来了无尽的欢乐&#xff0c;但猫毛无处不在的问题确实让不少猫主人感到头疼。不论是长毛猫还是短毛猫&#xff0c;它们掉落的浮毛飘浮在空气中&#xff0c;不仅影响家居环境的整洁度&#xff0c;还可能成为过敏的源头。因此&#xff0c;如何高效地处理这些猫浮…

多模态融合 + 慢病精准预测

多模态融合 慢病精准预测 慢病预测算法拆解子解法1&#xff1a;多模态数据集成子解法2&#xff1a;实时数据处理与更新子解法3&#xff1a;采用大型语言多模态模型&#xff08;LLMMs&#xff09;进行深度学习分析 慢病预测更多模态 论文&#xff1a;https://arxiv.org/pdf/2406…

创新校园服务模式 跑腿小程序平台源码构建与实践 前后端分离 带完整的安装代码包以及部署教程

系统概述 本项目是一个集任务发布、接单、支付、评价于一体的跑腿服务小程序平台&#xff0c;专为高校校园设计。系统采用前后端分离架构&#xff0c;前端负责用户界面展示和交互逻辑&#xff0c;后端处理业务逻辑、数据存取等&#xff0c;两者通过API接口进行通信&#xff0c…

『手撕Vue-CLI』 添加自定义指令

添加 create 指令 在 vue-cli 中&#xff0c;create 指令是用来创建一个新的项目的&#xff0c;我实现的 nue --help 的帮助信息中只有 --version&#xff0c;--help 这两个指令&#xff0c;所以当用户使用我的 nue-cli 时&#xff0c;并不知道有 create 这个指令&#xff0c;所…

Conan安装与C++第三方环境配置保姆级图文教程(附速查字典)

目录 1 什么是Conan&#xff1f;2 Conan安装与配置3 Conan的常见操作3.1 搜索指定包3.2 安装指定包3.3 本地包管理3.4 查看项目依赖 4 Conan构建项目案例 1 什么是Conan&#xff1f; Conan是一个开源的C/C包管理器&#xff0c;用于管理和构建C/C项目所需的依赖库。传统上&…

BIOS设置与系统分区

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 目录 一BIOS 1破解密码的前提 2B…

CrossViT:用于图像分类的交叉注意多尺度Vision Transformer

提出了一种双支路Transformer来组合不同大小的图像补丁(即变压器中的令牌)以产生更强的图像特征。方法处理具有不同计算复杂度的两个独立分支的小补丁和大补丁令牌,然后这些令牌纯粹通过注意多次融合以相互补充。此外,为了减少计算量,开发了一个简单而有效的基于交叉关注的令…

98 - IDEA远程调试服务器Java程序

Java 提供了一套标准的调试协议&#xff08;JDWP - Java Debug Wire Protocol&#xff09;&#xff0c;允许调试器&#xff08;IDE&#xff09;与被调试程序&#xff08;应用&#xff09;之间进行通信。 1.服务器特定命令启动程序 在服务器上以以下命令启动Java程序 java -a…

linux 离线安装docker

测试服务器&#xff1a;银河麒麟V10 x86_64 注意&#xff1a;推荐使用国内的镜像站下载&#xff0c;因为官网不挂梯子无法访问&#xff0c;我用的是清华大学开源软件镜像站 一、下载离线包&#xff1a; 官网下载docker离线包 下载地址&#xff1a;https://download.docker.c…