资源描述
企业进销存管理系统课程设计软件工程
河南理工大学
计算机科学与技术学院
课程设计报告
( - -1)
课程名称 软件工程课程设计
设计题目 企业进销存管理系统
学生姓名 徐 松
学 号
专业班级 软件工程1302
指导教师 王 静
年 1 月 14 日
一、系统背景....................................................................................................................................3
二、系统分析 3
1.理解需求........................................................................................................................3
2.需求任务分析................................. ......................3
3.数据库..............................................................4
三、系统设计....................................................................................................................................4
1.Item类设计 8
2.数据模型公共类 9
3.Dao公共类 14
3.4系统登录模块设计 15
1.设计登录窗体 15
2.密码文本框 16
3.“登录”按钮 17
3.5系统主窗体设计 18
1.设计菜单栏 18
2.设计工具栏 18
3.设计状态栏 19
3.6销售单模块设计 19
1.设计销售窗体 19
2.添加销售商品 19
3.销售统计 19
4.商品销售 19
四、总结..........................................................................................................................................21
一、系统背景
中小企业在中国经济发展中具有重要地位,随着中国市场经济的蓬勃发展和人们对计算机的普遍应用,批发、零售行业正处在一个高速发展的时期。行业的快速发展必然导致竞争的加剧,要想在激烈的市场竞争中谋求发展,客观上要求企业必须加强内部管理,提高运营效率。而中国大部分小型批发、零售企业在信息机制上还没有摆脱原有的手工模式,企业内部没有形成完善的、有效的信息化管理机制,企业发展的动力不足,从而影响企业的持续、稳定、快速的发展。
当今国内外多数企业的竞争特点是:产品的种类、规格特别多,市场需求变化很快,与分销商,零售商的关系日益密切等。而随着业务量的扩大,传统的管理方法已经无法处理日益膨胀的大量的业务数据,企业采用电脑管理进货、库存、销售等诸多环节也已成为趋势及必然。
实现企业信息化管理是现代社会中小企业稳步发展的必要条件,它能够提高企业的管理水平和工作效率,最大限度地减少手工操作带来的失误。进销存管理系统正是一个信息化管理软件,能够实现企业的进货、销售、库存管理等各项业务的信息化管理。 出于以上原因,本课程设计将基于MySQL数据库并以JAVA为开发环境设计实现一个企业进销存管理系统。该系统包括基础信息管理、进货管理、销售管理、库存管理、查询统计、系统管理几个模块,主要是处理商业企业商品的采购、库存和销售各个环节的活动,具有良好的人机界面。考虑到系统的使用对象可能较多,权限管理良好,数据查询方便,支持多条件查询。
二、系统分析
1、理解需求
本系统经过进销存系统的终端用户和客户的进行调研后,得出系统需求的关键
(1)进货管理 商品进货信息管理:商品进货信息包括商品进货数量、单价、供货商、进货日期、等。商品进货管理功能完成进货信息登记、修改和删除等。更新库存:进货信息的变动直接关系到库存的变化
(2)库存管理
库存商品信息管理::商品库存信息包括商品进货数量、单价、供货商、进货日期、等。商品库存管理功能完成库存信息登记、修改和删除、查询等。
(3)销售管理
信息管理:商品销售信息包括商品销售数量、单价、统计日等商品销售。管理功能
完成销售信息登记、修改和删除,以及销售总汇查询。
本系统应该对基础数据(用户数据字典)进行维护。系统应该提供强大的数据统计、查询、报表生成及打印等功能。系统客户端运行在Windows各版的平台下,系统还应该有一个较好飞图形用户界面。系统还应该有很好的可扩展性。系统应该容易上手,方便使用。
2、需求分析任务
第一项任务:画出“进销存管理系统”的组合结构图,即组织结构模型。
第二项任务:画出“进销存管理系统”的业务操作图,即业务操作模型。
第三项任务:画出“进销存管理系统”的数据流程图。
第四项任务:列出“进销存管理系统”的功能点列表,即功能模型。
第五项任务:列出“进销存管理系统”的性能点表,即性能模型。
第六项任务:确定“进销存管理系统”的环境模型,即运行环境。
3.数据库
数据库设计是进销存信息系统的核心,采用规范化设计,使数据库结构尽可能简化,减少冗余,保持系统数据结构的一致性。根据不同的需求,一个商品流通企业进销存管理系统可包括几个到上百个不等的数据表、数据视图、存储过程以及函数等,但最基本的数据表应该包括:操作用户数据表、公司信息数据表、采购明细数据表、采购客户数据表、采购信息数据表、供应客户数据表、商品信息数据表、销售明细数据表和销售信息数据表;数据视图包括:采购入库明细视图、累计采购商品视图、累计销售商品视图和销售出库明细视图
角色定义
组织结构图中各单位职责说明与相关业务,如表:
销售人员信息单据
进货信息单据
商品销售信息单据
用户信息单据
经手人信息表(jsr)
客户实体E-R图
企业进销存管理系统将记录所有的客户信息,在销售、退货等操作时,将直接引用该客户的实体属性。客户实体包括客户编号、客户名称、简称、地址、电话、邮政编码、联系人、联系人电话、传真、开户行和账号等属性,客户实体E-R图如图所示。
商品实体E-R图
供应商实体E-R图
进销存管理系统数据流图
三、系统设计
1.目的
从该阶段开始正式进入软件的实际开发阶段,本阶段完成系统的大致设计并明确司徒的数据结构与软件结构。在软件设计阶段主要是把一个软件需求转化为软件表示的过程,
2.术语定义
总体结构
软件系统的总体逻辑结构。本系统采用面向对象的设计方法,因此逻辑
结构为部件组装图
概念模型
CDM 关系数据库的逻辑设计模型,包括一张逻辑E-R图及相应的数据字典
物理模型
PDM 关系数据库物理设计模型,包括一张物理表关系图及其相应的数据字典
角色
数据库中享有某些特权操作的用户
子系统
具有相对独立功能的小系统,一个大的软件系统能够划分为多个子系
统,每个子系统可由多个模块或多个部件组成
模块
具有功能独立、能被调用的信息单元
3. 系统构架
1.Item类设计
Item类是系统的公共类之一,主要用于封装和传递参数信息,这是典型命令模式的实现。在Dao类中经常使用该类作为方法参数;另外,在各个窗体界面中也经常使用该类作组件数据,其toString()方法将返回name属性值,因此显示到各个组件上的内容就是Item类的对象所代表的商品、供应商或者客户等信息中的名称。
关键代码如下
package com.lzw;
public class Item {
private String id; //定义id属性
private String name; //定义name属性
public Item() {
}
public Item(String id,String name) {
this.id=id;
this.name=name;
}
public String getId() { //定义得到id属性的方法
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() { //定义得到那么属性的方法
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() { //定义该类字符串的表现形式
return getName();
}
}
2.数据模型公共类
在com.lzw.dao.model包中存放的是数据模型公共类,它们对应着数据库中不同的数据表,这些模型将被访问数据库的Dao类和程序中各个模块甚至各个组件所使用。和Item公共类的使用方法类似,数据模型也是对数据表中所有字段(属性)的封装,可是数据模型是纯粹的模型类,它不但需要重写父类的toString()方法,还要重写hashCode()方法和equals()方法模型类主要用于存储数据,并经过相应的getXXX()方法和setXXX()方法实现不同属性的访问原则。
以商品数据表为例其代码:
public class TbSpinfo implements java.io.Serializable {
private String id;
private String spname;
private String jc;
private String cd;
private String dw;
private String gg;
private String bz;
private String ph;
private String pzwh;
private String memo;
private String gysname;
public TbSpinfo() {
}
public TbSpinfo(String id) {
this.id = id;
}
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
public String getSpname() {
return this.spname;
}
public void setSpname(String spname) {
this.spname = spname;
}
public String getJc() {
return this.jc;
}
public void setJc(String jc) {
this.jc = jc;
}
public String getCd() {
return this.cd;
}
public void setCd(String cd) {
this.cd = cd;
}
public String getDw() {
return this.dw;
}
public void setDw(String dw) {
this.dw = dw;
}
public String getGg() {
return this.gg;
}
public void setGg(String gg) {
this.gg = gg;
}
public String getBz() {
return this.bz;
}
public void setBz(String bz) {
this.bz = bz;
}
public String getPh() {
return this.ph;
}
public void setPh(String ph) {
this.ph = ph;
}
public String getPzwh() {
return this.pzwh;
}
public void setPzwh(String pzwh) {
this.pzwh = pzwh;
}
public String getMemo() {
return this.memo;
}
public void setMemo(String memo) {
this.memo = memo;
}
public String getGysname() {
return this.gysname;
}
public void setGysname(String gysname) {
this.gysname = gysname;
}
public String toString() {
return getSpname();
}
@Override
public int hashCode() {
final int PRIME = 31;
int result = 1;
result = PRIME * result + ((bz == null) ? 0 : bz.hashCode());
result = PRIME * result + ((cd == null) ? 0 : cd.hashCode());
result = PRIME * result + ((dw == null) ? 0 : dw.hashCode());
result = PRIME * result + ((gg == null) ? 0 : gg.hashCode());
result = PRIME * result + ((gysname == null) ? 0 : gysname.hashCode());
result = PRIME * result + ((id == null) ? 0 : id.hashCode());
result = PRIME * result + ((jc == null) ? 0 : jc.hashCode());
result = PRIME * result + ((memo == null) ? 0 : memo.hashCode());
result = PRIME * result + ((ph == null) ? 0 : ph.hashCode());
result = PRIME * result + ((pzwh == null) ? 0 : pzwh.hashCode());
result = PRIME * result + ((spname == null) ? 0 : spname.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final TbSpinfo other = (TbSpinfo) obj;
if (bz == null) {
if (other.bz != null)
return false;
} else if (!bz.equals(other.bz))
return false;
if (cd == null) {
if (other.cd != null)
return false;
} else if (!cd.equals(other.cd))
return false;
if (dw == null) {
if (other.dw != null)
return false;
} else if (!dw.equals(other.dw))
return false;
if (gg == null) {
if (other.gg != null)
return false;
} else if (!gg.equals(other.gg))
return false;
if (gysname == null) {
if (other.gysname != null)
return false;
} else if (!gysname.equals(other.gysname))
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (jc == null) {
if (other.jc != null)
return false;
} else if (!jc.equals(other.jc))
return false;
if (memo == null) {
if (other.memo != null)
return false;
} else if (!memo.equals(other.memo))
return false;
if (ph == null) {
if (other.ph != null)
return false;
} else if (!ph.equals(other.ph))
return false;
if (pzwh == null) {
if (other.pzwh != null)
return false;
} else if (!pzwh.equals(other.pzwh))
return false;
if (spname == null) {
if (other.spname != null)
return false;
} else if (!spname.equals(other.spname))
return false;
return true;
}
}
3.Dao公共类
Dao的全称是Data Access Object,即数据访问对象。本项目中应用该名称作为数据库访问类的名称,在该类中实现了数据库的驱动、连接、关闭和多个操作数据库的方法,这些方法包括不同数据表的操作方法。在介绍具体的数据库访问方法之前,先来看一下Dao类的定义,也就是数据库驱动和连接的代码。
代码如下
public class Dao {
static Statement sql;
static ResultSet res;
protected static String dbClassName="com.mysql.jdbc.Driver";
protected static String dbUrl="jdbc:mysql://localhost:3306/db_database28";
protected static String dbUser="root";
protected static String dbPwd="";
protected static String second = null;
public static Connection conn=null;
static{
try{
if(conn==null){
Class.forName(dbClassName).newInstance();
conn = (Connection) DriverManager.getConnection(dbUrl,dbUser,dbPwd);
}
}catch(Exception ee){
ee.printStackTrace();
}
}
3.4系统登录模块设计
1.设计登录窗体
登录模块的窗体设计由两部分组成,一部分是登录窗体,另一部分是窗体中带背景图片的内容面板。
1.创立内容面板
public class LoginPanel extends JPanel {
public int width, height;
private Image img;
public LoginPanel() {
super();
URL url = getClass().getResource("/res/login.jpg");
img = new ImageIcon(url).getImage();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, this);
}
}
2.创立登录窗体
private LoginPanel getLoginPanel() {
if (loginPanel == null) {
jLabel1 = new JLabel();
jLabel1.setBounds(new Rectangle(86, 71, 55, 18));
jLabel1.setText("密 码:");
jLabel = new JLabel();
jLabel.setText("用户名:");
jLabel.setBounds(new Rectangle(85, 41, 56, 18));
loginPanel = new LoginPanel();
loginPanel.setLayout(null);
loginPanel.setBackground(new Color(0xD8DDC7));
loginPanel.add(jLabel, null);
loginPanel.add(getUserField(), null);
loginPanel.add(jLabel1, null);
loginPanel.add(getPasswordField(), null);
loginPanel.add(getLoginButton(), null);
loginPanel.add(getExitButton(), null);
}
return loginPanel;
}
2.密码文本框
在系统登录窗体的“密码”文本框中添加了按键事件监听器,它在获取到“密码”文本框输入的回车字符时将执行登录事件,也就是说在“密码”文本框输入密码后,按Enter键将执行与单击“登录”按钮相同的业务逻辑。
代码如下:
private JPasswordField getPasswordField() {
if (passwordField == null) {
passwordField = new JPasswordField();
passwordField.setBounds(new Rectangle(143, 69, 125, 22));
passwordField.addKeyListener(new KeyAdapter() {
public void keyTyped(KeyEvent e) {
if (e.getKeyChar() == '\n')
loginButton.doClick();
}
});
}
return passwordField;
}
3.“登录”按钮
“登录”按钮用于执行用户名和密码的验证工作,如果验证用户名和密码有效,则启动系统,否则禁止进入系统。
在“登录”按钮的动作事件监听器中,首先获取用户输入的用户名与密码信息,然后调用Dao类的checkLogin()方法,如果该方法返回true则登录成功,否则禁止用户登录,并提示输入的用户名与密码无法登录系统。
如图所示
代码如下:
private JButton getLoginButton() {
if (loginButton == null) {
loginButton = new JButton();
loginButton.setBounds(new Rectangle(109, 114, 48, 20));
loginButton.setIcon(new ImageIcon(getClass().getResource(
"/res/loginButton.jpg")));
loginButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
userStr = userField.getText();
String passStr = new String(passwordField
.getPassword());
if (!Dao.checkLogin(userStr, passStr)) {
JOptionPane.showMessageDialog(LoginDialog.this,
"用户名与密码无法登录", "登录失败",
JOptionPane.ERROR_MESSAGE);
return;
}
} catch (Exception e1) {
e1.printStackTrace();
}
mainFrame.setDefaultCloseOperation(EXIT_ON_CLOSE);
mainFrame.setVisible(true);
MainFrame.getCzyStateLabel().setText(userStr);
setVisible(false);
}
});
}
return loginButton;
}
3.5系统主窗体设计
1.设计菜单栏
本系统的菜单栏是由MenuBar类实现的,该类是一个自定义菜单栏类,它继承JMenuBar类成为Swing的菜单栏组件。下面以创立进货单菜单为例,。
(1)创立MenuBar类,该类继承javax.swing.JMenuBar类,而且在该类中定义一个私有的成员变量,类型为JMenu,用于表示菜单对象。
(2)编写一个名称为getJinhuo_Menu()的方法,该方法的返回值为一个JMenu对象,也就是一个菜单对象。在该方法中,当进货菜单对象为null时,创立一个菜单对象,并为其设置菜单名和快捷键。
(3)编写一个初始化菜单栏界面的方法initialize(),在该方法中,首先设置组件的尺寸,然后调用JMenuBar对象的add()方法向菜单栏中添加一个菜单。
(4)编写以下构造方法,用于调用初始化菜单栏界面。
(5)在MenuBar类,再创立一个JMenuItem类型的成员变量jinhuoItem,表示进货菜单项。
(6)编写一个名称为getJinhuoItem()的方法,该方法的返回值为一个JMenuItem对象,也就是一个菜单项对象。在该方法中,当进货单菜单项对象为null时,创立一个菜单项对象,并为其设置菜单项名、图标和动作事件监听器。(7)按照步骤(5)和步骤(6)的方法再创立一个进货退货菜单项对象,名称为jinhuo_tuihuoItem。
(8)在getJinhuo_Menu()方法中,应用JMenu对象的add()方法向菜单中添加菜单项。
2.设计工具栏
工具栏用于放置常见命令按钮,如进货单、销售单、库存盘点等。
向本系统中添加工具栏的方法和添加菜单栏的方法类似,也需要继承Swing的JTool组件编写自己的工具栏。当然,也能够直接使用Swing的JTool组件。组件的initialize()方法用于初始化工具栏的程序界面。
3.设计状态栏
本系统的状态栏显示了当前选择的功能窗体、登录用户名、当前日期和本系统所属公司,即版权所有者等信息,如下图所示。
3.6销售单模块设计
1.设计销售窗体
2.添加销售商品
在销售单窗体中单击“添加”按钮,将向table表格中添加新的空行,操作员能够在空行的第一列字段的商品下拉列表框中选择销售的商品,这个下拉列表框和进货单窗体的不同,它不是根据供应商字段确定选择框内容,而是包含了数据库中所有能够销售的商品。要实现添加销售商品功能,需要为“添加”按钮添加动作监听器,在监听器中实现相应的业务逻辑。
3.销售统计
和进货单的统计功能类似,销售单也需要统计功能,统计的内容包括货品数量、品种数量、合计金额等信息,实现方式也是经过table表格的事件监听器来处理相应的统计业务,可是销售单窗体使用的不是PropertyChangeListener属性改变事件监听器,而是使用ContainerListener容器监听器。
4.商品销售
在销售单窗体中添加完销售商品之后,单击“销售”按钮,将完成本次销售单的销售业务。系统会记录本次销售信息,并从库存表中扣除销售的商品数量。这些业务处理都是在“销售”按钮的动作监听器中完成的,该监听器需要获取销售单窗体中的所有销售信息和商品信息,将所有商品信息封装为销售明细表的模型对象,并将这些模型对象放到一个集合中,然后调用Dao公共类的insertSellInfo()方法将该集合与销售主表的模型对象保存到数据库中。
初始化表格代码:
private void initTable() {
String[] columnNames = { "商品名称", "商品编号", "供应商", "产地", "单位", "规格", "单价",
"数量", "包装", "批号", "批准文号" };
((DefaultTableModel) table.getModel())
.setColumnIdentifiers(columnNames);
TableColumn column = table.getColumnModel().getColumn(0);
final DefaultCellEditor editor = new DefaultCellEditor(sp);
editor.setClickCountToStart(2);
column.setCellEditor(editor);
}
初始化商品下拉框:
private void initSpBox() {
List list = new ArrayList();
ResultSet set = Dao.query(" select * from tb_spinfo"
+ " where id in (select id from tb_kucun where kcsl>0)");
sp.removeAllItems();
sp.addItem(new TbSpinfo());
for (int i = 0; table != null && i < table.getRowCount(); i++) {
TbSpinfo tmpInfo = (TbSpinfo) table.getValueAt(i, 0);
if (tmpInfo != null && tmpInfo.getId() != null)
list.add(tmpInfo.getId());
}
try {
while (set.next()) {
TbSpinfo spinfo = new TbSpinfo();
spinfo.setId(set.getString("id").trim());
if (list.contains(spinfo.getId()))
continue;
spinfo.setSpname(set.getString("spname").trim());
spinfo.setCd(set.getString("cd").trim());
spinfo.setJc(set.getString("jc").trim());
spinfo.setDw(set.getString("dw").trim());
spinfo.setGg(set.getString("gg").trim());
spinfo.setBz(set.getString("bz").trim());
spinfo.setPh(set.getString("ph").
展开阅读全文