上海海洋大学信息学院软件工程作业报告设计题目:停车场管理系统学院:信息学院专业:空间信息与数字技术班级:1、2班学生姓名:代雪1353247(组长)梓桐1353204、亚松1353147 花1353209、仪1353113 程梦雪13531151.引言21世纪以来,现代化产业高速发展,汽车作为日常交通工具已经普及社会的每一个角落,给人们的日常生活带来了极大的便利。
但是随着汽车拥有量的急剧增加,车辆停放的问题随之而来,如果没有合理的停放规则和秩序,势必引起多不必要的麻烦,反而给生活带来不便。
停车场作为交通设施的组成部分,随着交通运输的繁忙和不断发展,人们对其管理的要求也不断提高,都希望管理能够达到便、快捷以及安全的效果。
然后目前的多停车场还处于一种纯人工的管理的模式,在车辆的管理上效率低下,而且十分容易出错。
因此需要一种合适的管理系统来解决这些问题,达到高效,简易的效果,给广大人民的出行带来便。
本论文旨在设计一个简单、高效且实用的停车场管理系统,希望能解决目前管理上存在的一些问题。
系统的设计过程经过了需求分析阶段、概念设计阶段、逻辑结构设计阶段、数据库物理设计阶段、数据库的实施和维护以及系统的调试与测试,最终完成了一个比较完善的收费停车场管理系统。
2.需求分析需求分析是设计数据库的起点,需求分析的结果是否准确地反映了用户的实际要求,将直接影响到后面各个阶段的设计,并影响到设计结果是否合理和实用。
目前停车场的管理式比较落后,已经不能适应现代社会的实际需求,本系统的开发能给管理上带来新鲜的活力,提高管理的效率,具有较高的实用性和开发价值。
通过调查了解分析停车管理的现状,弄清用户对开发的数据库应用系统的确切要求,以及停车场管理的流程,系统的具体功能和数据库中数据信息。
2.1处理对象系统处理的对象包括车辆信息、固定车位信息、自由车位信息、停车车辆信息以及收费记录等五个面。
即固定车位信息:车位编号、车位位置、车牌、车主姓名、车辆品牌、车辆颜色、车辆照片、联系地址、联系式、车位余额;自由车位信息:车位编号、车位位置;车辆信息:车牌、车辆品牌、车辆颜色;停车信息:车位编号、车牌、进入时间、离开时间、时间段、车位类型、在位情况、收费费率;收费记录:车位编号、车牌、停车时间、停车费用、发票编号。
2.2功能要求整个系统具体包括三个子系统,分别为:停车处理子系统、车位综合管理子系统以及收费子系统。
处理的功能包括:车辆信息的查询以及更新;空闲车位信息的查询;固定车位信息的查询;进出车辆记录的更新和收费信息的查询与更新等。
2.3业务流程图2.4数据流图2.5数据字典数据项:表2-1数据项说明数据项编号数据项名数据项含义与其它数据项的关系存储结构别名DI-1 Cwno 车位编号char(10) 编号DI-2 Carno 车牌char(10) 车牌DI-3 Carname 车主姓名char(10) 姓名数据项编号数据项名数据项含义与其它数据项的关系存储结构别名DI-4 Carcolor 车辆颜色char(4) 颜色DI-5 Carpho 车辆照片bit 照片DI-6 Caradd 联系地址char(20) 地址DI-7 Cartel 联系式char(20)DI-8 Carat 在位情况char(4)DI-9 Carin 进入时间datetimeDI-10 Carout 离开时间datetimeDI-11 Carmon 车位余额float 余额DI-12 Montime 收费费率float 费率DI-13 Moneypay 停车费用float 收费DI-14 Cwtype 车位类型char(4)DI-15 Cartime 停车时间float 时间DI-16 Piece 发票编号char(20)Dl-17 Carsb 车辆品牌char(10) 车名Dl-18 Cwpace 车位位置char(10) 位置Dl-19 Timetype 时间段char(6)2.6逻辑描述表2-3处理逻辑描述PR-2判断用户修改要涉及的模块,同时把相应的修改数据传到相应的模块之中固定车位信息模块、自由车位信息模块、停车车辆信息模块、进出车辆记录信息模块、收费记录模块:先确定更新所涉及的功能模块;然后,把更新信息传送到相应的模块中;最后,进行相应的更新操作。
3.概念设计3.1目标概念结构设计师是将需求分析得到的用户需求抽象为信息结构即概念模型的过程。
它是整个数据库设计的关键。
概念结构设计步骤分为两步:第一步是抽象数据并设计局部视图,第二步是集成局部视图,得到全局的概念结构。
3.2设计过程(1)选择中层数据流为切入点,通常选择实际系统中的子系统;(2)设计分E-R图,即各子模块的E-R图;(3)生成初步E-R图,通过合并法,做到各子系统实体、属性、联系统一;(4)生成全局E-R图,通过消除冲突等面。
通过分析系统的业务流图与数据流图,得到系统围绕“车辆”与“车位”之间的相互关系。
3.3阶段成果分E-R图:全局E-R图:4.逻辑设计4.1目标逻辑结构设计的任务是把概念结构设计阶段设计好的基本E-R图转换为与选用DBMS 产品所支持的数据模型相符合的逻辑结构。
逻辑结构设计时一般要分为3步进行:将概念结构转换为一般的关系、网状、层次模型;将转换来的关系、网状、层次模型向特定DBMS 支持下的数据模型转换;对数据模型进行优化。
4.2任务与结果4.2.1数据组织(1)将E-R模型转换为关系模型转换的原则是:一个实体型转换为一个关系模式。
实体的属性就是关系的属性,实体的码就是关系的码。
对于实体间的联系则有以下不同的情况:一个1:1联系可以转换为一个独立的关系模式,也可以与任意一端对应的关系模式合并。
三个或三个以上实体间的一个多元联系可以转换为一个关系模式。
与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。
一个1:n联系可以转换为一个独立的关系模式,也可以与n端对应的关系模式合并。
如果转换为一个独立的关系模式,则与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为n端实体的码。
一个m:n联系转换为一个关系模式。
与该联系相连的各实体的码以及联系本身的属性均转换为关系的属性,而关系的码为各实体码的组合。
3个或3个以上实体间的一个多元联系可以转换位一个关系模型。
与该多元联系相连的各实体的码以及联系本身的属性均转换为关系的属性,各实体的码组成关系的码或关系码的一部分。
4.2.2功能模块图图9.系统功能模块图5.物理设计5.1目标物理设计就是为一个给定的逻辑数据结构模型选取一个最合适应用要求的物理结构的过程。
物理设计通常分为两步:确定数据库的物理结构,在关系数据库中主要指存取法和存储结构;对物理结构进行评价,评价的重点是时间和空间效率。
如果评价结果满足原设计要求,则可进入到物理实施阶段,否则,就需要重新设计或修改物理结构,有时甚至要返回逻辑设计阶段修改数据模型。
物理设计的容包括:为关系模型选择存取法;设计关系、索引等数据库文件的物理存储结构。
5.2任务5.2.1数据存取面由于经常需要判断是否有空余车位,所以要经常查询停车信息,因此在Stop表的Cwno 上建立聚簇索引以提高查询效率。
为了便查询各个车辆的收费记录,在Moneynote表的Carno上建立聚簇索引以提高查询效率5.2.2功能模块图(1)车位信息查询及更新模块图:图10.车位信息查询及更新模块图(2)停车信息查询及更新模块图:图11.停车信息查询及更新模块图(3)收费费率查询及更新模块图:图12.收费费率查询及更新模块图6.部分功能代码实现系统界面车辆进场信息查询出场结算/*** 用于实现登录的界面*/package .view;import .model.LoginModel;import .model.SellModel;import .mytools.*;import .sun.awt.AWTUtilities;import java.awt.*;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.event.MouseListener;import java.awt.event.MouseMotionAdapter; import javax.imageio.ImageIO;import javax.swing.*;import javax.swing.border.MatteBorder;import java.io.*;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.Map;import java.util.Vector;@SuppressWarnings("serial")public class Park extends JFrame implements MouseListener {//全局的位置变量,用于表示鼠标在窗口上的位置static Point origin = new Point();// 定义组件ImagePanel bkim = null;JButton min, close, loginqueding,carIn, carOut, Search, Exit;JComboBox user;JPasswordField password;JPanel contentPane=new JPanel( );String[] allparas = {"1"};int count = ParkPojo.getCarCount();String indate = null;static String userId = getRandomString(8);@SuppressWarnings("unused")public static void main(String[] args) {// TODO Auto-generated method stubPark login1 = new Park();}public void setbutton(JButton jb) {jb.setContentAreaFilled(false);jb.setBorderPainted(false);jb.setFocusPainted(false);jb.addMouseListener(this);jb.setOpaque(false);}// 窗口操作控制菜单public void windowsmenu() {min = new JButton(new ImageIcon("image/Loginmin.png"));min.setBounds(346, 0, 27, 21);min.setRolloverIcon(new ImageIcon("image/LoginminC.png"));setbutton(min);min.setToolTipText("最小化");close = new JButton(new ImageIcon("image/Loginclose.png"));close.setBounds(370, 0, 29, 21);close.setRolloverIcon(new ImageIcon("image/LogincloseC.png"));setbutton(close);close.setToolTipText("关闭");//bkim.add(min);//bkim.add(close);}// 构造函数public Park() {// 设置窗体的样式为当前系统的样式try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());} catch (Exception e) {// TODO: handle exception}Image loginbk = null;try {loginbk = ImageIO.read(new File("image/pc1.jpg"));} catch (IOException e) {// TODO: handle exceptione.printStackTrace();}// 窗口背景面板bkim = new ImagePanel(loginbk);bkim.setLayout(null);carIn = new JButton(new ImageIcon("image/carin.png")); carIn.setBounds(100, 36, , 60);carIn.setRolloverIcon(new ImageIcon("image/carin.png")); setbutton(carIn);carIn.setToolTipText("车辆进场");carOut = new JButton(new ImageIcon("image/carout.png")); carOut.setBounds(100, 100, , 60);carOut.setRolloverIcon(new ImageIcon("image/carout.png")); setbutton(carOut);carOut.setToolTipText("出场结算");Search = new JButton(new ImageIcon("image/infoquery.png")); Search.setBounds(100, 160, , 60);Search.setRolloverIcon(new ImageIcon("image/infoquery.png")); setbutton(Search);Search.setToolTipText("信息查询");Exit = new JButton(new ImageIcon("image/exit.png"));Exit.setBounds(100, 220, , 60);Exit.setRolloverIcon(new ImageIcon("image/exit.png")); setbutton(Exit);Exit.setToolTipText("退出");bkim.add(carIn);bkim.add(carOut);bkim.add(Search);bkim.add(Exit);windowsmenu();this.setUndecorated(true);WindowMove();setOpacity();this.add(bkim);this.setSize(400, 290);this.setVisible(true);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);}// 窗体移动函数public void WindowMove() {//设置没有标题的窗口可以拖动this.addMouseListener(new MouseAdapter(){public void mousePressed(MouseEvent e){ //按下(mousePressed 不是点击,而是鼠标被按下没有抬起)origin.x = e.getX(); //当鼠标按下的时候获得窗口当前的位置origin.y = e.getY();}});this.addMouseMotionListener(new MouseMotionAdapter(){public void mouseDragged(MouseEvent e){Point p =getLocation(); //当鼠标拖动时获取窗口当前位置//设置窗口的位置//窗口当前的位置+ 鼠标当前在窗口的位置- 鼠标按下的时候在窗口的位置setLocation(p.x + e.getX() - origin.x, p.y + e.getY() - origin.y);}});}@Overridepublic void mouseClicked(MouseEvent e) {// TODO Auto-generated method stubif(e.getSource() == min) {setState(JFrame.ICONIFIED);}if(e.getSource() == close) {dispose();}if(e.getSource() == loginqueding) {String userid = user.getSelectedItem().toString().trim();String upassword = new String(this.password.getPassword());if (userid.equals("")) {JOptionPane.showMessageDialog(this, "请输入用户再登录");return;}if (upassword.equals("")) {JOptionPane.showMessageDialog(this, "请输入密码再登录");return;}if (userid.equals("admin") || upassword.equals("418218")) {new UserMainWindows();this.dispose();return;}if (!LoginModel.checkid(userid)) {JOptionPane.showMessageDialog(this, "<html><br/>抱歉 <font color = 'red'>"+userid+"</font> 没有登录此系统的权限<br/>");return;}if (LoginModel.checkpassword(userid, upassword)) {new UserMainWindows();}else {JOptionPane.showMessageDialog(this, "密码不正确,请重新输入密码");this.password.setText("");return;}}else if(e.getSource() == carIn){if(count>0){if(indate == null){count--;ParkPojo.setCarCount(count);Date date=new Date();DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time=format.format(date);indate = time;JOptionPane.showMessageDialog(this, "车辆已停入,剩余车位"+count+",现在时间:"+time);}else{JOptionPane.showMessageDialog(this, "您已停入");}}else{JOptionPane.showMessageDialog(this, "已无车位");}}else if(e.getSource() == carOut){Date date=new Date();DateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");String time=format.format(date);if(indate == null){JOptionPane.showMessageDialog(this, "未停入车辆");}else{count++;ParkPojo.setCarCount(count);int thour = Integer.parseInt(dateDiff(indate,time,"yyyy-MM-dd HH:mm:ss").get("hour").toString())+1;JOptionPane.showMessageDialog(this, "共停放"+thour+"小时,费用是:"+(thour*ParkPojo.getA())+"元");indate = null;}}else if(e.getSource() == Search){if(indate == null){JOptionPane.showMessageDialog(this, "未停入车辆");}else{new ParkQuery(indate);}}else if(e.getSource() == Exit){dispose();}}@Overridepublic void mouseEntered(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseExited(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mousePressed(MouseEvent e) {// TODO Auto-generated method stub}@Overridepublic void mouseReleased(MouseEvent e) {// TODO Auto-generated method stub}// 窗口淡入淡出函数public void setOpacity() {// 窗口设置淡入淡出代码段AWTUtilities.setWindowOpacity(Park.this, 0f);ActionListener lisener = new ActionListener() {float alpha = 0;@Overridepublic void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubif (alpha < 0.9) {AWTUtilities.setWindowOpacity(Park.this, alpha+=0.1);}else {AWTUtilities.setWindowOpacity(Park.this, 1);Timer source = (Timer) e.getSource();source.stop();}}};// 设置线程控制new Timer(50, lisener).start();}/*** 计算两个日期相差几天* @author ym* @date Nov 12, 2013 2:30:38 PM* @param startTime* @param endTime* @param format 格式*/private Map dateDiff(String startTime, String endTime, String format) { // TODO Auto-generated method stub// 按照传入的格式生成一个simpledateformate对象SimpleDateFormat sf = new SimpleDateFormat(format);long nd = 1000 * 24 * 60 * 60;// 一天的毫秒数long nh = 1000 * 60 * 60;// 一小时的毫秒数long nm = 1000 * 60;// 一分钟的毫秒数long ns = 1000;// 一秒钟的毫秒数long diff;Map diffMap = new HashMap();try {diff = sf.parse(endTime).getTime() - sf.parse(startTime).getTime();long day = diff / nd;// 计算差多少天long hour = diff % nd / nh;// 计算差多少小时long min = diff % nd % nh / nm;// 计算差多少分钟long sec = diff % nd % nh % nm / ns;// 计算差多少秒// 输出结果System.out.println("时间相差:" + day + "天" + hour + "小时" + min + "分钟"+ sec + "秒。