一、Springboot项目开始前的准备工作
1、配置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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.1</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo9</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo9</name>
<description>demo9</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--MySQL驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.22</version>
</dependency>
<!--mybatis-plus启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
<!--代码生成模板-->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
<!-- 代码自动生成器依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.5.19</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.3.0.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2、编写application.yml
spring:
datasource:
url: 数据库路径
driver-class-name: com.mysql.cj.jdbc.Driver
username: 数据库的用户名
password: 数据库的密码
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #??sql??
global-config:
db-config:
#定义逻辑删除字段
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1
#配置端口
server:
port: 8088
servlet:
context-path: "/test"
files:
upload:
path: D:/fileupload
3、使用代码生成器
会根据实体类自动生成所对应的controller、mapper、service等代码结构。
package com.example.demo9;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
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.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
public class CodeGenerator {
public static void main(String[] args) {
// 需要构建一个 代码自动生成器 对象
AutoGenerator mpg = new AutoGenerator();
// 配置策略
// 1、全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("zyj");
gc.setOpen(false);
gc.setFileOverride(true); // 是否覆盖
//gc.setServiceName("%Service"); // 去Service的I前缀
gc.setIdType(IdType.ID_WORKER);
gc.setDateType(DateType.ONLY_DATE);
gc.setSwagger2(true);
mpg.setGlobalConfig(gc);
//2、设置数据源
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://192.168.10.46:3306/zyj?useSSL=false&serverTimezone=GMT%2B8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("ciic");
dsc.setPassword("ciic");
dsc.setDbType(DbType.MYSQL);
mpg.setDataSource(dsc);
//3、包的配置
PackageConfig pc = new PackageConfig();
pc.setModuleName("xmgl");
pc.setParent("com.example.demo9");
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
mpg.setPackageInfo(pc);
//4、策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("tb_department","tb_employee","tb_info"); // 设置要映射的表名 strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setTablePrefix("tb_");
strategy.setRestControllerStyle(true);
strategy.setVersionFieldName("version");
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setEntityLombokModel(true); // 自动lombok;
strategy.setLogicDeleteFieldName("deleted");
// 自动填充配置
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
// 乐观锁
strategy.setVersionFieldName("version");
strategy.setRestControllerStyle(true);
strategy.setControllerMappingHyphenStyle(true); //localhost:8080 / hello_id_2
mpg.setStrategy(strategy);
mpg.execute(); //执行
}
}
4、项目结构
二、开始搭建项目
1、model
即数据库的实体对象
Department:
package com.example.demo9.xmgl.model;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author zyj
* @since 2022-07-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("tb_department")
@ApiModel(value="Department对象", description="")
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "did", type = IdType.NONE)
private Integer did;
@TableField("dname")
private String dname;
@TableLogic
private Integer deleted;
}
Employee:
package com.example.demo9.xmgl.model;
import com.baomidou.mybatisplus.annotation.*;
import java.io.Serializable;
import io.swagger.annotations.ApiModel;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* <p>
*
* </p>
*
* @author zyj
* @since 2022-07-13
*/
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("tb_employee")
@ApiModel(value="Employee对象", description="")
public class Employee implements Serializable {
private static final long serialVersionUID = 1L;
public static Object selectPage;
@TableId(value = "eid", type = IdType.NONE)
private Integer eid;
@TableField("ename")
private String ename;
@TableField("salary")
private Integer salary;
@TableField("did")
private Integer did;
@TableLogic
private Integer deleted;
}
Files:
package com.example.demo9.xmgl.model;
import com.baomidou.mybatisplus.annotation.*;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serializable;
import java.sql.Date;
@Data
@TableName("files")
public class Files implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;//编号
private String filesName;//文件名称
private String type;//文件类型
private Double size;//文件大小
private String url;//下载链接
private String md5;//文件MD5
private Boolean enable;//链接是否可用(1:是 0:否)
@TableField(fill = FieldFill.INSERT)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;//创建时间
@TableField(fill = FieldFill.INSERT_UPDATE)
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime;//更新时间
@TableLogic()
private Integer isDelete;//是否删除(1:是 0:否)
}
2、VO和DTO
(1)VO(View Object)视图对象:我们输入输出类都是属于VO,用于表示一个与前端交互的java对象。
(2)DTO(Data Transfer Object)数据传输对象:前端调用时传输。通常用于不同服务或服务不同分层之间的数据传输。
(3)我的理解:DTO就是前端传给后端的数据,VO就是后端传给前端的数据。
DepartmentDto:
package com.example.demo9.xmgl.dto;
import com.example.demo9.xmgl.model.Department;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
//@Data提供类的get、set、equals、hashCode、canEqual、toString方法
@Data
@Setter
@Getter
public class DepartmentDto extends Department {
private Integer did;
private String dname;
}
EmployeeDto:
package com.example.demo9.xmgl.dto;
import com.baomidou.mybatisplus.annotation.TableField;
import com.example.demo9.xmgl.model.Employee;
import io.swagger.models.auth.In;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
@Data
@Setter
@Getter
public class EmployeeDto extends Employee {
private Integer eid;
private String ename;
private Integer salary;
private Integer did;
private List<Integer> eids;
}
PageDto:
package com.example.demo9.xmgl.dto;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
* 分页
*/
@Data
public class PageDto {
//当前页
private Integer currentPage;
//几条数据为一页
private Integer pageSize;
}
DepartmentVo:
package com.example.demo9.xmgl.vo;
import com.example.demo9.xmgl.model.Department;
import lombok.Data;
@Data
public class DepartmentVo {
private Integer did;
private String dname;
}
Employee:
package com.example.demo9.xmgl.vo;
import com.baomidou.mybatisplus.annotation.TableField;
import com.example.demo9.xmgl.model.Employee;
import lombok.Data;
@Data
public class EmployeeVo {
private Integer eid;
private String ename;
private Integer salary;
private Integer did;
}
PageVo:
package com.example.demo9.xmgl.vo;
import lombok.Data;
import java.util.List;
@Data
public class PageVo {
List<EmployeeVo> data;
private Integer total;
}
3、Mapper
@Mapper
public interface DepartmentMapper extends BaseMapper<Department> {
}
@Mapper
public interface EmployeeMapper extends BaseMapper<Employee> {
}
@Mapper
public interface FilesMapper extends BaseMapper<Files> {
}
4、Controller
@PathVariable : 映射 URL 绑定的占位符。
@RequestParam : 这个注解是用于后端接收数据的。接收的参数是来自 requestHeader 中,即请求头。
@RequestBody :这个注解也是用于后端接收数据的。接收的参数是来自 requestBody 中,即请求体。
DepartmentController:
package com.example.demo9.xmgl.controller;
import com.example.demo9.xmgl.dto.DepartmentDto;
import com.example.demo9.xmgl.model.Employee;
import com.example.demo9.xmgl.service.IDepartmentService;
import com.example.demo9.xmgl.vo.DepartmentVo;
import com.example.demo9.xmgl.vo.EmployeeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 前端控制器
* </p>
*
* @author zyj
* @since 2022-07-13
*/
@RestController
@RequestMapping("/department")
public class DepartmentController {
@Autowired
private IDepartmentService departmentService;
@PostMapping("/findAllDep")
@ResponseBody
public Object findAllDep(){
//查询所有部门
try {
return departmentService.findAllDep();
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/createDep")
public Object adddep(@RequestBody DepartmentDto departmentDto){
//新增部门
try{
departmentService.addDep(departmentDto);
return "添加部门成功";
}catch (Exception exception){
return exception.getMessage();
}
}
@PostMapping("/deleteDep")
public Object deleteDep(@RequestBody DepartmentDto departmentDto){
//删除部门
try {
departmentService.deleteDep(departmentDto);
return "删除部门成功";
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/updateDep")
public Object updatedep(@RequestBody DepartmentDto departmentDto){
//编辑部门
try {
departmentService.updateDep(departmentDto);
return "编辑部门成功";
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/getDep")
@ResponseBody
public Object getDep(@RequestBody DepartmentDto departmentDto){
//查询部门
try {
DepartmentVo departmentVo;
departmentVo= (DepartmentVo) departmentService.getDep(departmentDto);
return departmentVo;
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/getEid")
public Object getEid(@RequestBody DepartmentDto departmentDto){
//获取部门中的员工
try {
List<EmployeeVo> employeeVoList = (List<EmployeeVo>) departmentService.getEid(departmentDto);
return employeeVoList;
} catch (Exception e) {
return e.getMessage();
}
}
}
EmployeeController:
package com.example.demo9.xmgl.controller;
import com.example.demo9.xmgl.dto.EmployeeDto;
import com.example.demo9.xmgl.dto.PageDto;
import com.example.demo9.xmgl.service.IEmployeeService;
import com.example.demo9.xmgl.vo.EmployeeVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Map;
/**
* <p>
* 前端控制器
* </p>
*
* @author zyj
* @since 2022-07-13
*/
@RestController
@RequestMapping("/employee")
public class EmployeeController {
@Autowired
private IEmployeeService employeeService;
@PostMapping("/createEmp")
@ResponseBody
public Object createEmp(@RequestBody EmployeeDto employeeDto) {
//添加员工
try {
employeeService.addEmp(employeeDto);
return "添加员工成功";
} catch (Exception exception) {
return exception.getMessage();
}
}
@PostMapping("/deleteEmp")
@ResponseBody
public Object deleteEmp(@RequestBody Map<String,String> map ) {
//删除员工
try {
employeeService.deleteEmp(Integer.parseInt(map.get("eid")));
return "员工删除成功";
} catch (Exception e) {
return e.getMessage();
}
}
/**
* 批量删除
* @param
* @return
*/
@PostMapping("/deleteBatch")
@ResponseBody
public Object deleteBatch(@RequestBody Map<String, List<Integer>> map){
try{
employeeService.deleteEmps(map.get("eids"));
return "批量删除成功";
}catch (Exception e){
return e.getMessage();
}
}
@PostMapping("/updateEmp")
@ResponseBody
public Object updateEmp(@RequestBody EmployeeDto employeeDto) {
//编辑员工
try {
employeeService.updateEmp(employeeDto);
return "编辑员工成功";
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/getEmp")
@ResponseBody
public Object getEmp(@RequestBody EmployeeDto employeeDto) {
//查询员工
try {
EmployeeVo employeeVo;
employeeVo = (EmployeeVo) employeeService.getEmp(employeeDto);
return employeeVo;
} catch (Exception e) {
return e.getMessage();
}
}
@PostMapping("/getEmpByEname")
@ResponseBody
public Object getEmpByEname(@RequestBody EmployeeDto employeeDto){
try {
return employeeService.getEmpByEname(employeeDto);
}catch (Exception e){
return e.getMessage();
}
}
@PostMapping("/findAllEmp")
@ResponseBody
public Object findAllEmp(@RequestBody PageDto pageDto) {
//查询所有员工
try {
return employeeService.findAllEmp(pageDto);
} catch (Exception e) {
return e.getMessage();
}
}
}
FilesController:
package com.example.demo9.xmgl.controller;
import com.example.demo9.xmgl.service.IFilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
@RestController
@RequestMapping("/files")
public class FilesController {
@Autowired
private IFilesService filesService;
@PostMapping("/upload")
public Object upload(@RequestParam MultipartFile file) {
//获取上传文件
try {
String url = filesService.upload(file);
return "上传文件成功";
}catch (Exception e){
return e.getMessage();
}
//return Result.ok(url);
}
@GetMapping("/{filesUUID}")
public void download(@PathVariable String filesUUID, HttpServletResponse response) {
//下载文件
filesService.download(filesUUID, response);
}
}
5、service
(1)接口类
IDepartmentService:
package com.example.demo9.xmgl.service;
import com.example.demo9.xmgl.dto.DepartmentDto;
import com.example.demo9.xmgl.model.Department;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.demo9.xmgl.vo.DepartmentVo;
/**
* <p>
* 服务类
* </p>
*
* @author zyj
* @since 2022-07-13
*/
public interface IDepartmentService {
//查询所有部门
Object findAllDep();
//新增部门
void addDep(DepartmentDto departmentDto) throws Exception;
//删除部门
void deleteDep(DepartmentDto departmentDto) throws Exception;
//编辑部门
void updateDep(DepartmentDto departmentDto) throws Exception;
//查询部门
Object getDep(DepartmentDto departmentDto) throws Exception;
//通过部门查询员工
Object getEid(DepartmentDto departmentDto) throws Exception;
}
IEmployeeService:
package com.example.demo9.xmgl.service;
import com.example.demo9.xmgl.dto.DepartmentDto;
import com.example.demo9.xmgl.dto.EmployeeDto;
import java.util.List;
/**
* <p>
* 服务类
* </p>
*
* @author zyj
* @since 2022-07-13
*/
public interface IEmployeeService{
/**
* 查询所有员工
* @param pageDto
* @return
*/
Object findAllEmp(com.example.demo9.xmgl.dto.PageDto pageDto);
/**
* 新增员工
* @param employeeDto
* @throws Exception
*/
void addEmp(EmployeeDto employeeDto) throws Exception;
/**
* 删除员工
* @param eid
* @throws Exception
*/
void deleteEmp(int eid) throws Exception;
/**
* 批量删除员工
* @param eids
* @throws Exception
*/
void deleteEmps(List<Integer> eids) throws Exception;
/**
* 编辑员工
* @param employeeDto
* @throws Exception
*/
void updateEmp(EmployeeDto employeeDto) throws Exception;
/**
* 查询员工
* @param employeeDto
* @return
* @throws Exception
*/
Object getEmp(EmployeeDto employeeDto) throws Exception;
/**
* 通过部门ID查询员工
* @param employeeDto
* @return
* @throws Exception
*/
Object getEmpByEname(EmployeeDto employeeDto) throws Exception;
}
(2)具体实现类
DepartmentServiceImpl:
package com.example.demo9.xmgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.demo9.xmgl.dto.DepartmentDto;
import com.example.demo9.xmgl.mapper.EmployeeMapper;
import com.example.demo9.xmgl.mapper.DepartmentMapper;
import com.example.demo9.xmgl.model.Department;
import com.example.demo9.xmgl.model.Employee;
import com.example.demo9.xmgl.service.IDepartmentService;
import com.example.demo9.xmgl.vo.DepartmentVo;
import com.example.demo9.xmgl.vo.EmployeeVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author zyj
* @since 2022-07-13
*/
@Service
public class DepartmentServiceImpl implements IDepartmentService {
@Autowired
private DepartmentMapper departmentMapper;
@Autowired
private EmployeeMapper employeeMapper;
/* private DepartmentDto departmentDto;
private DepartmentVo departmentVo;*/
@Override
public Object findAllDep() {
System.out.println("--查询所有部门--");
List<Department> departmentList=departmentMapper.selectList(null);
List<DepartmentVo> departmentVoList=new ArrayList<>();
for(Department department:departmentList){
DepartmentVo departmentVo=new DepartmentVo();
BeanUtils.copyProperties(department,departmentVo);
departmentVoList.add(departmentVo);
}
return departmentVoList;
}
@Override
public void addDep(DepartmentDto departmentDto) throws Exception {
System.out.println("--新增部门--");
DepartmentVo departmentVo=new DepartmentVo();
if (departmentMapper.selectById(departmentDto.getDid()) != null) {
throw new Exception("该部门已存在");
} else {
departmentMapper.insert(departmentDto);
}
}
@Override
public void deleteDep(DepartmentDto departmentDto) throws Exception {
System.out.println("--根据部门ID删除部门--");
if (departmentMapper.selectById(departmentDto.getDid()) != null) {
departmentMapper.deleteById(departmentDto.getDid());
//将该部门中的所有员工进行删除
LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Employee::getDid, departmentDto.getDid());
employeeMapper.delete(lambdaQueryWrapper);
} else {
throw new Exception("该部门不存在");
}
}
@Override
public void updateDep(DepartmentDto departmentDto) throws Exception {
System.out.println("--编辑部门--");
if (departmentMapper.selectById(departmentDto.getDid()) != null) {
departmentMapper.updateById(departmentDto);
} else {
throw new Exception("该部门不存在");
}
}
@Override
public Object getDep(DepartmentDto departmentDto) throws Exception {
System.out.println("--通过部门ID查询部门--");
DepartmentVo departmentVo= new DepartmentVo();
if (departmentMapper.selectById(departmentDto.getDid()) != null) {
Department department=departmentMapper.selectById(departmentDto.getDid());
BeanUtils.copyProperties(department,departmentVo);
return departmentVo;
} else {
throw new Exception("部门不存在");
}
}
@Override
public Object getEid(DepartmentDto departmentDto) throws Exception {
System.out.println("--该部门下的所有员工--");
if(departmentMapper.selectById(departmentDto.getDid()) != null){
departmentMapper.selectById(departmentDto.getDid());
LambdaQueryWrapper<Employee> lambdaQueryWrapper = new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Employee::getDid, departmentDto.getDid());
List<Employee> employeeList = employeeMapper.selectList(lambdaQueryWrapper);
List<EmployeeVo> employeeVoList=new ArrayList<>();
for (Employee employee:employeeList){
EmployeeVo employeeVo=new EmployeeVo();
BeanUtils.copyProperties(employee,employeeVo);
employeeVoList.add(employeeVo);
}
return employeeVoList;
}else
{
throw new Exception("该部门不存在");
}
}
}
EmployeeServiceImpl:
package com.example.demo9.xmgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo9.xmgl.dto.DepartmentDto;
import com.example.demo9.xmgl.dto.EmployeeDto;
import com.example.demo9.xmgl.mapper.DepartmentMapper;
import com.example.demo9.xmgl.model.Department;
import com.example.demo9.xmgl.model.Employee;
import com.example.demo9.xmgl.mapper.EmployeeMapper;
import com.example.demo9.xmgl.service.IEmployeeService;
import com.example.demo9.xmgl.vo.DepartmentVo;
import com.example.demo9.xmgl.vo.EmployeeVo;
import com.example.demo9.xmgl.vo.PageVo;
import io.swagger.models.auth.In;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* <p>
* 服务实现类
* </p>
*
* @author zyj
* @since 2022-07-13
*/
@Service
public class EmployeeServiceImpl implements IEmployeeService{
@Autowired
private EmployeeMapper employeeMapper;
@Autowired
private DepartmentMapper departmentMapper;
private Employee employee;
/**
* 查询所有员工
* @param pageDto
* @return
*/
@Override
public Object findAllEmp(com.example.demo9.xmgl.dto.PageDto pageDto) {
System.out.println("--查询所有员工--");
IPage<Employee> iPage=new Page(pageDto.getCurrentPage(), pageDto.getPageSize());
IPage<Employee> employeeIPage=employeeMapper.selectPage(iPage,null);
PageVo pageVo=new PageVo();
List<EmployeeVo> employeeVoList=new ArrayList<>();
for(Employee employee:employeeIPage.getRecords()){
EmployeeVo employeeVo=new EmployeeVo();
BeanUtils.copyProperties(employee,employeeVo);
employeeVoList.add(employeeVo);
}
// List<Employee> employeeList=employeeMapper.selectList(null);
// List<EmployeeVo> employeeVoList=new ArrayList<>();
// for(Employee employee:employeeList){
// EmployeeVo employeeVo=new EmployeeVo();
// BeanUtils.copyProperties(employee,employeeVo);
// employeeVoList.add(employeeVo);
// }
pageVo.setData(employeeVoList);
pageVo.setTotal((int) employeeIPage.getTotal());
return pageVo;
}
/**
* 新增员工
* @param employeeDto
* @throws Exception
*/
@Override
public void addEmp(EmployeeDto employeeDto) throws Exception {
System.out.println("--新增员工--");
if(employeeMapper.selectById(employeeDto.getEid())!=null){
throw new Exception("该员工已存在");
}else {
if(departmentMapper.selectById(employeeDto.getDid())!=null){
employeeMapper.insert(employeeDto);
}else {
throw new Exception("该部门不存在无法添加");
}
}
}
/**
* 删除员工
* @param eid
* @throws Exception
*/
@Override
public void deleteEmp(int eid) throws Exception {
System.out.println("--删除员工--");
if (employeeMapper.selectById(eid) != null) {
employeeMapper.deleteById(eid);
} else {
throw new Exception(eid+"员工不存在");
}
}
/**
* 批量删除员工
* @param
* @throws Exception
*/
@Override
@Transactional(rollbackFor=Exception.class)
/**
* @Transactional注解只能应用到public方法或者类上才有效
* 加入 @transactional 注解,抛出异常之后,事务会自动回滚,数据不会插入到数据库中。
* rollbackFor 属性 用于指定能够触发事务回滚的异常类型,可以指定多个异常类型。
*/
public void deleteEmps(List<Integer> eids) throws Exception {
if(!eids.isEmpty()){
for(int i = 0; i < eids.size(); i++){
System.out.println(eids.get(i));
deleteEmp(eids.get(i));
}
}else{
throw new Exception("员工不存在");
}
}
/**
* 编辑员工
*
* @param employeeDto
* @throws Exception
*/
@Override
public void updateEmp(EmployeeDto employeeDto) throws Exception {
System.out.println("--编辑员工--");
if (employeeMapper.selectById(employeeDto.getEid()) == null) {
throw new Exception("该员工不存在");
}
if(departmentMapper.selectById(employeeDto.getDid()) == null){
throw new Exception("该部门不存在,无法编辑");
}
employeeMapper.updateById(employeeDto);
// if (employeeMapper.selectById(employeeDto.getEid()) != null) {
// if(employeeDto.getDid()!=null){
// if(departmentMapper.selectById(employeeDto.getDid())!=null){
// employeeMapper.updateById(employeeDto);
// }else {
// throw new Exception("该部门不存在,无法编辑");
// }
// }else {
// employeeMapper.updateById(employeeDto);
// }
// } else {
// throw new Exception("该员工不存在");
// }
}
@Override
public Object getEmp(EmployeeDto employeeDto) throws Exception {
System.out.println("--根据员工ID获取员工信息--");
EmployeeVo employeeVo=new EmployeeVo();
if (employeeMapper.selectById(employeeDto.getEid()) != null) {
Employee employee= employeeMapper.selectById(employeeDto.getEid());
BeanUtils.copyProperties(employee,employeeVo);
return employeeVo;
} else {
throw new Exception("该员工不存在");
}
}
/**
* 根据员工姓名获取员工
* @param employeeDto
* @return
* @throws Exception
*/
@Override
public Object getEmpByEname(EmployeeDto employeeDto) throws Exception {
LambdaQueryWrapper<Employee> lambdaQueryWrapper=new LambdaQueryWrapper<>();
lambdaQueryWrapper.eq(Employee::getEname,employeeDto.getEname());
List<Employee> employeeList=employeeMapper.selectList(lambdaQueryWrapper);
List<EmployeeVo> employeeVoList=new ArrayList<>();
if(employeeMapper.selectList(lambdaQueryWrapper)!=null){
for(Employee employee : employeeList){
EmployeeVo employeeVo=new EmployeeVo();
BeanUtils.copyProperties(employee,employeeVo);
employeeVoList.add(employeeVo);
}
return employeeVoList;
}else {
throw new Exception("该员工不存在");
}
}
}
FilesService:
package com.example.demo9.xmgl.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.demo9.xmgl.mapper.FilesMapper;
import com.example.demo9.xmgl.model.Files;
import com.example.demo9.xmgl.service.IFilesService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;
@Service
public class FilesServiceImpl implements IFilesService {
@Value("${files.upload.path}")
private String filesUploadPath; //获取文件路径
@Autowired
private FilesMapper filesMapper;
@Override
public String upload(MultipartFile file) {
//将相对路径转化为绝对路径
String destPath = new File(filesUploadPath).getAbsolutePath();
//文件夹路径名称,原始文件名
String originalFilename = file.getOriginalFilename();
//文件大小
double size = file.getSize();
//文件类型,获取文件后缀名
String type = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
//使用uuid生成随机唯一值,防止文件名称重复造成文件覆盖
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
//新的文件名称,uuid+文件类型
String fileUuid = uuid + "." + type;
//新的文件地址,绝对路径+新的文件名称
File uploadFile = new File(destPath + "/" + fileUuid);
//判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
File parentFile = uploadFile.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
try {
String url;
//获取文件的md5,通过对比文件md5,防止上传相同内容的文件
String md5 = DigestUtils.md5DigestAsHex(file.getInputStream());
//通过MD5来查询文件
Files dbFiles = this.getFileByMD5(md5);
if (dbFiles != null) {//如果数据库存在相同文件,直接获取url
url = dbFiles.getUrl();
} else {//如果数据库不存在相同文件,先存储到本地磁盘,再设置文件url
file.transferTo(uploadFile);//把获取到的文件存储带磁盘目录
url = "http://localhost:8080/files/" + fileUuid;//设置文件url
}
//将文件存储到数据库
Files saveFile = new Files();
saveFile.setFilesName(originalFilename);
saveFile.setType(type);
saveFile.setSize(size / 1024);//(单位:KB)
saveFile.setUrl(url);
saveFile.setMd5(md5);
//保存操作
filesMapper.insert(saveFile);
//返回文件下载路径url
return url;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
//将文件以流的形式一次性读取到内存,通过响应输出流输出到前端
@Override
public void download(String filesUUID, HttpServletResponse response) {
try {
//根据文件的唯一标识码获取文件
File uploadFile = new File(filesUploadPath + filesUUID);
//读取文件的字节流
FileInputStream fileInputStream = new FileInputStream(uploadFile);
//将文件写入输入流
InputStream inputStream = new BufferedInputStream(fileInputStream);
byte[] buffer = new byte[inputStream.available()];
inputStream.read(buffer);
inputStream.close();
//attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.png"
//filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filesUUID, "UTF-8"));
response.setContentType("application/octet-stream");
//设置输出流的格式
ServletOutputStream os = response.getOutputStream();
os.write(buffer);
//关闭
fileInputStream.close();
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
//通过文件MD5查询文件
private Files getFileByMD5(String md5) {
//查找数据库是否已经存在一样的图片
QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("md5", md5);
List<Files> filesList = filesMapper.selectList(queryWrapper);
return filesList.size() == 0 ? null : filesList.get(0);
}
}
二、搭建Vue项目
1、使用axios实现跨域
module.exports=({
publicPath: process.env.NODE_ENV === 'production' ? '/kuaChengTongBan/' : '/',
//outputDir: 'kuaChengTongBan', // 更改打包路径,项目默认的路径是dist
// 请求代理
devServer: {
proxy: {
//广州市海珠区
'/test': {//'/ApprItemInterface'是接口部署的包名
target: 'http://localhost:8088',//该包名部署的端口(后端)
ws: true,
changeOrigin: true
},
}
},
// 生产环境下的sourceMap
productionSourceMap: true,
chainWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 为生产环境修改配置...s
config
.externals({
'vue': 'Vue',
'vue-router': 'VueRouter'
})
} else {
// 为开发环境修改配置...
}
},
lintOnSave:false
})
2、package.json配置文件
{
"name": "demo6",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@element-plus/icons-vue": "^2.0.6",
"axios": "^0.27.2",
"core-js": "^3.8.3",
"element-plus": "^2.2.11",
"vue": "^3.2.13",
"vue-router": "^4.1.3"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"eslint": "^7.32.0",
"eslint-plugin-vue": "^8.0.3",
"less": "^4.1.3",
"less-loader": "^11.0.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}
3、App.vue
<template>
<EmployeeTable></EmployeeTable>
</template>
<script setup>
import EmployeeTable from "./components/EmployeeTable.vue";
</script>
4、各个组件的实现
EmployeeTable.vue
<template>
<div class="common-layout">
<el-container>
<el-header style="color: #409eff">
<h1 align="center">员工管理系统</h1>
</el-header>
<el-main>
<!-- 点击查询会出现的弹窗 -->
<el-drawer
v-model="drawer"
:with-header="true"
:close-on-click-modal="false"
>
<span>
<!-- 弹窗中的表单 -->
<el-form label-width="100px">
<el-form-item label="员工ID:">
{{ getemp.eid }}
</el-form-item>
<el-form-item label="员工姓名:">
{{ getemp.ename }}
</el-form-item>
<el-form-item label="薪资:">
{{ getemp.salary }}
</el-form-item>
<el-form-item label="部门ID:">
{{ getemp.did }}
</el-form-item>
</el-form>
</span>
</el-drawer>
<!-- 存放数据的表格 -->
<el-row>
<el-col :span="5"></el-col>
<el-col :span="14">
<div
style="
display: flex;
width: 100%;
justify-content: space-between;
align-items: center;
"
>
<div>
<el-button @click="addEmp()" ><el-icon><Plus /></el-icon>新增</el-button>
<el-button @click="deleteBatch()" :icon="Delete">批量删除</el-button>
</div>
<div style="display: flex">
<el-select
v-model="value"
placeholder="查询条件"
@change="selectChange"
>
<el-option
v-for="item in selectValue"
:key="item.value"
:label="item.label"
:value="item.value"
></el-option>
</el-select>
<el-input
placeholder="请输入"
v-model="inputValue"
:prefix-icon="Search"
clearable
></el-input>
<el-button @click="getID(inputValue)" :icon="Search"
>查询</el-button
>
</div>
</div>
<!-- Config Provider配置语言 -->
<el-config-provider :locale="locale">
<!--在列中设置 sortable 属性即可实现以该列为基准的排序, Table 的 default-sort 属性设置默认的排序列和排序顺序 -->
<!--在列中设置 filters 和 filter-method 属性即可开启该列的筛选, filters 是一个数组,filter-method 是一个方法,它用于决定某些数据是否显示, 会传入三个参数:value, row和column。 -->
<el-table
ref="tableRef"
@selection-change="handleSelectionChange"
:data="emps"
:default-sort="{ prop: 'eid', order: 'ascending' }"
:header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }"
v-loading="loading"
stripe
border
>
<el-table-column type="selection"> </el-table-column>
<el-table-column
label="员工ID"
prop="eid"
width="150"
align="center"
sortable
></el-table-column>
<el-table-column
label="员工姓名"
prop="ename"
width="150"
align="center"
></el-table-column>
<el-table-column
label="薪资"
prop="salary"
width="150"
align="center"
></el-table-column>
<el-table-column
label="部门ID"
prop="did"
width="150"
align="center"
:filters="[
{ text: 1001, value: 1001 },
{ text: 1002, value: 1002 },
{ text: 1003, value: 1003 },
]"
:filter-method="filterDid"
></el-table-column>
<el-table-column label="操作" align="center">
<template #default="scope">
<el-button @click="editEmp(scope.row)" :icon="Edit"
>编辑</el-button
>
<!-- 气泡确认框提示删除 -->
<el-popconfirm
confirm-button-text="删除"
cancel-button-text="取消"
:icon="InfoFilled"
title="确定删除此数据?"
@confirm="confirmEvent(scope.row)"
@cancel="cancelEvent"
>
<template #reference>
<el-button :icon="Delete">删除</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
<!-- page-size每页显示条目个数;total总条目数;layout组件布局,total总数,prev上一页,next下一页,pager页码列表,jumper跳页 -->
<!-- size-change为page-size改变时触发,current-change为current-page改变时触发 -->
<el-pagination
layout="total,sizes,prev,pager,next,jumper"
v-model:currentPage="currentPage"
v-model:page-size="pageSize"
:page-sizes="[1, 2, 3, 4, 5, 8]"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
>
</el-pagination>
</el-config-provider>
</el-col>
<el-col :span="5"></el-col>
</el-row>
</el-main>
</el-container>
<!-- 点击编辑或者新增按钮出现的对话框 -->
<el-dialog
:title="operateType === 'add' ? '新增员工' : '编辑员工'"
v-model="dialogVisible"
:close-on-click-modal="false"
width="20%"
center
>
<CommonFrom
:emp="operateEmp"
:operateTypes="operateType"
ref="commRef"
></CommonFrom>
<template #footer>
<span class="dialog-footer">
<el-button @click="(dialogVisible = false), (loading = false)"
>取消</el-button
>
<el-button type="primary" @click="confirm">确定</el-button>
</span>
</template>
</el-dialog>
</div>
<div>
<FileUpload></FileUpload>
</div>
</template>
<script setup>
//不要变量名重复使用,都使用getemp.value就要将getemp定义为const getemp=ref({})
//引入axios
import http from "axios";
import CommonFrom from "./CommonForm.vue";
import { ref, onMounted, reactive, computed } from "vue";
import { InfoFilled, Search, Edit, Delete } from "@element-plus/icons-vue";
import zhCn from "element-plus/dist/locale/zh-cn.mjs";
import en from "element-plus/dist/locale/en.mjs";
//import { column } from "element-plus/es/components/table-v2/src/common";
import FileUpload from "./FileUpload.vue";
//import { ta } from "element-plus/es/locale";
import { ElTable } from "element-plus";
// import { FormInstance, FormRules } from "element-plus";
//定义表格中的数据
const emps = ref([]);
//定义操作表格数据
const operateEmp = ref({});
//定义获取CommonFrom组件中的数据
const commRef = ref(null);
//定义抽屉的弹出
const drawer = ref(false);
//定义对话框的弹出
const dialogVisible = ref(false);
//定义对话框中的标签,初始化定义为新增add
const operateType = ref("add");
//查询输入框中的值
const inputValue = ref();
//定义表单传过来的数据
const getemp = ref([]);
//定义当前页
const currentPage = ref(1);
//初始状态下一页当中有几条数据
const pageSize = ref(5);
//总共几条数据
const total = ref();
//定义表格中多选表单数据
const multipleSelection = ref();
//出现弹窗之后,表格呈现加载
const loading = ref(false);
const tableRef = ref();
//配置语言
const language = ref("zh-cn");
const locale = computed(() => (language.value === "zh-cn" ? zhCn : en));
const toggle = () => {
language.value = language.value === "zh-cn" ? "en" : "zh-cn";
};
//表格中的多选
const handleSelectionChange = (val) => {
multipleSelection.value = val;
};
//批量删除
const deleteBatch = () => {
//getSelectionRows是table中的一个方法,getSelectionRows返回当前选中的行
const deleteRow = tableRef.value.getSelectionRows();
console.log(deleteRow);
//将要删除的员工ID定义为一个数组
const deleteEid = ref([]);
//遍历选中的当前行,获取员工ID
for (let i = 0; i < deleteRow.length; i++) {
deleteEid.value.push(deleteRow[i].eid);
}
console.log(deleteEid.value);
http
.post("employee/deleteBatch", { eids: deleteEid.value })
.then((r) => {
console.log(r);
})
.catch((e) => {
console.log(e);
});
init();
};
//通过部门ID筛选表格数据
const filterDid = (value, row, column) => {
const property = column["property"];
return row[property] === value;
};
//配置查询条件多选框
const value = ref("");
const selectValue = [
{
value: 1,
label: "员工ID",
},
{
value: 2,
label: "员工姓名",
},
];
//配置路径
http.defaults.baseURL = "/test";
onMounted(() => {
http
.post("employee/findAllEmp", {
currentPage: currentPage.value,
pageSize: pageSize.value,
})
.then((r) => {
console.log(r);
emps.value = r.data.data;
total.value = r.data.total;
})
.catch((e) => {
console.log(e);
alert(e);
});
});
//刷新数据
const init = () => {
http
.post("employee/findAllEmp", {
currentPage: currentPage.value,
pageSize: pageSize.value,
})
.then((r) => {
console.log(r);
emps.value = r.data.data;
total.value = r.data.total;
})
.catch((e) => {
console.log(e);
alert(e);
});
};
init();
/**
* 改变每页的数据数
* @param {*} val
*/
const handleSizeChange = (val) => {
pageSize.value = val;
console.log(val);
init();
};
/**
* 改变当前页
*/
const handleCurrentChange = (val) => {
currentPage.value = val;
console.log(val);
init();
};
//切换查询条件
const val = ref();
const selectChange = (selectVal) => {
val.value = selectVal;
console.log(val);
};
//根据员工ID或者员工姓名进行查询
const getID = (inputValue) => {
if (val.value == 1) {
// 根据员工ID进行查询
http
.post("employee/getEmp", { eid: inputValue })
.then((r) => {
console.log(r.data);
getemp.value = r.data;
drawer.value = true;
})
.catch((e) => {
console.log(e);
alert(e);
});
} else {
//根据员工姓名进行查询
http
.post("employee/getEmpByEname", { ename: inputValue })
.then((r) => {
console.log(r.data);
getemp.value = r.data[0];
drawer.value = true;
})
.catch((e) => {
console.log(e);
alert(e);
});
}
};
//触发新增
const addEmp = () => {
dialogVisible.value = true;
loading.value = true;
operateType.value = "add";
operateEmp.value = {
eid: "",
ename: "",
salary: "",
did: "",
};
};
//触发编辑
const editEmp = (item) => {
dialogVisible.value = true;
loading.value = true;
operateType.value = "edit";
operateEmp.value = JSON.parse(JSON.stringify(item));
};
//实现对话框确定按钮
const confirm = () => {
//对表单输入的值进行校验
//validate方法,对整个表单的内容进行验证
commRef.value.ruleFormRef.validate((valid) => {
if (valid) {
if (operateType.value === "add") {
//调用新增接口
dialogVisible.value = false;
loading.value = false;
console.log("=======");
console.log(operateEmp.value);
emps.value.push(operateEmp.value);
http
.post("employee/createEmp", operateEmp.value)
.then((r) => {
console.log(r);
})
.catch((e) => {
console.log(e);
alert(e);
});
init();
} else {
//调用编辑接口
dialogVisible.value = false;
loading.value = false;
console.log("+++");
console.log(operateEmp.value);
//调用后端的编辑方法
http
.post("employee/updateEmp", operateEmp.value)
.then((r) => {
console.log(r);
})
.catch((e) => {
console.log(e);
alert(e);
});
init();
}
}
});
};
//删除操作,点击二次删除的删除操作
const confirmEvent = (item) => {
//返回某个指定的字符串值在字符串中首次出现的位置。
const index = emps.value.indexOf(item);
console.log(index);
if (index > -1) {
emps.value.splice(index, 1);
}
//调用后端的删除方法
http
.post("employee/deleteEmp", item)
.then((r) => {
console.log(r);
})
.catch((e) => {
console.log(e);
alert(e);
});
};
//二次删除中的取消操作
const cancelEvent = () => {
console.log("取消删除");
};
</script>
<style lang="less" scoped>
.common-layout {
height: calc(100% - 62px);
background-color: #fff;
position: relative;
.pager {
position: absolute;
bottom: 0;
right: 20px;
}
}
</style>
CommonForm.vue
<template>
<el-form label-width="100px" ref="ruleFormRef" :rules="rules" :model="emp">
<el-form-item label="员工ID:" prop="eid">
<el-input
type="number"
placeholder="员工ID"
style="width: fit-content"
v-model="emp.eid"
v-if="operateTypes == 'add'"
clearable
></el-input>
<span v-else>{{ emp.eid }}</span>
</el-form-item>
<el-form-item label="员工姓名:" prop="ename">
<el-input
type="text"
placeholder="员工姓名"
style="width: fit-content"
v-model="emp.ename"
clearable
></el-input>
</el-form-item>
<el-form-item label="薪资:" prop="salary">
<el-input
style="width: fit-content"
v-model.number="emp.salary"
clearable
></el-input>
</el-form-item>
<el-form-item label="部门ID:" prop="did">
<el-select v-model="emp.did" placeholder="选择部门">
<el-option label="1001" value="1001"></el-option>
<el-option label="1002" value="1002"></el-option>
<el-option label="1003" value="1003"></el-option>
</el-select>
<!-- <el-input type="text" style="width: fit-content" v-model="emp.did"></el-input> -->
</el-form-item>
</el-form>
</template>
<script setup>
// defineProps用于组件通信中父组件给子组件传值,其用来声明props,其接收值为props选项相同的值
// defineEmits用于组件通信中子级组件向父级组件传值,其用来声明emit,其接收内容于emit选项一致
// defineExpose组件暴露自己的属性以及方法,去供外部使用,常用于父子组件关系
import { defineProps, reactive,ref,defineExpose } from "vue";
const formSize = ref('default')
const ruleFormRef = ref(null)
const validateEid=(rule,value,callback)=>{
if(value===''){
callback(new Error('请输入员工ID'))
}
//setTimeout定时执行,是设置一个时间,等待时间到达的时候只执行一次,但是执行完以后定时器还在,只是没有运行
//setTimeout(方法名或方法, 延时); 第一个参数为方法名或者方法,注意为方法名的时候不要加括号,第二个参数为时间间隔
setTimeout(()=>{
if(Number(value)<100){
callback(new Error('输入的员工ID不符合格式'))
}else if(Number(value)>200){
callback(new Error('输入的员工ID不符合格式'))
}else{
callback()
}
},1000)
}
const validateEname=(rule,value,callback)=>{
if(value===''){
callback(new Error('请输入员工姓名'))
}else{
callback()
}
}
const validateSalary=(rule,value,callback)=>{
setTimeout(()=>{
if(!Number.isInteger(value)){
callback(new Error('请输入数字'))
}else{
callback()
}
})
}
const validateDid=(rule,value,callback)=>{
if(value===''){
callback(new Error('请输入员工ID'))
}
else{
callback()
}
}
const rules=reactive({
eid:[
{
validator:validateEid,
required:true,
trigger:'blur'
}
],
ename:[
{
validator:validateEname,
required:true,
trigger:'blur'
},
{
min:2,
max:10,
message:'员工姓名必须在2-10个字符'
}
],
salary:[
{
validator:validateSalary,
required:true,
trigger:'blur'
}
],
did:[
{
validator:validateDid,
required:true,
trigger:'change'
}
]
})
const formRule=()=>{
ruleFormRef.value.validate()
}
defineExpose({rules,ruleFormRef})
const props = defineProps({
emp: Object,
operateTypes:String
});
</script>
FileUpload.vue
<template>
<div>
<el-upload
action="http://localhost:8080/test/files/upload"
v-model:file-list="fileList"
:show-file-list="true"
multiple
:on-success="handleUploadSuccess"
:limit="3"
:on-change="handleChange"
style="display: inline-block"
>
<template #trigger>
<el-button type="primary">上传</el-button>
</template>
<template>
<el-button type="primary" icon="el-icon-download" @click="download">下载</el-button>
</template>
</el-upload>
</div>
</template>
<script setup>
import { ElMessage } from "element-plus";
import http from 'axios'
import { ref } from "vue";
const handleUploadSuccess = (res) => {
ElMessage({
message: "上传文件成功",
type: "success",
});
console.log(res);
};
const download=()=>{
http.post("/test/files/{filesUUID}",{filesUUID}).then((r)=>{
console.log(r);
}).catch((e)=>{
console.log(e);
})
}
const handleChange = (uploadFile, uploadFiles) => {};
</script>