一、项目概述
后端:Python,Django框架
前端:Vue,Element-ui
数据库:MySQL
使用工具:PyCharm,Visual Studio Code
二、效果展示
2.1: 主页面展示
2.2: 查看学生信息
2.3: 增加页面
2.4: 修改页面
2.5: 删除页面
三、数据库配置
3.1: 数据库连接(settings.py)
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": 'studentbe', //数据库名
"USER": 'root', //用户名称
"PASSWORD": '123456', //用户密码
"HOST": '127.0.0.1', //一般默认为127.0.0.1
"POST": '3306' //端口
}
3.2: 数据库(models.py)
#Student: 学号,姓名,性别,出生日期,手机号码,邮箱住址,家庭住址,照片
class Student(models.Model):
gender_choices = (('男','男'),('女','女'))
sno = models.IntegerField(db_column="SNo",primary_key=True,null=False) #学号,不允许为空
name = models.CharField(db_column="SName",max_length=100,null=False) #姓名,最长为100
gender = models.CharField(db_column="Gender",max_length=100,choices=gender_choices) #性别
birthday = models.DateField(db_column="Birthday",null=False) #出生日期,不允许为空
mobile = models.CharField(db_column="Mobile",max_length=100) #手机号码
email = models.CharField(db_column="Email",max_length=100) #邮箱地址
address = models.CharField(db_column="Address",max_length=200) #家庭住址
image = models.CharField(db_column="Image",max_length=200,null=True) #照片
#默认情况下生成的标名为:App_class,如果需要自定义表名,需要使用class Meta
class Meta:
managed = True
db_table = "Student"
#_str_方法
def _str_(self):
return "学号:%s\t姓名:%s\t性别:%s" %(self.sno,self.name,self.gender)
3.3: 创建数据库
终端里输入
python manage.py makemigrations
python manage.py migrate
四、后端代码编写
4.1: view.py
from django.shortcuts import render
# Create your views here.
# 引入Student的类
from student.models import Student
# 引入JsonResponse模块
from django.http import JsonResponse
# 导入json模块
import json
# 导入Q查询
from django.db.models import Q
# 导入settings
from django.conf import settings
# 导入os
import os
# 导入uuid类
import uuid
# 导入哈希库
import hashlib
import openpyxl
"""获取所有学生的信息"""
def get_student(request):
try:
# 使用ORM获取所有学生信息 并把对象转为字典格式
obj_students = Student.objects.all().values()
# 把结果转为List
students = list(obj_students)
# 返回
return JsonResponse({'code':1, 'data':students})
except Exception as e:
# 如果出现异常,返回
return JsonResponse({'code': 0, 'msg': "获取学生信息出现异常,具体错误:" + str(e)})
"""查询学生信息"""
def query_students(request):
# 接收传递过来的查询条件--- axios默认是json --- 字典类型('inputstr')-- data['inputstr']
data = json.loads(request.body.decode('utf-8'))
try:
# 使用ORM获取满足条件的学生信息 并把对象转为字典格式
obj_students = Student.objects.filter(Q(sno__icontains=data['inputstr']) |
Q(name__icontains=data['inputstr']) |
Q(gender__icontains=data['inputstr']) |
Q(mobile__icontains=data['inputstr']) |
Q(email__icontains=data['inputstr']) |
Q(address__icontains=data['inputstr'])).values()
# 把外层的容器转为List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
# 如果出现异常,返回
return JsonResponse({'code': 0, 'msg': "查询学生信息出现异常,具体错误:" + str(e)})
"""判断学号是否存在"""
def is_exists_sno(request):
# 接收传递过来的学号
data = json.loads(request.body.decode('utf-8'))
# 进行校验
try:
obj_students = Student.objects.filter(sno=data['sno'])
if obj_students.count() == 0:
return JsonResponse({'code': 1, 'exists': False})
else:
return JsonResponse({'code': 1, 'exists': True})
except Exception as e:
return JsonResponse({'code': 0, 'msg':"校验学号失败,具体原因:" + str(e)})
"""添加学生到数据库"""
def add_student(request):
# 接收前端传递过来的值
data = json.loads(request.body.decode("utf-8"))
try:
# 添加到数据库
obj_student = Student(sno=data['sno'],
name=data['name'],
gender=data['gender'],
birthday=data['birthday'],
mobile=data['mobile'],
email= data['email'],
address=data['address'],
image=data['image'])
# 执行添加
obj_student.save()
# 使用ORM获取所有学生信息 并把对象转为字典格式
obj_students = Student.objects.all().values()
# 把外层的容器转为List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
return JsonResponse({'code':0 , 'msg': "添加到数据库出现异常,具体原因:" + str(e)})
"""修改学生到数据库"""
def update_student(request):
# 接收前端传递过来的值
data = json.loads(request.body.decode("utf-8"))
try:
# 查找到要修改的学生信息
obj_student = Student.objects.get(sno=data['sno'])
# 依次修改
obj_student.name = data['name']
obj_student.gender = data['gender']
obj_student.birthday = data['birthday']
obj_student.mobile = data['mobile']
obj_student.email = data['email']
obj_student.address = data['address']
obj_student.image = data['image']
# 保存
obj_student.save()
# 使用ORM获取所有学生信息 并把对象转为字典格式
obj_students = Student.objects.all().values()
# 把外层的容器转为List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
return JsonResponse({'code':0 , 'msg': "修改保存到数据库出现异常,具体原因:" + str(e)})
"""删除一条学生信息"""
def delete_student(request):
# 接收前端传递过来的值
data = json.loads(request.body.decode("utf-8"))
try:
# 查找到要修改的学生信息
obj_student = Student.objects.get(sno=data['sno'])
# 删除
obj_student.delete()
# 使用ORM获取所有学生信息 并把对象转为字典格式
obj_students = Student.objects.all().values()
# 把外层的容器转为List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
return JsonResponse({'code': 0, 'msg': "删除学生信息写入数据库出现异常,具体原因:" + str(e)})
"""批量删除学生信息"""
def delete_students(request):
# 接收前端传递过来的值
data = json.loads(request.body.decode("utf-8"))
try:
# 遍历传递的集合
for one_student in data['student']:
# 查询当前记录
obj_student = Student.objects.get(sno=one_student['sno'])
# 执行删除
obj_student.delete()
# 使用ORM获取所有学生信息 并把对象转为字典格式
obj_students = Student.objects.all().values()
# 把外层的容器转为List
students = list(obj_students)
# 返回
return JsonResponse({'code': 1, 'data': students})
except Exception as e:
return JsonResponse({'code': 0, 'msg': "批量删除学生信息写入数据库出现异常,具体原因:" + str(e)})
"""接收上传的文件"""
def upload(request):
# 接收上传的文件
rev_file = request.FILES.get('avatar')
# 判断,是否有文件
if not rev_file:
return JsonResponse({'code':0, 'msg':'图片不存在!'})
# 获得一个唯一的名字: uuid +hash
new_name = get_random_str()
# 准备写入的URL
file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1] )
# 开始写入到本次磁盘
try:
f = open(file_path,'wb')
# 多次写入
for i in rev_file.chunks():
f.write(i)
# 要关闭
f.close()
# 返回
return JsonResponse({'code': 1, 'name': new_name + os.path.splitext(rev_file.name)[1]})
except Exception as e:
return JsonResponse({'code':0, 'msg':"系统报错:" + str(e)})
def get_random_str():
#获取uuid的随机数: uuid共5种生成随机数的方法,这里选用第4种
uuid_val = uuid.uuid4()
#获取uuid的随机数字符串
uuid_str = str(uuid_val).encode('utf-8')
#获取md5实例
md5 = hashlib.md5()
#拿取uuid的md5摘要
md5.update(uuid_str)
#返回固定长度的字符串
return md5.hexdigest()
"""从Excel批量导入学生信息"""
def import_students_excel(request):
# ========1.接收Excel文件存储到Media文件夹 =======
rev_file = request.FILES.get('excel')
# 判断,是否有文件
if not rev_file:
return JsonResponse({'code': 0, 'msg': 'Excel文件不存在!'})
# 获得一个唯一的名字: uuid +hash
new_name = get_random_str()
# 准备写入的URL
file_path = os.path.join(settings.MEDIA_ROOT, new_name + os.path.splitext(rev_file.name)[1])
# 开始写入到本次磁盘
try:
f = open(file_path, 'wb')
# 多次写入
for i in rev_file.chunks():
f.write(i)
# 要关闭
f.close()
except Exception as e:
return JsonResponse({'code': 0, 'msg': str(e)})
#====== 2.读取存储在Media文件夹的数据 =====
ex_students = read_excel_dict(file_path)
# ====3.把读取的数据存储到数据库 =====
# 定义几个变量: success: error: errors
success = 0
error = 0
error_snos = []
# 开始遍历
for one_student in ex_students:
try:
obj_student = Student.objects.create(sno=one_student['sno'],
name=one_student['name'],
gender=one_student['gender'],
birthday=one_student['birthday'],
mobile=one_student['mobile'],
email=one_student['email'],
address=one_student['address'])
# 计数
success += 1
except:
# 如果失败了
error += 1
error_snos.append(one_student['sno'])
# 4. 返回--导入信息(成功:5,失败:4--(sno)),所有学生
obj_students = Student.objects.all().values()
students = list(obj_students)
return JsonResponse({'code':1, 'success':success,'error':error,'errors':error_snos, 'data':students})
"""导出数据到excel"""
def export_student_excel(request):
#获取所有的学生信息
obj_students = Student.objects.all().values()
#转为List
students = list(obj_students)
#准备名称
excel_name = get_random_str() + ".xlsx"
#准备写入的路径
path = os.path.join(settings.MEDIA_ROOT, excel_name)
#写入到excel
write_to_excel(students, path)
#返回
return JsonResponse({'code':1, 'name':excel_name})
"""读取Excel数据,存储为字典 --- [{},{},{},]"""
def read_excel_dict(path:str):
# 实例化一个wrokbook
workbook = openpyxl.load_workbook(path)
# 实例化一个sheet
sheet = workbook['student']
# 定义一个变量存储最终的数据--[]
students = []
# 准备key
keys = ['sno','name','gender','birthday','mobile','email','address']
# 遍历
for row in sheet.rows:
# 定义一个临时的字典
temp_dict = {}
# 组合值和key
for index,cell in enumerate(row):
# 组和
temp_dict[keys[index]] = cell.value
# 附加到list中
students.append(temp_dict)
#返回
return students
"""把数据库写入到Excel"""
def write_to_excel(data:list, path:str):
# 实例化一个workbook
workbook = openpyxl.Workbook()
# 激活一个sheet
sheet = workbook.active
# 为sheet命名
sheet.title = 'student'
# 准备keys
keys = data[0].keys()
# 准备写入数据
for index, item in enumerate(data):
# 遍历每一个元素
for k,v in enumerate(keys):
sheet.cell(row=index + 1, column=k + 1, value=str(item[v]))
# 写入到文件
workbook.save(path)
4.2: urls.py
from django.contrib import admin
from django.urls import path
from student import views
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path("admin/", admin.site.urls),
path('students/',views.get_student), # 获取所有学生信息的接口
path('students/query/', views.query_students), # 查询学生信息的接口
path('sno/check/', views.is_exists_sno), # 校验学号是否存在
path('student/add/', views.add_student), # 添加学生信息的接口
path('student/update/', views.update_student), # 修改学生信息的接口
path('student/delete/', views.delete_student), # 删除一个学生信息的接口
path('students/delete/', views.delete_students), # 批量删除学生信息的接口
path('upload/', views.upload), # 上传文件的接口
path('excel/import/', views.import_students_excel), # 导入Excel文件
path('excel/export/', views.export_student_excel), # 导出Excel文件
]
# 允许media中的所有文件被访问
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
五、前端编写
5.1: vue框架(不涉及vue脚手架)
5.2: index.css
html,body,#app,.el-container{
margin: 0px;
padding:0px;
height: 100%;
}
.el-header {
background-color: #b3c0d1;
color: #333;
text-align: left;
line-height: 80px;
font-size:32px;
font-weight: bold;
}
.el-footer {
background-color: #b3c0d1;
color: #333;
text-align: center;
line-height: 30px;
}
.el-aside {
background-color: #d3dce6;
color: #333;
text-align: center;
line-height: 200px;
}
.el-dialog .avatar-uploader .el-upload {
border: 1px dashed #d9d9d9;
border-radius: 6px;
cursor: pointer;
position: relative;
overflow: hidden;
}
.el-dialog .avatar-uploader .el-upload:hover {
border-color: #409EFF;
}
.el-dialog .avatar-uploader-icon {
font-size: 28px;
color: #8c939d;
width: 178px;
height: 178px;
line-height: 178px;
text-align: center;
}
.el-dialog .avatar {
width: 178px;
height: 178px;
display: block;
}
5.3: index.js
const app = new Vue({
el: '#app',
data() {
//校验学号是否存在!
const rulesSNo = (rule, value, callback) => { //格式是固定的
if (this.isEdit) { //修改功能现实时,学号写死
callback();
}
//使用Axios进行校验
axios.post(
this.baseURL + 'sno/check/',
{
sno: value,
}
)
.then((res) => {
//请求成功
if (res.data.code === 1) {
if (res.data.exists) {
callback(new Error("学号已存在!"));
} else {
callback();
}
} else {
//请求失败
callback(new Error("校验学号后端出现异常!"))
}
})
.catch((err) => {
//如果请求失败在控制台打印
console.log(err);
});
}
return {
students: [], //所有的学生信息
pageStudents: [], //分页后当前页的学生
baseURL: "http://192.168.xx.xx:8000/",
inputStr: '', //输入的查询条件
selectStudents: [], //选择复选框是把选择记录存在这个几个
//====分页相关的变量====
total: 0, //数据的总行数
currentpage: 1, //当前的所在的页
pagesize: 10, //每页显示多少行数据
//====弹出框表单====
dialogVisible: false, //控制弹出框表单是否展示
dialogTitle: "", //弹出框的标题
isView: false, //标识是否是查看
isEdit: false, //标识是否是修改
studentForm: { //弹出框表单对相应绑定数据
sno: '', //序号
name: '', //姓名
gender: '', //性别
birthday: '', //生日
mobile: '', //手机号
email: '', //邮箱
address: '', //家庭地址
image: '', //照片
imageUrl: '',
},
rules: {
sno: [
{ required: true, message: '学号不能为空', trigger: 'blur' },
{ pattern: /^[9][5]\d{3}$/, message: '学号必须是95开头的五位数', trigger: 'blur' }, //正则表达式95开头的5个数字
{ validator: rulesSNo, trigger: 'blur' }, //校验学号是否存在!
],
name: [
{ required: true, message: '姓名不能为空', trigger: 'blur' },
{ pattern: /^[\u4e00-\u9fa5]{2,5}$/, message: '姓名必须是2-5个汉字', trigger: 'blur' },//2-5个汉字
],
gender: [
{ required: true, message: '性别不能为空', trigger: 'change' }, //只能填写男或女
],
birthday: [
{ required: true, message: '出生日期不能为空', trigger: 'change' }, //符合yyyy-MM-dd要求
],
mobile: [
{ required: true, message: '手机号码不能为空', triggler: 'blur' },
{ pattern: /^[1][35789]\d{9}$/, message: '手机号码必须要符合规范', trigger: 'blur' }, //[1][35789]\d{9}
],
email: [
{ required: true, message: '邮箱地址不能为空', trigger: 'blur' },
{ pattern: /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/, message: '邮箱地址必须要符合规范', trigger: 'blur' },
],
address: [
{ required: true, message: '家庭住址不能为空', trigger: 'blur' }, //不能为空
]
}
}
},
mounted() {
//自动加载数据
this.getStudents();
},
methods: {
//根据Id获取image
getImageBySno(sno) {
//遍历
for (oneStudent of this.students) {
//判断
if (oneStudent.sno == sno) {
return oneStudent.image;
}
}
},
//获取所有学生信息
getStudents: function () {
//记录this的地址
let that = this
//使用Axios实现Ajax请求
axios
.get(that.baseURL + "students/")
.then(function (res) {
//请求成功后执行的函数
if (res.data.code === 1) {
//把数据给students
that.students = res.data.data;
//获取返回记录的总行数
that.total = res.data.data.length;
//获取当前页的数据
that.getPageStudents();
//提示:
that.$message({
message: '数据加载成功!',
type: 'success'
});
console.log(that.students)
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
})
.catch(function (err) {
//请求失败后执行的函数
console.log(err);
});
},
getAllStudents() {
//清空输入的inputStr
this.inputStr = "";
//获取所有的数据
this.getStudents();
},
//获取当前页的学生数据
getPageStudents() {
//清空pageStudents中的数据
this.pageStudents = [];
//获得当前页的数据
for (let i = (this.currentpage - 1) * this.pagesize; i < this.total; i++) {
//遍历数据添加到pageStudent中
this.pageStudents.push(this.students[i]);
//判断是否达到一页的要求
if (this.pageStudents.length === this.pagesize) break;
}
},
//实现学生信息查询
queryStudents() {
//使用Ajax请求--POST-->传递InputStr
let that = this
//开始Ajax请求
axios
.post(
that.baseURL + "students/query/",
{
inputstr: that.inputStr,
}
)
.then(function (res) { //成功
if (res.data.code === 1) {
//把数据给students
that.students = res.data.data;
//获取返回记录的总行数
that.total = res.data.data.length;
//获取当前页的数据
that.getPageStudents();
//提示:
that.$message({
message: '查询数据加载成功!',
type: 'success'
});
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
})
.catch(function (err) { //失败
console.log(err);
that.$message.error("获取后端查询结果出现异常!");
});
},
//添加学生时打开表单
addStudent() {
//修改标题
this.dialogTitle = "添加学生明细";
//弹出表单
this.dialogVisible = true;
},
//查看学生的明细
viewStudent(row) {
//修改标题
this.dialogTitle = "查看学生明细";
//修改isView变量
this.isView = true;
//弹出表单
this.dialogVisible = true;
/*
深拷贝方法01:
this.studentForm.sno = row.sno;
this.studentForm.name = row.name;
this.studentForm.gender = row.gender;
this.studentForm.birthday = row.birthday;
this.studentForm.mobile = row.mobile;
this.studentForm.email = row.email;
this.studentForm.address = row.address;
*/
//深拷贝方法02:
this.studentForm = JSON.parse(JSON.stringify(row))
//获取照片
this.studentForm.image = this.getImageBySno(row.sno);
//获取照片URL
this.studentForm.imageUrl = this.baseURL + 'media/' + this.studentForm.image;
},
//修改学生的明细
updateStudent(row) {
//修改标题
this.dialogTitle = "修改学生明细";
//修改isEdit变量
this.isEdit = true;
//弹出表单
this.dialogVisible = true;
//深拷贝方法:
this.studentForm = JSON.parse(JSON.stringify(row))
//获取照片
this.studentForm.image = this.getImageBySno(row.sno);
//获取照片URL
this.studentForm.imageUrl = this.baseURL + 'media/' + this.studentForm.image;
},
//提交学生的表单(添加、修改)
submitStudentForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {
//校验成功后,执行添加或者修改?
if (this.isEdit) {
//修改
this.submitUpdateStudent();
} else {
//添加
this.submitAddStudent();
}
} else {
console.log('error submit!!');
return false;
}
});
},
//添加到数据库的函数
submitAddStudent() {
//定义that
let that = this;
//执行Axios请求
axios
.post(that.baseURL + 'student/add/', that.studentForm)
.then(res => {
//执行成功
if (res.data.code === 1) {
//获取所有学生的信息
that.students = res.data.data;
//获取记录条数
that.total = res.data.data.length;
//获取分页信息
that.getPageStudents();
//提示:
that.$message({
message: '数据添加成功!',
type: 'success'
});
//关闭窗体
this.closeDialogForm('studentForm');
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
})
.catch(err => {
//执行失败
console.log(err);
that.$message.error("获取后端查询结果出现异常!");
})
},
//修改更新到数据库
submitUpdateStudent() {
//定义that
let that = this;
//执行Axios请求
axios
.post(that.baseURL + 'student/update/', that.studentForm)
.then(res => {
//执行成功
if (res.data.code === 1) {
//获取所有学生的信息
that.students = res.data.data;
//获取记录条数
that.total = res.data.data.length;
//获取分页信息
that.getPageStudents();
//提示:
that.$message({
message: '数据修改成功!',
type: 'success'
});
//关闭窗体
this.closeDialogForm('studentForm');
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
})
.catch(err => {
//执行失败
console.log(err);
that.$message.error("修改时获取后端查询结果出现异常!");
})
},
//删除一条学生记录
deleteStudent(row) {
//等待确认
this.$confirm('是否确认删除学生信息为学号:' + row.sno + '\t姓名:' + row.name + ']的学生信息?',
'提示', {
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//确认删除响应事件
let that = this
//调用后端接口
axios.post(that.baseURL + 'student/delete/', { sno: row.sno })
.then(res => {
if (res.data.code === 1) {
//获取所有学生信息
that.students = res.data.data;
//获取记录数
that.total = res.data.data.length;
//分页
that.getPageStudents();
//提示
that.$message({
message: '数据删除成功!',
type: 'success'
});
} else {
that.$message.error(res.data.msg);
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
//批量删除
deleteStudents() {
//等待确认
this.$confirm("是否确认批量删除" + this.selectStudents.length + "个学生信息吗?",
'提示', {
confirmButtonText: '确定删除',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//确认删除响应事件
let that = this
//调用后端接口
axios.post(that.baseURL + 'students/delete/', { student: that.selectStudents })
.then(res => {
if (res.data.code === 1) {
//获取所有学生信息
that.students = res.data.data;
//获取记录数
that.total = res.data.data.length;
//分页
that.getPageStudents();
//提示
that.$message({
message: '数据批量删除成功!',
type: 'success'
});
} else {
that.$message.error(res.data.msg);
}
})
}).catch(() => {
this.$message({
type: 'info',
message: '已取消删除'
});
});
},
//关闭弹出框的表单
closeDialogForm(formName) {
//重置表单的校验
this.$refs[formName].resetFields();
//清空
this.studentForm.sno = "";
this.studentForm.name = "";
this.studentForm.gender = "";
this.studentForm.birthday = "";
this.studentForm.mobile = "";
this.studentForm.email = "";
this.studentForm.address = "";
this.studentForm.image = "",
this.studentForm.imageUrl = "",
//关闭
this.dialogVisible = false;
//初始化isView和isEdit值
this.isEdit = false;
this.isView = false;
},
//选择学生头像后点击确定后触发的事件
uploadPicturePost(file) {
//定义that
let that = this;
//定义一个FormData类
let fileReq = new FormData();
//把照片传进去
fileReq.append('avatar', file.file); //--保持与后端完全一致
//使用Axios发起Ajax请求
axios(
{
method: 'post',
url: that.baseURL + 'upload/',
data: fileReq
}
).then(res => {
// 根据code判断是否成功
if (res.data.code === 1) {
//把照片给image
that.studentForm.image = res.data.name;
//拼接imageurl
that.studentForm.imageUrl = that.baseURL + "media/" + res.data.name;
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
}).catch(err => {
console.log(err);
that.$message.error("上传头像出现异常!");
})
},
//导入excel
uploadExcelPost(file) {
let that = this
//实例化一个formdata
//定义一个FormData类
let fileReq = new FormData();
//把照片穿进去
fileReq.append('excel', file.file);
//使用Axios发起Ajax请求
axios(
{
method: 'post',
url: that.baseURL + 'excel/import/',
data: fileReq
}
).then(res => {
// 根据code判断是否成功
if (res.data.code === 1) {
//把照片给image
that.students = res.data.data;
//计算总共多少条
that.total = res.data.data.length;
//分页
that.getPageStudents();
//弹出框体显示结果
this.$alert('本次导入完成!成功:' + res.data.success +'失败:'+ res.data.error
, '导入结果展示', {
confirmButtonText: '确定',
callback: action => {
this.$message({
type: 'info',
message: "本次导入失败数量为:" + res.data.error + ",具体的学号:"+res.data.errors,
});
}
});
//把失败明细打印
console.log("本次导入失败数量为:" + res.data.error + ",具体的学号:");
console.log(res.data.errors);
} else {
//失败的提示!
that.$message.error(res.data.msg);
}
}).catch(err => {
console.log(err);
that.$message.error("上传Excel出现异常!");
})
},
//导出excel
exportToExcel(){
let that = this
axios.get(that.baseURL + 'excel/export/')
.then(res=>{
if(res.data.code ===1){
//拼接excel 的完整URL
let url = that.baseURL + 'media/'+ res.data.name;
//下载
window.open(url);
} else {
that.$message.error("导出Excel出现异常");
}
})
.catch(err=>{
console.log(err);
});
},
//分页时修改每页的行数
handleSizeChange(size) {
//修改当前每页数据行数
this.pagesize = size;
//数据重新分页
this.getPageStudents();
},
//调整当前的页码
handleCurrentChange(pageNumber) {
//修改当前的页码
this.currentpage = pageNumber;
//数据重新分页
this.getPageStudents();
},
//选择复选框时触发的操作
handleSelectionChange(data) {
this.selectStudents = data;
console.log(data);
},
},
})
注意:baseURL: "http://192.168.xx.xx:8000/"中,192.168.xx.xx为自己电脑的ip地址,8000为端口号
5.4: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>学生信息管理系统</title>
<!-- 引入外部的样式文件 -->
<link rel="stylesheet" href="./css/index.css" />
<!-- 引入Element UI样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<!-- 使用CDN引入Vue模块-->
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<!-- 引入Element组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- 引入Axios组件库 -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<el-container>
<el-header style="height: 80px;">学生信息管理系统</el-header>
<el-container>
<!-- 侧边栏 -->
<el-aside width="200px">
<el-menu default-active="2" class="el-menu-vertical-demo">
<el-menu-item index="1">
<i class="el-icon-menu"></i>
<span slot="title">班级管理</span>
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-user"></i>
<span slot="title">学生信息</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-s-custom"></i>
<span slot="title">讲师信息</span>
</el-menu-item>
<el-menu-item index="4">
<i class="el-icon-document"></i>
<span slot="title">课程管理</span>
</el-menu-item>
</el-menu>
</el-aside>
<el-container>
<!-- 主窗体 -->
<el-main>
<!-- 面包屑导航 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<el-breadcrumb-item>首页</el-breadcrumb-item>
<el-breadcrumb-item>学生管理</el-breadcrumb-item>
</el-breadcrumb>
<!-- 表单 -->
<el-form :inline="true" style="margin-top:30px;">
<el-row>
<el-col :span="12">
<el-form-item label="请输入查询条件:">
<el-input v-model="inputStr" placeholder="输入查询条件" style="width: 420px;">
</el-input>
</el-form-item>
</el-col>
<el-col :span="8" style="text-align: right;padding-right:10px;">
<el-button-group>
<el-button type="primary" icon="el-icon-search" @click="queryStudents()">查询
</el-button>
<el-button type="primary" icon="el-icon-tickets" @click="getAllStudents()">全部
</el-button>
<el-button type="primary" icon="el-icon-circle-plus-outline"
@click="addStudent()">添加</el-button>
</el-button-group>
</el-col>
<el-col :span="2">
<el-upload :show-file-list="false" :http-request="uploadExcelPost">
<el-button type="primary">导入Excel</el-button>
</el-upload>
</el-col>
<el-col :span="2">
<el-button type="primary" @click="exportToExcel()">导出Excel</el-button>
</el-col>
</el-row>
</el-form>
<!-- 表格 -->
<el-table :data="pageStudents" border style="width: 100%" size="mini"
@selection-change="handleSelectionChange">
<el-table-column type="selection">
</el-table-column>
<el-table-column type="index" label="序号" align="center" width="60">
</el-table-column>
<el-table-column prop="sno" label="学号" width="80">
</el-table-column>
<el-table-column prop="name" label="姓名" width="80">
</el-table-column>
<el-table-column prop="gender" label="性别" width="60">
</el-table-column>
<el-table-column prop="birthday" label="出生日期" align="center" width="100">
</el-table-column>
<el-table-column prop="mobile" label="电话" align="center" width="120">
</el-table-column>
<el-table-column prop="email" label="邮箱" align="center" width="220">
</el-table-column>
<el-table-column prop="address" label="地址" align="center">
</el-table-column>
<el-table-column label="操作" width="180" align="center">
<template slot-scope="scope">
<el-button type="success" icon="el-icon-more" size="mini" circle
@click="viewStudent(scope.row)"></el-button>
<el-button type="primary" icon="el-icon-edit" size="mini" circle
@click="updateStudent(scope.row)"></el-button>
<el-button type="danger" icon="el-icon-delete" size="mini" circle
@click="deleteStudent(scope.row)"></el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<el-row style="margin-top: 20px;">
<el-col :span="8" style="text-align: left">
<el-button type="danger" icon="el-icon-delete" size="mini" @click="deleteStudents()">
批量删除</el-button>
</el-col>
<el-col :span="16" style="text-align: right">
<el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange"
:current-page="currentpage" :page-sizes="[5, 10, 50, 100]" :page-size="pagesize"
layout="total, sizes, prev, pager, next, jumper" :total="total">
</el-pagination>
</el-col>
</el-row>
<!-- 弹出框的学生明细表单 -->
<el-dialog :title="dialogTitle" :visible.sync="dialogVisible" width="50%"
@close="closeDialogForm('studentForm')">
<el-form :model="studentForm" :rules="rules" ref="studentForm" :inline="true"
style="margin-left: 20px;" label-width="110px" label-position="right" size="mini">
<el-upload class="avatar-uploader"
:show-file-list="false" :http-request="uploadPicturePost" :disabled="isView" style="text-align: center;margin:20px;" >
<img v-if="studentForm.image" :src="studentForm.imageUrl" class="avatar">
<i v-else class="el-icon-plus avatar-uploader-icon"></i>
</el-upload>
<el-form-item label="学号:" prop="sno">
<el-input v-model="studentForm.sno" :disabled="isEdit||isView"
suffix-icon="el-icon-edit"></el-input>
</el-form-item>
<el-form-item label="姓名:" prop="name">
<el-input v-model="studentForm.name" :disabled="isView" suffix-icon="el-icon-edit">
</el-input>
</el-form-item>
<el-form-item label="性别:" prop="gender">
<el-select v-model="studentForm.gender" :disabled="isView" placeholder="请选择性别">
<el-option value="男"></el-option>
<el-option value="女"></el-option>
</el-select>
</el-form-item>
<el-form-item label="出生日期:" prop="birthday">
<el-date-picker v-model="studentForm.birthday" value-format="yyyy-MM-dd"
:disabled="isView" type="date" placeholder="选择日期" style="width:93% ">
</el-date-picker>
</el-form-item>
<el-form-item label="手机号码:" prop="mobile">
<el-input v-model="studentForm.mobile" :disabled="isView"
suffix-icon="el-icon-edit"></el-input>
</el-form-item>
<el-form-item label="邮箱地址:" prop="email">
<el-input v-model="studentForm.email" :disabled="isView" suffix-icon="el-icon-edit">
</el-input>
</el-form-item>
<el-form-item label="家庭住址:" prop="address">
<el-input v-model="studentForm.address" :disabled="isView"
suffix-icon="el-icon-edit" style="width:262%"></el-input>
</el-form-item>
</el-form>
<span slot="footer" class="dialog-footer">
<el-button type="primary" size="mini" v-show="!isView"
@click="submitStudentForm('studentForm')">确 定</el-button>
<el-button type="info" size="mini" @click="closeDialogForm('studentForm')">取 消
</el-button>
</span>
</el-dialog>
</el-main>
<el-footer style="height: 30px;">学生信息管理系统 版权所有:Django | 2024-4-20</el-footer>
</el-container>
</el-container>
</el-container>
</div>
</body>
</html>
<!-- 引入Vue代码 -->
<script src="js/index.js"></script>
六、项目完整代码
版权归原作者 べ承诺ゞ都苍茫的可笑の、 所有, 如有侵权,请联系我们删除。