1、后端编写
1.1 Service服务层编写
package com.gmw.musicserver.service;
import com.gmw.musicserver.entity.Consumer;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* <p>
* 用户表 服务类
* 前端用户service接口
* </p>
*
* @author 未进化的程序猿
* @since 2022-01-26
*/
public interface ConsumerService extends IService<Consumer> {
/**
*增加用户
*/
public boolean insertConsumer(Consumer consumer);
/**
*修改用户
*/
public boolean updateConsumer(Consumer consumer);
/**
* 删除用户
*/
public boolean deleteConsumer(Integer id);
/**
* 根据主键查询整个对象
*/
public Consumer selectByPrimaryKey(Integer id);
/**
* 查询所有用户
*/
public List<Consumer> allConsumer();
/**
* 修改密码
*/
public boolean verifyPassword(String username,String password);
/**
* 根据账号查询
*/
public Consumer getByUsername(String username);
}
package com.gmw.musicserver.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gmw.musicserver.entity.Consumer;
import com.gmw.musicserver.mapper.ConsumerMapper;
import com.gmw.musicserver.service.ConsumerService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* <p>
* 用户表 服务实现类
* </p>
*
* @author 未进化的程序猿
* @since 2022-01-26
*/
@Service
public class ConsumerServiceImpl extends ServiceImpl<ConsumerMapper, Consumer> implements ConsumerService {
/**
* 增加用户
*
* @param consumer
*/
@Override
public boolean insertConsumer(Consumer consumer) {
return this.baseMapper.insert(consumer) > 0;
}
/**
* 修改用户
*
* @param consumer
*/
@Override
public boolean updateConsumer(Consumer consumer) {
return this.baseMapper.updateById(consumer) > 0;
}
/**
* 删除用户
*
* @param id
*/
@Override
public boolean deleteConsumer(Integer id) {
return this.baseMapper.deleteById(id) > 0;
}
/**
* 根据主键查询整个对象
*
* @param id
*/
@Override
public Consumer selectByPrimaryKey(Integer id) {
return this.baseMapper.selectById(id);
}
/**
* 查询所有用户
*/
@Override
public List<Consumer> allConsumer() {
return this.baseMapper.selectList(null);
}
/**
* 修改密码
*
* @param username
* @param password
*/
@Override
public boolean verifyPassword(String username, String password) {
QueryWrapper<Consumer> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
queryWrapper.eq("password",password);
return this.baseMapper.selectCount(queryWrapper) > 0;
}
/**
* 根据账号查询
*
* @param username
*/
@Override
public Consumer getByUsername(String username) {
QueryWrapper<Consumer> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
return this.baseMapper.selectOne(queryWrapper);
}
}
1.2 Controller控制层编写
package com.gmw.musicserver.controller;
import com.gmw.musicserver.commonutils.R;
import com.gmw.musicserver.entity.Consumer;
import com.gmw.musicserver.entity.Song;
import com.gmw.musicserver.service.ConsumerService;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* <p>
* 用户表 前端控制器
* </p>
*
* @author 未进化的程序猿
* @since 2022-01-26
*/
@RestController
@RequestMapping("/musicserver/consumer")
public class ConsumerController {
public static final Logger logger = LoggerFactory.getLogger(ConsumerController.class);
@Autowired
private ConsumerService consumerService;
/**
* 添加前端用户
*/
@PostMapping(value = "/addConsumer")
public R addConsumer(HttpServletRequest request){
String username = request.getParameter("username").trim(); //账号
String password = request.getParameter("password").trim(); //密码
String sex = request.getParameter("sex").trim(); //性别
String phoneNum = request.getParameter("phoneNum").trim(); //手机号
String email = request.getParameter("email").trim(); //电子邮箱
String birth = request.getParameter("birth").trim(); //生日
String introduction = request.getParameter("introduction").trim();//签名
String location = request.getParameter("location").trim(); //地区
String avator = request.getParameter("avator").trim(); //头像地址
if(username==null||username.equals("")){
return R.error().message("用户名不能为空!!");
}
if(password==null||password.equals("")){
return R.error().message("密码不能为空!!");
}
//把生日转换成Date格式
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date birthDate = new Date();
try {
birthDate = dateFormat.parse(birth);
} catch (ParseException e) {
e.printStackTrace();
}
//保存到前端用户的对象中
Consumer consumer = new Consumer();
consumer.setUsername(username);
consumer.setPassword(password);
consumer.setSex(Integer.parseInt(sex));
consumer.setPhoneNum(phoneNum);
consumer.setEmail(email);
consumer.setBirth(birthDate);
consumer.setIntroduction(introduction);
consumer.setLocation(location);
consumer.setAvator(avator);
logger.info("保存前端用户对象: {}",consumer);
boolean flag = this.consumerService.insertConsumer(consumer);
if(flag){ //保存成功
return R.ok().message("添加成功!!");
}else {
return R.error().message("添加失败!!");
}
}
/**
* 修改前端用户
*/
@PostMapping(value = "/updateConsumer")
public R updateConsumer(HttpServletRequest request){
String id = request.getParameter("id").trim(); //主键
String username = request.getParameter("username").trim(); //账号
String password = request.getParameter("password").trim(); //密码
String sex = request.getParameter("sex").trim(); //性别
String phoneNum = request.getParameter("phoneNum").trim(); //手机号
String email = request.getParameter("email").trim(); //电子邮箱
String birth = request.getParameter("birth").trim(); //生日
String introduction = request.getParameter("introduction").trim();//签名
String location = request.getParameter("location").trim(); //地区
if(username==null||username.equals("")){
return R.error().message("用户名不能为空!!");
}
if(password==null||password.equals("")){
return R.error().message("密码不能为空!!");
}
//把生日转换成Date格式
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date birthDate = new Date();
try {
birthDate = dateFormat.parse(birth);
} catch (ParseException e) {
e.printStackTrace();
}
//保存到前端用户的对象中
Consumer consumer = new Consumer();
consumer.setId(Integer.parseInt(id));
consumer.setUsername(username);
consumer.setPassword(password);
consumer.setSex(Integer.parseInt(sex));
consumer.setPhoneNum(phoneNum);
consumer.setEmail(email);
consumer.setBirth(birthDate);
consumer.setIntroduction(introduction);
consumer.setLocation(location);
logger.info("保存前端用户修改对象: {}",consumer);
boolean flag = this.consumerService.updateConsumer(consumer);
if(flag){ //保存成功
return R.ok().message("修改成功!!");
}else {
return R.error().message("修改失败!!");
}
}
/**
* 删除前端用户
*/
@GetMapping(value = "/deleteConsumer")
public R deleteConsumer(HttpServletRequest request){
String id = request.getParameter("id").trim(); //主键
//-TODO 先查询到数据库中对应的文件地址,删除掉它再进行下面的代码
//通过ID主键查询用户对象
Consumer consumer = this.consumerService.selectByPrimaryKey(Integer.parseInt(id));
//获取用户图片
String avator = consumer.getAvator();
logger.info("获取用户图片: {}",avator);
//如果文件的相对路径是/img/avatorImages/user.jpg就没必要删除
//因为它是当作默认相对路径的,需要用到
if(!avator.equals("/img/avatorImages/user.jpg")){
//获取用户图片保存的文件目录
String avatorPath = System.getProperty("user.dir") + avator;
logger.info("获取用户图片保存的文件目录: {}",avatorPath);
File file = new File(avatorPath);
if(file.isFile()){
//判断如果是文件的话,就删除文件
boolean isDelete = file.delete();
logger.info("是否删除成功: {}",isDelete);
if(!isDelete){
return R.error().message("删除用户失败!!");
}
}
}
boolean flag = this.consumerService.deleteConsumer(Integer.parseInt(id));
if(flag){
return R.ok().message("删除成功!!");
}
return R.error().message("删除失败!!");
}
/**
* 根据主键查询整个对象
*/
@GetMapping(value = "/selectByPrimaryKey")
public R selectByPrimaryKey(HttpServletRequest request){
String id = request.getParameter("id").trim(); //主键
Consumer consumer = this.consumerService.selectByPrimaryKey(Integer.parseInt(id));
return R.ok().data("consumer",consumer);
}
/**
* 查询所有前端用户
*/
@GetMapping(value = "/allConsumer")
public R allConsumer(HttpServletRequest request){
List<Consumer> consumers = this.consumerService.allConsumer();
return R.ok().data("list",consumers);
}
/**
* 更新前端用户图片
*/
@PostMapping(value = "/updateConsumerPic")
public R updateConsumerPic(@RequestParam("file") MultipartFile avatorFile, @RequestParam("id")int id){
/**
* 更新用户图片之前,必须把原来的用户图片删除掉
*/
//通过ID主键查询用户对象
Consumer consumer1 = this.consumerService.selectByPrimaryKey(id);
//获取用户图片
String avator = consumer1.getAvator();
logger.info("获取用户图片: {}",avator);
//如果文件的相对路径是/img/avatorImages/user.jpg就没必要删除
//因为它是当作默认相对路径的,需要用到
if(!avator.equals("/img/avatorImages/user.jpg")){
//获取用户图片保存的文件目录
String avatorPath = System.getProperty("user.dir") + avator;
logger.info("获取用户图片保存的文件目录: {}",avator);
File file1 = new File(avator);
if(file1.isFile()){
file1.delete();
}
}
//开始更新用户图片
if(avatorFile.isEmpty()){
return R.error().message("文件上传失败!!");
}
//文件名=当前时间到毫秒+原来的文件名
String fileName = System.currentTimeMillis()+avatorFile.getOriginalFilename();
//文件路径
String filePath = System.getProperty("user.dir")+System.getProperty("file.separator")
+ "img" + System.getProperty("file.separator") + "avatorImages";
//如果文件路径不存在,新增该路径
File file1 = new File(filePath);
if(!file1.exists()){
file1.mkdir();
}
//实际的文件地址
File dest = new File(filePath+System.getProperty("file.separator")+fileName);
//存储到数据库里的相对文件地址
String storeAvatorPath = "/img/avatorImages/"+fileName;
try {
avatorFile.transferTo(dest);
Consumer consumer = new Consumer();
consumer.setId(id);
consumer.setAvator(storeAvatorPath);
boolean flag = this.consumerService.updateConsumer(consumer);
if(flag){
return R.ok().message("文件上传成功!!");
}else {
return R.error().message("文件上传失败!!");
}
} catch (IOException e) {
return R.error().message("文件上传失败!! "+ e.getMessage());
}
}
}
2、前端编写
<template>
<div class="table">
<div class="container">
<div class="handle-box">
<el-button type="primary" size="mini" @click="delAll">批量删除</el-button>
<el-input v-model="select_word" size="mini" placeholder="筛选相关用户" class="handle-input"></el-input>
<el-button type="primary" size="mini" @click="centerDialogVisible = true">添加新用户</el-button>
</div>
</div>
<el-table size="mini" ref="multipleTable" border style="width:100%" height="680px" :data="data" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="40"></el-table-column>
<el-table-column label="用户图片" width="110" align="center">
<template slot-scope="scope">
<div class="consumer-img">
<img :src="getUrl(scope.row.avator)" style="width:100%"/>
</div>
<el-upload :action="uploadUrl(scope.row.id)" :before-upload="beforeAvatorUpload"
:on-success="handleAvatorSuccess">
<el-button size="mini">更新图片</el-button>
</el-upload>
</template>
</el-table-column>
<el-table-column prop="username" label="用户名" width="120" align="center"></el-table-column>
<el-table-column label="性别" width="50" align="center">
<template slot-scope="scope">
{{changeSex(scope.row.sex)}}
</template>
</el-table-column>
<el-table-column prop="phoneNum" label="手机号" width="120" align="center"></el-table-column>
<el-table-column prop="email" label="电子邮箱" width="240" align="center"></el-table-column>
<el-table-column label="生日" width="120" align="center">
<template slot-scope="scope">
{{attachBirth(scope.row.birth)}}
</template>
</el-table-column>
<el-table-column prop="introduction" label="签名" align="center"></el-table-column>
<el-table-column prop="location" label="地区" width="100" align="center"></el-table-column>
<el-table-column label="操作" width="150" align="center">
<template slot-scope="scope">
<el-button size="mini" @click="handleEdit(scope.row)">编辑</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
</template>
</el-table-column>
</el-table>
<div class="pagination">
<el-pagination
background
layout = "total,prev,pager,next"
:current-page="currentPage"
:page-size="pageSize"
:total="tableData.length"
@current-change="handleCurrentChange"
>
</el-pagination>
</div>
<el-dialog title="添加新用户" :visible.sync="centerDialogVisible" width="400px" center>
<el-form :model="registerForm" ref="registerForm" label-width="80px" :rules="rules">
<el-form-item prop="username" label="用户名" size="mini">
<el-input v-model="registerForm.username" placeholder="用户名"></el-input>
</el-form-item>
<el-form-item prop="password" label="密码" size="mini">
<el-input type="password" v-model="registerForm.password" placeholder="密码"></el-input>
</el-form-item>
<el-form-item label="性别" size="mini">
<input type="radio" name="sex" value="0" v-model="registerForm.sex"> 女
<input type="radio" name="sex" value="1" v-model="registerForm.sex"> 男
</el-form-item>
<el-form-item prop="phoneNum" label="手机号" size="mini">
<el-input v-model="registerForm.phoneNum" placeholder="手机号"></el-input>
</el-form-item>
<el-form-item prop="email" label="电子邮箱" size="mini">
<el-input v-model="registerForm.email" placeholder="电子邮箱"></el-input>
</el-form-item>
<el-form-item prop="birth" label="生日" size="mini">
<el-date-picker type="date" placeholder="选择日期" v-model="registerForm.birth" style="width:100%"></el-date-picker>
</el-form-item>
<el-form-item prop="introduction" label="签名" size="mini">
<el-input v-model="registerForm.introduction" placeholder="签名"></el-input>
</el-form-item>
<el-form-item prop="location" label="地区" size="mini">
<el-input v-model="registerForm.location" placeholder="地区"></el-input>
</el-form-item>
</el-form>
<span slot="footer">
<el-button size="mini" @click="centerDialogVisible = false">取消</el-button>
<el-button size="mini" @click="addConsumer">确定</el-button>
</span>
</el-dialog>
<el-dialog title="修改用户" :visible.sync="editVisible" width="400px" center>
<el-form :model="form" ref="form" label-width="80px" :rules="rules">
<el-form-item prop="username" label="用户名" size="mini">
<el-input v-model="form.username" placeholder="用户名"></el-input>
</el-form-item>
<el-form-item prop="password" label="密码" size="mini">
<el-input type="password" v-model="form.password" placeholder="密码"></el-input>
</el-form-item>
<el-form-item label="性别" size="mini">
<input type="radio" name="sex" value="0" v-model="form.sex"> 女
<input type="radio" name="sex" value="1" v-model="form.sex"> 男
</el-form-item>
<el-form-item prop="phoneNum" label="手机号" size="mini">
<el-input v-model="form.phoneNum" placeholder="手机号"></el-input>
</el-form-item>
<el-form-item prop="email" label="电子邮箱" size="mini">
<el-input v-model="form.email" placeholder="电子邮箱"></el-input>
</el-form-item>
<el-form-item prop="birth" label="生日" size="mini">
<el-date-picker type="date" placeholder="选择日期" v-model="form.birth" style="width:100%"></el-date-picker>
</el-form-item>
<el-form-item prop="introduction" label="签名" size="mini">
<el-input v-model="form.introduction" placeholder="签名"></el-input>
</el-form-item>
<el-form-item prop="location" label="地区" size="mini">
<el-input v-model="form.location" placeholder="地区"></el-input>
</el-form-item>
</el-form>
<span slot="footer">
<el-button size="mini" @click="editVisible = false">取消</el-button>
<el-button size="mini" @click="editSave">确定</el-button>
</span>
</el-dialog>
<el-dialog title="删除用户" :visible.sync="delVisible" width="300px" center>
<div align="center">删除不可恢复,是否确定删除?</div>
<span slot="footer">
<el-button size="mini" @click="delVisible = false">取消</el-button>
<el-button size="mini" @click="deleteRow">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import {getAllConsumer,setConsumer,updateConsumer,delConsumer} from '../api/consumer/index';
import { mixin } from '../mixins/index';
export default {
mixins: [mixin],
data(){
return{
centerDialogVisible: false, //添加弹窗是否显示
editVisible: false, //编辑弹窗是否显示
delVisible: false, //删除弹窗是否显示
registerForm:{ //添加框
username: '',
password: '',
sex: '1',
phoneNum: '',
email: '',
birth: '',
introduction: '',
location: ''
},
form:{ //编辑框
id: '',
username: '',
password: '',
sex: '',
phoneNum: '',
email: '',
birth: '',
introduction: '',
location: ''
},
tableData: [],
tempData: [],
select_word: '',
pageSize: 5, //分页每页大小
currentPage: 1, //当前页
idx: -1, //当前选择项
multipleSelection: [], //哪些项已经打勾
rules: {
username: [
{required: true,message: '请输入用户名',trigger: 'blur'}
],
password: [
{required: true,message: '请输入密码',trigger: 'blur'}
],
phoneNum: [
{required: true,message: '请输入手机号',trigger: 'blur'}
],
email: [
{required: true,message: '请输入电子邮箱',trigger: 'blur'},
{type: 'email',message:'请输入正确的电子邮箱地址',trigger:['blur','change']}
],
introduction: [
{required: true,message: '请输入签名',trigger: 'blur'}
],
location: [
{required: true,message: '请输入地区',trigger: 'blur'}
]
}
}
},
computed:{
//计算当前搜索结果表里的数据
data(){
return this.tableData.slice((this.currentPage - 1) * this.pageSize,this.currentPage * this.pageSize)
}
},
watch:{
//搜索框里面的内容发生变化的时候,搜索结果table列表的内容跟着它的内容发生变化
select_word: function(){
if(this.select_word == ''){
this.tableData = this.tempData;
}else{
this.tableData = [];
for(let item of this.tempData){
if(item.username.includes(this.select_word)){
this.tableData.push(item);
}
}
}
}
},
created(){
this.getData();
},
methods:{
//获取当前页
handleCurrentChange(val){
this.currentPage = val;
},
//查询所有用户
getData(){
this.tempData = [];
this.tableData = [];
getAllConsumer().then(res => {
this.tempData = res.data.list;
this.tableData = res.data.list;
this.currentPage = 1;
})
},
//添加用户
addConsumer(){
this.$refs['registerForm'].validate(valid =>{
if(valid){
let d = this.registerForm.birth;
let datetime = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
let params = new URLSearchParams();
params.append('username',this.registerForm.username);
params.append('password',this.registerForm.password);
params.append('sex',this.registerForm.sex);
params.append('phoneNum',this.registerForm.phoneNum);
params.append('email',this.registerForm.email);
params.append('birth',datetime);
params.append('introduction',this.registerForm.introduction);
params.append('location',this.registerForm.location);
params.append('avator','/img/avatorImages/user.jpg');
setConsumer(params)
.then(res => {
if(res.code == 20000){
this.getData();
this.notify("添加成功","success");
}else{
this.notify("添加失败","error");
}
})
.catch(err => {
console.log(err);
});
this.centerDialogVisible = false;
}
})
},
//弹出编辑页面
handleEdit(row){
this.editVisible = true;
this.form = {
id: row.id,
username: row.username,
password: row.password,
sex: row.sex,
phoneNum: row.phoneNum,
email: row.email,
birth: row.birth,
introduction: row.introduction,
location: row.location
}
},
//保存编辑页面修改的数据
editSave(){
this.$refs['form'].validate(valid =>{
if(valid){
let d = new Date(this.form.birth);
let datetime = d.getFullYear()+'-'+(d.getMonth()+1)+'-'+d.getDate();
let params = new URLSearchParams();
params.append('id',this.form.id);
params.append('username',this.form.username);
params.append('password',this.form.password);
params.append('sex',this.form.sex);
params.append('phoneNum',this.form.phoneNum);
params.append('email',this.form.email);
params.append('birth',datetime);
params.append('introduction',this.form.introduction);
params.append('location',this.form.location);
updateConsumer(params)
.then(res => {
if(res.code == 20000){
this.getData();
this.notify("修改成功","success");
}else{
this.notify("修改失败","error");
}
})
.catch(err => {
console.log(err);
});
this.editVisible = false;
}
})
},
//更新图片
uploadUrl(id){
return `${this.$store.state.HOST}/musicserver/consumer/updateConsumerPic?id=${id}`
},
//删除一名用户
deleteRow(){
delConsumer(this.idx)
.then(res => {
if(res.code == 20000){
this.getData();
this.notify("删除成功","success");
}else{
this.notify("删除失败","error");
}
})
.catch(err => {
console.log(err);
});
this.delVisible = false;
}
}
}
</script>
<style scoped>
.handle-box{
margin-bottom: 20px;
}
.consumer-img{
width: 100%;
height: 80px;
border-radius: 5px;
margin-bottom: 5px;
overflow: hidden;
}
.handle-input{
width: 300px;
display: inline-block;
}
.pagination{
display: flex;
justify-content: center;
}
</style>
编写请求后端接口的方法
import {get,post} from '../http'
//============用户相关================
//查询用户
export const getAllConsumer =() => get(`musicserver/consumer/allConsumer`);
//添加用户
export const setConsumer = (params) => post(`musicserver/consumer/addConsumer`,params);
//编辑用户
export const updateConsumer = (params) => post(`musicserver/consumer/updateConsumer`,params);
//删除用户
export const delConsumer = (id) => get(`musicserver/consumer/deleteConsumer?id=${id}`);
引入请求后端接口方法