1.我的小组长是 李梦丹 ,我们组课程设计的题目是: 影院管理系统 ,我认领的功能模块是: 电影信息管理
2.生成虚拟数据
import csv
import random
from faker import Faker
# 初始化Faker并设置locale为zh_CN
fake = Faker('zh_CN')
# 更多的形容词和名词
adjectives = [
'疯狂', '热血', '浪漫', '奇幻', '无敌', '史诗', '梦幻', '星际', '暗黑', '未来',
'古典', '神秘', '冒险', '史诗', '超级', '不朽', '深海', '终极', '极限', '无敌'
]
nouns = [
'的石头', '之旅', '岁月', '江湖', '之夜', '传说', '帝国', '之战', '世界', '之心',
'探秘', '奇遇', '逃亡', '追击', '复仇', '归来', '守护者', '英雄', '时空', '勇士'
]
# 用于跟踪已经生成过的电影名称
generated_names = set()
# 生成不重复的电影名称
def random_film_name():
while True:
# 使用多个词汇组合生成电影名称
name = random.choice(adjectives) + random.choice(nouns)
# 检查名称是否唯一
if name not in generated_names:
generated_names.add(name)
return name
# 生成随机上映日期(过去10年内的日期)
def random_release_date():
start_date = fake.past_date(start_date="-10y")
return start_date.strftime('%Y-%m-%d')
# 生成随机中文人名
def random_chinese_name():
return fake.name()
# 生成随机电影类型(可能是多种)
def random_film_types(max_types=3):
types = [
'动作', '喜剧', '爱情', '科幻', '悬疑', '恐怖', '剧情', '动画', '战争', '历史',
'传记', '奇幻', '冒险', '灾难', '家庭', '音乐'
]
return ', '.join(random.choices(types, k=random.randint(1, max_types)))
# 生成随机电影描述
def random_film_description():
# 使用Faker生成一个随机的中文句子作为电影描述
return fake.sentence(nb_words=6, variable_nb_words=True)
# 初始化数据列表
data = []
# 生成200条数据
for _ in range(200):
movie_data = {
'电影编号': None, # 编号在写入CSV时由数据库自增,这里留空
'电影名称': random_film_name(),
'上映日期': random_release_date(),
'导演': random_chinese_name(),
'主演': ', '.join([random_chinese_name() for _ in range(random.randint(1, 4))]),
'类型': random_film_types(),
'简介': random_film_description()
}
data.append(movie_data)
# 写入CSV文件
with open('chinese_films.csv', 'w', newline='', encoding='utf-8') as csvfile:
fieldnames = ['电影编号', '电影名称', '上映日期', '导演', '主演', '类型', '简介']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for row in data:
writer.writerow(row)
# 清理已生成的名称集合(如果需要)
generated_names.clear()
print("数据已成功导出到chinese_films.csv文件中。")
新建数据表
create table film
(
id int auto_increment
primary key,
name varchar(255) not null,
date date null,
director varchar(255) null,
actor text null,
style varchar(100) null,
description text null
);
使用navicat导入数据
3.完成表的查询和分页,编辑、删除功能
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">
<el-container style="height:80px; position: sticky; top: 0;z-index: 10" >
<el-header>
<div>
<img src="./img/head.jpg" alt="">
<span>影院管理系统</span>
</div>
<el-button type="info" @click="back" style="height:40px;background-color: #F5D05B">退出</el-button>
</el-header>
<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-main>
<!--查询框-->
<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>
</div>
<!--卡片视图-->
<el-card>
<!--用户信息表-->
<el-table :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))" style="width: 100%">
<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
@focus="handleFocus">
</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>
</body>
<script>
new Vue({
el:"#app",
data(){
return{
film:{
date:'',
},
tableData:[],
search: '',
currentPage: 1,
pageSize: 20,
total:null,
//编辑规则
editRule: {
editDialog: false, //弹窗
},
formInline: {
name: '',
director: '',
date: []
}
}
},
methods:{
//返回
back(){
location.href='login.html'
},
//取消弹框
cancel(){
this.editRule.editDialog=false;
},
//编辑回显
handleEdit(index, row) {
this.editRule.editDialog=true;
var URL=`films/edit/${row.id}`
axios.get(URL).then(response=>{
if(response.data.code){
this.film=response.data.data;
}
}).catch(error=>{})
console.log(index, row);
},
//弹框编辑信息并确认
update:function(){
var URL='/films/update';
//put请求用于更新资源.url 是你想要更新的资源的地址;this.film是包含更新后数据的对象,这个对象将被发送到服务器以更新资源。
axios.put(URL,this.film).then(res => {
if (res.data.code) {
this.editRule.editDialog = false;
//location.reload();
this.findAll();
} else {
alert(res.data.message);
}
}).catch(error => {
// 在这里处理错误,例如显示错误信息
console.error(error);
alert('更新失败: ' + error.message);
});
},
//根据ID删除
handleDelete(index,row) {
if (window.confirm("确定要删除该记录吗?")) {
try {
axios.delete(`/films/delete/${row.id}`);
alert("删除成功");
this.findAll();
} catch (error) {
console.error(error.message);
alert("删除失败,请稍后再试");
}
}
},
//分页
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);
});
}
},
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>
FilmMapper.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.caz.mapper.FilmMapper">
<!-- 查询 -->
<select id="list" resultType="com.caz.pojo.Film">
select * from film
</select>
<!-- 条件分页查询 -->
<select id="list_chaxun" resultType="com.caz.pojo.Film">
select * from film
<where>
<if test="name != null and name != ''">
author like concat('%',#{name},'%')
</if>
<if test="director != null and director != ''">
and director like concat('%',#{director},'%')
</if>
</where>
</select>
<!--根据id删除-->
<delete id="deleteById" parameterType="java.lang.Integer">
delete from film where id = #{id}
</delete>
<select id="getById" resultType="com.caz.pojo.Film">
select * from film
<where>
id= #{id}
</where>
</select>
<update id="update">
update film
<set>
<if test="name != null and name != ''">
name =#{name},
</if>
<if test="date != null and date != ''">
date =#{date},
</if>
<if test="director != null and director != ''">
director =#{director},
</if>
<if test="actor != null and actor != ''">
actor =#{actor},
</if>
<if test="style != null and style != ''">
style =#{style},
</if>
<if test="description != null and description != ''">
description =#{description},
</if>
</set>
where id=#{id}
</update>
</mapper>
FilmMapper
package com.caz.mapper;
import com.caz.pojo.Film;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface FilmMapper {
List<Film> list();
List<Film> list_chaxun(@Param("name") String name, @Param("director") String director);
//根据id删除
void deleteById(Integer id);
Film getById(Integer id);
void update(Film film);
}
FilmService
package com.caz.service;
import com.caz.pojo.Film;
import com.caz.pojo.PageBean;
import org.springframework.stereotype.Service;
@Service
public interface FilmService {
PageBean list(Integer page, Integer pageSize);
//分页查询
PageBean list_chaxun(Integer page, Integer pageSize, String name, String director);
//删除数据
void delete(Integer id);
Film getById(Integer id);
void update (Film film);
}
实现类
package com.caz.service.impl;
import com.caz.mapper.FilmMapper;
import com.caz.pojo.Film;
import com.caz.pojo.PageBean;
import com.caz.service.FilmService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class FilmServiceImpl implements FilmService {
@Autowired
private FilmMapper filmMapper;
@Override
public PageBean list(Integer page, Integer pageSize) {
// 设置分页参数
PageHelper.startPage(page, pageSize);
// 执行分页查询
List<Film> filmList = filmMapper.list();
// System.out.println(poetList);
// 获取分页结果
PageInfo<Film> p = new PageInfo<>(filmList);
//封装PageBean
PageBean pageBean = new PageBean(p.getTotal(), p.getList());
return pageBean;
}
@Override
public PageBean list_chaxun(Integer page,Integer pageSize,String name,String director) {
// 设置分页参数
PageHelper.startPage(page, pageSize);
// 执行分页查询
List<Film> filmList = filmMapper.list_chaxun(name,director);
// 获取分页结果
PageInfo<Film> p = new PageInfo<>(filmList);
//封装PageBean
PageBean pageBean = new PageBean(p.getTotal(), p.getList());
return pageBean;
}
@Override
public void delete(Integer id){
filmMapper.deleteById(id);
}
@Override
public Film getById(Integer id){
return filmMapper.getById(id);
}
@Override
public void update(Film film) {
filmMapper.update(film);
}
}
Film
package com.caz.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Film {
private Integer id;
private String name;
private String date;
private String director;
private String actor;
private String style;
private String description;
}
FilmController
package com.caz.controller;
import com.caz.pojo.Film;
import com.caz.pojo.PageBean;
import com.caz.pojo.Result;
import com.caz.service.FilmService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@Slf4j
@RestController
@RequestMapping("/films")
public class FilmController {
@Autowired
private FilmService filmService;
//查询所有数据
@GetMapping("/{page}/{pageSize}")
public Result page(@PathVariable Integer page,
@PathVariable Integer pageSize,
String name, String director) {
//记录日志
log.info("分页查询,参数:{},{},{},{},{},{}", page, pageSize,name, director);
//调用业务层分页查询功能
PageBean pageBean = filmService.list_chaxun(page, pageSize, name, director);
//响应
return Result.success(pageBean);
}
//删除信息
@DeleteMapping("/delete")
public Result delete( Integer id) {
log.info("根据id删除:{}", id);
filmService.delete(id);
return Result.success();
}
//查询回显
@GetMapping("/edit/{id}")
public Result getById(@PathVariable Integer id) {
log.info("根据id查询信息:{}", id);
Film film=filmService.getById(id);
return Result.success(film);
}
//更新信息
@PutMapping("/update")
public Result update(@RequestBody Film film){
log.info("更新电影信息:{}", film);
filmService.update(film);
return Result.success();
}
}
运行结果
4.查询功能纠错
代码中没有为author、style参数定义来源,可以在mapper中的方法传入两个参数时,给参数加上@(Param)注解