模块一(讲师管理模块)
后端(准备工作)
准备工作
搭建项目
项目结构的搭建
创建父工程
pom类型(父工程)
依赖管理版本和公共依赖
搭建子模块
| <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> |
| <modelVersion>4.0.0</modelVersion> |
| <modules> |
| <module>service</module> |
| </modules> |
| <parent> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-parent</artifactId> |
| <version>2.2.1.RELEASE</version> |
| <relativePath/> |
| </parent> |
| <groupId>org.example</groupId> |
| <artifactId>guli</artifactId> |
| <packaging>pom</packaging> |
| <version>0.0.1-SNAPSHOT</version> |
| <name>guli</name> |
| <description>Demo project for Spring Boot</description> |
| |
| <properties> |
| <java.version>1.8</java.version> |
| <guli.version>0.0.1-SNAPSHOT</guli.version> |
| <mybatis-plus.version>3.0.5</mybatis-plus.version> |
| <velocity.version>2.0</velocity.version> |
| <swagger.version>2.7.0</swagger.version> |
| <aliyun.oss.version>2.8.3</aliyun.oss.version> |
| <jodatime.version>2.10.1</jodatime.version> |
| <poi.version>3.17</poi.version> |
| <commons-fileupload.version>1.3.1</commons-fileupload.version> |
| <commons-io.version>2.6</commons-io.version> |
| <httpclient.version>4.5.1</httpclient.version> |
| <jwt.version>0.7.0</jwt.version> |
| <aliyun-java-sdk-core.version>4.3.3</aliyun-java-sdk-core.version> |
| <aliyun-sdk-oss.version>3.1.0</aliyun-sdk-oss.version> |
| <aliyun-java-sdk-vod.version>2.15.2</aliyun-java-sdk-vod.version> |
| <aliyun-java-vod-upload.version>1.4.11</aliyun-java-vod-upload.version> |
| <aliyun-sdk-vod-upload.version>1.4.11</aliyun-sdk-vod-upload.version> |
| <fastjson.version>1.2.28</fastjson.version> |
| <gson.version>2.8.2</gson.version> |
| <json.version>20170516</json.version> |
| <commons-dbutils.version>1.7</commons-dbutils.version> |
| <canal.client.version>1.1.0</canal.client.version> |
| <docker.image.prefix>zx</docker.image.prefix> |
| <cloud-alibaba.version>0.2.2.RELEASE</cloud-alibaba.version> |
| </properties> |
| |
| <dependencyManagement> |
| <dependencies> |
| |
| <dependency> |
| <groupId>org.springframework.cloud</groupId> |
| <artifactId>spring-cloud-dependencies</artifactId> |
| <version>Hoxton.RELEASE</version> |
| <type>pom</type> |
| <scope>import</scope> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.springframework.cloud</groupId> |
| <artifactId>spring-cloud-alibaba-dependencies</artifactId> |
| <version>${cloud-alibaba.version}</version> |
| <type>pom</type> |
| <scope>import</scope> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.baomidou</groupId> |
| <artifactId>mybatis-plus-boot-starter</artifactId> |
| <version>${mybatis-plus.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.apache.velocity</groupId> |
| <artifactId>velocity-engine-core</artifactId> |
| <version>${velocity.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>io.springfox</groupId> |
| <artifactId>springfox-swagger2</artifactId> |
| <version>${swagger.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>io.springfox</groupId> |
| <artifactId>springfox-swagger-ui</artifactId> |
| <version>${swagger.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>com.aliyun.oss</groupId> |
| <artifactId>aliyun-sdk-oss</artifactId> |
| <version>${aliyun.oss.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>joda-time</groupId> |
| <artifactId>joda-time</artifactId> |
| <version>${jodatime.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.apache.poi</groupId> |
| <artifactId>poi</artifactId> |
| <version>${poi.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.apache.poi</groupId> |
| <artifactId>poi-ooxml</artifactId> |
| <version>${poi.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>commons-fileupload</groupId> |
| <artifactId>commons-fileupload</artifactId> |
| <version>${commons-fileupload.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>commons-io</groupId> |
| <artifactId>commons-io</artifactId> |
| <version>${commons-io.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.apache.httpcomponents</groupId> |
| <artifactId>httpclient</artifactId> |
| <version>${httpclient.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.google.code.gson</groupId> |
| <artifactId>gson</artifactId> |
| <version>${gson.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>io.jsonwebtoken</groupId> |
| <artifactId>jjwt</artifactId> |
| <version>${jwt.version}</version> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>com.aliyun</groupId> |
| <artifactId>aliyun-java-sdk-core</artifactId> |
| <version>${aliyun-java-sdk-core.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>com.aliyun.oss</groupId> |
| <artifactId>aliyun-sdk-oss</artifactId> |
| <version>${aliyun-sdk-oss.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>com.aliyun</groupId> |
| <artifactId>aliyun-java-sdk-vod</artifactId> |
| <version>${aliyun-java-sdk-vod.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>com.aliyun</groupId> |
| <artifactId>aliyun-java-vod-upload</artifactId> |
| <version>${aliyun-java-vod-upload.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>com.aliyun</groupId> |
| <artifactId>aliyun-sdk-vod-upload</artifactId> |
| <version>${aliyun-sdk-vod-upload.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>com.alibaba</groupId> |
| <artifactId>fastjson</artifactId> |
| <version>${fastjson.version}</version> |
| </dependency> |
| <dependency> |
| <groupId>org.json</groupId> |
| <artifactId>json</artifactId> |
| <version>${json.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>commons-dbutils</groupId> |
| <artifactId>commons-dbutils</artifactId> |
| <version>${commons-dbutils.version}</version> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.alibaba.otter</groupId> |
| <artifactId>canal.client</artifactId> |
| <version>${canal.client.version}</version> |
| </dependency> |
| </dependencies> |
| </dependencyManagement> |
| |
| <build> |
| <plugins> |
| <plugin> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-maven-plugin</artifactId> |
| </plugin> |
| </plugins> |
| </build> |
| |
| </project> |
| |
搭建servce模块
| <?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"> |
| <parent> |
| <artifactId>guli</artifactId> |
| <groupId>org.example</groupId> |
| <version>0.0.1-SNAPSHOT</version> |
| </parent> |
| <modelVersion>4.0.0</modelVersion> |
| <version>1.0.0</version> |
| <artifactId>service</artifactId> |
| <packaging>pom</packaging> |
| <modules> |
| <module>service_edu</module> |
| <module>service_vod</module> |
| </modules> |
| |
| <dependencies> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>com.baomidou</groupId> |
| <artifactId>mybatis-plus-boot-starter</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>mysql</groupId> |
| <artifactId>mysql-connector-java</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.apache.velocity</groupId> |
| <artifactId>velocity-engine-core</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>io.springfox</groupId> |
| <artifactId>springfox-swagger2</artifactId> |
| </dependency> |
| <dependency> |
| <groupId>io.springfox</groupId> |
| <artifactId>springfox-swagger-ui</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.projectlombok</groupId> |
| <artifactId>lombok</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.apache.poi</groupId> |
| <artifactId>poi</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>org.apache.poi</groupId> |
| <artifactId>poi-ooxml</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>commons-fileupload</groupId> |
| <artifactId>commons-fileupload</artifactId> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.apache.httpcomponents</groupId> |
| <artifactId>httpclient</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>commons-io</groupId> |
| <artifactId>commons-io</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>com.google.code.gson</groupId> |
| <artifactId>gson</artifactId> |
| </dependency> |
| |
| <dependency> |
| <groupId>junit</groupId> |
| <artifactId>junit</artifactId> |
| <version>4.12</version> |
| </dependency> |
| </dependencies> |
| |
| </project> |
搭建service_edu模块
注意:springboot2.4.1不支持 velocity-engine-core 2.0
在idle中搭建工程
![image-20221007223034372]()
搭建配置文件
| |
| spring: |
| application: |
| name: service-edu |
| active: dev |
| |
| server: |
| port: 8001 |
| mybatis-plus: |
| configuration: |
| log-impl: org.apache.ibatis.logging.stdout.StdOutImpl |
| mapper-locations: classpath:com/atguigu/service/*/mapper/*.xml |
| global-config: |
| db-config: |
| logic-delete-value: 1 |
| logic-not-delete-value: 0 |
| |
| spring: |
| datasource: |
| type: com.zaxxer.hikari.HikariDataSource |
| driver-class-name: com.mysql.cj.jdbc.Driver |
| url: jdbc:mysql://localhost:3306/guli?serverTimezone=GMT%2B8 |
| username: root |
| password: root |
| hikari: |
| connection-test-query: SELECT 1 |
| connection-timeout: 60000 |
| idle-timeout: 500000 |
| max-lifetime: 540000 |
| maximum-pool-size: 12 |
| minimum-idle: 10 |
| pool-name: GuliHikariPool |
| jackson: |
| date-format: yyyy-MM-dd HH:mm:ss |
| |
| time-zone: GMT+8 |
mp代码生成器
使用代码生成器,生成相关代码,在实际开发中使用较多
| |
| <dependency> |
| <groupId>org.apache.velocity</groupId> |
| <artifactId>velocity-engine-core</artifactId> |
| </dependency> |
CodeGenertor
| package com.guli; |
| |
| import com.baomidou.mybatisplus.annotation.DbType; |
| import com.baomidou.mybatisplus.annotation.IdType; |
| import com.baomidou.mybatisplus.generator.AutoGenerator; |
| import com.baomidou.mybatisplus.generator.config.DataSourceConfig; |
| import com.baomidou.mybatisplus.generator.config.GlobalConfig; |
| import com.baomidou.mybatisplus.generator.config.PackageConfig; |
| import com.baomidou.mybatisplus.generator.config.StrategyConfig; |
| import com.baomidou.mybatisplus.generator.config.rules.DateType; |
| import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; |
| import org.junit.Test; |
| |
| |
| |
| |
| |
| public class CodeGenerator { |
| |
| @Test |
| public void run() { |
| |
| |
| AutoGenerator mpg = new AutoGenerator(); |
| |
| |
| GlobalConfig gc = new GlobalConfig(); |
| String projectPath = System.getProperty("user.dir"); |
| |
| gc.setOutputDir("E:\\zouzilu\\Java_code\\guli\\service\\service_edu" + "/src/main/java"); |
| gc.setAuthor("testjava"); |
| gc.setOpen(false); |
| gc.setFileOverride(false); |
| gc.setServiceName("%sService"); |
| gc.setIdType(IdType.ID_WORKER_STR); |
| gc.setDateType(DateType.ONLY_DATE); |
| gc.setSwagger2(true); |
| |
| mpg.setGlobalConfig(gc); |
| |
| |
| DataSourceConfig dsc = new DataSourceConfig(); |
| dsc.setUrl("jdbc:mysql://localhost:3306/guli"); |
| dsc.setDriverName("com.mysql.jdbc.Driver"); |
| dsc.setUsername("root"); |
| dsc.setPassword("root"); |
| dsc.setDbType(DbType.MYSQL); |
| mpg.setDataSource(dsc); |
| |
| |
| PackageConfig pc = new PackageConfig(); |
| pc.setModuleName("eduservice"); |
| pc.setParent("com.guli"); |
| pc.setController("controller"); |
| pc.setEntity("entity"); |
| pc.setService("service"); |
| pc.setMapper("mapper"); |
| mpg.setPackageInfo(pc); |
| |
| |
| StrategyConfig strategy = new StrategyConfig(); |
| strategy.setInclude("edu_teacher"); |
| strategy.setNaming(NamingStrategy.underline_to_camel); |
| strategy.setTablePrefix(pc.getModuleName() + "_"); |
| strategy.setColumnNaming(NamingStrategy.underline_to_camel); |
| strategy.setEntityLombokModel(true); |
| strategy.setRestControllerStyle(true); |
| strategy.setControllerMappingHyphenStyle(true); |
| mpg.setStrategy(strategy); |
| |
| |
| mpg.execute(); |
| } |
| } |
| |
出错
The server time zone value '?й???????' is unrecognized or represents more than one time zone
方案1、在项目代码-数据库连接URL后,加上 ?serverTimezone=UTC(注意大小写必须一致)
| spring.datasource.url=jdbc:mysql://localhost:3306/guli?serverTimezone=UTC |
方案2、在mysql中设置时区,默认为SYSTEM(推荐)
set global time_zone=’+8:00’
| mysql> set global time_zone='+8:00'; |
| Query OK, 0 rows affected (0.01 sec) |
| |
注意:mybatisplus在service层中已经把mapper集成
| @Autowired |
| private EduTeacherService teacherService; |
| |
| |
| @GetMapping("findAll") |
| public List<EduTeacher> findAllTeacher(){ |
| |
| List<EduTeacher> list = teacherService.list(null); |
| return list; |
| } |
| |
搭建启动类
| |
| @SpringBootApplication |
| @MapperScan("com.guli.eduservice.mapper") |
| public class EduApplication { |
| |
| public static void main(String[] args) { |
| SpringApplication.run(EduApplication.class,args); |
| } |
| } |
| |
在controller层搭建测试代码
| package com.guli.eduservice.controller; |
| |
| |
| import com.guli.eduservice.entity.EduTeacher; |
| import com.guli.eduservice.service.EduTeacherService; |
| import org.springframework.beans.factory.annotation.Autowired; |
| import org.springframework.web.bind.annotation.GetMapping; |
| import org.springframework.web.bind.annotation.RequestMapping; |
| |
| import org.springframework.web.bind.annotation.RestController; |
| |
| import java.util.List; |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| @RestController |
| @RequestMapping("/eduservice/teacher") |
| public class EduTeacherController { |
| @Autowired |
| private EduTeacherService teacherService; |
| |
| |
| @GetMapping("findAll") |
| public List<EduTeacher> findAllTeacher(){ |
| |
| List<EduTeacher> list = teacherService.list(null); |
| return list; |
| } |
| } |
| |
测试(启动)
![image-20221008171440692]()
发现一个时间问题
| |
| spring.jackson.date-format=yyyy-MM-dd HH:mm:ss |
| spring.jackson.time-zone=GMT+8 |
讲师逻辑删除(功能)
在删除主键上加注解
| @TableLogic |
| @ApiModelProperty(value = "逻辑删除 1(true)已删除, 0(false)未删除") |
| private Boolean isDeleted; |
配置文件加入逻辑删除组件
| |
| mybatis-plus.global-config.db-config.logic-delete-value = 1 |
| mybatis-plus.global-config.db-config.logic-not-delete-value = 0 |
分页查询
设置分页查询的插件
| @Configuration |
| @MapperScan("com.guli.eduservice.mapper") |
| public class EduConfig { |
| |
| |
| |
| |
| @Bean |
| public ISqlInjector sqlInjector() { |
| return new LogicSqlInjector(); |
| } |
| |
| |
| |
| |
| @Bean |
| public PaginationInterceptor paginationInterceptor() { |
| return new PaginationInterceptor(); |
| } |
| } |
编写分页查询的代码
| @ApiOperation(value = "分页查询") |
| @GetMapping("pageTeacher/{current}/{limit}") |
| public Result pageListTeacher( @PathVariable("current") Long current, |
| @PathVariable("limit") Long limit){ |
| |
| Page<EduTeacher> page =new Page<>(current,limit); |
| |
| teacherService.page(page,null); |
| |
| long total = page.getTotal(); |
| List<EduTeacher> list = page.getRecords(); |
| return Result.ok().data("total",total).data("rows",list); |
| } |
带有条件的分页查询
建立一个对象接受传递的参数
| package com.guli.eduservice.entity.vo; |
| |
| import io.swagger.annotations.ApiModelProperty; |
| import lombok.Data; |
| |
| @Data |
| public class TeacherQuery { |
| |
| @ApiModelProperty(value = "教师名称,模糊查询") |
| private String name; |
| |
| @ApiModelProperty(value = "头衔 1高级讲师 2首席讲师") |
| private Integer level; |
| |
| @ApiModelProperty(value = "查询开始时间", example = "2019-01-01 10:10:10") |
| private String begin; |
| |
| @ApiModelProperty(value = "查询结束时间", example = "2019-12-01 10:10:10") |
| private String end; |
| } |
| |
具体的条件分页代码
| @ApiOperation(value = "分页查询带参数") |
| @PostMapping("pageTeacherCondition/{current}/{limit}") |
| public Result pageTeacherCondition(@PathVariable("current") Long current, |
| @PathVariable("limit") Long limit, |
| @RequestBody(required = false) TeacherQuery teacherQuery){ |
| |
| Page<EduTeacher> page =new Page<>(current,limit); |
| |
| QueryWrapper<EduTeacher> queryWrapper =new QueryWrapper<>(); |
| |
| |
| String name = teacherQuery.getName(); |
| Integer level = teacherQuery.getLevel(); |
| String begin = teacherQuery.getBegin(); |
| String end = teacherQuery.getEnd(); |
| if(!StringUtils.isEmpty(name)){ |
| queryWrapper.like("name",name); |
| } |
| if(!StringUtils.isEmpty(level)){ |
| queryWrapper.eq("level",level); |
| } |
| if(!StringUtils.isEmpty(begin)){ |
| queryWrapper.ge("gmt_create",begin); |
| } |
| if(!StringUtils.isEmpty(end)){ |
| queryWrapper.le("gmt_modified",end); |
| } |
| |
| teacherService.page(page,queryWrapper); |
| |
| long total = page.getTotal(); |
| List<EduTeacher> list = page.getRecords(); |
| return Result.ok().data("total",total).data("rows",list); |
| } |
| |
| |
添加用户
自动添加相关数据
添加自动添加配置
| @Component |
| public class MyMetaObjectHandler implements MetaObjectHandler { |
| @Override |
| public void insertFill(MetaObject metaObject) { |
| |
| this.setFieldValByName("gmtCreate", new Date(), metaObject); |
| this.setFieldValByName("gmtModified", new Date(), metaObject); |
| } |
| |
| @Override |
| public void updateFill(MetaObject metaObject) { |
| this.setFieldValByName("gmtModified", new Date(), metaObject); |
| } |
| } |
代码
| |
| |
| |
| |
| |
| @ApiOperation(value = "添加教师") |
| @PostMapping("addTeacher") |
| public Result addTeacher(@RequestBody EduTeacher eduTeacher){ |
| boolean save = teacherService.save(eduTeacher); |
| if(save){ |
| return Result.ok(); |
| }else { |
| return Result.error(); |
| } |
| } |
修改教师
| |
| |
| |
| |
| |
| @ApiOperation(value = "根据讲师id进行查询") |
| @GetMapping("getTeacher/{id}") |
| public Result getTeacher(@PathVariable String id) { |
| EduTeacher eduTeacher = teacherService.getById(id); |
| return Result.ok().data("teacher",eduTeacher); |
| } |
| |
| |
| |
| |
| |
| |
| @ApiOperation(value = "讲师修改功能") |
| @PostMapping("updateTeacher") |
| public Result updateTeacher(@RequestBody EduTeacher eduTeacher) { |
| boolean flag = teacherService.updateById(eduTeacher); |
| if(flag) { |
| return Result.ok(); |
| } else { |
| return Result.error(); |
| } |
| } |
| |
Common模块(公共模块)
common模块中放置所以模块所需要的共同代码
注意!!!
在其他模块中导入时,扫描相关的配置类加入,在启动类中加入
@ComponentScan(basePackages = {"com.guli(包)"}) //加入扫描规则
加入配置后只要导入其他模块中含有包名就扫描到本模块中
Swagger整合在common模块中
公共模块Common的 Pom.xm l配置
| <?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"> |
| <parent> |
| <artifactId>guli</artifactId> |
| <groupId>org.example</groupId> |
| <version>0.0.1-SNAPSHOT</version> |
| </parent> |
| <modules> |
| <module>service_base</module> |
| </modules> |
| <modelVersion>4.0.0</modelVersion> |
| <artifactId>common</artifactId> |
| <packaging>pom</packaging> |
| <properties> |
| <maven.compiler.source>8</maven.compiler.source> |
| <maven.compiler.target>8</maven.compiler.target> |
| </properties> |
| <dependencies> |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-web</artifactId> |
| <scope>provided </scope> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>com.baomidou</groupId> |
| <artifactId>mybatis-plus-boot-starter</artifactId> |
| <scope>provided </scope> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.projectlombok</groupId> |
| <artifactId>lombok</artifactId> |
| <scope>provided </scope> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>io.springfox</groupId> |
| <artifactId>springfox-swagger2</artifactId> |
| <scope>provided </scope> |
| </dependency> |
| <dependency> |
| <groupId>io.springfox</groupId> |
| <artifactId>springfox-swagger-ui</artifactId> |
| <scope>provided </scope> |
| </dependency> |
| |
| |
| <dependency> |
| <groupId>org.springframework.boot</groupId> |
| <artifactId>spring-boot-starter-data-redis</artifactId> |
| </dependency> |
| |
| |
| |
| |
| |
| |
| |
| </dependencies> |
| |
| </project> |
SwaggerConfig
配置swagger插件
| package com.atguigu.servicebase; |
| |
| import com.google.common.base.Predicates; |
| import org.springframework.context.annotation.Bean; |
| import org.springframework.context.annotation.Configuration; |
| import springfox.documentation.builders.ApiInfoBuilder; |
| import springfox.documentation.builders.PathSelectors; |
| import springfox.documentation.service.ApiInfo; |
| import springfox.documentation.service.Contact; |
| import springfox.documentation.spi.DocumentationType; |
| import springfox.documentation.spring.web.plugins.Docket; |
| import springfox.documentation.swagger2.annotations.EnableSwagger2; |
| |
| @Configuration |
| @EnableSwagger2 |
| public class SwaggerConfig { |
| |
| @Bean |
| public Docket webApiConfig(){ |
| return new Docket(DocumentationType.SWAGGER_2) |
| .groupName("webApi") |
| .apiInfo(webApiInfo()) |
| .select() |
| .paths(Predicates.not(PathSelectors.regex("/admin/.*"))) |
| .paths(Predicates.not(PathSelectors.regex("/error.*"))) |
| .build(); |
| |
| } |
| |
| private ApiInfo webApiInfo(){ |
| |
| return new ApiInfoBuilder() |
| .title("网站-课程中心API文档") |
| .description("本文档描述了课程中心微服务接口定义") |
| .version("1.0") |
| .contact(new Contact("java", "http://atguigu.com", "1123@qq.com")) |
| .build(); |
| } |
| } |
| |
swagger的基本使用规则
-
在controller类中加入注解
| @Api(description = "讲师管理") |
-
在方法上加上注解
| @ApiOperation(value = "所以讲师列表") |
| @GetMapping("findAll") |
| public List<EduTeacher> findAllTeacher(){ |
| |
| List<EduTeacher> list = teacherService.list(null); |
| return list; |
| } |
-
在参数上加上注解
| @ApiOperation(value = "逻辑删除表") |
| @DeleteMapping("{id}") |
| public boolean removeTeacher(@ApiParam(name = "id",value = "讲师Id",required = true) @PathVariable("id") String id){ |
| return teacherService.removeById(id); |
| } |
统一管理返回对象
建立模块common_utils
![]()
创建interface定义数据的返回状态码
| public interface ResultCode { |
| public static Integer SUCCESS = 20000; |
| public static Integer ERROR = 200001; |
| } |
创建返回对象
| package com.guli.commonutils; |
| import io.swagger.annotations.ApiModelProperty; |
| import lombok.Data; |
| import java.util.HashMap; |
| import java.util.Map; |
| |
| |
| @Data |
| public class R { |
| |
| @ApiModelProperty(value = "是否成功") |
| private Boolean success; |
| |
| @ApiModelProperty(value = "返回码") |
| private Integer code; |
| |
| @ApiModelProperty(value = "返回消息") |
| private String message; |
| |
| @ApiModelProperty(value = "返回数据") |
| private Map<String, Object> data = new HashMap<String, Object>(); |
| |
| |
| private R() { |
| } |
| |
| |
| public static R ok() { |
| R r = new R(); |
| r.setSuccess(true); |
| r.setCode(ResultCode.SUCCESS); |
| r.setMessage("成功"); |
| return r; |
| } |
| |
| |
| public static R error() { |
| R r = new R(); |
| r.setSuccess(false); |
| r.setCode(ResultCode.ERROR); |
| r.setMessage("失败"); |
| return r; |
| } |
| |
| public R success(Boolean success) { |
| this.setSuccess(success); |
| return this; |
| } |
| |
| public R message(String message) { |
| this.setMessage(message); |
| return this; |
| } |
| |
| public R code(Integer code) { |
| this.setCode(code); |
| return this; |
| } |
| |
| public R data(String key, Object value) { |
| this.data.put(key, value); |
| return this; |
| } |
| |
| public R data(Map<String, Object> map) { |
| this.setData(map); |
| return this; |
| } |
| } |
在service模块中到日
| <dependency> |
| <groupId>org.example</groupId> |
| <artifactId>common_utils</artifactId> |
| <version>0.0.1-SNAPSHOT</version> |
| </dependency> |
例子:
| |
| |
| |
| |
| @ApiOperation(value = "所以讲师列表") |
| @GetMapping("findAll") |
| public R findAllTeacher(){ |
| |
| List<EduTeacher> list = teacherService.list(null); |
| return R.ok().data("items",list); |
| } |
| |
| |
| |
| |
| |
| @ApiOperation(value = "逻辑删除表") |
| @DeleteMapping("{id}") |
| public R removeTeacher(@ApiParam(name = "id",value = "讲师Id",required = true) @PathVariable("id") String id){ |
| boolean flag = teacherService.removeById(id); |
| if(flag){ |
| return R.ok(); |
| }else { |
| return R.error(); |
| } |
| } |
| |
统一配置异常处理
![image-20221009222626518]()
| 首先,@ControllerAdvice本质上是一个@Component,因此也会被当成组建扫描。 |
全局异常处理
| @ControllerAdvice |
| public class GlobalExceptionHandler { |
| |
| |
| @ExceptionHandler(Exception.class) |
| @ResponseBody |
| public Result error(Exception e) { |
| e.printStackTrace(); |
| return Result.error().message("执行了全局异常处理.."); |
| } |
| } |
| |
特定异常
| |
| @ExceptionHandler(ArithmeticException.class) |
| @ResponseBody |
| public Result error(ArithmeticException e) { |
| e.printStackTrace(); |
| return Result.error().message("执行了全局异常处理.."); |
| } |
| } |
自定义异常
同一日志处理
![3-统一日志处理]()
打印佛主
banner.txt在配置文件的同级目录下
logback-spring.xml
| <?xml version="1.0" encoding="UTF-8"?> |
| <configuration scan="true" scanPeriod="10 seconds"> |
| |
| |
| |
| |
| |
| <contextName>logback</contextName> |
| |
| <property name="log.path" value="E:/zouzilu/Project/logback_data" /> |
| |
| |
| |
| |
| |
| |
| |
| |
| <property name="CONSOLE_LOG_PATTERN" |
| value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/> |
| |
| |
| |
| <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> |
| |
| |
| <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> |
| <level>INFO</level> |
| </filter> |
| <encoder> |
| <Pattern>${CONSOLE_LOG_PATTERN}</Pattern> |
| |
| <charset>UTF-8</charset> |
| </encoder> |
| </appender> |
| |
| |
| |
| |
| |
| <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| |
| <file>${log.path}/log_info.log</file> |
| |
| <encoder> |
| <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> |
| <charset>UTF-8</charset> |
| </encoder> |
| |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| |
| <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| <maxFileSize>100MB</maxFileSize> |
| </timeBasedFileNamingAndTriggeringPolicy> |
| |
| <maxHistory>15</maxHistory> |
| </rollingPolicy> |
| |
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| <level>INFO</level> |
| <onMatch>ACCEPT</onMatch> |
| <onMismatch>DENY</onMismatch> |
| </filter> |
| </appender> |
| |
| |
| <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| |
| <file>${log.path}/log_warn.log</file> |
| |
| <encoder> |
| <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> |
| <charset>UTF-8</charset> |
| </encoder> |
| |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| <maxFileSize>100MB</maxFileSize> |
| </timeBasedFileNamingAndTriggeringPolicy> |
| |
| <maxHistory>15</maxHistory> |
| </rollingPolicy> |
| |
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| <level>warn</level> |
| <onMatch>ACCEPT</onMatch> |
| <onMismatch>DENY</onMismatch> |
| </filter> |
| </appender> |
| |
| |
| |
| <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> |
| |
| <file>${log.path}/log_error.log</file> |
| |
| <encoder> |
| <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern> |
| <charset>UTF-8</charset> |
| </encoder> |
| |
| <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> |
| <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern> |
| <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP"> |
| <maxFileSize>100MB</maxFileSize> |
| </timeBasedFileNamingAndTriggeringPolicy> |
| |
| <maxHistory>15</maxHistory> |
| </rollingPolicy> |
| |
| <filter class="ch.qos.logback.classic.filter.LevelFilter"> |
| <level>ERROR</level> |
| <onMatch>ACCEPT</onMatch> |
| <onMismatch>DENY</onMismatch> |
| </filter> |
| </appender> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| <springProfile name="dev"> |
| |
| <logger name="com.guli" level="INFO" /> |
| |
| |
| |
| |
| |
| |
| <root level="INFO"> |
| <appender-ref ref="CONSOLE" /> |
| <appender-ref ref="INFO_FILE" /> |
| <appender-ref ref="WARN_FILE" /> |
| <appender-ref ref="ERROR_FILE" /> |
| </root> |
| </springProfile> |
| |
| |
| |
| <springProfile name="pro"> |
| |
| <root level="INFO"> |
| <appender-ref ref="CONSOLE" /> |
| <appender-ref ref="DEBUG_FILE" /> |
| <appender-ref ref="INFO_FILE" /> |
| <appender-ref ref="ERROR_FILE" /> |
| <appender-ref ref="WARN_FILE" /> |
| </root> |
| </springProfile> |
| |
| </configuration> |
后台系统登录
管理员登录
登录时返回两个方法
| |
| @GetMapping("info") |
| public Result info(){ |
| return Result.ok().data("roles","[admin]").data("name","admin").data("avator","https://profile-avatar.csdnimg.cn/eb6bb064352748f3a18cfb856a7ab860_weixin_44037376.jpg!3"); |
| } |
| |
跨域问题的解决CORS
方法一:加注解
方法二:网关解决
方法三:springMvc的配置文件
前端模块搭建
前段页面框架说明
前段入口
包含的框架
基于 Vue + elementUI
目录说明
build:
项目编译所在的目录
config目录:
修改 index.js 中修改eslint改为false
| |
| |
| |
| useEslint: false, |
| |
| |
| showEslintErrorsInOverlay: false, |
| |
| |
| |
dev.env.js:修改访问后端的接口地址
修改访问后端的接口地址
搭建项目前段的页面环境
packag.config.js
| { |
| "name": "vue-admin-template", |
| "version": "3.8.0", |
| "license": "MIT", |
| "description": "A vue admin template with Element UI & axios & iconfont & permission control & lint", |
| "author": "Pan <panfree23@gmail.com>", |
| "scripts": { |
| "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js", |
| "start": "npm run dev", |
| "build": "node build/build.js", |
| "build:report": "npm_config_report=true npm run build", |
| "lint": "eslint --ext .js,.vue src", |
| "test": "npm run lint", |
| "svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml" |
| }, |
| "dependencies": { |
| "axios": "0.18.0", |
| "element-ui": "2.4.6", |
| "js-cookie": "2.2.0", |
| "normalize.css": "7.0.0", |
| "nprogress": "0.2.0", |
| "vue": "2.5.17", |
| "vue-router": "3.0.1", |
| "vuex": "3.0.1" |
| }, |
| "devDependencies": { |
| "autoprefixer": "8.5.0", |
| "babel-core": "6.26.0", |
| "babel-eslint": "8.2.6", |
| "babel-helper-vue-jsx-merge-props": "2.0.3", |
| "babel-loader": "7.1.5", |
| "babel-plugin-syntax-jsx": "6.18.0", |
| "babel-plugin-transform-runtime": "6.23.0", |
| "babel-plugin-transform-vue-jsx": "3.7.0", |
| "babel-preset-env": "1.7.0", |
| "babel-preset-stage-2": "6.24.1", |
| "chalk": "2.4.1", |
| "copy-webpack-plugin": "4.5.2", |
| "css-loader": "1.0.0", |
| "eslint": "4.19.1", |
| "eslint-friendly-formatter": "4.0.1", |
| "eslint-loader": "2.0.0", |
| "eslint-plugin-vue": "4.7.1", |
| "eventsource-polyfill": "0.9.6", |
| "file-loader": "1.1.11", |
| "friendly-errors-webpack-plugin": "1.7.0", |
| "html-webpack-plugin": "4.0.0-alpha", |
| "mini-css-extract-plugin": "0.4.1", |
| "node-notifier": "5.2.1", |
| "node-sass": "^4.7.2", |
| "optimize-css-assets-webpack-plugin": "5.0.0", |
| "ora": "3.0.0", |
| "path-to-regexp": "2.4.0", |
| "portfinder": "1.0.16", |
| "postcss-import": "12.0.0", |
| "postcss-loader": "2.1.6", |
| "postcss-url": "7.3.2", |
| "rimraf": "2.6.2", |
| "sass-loader": "7.0.3", |
| "script-ext-html-webpack-plugin": "2.0.1", |
| "semver": "5.5.0", |
| "shelljs": "0.8.2", |
| "svg-sprite-loader": "3.8.0", |
| "svgo": "1.0.5", |
| "uglifyjs-webpack-plugin": "1.2.7", |
| "url-loader": "1.0.1", |
| "vue-loader": "15.3.0", |
| "vue-style-loader": "4.1.2", |
| "vue-template-compiler": "2.5.17", |
| "webpack": "4.16.5", |
| "webpack-bundle-analyzer": "2.13.1", |
| "webpack-cli": "3.1.0", |
| "webpack-dev-server": "3.1.5", |
| "webpack-merge": "4.1.4" |
| }, |
| "engines": { |
| "node": ">= 6.0.0", |
| "npm": ">= 3.0.0" |
| }, |
| "browserslist": [ |
| "> 1%", |
| "last 2 versions", |
| "not ie <= 8" |
| ] |
| } |
| |
下载module包
运行项目
![image-20221014223232092]()
前端开发过程
![image-20221016154601071]()
讲师列表前端
1 添加路由
| |
| { |
| path: '/teacher', |
| component: Layout, |
| redirect: '/teacher/table', |
| name: '讲师管理', |
| meta: { title: '讲师管理', icon: 'example' }, |
| children: [ |
| { |
| path: 'table', |
| name: '讲师列表', |
| component: () => import('@/views/edu/teacher/list'), |
| meta: { title: '讲师列表', icon: 'table' } |
| }, |
| { |
| path: 'save', |
| name: '添加讲师', |
| component: () => import('@/views/edu/teacher/save'), |
| meta: { title: '添加讲师', icon: 'tree' } |
| } |
| ] |
| }, |
2 添加相应的Vue页面
| <template> |
| <div class="app-container"> |
| |
| <el-form :inline="true" class="demo-form-inline"> |
| <el-form-item> |
| <el-input v-model="teacherQuery.name" placeholder="讲师名"/> |
| </el-form-item> |
| |
| <el-form-item> |
| <el-select v-model="teacherQuery.level" clearable placeholder="讲师头衔"> |
| <el-option :value="1" label="高级讲师"/> |
| <el-option :value="2" label="首席讲师"/> |
| </el-select> |
| </el-form-item> |
| |
| <el-form-item label="添加时间"> |
| <el-date-picker |
| v-model="teacherQuery.begin" |
| type="datetime" |
| placeholder="选择开始时间" |
| value-format="yyyy-MM-dd HH:mm:ss" |
| default-time="00:00:00" |
| /> |
| </el-form-item> |
| <el-form-item> |
| <el-date-picker |
| v-model="teacherQuery.end" |
| type="datetime" |
| placeholder="选择截止时间" |
| value-format="yyyy-MM-dd HH:mm:ss" |
| default-time="00:00:00" |
| /> |
| </el-form-item> |
| |
| <el-button type="primary" icon="el-icon-search" @click="getList()">查询</el-button> |
| <el-button type="default" @click="resetData()">清空</el-button> |
| </el-form> |
| |
| |
| <el-table |
| :data="list" |
| border |
| fit |
| highlight-current-row> |
| <el-table-column |
| label="序号" |
| width="70" |
| align="center"> |
| <template slot-scope="scope"> |
| {{ (page - 1) * limit + scope.$index + 1 }} |
| </template> |
| </el-table-column> |
| |
| <el-table-column prop="name" label="名称" width="80" /> |
| |
| <el-table-column label="头衔" width="80"> |
| <template slot-scope="scope"> |
| {{ scope.row.level===1?'高级讲师':'首席讲师' }} |
| </template> |
| </el-table-column> |
| |
| <el-table-column prop="intro" label="资历" /> |
| |
| <el-table-column prop="gmtCreate" label="添加时间" width="160"/> |
| |
| <el-table-column prop="sort" label="排序" width="60" /> |
| |
| <el-table-column label="操作" width="200" align="center"> |
| <template slot-scope="scope"> |
| <router-link :to="'/edu/teacher/edit/'+scope.row.id"> |
| <el-button type="primary" size="mini" icon="el-icon-edit">修改</el-button> |
| </router-link> |
| <el-button type="danger" size="mini" icon="el-icon-delete" @click="removeDataById(scope.row.id)">删除</el-button> |
| </template> |
| </el-table-column> |
| </el-table> |
| |
| |
| <el-pagination |
| :current-page="page" |
| :page-size="limit" |
| :total="total" |
| style="padding: 30px 0; text-align: center;" |
| layout="total, prev, pager, next, jumper" |
| next-text="下一页" |
| prev-text="上一页" |
| > |
| </el-pagination> |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| </div> |
| |
3 在api中添加相应的方法
![image-20221017000110294]()
| import request from '@/utils/request' |
| export default{ |
| |
| getTeacherListPage(current,limit,teacherQuery){ |
| return request({ |
| url:`/eduservice/teacher/pageTeacherCondition/${current}/${limit}`, |
| method:'post', |
| |
| |
| data:teacherQuery |
| }) |
| |
| } |
| |
| } |
4 在Vue页面中添加相应的api与数据,实现功能
| </template> |
| |
| <script> |
| import teacher from '@/api/edu/teacher/teacher' |
| export default { |
| |
| data(){ |
| |
| return{ |
| list:null, |
| page:1, |
| limit:8, |
| total:0, |
| teacherQuery:{} |
| |
| } |
| }, |
| created(){ |
| |
| this.getList() |
| |
| }, |
| methods: { |
| |
| |
| |
| getList (page=1){ |
| this.page = page |
| teacher.getTeacherListPage(this.page,this.limit,this.teacherQuery) |
| .then( |
| response=>{ |
| this.list = response.data.rows |
| this.total = response.data.total |
| } |
| ) |
| .catch( |
| error=>{ |
| console.log(error) |
| } |
| ) |
| }, |
| |
| |
| resetData(){ |
| this.teacherQuery = {} |
| this.getList() |
| }, |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| removeDataById(id){ |
| |
| |
| this.$confirm('此操作将永久删除讲师记录, 是否继续?', '提示', { |
| confirmButtonText: '确定', |
| cancelButtonText: '取消', |
| type: 'warning' |
| }).then( |
| |
| ()=>{ |
| teacher.remove(id) |
| .then(response=>{ |
| |
| |
| this.$message({ |
| type:'success', |
| message:'删除成功!' |
| }); |
| |
| this.getList() |
| }) |
| }) |
| |
| .catch( |
| |
| |
| |
| |
| |
| |
| |
| ) |
| } |
| }, |
| } |
| </script> |
| |
| <style> |
| |
| </style> |
添加讲师
| <template> |
| <div class="app-container"> |
| <el-form label-width="120px"> |
| <el-form-item label="讲师名称"> |
| <el-input v-model="teacher.name"/> |
| </el-form-item> |
| <el-form-item label="讲师排序"> |
| <el-input-number v-model="teacher.sort" controls-position="right" min="0"/> |
| </el-form-item> |
| <el-form-item label="讲师头衔"> |
| <el-select v-model="teacher.level" clearable placeholder="请选择"> |
| <el-option :value="1" label="高级讲师"/> |
| <el-option :value="2" label="首席讲师"/> |
| </el-select> |
| </el-form-item> |
| <el-form-item label="讲师资历"> |
| <el-input v-model="teacher.career"/> |
| </el-form-item> |
| <el-form-item label="讲师简介"> |
| <el-input v-model="teacher.intro" :rows="10" type="textarea"/> |
| </el-form-item> |
| <!-- 讲师头像:TODO --> |
| <el-form-item> |
| <el-button :disabled="saveBtnDisabled" type="primary" @click="saveOrUpdate">保存</el-button> |
| </el-form-item> |
| </el-form> |
| |
| </div> |
| </template> |
| |
| <script> |
| import teacher from '@/api/edu/teacher/teacher' |
| export default { |
| name:"save", |
| //数据 |
| data(){ |
| return{ |
| teacher:{ |
| name: '', |
| sort: 0, |
| level: 1, |
| career: '', |
| intro: '', |
| avatar: '' |
| }, |
| } |
| }, |
| //事件 |
| methods:{ |
| saveOrUpdate(){ |
| console.log(this.teacher) |
| } |
| }, |
| created(){ |
| |
| } |
| } |
| </script> |
| |
| <style> |
| |
| </style> |
| |
| |
| addTeacher(teacher){ |
| return request({ |
| url:`/eduservice/teacher/addTeacher`, |
| method:'post', |
| data:teacher |
| }) |
| } |
修改讲师
修改路由(hidden :隐藏路由)
| { |
| path: 'edit/:id', |
| name: '修改讲师', |
| component: () => import('@/views/edu/teacher/save'), |
| meta: { title: '修改讲师', noCache: true }, |
| hidden: true |
| } |
| <router-link :to="'/teacher/edit/'+scope.row.id"> |
| |
| <el-button type="primary" size="mini" icon="el-icon-edit" >修改</el-button> |
| </router-link> |
在api中
| |
| getTeacherById(id){ |
| return request({ |
| url:`/eduservice/teacher/getTeacher/${id}`, |
| method:'get', |
| }) |
| }, |
| |
| updateTeacherInfo(teacher){ |
| return request({ |
| url:`/eduservice/teacher/updateTeacher`, |
| method:'post', |
| data: teacher |
| }) |
| } |
在save.js中
| <script> |
| import teacherApi from '@/api/edu/teacher/teacher' |
| export default { |
| name:"save", |
| |
| data() { |
| return { |
| teacher:{ |
| name: '', |
| sort: 0, |
| level: 1, |
| career: '', |
| intro: '', |
| avatar: '' |
| }, |
| saveBtnDisabled:false |
| } |
| }, |
| |
| created() { |
| if(this.$route.params && this.$route.params.id){ |
| |
| const id =this.$route.params.id |
| this.getInfo(id) |
| } |
| }, |
| methods:{ |
| |
| |
| saveOrUpdate() { |
| if(!this.teacher.id){ |
| |
| this.saveTeacher() |
| } |
| else{ |
| |
| this.updateTeacher() |
| } |
| |
| }, |
| |
| saveTeacher(){ |
| teacherApi.addTeacher(this.teacher) |
| .then( |
| response => { |
| this.$message({ |
| type:'success', |
| message:'添加成功!' }); |
| |
| this.$router.push({path:'/teacher/table'}) |
| }) |
| }, |
| |
| getInfo(id){ |
| teacherApi.getTeacherById(id) |
| .then( |
| response =>{ |
| this.teacher = response.data.teacher |
| } |
| ) |
| .catch() |
| } |
| , |
| |
| updateTeacher(){ |
| teacherApi.updateTeacherInfo(this.teacher).then( |
| response=>{ |
| this.$message({ |
| type:'success', |
| message:'修改成功!' |
| }) |
| }, |
| this.$router.push({path:'/teacher/table'}) |
| ).catch() |
| } |
| } |
| } |
| </script> |
存在的bug
先修改后点击添加,数据还存在在页面中
应该清空数据
!! 多次路由跳转到同一个页面,create自会执行第一次
解决思路:
使用监听方法 watch
| watch:{ |
| |
| $route(to,from) { |
| |
| |
| clearData() |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?