资源描述
数据结构课程设计
题目:银行排队系统
目 录
目录 1
摘要 2
第1章 前言 2
1.1 应用背景 2
1.2 设计目标及内容 3
1.3 可行性分析 3
1.3.1 经济可行性 3
1.3.2 技术可行性 3
第2章 系统分析 4
2.1 系统功能 4
2.2 系统功能要求 4
2.2.1 概述 4
2.2.2 开发意图 4
2.2.3 应用目标 5
2.2.4 运行环境 5
2.3 业务流程分析 5
第3章 系统设计 6
3.1 控制流图 6
3.2 数据流图 6
3.3 系统交互及界面设计 7
3.3.1 计数器类的设计 7
3.3.2 队列服务类的设计 7
3.3.3 用户类的设计 7
3.3.4 界面类的设计 8
3.35排队程序(数据结构中的队列实现)………………………………………………………………………12
第4章 系统实现 13
4.1 开发工具Eclips简介 14
4.2 系统功能实现 14
第5章 工作总结 14
摘要
随着银行业务量的快速发展,银行柜台业务承受的压力越来越大,排队等待现象屡见不鲜,银行排长队现象成为困扰银行和用户的难题。为了解决这一难题,目前大部分银行的营业厅都使用了取号系统来改善银行窗口排长队的现象,提高银行的服务效率。本文设计并实现了银行取号模拟系统,模拟取号的整个过程,实现了取号、排队、服务、及管理等功能。系统能够记录用户及工作人员的相关信息,管理员通过对用户及工作人员信息的统计和分析,可以进一步优化银行营业厅的排队问题,提高银行业务办理效率。本文首先对取号系统的研究背景、现状、意义等进行了描述;然后通过数据流图、用例图等对系统进行需求分析,确定系统的功能;在确定功能的基础上,进行系统设计,设计出系统的总体结构和后台数据库;最后,基于java语言实现整个系统,并对系统进行了测试,保证了系统的稳定性和可靠性。
关键词:银行;排队;取号系统;模拟;用例图
说明:由于组内成员所选方向都为Java,所以此课程设计主要用Java来做,里面的排队程序我们用数据结构中的队列替换。
第1章 前言
1.1 应用背景
早期的排队机只是一种将来话均匀分配以及提供人工或自动应答的设备,没有提供较多的功能,随着CTI(Computer Telephone Intergration)技术的发展,在排队机上开发了越来越多功能的中间部件,使排队机的功能日益强大。 排队机采用了性能强大的 CPU、大规模集成电路、数字交换技术和计算机系统集成技术,使系统容量、话务处理能力、可靠性得到了极大的提高。同时,它还采用模块化结构设计,扩容、升级十分方便,可随着业务量的发展而平滑扩容至新的容量,并采用了多种局间中继接口,使其组网更方便。 随着银行业务量的快速发展,银行柜台业务承受的压力越来越大,排队等待现象屡见不鲜,银行排长队现象成为困扰银行和用户的难题,目前大部分银行的营业厅都使用了取号系统来改善银行窗口排长队的现象,提高银行的服务效率。 取号系统是一种综合运用计算机技术、网络技术、多媒体技术、通讯控制技术的高新技术产品,能有效地代替用户进行排队,适用于各类窗口服务行业,目前已经广泛应用于银行、医院等行业。使用取号排队系统,一方面可消除用户长时间“站队”的辛苦、对“站错队”、“插队”的抱怨,避免发生排错队和混乱噪杂的现象,减少许多不必要的纠纷,全面改善服务质量和企业形象,另一方面更可以依据统计数据调整业务分配、挖掘潜力、合理安排窗口服务,减少群众的等候时间,提高办事效率。 同时,排队系统支持多种形式的排队,可依照业务的种类或用户种类进行排队。支持对特殊对象(会员)的优先服务。支持多道手续的自动转移。支持多套派号机及打印机以满足业务大厅有多个出入口的自然环境。 目前,排队机在现代社会的各行各业都有应用,如:银行、保险等金融行业营业大厅,移动、联通、电信等通信行业营业大厅,医院、工商、税务、邮政、机场、餐饮等营业大厅。为用户带来了极大的方便。
1.2 设计目标及内容
银行取号机(叫号机)到处可见,也就是我们在生活中经常看到的排队机,它给用户带来了很大的方便。银行取号模拟系统,模拟了取号排队的功能,至于完全的模拟需要硬件与软件的结合。本模拟系统的最终目标是:实现叫号机的基本功能,即用户到达后可以叫号,工作人员登录进入系统后可以对用户进行办理业务,管理员对用户及工作人员的相关信息进行统计。
取号模拟系统是根据叫号机的原理,实现叫号机软件方面的功能,模拟从用户到达到办理完业务离开的整个流程,其中包括了工作人员的工作流程。主要研究内容分两个模块,首先,用户模块:研究用户排队的统计情况。其次,工作人员模块:工作人员管理模块:主要是对用户及工作人员的相关信息进行统计,如:当前被叫取用户的编号。
1.3 可行性分析
1.3.1 经济可行性
银行取号模拟系统的开发可以解决各行各业中因排队长,排队乱等问题带来的不必要的麻烦,人工管理排队既浪费人力,又不能从根本上解决排队长排队乱的问题,而且容易引起争执。本系统的开发周期短,耗费资金较少,且有一定的实用价值,各类企事业单位都可以使用。
1.3.2 技术可行性
⑴java介绍
Java,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台的总称。用Java实现的HotJava浏览器(支持Java applet)显示了Java的魅力:跨平台、动态的Web、Internet计算。从此,Java被广泛接受并推动了Web的迅速发展,常用的浏览器现在均支持Java applet。总之,目前以看到了Java对信息时代的重要性,未来还会不断发展,Java在应用方面将会有更广阔的前景。近年来随着 Internet 技术的飞速发展及用户需求的不断升级,Web 页面技术也不断的推陈出新,使得Web 站点的功能越来越强大,能够提供的服务种类越来越繁多。
⑵SWT/JFace 介绍
Java是一种强大的编程语言。但强大就意味复杂,尤其是和Java相关的名词就象天上的星星一样,数都数不过来。在本文中就涉及到两个比较常用的名词SWT和JFace。在标题中将SWT和JFace放到一起,并不是说SWT和JFace是一个意思,而是说它们的关系非常紧密。
基于Java的图形库最主要的有三种,它们分别是Swing、AWT和SWT。其中前两个是Sun随JDK一起发布的,而SWT则是由IBM领导的开源项目(现在已经脱离IBM 了)Eclipse的一个子项目。SWT的执行效率非常高。这是由于SWT的底层是由C编写的。由于SWT通过C直接调用系统层的GUI API。因此,使用SWT编写GUI程序,在外观上就和使用C++、Delphi(在Windows下)编写的程序完全一样。它的这一点和AWT类似。 AWT在底层也是使用C直接调用系统层的GUI API。但它们是有区别的,最大的区别可能就是一个是Sun提供的,一个是Eclipse自带的。这就意味着如果使用AWT,只要机器上安装了JDK或 JRE,发布软件时无需带其它的库。而如何使用SWT,在发布时必须要自带上SWT的*.dll(Windows版)或*.so(Linux/Unix 版)文件以及相关的*.jar包。还有就是它们所提供的图形接口有一些差异。SWT可能更丰富一些,我们可以看看Eclipse的界面就知道了。但随着 Sun对AWT库的不断更新,AWT的图形表现能力也在不断地提高。
虽然SWT很强大,但它比较底层。也就是说它的一些功能在使用上还比较低级,不太符合面向对象的特征。因此,在SWT的基础上又开发了JFace。JFace在SWT上进行了一定的扩展。因此,也可说JFace是基于 SWT的,就象在VC中使用MFC来包装Win32 API一样。
第2章 系统分析
2.1 系统功能
本系统最终实现的是银行取号模拟功能,硬件是用简单的组件代替,共分为两个模块,用户模块、工作人员模块。系统最终能够实现用户取号排队,工作人员为用户办理业务,系统统计用户及工作人员的信息,根据统计结果,对系统进行优化。模拟现实生活中银行排队办理业务的过程。具体功能模块如下:
l 用户模块
用户进入界面后,根据自己办理的业务选择不同的业务类型(由于个人能力有限没有实现),用户领取小票排队,系统会在用户选择后,给出用户的信息,如:用户号、前面还有几位用户正在等待。票号由系统根据用户的到达顺序,自动生成。
l 工作人员模块
工作人员按呼叫键后,系统显示信息,提示用户前往柜台办理业务。
2.2 系统功能要求
2.2.1 概述
本系统的任务是,最终用户能成功的办理业务,工作人员可以为用户很好的服务,在服务结束后,用户与工作人员的信息便保存在内存中,以便后面用户的编号的获取,直到服务器停止。
2.2.2 开发意图
⑴ 模拟取号机的功能,减少排队中带来的麻烦;
⑵ 模拟银行取号的过程,加深对排队叫号机原理的认识;
⑶ 巩固自己对java、SWT/JFace、软件工程等相关课程的知识掌握。
2.2.3 应用目标
通过银行取号模拟系统,用户能够快速方便的取号排队进行业务办理,工作人员为用户办理业务,由系统来统计用户的排队情况,工作人员的工作效率等,使银行取号模拟系统能够更好的模拟现实中银行叫号机的功能。
2.2.4 运行环境
l 硬件环境:硬件要求 CPU P4 内存 1G 硬盘 320G,或者更高环境
l 软件环境:windowsXP/windows2000、MyEclipse6.0、Tomcat6.0、JDK1.5
2.3 业务流程分析
下面是理想中的业务流程分析,由于个人能力的有限,只实现了最简单、最基本的功能。
⑴ 用户能够选择业务类型 用户来到前台办理业务,可根据自己的需要选择不同的业务类型,在用户选择后,给出用户提示信息:用户号、业务类型、到达时间、以及队列中的用户数量。
⑵ 工作人员需登录进入服务状态 每个工作人员在进入服务台之前必须输入正确的用户名和密码,否则会给出提示信息,登录后会显示该工作人员的相关信息:工号、窗口号。每个用户名只能登录一次,否则给出重复登录信息。
⑶ 工作人员能够看到当前正在排队的用户数量 为了提高工作人员的办公效率,可提示工作人员当前正在等待的用户的数量,当用户数量为0 时, 如果工作人员继续呼叫,给出提示信息。
⑷ 工作人员可呼叫或重复呼叫用户 在工作人员呼叫用户办理业务时,如该用户没有及时到达,可按重复呼叫按钮继续呼叫。
⑸ 管理员可统计用户及工作人员信息 管理员在进入管理界面时,需要输入正确的用户名和密码,等待验证后方可查看用户及工作人员的详细信息。
⑹ 管理员可统计用户流量 待管理员进入管理界面后,可输入不同的查询条件,按照年月日统计客户流量。
⑺ 管理员可统计用户的平均等待时间 管理员统计用户的平均等待时间分四种情况:
① 特定日期:某年、某月、某日;
② 特定日期段:某年-某年、某月-某月、某日-末日;
③ 特定时间:某日的某时某分某秒-该日的某时某分某秒;
④ 特定时间段:某年某月某日某时某分某秒-某年某月某日某时某分某秒。
⑻ 管理员可统计每个工作人员办理不同业务的数量。
⑼ 管理员可维护用户及工作人员的信息。
⑽ 权限最大的管理员维护其他管理员的信息 本系统有多个管理员,其中有一个初始管理员权限最大,可增、删、改管理员信息,其他管理员只有管理用户及工作人员信息的权限,不能对管理员的信息进行操作。
第3章 系统设计
3.1 控制流图
根据前面的描述,画出该银行排队叫号系统的控制流程图如下:
3.2 数据流图
根据前面的描述,画出该银行排队叫号系统的数据流程图如下:
3.3 系统交互及界面设计
3.3.1 服务器端类的设计
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.FileOutputStream;
import .ServerSocket;
import .Socket;
import java.util.Calendar;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Timer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import java.util.TimerTask;
public class Servernew
{
JFrame jf;
JTextField display=new JTextField();
JLabel show1;
JLabel show2;
JButton pause1;
JButton pause2;
JPanel window1;
JPanel window2;
JPanel jp;
SeqQueue1 CommQueue=new SeqQueue1(1000);
SeqQueue1 VipQueue=new SeqQueue1(1000);
public SeqQueue1 getComm()
{
return CommQueue;
}
public SeqQueue1 getVip()
{
return this.VipQueue;
}
public JTextField getDisplay()
{
return display;
}
public void setDisplay(JTextField display)
{
this.display=display;
}
public void createUI()
{
JFrame jf=new JFrame("排队窗");
JLabel show1=new JLabel("1号窗口");
JLabel show2=new JLabel("2号窗口");
JButton pause1=new JButton("下一位");
JButton pause2=new JButton("下一位");
pause1.setActionCommand("start1");
pause2.setActionCommand("start2");
Container c=jf.getContentPane();
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setSize(600,400);
Dimension ds=Toolkit.getDefaultToolkit().getScreenSize();//ds(display)
Dimension js=jf.getSize();//js(JFramesize)
if(js.width>ds.width)
js.width=ds.width;
if(js.height>ds.height)
js.height=ds.height;
jf.setLocation((ds.width-js.width)/2,(ds.height-js.height)/2);
jf.setVisible(true);
c.setLayout(null);
pause1.setActionCommand("start1");
pause2.setActionCommand("start2");
show1.setBounds(200,270,50,15);
show2.setBounds(400,270,50,15);
pause1.setBounds(178,300,100,50);
pause2.setBounds(378,300,100,50);
display.setBounds(0,100,600,120);
c.add(pause1);
c.add(pause2);
c.add(show1);
c.add(show2);
c.add(display);
display.setFont(new Font("汉真广标", Font.BOLD, 30));
//display.setOpaque(false);
display.setHorizontalAlignment(JTextField.CENTER);
display.setEditable(false);
display.setForeground(Color.blue);
display.setBackground(Color.black);
display.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(51, 255, 51)));
Font fontstr = new Font("宋体", Font.BOLD, 12);
Font fontstr1 = new Font("楷体", Font.BOLD, 16);
show1.setFont(fontstr);
show2.setFont(fontstr);
pause1.setFont(fontstr1);
pause2.setFont(fontstr1);
pause1.setBackground(Color.pink);
pause2.setBackground(Color.pink);
Icon m = new ImageIcon("sixth.jpg");
JLabel pic = new JLabel(m);
pic.setBounds(0,0,600, 155);
c.add(pic);
c.setBackground(Color.white);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ServerListener5 listener=new ServerListener5(this);
pause1.addActionListener(listener);
pause2.addActionListener(listener);
}
public static void main(String args[])
{
Hashtable<String,DataOutputStream> userList=new Hashtable<String,DataOutputStream>();
String name;
DataInputStream dis;
DataOutputStream dos;
try
{
ServerSocket ss=new ServerSocket(9513);//端口号UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU
while(true)
{
Socket s=ss.accept();
dos=new DataOutputStream(s.getOutputStream());
dis=new DataInputStream(s.getInputStream());
name=dis.readUTF();
userList.put(name, dos);
Servernew server=new Servernew();
server.createUI();
MyTimerTask myTimerTask = new MyTimerTask(server);
Timer timer = new Timer();
timer.schedule(myTimerTask, 0, 3000);
MyTimerTask1 myTimerTask1 = new MyTimerTask1(server);
Timer timer1 = new Timer();
timer1.schedule(myTimerTask1, 1000, 3000);
new MyServerReader1(server,name,dis,userList).start();
}
}catch(Exception e)
{
e.printStackTrace();
}
}
}
class ServerListener5 implements ActionListener//按钮事件监听
{
private Servernew ser;
public ServerListener5(Servernew server)
{
this.ser=server;
}
public void actionPerformed(ActionEvent e)
{
if(ser.getVip().isEmpty())
{
int tempNum=1;
String st=e.getActionCommand();
if(st.equals("start1"))
{
try {
tempNum=ser.getVip().delete();
} catch (Exception e1) {
}
ser.getDisplay().setText("请金卡用户"+tempNum+"号,到1号窗口接受服务");
}
else if(st.equals("start2"))
{
try {
tempNum=ser.getVip().delete();
} catch (Exception e1) {
}
ser.getDisplay().setText("请金卡用户"+tempNum+"号,到2号窗口接受服务");
}
}
else if(ser.getComm().isEmpty())
{
int tempNum=-1;
String st=e.getActionCommand();
if(st.equals("start1"))
{
try {
tempNum=ser.getComm().delete();
} catch (Exception e1)
{
ser.getDisplay().setText("无人排队");
}
ser.getDisplay().setText("请普通用户"+tempNum+"号,到1号窗口接受服务");
}
else if(st.equals("start2"))
{
try {
tempNum=ser.getComm().delete();
} catch (Exception e1)
{
ser.getDisplay().setText("无人排队");
}
ser.getDisplay().setText("请普通用户"+tempNum+"号,到2号窗口接受服务");
}
}
else ser.getDisplay().setText("无人排队");
}
}
class MyServerReader1 extends Thread
{
private String name;
private DataInputStream dis;
private Servernew ser;
private Hashtable<String,DataOutputStream> userList;
public MyServerReader1(Servernew ser,String name,DataInputStream dis,Hashtable<String,DataOutputStream> userList)
{
this.ser=ser;
this.name=name;
this.dis=dis;
this.userList=userList;
}
public void run()
{
while(true)
{
int info;
String sendmessage1=ser.getComm().getSize()+ser.getVip().getSize()+"";
String sendmessage2="-"+ser.getVip().getSize()+"";
try
{
info=Integer.parseInt(dis.readUTF());
if(info>0)
{
ser.getComm().append(info);
transmitMessage1(sendmessage1);
}
else if(info<0)
{
ser.getVip().append(Math.abs(info));
transmitMessage1(sendmessage2);
}
}catch(Exception e){}
}
}
public void transmitMessage1(String info)
{
Collection does=userList.values();
DataOutputStream dos;
for(Object o:does)
{
dos=(DataOutputStream)o;
try
{
dos.writeUTF(info);
}catch(Exception e){}
}
}
}
class SeqQueue1 //队列
{
static final int defaultSize=0;
int front;
int rear;
int count;
int maxSize;
int[] data;
public SeqQueue1()
{
initiate(defaultSize);
}
public SeqQueue1(int s)
{
initiate(s);
}
private void initiate(int s)
{
maxSize=s;
front=rear=0;
count=0;
data=new int[s];
}
public void append(Integer obj)throws Exception
{
if(count>0&&front==rear)
{
throw new Exception("排队已满");
}
data[rear]=obj;
rear=(rear+1)%maxSize;
count++;
}
public int delete()throws Exception
{
if(count==0)
{
throw new Exception("真无人排队");
}
int temp=data[front];
front=(front+1)%maxSize;
count--;
return temp;
}
public int getSize()
{
return count;
}
public boolean isEmpty()
{
return count>0;
}
}
class MyTimerTask extends TimerTask //一号窗口定时控制
{
private Servernew ser;
public MyTimerTask(Servernew server)
{
this.ser=server;
}
public void run()
{
if(ser.getVip().isEmpty())
{
int tempNum=1;
try {
tempNum=ser.getVip().delete();
ser.getDisplay().setText("请金卡用户"+tempNum+"号,到1号窗口接受服务");
} catch (Exception e1) {}
}
else if(ser.getComm().isEmpty())
{
int tempNum=-1;
try {
tempNum=ser.getComm().delete();
ser.getDisplay().setText("请普通用户"+tempNum+"号,到1号窗口接受服务");
} catch (Exception e1) {}
}
else
ser.getDisplay().setText("无人排队");
}
}
class MyTimerTask1 extends TimerTask //二号窗口定时控制
{
private Servernew ser;
public MyTimerTask1(Servernew server)
{
this.ser=server;
}
public void run()
{
if(ser.getVip().isEmpty())
{
int tempNum=1;
try {
tempNum=ser.getVip().delete();
ser.getDisplay().setText("请金卡用户"+tempNum+"号,到2号窗口接受服务");
} catch (Exception e1) {}
}
else if(ser.getComm().isEmpty())
{
int tempNum=-1;
try {
tempNum=ser.getComm().delete();
ser.getDisplay().setText("请普通用户"+tempNum+"号,到2号窗口接受服务");
} catch (Exception e1) {}
}
else
ser.getDisplay().setText("无人排队");
}
}
} 3.3.2 客户端的设计
import java.awt.Button;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
展开阅读全文