编写登录页面,让自己的页面有权限管理功能。
cookie:服务器会自动将cookie响应给浏览器;浏览器接收到响应回来的数据后,会自动将cookie存储在浏览器本地;在后续的请求中,浏览器会自动将cookie携带到服务器中。
login.html
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--引入组件库-->
<script src="js/jquery.min.js"></script>
<script src="js/vue.js"></script>
<script src="js/element.js"></script>
<script src="js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="js/element.css">
<title>登录页面</title>
</head>
<body>
<div id="app">
<div class="Login_container">
<div class="Login_box">
<div class="avatar_box">
<img src="./img/head.jpg" alt="">
</div>
<!--登录表单区-->
<el-form :model="form" :rules="rules" ref="loginForm" label-width="80px" class="login_form">
<el-form-item label="用户" prop="username">
<el-input v-model="form.username"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="form.password"></el-input>
</el-form-item>
<div class="btns">
<el-button type="primary" :plain="true" @click="onSubmit">登录</el-button>
<el-button type="primary" @click="resetForm('loginForm')">重置</el-button>
</div>
</el-form>
</div>
</div>
</div>
</body>
<script>
new Vue({
el: "#app",
data() {
return {
//登录表单的数据绑定对象
form: {
username: '',
password: ''
},
//表单的验证规则对象
rules: {
//用户名合法
username: [
{required: true, message: '请输入登录名称', trigger: 'blur'},
{min: 3, max: 10, message: '长度在 3 到 10 个字符', trigger: 'blur'}
],
//密码合法
password: [
{required: true, message: '请输入密码', trigger: 'blur'},
{min: 6, max: 15, message: '长度在 6 到 15 个字符', trigger: 'blur'}
]
}
};
},
methods: {
//登录
onSubmit() {
var url = `/login`
console.log(this.form.username);
console.log(this.form.password);
axios.post(url, {
username: this.form.username,
password: this.form.password
})
.then(response => {
if (response.data.code) {
console.log('查询结果不为空');
location.href = 'film.html'
} else {
alert("用户名密码错误")
}
})
.catch(error=>{
console.error(error);
})
},
//重置
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
})
</script>
<style>
#app {
height: 750px;
}
.Login_container {
background-image: url("./img/login.png");
background-size: cover;
background-position: center;
background-repeat: no-repeat;
height: 100%;
/* 如果容器是 body 或其他可能不完全占据视口的元素,你可能需要额外的样式来确保它占据整个视口 */
width: 100%;
}
.Login_box {
width: 450px;
height: 300px;
background-color: rgba(255, 255, 255, 0.3);
border-radius: 3px;
position: absolute;
left: 36%;
top: 50%;
transform: translate(-50%, -50%);
}
.avatar_box {
height: 130px;
width: 130px;
border: 1px solid #eee;
border-radius: 50%;
padding: 8px;
box-shadow: 0 0 10px #ddd;
position: absolute;
left: 50%;
top: 4%;
transform: translate(-50%, -50%);
background-color: #fff;
}
img {
width: 120px;
border-radius: 50%;
background-color: #eee;
}
.login_form {
position: absolute;
bottom: 25px;
left: 30px;
}
.btns {
display: flex;
justify-content: flex-end;
}
</style>
</html>
film.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!--引入组件库-->
<script src="js/jquery.min.js"></script>
<script src="js/vue.js"></script>
<script src="js/element.js"></script>
<script src="js/axios-0.18.0.js"></script>
<link rel="stylesheet" href="js/element.css">
<title>电影信息管理</title>
</head>
<body>
<div id="app">
<div v-if="resData.code==1">
<el-container style="height: 100vh; display: flex; flex-direction: row;">
<!--侧边栏-->
<el-aside width="200px">
<el-menu background-color="#FEF5E4" text-color="#F09466" active-text-color="#ffd04b"
style="position: absolute;top: 100px;">
<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-document"></i>
<span slot="title">
电影信息管理
</span>
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-document"></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-header style="height:80px; position: sticky; top: 0;z-index: 10">
<div>
<img src="./img/head.jpg" alt="">
影院管理系统
</div>
<el-button type="info" @click="back" style="height:40px; background-color: #D7A93A">退出</el-button>
</el-header>
<!--主要内容区-->
<el-main style="flex: 1; overflow: auto;">
<div align="center">
<el-form :inline="true" :model="formInline" class="demo-form-inline">
<el-form-item label="电影名称">
<el-input v-model="formInline.name" placeholder="电影名称"></el-input>
</el-form-item>
<el-form-item label="导演姓名">
<el-input v-model="formInline.director" placeholder="导演姓名"></el-input>
</el-form-item>
<el-form-item label="上映日期">
<div class="block">
<el-date-picker v-model="formInline.date" type="daterange" range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期">
</el-date-picker>
</div>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">查询</el-button>
</el-form-item>
</el-form>
<el-button type="primary" @click="showDialog">新增电影</el-button>
<el-button type="danger" @click="deleteSelected">批量删除</el-button>
<!--新增电影弹框-->
<el-dialog title="新增电影信息" :visible.sync="insertRule.insertDialog" width="50%" center>
<el-form :model="insertRule.ruleForm" label-width="100px">
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="电影编号" prop="id">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.id" placeholder="请输入电影编号"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="电影名称" prop="name">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.name" placeholder="请输入电影名称"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="上映日期" prop="date">
<el-date-picker
v-model="film.date"
type="date"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
clearable>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="导演" prop="director">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.director" placeholder="请输入导演姓名"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="演员" prop="actor">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.actor" placeholder="请输入演员名称"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="类型" prop="style">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.style" placeholder="请输入电影类型"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="简介" prop="description">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.description" placeholder="请输入电影简介"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
</el-form>
<span slot="footer" class="checkRule_footer">
<el-button type="" @click="cancelinsert">取 消</el-button>
<el-button type="primary" @click="insertFilm">确 定</el-button>
</span>
</el-dialog>
</div>
<el-card>
<!--用户信息表-->
<el-table
:data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))"
style="width: 100%">
<el-table-column type="selection" width="55" align="center"></el-table-column>
<el-table-column prop="id" label="电影编号" width="80"></el-table-column>
<el-table-column prop="name" label="电影名称" width="150"></el-table-column>
<el-table-column prop="date" label="上映时间"></el-table-column>
<el-table-column prop="director" label="导演" width="100"></el-table-column>
<el-table-column prop="actor" label="主演" width="200"></el-table-column>
<el-table-column prop="style" label="类型"></el-table-column>
<el-table-column prop="description" label="简介"></el-table-column>
<el-table-column align="right">
<template slot="header" slot-scope="scope">
<el-input v-model="search" size="mini" placeholder="快捷输入电影名称搜索"/>
</template>
<template slot-scope="scope">
<!--编辑信息弹框-->
<el-dialog title="编辑电影信息" :visible.sync="editRule.editDialog" width="50%" center>
<el-form :model="editRule.ruleForm" label-width="100px">
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="电影编号" prop="id">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.id"
placeholder="请输入电影编号"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="电影名称" prop="name">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.name"
placeholder="请输入电影名称"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="上映日期" prop="date">
<el-date-picker
v-model="film.date"
type="date"
placeholder="选择日期"
format="yyyy-MM-dd"
value-format="yyyy-MM-dd"
clearable>
</el-date-picker>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="导演" prop="director">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.director"
placeholder="请输入导演姓名"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="演员" prop="actor">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.actor"
placeholder="请输入演员名称"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="类型" prop="style">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.style"
placeholder="请输入电影类型"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="20">
<el-form-item label="简介" prop="description">
<el-row :gutter="4">
<el-col :span="12" class="checkRule_list">
<el-input v-model="film.description"
placeholder="请输入电影简介"></el-input>
</el-col>
</el-row>
</el-form-item>
</el-col>
</el-row>
</el-form>
<span slot="footer" class="checkRule_footer">
<el-button type="" @click="cancel">取 消</el-button>
<el-button type="primary" @click="update">确 定</el-button>
</span>
</el-dialog>
<el-button size="mini" type="primary" @click="handleEdit(scope.$index, scope.row)">
Edit
</el-button>
<el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">
Delete
</el-button>
</template>
</el-table-column>
</el-table>
<!--分页-->
<el-pagination
layout="total, sizes, prev, pager, next, jumper"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="[20, 30, 40, 50]"
:page-size="pageSize"
:total="total">
</el-pagination>
</el-card>
</el-main>
</el-container>
</el-container>
</div>
<div v-else-if="resData.code==0">
您还未登录,没有权限访问!
</div>
</div>
</body>
<script>
new Vue({
el: "#app",
data() {
return {
tableData: [],
resData: {
code:"" ,
msg:"" ,
data:""
},
search: '',
currentPage: 1,
pageSize: 20,
total: null,
//编辑规则
editRule: {
editDialog: false, //弹窗
},
insertRule: {
insertDialog: false, //弹窗
},
film: {},
//查询
formInline: {
name: '',
director: '',
date: []
}
}
},
methods: {
//返回
back() {
var url =`logout`;
axios.get(url).then(result=>{
location.href = "login.html";
})
},
//取消弹框
cancel() {
this.editRule.editDialog = false;
},
cancelinsert() {
this.insertRule.insertDialog = false;
this.resetForm(); // resetForm方法来重置表单
},
insertFilm() {
// 使用Axios发送POST请求到服务器
axios.post('films/insert', this.film)
.then(response => {
// 请求成功处理
console.log(response.data);
// 关闭弹框,清除表单数据,并弹出友好提示
this.insertRule.insertDialog = false;
this.resetForm(); // resetForm方法来重置表单
alert('新增成功!'); // 使用alert弹出提示
})
.catch(error => {
// 请求失败处理
console.error(error);
// 弹出错误信息给用户
// 你可以从error对象中提取具体的错误信息来显示
let errorMessage = '新增失败';
if (error.response && error.response.data && error.response.data.message) {
errorMessage = error.response.data.message;
}
alert(errorMessage); // 使用alert弹出错误信息
});
},
// 假设你还有一个resetForm方法用于重置表单
resetForm() {
this.film = {
// 初始化表单数据
name: '',
date: '',
director: '',
actor: '',
style: '',
description: ''
};
},
showDialog() {
this.insertRule.insertDialog = true;
},
// 编辑回显
handleEdit(index, row) {
// 立即显示对话框
this.editRule.editDialog = true;
// 构造URL并发送请求
var URL = `films/edit/${row.id}`;
axios.get(URL)
.then(response => {
// 假设 response.data.code 为 true 表示成功
if (response.data.code) {
// 更新数据
this.film = response.data.data;
// 可以选择在这里隐藏加载指示器
} else {
// 处理错误情况
console.error('获取电影信息失败', response.data);
// 可以在这里给用户一个反馈,例如显示错误消息
}
})
.catch(error => {
// 处理网络错误或请求失败的情况
console.error('获取电影信息时发生错误', error);
// 可以在这里给用户一个反馈,例如显示错误消息
});
},
//弹框编辑信息并确认
update() {
var URL = '/films/update';
axios.put(URL, this.film)
.then(res => {
if (res.status === 200 && res.data.code) { // 检查HTTP状态码和自定义状态码
this.editRule.editDialog = false;
this.findAll(); // 刷新列表
// 可以添加一个成功提示或消息
} else {
alert('更新失败: ' + res.data.message); // 显示更详细的错误信息
}
})
.catch(error => {
// 在这里处理错误,例如显示错误信息
console.error(error);
alert('更新失败: ' + (error.response ? error.response.data.message : '未知错误')); // 显示更详细的错误信息
});
},
async handleDelete(index, row) {
if (window.confirm("确定要删除该记录吗?")) {
try {
const response = await axios.delete(`/films/delete/${row.id}`);
// 检查响应状态码(如果需要)
if (response.status >= 200 && response.status < 300) {
this.showSuccessMessage("删除成功");
this.findAll();
} else {
throw new Error('Server returned an unexpected status code');
}
} catch (error) {
console.error(error); // 这里可以打印更完整的错误信息
this.showErrorMessage("删除失败,请稍后再试");
}
}
},
showSuccessMessage(message) {
alert(message); // 作为临时解决方案
},
showErrorMessage(message) {
alert(message); // 作为临时解决方案
},
//分页
findAll() {
var url = `/films/${this.currentPage}/${this.pageSize}`
axios.get(url)
.then(res => {
this.tableData = res.data.data.rows;
this.total = res.data.data.total;
console.log(this.tableData);
console.log(this.total);
})
.catch(error => {
console.error(error);
})
},
handleSizeChange(val) {
this.pageSize = val;
this.findAll();
console.log(`每页 ${val} 条`);
},
handleCurrentChange(val) {
this.currentPage = val;
this.findAll();
console.log(`当前页: ${val}`);
},
onSubmit() {
// 假设startDate和endDate已经是有效的Date对象
// 将它们转换为可读的字符串格式(例如ISO 8601)
let startDateStr = this.formInline.date[0] ? this.formInline.date[0].toISOString().split('T')[0] : '';
let endDateStr = this.formInline.date[1] ? this.formInline.date[1].toISOString().split('T')[0] : '';
// 构造URL,包含所有查询参数
var url = `/films/${this.currentPage}/${this.pageSize}?name=${encodeURIComponent(this.formInline.name)}&director=${encodeURIComponent(this.formInline.director)}&startDate=${encodeURIComponent(startDateStr)}&endDate=${encodeURIComponent(endDateStr)}`;
// 注意:下面的console.log语句不应该出现在对象字面量中,应该作为独立的语句
console.log(this.formInline.name);
console.log(this.formInline.director);
axios.get(url)
.then(res => {
this.tableData = res.data.data.rows;
this.total = res.data.data.total;
console.log(this.tableData);
console.log(this.total);
})
.catch(error => {
console.error(error);
});
}
},
mounted() {
var url = '/film'
axios.get(url)
.then(response => {
this.resData = response.data;
console.log(this.resData);
console.log(this.resData.code);
})
.catch(error=>{
console.error(error);
})
},
created() {
this.findAll();
}
})
</script>
<style>
a {
color: white;
text-decoration: none;
}
.el-header {
background-color: #FEF5E4;
display: flex;
justify-content: space-between;
align-items: center;
color: #F09466;
font-size: 40px;
}
> div {
display: flex;
align-items: center;
}
img {
width: 55px;
border-radius: 50%;
background-color: #eee;
}
.el-aside {
background-color: #FEF5E4;
height: 100%;
}
body > .el-container {
margin-bottom: 40px;
}
.el-container:nth-child(5) .el-aside,
.el-container:nth-child(6) .el-aside {
line-height: 260px;
}
.el-container:nth-child(7) .el-aside {
line-height: 280px;
}
</style>
</html>
controller
package com.caz.controller;
import com.caz.pojo.Manager;
import com.caz.pojo.Result;
import com.caz.service.ManagerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@RestController
public class LoginController {
@Autowired
private ManagerService managerService;
@PostMapping("/login")
//RequestBody 将json格式的数据封装到实体类中
/*public Result login(HttpServletRequest request, @RequestBody Manager manager) {
Manager m = managerService.login(manager);
if (m != null) {
request.getSession().setAttribute("managers", manager.getName());
String managers = (String) request.getSession().getAttribute("managers");
System.out.println("查询不为空。"+managers);
return Result.success();
}
else{
String managers = (String) request.getSession().getAttribute("managers");
System.out.println("查询为空。"+managers);
return Result.error("用户名或密码错误");
}
}*/
//HttpServletRequest用于获取客户端发送的HTTP请求的信息,使用了Spring MVC的@RequestBody注解的参数-HTTP请求的内容体(Body)是JSON或其他格式的数据时,Spring MVC会自动将这个数据转换为Users类型的Java对象。
public Result login(HttpServletRequest httpServletRequest, @RequestBody Manager manager) {
// 尝试使用提供的manager信息进行登录
Manager loggedInManager = managerService.login(manager);
// 如果登录成功,loggedInManager将不为null
if (loggedInManager != null) {
// 登录成功,将用户名保存到session中
httpServletRequest.getSession().setAttribute("username", loggedInManager.getUsername());
// 可选:获取并打印session中的用户名,以验证设置成功
String username = (String) httpServletRequest.getSession().getAttribute("username");
System.out.println("登录成功,用户名:" + username);
// 返回成功的结果
return Result.success();
} else {
// 登录失败,返回错误信息
System.out.println("登录失败,用户名或密码错误");
return Result.error("用户名或密码错误");
}
}
@GetMapping("/logout")
public Result logout(HttpServletRequest request) {
//清理Session中保存的当前登录管理员的id
request.getSession().removeAttribute("managers");
return Result.success("退出成功");
}
@GetMapping("/film")
public Result film(HttpServletRequest request) {
String username = (String) request.getSession().getAttribute("username");
if (username != null) {
System.out.println("查询不为空"+username);
return Result.success();
} else {
System.out.println("查询为空");
return Result.error("无权限访问!");
}
}
}
mapper
@Mapper
public interface ManagerMapper {
Manager getByUsernameAndPassword(Manager manager);
}
service
public interface ManagerService {
Manager login(Manager manager);
}