大家好,又见面了,我是你们的朋友全栈君。
【摘要】
进销存管理系统是一个基于Internet的应用系统,它是一个面对当前的进销存管理工作基本还处于手工和半信息自动化处理状态而应运而生的一个基于Internet的一个完全信息自动化的系统,整个系统从符合操作简便、界面友好、灵活、实用、安全的要求出发,完成进货、销售、库存管理的全过程。
企业单位只需具备访问Internet的条件即可在系统发布的站点上进行进销存的管理。在图型化的人机界面中完成日常的进销存管理工作.一方面摆脱了时间和空间的限制,另一方面有效的解决的数据共享的问题。
经过实际使用证明,本文所设计的企业进销存管理系统可以满足企业进货、销售管理方面的需要。
【关键词】库存 销售 企业进销存管理系统
目录
摘要 1
0 引言 1
1 系统分析 2
1.1 需求分析 2
1.2 可行性分析 2
2 总体设计 2
2.1 项目规划 2
2.2 系统功能结构图 3
3 系统设计 3
3.1 设计目标 3
3.2 开发及运行环境 4
3.3 数据库设计 4
4 JavaBean的编写 5
4.1 数据库操作的JavaBean的编写 5
4.2 中文乱码处理的JavaBean的编写 7
4.3 客户基本信息的JavaBean的编写 7
4.4 提交客户信息的JavaBean的编写 8
4.5 查询、分页JavaBean的编写(QuestString.java) 9
4.6 显示系统时间的JavaBean的编写 14
5 用户登录模块设计 15
6 系统首页设计 16
7 基础信息管理主要功能模块设计 18
7.1 客户信息管理设计 18
7.2 客户信息查询设计 19
8 库存管理主要功能模块设计 22
8.1 商品入库信息设计 23
8.2 商品价格调整设计 26
附录A 参考文献
附录B 数据表
附录C 文件架构图
0 引言
随着中国电子商务、互联网业务的迅猛发展,国内许多企业已跨入电脑网络管理时代,并因此提高了管理效率和市场竞争力。但目前仍有部分企业还停留在原始计账管理阶段。而随着全球经济信息化的进程和WTO的成功实现,企业面临着前所未有的机遇和挑战,在如此激变的社会形势和激烈的市场竞争下,愈来愈多的企业管理者意识到效率管理和科学管理的重要性,以及增强市场竞争力的迫切性,因此建立科学、规范、高效的管理制度和秉承富有竞争力的经营理念是每一个企业管理者的渴望,企业采用电脑管理进货、库存、销售等诸多环节也已成为趋势及必然。
在进货、库存、销售环节中,由于商品种类繁多、业务量大、库存管理复杂,使用手工操作的工作量很大,在操作过程中也很容易出现各种错误。而采用计算机管理则可以大大提高日常工作的效率,不仅将原来由手工操作的进货、出货及销售这一整套流程用计算机进行全程管理,而且消除了手工操作中可能存在的不确定因素,达到进销存管理流程清晰,从而能够比较彻底地贯彻经营者的管理模式。
1 系统分析
1.1 需求分析
通过调查研究,要求系统满足以下功能:
由于操作人员的计算机知识水平有限,因此要求系统具有良好的人机界面。
如果系统的使用对象较多,则要求有较好的权限管理。
方便的数据查询功能,并支持多条件查询。
在各种单据中根据输入的基础数据自动计算金额,尽量减少人工干预。
对客户或供应商的往来账目进行有效管理,绝不存在假账、漏账、差账等情况。
通过计算机,能够直接“透视”仓库存储情况。
对某一时间段内的某种商品的销售情况按数量或金额进行升序或降序排行。
图表分析年销售额。
1.2 可行性分析
通过计算机网络系统对企业进行全面的管理,满足了企业的现代化管理的要求。
经济性
当前许多中小型企业都使用人工管理方式(即纸和笔)来管理企业的进销存,这样的管理方式既困难又浪费时间和成本,并且容易出现漏账、差账的情况,因此中小企业应该向大型企业那样采用先进的管理方式,提高企业效率、降低企业运营成本。
技术性
企业进销存管理系统从中小企业的实际出发,可有效地管理企业的进销存情况,并降低企业运营成本、及时调整营销策略、提高库房的利用率。
2 总体设计
2.1 项目规划
企业进销存管理系统是一个典型的数据库开发应用程序,由基础信息管理、库存管理、商品销售、查询统计、往来管理、系统设置6部分组成。
基础信息管理
该模块主要是对企业的客户信息、商品信息、供应商信息进行有效管理,并可实现按不同条件对这些数据进行查询。
库存管理
该模块主要是对商品的入库及入库退货信息进行有效管理,对商品的价格进行调整,同时可按不同条件查询库存商品。
商品销售
该模块主要是对商品的销售及销售退货信息进行有效管理。
查询统计
该模块主要实现按不同条件查询商品的入库信息及销售信息,并可对某一时间段内某种商品的销售情况按数量或金额进行升序或降序排行,同时可对某一年度的销售额进行图表分析。
往来管理
该模块主要实现对商品的入库结账、入库退货结账、销售结账、销售退货结账信息进行有效管理,同时可实现销售结账信息及入库结账信息的查询操作。
系统设置
访模块主要实现对操作员及操作员密码进行有效管理。
2.2 系统功能结构图
企业进销存管理系统的功能结构如图1所示。
3.1 设计目标
本系统针对中小型企业进销存管理现状,通过网络对企业的进销存进行有效管理。本系统主要实现如下目标:
系统采用人机对话方式,界面美观友好,信息查询灵活、方便、快捷、准确,数据存储安全可靠。
实现企业内一些基础信息的设置及查询。
商品的入库、入库退货、销售、销售退货流程清晰。
数据计算自动完成,提高工作效率。
与供应商和客户之间的账目清晰。
以图表形式对年销售额进行分析。
实现多条件查询。
可方便快捷地查询库存信息,并可对商品价格进行调整。
对某一时间段内的某种商品按照销售数量或销售金额进行销售升序排行或降序排行。
操作员可以随时修改自己的口令。
对用户输入的数据,系统进行严格的数据检验,尽可能排除人为的错误。
系统最大限度地实现了易维护性和易操作性。
系统运行稳定、安全可靠。
3.2 开发及运行环境
硬件平台:
CPU:P41.8GHz。
内存:256MB以上。
软件平台:
操作系统:Windows 2000。
数据库:SQL Server 2000。
开发工具包:JDK Version1.4.2。
JSP服务器:Tomcat。
浏览器:IE5.0,推荐使用IE6.0。
分辨率:最佳效果1024×768像素。
3.3 数据库设计
本系统采用SQL Server 2000数据库,系统数据库名称为db_shopping。数据库db_shopping中包含17张表。关于数据库中的数据表请参见附录B。
4 JavaBean的编写
根据系统的需求编写需要的JavaBean。下面将给出企业进销存管理系统中所需要的JavaBean的编写过程。
4.1 数据库操作的JavaBean的编写
数据库连接的JavaBean的编写代码如下:
package com.mingri.dbconn;
import java.sql.;
import javax.naming.;
import javax.sql.DataSource;
public class DBConn
{
public static synchronized Connection getConnection() throws Exception{
try{
Context initCtx=new javax.naming.InitialContext(); //获得JNDI初始上下文对象
//在JNDI命名空间java:comp/env段里获得上下文对象
Context envCtx=(Context)initCtx.lookup(“java:comp/env”);
DataSource ds=(DataSource)envCtx.lookup(“jdbc/mingri”); //通过JNDI名获得数据源对象
return ds.getConnection(); }
catch(SQLException e){
throw e;
}
catch(NamingException e){
throw e;
}
}
}
数据库操作的JavaBean的编写代码如下:
package com.mingri.dbconn;
import java.sql.*;
import com.mingri.dbconn.DBConn;
public class DBResult
{
private Connection con;
public DBResult(){
this.con=DBConn.getConnection();
}
/**
- 用于获得执行SQL语句的ResultSet对象
/
public ResultSet getResult(String sql){
try{
Statement stmt=con.createStatement();
ResultSet rs=stmt.executeQuery(sql);
return rs;
}
catch(Exception e){}
return null;
}
/* - 用于执行SQL语句没有返回值
/
public void doExecute(String sql){
try{
Statement stmt=con.createStatement();
stmt.executeQuery(sql);
}catch(Exception e){}
}
/* - 用于获得执行SQL语句的PreparedStatement(预处理)对象
/
public PreparedStatement getPreparedStatement(String sql){
try{
PreparedStatement pstmt=con.prepareStatement(sql);
return pstmt;
}
catch(Exception e){}
return null;
}
/* - 关闭连接
/
public void closeCon(){
try{
this.con.close();
}catch(Exception e){
e.printStackTrace(); } }
}
4.2 中文乱码处理的JavaBean的编写
在JSP开发中,经常出现乱码问题,我们可以指定编码方式,以消除乱码。
package com.mingri.chinese;
import java.io.;
public class ToChinese
{
public String trans(String chi){
String result=null;
byte temp[];
try{
temp=chi.getBytes(“iso-8859-1”);
result=new String(temp);
}
catch(UnsupportedEncodingException e){
System.out.println(e.toString());
}
return result;
}
}
4.3 客户基本信息的JavaBean的编写
这段代码用来封装客户的基本信息,并对每个属性提供setXXX()和getXXX()方法,来对其进行操作。
package com.mingri.info;
public class KhinfoBean
{
private String khname; //客户全称
private String khjc; //客户简称
private String address; //地址
private String postcode; //邮政编码
private String tel; //电话
private String fax; //传真
private String lxr; //联系人
private String lxrtel; //联系人电话
private String email; //电子邮箱
private String khyh; //开户银行
private String yhzh; //银行账号
public String getKhname() {
return khname;
}
public void setKhname(String khname) {
this.khname = khname;
}
……//省略部分代码
}
4.4 提交客户信息的JavaBean的编写
在填写完客户基本信息后,就应该向数据库中执行插入操作。这个类中有两个方法setKhinfo()和Regist()。其中setKhinfo(KhinfoBean khinfo)方法是用来设置该类中的属性khinfo,其值为参数传递来的KhinfoBean的对象。然后执行预处理语句,并通过预处理对象pstmt的setString()方法来设置准备要插入数据库的内容,最后通过execute()来执行插入的操作。具体代码如下:
package com.mingri.info;
import com.mingri.dbconn.DBResult;
import java.sql.;
public class KhRegist
{
private KhinfoBean khinfo;
DBResult rst=new DBResult();
public void setKhinfo(KhinfoBean khinfo){
this.khinfo=khinfo;
}
public void regist() throws Exception{
String reg=“insert into tb_customer values(?,?,?,?,?,?,?,?,?,?,?)”;
try{
PreparedStatement pstmt=rst.getPreparedStatement(reg); //创建一个预处理语句,然后设置他们的参数
pstmt.setString(1,khinfo.getKhname());
pstmt.setString(2,khinfo.getKhjc());
pstmt.setString(3,khinfo.getAddress());
pstmt.setString(4,khinfo.getPostcode());
pstmt.setString(5,khinfo.getTel());
pstmt.setString(6,khinfo.getFax());
pstmt.setString(7,khinfo.getLxr());
pstmt.setString(8,khinfo.getLxrtel());
pstmt.setString(9,khinfo.getEmail());
pstmt.setString(10,khinfo.getKhyh());
pstmt.setString(11,khinfo.getYhzh());
//执行更新操作
pstmt.executeUpdate();
}
catch(Exception e){
e.printStackTrace();
throw e;
}
}
}
4.5 查询、分页JavaBean的编写(QuestString.java)
该系统中主要的方法分为两部分:一部分是根据用户提交的不同请求调用不用的方法来获取SQL语句;另一部分是用于分页显示。用于完成分页显示的方法有:
void setQuerySql(String httpfile,String pages,String strCount):通过参数传递来设置Bean中的属性。
void querySql(String countSql):执行SQL语句,获得分页显示时的各个属性。
String pageFooter():用来动态的给出一个表单该表单用来进行分页和统计页面间的跳转。
这部分代码是本系统中查询部分的骨架,所有涉及到查询操作的代码部分全都调用了该Bean 中相应的方法,并完成了分页显示。代码如下:
package com.mingri.info;
import com.mingri.dbconn.DBResult;
import java.sql.;
import java.io.;
public class QuestString
{
private int curPage; //当前页数
private int maxPage; //最大页数
private int maxRowCount; //总记录数(即从数据库中查出的所有记录)
private int pageSize=2; //每页要显示的记录数
private DBResult db; //记录集对象
private String httpFile; //当前地址栏的文件,即具体的JSP文件
private String cif; //选择的查询字段
private String ccif; //选择的查询运算符
private String qvalue; //查询关键字
private String countSql=null; //用来存储select count () ……语句
private String topSql=null; //用来存储 select top 2……语句
private String nowPage=null; //初始化当前页curPage变量,即获取当前页的具体页号
private String str_parameter; //在做翻页时,传递除pages以外的其他参数
private String andor; //查询的与/或条件
private String sdate; //查询起始时间,即从什么日期开始查询
private String edate; //查询结束时间,即到什么日期结束
private String orderby; //排序条件,即按什么排序
private String paixu; //排序方法,即升序或降序
public QuestString(){ //构造方法,用来设置db为一个DBResult()对象
db=new DBResult();
}
public int getCurPage() {
return curPage;
}
public void setCurPage(int curPage) {
this.curPage = curPage;
}
//省略了对Bean中其他属性设置的部分代码
……
/** - 通过参数传递来设置Bean中的属性
/
public void setQuerySql(String httpfile,String pages,String strCount){
this.nowPage=pages; //将表单提交过来的参数pages(第几页)的值传递给变量nowPage保存
this.httpFile=httpfile; //用来动态设置处理表单请求的JSP文件
this.countSql=strCount; //用来设置执行select count()……的SQL语句
try{
querySql(countSql); //调用querySql方法,并将参数countSql传递到该方法中
}catch(Exception e){
e.printStackTrace();
}
}
/** - 执行SQL语句,获得分页显示时的各个属性
/
public void querySql(String countSql) throws SQLException{
//在setQuerySql方法中已经设置了nowPage的值,其值就是pages
if(this.nowPagenull){ //如果nowPage的值为空,也就是传递pages的值为空
this.curPage=1; //那么就将当前页的值设为1;
}
else{
this.curPage=Integer.parseInt(this.nowPage);
if(this.curPage<1){ //如果当前页小于1,那么就将当前页的值设为1
this.curPage = 1;
}
}
ResultSet rsCount=db.getResult(countSql); //执行SQL语句获得记录总数
if(rsCount.next()){
this.maxRowCount=rsCount.getInt(1); //获取记录总数,即所要查询记录的总行数
}
//获取总页数,即如果当总记录数除以每页显示的记录的余数为0时,总页数就等于两数整除的结果
//如果余数不等于0,那么总页数就等于两数整除的结果加1
this.maxPage=(this.maxRowCount%this.pageSize0)?(this.maxRowCount/this.pageSize):(this.maxRowCount/this.pageSize+1);
if(this.curPage>this.maxPage){ //如果当前页大于总页数,则当前页等于总页数
this.curPage=this.maxPage; //那么当前页就是最大页
}
rsCount.close(); //关闭总记录数的结果集
}
/* - 一个字符串,用来动态的给出一个表单
- 该表单用来进行分页和统计页面间的跳转
*/
public String pageFooter()
{
//创建一个表单
String str = “”;
int prev = this.curPage- 1; //向前翻页,即当前页减1
int next = this.curPage +1; //向后翻页,即当前页加1
str = str + "<font style='font-size: 10pt'>总计<font color='red'>" + this.getMaxRowCount() +
"</font>条记录," + "【共<font color='red'>" + this.getMaxPage()+ "</font>页】";
str = str + "【 <font color='red'>" + this.pageSize + "</font>条/页】 当前第<font color='red'>" +
this.getCurPage() + "</font>页 ";
if(this.curPage > 1)
str = str + " <A href=" + this.httpFile + "?pages=1" + str_parameter + ">首页</A> ";
else
str = str + " 首页 ";
if(this.curPage > 1)
str = str + " <A href=" + this.httpFile + "?pages=" + prev + str_parameter + ">上一页</A> ";
else
str = str + " 上一页 ";
if(this.curPage < this.maxPage)
str = str + " <A href=" + this.httpFile + "?pages=" + next + str_parameter + ">下一页</A> ";
else
str = str + " 下一页 ";
if(this.maxPage > 1 && this.curPage!= this.maxPage)
str = str + " <A href=" + this.httpFile + "?pages=" + this.maxPage + str_parameter + ">尾页</A>";
else
str = str + " 尾页</font>";
//在页面跳转间设置隐藏表单,来保存不同的请求
str = str + "转到<input type ='text' name='pages' size='2'>页"+
"<input type='hidden' name='ccif' value='"+this.ccif+
"'><input type ='hidden' name='cif' value='"+this.cif+
"'><input type ='hidden' name='qvalue' value='"+this.qvalue+
"'><input type ='hidden' name='andor' value='"+this.andor+
"'><input type ='hidden' name='sdate' value='"+this.sdate+
"'><input type ='hidden' name='edate' value='"+this.edate+
"'><input type ='hidden' name='orderby' value='"+this.orderby+
"'><input type ='hidden' name='paixu' value='"+this.paixu+
"'><input type='submit' name='sumbmit' value='go'></form>";
return str;
}
/**
- 根据不同条件来获取不同的查询前N条的SQL语句
/
public String getString(String table){
if(ccif.equals(“=”))
{
String strSql=”select top “+this.pageSizethis.curPage+” * from “+table+
” where”+” “+cif+”=”+”’”+qvalue+”’”;
return strSql;
}
else if(ccif.equals(“LIKE”))
{
String strSql=“select top “+this.pageSizethis.curPage+” * from “+table+
” where”+” “+cif+” “+“like”+” “+”’%”+qvalue+”%’”;
return strSql;
}
else if(ccif.equals(“ALL”))
{
String strSql=”select top “+this.pageSizethis.curPage+” * from “+table;
return strSql;
}
else if(ccif.equals(”<”))
{
String strSql=“select top “+this.pageSize*this.curPage+” * from “+table+
” where “+cif+” < ‘”+qvalue+”’”;
return strSql;
}
return null;
}
/** - 根据不同条件来获得不同的计算记录总数的SQL语句
/
public String getCount(String table){
if(ccif.equals(“=”))
{
String strSql=”select count() from “+table+” where”+” “+cif+”=”+”’”+qvalue+”’”;
return strSql;
}
else if(ccif.equals(“LIKE”))
{
String strSql=“select count() from “+table+” where”+” “+cif+” “+“like”+” “+”’%”+qvalue+”%’”;
return strSql;
}
else if(ccif.equals(“ALL”))
{
String strSql=”select count() from “+table;
return strSql;
}
else if(ccif.equals(”<”))
{
String strSql=“select count(*) from “+table+” where “+cif+” < ‘”+qvalue+”’”;
return strSql;
}
return null;
}
/** - 根据不同条件和不同的起始日期和结束日期来获得不同的计算记录总数的SQL语句
/
public String getDateCount(String table){
if(ccif.equals(“=”)) //在sdate到edate时间段中进行精确查询
{
String strSql=”select count() from “+table+” where “+cif+” = ‘”+qvalue+”’”+
andor+” xsdate between ‘”+sdate+”’ and ‘”+edate+”’”;
return strSql;
}
else if(ccif.equals(“LIKE”)) //在sdate到edate时间段中进行模糊查询
{
String strSql=”select count() from “+table+” where “+cif+” like ‘%”+qvalue+”%’”+
andor+” xsdate between ‘”+sdate+”’ and ‘”+edate+”’”;
return strSql;
}
else if(ccif.equals(“ALL”)) //取出表中所有记录
{
String strSql=”select count() from “+table;
return strSql;
}
return null;
}
/** - 根据不同条件和不同的起始日期和结束日期来获得不同的查询,前N条的SQL语句
/
public String getDateString(String table){
if(ccif.equals(“=”))
{
String strSql=”select top “+this.pageSizethis.curPage+” * from “+table+
” where “+cif+” = ‘”+qvalue+”’”+andor+
” xsdate between ‘”+sdate+”’ and ‘”+edate+”’”;
return strSql;
}
else if(ccif.equals(“LIKE”))
{
String strSql=”select top “+this.pageSizethis.curPage+” * from “+table+
” where “+cif+” like ‘%”+qvalue+”%’”+andor+
” xsdate between ‘”+sdate+”’ and ‘”+edate+”’”;
return strSql;
}
else if(ccif.equals(“ALL”))
{
String strSql=”select top “+this.pageSizethis.curPage+” * from “+table;
return strSql;
}
return null;
}
/** - 子查询中得到从起始日期到结束日期这段时间所有不重复的spid(商品id),并返回不重复的spid的总数
/
public String getOrderCount(String table){
String strSql=”select count() from (select spid from “+table+
” where xsdate between ‘”+sdate+”’ and ‘”+edate+
“’ group by spid) as aa”;
return strSql;
}
/** - 联合查询查询出某一表中从起始到结束日期间所有不重复的spid(商品id)
- 并且将所有相同spid下的sl(数量)和je(金额)求和,即计算出某一商品在
- 某一时间段内的总销售数量和销售总额
- 最后通过联合查询在tb_brand表(商品信息表)中将该spid所对应商品的其他一些信息查询出来
/
public String getOrderString(String table){
String strSql=”select top “+ this.pageSizethis.curPage+
“* from tb_brand a inner join (select spid,sum(sl) as sl,sum(je) as je”+
” from “+table+” where xsdate between ‘”+sdate+”’ and ‘”+edate+”’ group by spid ) as b”+
” on a.id=b.spid order by “+orderby+” “+paixu;
return strSql;
}
}
4.6 显示系统时间的JavaBean的编写
在本系统中,商品的入库编号、销售票号等都是由“2位英文字母+系统时间+5位数字”自动生成的,所以我们将系统时间封装到Bean中,这样可以很好的将这部分代码重用。具体代码如下:
package com.mingri.showtime;
import java.util.*;
public class ShowTime
{
private Date date=null;
private int yy; //保存由Date类中getYear()方法返回的整型数值
private int mm; //保存由Date类中getMonth()方法返回的整型数值
private int dd; //保存由Date类中getDate()方法返回的整型数值
private String sy;
private String sm;
private String sd;
public ShowTime(){
date=new Date();
yy=date.getYear()+1900; //只有加上1900才是系统当前的年份
mm=date.getMonth()+1; //只有加上1才识系统当前的月份
dd=date.getDate();
sy=String.valueOf(yy); //将整型yy转化为字符串类型
sm=String.valueOf(mm); //将整型mm转化为字符串类型
sd=String.valueOf(dd); //将整型dd转化为字符串类型
//如果月份是1位数在前面加上”0”,即如果是1月份那么显示的就是”01″
if(sm.length()==1){
sm=“0”+sm;}
if(sd.length()==1){
sd=“0”+sd; }
}
public String getDateString(){
return sy+sm+sd; }
public String getDate(){
return sy+”-“+sm+”-“+sd;
}
}
。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。.
相关内容及全部资源下载地址:请点击》》》
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/138494.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...