目录
项目目录结构
项目功能:
首页功能
1、登录
2、用户注册
3、商家注册
用户功能
1、展示全部影片信息
2、根据电影名查询电影信息
3、评分功能
4、购票功能
5、退出系统
商家功能
1、展示当前店铺电影详情
2、上架电影
3、下架电影
4、修改电影
5、退出系统
源码即各功能实现原理简述:
1、项目结构
bean包 :里面放了四个实体类
a、User类:用户类,是客户和商家的父类。
b、Business类:商家类,里面是一些商家的独有信息。
c、Customer类:客户类,因为客户信息在User类里面都有,所以这个类中并没有任何内容。
d、Movie类:电影类,封装了电影信息
run包:里面只有一个功能实现类,所有的功能代码都在这个类中
2、准备工作
/*定义系统的数据容器 用于封装数据
1、存储很多用户(客户对象,商家对象)
*/
public static final List<User> ALL_USERS = new ArrayList<>();
/*
2、存储系统全部商家和排片信息
商家1=[p1,p2,p3.....]
商家2=[p1,p2,p3.......]
*/
public static Map<Business,List<Movie>> ALL_MOVIES = new HashMap<>();
public static final Scanner SYS_SC = new Scanner(System.in); // 系统扫描器
//定义一个静态的User类型的变量记住当前登录成功的用户对象
public static User loginUser;
// 时间格式化对象
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 日志对象
public static final Logger LOGGER = LoggerFactory.getLogger("MovieSystem.class");
/*
3、准备一些测试数据
*/
static {
Customer c = new Customer();
c.setLoginName("ldh888");
c.setPassword("123456");
c.setUserName("刘德华");
c.setSex('男');
c.setPhone("1222222");
c.setMoney(10000);
ALL_USERS.add(c);
Customer c1 = new Customer();
c1.setLoginName("gzl888");
c1.setPassword("123456");
c1.setUserName("关之琳");
c1.setSex('女');
c1.setPhone("13333333");
c1.setMoney(2000);
ALL_USERS.add(c1);
Business b = new Business();
b.setLoginName("baozugong888");
b.setPassword("123456");
b.setUserName("包租公");
b.setMoney(0);
b.setSex('男');
b.setPhone("144444444");
b.setAddress("火星6号2B二层");
b.setShopName("甜甜圈国际影城");
ALL_USERS.add(b);
// 注意 商家信息一定要加入到店铺排片信息中去
List<Movie> movies = new ArrayList<>();
ALL_MOVIES.put(b,movies);
Business b2 = new Business();
b2.setLoginName("baozupo888");
b2.setPassword("123456");
b2.setUserName("包租婆");
b2.setMoney(0);
b2.setSex('女');
b2.setPhone("15555555");
b2.setAddress("火星8号8B八层");
b2.setShopName("巧克力国际影城");
ALL_USERS.add(b2);
// 注意 商家信息一定要加入到店铺排片信息中去
List<Movie> movies2 = new ArrayList<>();
ALL_MOVIES.put(b2,movies2);
}
首先定义一个静态的集合:ALL_USERS用于存放所有的用户信息。
然后定义一个Map:ALL_MOVIES用于存放商家信息和电影信息,商家和其对应的电影信息以键值对的形式存放在这个Map中
定义扫描器,这样就不用在主代码中再定义
定义一个User类型的变量来记录当前登录的用户(这个变量在很多功能中都会用到,着重理解为什么要这样处理)
创建简单日期格式化对象 用于格式化和解析时间
创建日志对象(这个对象可有可无,若没有,则需要把代码中的日志代码删除。到底用不用看自己心情)
最后准备一些测试数据,包括两个用户和两个商家
3、主要功能介绍
1、展示主页面
private static void showMain() {
while (true) {
System.out.println("==================电影首页=====================");
System.out.println("1、登录");
System.out.println("2、用户注册");
System.out.println("3、商家注册");
System.out.print("请输入命令:");
String command = SYS_SC.nextLine();
switch (command){
case "1":
// 登录了
login();
break;
case "2":
CustomerRegister();
break;
case "3":
businessRegister();
break;
default:
System.out.println("命令输入有误");
}
}
}
运行程序之后展示的页面,这个页面没有难度。这里没有加退出系统功能,如果需要可自行添加
2、登录功能
private static void login() {
while (true) {
System.out.print("请输入登录的名称:");
String loginName = SYS_SC.nextLine();
System.out.print("请您输入登录密码:");
String password = SYS_SC.nextLine();
// 1、 根据登录名查询用户对象
User u = getUserByLoginName(loginName);
// 2、 判断用户对象是否存在 存在说明登录名称正确了
if (u!= null){
// 3、比对密码是否正确
if (u.getPassword().equals(password)){
// 登录成功了
loginUser = u; // 记住登陆成功的用户
LOGGER.info(u.getUserName() +"登录了系统~~~");
// 判断是用户登录的还是商家登录的
if ( u instanceof Customer){
// 当前登录的普通用户
showCustomerMain();
}else{
// 当前登录的是商家用户
showBusinessMain();
}
return;
}else {
System.out.println("密码有毛病");
}
}else {
System.out.println("登录名输入错误,请重新输入~~~~");
}
}
}
首先输入登录名和密码:然后根据用户名去判断是否有当前用户,那就要有一个新的功能:根据用户名去寻找用户,这个功能不止会用到一次,所以封装成方法
具体实现如下:
public static User getUserByLoginName(String loginName){
for (User user : ALL_USERS) {
//判断这个用户的登录名是不是我们想要的
if (user.getLoginName().equals(loginName)){
return user;
}
}
return null; // 查询无此用户
}
}
如果存在这个用户这个方法会返回一个User类型的变量也就是用户和商家的父类对象,否则返回null。这个功能的实现也比较简单。接着上面的讲:
当我们判断了当前输入的用户是否存在之后,我们就可以继续处理登录逻辑也就是当返回值不为null的时候,我们就可以继续去判断输入的密码是否和设置的密码一样,若一样,则登录成功,同时把这个对象覆赋给loginUser,让loginUser去记住当前登录的用户。因为User是用户类的商家类的父类,所以到这个时候我们还无法确认登录的到底是商家还是用户。而无论是商家还是用户,我们希望他们都能通过这个登录页面登录系统,因为,如果给商家和用户分别制定不同的登录入口,这是很麻烦的一件事,重复代码太多。所以我们才会让getUserByLoginName这个方法返回一个User类型的变量,这也是为什么loginUser也是User类型的原因,这里用了多态的思想。
我们要想让同一个登录页面在不同类型的使用者登录之后展现不一样的功能,我们就要去判断getUserByLoginName这个方法返回的User的真实类型到底是Customer还是Business,如果是Customer就展示客户界面,如果是Business就展示商家界面。
3、展示客户功能页面
/**
* @Description: 客户操作界面
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/28 20:56
*/
private static void showCustomerMain() {
System.out.println("===============黑马电影客户界面===============");
System.out.println("请您选择要操作的功能");
System.out.println("1、展示全部影片信息");
System.out.println("2、根据电影名查询电影信息");
System.out.println("3、评分功能");
System.out.println("4、购票功能");
System.out.println("5、退出系统");
while (true) {
System.out.print("请您选择要操作的命令:");
String command = SYS_SC.nextLine();
switch (command){
case "1":
// 展示全部影片
showAllMovies();
break;
case "2":
//根据电影名查询电影信息
selectedMovieByName();
break;
case "3":
score();
break;
case "4":
// 购票功能
buyMovie();
break;
case "5":
System.out.println(loginUser.getUserName() + "已退出,欢迎下次再来~~~");
return;
default:
System.out.println("不存在该命令~~~");
break;
}
}
}
这个功能也没难度。下一个
4、客户功能--展示全部影片
/**
* @Description: 展示全部商家和其排片信息
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 15:53
*/
private static void showAllMovies() {
ALL_MOVIES.forEach((business, movies) -> {
System.out.println(business.getShopName() +"\t\t电话:" + business.getPhone() +"\t\t地址:"+business.getAddress());
System.out.println("\t\t\t"+"片名\t\t\t\t\t主演\t\t\t\t时长\t\t\t\t评分\t\t\t票价\t\t\t\t余票数量\t\t\t\t放映时间");
for (Movie movie : movies) {
System.out.println("\t\t\t"+movie.getName()+"\t\t\t"+movie.getActor()+"\t\t\t"+movie.getTime()+
"\t\t\t"+movie.getScore()+"\t\t\t"+movie.getPrice()+"\t\t\t"+movie.getNumber()+
"\t\t\t\t"+sdf.format(movie.getStartTime()));
}
});
}
用forEach去遍历ALL_MOVIES,在ALL_MOVIES中店铺和影片名称是键值对的形式,而且这个Map的值还是List<Movies>类型,所以这样每个店铺才能存放很多部电影。
5、客户功能--根据电影名查询信息
/**
* @Description: 根据电影名称查询电影信息
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/8/15 13:49
*/
private static void selectedMovieByName() {
System.out.println("请输入要查询的电影名称:");
String movieName = SYS_SC.nextLine();
// 遍历全部影片信息的Map
ALL_MOVIES.forEach((business, movies)->{
// 遍历电影信息
movies.forEach((movie)->{
// 判断是否有当前电影
if (movie.getName().contains(movieName)){
System.out.println(business.getShopName() +"\t\t电话:" + business.getPhone() +"\t\t地址:"+business.getAddress());
System.out.println("\t\t\t"+"片名\t\t\t\t\t主演\t\t\t\t时长\t\t\t\t评分\t\t\t票价\t\t\t\t余票数量\t\t\t\t放映时间");
System.out.println("\t\t\t"+movie.getName()+"\t\t\t"+movie.getActor()+"\t\t\t"+movie.getTime()+
"\t\t\t"+movie.getScore()+"\t\t\t"+movie.getPrice()+"\t\t\t"+movie.getNumber()+
"\t\t\t\t"+sdf.format(movie.getStartTime()));
}else{
System.out.println("没有找到这部电影~~~");
}
});
});
}
这个功能也不难,先遍历ALL_MOVIES集合,每遍历到一个键值对再去遍历值的集合,判断值集合中有没有想要查询的电影信息,有就输出电影信息,没有则输出提示信息
6、客户功能--评分功能
/**
* @Description: 影片评分系统
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/8/15 14:11
*/
private static void score() {
showAllMovies();
System.out.println("请输入要评价的电影名称:");
String movieName = SYS_SC.nextLine();
// 遍历所有电影房信息的Map
ALL_MOVIES.forEach(( business, movies) ->{
movies.forEach(( movie->{
if (movie.getName().equals(movieName)){
System.out.println("请输入分数:");
double score = Double.parseDouble(SYS_SC.nextLine());
if (movie.getScore()==0){
movie.setScore(score);
}else{
double nowScore = (movie.getScore()+score)/2;
movie.setScore(nowScore);
}
System.out.println("评分成功~~~");
}else{
System.out.println("没有找到这部电影~~~~");
}
}
));
});
}
这个功能的基本逻辑和上一个功能一样,都是根据电影名称去寻找某一部电影,只不过是找到之后要去给电影评分。评分是要注意,我们并不想每次评分的时候都把以前的分数给覆盖了,而是计算平均值。那么这里就又有一个点要注意了,当我们第一次评分时,在此之前,这部电影并没有分数,所以这个时候的评分,就可以直接把以前的分数覆盖。
7、客户功能--购票功能
/**
* @Description: 用户购票功能
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 16:02
*/
private static void buyMovie() {
showAllMovies();
System.out.println("=============用户购票功能==============");
while (true) {
System.out.print("请你输入需要买票的门店:");
String shopName = SYS_SC.nextLine();
// 查询是否存在商家
Business business= getUserByShopName(shopName);
if (business == null){
System.out.println("对不起,没有这个商家");
}else {
// 此商家全部的排片
List<Movie> movies = ALL_MOVIES.get(business);
// 判断此商家是否有排片
if (movies.size()>0){
// 开始进行选片购买
while (true) {
System.out.print("请你输入需要购买的电影名称:");
String movieName =SYS_SC.nextLine();
// 去当前上架下,查询是否有这个电影
Movie movie = getMovieByShopNameAndMovieName(business,movieName);
if (movie !=null){
// 开始购买
while (true) {
System.out.print("请您输入要购买的电影票数:");
String number = SYS_SC.nextLine();
int buyNumber = Integer.parseInt(number);
// 判断余票是否足够
if (movie.getNumber()>=buyNumber){
// 可以购买了
// 计算需要花费的金额
double money = BigDecimal.valueOf(movie.getPrice()).multiply(BigDecimal.valueOf(buyNumber)).doubleValue();
if (loginUser.getMoney()>=money){
// 终于开始买票了
System.out.println("您成功购买了"+movie.getName()+buyNumber+"张票,总金额为:"+money);
// 更新客户与商家的金额
loginUser.setMoney(loginUser.getMoney()-money);
business.setMoney(business.getMoney()+money);
movie.setNumber(movie.getNumber()-buyNumber);
return;
}else {
System.out.println("对不起,你的钱不够~~~");
System.out.println("是否要继续买票? (y/n)");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
default:
System.out.println("好的");
return;
}
}
}else {
// 票数不够
System.out.println("您当前最多可以都买"+movie.getNumber()+"张票~~~");
System.out.println("是否要继续买票? (y/n)");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
default:
System.out.println("好的");
return;
}
}
}
}else {
System.out.println("对不起,电影名称有毛病~~~");
}
}
}else {
System.out.println("该电影院关门了~~~");
System.out.println("是否要继续买票? (y/n)");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
default:
System.out.println("好的");
return;
}
}
}
}
}
这个方法虽然代码长,但是逻辑并不复杂。
首先,我们要想买电影票就要先确定买哪个电影院的,那就要根据用户输入的电影院名称去判断是否有这个电影院。那这个功能我也封装成了一个方法。代码如下
/**
* @Description: 根据店铺名查询是否存在这个商家
* @Param: [shopName]
* @return: com.lly.bean.Business
* @Author: lly
* @Date: 2022/7/29 16:07
*/
public static Business getUserByShopName(String shopName){
Set<Business> businesses = ALL_MOVIES.keySet();
for (Business business : businesses) {
if (business.getShopName().equals(shopName)){
return business;
}
}
return null;
}
因为我们查询的是商家,所以之间返回商家类型的返回值。这个方法和上面的getUserByLoginName很像。
当查到这个电影院之后,getUserByShopName返回的其实就是ALL_MOVIES这个Map的键,那我们只需要根据返回值去ALL_MOVIES把对应的值取出来就可以进行下一步的判断。之后,我们就要根据用户输入的电影名去判断这个电影院里有没有上架电影,如果一部电影都没有上架,那肯定不能在这个电影院买票。但我们确定了这个电影院有电影可看的之后,就可以进行购票操作了。这个逻辑不难。
8、商家功能--展示影片详情
private static void showBusinessInfos() {
System.out.println("=================商家详情界面===================");
// 根据商家对象(就是当前登录用户的loginUser),最为Map的键 提取对应的值就是其排片信息
Business business = (Business)loginUser;
System.out.println(business.getShopName() +"\t\t电话:" + business.getPhone() +"\t\t地址:"+business.getAddress());
List<Movie> movies = ALL_MOVIES.get(loginUser);
if (movies.size()>0){
System.out.println("片名\t\t\t\t\t主演\t\t\t\t时长\t\t\t\t评分\t\t\t票价\t\t\t\t余票数量\t\t\t\t放映时间");
for (Movie movie : movies) {
System.out.println(movie.getName()+"\t\t\t"+movie.getActor()+"\t\t\t"+movie.getTime()+
"\t\t\t"+movie.getScore()+"\t\t\t"+movie.getPrice()+"\t\t\t"+movie.getNumber()+
"\t\t\t\t"+sdf.format(movie.getStartTime()));
}
}else {
System.out.println("您的店铺当前无片可播~~~");
}
这个方法和客户功能的展示影片信息类似,区别只是客户的展示影片信息是展示所有店铺的影片信息。而这个功能只会展示自己店铺的影片信息。逻辑基本一样。
9、商家功能--上架电影
/**
* @Description: 商家进行电影上架
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 13:57
*/
private static void addMovie() {
System.out.println("==============上架电影==================");
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(loginUser);
System.out.print("请你输入新片名:");
String name = SYS_SC.nextLine();
System.out.print("请您输入主演:");
String actor = SYS_SC.nextLine();
System.out.print("请您输入时长:");
String time = SYS_SC.nextLine();
System.out.print("请您输入票价:");
String price = SYS_SC.nextLine();
System.out.print("请你输入票数:");
String totalNumber = SYS_SC.nextLine();
while (true) {
try {
System.out.println("请你输入影片放映时间:");
String startTime = SYS_SC.nextLine();
// 封装成电影对象 ,加入到集合movies中去
Movie movie = new Movie(name,actor, Double.valueOf(time),Double.valueOf(price),Integer.valueOf(totalNumber),
sdf.parse(startTime));
movies.add(movie);
System.out.println("你已经成功上架了:《"+movie.getName()+"》");
return; // 直接退出去
} catch (ParseException e) {
e.printStackTrace();
System.out.println();
LOGGER.error("时间解析错误~~~");
}
}
}
这个功能的逻辑也很简单,因为存储电影及商家信息的Map的键是Business类型,值是List<Movie>类型 所以我们要先确定当前使用这个功能的店铺是谁的。这就又要用到loginUser了,loginUser内保存的是谁,那这里操作的就是谁的店铺。我们要上架电影,就要先获取这个店铺本身存储电影的List<Movie>集合,这只需要根据loginUser就可以获得。获得之后,直接吧要上架的信息给加到这个集合里面就可以了。这个方法要注意的就是解析时间字符串了。我们的准备阶段定义的时间格式是什么样的,在这就要按照什么样的时间格式输入,如果输错了就会报解析异常。所以这里我进行了异常处理。我只是打印了异常栈信息。你们可以自己改成其他的操作,比如如果输错了就让商家重新输入。自行发挥~~
10、商家功能--下架电影
private static void deleteMovie() {
System.out.println("===============下架电影=================");
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(loginUser);
if ( movies.size()== 0){
System.out.println("当前没有电影可下架~~~");
return;
}
while (true) {
// 让用户选择需要下架的电影名称
System.out.println("请您输入需要下架的电影名称:");
String movieName = SYS_SC.nextLine();
// 去查询有没有这个影片
Movie movie = getMovieByName(movieName);
if (movie!=null){
// 下架这个电影
movies.remove(movie);
System.out.println("您当前店铺已经成功下架了:"+movie.getName());
showBusinessInfos();
return;
}else {
System.out.println("您的店铺没有上架该影片~~~");
System.out.println("请问要继续吗下架吗?(y/n):");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
case "n":
System.out.println("好的~~~");
return;
}
}
}
}
这个功能的逻辑和上架电影的逻辑也是基本一样,一个是往集合里面加数据,一个是从集合里面删除数据。只需注意一些细节的判断,比如这个店铺根本就没有上架电影,那这个时候当然也就没有电影可以下架。
11、商家功能--修改电影
/**
* @Description: 修改影片信息
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 14:54
*/
private static void updateMovie() {
System.out.println("===============修改电影=================");
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(loginUser);
if ( movies.size()== 0){
System.out.println("当前没有电影可修改~~~");
return;
}
while (true) {
// 让用户选择需要下架的电影名称
System.out.println("请您输入需要修改的电影名称:");
String movieName = SYS_SC.nextLine();
// 去查询有没有这个影片
Movie movie = getMovieByName(movieName);
if (movie!=null){
System.out.print("请你输入修改后的片名:");
String name = SYS_SC.nextLine();
System.out.print("请您输入修改后的主演:");
String actor = SYS_SC.nextLine();
System.out.print("请您输入修改后的时长:");
String time = SYS_SC.nextLine();
System.out.print("请您输入修改后的票价:");
String price = SYS_SC.nextLine();
System.out.print("请你输入修改后的票数:");
String totalNumber = SYS_SC.nextLine();
while (true) {
try {
System.out.println("请你输入修改后的影片放映时间:");
String startTime = SYS_SC.nextLine();
movie.setName(name);
movie.setActor(actor);
movie.setTime(Double.parseDouble(time));
movie.setPrice(Double.parseDouble(price));
movie.setNumber(Integer.parseInt(totalNumber));
movie.setStartTime(sdf.parse(startTime));
System.out.println("恭喜您,已经成功修改了该影片~~~");
showBusinessInfos();
return; // 直接退出去
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("时间解析错误~~~");
}
}
}else {
System.out.println("您的店铺没有上架该影片~~~");
System.out.println("请问要继续吗修改吗?(y/n):");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
case "n":
System.out.println("好的~~~");
return;
}
}
}
}
又是一样的逻辑。就不做介绍了~
到此为止,这个模拟系统的主要方法就介绍完了。大部分的逻辑都不难,因为ALL_MOVIES这个集合用到了集合嵌套,所以在处理这个集合的时候可能会有一点绕。
完整源码
1、bean包
Business.java
package com.lly.bean;
public class Business extends User{
// 店铺名称
private String shopName;
//店铺地址
private String address;
public String getShopName() {
return shopName;
}
public void setShopName(String shopName) {
this.shopName = shopName;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
Customer.java
package com.lly.bean;
public class Customer extends User {
}
Movie.java
package com.lly.bean;
import java.util.Date;
public class Movie {
private String name ;
private String actor;
private double score;
private double time;
private double price;
private int number ; // 余票
private Date startTime; // 放映时间
public Movie() {
}
public Movie(String name, String actor, double time, double price, int number, Date startTime) {
this.name = name;
this.actor = actor;
this.time = time;
this.price = price;
this.number = number;
this.startTime = startTime;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getActor() {
return actor;
}
public void setActor(String actor) {
this.actor = actor;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
public double getTime() {
return time;
}
public void setTime(double time) {
this.time = time;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
}
User.java
package com.lly.bean;
/**
* @description: 用户类 客户和商家的父类
* @author: lly
* @create: 2022/7/28 19:58
**/
public class User {
private String loginName; // 假名 不能重复
private String userName; // 真名
private String password;
private char sex;
private String phone;
private double money;
public User() {
}
public User(String loginName, String userName, String password, char sex, String phone, double money) {
this.loginName = loginName;
this.userName = userName;
this.password = password;
this.sex = sex;
this.phone = phone;
this.money = money;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
}
2、run包
MovieSystem.java
package com.lly.run;
import com.lly.bean.Business;
import com.lly.bean.Customer;
import com.lly.bean.Movie;
import com.lly.bean.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class MovieSystem {
/*定义系统的数据容器 用于封装数据
1、存储很多用户(客户对象,商家对象)
*/
public static final List<User> ALL_USERS = new ArrayList<>();
/*
2、存储系统全部商家和排片信息
商家1=[p1,p2,p3.....]
商家2=[p1,p2,p3.......]
*/
public static Map<Business,List<Movie>> ALL_MOVIES = new HashMap<>();
public static final Scanner SYS_SC = new Scanner(System.in); // 系统扫描器
//定义一个静态的User类型的变量记住当前登录成功的用户对象
public static User loginUser;
// 时间格式化对象
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 日志对象
public static final Logger LOGGER = LoggerFactory.getLogger("MovieSystem.class");
/*
3、准备一些测试数据
*/
static {
Customer c = new Customer();
c.setLoginName("ldh888");
c.setPassword("123456");
c.setUserName("黑马刘德华");
c.setSex('男');
c.setPhone("1222222");
c.setMoney(10000);
ALL_USERS.add(c);
Customer c1 = new Customer();
c1.setLoginName("gzl888");
c1.setPassword("123456");
c1.setUserName("黑马关之琳");
c1.setSex('女');
c1.setPhone("13333333");
c1.setMoney(2000);
ALL_USERS.add(c1);
Business b = new Business();
b.setLoginName("baozugong888");
b.setPassword("123456");
b.setUserName("黑马包租公");
b.setMoney(0);
b.setSex('男');
b.setPhone("144444444");
b.setAddress("火星6号2B二层");
b.setShopName("甜甜圈国际影城");
ALL_USERS.add(b);
// 注意 商家信息一定要加入到店铺排片信息中去
List<Movie> movies = new ArrayList<>();
ALL_MOVIES.put(b,movies);
Business b2 = new Business();
b2.setLoginName("baozupo888");
b2.setPassword("123456");
b2.setUserName("黑马包租婆");
b2.setMoney(0);
b2.setSex('女');
b2.setPhone("15555555");
b2.setAddress("火星8号8B八层");
b2.setShopName("巧克力国际影城");
ALL_USERS.add(b2);
// 注意 商家信息一定要加入到店铺排片信息中去
List<Movie> movies2 = new ArrayList<>();
ALL_MOVIES.put(b2,movies2);
}
public static void main(String[] args) {
// 首页展示
showMain();
}
/**
* @Description: 首页展示
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/28 20:40
*/
private static void showMain() {
while (true) {
System.out.println("==================电影首页=====================");
System.out.println("1、登录");
System.out.println("2、用户注册");
System.out.println("3、商家注册");
System.out.print("请输入命令:");
String command = SYS_SC.nextLine();
switch (command){
case "1":
// 登录了
login();
break;
case "2":
CustomerRegister();
break;
case "3":
businessRegister();
break;
default:
System.out.println("命令输入有误");
}
}
}
/**
* @Description: 商家注册功能
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/8/15 14:36
*/
private static void businessRegister() {
System.out.println("==============商家注册界面==============");
Business b = new Business();
System.out.println("请输入登录名");
String loginName = SYS_SC.nextLine();
User user = getUserByLoginName(loginName);
if (user == null) {
b.setLoginName(loginName);
while (true) {
System.out.println("请输入登录密码:");
String password = SYS_SC.nextLine();
System.out.println("请再次输入登录密码:");
String okPassword = SYS_SC.nextLine();
if (okPassword.equals(password)) {
b.setPassword(okPassword);
break;
}else{
System.out.println("两次吗密码输入不一致,请重新输入");
}
}
System.out.println("请输入用户名:");
String userName = SYS_SC.nextLine();
b.setUserName(userName);
while (true) {
System.out.println("请输入性别:");
String sex = SYS_SC.nextLine();
if (sex.equals("男")|| sex.equals("女")){
char gender = sex.charAt(0);
b.setSex(gender);
break;
}else {
System.out.println("暂不支持这个性别,请重新输入~~~");
}
}
System.out.println("请输入电话号码~~~");
String phone = SYS_SC.nextLine();
// 这里也可以用正则表达式判断手机号的合法性
b.setPhone(phone);
// System.out.println("请输入存入金额:");
// double money = Double.parseDouble(SYS_SC.nextLine());
// b.setMoney(money);
System.out.println("请输入店铺地址:");
String address = SYS_SC.nextLine();
b.setAddress(address);
System.out.println("请输入店铺名称:");
String shopName = SYS_SC.nextLine();
b.setShopName(shopName);
ALL_USERS.add(b);
List<Movie> movies = new ArrayList<>();
ALL_MOVIES.put(b,movies);
System.out.println("恭喜您注册成功~~~");
}else{
System.out.println("登录名已存在~~~");
}
}
/**
* @Description: 用户注册功能
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/8/15 14:36
*/
private static void CustomerRegister() {
System.out.println("==============用户注册界面==============");
Customer c = new Customer();
System.out.println("请输入登录名");
String loginName = SYS_SC.nextLine();
User user = getUserByLoginName(loginName);
if (user == null) {
c.setLoginName(loginName);
while (true) {
System.out.println("请输入登录密码:");
String password = SYS_SC.nextLine();
System.out.println("请再次输入登录密码:");
String okPassword = SYS_SC.nextLine();
if (okPassword.equals(password)) {
c.setPassword(okPassword);
break;
}else{
System.out.println("两次吗密码输入不一致,请重新输入");
}
}
System.out.println("请输入用户名:");
String userName = SYS_SC.nextLine();
c.setUserName(userName);
while (true) {
System.out.println("请输入性别:");
String sex = SYS_SC.nextLine();
if (sex.equals("男")|| sex.equals("女")){
char gender = sex.charAt(0);
c.setSex(gender);
break;
}else {
System.out.println("暂不支持这个性别,请重新输入~~~");
}
}
System.out.println("请输入电话号码~~~");
String phone = SYS_SC.nextLine();
// 这里也可以用正则表达式判断手机号的合法性
c.setPhone(phone);
System.out.println("请输入存入金额:");
double money = Double.parseDouble(SYS_SC.nextLine());
c.setMoney(money);
ALL_USERS.add(c);
System.out.println("恭喜您注册成功~~~");
}else{
System.out.println("登录名已存在~~~");
}
}
/**
* @Description: 用户和商家登录
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/28 20:44
*/
private static void login() {
while (true) {
System.out.print("请输入登录的名称:");
String loginName = SYS_SC.nextLine();
System.out.print("请您输入登录密码:");
String password = SYS_SC.nextLine();
// 1、 根据登录名查询用户对象
User u = getUserByLoginName(loginName);
// 2、 判断用户对象是否存在 存在说明登录名称正确了
if (u!= null){
// 3、比对密码是否正确
if (u.getPassword().equals(password)){
// 登录成功了
loginUser = u; // 记住登陆成功的用户
LOGGER.info(u.getUserName() +"登录了系统~~~");
// 判断是用户登录的还是商家登录的
if ( u instanceof Customer){
// 当前登录的普通用户
showCustomerMain();
}else{
// 当前登录的是商家用户
showBusinessMain();
}
return;
}else {
System.out.println("密码有毛病");
}
}else {
System.out.println("登录名输入错误,请重新输入~~~~");
}
}
}
/**
* @Description: 商家后台操作界面
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 13:18
*/
private static void showBusinessMain() {
while (true) {
System.out.println("================黑马电影商家界面===================");
LOGGER.info(loginUser.getUserName()+"商家正在看自己的详情~~~");
System.out.println(loginUser.getUserName()+ (loginUser.getSex()=='男' ? "先生": "女士" )+"您好,请您选择商家操作的功能:" );
System.out.println("1、展示详情");
System.out.println("2、上架电影");
System.out.println("3、下架电影");
System.out.println("4、修改电影");
System.out.println("5、退出");
System.out.print("请输入您要操作的命令:");
String command = SYS_SC.nextLine();
switch (command) {
case "1" ->
// 展示详情
showBusinessInfos();
case "2" ->
// 上架电影
addMovie();
case "3" ->
// 下架电影
deleteMovie();
case "4" ->
// 修改电影
updateMovie();
case "5" -> {
// 退出
System.out.println(loginUser.getUserName() + "已退出,欢迎下次再来~~~");
return;
}
default -> System.out.println("不存在该命令~~~");
}
}
}
/**
* @Description: 修改影片信息
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 14:54
*/
private static void updateMovie() {
System.out.println("===============修改电影=================");
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(loginUser);
if ( movies.size()== 0){
System.out.println("当前没有电影可修改~~~");
return;
}
while (true) {
// 让用户选择需要下架的电影名称
System.out.println("请您输入需要修改的电影名称:");
String movieName = SYS_SC.nextLine();
// 去查询有没有这个影片
Movie movie = getMovieByName(movieName);
if (movie!=null){
System.out.print("请你输入修改后的片名:");
String name = SYS_SC.nextLine();
System.out.print("请您输入修改后的主演:");
String actor = SYS_SC.nextLine();
System.out.print("请您输入修改后的时长:");
String time = SYS_SC.nextLine();
System.out.print("请您输入修改后的票价:");
String price = SYS_SC.nextLine();
System.out.print("请你输入修改后的票数:");
String totalNumber = SYS_SC.nextLine();
while (true) {
try {
System.out.println("请你输入修改后的影片放映时间:");
String startTime = SYS_SC.nextLine();
movie.setName(name);
movie.setActor(actor);
movie.setTime(Double.parseDouble(time));
movie.setPrice(Double.parseDouble(price));
movie.setNumber(Integer.parseInt(totalNumber));
movie.setStartTime(sdf.parse(startTime));
System.out.println("恭喜您,已经成功修改了该影片~~~");
showBusinessInfos();
return; // 直接退出去
} catch (Exception e) {
e.printStackTrace();
LOGGER.error("时间解析错误~~~");
}
}
}else {
System.out.println("您的店铺没有上架该影片~~~");
System.out.println("请问要继续吗修改吗?(y/n):");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
case "n":
System.out.println("好的~~~");
return;
}
}
}
}
private static void deleteMovie() {
System.out.println("===============下架电影=================");
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(loginUser);
if ( movies.size()== 0){
System.out.println("当前没有电影可下架~~~");
return;
}
while (true) {
// 让用户选择需要下架的电影名称
System.out.println("请您输入需要下架的电影名称:");
String movieName = SYS_SC.nextLine();
// 去查询有没有这个影片
Movie movie = getMovieByName(movieName);
if (movie!=null){
// 下架这个电影
movies.remove(movie);
System.out.println("您当前店铺已经成功下架了:"+movie.getName());
showBusinessInfos();
return;
}else {
System.out.println("您的店铺没有上架该影片~~~");
System.out.println("请问要继续吗下架吗?(y/n):");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
case "n":
System.out.println("好的~~~");
return;
}
}
}
}
/**
* @Description: 查询当前商家的电影排片
* @Param: [movieName]
* @return: com.lly.bean.Movie
* @Author: lly
* @Date: 2022/7/29 14:50
*/
public static Movie getMovieByName(String movieName){
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(business);
for (Movie movie : movies) {
if (movie.getName().contains(movieName)){
return movie;
}
}
return null;
}
/**
* @Description: 商家进行电影上架
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 13:57
*/
private static void addMovie() {
System.out.println("==============上架电影==================");
Business business = (Business)loginUser;
List<Movie> movies = ALL_MOVIES.get(loginUser);
System.out.print("请你输入新片名:");
String name = SYS_SC.nextLine();
System.out.print("请您输入主演:");
String actor = SYS_SC.nextLine();
System.out.print("请您输入时长:");
String time = SYS_SC.nextLine();
System.out.print("请您输入票价:");
String price = SYS_SC.nextLine();
System.out.print("请你输入票数:");
String totalNumber = SYS_SC.nextLine();
while (true) {
try {
System.out.println("请你输入影片放映时间:");
String startTime = SYS_SC.nextLine();
// 封装成电影对象 ,加入到集合movies中去
Movie movie = new Movie(name,actor, Double.valueOf(time),Double.valueOf(price),Integer.valueOf(totalNumber),
sdf.parse(startTime));
movies.add(movie);
System.out.println("你已经成功上架了:《"+movie.getName()+"》");
return; // 直接退出去
} catch (ParseException e) {
e.printStackTrace();
System.out.println();
LOGGER.error("时间解析错误~~~");
}
}
}
/**
* @Description: 展示当前商家的影片详情
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 13:38
*/
private static void showBusinessInfos() {
System.out.println("=================商家详情界面===================");
// 根据商家对象(就是当前登录用户的loginUser),最为Map的键 提取对应的值就是其排片信息
Business business = (Business)loginUser;
System.out.println(business.getShopName() +"\t\t电话:" + business.getPhone() +"\t\t地址:"+business.getAddress());
List<Movie> movies = ALL_MOVIES.get(loginUser);
if (movies.size()>0){
System.out.println("片名\t\t\t\t\t主演\t\t\t\t时长\t\t\t\t评分\t\t\t票价\t\t\t\t余票数量\t\t\t\t放映时间");
for (Movie movie : movies) {
System.out.println(movie.getName()+"\t\t\t"+movie.getActor()+"\t\t\t"+movie.getTime()+
"\t\t\t"+movie.getScore()+"\t\t\t"+movie.getPrice()+"\t\t\t"+movie.getNumber()+
"\t\t\t\t"+sdf.format(movie.getStartTime()));
}
}else {
System.out.println("您的店铺当前无片可播~~~");
}
}
/**
* @Description: 客户操作界面
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/28 20:56
*/
private static void showCustomerMain() {
System.out.println("===============黑马电影客户界面===============");
System.out.println("请您选择要操作的功能");
System.out.println("1、展示全部影片信息");
System.out.println("2、根据电影名查询电影信息");
System.out.println("3、评分功能");
System.out.println("4、购票功能");
System.out.println("5、退出系统");
while (true) {
System.out.print("请您选择要操作的命令:");
String command = SYS_SC.nextLine();
switch (command){
case "1":
// 展示全部影片
showAllMovies();
break;
case "2":
//根据电影名查询电影信息
selectedMovieByName();
break;
case "3":
score();
break;
case "4":
// 购票功能
buyMovie();
break;
case "5":
System.out.println(loginUser.getUserName() + "已退出,欢迎下次再来~~~");
return;
default:
System.out.println("不存在该命令~~~");
break;
}
}
}
/**
* @Description: 影片评分系统
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/8/15 14:11
*/
private static void score() {
showAllMovies();
System.out.println("请输入要评价的电影名称:");
String movieName = SYS_SC.nextLine();
// 遍历所有电影房信息的Map
ALL_MOVIES.forEach(( business, movies) ->{
movies.forEach(( movie->{
if (movie.getName().equals(movieName)){
System.out.println("请输入分数:");
double score = Double.parseDouble(SYS_SC.nextLine());
if (movie.getScore()==0){
movie.setScore(score);
}else{
double nowScore = (movie.getScore()+score)/2;
movie.setScore(nowScore);
}
System.out.println("评分成功~~~");
}else{
System.out.println("没有找到这部电影~~~~");
}
}
));
});
}
/**
* @Description: 根据电影名称查询电影信息
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/8/15 13:49
*/
private static void selectedMovieByName() {
System.out.println("请输入要查询的电影名称:");
String movieName = SYS_SC.nextLine();
// 遍历全部影片信息的Map
ALL_MOVIES.forEach((business, movies)->{
// 遍历电影信息
movies.forEach((movie)->{
// 判断是否有当前电影
if (movie.getName().contains(movieName)){
System.out.println(business.getShopName() +"\t\t电话:" + business.getPhone() +"\t\t地址:"+business.getAddress());
System.out.println("\t\t\t"+"片名\t\t\t\t\t主演\t\t\t\t时长\t\t\t\t评分\t\t\t票价\t\t\t\t余票数量\t\t\t\t放映时间");
System.out.println("\t\t\t"+movie.getName()+"\t\t\t"+movie.getActor()+"\t\t\t"+movie.getTime()+
"\t\t\t"+movie.getScore()+"\t\t\t"+movie.getPrice()+"\t\t\t"+movie.getNumber()+
"\t\t\t\t"+sdf.format(movie.getStartTime()));
}else{
System.out.println("没有找到这部电影~~~");
}
});
});
}
/**
* @Description: 用户购票功能
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 16:02
*/
private static void buyMovie() {
showAllMovies();
System.out.println("=============用户购票功能==============");
while (true) {
System.out.print("请你输入需要买票的门店:");
String shopName = SYS_SC.nextLine();
// 查询是否存在商家
Business business= getUserByShopName(shopName);
if (business == null){
System.out.println("对不起,没有这个商家");
}else {
// 此商家全部的排片
List<Movie> movies = ALL_MOVIES.get(business);
// 判断此商家是否有排片
if (movies.size()>0){
// 开始进行选片购买
while (true) {
System.out.print("请你输入需要购买的电影名称:");
String movieName =SYS_SC.nextLine();
// 去当前上架下,查询是否有这个电影
Movie movie = getMovieByShopNameAndMovieName(business,movieName);
if (movie !=null){
// 开始购买
while (true) {
System.out.print("请您输入要购买的电影票数:");
String number = SYS_SC.nextLine();
int buyNumber = Integer.parseInt(number);
// 判断余票是否足够
if (movie.getNumber()>=buyNumber){
// 可以购买了
// 计算需要花费的金额
double money = BigDecimal.valueOf(movie.getPrice()).multiply(BigDecimal.valueOf(buyNumber)).doubleValue();
if (loginUser.getMoney()>=money){
// 终于开始买票了
System.out.println("您成功购买了"+movie.getName()+buyNumber+"张票,总金额为:"+money);
// 更新客户与商家的金额
loginUser.setMoney(loginUser.getMoney()-money);
business.setMoney(business.getMoney()+money);
movie.setNumber(movie.getNumber()-buyNumber);
return;
}else {
System.out.println("对不起,你的钱不够~~~");
System.out.println("是否要继续买票? (y/n)");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
default:
System.out.println("好的");
return;
}
}
}else {
// 票数不够
System.out.println("您当前最多可以都买"+movie.getNumber()+"张票~~~");
System.out.println("是否要继续买票? (y/n)");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
default:
System.out.println("好的");
return;
}
}
}
}else {
System.out.println("对不起,电影名称有毛病~~~");
}
}
}else {
System.out.println("该电影院关门了~~~");
System.out.println("是否要继续买票? (y/n)");
String command = SYS_SC.nextLine();
switch (command){
case "y":
break;
default:
System.out.println("好的");
return;
}
}
}
}
}
public static Movie getMovieByShopNameAndMovieName(Business business ,String name ){
List<Movie> movies = ALL_MOVIES.get(business);
for (Movie movie : movies) {
if (movie.getName().contains(name)){
return movie;
}
}
return null;
}
/**
* @Description: 根据店铺名查询是否存在这个商家
* @Param: [shopName]
* @return: com.lly.bean.Business
* @Author: lly
* @Date: 2022/7/29 16:07
*/
public static Business getUserByShopName(String shopName){
Set<Business> businesses = ALL_MOVIES.keySet();
for (Business business : businesses) {
if (business.getShopName().equals(shopName)){
return business;
}
}
return null;
}
/**
* @Description: 展示全部商家和其排片信息
* @Param: []
* @return: void
* @Author: lly
* @Date: 2022/7/29 15:53
*/
private static void showAllMovies() {
ALL_MOVIES.forEach((business, movies) -> {
System.out.println(business.getShopName() +"\t\t电话:" + business.getPhone() +"\t\t地址:"+business.getAddress());
System.out.println("\t\t\t"+"片名\t\t\t\t\t主演\t\t\t\t时长\t\t\t\t评分\t\t\t票价\t\t\t\t余票数量\t\t\t\t放映时间");
for (Movie movie : movies) {
System.out.println("\t\t\t"+movie.getName()+"\t\t\t"+movie.getActor()+"\t\t\t"+movie.getTime()+
"\t\t\t"+movie.getScore()+"\t\t\t"+movie.getPrice()+"\t\t\t"+movie.getNumber()+
"\t\t\t\t"+sdf.format(movie.getStartTime()));
}
});
}
/**
* @Description: 根据用户名查询是否有此用户
* @Param: [loginName]
* @return: com.lly.bean.User
* @Author: lly
* @Date: 2022/7/28 20:51
*/
public static User getUserByLoginName(String loginName){
for (User user : ALL_USERS) {
//判断这个用户的登录名是不是我们想要的
if (user.getLoginName().equals(loginName)){
return user;
}
}
return null; // 查询无此用户
}
}
具体功能图片你们就自己玩吧