项目总体要求>>>1. 分层设计2. 使用单例模式封装数据类3. Dao层不可出现于用户交互的代码,如输入或者输入等4. 在合适的地方使用try...catch...进行异常处理[★] 5. 在合适的地方使用 log4j 记录日志:记录在文件中6. 用户输入信息必须进行合理性验证7. 进行增删改操作的最后,必须有确认步骤8. 输出中不能有null、false、true等专业词汇 9. 程序不能出异常,不能非法退出IDEA 控制台菜单界面参考>>>1. 登陆2. 注册(用户名不能重复)3. 最新二手车信息4. 搜索车辆[★] 5. 对比车辆[★] 6. 我的收藏7. 后台管理8. 退出系统项目具体要求>>>
一、登录注册1) 选择登陆:要求输入用户名密码和验证码;输入错误时要给出相应的提示信息2) 选择注册:要求输入用户名,密码,确认密码,邮箱,手机号,注册日期;如果用户名或邮箱或手机号已被使用,则该用户注册失败,也应给与相应的提示信息;邮箱、手机号皆需验证规则二、最新二手车信息3) 选择最新二手车信息:要求显示最新发布的10辆二手车的信息内容:包含车辆的品牌,车型,里程数,价格等呈现的内容如下(参考):品牌    车型    里程数    价格      发布时间1.大众    朗逸    54000    75000     2014-7-52....10.4) 以上看到的10辆车的信息可以进行选择后显示车辆的详细信息:包含之前呈现的信息以及排量,上牌的时间,离合器类型等同时在下方呈现菜单(参考):1. 收藏(必须登陆后才能进行收藏)2. 加入对比3. 购买(只能在登陆后才能看到该菜单项)4. 返回主菜单5) 选择收藏:将该车辆收藏至登陆人的"我的收藏";当用户选择主菜单中的"我的收藏"选项时,可以查看登陆人收藏的所有车辆信息;每个人最多只能收藏10辆车;在收藏第11辆车的时将第01辆车移除收藏列表6) 选择加入对比:可以将车辆加入对比列表,对比列表最多只能存储4辆车的信息;若车辆已满,则给出提示信息,同时可选择是否将页面跳转至"对比车辆"菜单项7) 选择购买:支付登陆人的金额,若金额不够,则购买失败,否则交易成功,打印凭条三、搜索车辆8) 选择搜索车辆:进入如下菜单:1. 根据品牌搜索2. 根据价格搜索3. 根据上牌日期搜索9) 选择根据品牌搜索:要求呈现当前二手车系统的所有品牌信息,显示如下:1. 大众2. 福特3. 斯柯达...10) 选择品牌后,要求呈现该品牌所对应的所有车型,如选择了上面的1后,显示如下:1. 桑塔纳2. 朗逸3. 速腾4. 帕萨特...11) 选择车型后查看该车辆的详细信息,显示对应品牌车型所发布的所有二手车的信息;信息呈现的内容同 3),可以对车辆进行选择,该功能同 4)12) 选择根据价格搜索:呈现如下菜单:1. 5万以下2. 5-10万3. 10-15万4. 15万以上13) 选择任意项搜索出对应价格范围的车辆信息,信息呈现内容同 3),可以对车辆进行选择,该功能同 4)14) 选择根据上牌日期搜索:输入起始年份和月份以及结束的年份和月份,可以显示对应时间范围中的所有二手车信息,内容呈现同 3),可以对车辆进行选择,该功能同 4)四、对比车辆15) 选择对比车辆:呈现如下菜单:1. 查看对比信息2. 删除对比车辆3. 返回上一级菜单16) 选择查看对比信息:可以将之前加入对比的车辆信息进行对比(如果只有一辆车则无法参与对比);          对比信息如下:品牌     雪佛兰       大众       车型     科鲁兹     朗逸价格     65000      75000排量     1.6        1.6里程数   32000      23000离合器   自动挡     手自一体上牌时间  ...       ...返回上一个菜单17) 选择删除对比车辆:需要先显示对比列表中的车辆品牌和车型;选择要删除的车辆,进行删除(删除操作时要给出提示信息)五、我的收藏18) 选择我的收藏,可以查看收藏的车辆信息;内容呈现同 3),可以选择查看收藏车辆的详细信息,该功能同 4)六、后台管理19)   选择后台管理:呈现如下菜单:1. 品牌管理2. 车型管理3. 发布车辆信息20) 选择品牌管理:添加品牌信息21) 选择车型管理:首先呈现所有的品牌信息,选择品牌后呈现如下菜单:1. 添加车型2. 删除车型22) 选择添加车型:输入车型名称并将该车型添加至对应的品牌中23) 选择删除车型:显示当前品牌下所有的对应的车型;选择车型后可以删除该车型(该车型对应的二手车都应删除);收藏夹,对比列表中的该车型的车都应该被删除24) 选择发布车辆信息:要求输入车辆的详细信息(要求品牌和车型是通过选择获取的,其余直接键盘输入获取)同时自动根据当前系统时间记录发布车辆的时间

【项目整体思路】

1、首先是util层(工具层),有两个类(CommonUtil、RandomFourNumUtils)

  • RandomFourNumUtils:生成一个String类型的四位随机数
  • CommonUtil:dateStrIsValid:检查日期字符串是否合法,用Try-Catch抛出异常

2、其次是main层,有两个类(Main、easycheck

  • easycheck:系统使用说明与项目要求(方便对照)
  • Main:主菜单(Switch实现)

3、然后是entity层(实体层),有五个类

  • Admin:实现对象序列化(设置用户名与密码)
  • Brand:同上(设置品牌名称与编号)
  • Car:同上(设置汽车各类参数)
  • CarType:同上(设置车型编号与名称)
  • User:同上(设置用户相关信息)

4、接着是Dao层(数据存取对象层),有三个类

  • UserDao:使用单例模式封装数据类
  • saveUser: 保存用户信息
  • findUserByNameAndPassword:根据账号和密码查询用户
  • FileDB:文件操作类
  • saveObjToFile:将对象保存到文件中,如果本地不存在数据就创建一个文件,用Try-Catch抛出异常
  • getObjFromFile:从文件中读出对象,并且返回文件中存储的序列化对象
  • 如果本地不存在数据,就创建一个文件用Try-Catch抛出异常
  • DataAccessDao:数据访问类,通过I/O流对文件的操作,实现数据的增删改查
  • buy:买车
  • saveCarType:添加车型
  • queryRecentTenCars:查询最新10条发布车辆信息
  • saveBrand:添加品牌,用isExistsBrand判断是否可以添加品牌

5、最后是service层,有四个类

  • 1)首先是CarService类:
  • 可以根据车型、品牌、价格、挂牌日期,筛选出符合条件的车并显示,相应的可以根据情况收藏车或购买,购买的话打印账单
  • 2)其次是RegisterService类:
  • 注册类,检查输入,用户是否已经存在,输入邮箱手机号等,均成功则注册完成
  • 在这里默认用户存款10W
  • 3)然后是LoginService类:
  • 登陆类,与注册类大致相同,其中要防止多人多次登陆,登陆后更改功能1
  • 4)最后是BakendService类:
  • 后台服务,用伪管理员密码控制登陆,进入后可以对车辆类作出增删,也可以对相应已经登陆的用户增加余额

【部分源码】

MAIN

package main;import entity.User;
import service.BakendService;
import service.CarService;
import service.LoginService;
import service.RegisterService;import java.util.Scanner;public class Main {public static boolean isLogin=false;public static User user;public static void main(String[] args)  {boolean isFirst=true;LoginService loginService = new LoginService();RegisterService registerService = new RegisterService();CarService carService = new CarService();BakendService bakendService = new BakendService();System.out.println("****** 主菜单 ******");System.out.println("1: 登录");System.out.println("2: 注册");System.out.println("3: 最新二手车信息");System.out.println("4: 搜索车辆");System.out.println("6: 我的收藏");System.out.println("7: 后台管理");System.out.println("8: 退出系统.");System.out.print("请输入功能前对应的数字:");while (true) {if(!isFirst) {System.out.println("请输入功能前对应的数字继续...");}isFirst=false;Scanner sc = new Scanner(System.in);String choice = sc.nextLine();// 选择switch (choice) {case "1":loginService.login();break;case "2":registerService.register();break;case "3":carService.queryTenCars();break;case "4":carService.searchCar();break;case "6":carService.queryAllMyLike();break;case "7":bakendService.showBakendManage();break;case "8":System.exit(1);break;default:System.out.println("输入的数字错误");break;}}}
}

USER DAO

package dao;import entity.User;import java.util.ArrayList;
import java.util.List;public class UserDao {private static UserDao instance;private String userFile = "user.txt";//单例模式public static UserDao getInstance(){if(instance==null){synchronized (UserDao.class){if(instance==null){instance = new UserDao();}}}return instance;}/*** 保存用户信息* @param user*/public void saveUser(User user){FileDB<List<User>> fileDB = new FileDB<>(userFile);List<User> userList = fileDB.getObjFromFile();if(userList ==null) {userList = new ArrayList<>();}userList.add(user);fileDB.saveObjToFile(userList);}/*** 根据账号和密码查询用户* @param userName* @param password* @return*/public User findUserByNameAndPassword(String userName,String password){FileDB<List<User>> fileDB = new FileDB<>(userFile);List<User> userList = fileDB.getObjFromFile();if(userList!=null) {for (int i = 0; i < userList.size(); i++) {if (userList.get(i).getUserName().equals(userName)&&userList.get(i).getPassword().equals(password)) {return userList.get(i);}}}return null;}/*** 检查用户名是否村子* @param userName* @return*/public boolean checkUserNameExists(String userName){FileDB<List<User>> fileDB = new FileDB<>(userFile);List<User> userList = fileDB.getObjFromFile();if(userList!=null) {for (int i = 0; i < userList.size(); i++) {if (userList.get(i).getUserName().equals(userName)) {return true;}}}return false;}/*** 检查邮箱是否存在* @param email* @return*/public boolean checkEmailExists(String email){FileDB<List<User>> fileDB = new FileDB<>(userFile);List<User> userList = fileDB.getObjFromFile();if(userList!=null) {for (int i = 0; i < userList.size(); i++) {if (userList.get(i).getEmail().equals(email)) {return true;}}}return false;}/*** 检查手机号是否存在* @param phone* @return*/public boolean checkPhoneExists(String phone){FileDB<List<User>> fileDB = new FileDB<>(userFile);List<User> userList = fileDB.getObjFromFile();if(userList!=null) {for (int i = 0; i < userList.size(); i++) {if (userList.get(i).getPhone().equals(phone)) {return true;}}}return false;}
}

ADMIN

package entity;import java.io.Serializable;public class Admin implements Serializable {private String name;//用户名private String password;//密码public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}

LoginService

package service;import dao.UserDao;
import entity.User;
import main.Main;import java.util.Scanner;
/**类名:登录类* 作用:处理登录业务逻辑*/
public class LoginService {/*** 检查用户名格式* @param userName* @return*/public  boolean checkUserName(String userName){if(userName!=null&&userName.trim().length()>=3&&userName.trim().length()<=10){return true;}else{return false;}}public  void login() {UserDao userDao = UserDao.getInstance();// 键盘录入信息System.out.println("登录");System.out.println("------------------------");System.out.println("请输入用户名与密码");System.out.println("用户名长度限制3~10字符");System.out.println("密码长度限制6~32字符");System.out.println("------------------------");Scanner sc = new Scanner(System.in);String userName="";String password="";while (true) {System.out.println("请输入用户名");boolean flag = false;userName = sc.nextLine();// 判断用户名是否合规flag=checkUserName(userName);if (flag == false) {System.out.println("用户名长度错误!");} else {System.out.println("请输入密码");password = sc.nextLine();User user = userDao.findUserByNameAndPassword(userName,password);if(user!=null){System.out.println("登录成功");Main.isLogin=true;Main.user = user;break;}else {System.out.println("用户名密码校验失败,请重新输入用户名、密码");}}}}
}

RandomFourNumUtils

package util;import java.util.Arrays;
import java.util.Collections;
import java.util.List;public class RandomFourNumUtils {/*** 生成一个四位数,包括字母* @return*/public static String getRandomFourNum() {String[] beforeShuffle = new String[] { "2", "3", "4", "5", "6", "7","8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J","K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V","W", "X", "Y", "Z" };List list = Arrays.asList(beforeShuffle);Collections.shuffle(list);StringBuilder sb = new StringBuilder();for (int i = 0; i < list.size(); i++) {sb.append(list.get(i));}String afterShuffle = sb.toString();String result = afterShuffle.substring(5, 9);return result;}
}

《简易二手车交易系统案例—控制台—JAVA—IDEA》相关推荐

  1. ComeFuture英伽学院——2020年 全国大学生英语竞赛【C类初赛真题解析】(持续更新)

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  2. ComeFuture英伽学院——2019年 全国大学生英语竞赛【C类初赛真题解析】大小作文——详细解析

    视频:ComeFuture英伽学院--2019年 全国大学生英语竞赛[C类初赛真题解析]大小作文--详细解析 课件:[课件]2019年大学生英语竞赛C类初赛.pdf 视频:2020年全国大学生英语竞赛 ...

  3. 信息学奥赛真题解析(玩具谜题)

    玩具谜题(2016年信息学奥赛提高组真题) 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业.有一天, 这些玩具小人把小南的眼镜藏了起来.小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的 ...

  4. 信息学奥赛之初赛 第1轮 讲解(01-08课)

    信息学奥赛之初赛讲解 01 计算机概述 系统基本结构 信息学奥赛之初赛讲解 01 计算机概述 系统基本结构_哔哩哔哩_bilibili 信息学奥赛之初赛讲解 02 软件系统 计算机语言 进制转换 信息 ...

  5. 信息学奥赛一本通习题答案(五)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  6. 信息学奥赛一本通习题答案(三)

    最近在给小学生做C++的入门培训,用的教程是信息学奥赛一本通,刷题网址 http://ybt.ssoier.cn:8088/index.php 现将部分习题的答案放在博客上,希望能给其他有需要的人带来 ...

  7. 信息学奥赛一本通 提高篇 第六部分 数学基础 相关的真题

    第1章   快速幂 1875:[13NOIP提高组]转圈游戏 信息学奥赛一本通(C++版)在线评测系统 第2 章  素数 第 3 章  约数 第 4 章  同余问题 第 5 章  矩阵乘法 第 6 章 ...

  8. 信息学奥赛一本通题目代码(非题库)

    为了完善自己学c++,很多人都去读相关文献,就比如<信息学奥赛一本通>,可又对题目无从下手,从今天开始,我将把书上的题目一 一的解析下来,可以做参考,如果有错,可以告诉我,将在下次解析里重 ...

  9. 信息学奥赛一本通(C++版) 刷题 记录

    总目录详见:https://blog.csdn.net/mrcrack/article/details/86501716 信息学奥赛一本通(C++版) 刷题 记录 http://ybt.ssoier. ...

  10. 最近公共祖先三种算法详解 + 模板题 建议新手收藏 例题: 信息学奥赛一本通 祖孙询问 距离

    首先什么是最近公共祖先?? 如图:红色节点的祖先为红色的1, 2, 3. 绿色节点的祖先为绿色的1, 2, 3, 4. 他们的最近公共祖先即他们最先相交的地方,如在上图中黄色的点就是他们的最近公共祖先 ...

最新文章

  1. opencv:在二维定标中的应用
  2. php+ajax+jquery实现jsonp跨域
  3. EF Core3.0+ 通过拦截器实现读写分离与SQL日志记录
  4. 异常:This application has no explicit mapping for /error, so you are seeing this as a fallback.
  5. 基于Weblogic的JNDI数据库连接调优项
  6. 敏捷开发生态系统系列之一:序言及需求管理生态(客户价值导向-可工作软件-响应变化)...
  7. vbScript中WScript.Shell对象的 run 和 exec
  8. SharePoint 2013 Step by Step——How to Create a Lookup Column to Another Site(Cross Site) 阅读目录...
  9. 开源网络监控管理系统:OpenNMS
  10. oracle hint 谓词推进,SQL Hint都无法解救DB性能时,如何通过视图曲线救国?
  11. qt实现类似everything搜索功能,速度没有everything那么快
  12. win32 粒子编辑器
  13. 强烈推荐!!!Ubuntu19.04安装向日葵踩到的坑【尤其是ubuntu 19.04 遇到了libpng12.so.0 导致无法apt 更新!!!!】
  14. VSTO程序基本知识(二)
  15. 计算机无法进行磁盘碎片整理,无法启动win7系统磁盘碎片整理的解决方案
  16. 按摩器具抽查三成不合格 选购需注意哪些?
  17. python如何登录并爬取获得百度指数统计图数据
  18. 基于HTML贪吃蛇游戏摘要,基于JavaScript实现贪吃蛇游戏
  19. STM32开发GPRS传输的GPS定位器 C#编写服务器转发程序,客户端显示轨迹
  20. Linux的基础指令

热门文章

  1. 2022人工智能顶会时间序列论文汇总
  2. strcasecmp php,PHP strcmp()和strcasecmp()的区别实例
  3. python抽签代码_python3 实现口罩抽签的功能
  4. 【心电信号】基于matlab心电图PQRST检测【含Matlab源码 1549期】
  5. 丰田在北美的工厂配置了Invisible AI的智能系统
  6. 教大家怎么识别苹果手机真假
  7. 监控仪表盘_创建监控仪表板
  8. 小米汽车已上路?真TM快啊。。
  9. adb shell 小米手机_【转】【Android测试技巧】01. root后adb shell默认不是root用户时,如何将文件放入手机系统中...
  10. round()函数,四舍五入