惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

有赞技术团队
有赞技术团队
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
P
Palo Alto Networks Blog
C
Cisco Blogs
The Hacker News
The Hacker News
T
Threatpost
S
Schneier on Security
K
Kaspersky official blog
Spread Privacy
Spread Privacy
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
NISL@THU
NISL@THU
量子位
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Google DeepMind News
Google DeepMind News
Security Latest
Security Latest
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
博客园 - 叶小钗
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
News and Events Feed by Topic
爱范儿
爱范儿
P
Proofpoint News Feed
C
CERT Recently Published Vulnerability Notes
Project Zero
Project Zero
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Cisco Talos Blog
Cisco Talos Blog
GbyAI
GbyAI
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Apple Machine Learning Research
Apple Machine Learning Research
T
Tenable Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
V
Vulnerabilities – Threatpost
Forbes - Security
Forbes - Security
博客园 - 三生石上(FineUI控件)
C
Cyber Attacks, Cyber Crime and Cyber Security
N
News and Events Feed by Topic
V
V2EX
Webroot Blog
Webroot Blog
The Register - Security
The Register - Security
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
阮一峰的网络日志
阮一峰的网络日志
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
Scott Helme
Scott Helme
Simon Willison's Weblog
Simon Willison's Weblog
L
LangChain Blog
W
WeLiveSecurity
Cloudbric
Cloudbric

微风静语

用 codebase-memory-mcp 给 AI 编程加一层“代码记忆” EchoCraft - 专为独立开发者和小型团队打造的产品官网主题 Halo 站长必备:外链安全与流量分析神器——“链接工具箱”重磅升级! Halo插件开发:java17旧项目迁移至java21项目记录 Halo插件|一个面向创作者的多功能媒体处理工具集 分布式事务详解:从入门到精通 让你的网站初步适配PWA Halo主题 - 微浸:以轻量构建美学,用细节定义体验 深入理解Python爬虫技术:原理、实现与实践 Halo-2.20 新特性:自定义登录页面模版 vue3 中父子组件数据传输踩坑 将你的服务运维面板从宝塔替换为1panel Python实战项目:外星人入侵(源码分享) theme-hao主题适配友链自助提交插件 plugin-artalk 插件保姆级使用教程 plugin-blog-hao 插件部分功能演示 halo 插件开发踩坑记录(一) Thymeleaf 模版引擎语法浅记 信息洪流中的自我救赎 mac 系统里如何管理多个jdk版本 memso API 不完全指南 基础语法:从CPU角度看变量、数组、类型、运算、跳转、函数等语法 halo-theme-hao主题:artalk评论区美化 衡量个人成长 halo-theme-hao 主题魔改教程 分享一个魔改的 Artalk 评论系统邮件模版 halo-theme-hao 主题标签记录 开发一个 Halo2.0 的安全条跳转中台插件! Mac 软件推荐:使用 Mac 一年半来,我一直在用的软件! TypeScript教程---面向对象编程 软件版本命名规范 TypeScript教程---基础语法及编译设置 2024年家乡春季的第一场大雪 提问的智慧 基础篇:容器化部署技术 -—docker,从此摆脱多环境配置的苦恼! 普通本科的四年大学教育,给我带来了什么? 因果与平衡 程序的本质:代码是如何被执行的 软件开发者应该具备的基本提问素质 如何编写 Restful 风格的接口 探索力 Springboot入门基础篇 springboot中如何使用注解来实现aop Springboot项目生成接口文档方法 Java 实体代码生成器 lombok 的使用 深入 Java 泛型 分布式版本控制工具 git 的基本使用 初识Vue3--令人焕然一新的使用逻辑和代码组织方式! 浅谈前端发展史 为什么要学习数据结构和算法 关于富文本编辑器 wangeditor 在 vue2 项目中的使用
如何搭建前后端分离的项目
webjing · 2022-08-30 · via 微风静语

前后端分离已经成为现今的主流开发模式,本篇将通过 demo 报道登记管理系统介绍如何搭建一个前后端分离的 web 应用。

1、报道登记管理系统介绍

后台技术栈:

spring + spring mvc + mybatis + mysql8.0

前台技术:

vue + vuex + element-ui

主要功能介绍

1、用户登录(包括自动登录)、退出、权限拦截

2、学生报道登记管理(列表、新增、编辑、删除、按条件查询、文件上传)

2、页面展示

  • 管理员的主页显示

  • 填报界面

  • 用户管理界面

3、前后端项目结构

目录及构图

  • 后端目录结构图:

  • 前端目录结构图

前后端分离搭建项目时的要点:

  • 前端

    前端还是使用较为经典的 vue2 项目,通过 vue-cli 搭建。

  • 后端

    搭建时,注意还是搭建maven的web项目,这样才能建立后端服务,也尝试搭建过maven的普通Java项目,但是后边发现把它放在tomcat服务器里边无法为前端提供服务。

4、解决前后端分离时的跨域问题

4.1、为什么会产生跨域问题

跨域问题是因为浏览器的同源策略引起的,所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源。同源策略/SOP(Same origin policy)是一种约定,由 Netscape 公司 1995 年引入浏览器,它是浏览器最核心也最基本的安全功能,现在所有支持 JavaScript 的浏览器都会使用这个策略。如果缺少了同源策略,浏览器很容易受到 XSS、 CSFR 等攻击

4.2、如何解决跨域

4.2.1、前端解决

前端项目如果是vue项目,可以在vue的全局配置文件_vue.config.js_ 中进行配置,将需要访问的后端地址进行代理,从安全方面考虑,推荐这样做,具体配置如下:

const define = require("./src/util/define")
// define是自己定义的一些全局配置变量,便于管理
module.exports = {
  // 去除代码规范
  lintOnSave: false,
  devServer: {
    proxy: {
      "/api": {
        target: define.APIURL, // define.APIURL就是你后端服务的地址
        ws: true,
        changeOrigin: true,
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
}

4.2.2、后端解决

后端我使用的 spring 版本是 4.0 以上的,所以配置跨域很简单,只需要在相应的控制器或方法上加上注解 @CrossOrigin(origins = {"http://localhost:8080"})。

你也可以直接使用 @CrossOrgin 来进行配置,但是这样所有的访问地址都可以访问到你的服务,不安全。同时,这个注解也可以放在方法上,表示这个方法单独可以被访问

关于后端解决跨域的方式还有其他途径,比如全局配置拦截器,这里再不做细讲。

5、ssm 重要的配置文件

Pom.xml 依赖配置

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.cxsw</groupId>
  <artifactId>rmsService</artifactId>
  <version>1.0</version>
  <packaging>war</packaging>

  <name>rmsService</name>
  <!--FIXME change it to the project's website-->
  <url>http://localhost:3000</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <!-- 测试相关   -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.13.2</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-test</artifactId>
      <version>5.3.22</version>
    </dependency>
    <!-- spring 相关 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.22</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.3.22</version>
    </dependency>
    <!-- 事务相关 -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>5.3.22</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>5.3.22</version>
    </dependency>
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.9.9.1</version>
    </dependency>
    <!-- 数据层相关 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.10</version>
    </dependency>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.30</version>
    </dependency>
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.20</version>
    </dependency>
    <!-- 实体代码生成工具 -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
    </dependency>
    <!-- 整合mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>2.0.7</version>
    </dependency>
    <!-- jackson -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.13.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.13.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.13.3</version>
    </dependency>
    <!-- 文件上传相关-->
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
    </dependency>
    <dependency>
      <groupId>commons-io</groupId>
      <artifactId>commons-io</artifactId>
      <version>2.11.0</version>
    </dependency>
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-log4j12</artifactId>
      <version>1.7.36</version>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <port>3000</port>
          <path>/</path>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>

ApplicationContext.xml (spring 核心配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
                           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 组建扫描-->
    <context:component-scan base-package="com.cxsw.rms">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 配置数据源 -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${druid.jdbc.driver}"/>
        <property name="url" value="${druid.jdbc.url}"/>
        <property name="username" value="${druid.jdbc.username}"/>
        <property name="password" value="${druid.jdbc.password}"/>
    </bean>

    <!-- 整合mybtis -->
    <bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis.xml"/>
        <property name="mapperLocations" value="classpath:/mappers/*.xml"/>
    </bean>
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactoryBean"/>
    </bean>
    <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.cxsw.rms.repository"/>
    </bean>
    <!-- 配置声明式事务控制 -->
    <bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
        <tx:attributes>
            <tx:method name="insert*"/>
            <tx:method name="delete*"/>
            <tx:method name="update*"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="pointCut" expression="execution(* com.cxsw.rms.service.impl.*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointCut"/>
    </aop:config>

</beans>

SpringMVC.xml (springMVC的核心配置文件)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 配置组建扫描 -->
    <context:component-scan base-package="com.cxsw.rms.controller" />
    <!-- 配置注解驱动 -->
    <mvc:annotation-driven />

    <bean id="dateConverter" class="com.cxsw.rms.convert.DateConverter" />

    <bean class="org.springframework.context.support.ConversionServiceFactoryBean" id="conversionService">
        <property name="converters" ref="dateConverter" />

    </bean>
    <!-- 时间转换驱动 -->
    <mvc:annotation-driven conversion-service="conversionService"/>

    <!--  配置文件上传解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="52128800" />
        <property name="maxUploadSizePerFile" value="52128800"/>
        <property name="defaultEncoding" value="UTF-8"/>
    </bean>

    <mvc:default-servlet-handler />

</beans>

Mybatis 配置文件(ssm 集成之后可以不需要此配置文件,个人习惯而已)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>

    <!--  替换全限定名  -->
    <typeAliases>
        <typeAlias type="com.cxsw.rms.entity.User"  alias="user"/>
        <typeAlias type="com.cxsw.rms.entity.Student" alias="student"/>
    </typeAliases>

</configuration>

数据库的配置文件

✅ 注意mysql的版本,如果是8.0 驱动包是com.mysql.cj.jdbc.Driver,5.0版本的驱动包在 com.mysql.jdbc.Driver 下。导入依赖的时候格外要注意。

druid.jdbc.driver=com.mysql.cj.jdbc.Driver
druid.jdbc.url=jdbc:mysql://localhost:3306/rms?useUnicode=true&characterEncoding=utf-8
druid.jdbc.username=root
druid.jdbc.password=wb7446032001

Mapper 文件(示例)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.cxsw.rms.repository.StudentMapper">

    <resultMap id="studentMap" type="student">
        <id property="sid" column="SID" />
        <result property="name" column="NAME" />
        <result property="nation" column="NATION" />
        <result property="idCard" column="ID_CARD" />
        <result property="region" column="REGION" />
        <result property="education" column="EDUCATION" />
        <result property="school" column="SCHOOL" />
        <result property="major" column="MAJOR" />
        <result property="educationType" column="EDUCATION_TYPE" />
        <result property="email" column="EMAIL" />
        <result property="phone" column="PHONE" />
        <result property="employeeUnit" column="EMPLOYEE_UNIT" />
        <result property="registerBook" column="REGISTER_BOOK" />
        <result property="diploma" column="DIPLOMA" />
        <result property="creatTime" column="CREAT_TIME" />
    </resultMap>

    <insert id="insertStudent" parameterType="student">
        INSERT INTO STUDENTS (`SID`, `NAME`, NATION, ID_CARD, REGION, EDUCATION, SCHOOL, MAJOR, EDUCATION_TYPE,
                              EMAIL, PHONE, EMPLOYEE_UNIT, REGISTER_BOOK, DIPLOMA, CREAT_TIME) VALUE
                             (
                              #{sid}, #{name}, #{nation}, #{idCard}, #{region}, #{education}, #{school}, #{major},
                              #{educationType}, #{email}, #{phone}, #{employeeUnit}, #{registerBook}, #{diploma},
                              #{creatTime}
                              )
    </insert>

</mapper>

6、后端三层架构示例

持久层和实体类

映射数据库字段的实体个人建议使用Lombok代码生成器,这样你在修改字段的时候就不用来回手动生成get set tostring ….. 等方法了。

用法如下

  • 在你的依赖文件中导入Lombok的依赖坐标。
<dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.24</version>
</dependency>
  • 在你idea中的插件商店里边下载Lombok插件,不然代码生成不起作用,切记!!!
  • 在你的实体类里边配置注解,注解具体解释如下:

✅ @Data 用于生成get set hashCode toString 等方法 @AllArgsConstructor 生成全参数的构造法昂发

@NoArgsConstructor 生成无参数的构造方法

通过上图就可以发现,在单独写了实体字段的情况下,通过注解就可以自动生成代码。

持久层的接口:这里以新增数据的某个接口示例

/**
 * 信息登记数据层
 * @author zhangsan
 * @date 2022-08-25
 */
public interface StudentMapper {

    /**
     * 新增信息登记
     * @param student 信息登记对象
     * @return 0 代表新增失败 反之成功
     */
    int insertStudent(Student student);
}

对应的mapper(由于新增字段有点多,没有使用mybatis的注解来写sql)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.cxsw.rms.repository.StudentMapper">

   <!-- 这里的student是我在mybtais中配置的别名 -->
    <insert id="insertStudent" parameterType="student">
        INSERT INTO STUDENTS (`SID`, `NAME`, NATION, ID_CARD, REGION, EDUCATION, SCHOOL, MAJOR, EDUCATION_TYPE,
                              EMAIL, PHONE, EMPLOYEE_UNIT, REGISTER_BOOK, DIPLOMA, CREAT_TIME) VALUE
                             (
                              #{sid}, #{name}, #{nation}, #{idCard}, #{region}, #{education}, #{school}, #{major},
                              #{educationType}, #{email}, #{phone}, #{employeeUnit}, #{registerBook}, #{diploma},
                              #{creatTime}
                              )
    </insert>

</mapper>

业务层(由于业务不是很复杂,就是简单的数据处理,所以业务层就是调用持久层的接口返回数据)

/**
 *信息填报接口业务逻辑层
*@author zhangsan
 *@date 2022-08-26
 */
public interface StudentService {

        /**
        * 新增信息登记
        * @param student 信息登记对象
        * @return 0代表新增失败 反之成功
        */
        String insertStudent(Student student);
}

实现类:

/**
 * 信息填报业务层实现
 * @author zhangsan
 * @date 2022-08-26
 */
@Service
public class StudentServiceImpl implements StudentService {

    @Resource
    private StudentMapper studentMapper;

        /**
        * 新增信息登记
        * @param student信息登记对象
        * @return 0代表新增失败 反之成功
        */
        @Override
    public String insertStudent(Student student) {

        Date date = new Date(new java.util.Date(System.currentTimeMillis()).getTime());
        student.setCreatTime(date);
        studentMapper.insertStudent(student);
        List<Student> students = studentMapper.listStudents(student.getName(), "");
        User user = new User();
        user.setUsername(student.getName());
        user.setSid(students.get(0).getSid());
        int res = userMapper.updateUserForeignKey(user);
        if(res == 0){
            return "新增失败";
        }else{
            return "新增成功";
        }
    }
}

控制层

/**
 * 信息填报接口
 * @author zhangsan
 * date 2022-08-26
 */
@RestController
@RequestMapping(value = "/student")
public class StudentController {

    @Resource
    private StudentService studentService;

        /**
        * 新增信息填报接口
        * @param student 学生对象
        * @return result 对象
        */
    @PostMapping
    public Result createStudentList(@RequestBody Student student){

        if(student == null){
            return new Result(500, "上报信息不全", null);
        }else{
            String msg = studentService.insertStudent(student);
            return new Result(200, "操作成功", msg);
        }

    }

}

✅ 😁这就完成后端的一个接口了,紧接着测试完就可以将接口交给前端了,在这里,个人建议写接口写类的时候一定要写好 javadoc 文档注释,这样方便后来者查看,我写代码的时候一定会这样想:代码是写给别人看的,不是写给自己看的,所以一定要简洁明了

7、前端使用接口

✅ 前端我使用的是axios发送请求,并对请求做了简单封装。

import axios from "axios";
// message 是自己对element-ui总的消息提示框进行的封装,防止其重复弹出
import { message } from "@/util/message"

// 拦截响应
axios.interceptors.response.use(
    response => {
        if (!response?.data) return;
        const res = response.data;
        if (res.code !== 200) {
            message({
                message: res.msg || '请求出错,请重试',
                type: "error",
                duration: 1500,
                onClose: () => {
                    // 消息框退出时需要处理的逻辑
                }
            })
        } else {
            return res;
        }
    },
    error => {
        message({
            message: "请求出错,请重试",
            type: "error",
            duration: 1500
        })
        // 返回错误
        return Promise.reject(error)
    }
)

// 封装请求
const request = async ({ url, method, data, headers }) => {

    const type = method.toLocaleUpperCase();

    if (type === 'GET') {
        return await new Promise((res, rej) => {
            getRequest(url, data, res, rej)
        })
    } else if (type === 'POST') {
        return await new Promise((res, rej) => {
            postRequest(url, data, headers, res, rej)
        })
    } else if (type === 'PUT') {
        return await new Promise((res, rej) => {
            putReqeust(url, data, res, rej)
        })
    } else {
        return await new Promise((res, rej) => {
            deleteRequest(url, res, rej)
        })
    }
}
// get 请求
const getRequest = (url, datas, res, rej) => {
    axios.get(url, { params: datas }).then((data) => {
        res(data)
    }).catch((error) => {
        rej(error)
    })
}

// put 请求
const putReqeust = (url, datas, res, rej) => {
    axios.put(url, datas).then((data) => {
        res(data)
    }).catch((error) => {
        rej(error)
    })
}
// delete 请求
const deleteRequest = (url, res, rej) => {
    axios.delete(url).then((data) => {
        res(data)
    }).catch((error) => {
        rej(error)
    })
}
// post请求
const postRequest = (url, datas, headers, res, rej) => {
    axios.post(url, datas, headers).then((data) => {
        res(data)
    }).catch((error) => {
        rej(error)
    })
}

export default request;

message的封装如下:

import { Message } from 'element-ui'

let messageInstance = null;
// 防止重复弹出消息提示
const resetMessage = (options) => {
    if (messageInstance) {
        messageInstance.close()
    }
    messageInstance = Message(options)
};
let tipType = ["error", "info", "success", "warning"];
tipType.forEach(type => {
    resetMessage[type] = options => {
        if (typeof options === "string") {
            options = {
                message: options
            }
        }
        options.type = type
        return resetMessage(options)
    }
})
export const message = resetMessage

在 src 下构建目录 api 用于统一管理接口:

import request from "@/util/request";

// * 新增信息登记
export const addStudnetMsg = (data) => {
    return request({
        url: "/api/student",
        method: "POST",
        data
    })
}

在相应的页面中调用接口:

// 导入 api
import { updateStudentMsg, addStudnetMsg } from "@/api/student"

// 表单提交方法
        submitForm(formName) {
            this.$refs[formName].validate((valid) => {
                if (valid) {

                                         // 根据你实际的页面 调用接口
                    const formMethod = this.ruleForm.sid ? updateStudentMsg : addStudnetMsg;
                    this.ruleForm.region = this.ruleForm.region[0] + "-" + this.ruleForm.region[1] + "-" + this.ruleForm.region[2]
                    formMethod(this.ruleForm).then((data) => {
                        if (data?.code === 200) {
                            message({
                                type: "success",
                                message: data.msg,
                                duration: 1500,
                                onClose: () => {
                                    this.ruleForm.registerBook = ''
                                    this.ruleForm.diploma = ''
                                    this.$router.push("/");
                                    // 更新用户信息
                                    if (!this.ruleForm.sid) {
                                        let params = { username: sessionUtils.get('token').username };
                                        listUsers(params).then((data) => {
                                            if (data?.code === 200) {
                                                data.data[0].password = "";
                                                sessionUtils.set("token", data.data[0], 1000 * 60 * 60 * 6)
                                                // 将数据存储到vuex中
                                                this.$store.dispatch("userInfo/getUserInfo", data.data[0]);
                                            }
                                        })
                                    }
                                }
                            })
                        }
                    })

                } else {
                    return false;
                }
            });

😜至此,一个接口通了。

8、源码地址

前端gitee地址:https://gitee.com/wenjingxin/rms.git

后端gitee地址:https://gitee.com/wenjingxin/ssm.git

😁 分享不易,希望多多支持 🤝