#员工管理系统
1.项目准备
- 需求分析 模块 功能
- 库表设计 数据库
- 详细设计 流程图伪代码方式(没用上)
- 编码环节
环境准备
正式进入编码环节
- 测试
- 部署上线
2.技术选项
- 前端:vue + axios
- 后端:springboot + mybatis + mysql + tomcat
3.需求分析
###开始
1.创建数据库表
create table t_user(
id int(6) primary key auto_increment,
username varchar(60),
realname varchar(60),
password varchar(50),
sex varchar(4),
status varchar(4),
regsterTime timestamp
);
create table t_emp(
id int(6) primary key auto_increment,
`name` varchar(40),
path varchar(100),
salary double(10,2),
age int(3)
);
2.创建springboot的项目
3.导入依赖
<dependencies>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.2</version>
<scope>test</scope>
</dependency>
</dependencies>
4.编写配置文件
server.servlet.context-path=/ems_vue
server.port=8989
spring.application.name=ems
#配置数据库
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/emps?characterEncoding=utf-8
#配置数据库
#路径
mybatis.mapper-locations=classpath:com/huang/mapper/*.xml
mybatis.type-aliases-package=com.huang.entity
#日志
logging.level.com.huang.dao=debug
logging.level.com.huang.service=info
logging.level.com.huang.controller=info
##功能一、验证码的实现
1.编写注册页面regist.html
<div id="wrap">
<h1>我是注册页面</h1>
<div>
<h1>
<a href="#">main</a>
</h1>
</div>
<div>
<h1>注册</h1>
<form action="login.html" method="post">
<table cellpadding="0" cellspacing="0" border="0">
<tr>
<td valign="middle" align="right">
用户名:
</td>
<td valign="middle" align="left">
<input type="text" name="username"/>
</td>
</tr>
<tr>
<td valign="middle" align="right">
真实姓名:
</td>
<td valign="middle" align="left">
<input type="text" name="name"/>
</td>
</tr>
<tr>
<td valign="middle" align="right">
密码:
</td>
<td valign="middle" align="left">
<input type="password" name="pwd"/>
</td>
</tr>
<tr>
<td valign="middle" align="right">
性别:
</td>
<td valign="middle" align="left">
男
<input type="radio" name="sex" value="m" checked/>
女
<input type="radio" name="sex" value="f"/>
</td>
</tr>
<tr>
<td valign="middle" align="right">
验证码:
</td>
<td valign="middle" align="left">
<input type="text" name="number"/>
</td>
<td>
<!--用vue的 :src ,url 方法在下面的script中实现-->
<img id="num" :src="url"/>
<!--用vue的 @click ,getImg方法在下面的script中实现-->
<a href="javascript:;" @click="getImg">
<!--点击‘换一张’ 就会触发一次 getImg 方法,具体方法实现见<script>中-->
换一张
</a>
</td>
</tr>
</table>
<p>
<input type="submit" value="提交"/>
</p>
</form>
</div>
</div>
2.在regist.html中导入js文件(vue和axios的)
<script src="/ems_vue/js/vue.js"></script>
<script src="/ems_vue/js/axios.min.js"></script>
3.在java/main/com/huang/utils/VerifyCodeUtils.java文件中写生成验证码的工具类(网上找的资源)
4.编写controller,在…/UserController.java文件中
/**
* 生成验证码图片
*/
@GetMapping("getImage")
public String getImageCode(HttpServletRequest request) throws IOException {
//1.使用工具类生成验证码
String code = VerifyCodeUtils.generateVerifyCode(4);
//2.放入servletContext作用域
request.getServletContext().setAttribute("code",code);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
VerifyCodeUtils.outputImage(120,30,byteArrayOutputStream,code);
return "data:image/png;base64,"+ Base64Utils.encodeToString(byteArrayOutputStream.toByteArray());
}
5.在regist.html文件中编写vue相关的axios,为了获取到验证码图片
<script>
var app = new Vue({
el:"#wrap",
data:{
url:"",
},
methods:{
getImg(){
this.getSrc();
},
//封装获取随机验证码的图片(实现方法的复用)
getSrc(){
var _this = this;
//这个 ?time"+Math.random() 是为了实现随机产生一个
axios.get("http://localhost:8989/ems_vue/user/getImage?time"+Math.random()).then(res =>{
console.log(res.data);
_this.url = res.data;
});
}
},
created(){
this.getSrc();
}
})
</script>
##功能二、注册的实现
1.构建用户实体对象,在…/entity/User.java中
package com.huang.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.Date;
@Data
@Accessors(chain = true) //让set方法返回的不是void
public class User {
private String id; //数据库中是int,但在这里用String类型,是String类型的api较多,可以进行更为复杂的操作
private String username;
private String realname;
private String password;
private String sex;
private String status;
private Date regsterTime;
}
2.写一个关于插入的UserDAO接口,在…/dao/UserDAO.java中
package com.huang.dao;
import com.huang.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper //用来创建DAO对象
public interface UserDAO {
void save(User user);
}
3.写mapper配置文,在resources/com/huang/mapper/UserDAOMapper.xml中
<?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">
<!--命名空间一定要记得写,它管理的是com.huang.dao.UserDAO的接口-->
<mapper namespace="com.huang.dao.UserDAO">
<!-- useGeneratedKeys="true" keyProperty="id"使用自动生成的id -->
<insert id="save" parameterType="User" useGeneratedKeys="true" keyProperty="id">
insert into emps.t_user values (#{id},#{username},#{realname},#{password},#{sex},#{status},#{regsterTime})
</insert>
</mapper>
4.编写业务方法,编写业务接口,在…/service/UserService.java接口中
package com.huang.service;
import com.huang.entity.User;
//业务接口
public interface UserService {
//用户注册的方法
void register(User user);
}
5.对应的业务层,实现业务,在…/Service/UserServiceImpl.java中去实现UserService接口
package com.huang.service;
import com.huang.dao.UserDAO;
import com.huang.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
@Service
@Transactional
public class UserServiceImpl implements UserService {
//调用业务,去处理DAO,所以直接注入 UserDAO
@Autowired
private UserDAO userDAO;
@Override
public void register(User user) {
//1.生成用户的状态
user.setStatus("已经激活了哦");
//2.设置用户注册的时间
user.setRegsterTime(new Date());
//3.调用DAO
userDAO.save(user);
}
}
6.在UserController.java中添加一个注册功能的方法
@Autowired
private UserService userService;
/**
* 用来处理用户注册方法
*/
@PostMapping("register")
// Map是用来承载注册的信息
// @RequestBody User user ,user用来接收用户信息,其中的@RequestBody将json转换为User对象
// code用来表示接收验证码信息
// 用HttpServletRequest request 来拿之前的验证码信息
public Map<String, Object> register(@RequestBody User user, String code, HttpServletRequest request){
log.info("用户信息:[{}]",user.toString()); //打印日志信息
log.info("用户输入的验证信息:[{}]",code);
Map<String, Object> map = new HashMap<>(); //构建map集合来存放数据
//1.调用业务方法
try {
String key = (String) request.getServletContext().getAttribute("code"); //用request来拿前面存的code
//判断 用户输入的验证码key 和,当前的验证码code是否一致
if (key.equalsIgnoreCase(code)) {
userService.register(user);
map.put("state", true); //state是表示状态
map.put("msg", "注册成功L");
}else {
//当验证码没有通过时,抛出异常,再进入catch
throw new RuntimeException("验证码出现错误咯哦");
}
} catch (Exception e){
e.printStackTrace();
map.put("state", false);
map.put("msg","注册失败Q"+e.getMessage()); // e.getMessage() 表示用e捕获的具体信息
}
return map;
}
7.处理前台,发起request请求
- 1.在vue中定义一个user对象
data:{
user:{//定义一个user对象,为了注册用户使用的
sex:"男"
},
code:""
},
- 2.将用户输入的信息绑定给user对象 v-model="user.username"
<td valign="middle" align="left">
<input type="text" v-model="user.username"/>
</td>
- 3.同理将realname、password、sex都用v-model="user.xxx"去绑定
- 4.绑定验证码(但验证码不属于用户信息),要去data中定义一个code,然后再绑定v-model="code"
- 5.给提交表单的button 添加单击事件 @click="register",对这个事件,要在后台(即<script>中)发起请求
<script>
var app = new Vue({
el:"#wrap",
data:{
url:"",
user:{//定义一个user对象,为了注册用户使用的
sex:"男" //这个默认值,是让初始的时候就被选中,因为上面的 value="男"
},
code:""
},
methods:{
getImg(){
this.getSrc();
},
//封装获取随机验证码的图片(实现方法的复用)
getSrc(){
var _this = this;
axios.get("http://localhost:8989/ems_vue/user/getImage?time"+Math.random()).then(res =>{
console.log(res.data);
_this.url = res.data;
});
},
//@click="register" 对点击事件发起请求的操作
//用来注册用户信息的
register() {
// 01.对http://localhost:8989/ems_vue/user/register路径发起一个post请求
// 02.这里的 +this.code, this.user 代表地址栏传参,可以直接赋值给UserController.java 中对应的
// public Map<String, Object> register(@RequestBody User user, String code, HttpServletRequest request)
// 的code 和user
// 03.通过then来拿到结果(ES6的语法), .then(res => {
axios.post("http://localhost:8989/ems_vue/user/register?code="+this.code, this.user).then(res => {
console.log(res.data); //结果的打印,res.data是代表拿到的结果
if (res.data.state){
alert(res.data.msg+",点击确定跳转至登录页面!");
location.href="/ems_vue/login.html";
}else {
alert(res.data.msg);
}
});
}
},
created(){
this.getSrc();
}
})
</script>
8.根据用户输入的用户名,判断用户名是否存在(基于用户名去查询)
- 1.在UserDAO.java接口中先加入一个方法
User findByUserName(String username);
- 2.对findByUserName方法的实现,在UserDAOMapper.xml文件中
<select id="findByUserName" parameterType="String" resultType="User">
select id,username,realname,password,sex,status,regsterTime
from emps.t_user
where username = #{username};
</select>
- 3.在业务层做处理UserServiceImpl.java中,先查询用户User userDB = userDAO.findByUserName(user.getUsername()); 在判断是否为空if
package com.huang.service;
import com.huang.dao.UserDAO;
import com.huang.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserDAO userDAO;
@Override
public void register(User user) {
//0.查询用户输入用户名,判断用户是否存在
User userDB = userDAO.findByUserName(user.getUsername());
if (userDB == null){
//1.生成用户的状态
user.setStatus("已经激活了哦");
//2.设置用户注册的时间
user.setRegsterTime(new Date());
//3.调用DAO
userDAO.save(user);
} else {
throw new RuntimeException("用户名已经存在了,请修改。。。");
}
}
}
##功能三、登录
1.可以复用注册中使用名字查询的方法,即UserDAO.java中的findByUserName和相关的xml文件
2.在UserService.java接口中添加用户登录方法
User login(User user);
3.到UserServiceImpl.java中去实现 改登录方法
//实现UserService接口中的用户登录方法
@Override
public User login(User user) {
//1.根据用户输入的用户名进行查询
User userDB = userDAO.findByUserName(user.getUsername());
//判断用户名是否为空(到数据库中比较,是否为空)
if (!ObjectUtils.isEmpty(userDB)){ // 使用工具类 !ObjectUtils.isEmpty(userDB)的使用和userDB != null的效果相同
//2.用户名不为空时,再比较密码
//数据库中的密码userDB.getPassword() 和 当前的用户输入的密码user.getPassword() 作比较
if (userDB.getPassword().equals(user.getPassword())) {
return userDB;
} else {
throw new RuntimeException("密码不对哦");
}
}else {
throw new RuntimeException("用户名输入错误哦");
}
}
4.再到UserController.java中,处理登录方法
/**
* 用来处理登录方法
*/
@PostMapping("login")
public Map<String, Object> login(@RequestBody User user){
log.info("当前的登录用户的信息:[{}]",user.toString());
//1、收集数据
Map<String, Object> map = new HashMap<>();
try {
//2、调用业务方法 userService
User userDB = userService.login(user);
map.put("state", true);
map.put("msg", "登录成功啦!");
} catch (Exception e){
e.printStackTrace();
map.put("state", false);
map.put("msg", e.getMessage());
}
return map;
}
5.修改前端页面,在login.html
- 1.双向绑定用户名和密码 v-model="user.xxx"
- 2.对‘登录’时,添加一个单击事件 @click="login" 要在methods中写一个login(){}方法
<script src="/ems_vue/js/vue.js"></script>
<script src="/ems_vue/js/axios.min.js"></script>
<script>
<!-- new 一个vue实例 -->
var app = new Vue({
el:"#wrap",
data:{
user:{}, //用来保存用户数据
},
methods:{
//点击事件触发@click="login" 后,用户登录的方法
login(){
console.log(this.user);
//发送登录请求
axios.post("http://localhost:8989/ems_vue/user/login",this.user).then( res =>{
console.log(res.data);
if (res.data.state){
alert(res.data.msg+"点击确定,就到了另外一个地方啦");
location.href="/ems_vue/emplist.html";
}else {
alert(res.data.msg);
}
});
}
}
});
</script>
##功能四、展示用户信息(欢迎用户进入)
1.在UserController.java中,添加 map.put(“user”,userDB); 为了把登录的用户信息给user,给前端使用
/**
* 用来处理登录方法
*/
@PostMapping("login")
public Map<String, Object> login(@RequestBody User user){
log.info("当前的登录用户的信息:[{}]",user.toString());
Map<String, Object> map = new HashMap<>();
try {
User userDB = userService.login(user);
map.put("state", true);
map.put("msg", "登录成功啦!");
//在登录成功之后,放了一个用户的数据
map.put("user",userDB); //将用户信息给user
} catch (Exception e){
e.printStackTrace();
map.put("state", false);
map.put("msg", e.getMessage());
}
return map;
}
2.在前端的login.html中,将登录的用户信息放入localStorage中
//将登录的用户信息放入localStorage key value
localStorage.setItem("user",JSON.stringify(res.data.user));
//这里的"user"就是,在后台获取的 map.put("user",userDB); 里面的"user"
//这里的JSON.stringify(res.data.user)是将"user"存入res.data.user中,并且将对象形式转为JSON形式的存储
3.在emplist.html中取出用户信息,并使用
<script src="/ems_vue/js/vue.js"></script>
<script src="/ems_vue/js/axios.min.js"></script>
<script>
var app = new Vue({
el:"#wrap",
data:{ //vue的数据
user:{
realname:""
} //这个user对象是用来存放用户登录的信息
},
methods:{ //自定义函数
},
created(){ //生命周期函数
var userJSONString = localStorage.getItem("user"); //将login.html中存的数据取出来
if (userJSONString){
var user = JSON.parse(userJSONString); //将取出来的数据userJSONString转化为对象形式
this.user = user; //将去出来的数据user,赋值给data:{}中定义的数据user:{},即this.user
} else{
alert("您还没有登录哦!点击确定跳转到登录页面吧");
location.href="/ems_vue/login.html";
}
}
});
</script>
##功能五、安全退出
1.在emplist.html中添加‘安全退出’的按钮,添加点击事件@click=“logout”
<h1>
<input type="button" value="安全退出" @click="logout">
</h1>
2.在emplist.html中,为绑定的事件logout添加方法
methods:{ //自定义函数
//处理安全退出
logout(){
localStorage.removeItem("user");
location.reload(true); //刷新页面
}
},
功能六、列表展示
1.构建实体对象…/entity/Emp.java
package com.huang.entity;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain = true)
public class Emp {
private String id;
private String name;
private String path;
private Double salary;
private int age;
}
2.开发Emp的接口…/dao/EmpDAO.java
package com.huang.dao;
import com.huang.entity.Emp;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper //用于创建DAO对象
public interface EmpDAO {
List<Emp> findAll(); //查询所有的方法
}
3.对接口中的findAll()方法的实现,resources/com/huang/mapper/EmpDAPMapper.xml
<?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.huang.dao.EmpDAO">
<select id="findAll" resultType="Emp">
select id,name,path,salary,age from emps.t_emp
</select>
</mapper>
4.构建业务层,EmpService.java接口,构建Emp类型的集合方法
package com.huang.service;
import com.huang.entity.Emp;
import java.util.List;
public interface EmpService {
List<Emp> findAll();
}
5.开发EmpServiceImpl.java去实现EmpService(实现接口中没有实现的方法)
package com.huang.service;
import com.huang.dao.EmpDAO;
import com.huang.entity.Emp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
@Transactional
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpDAO empDAO;
@Override
@Transactional(propagation = Propagation.SUPPORTS) //支持事务
public List<Emp> findAll() {
return empDAO.findAll();
}
}
6.开发EmpController.java
package com.huang.controller;
import com.huang.entity.Emp;
import com.huang.service.EmpService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
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("emp")
@CrossOrigin //允许跨域
public class EmpController {
@Autowired //注入对应的业务对象
private EmpService empService;
//获取员工列表的方法
@GetMapping("findAll")
private List<Emp> findAll(){
return empService.findAll(); //获取所有员工的数据
}
}
7.通过EmpController.java已经可以拿到数据库中的数据,再去前端修改emplist.html
- 1.在data{}中添加一个emps:[]的数组,去接收后端从数据库中得到的结果
data:{ //vue的数据
emps:[],
},
- 2.在生命周期函数created(){}中,去查询所有信息
created(){ //生命周期函数
//查询所有员工
var _this = this;
axios.get("http://localhost:8989/ems_vue/emp/findAll").then(res =>{
_this.emps = res.data;
})
}
- 3.对拿到的数据,到页面中去遍历 ***v-for="(emp,index) in emps"***
<table border="1">
<tr>
<td width="70px">序号</td>
<td width="70px">名字</td>
<td width="70px">照片</td>
<td width="70px">工资</td>
<td width="70px">年龄</td>
<td width="150px">操作</td>
</tr>
<tr v-for="(emp,index) in emps" :key="emp.id">
<td v-text="emp.id"></td>
<td v-text="emp.name"></td>
<td>
<img :src="emp.path" style="height: 60px ;width: 60px">
</td>
<td v-text="emp.salary"></td>
<td v-text="emp.age"></td>
<td><a href="#">删除员工</a> <a href="#">修改</a> </td>
</tr>
</table>
##功能七、员工的添加(设计到文件的上传----头像的展示)
1.编写添加页面addEmp.html
- 1.在data{}中添加一个自定义的员工信息对象
data: {
emp:{}//定义一个员工信息的对象
},
- 2.添加绑定事件v-model="emp.xxx"
<input type="text" v-model="emp.name"/>
- 3.添加‘提交’按钮的单击事件saveEmp
<input type="button" @click="saveEmp" value="提交">
- 4.头像的要另外写
<input type="file" ref="myPhoto"/>
- 5.在methods{}中添加saveEmp()方法
methods: {
//保存员工信息
saveEmp(){
console.log(this.emp);//获取员工的信息
//拿到对应头像的myPhoto文件信息,其中.files[0]是为了拿到myPhoto文件中具体的第1个文件信息
console.log(this.$refs.myPhoto.files[0]); //获取文件信息
//文件上传时,请求方式必须是post 其中enctype属性必须为multipart/form-data
//构建员工formData对象,模拟一个表单
var formData = new FormData();
formData.append("name",this.emp.name);
formData.append("salary",this.emp.salary);
formData.append("age",this.emp.age);
formData.append("photo",this.$refs.myPhoto.files[0]);
var _this = this;
//通过axios的构造,再去配置,如何配置,见如下
axios({
method: "post", //这个method不能加s,否则
// 会报这个错误 Resolved [org.springframework.web.HttpRequestMethodNotSupportedException:Request method 'GET' not supported]
url: "http://localhost:8989/ems_vue/emp/save", //后端接口
data: formData, //把表单数据放进来就行
headers: {
'content-type': 'multipart/form-data'
}
}).then(res =>{ //通过then的方式拿到结果信息
console.log(res.data);
if (res.data.state){
if (window.confirm(res.data.msg+",点击确定就回到主页了")){
//如果点击了‘确定’就跳转到 改/ems_vue/emplist.html 页面
location.href = "/ems_vue/emplist.html";
} else {
//否则就保存到当前页面
_this.emp = {}; //保存到当前页面时,清除刚才填入的数据信息
}
} else {
alert(res.data.msg)
}
});
}
},
2.到EmpController.java中编写保存员工信息
//保存员工信息
@PostMapping(value = "save")
//这里的Emp emp用来接收用户信息,MultipartFile photo用来接收头像
// (这个photo要和前端的formData.append("photo",this.$refs.myPhoto.files[0]);里的photo写的要一致)
public Map<String, Object> save(Emp emp, MultipartFile photo) throws IOException {
log.info("员工信息:[{}]",emp.toString()); //日志信息
log.info("头像信息:[{}]",photo.getOriginalFilename());
Map<String, Object> map = new HashMap<>();
try {
//头像的保存
//这里的 UUID.randomUUID().toString() 表示原始的文件名,加上
// 原始文件的扩展名 FilenameUtils.getExtension(photo.getOriginalFilename())
String newFileName = UUID.randomUUID().toString()+"."+ FilenameUtils.getExtension(photo.getOriginalFilename());
photo.transferTo(new File(realPath,newFileName)); //进行文件的上传
//设置头像地址
emp.setPath(newFileName);
//保存员工信息
empService.save(emp); //这个save方法要去EmpService.java接口中创建(见第6 步)
map.put("state",true);
map.put("msg","员工信息保存成功!!");
} catch (Exception e) {
e.printStackTrace();
map.put("state", false);
map.put("msg","保存失败哦。");
}
return map;
}
3.到配置文件application.properties中添加对照片文件的存储路径
#声明文件上传的目录(为上传头像做准备)
photo.dir=D:\\Self-taught\\MY\\emps\\emp01\\src\\main\\resources\\static\\photos
4.到EmpController.java中去注入改文件上传的路径
@Value("${photo.dir}")
private String realPath;
5.在EmpService.java接口文件中创建,所需的save方法
void save(Emp emp);
6.有了save方法后,去EmpServiceImpl.java文件中去做实现
@Override
public void save(Emp emp) {
empDAO.save(emp); //调用EmpDAO的save方法,对emp进行保存,但是目前还没有,要求创建改save方法
}
7.到EmpDAO.java接口文件中,创建save方法,用于保存
void save(Emp emp);
8.对改save保存方法,在EmpDAO.xml文件中去实现(将员工信息保存到数据库中)
<insert id="save" parameterType="Emp" useGeneratedKeys="true" keyProperty="id">
insert into emps.t_emp values (#{id}, #{name}, #{path}, #{salary}, #{age})
</insert>
9.到emplist.html中实现头像的加载
<!-- 这里的 '/ems_vue/' 实现头像的加载 -->
<img :src="'/ems_vue/'+emp.path" style="height: 60px ;width: 60px">
10.到application.properties中放行资源的访问(图片资源)
#这里的photo.dir 是之前声明的路径
spring.resources.static-locations=classpath:/static/,file:${photo.dir}
##功能八、员工删除
1.到EmpDAO.java接口中,写一个delete的删除
void delete(String id);
2.到mapper中做实现,即SQL语句,在EmpDAOMapper.xml
<delete id="delete" parameterType="String">
delete from emps.t_emp where id = #{id}
</delete>
3.写完dao后,回到业务处理,到EmpService.java接口中写一个删除的方法
void delete(String id)
4.在EmpServiceImpl.java对delete方法的实现
@Override
public void delete(String id) {
empDAO.delete(id);
}
5.到EmpController.java中写删除员工信息的方法
//删除员工
@GetMapping("delete")
public Map<String,Object> delete(String id ){
log.info("删除员工的id是【{}】",id); //打印日志
Map<String, Object> map = new HashMap<>();
try {
//删除员工的头像
Emp photo = empService.findPhoto(id);
File file = new File(realPath, photo.getPath());
if (file.exists()){
//删除头像文件
file.delete();
}
//删除员工信息
empService.delete(id);
map.put("state",true);
map.put("msg","删除成功喽^-^");
} catch (Exception e) {
e.printStackTrace();
map.put("state",false);
map.put("msg","没有删除哦!");
}
return map;
}
6.编写前端删除操作,在emplist.html中
- 1.添加一个单击事件delEmp(emp.id),并获取要删除的那个id
<a href="#" @click="delEmp(emp.id)">删除员工</a>
- 2.在methods中编写delEmp(id){}方法
methods:{ //自定义函数
//删除员工的操作
delEmp(id){
if (window.confirm("确定要删除该员工的信息吗??")){
var _this = this;
axios.get("http://localhost:8989/ems_vue/emp/delete?id="+id).then(res =>{
if (res.data.state){
alert(res.data.msg+"点击确定,刷新数据");
_this.findAll(); //重新加载数据
}else {
alert(res.data.msg);
}
});
}
},
//查询员工列表方法(对该方法进行封装,实现复用)
findAll(){
var _this = this;
axios.get("http://localhost:8989/ems_vue/emp/findAll").then(res =>{
_this.emps = res.data;
})
}
},
7.删除时,要把用户的头像也删除了,步骤见8-13
8.在EmpDAO.java中编写查找改id对应的图片
Emp findPhoto(String id);
9.在mapper文件(EmpDAOMapper.xml)中,实现该方法
<select id="findPhoto" parameterType="String" resultType="Emp">
select id,name,path,salary,age from emps.t_emp
where id = #{id}
</select>
10.去业务层,添加数据接口(EmpService.java接口)
Emp findPhoto(String id);
11.到EmpServiceImpl.java中,对业务接口的方法进行实现
@Override
public Emp findPhoto(String id) {
return empDAO.findPhoto(id);
}
12.在EmpServiceImpl.java中查询到了员工的信息后,可以到EmpController.java中实现删除头像的操作
//删除员工的头像
Emp photo = empService.findPhoto(id); //查询对应的用户信息
File file = new File(realPath, photo.getPath()); //构建一个file,来获取文件
if (file.exists()){ //如果文件存在
//删除头像文件
file.delete();
}
##功能九、修改员工信息
1.先在emplist.html中穿一个id
<a :href="'/ems_vue/updateEmp.html?id='+emp.id">修改</a>
2.到updateEmp.html中截取获取到的页面
var app = new Vue({
el: "#wrap",
data:{
emp:{} //用户展示数据库回响用的对象
},
methods:{
//处理员工的修改信息
editEmp(){
console.log(this.emp); //拿到员工信息
console.log(this.$refs.photo.files[0]); //拿到头像信息<input ref="photo" type="file"/>,通过这个photo
var formData = new FormData();
formData.append("id",this.emp.id);
formData.append("name",this.emp.name);
formData.append("path",this.emp.path); //将原始的文件路径this.emp.path传给"path",否则文件(图片)会丢失
formData.append("salary",this.emp.salary);
formData.append("age",this.emp.age);
formData.append("photo",this.$refs.photo.files[0]);
var _this = this;
axios({ //通过axios的构造,再去配置,如何配置,见如下
method: "post",
url: "http://localhost:8989/ems_vue/emp/update",
data: formData,
headers: {
'content-type': 'multipart/form-data'
}
}).then(res =>{
console.log(res.data);
if (res.data.state){
if (window.confirm(res.data.msg+",点击确定就回到主页了")){
location.href = "/ems_vue/emplist.html";
}
} else {
alert(res.data.msg)
}
});
}
},
created(){
//获取对应的id信息
var start = location.href.lastIndexOf("="); //从路径的 = 等号 开始截取信息(截取的起始值)
var id = location.href.substring(start+1); //从start+1的位置开始截取
console.log(id);
//查询一个人的信息
var _this = this;
//通过获取id查询一个员工的方法(在EmpController.java中的/emp/findOne)来获取对应id的员工信息,见第3步
axios.get("http://localhost:8989/ems_vue/emp/findOne?id="+id).then(res=>{
console.log(res.data);
_this.emp = res.data; //展示数据库回响对象
});
}
})
3.在EmpController.java中,通过获取id查询一个员工信息的方法
//根据id查询一个员工的信息
@GetMapping("findOne")
public Emp findOne(String id){
log.info("查询一个员工信息的id是【{}】",id);
return empService.findPhoto(id); //之前删除用户头像时写的方法(是用来查询对应id的员工个人信息用的)
}
4.对在updateEmp.html中的created(){}方法中,获取到了***_this.emp = res.data;***的展示数据库的回响对象,进行双向绑定v-text=“emp.xxx”
<!--用户的id-->
<td valign="middle" v-text="emp.id" align="left">
<!--用户的name,salary,age都是同理可得-->
<input type="text" v-model="emp.name"/>
<!--用户的头像展示-->
<img :src="'/ems_vue/'+emp.path" style="height: 60px; width: 60px"/>
<input ref="photo" type="file"/>
5.给提交表单添加员一个单击事件editEmp,在methods:{}中实现,见步骤2
<input type="button" @click="editEmp" value="提交">
6.到EmpController.java中写修改员工信息的实现方法
//修改用户信息
@PostMapping(value = "update")
public Map<String, Object> update(Emp emp, MultipartFile photo) throws IOException {
log.info("员工信息:[{}]",emp.toString());
Map<String, Object> map = new HashMap<>();
try {
if (photo != null && photo.getSize() != 0){ //这个photo是一个MultipartFile 对象,是一直不为0的,所以要做这样的判断
log.info("头像信息:[{}]",photo.getOriginalFilename());
//头像的保存
String newFileName = UUID.randomUUID().toString()+"."+ FilenameUtils.getExtension(photo.getOriginalFilename());
photo.transferTo(new File(realPath,newFileName));
//设置头像地址
emp.setPath(newFileName);
}
//保存员工信息
empService.update(emp); //目前还没有update方法,要求EmpService中写一个update方法,见步骤7
map.put("state",true);
map.put("msg","员工信息更新成功!!");
} catch (Exception e) {
e.printStackTrace();
map.put("state", false);
map.put("msg","保存更新哦。");
}
return map;
}
7.在EmpService.java接口中创建一个update
void update(Emp emp);
8.在对应的业务中(EmpServiceImpl.java),执行update
@Override
public void update(Emp emp) {
empDAO.update(emp); //目前该EmpDAO中,还没有这个update方法,要去创建
}
9.在EmpDAO.java接口中创建update方法
void update(Emp emp);
10.到EmpDAOMapper.xml中去实现这个update方法
<update id="update" parameterType="Emp">
update emps.t_emp
set
name = #{name},
path = #{path},
salary = #{salary},
age = #{age}
where
id = #{id}
</update>