资源描述
网上图书销售系统
1课程设计的目的
传统的图书销售管理方法,都是通过人工统计和计算的管理方式进行的。这样的管理方法不但费时费力,也容易产生计算上的错误和疏漏;计算机技术的全面普及,打破了书店管理的传统管理方法,提高了管理效率的同时,克服了传统管理方法中易产生的问题,使管理员能够有序的、全面的对图书销售和库存进行管理。
网上图书销售系统可以完成书店的日常管理,如图书录入、图书销售、销售统计、查询库存等功能,迅速准确地对已售图书和剩余库存进行统计和汇总工作,大大提高了书店的管理效率和准确性。
2功能描述
本系统是根据书店的实际需求而开发的,要求稳定、可靠的实现图书销售的自动化管理,通过本系统可以达到以下目标:
(1)图书录入,包括图书的基本信息,如分类、进价、售价、作者等。
(2)图书销售,包括图书的售价、折扣、销售日期,并实现对库存量的修改。
(3)销售统计,包括按图书类型、书名、作者、出版社等进行统计。
(4)查询库存,对指定的某本图书剩余库存量进行查询。
(5)售完图书查询,对已售完图书进行查询。
3方案论证
3.1概要设计
模块功能分配如下:
(1)用户登陆功能:管理员登陆模块(M1)。
(2)图书录入功能:图书录入模块(M2)。
(3)图书销售功能:图书销售模块(M3)。
(4)销售统计功能:销售统计模块(M4)。
(5)查询图书库存功能:查询库存模块(M5)。
(6)售完图书查询功能:售完图书查询模块(M6)
图1图书销售管理系统功能模块图
3.2详细设计
3.2.1程序流程图
(1)在登录界面输入用户名和密码,登录成功后进入主界面。
图2登录模块流程图
(2)添加图书信息, “保存”按钮对应的方法为RAddBookDlg::OnSave()。
开始
结束
输入图书基本信息
判断输入是否正确且完整
添加该信息到关联表并写入数据库
是
否
图3 RAddBookDlg::OnSave()方法的流程图
(3)实现图书销售功能,“销售”按钮对应的方法为RSaleBookDlg::OnOK()。
开始
结束
输入书名或条形码
判断输入是否正确且FindBook()函数返回值为1
添加该信息到关联表并写入数据库
是
否
图4 RSaleBookDlg::OnOK()方法的流程图
3.3.2 数据描述
(1)数据库概要说明
数据库中包括管理员信息表、图书基本信息表、图书类型表、图书销售记录表等4个数据表。图5所示的即为本系统中数据库中的数据表结构图,该数据表结构图包含系统所有数据表。可以清晰地反应数据库信息。
图5 数据表结构图
(2)主要数据表的结构
表1 Pwd(管理员信息表)
字段名
数据类型
字段大小
描述
ID
int
4
管理员帐号
Password
nvarchar
50r
密码
表2 BookInfo(图书基本信息表)
字段名
数据类型
字段大小
描述
BookID
int
4
图书编号
BookName
nvarchar
50
图书名称
CategoryID
int
4
图书类型编号
Author
nvarchar
50
作者
Publisher
nvarchar
50
出版社
PublishDate
smalldatetime
4
出版日期
Purchase
float
8
进价
Price
float
8
售价
Stock
int
4
库存本数
Discount
int
4
折扣
BarCode
nvarchar
50
条形码
表3 BookCategory(图书类型表)
字段名
数据类型
长度
描述
CategoryID
int
4
图书类型编号
CategoryName
nvarchar
8
图书类型名称
表4 BookSale(图书销售记录表)
字段名
数据类型
长度
描述
ID
int
4
销售记录编号
BookID
int
4
图书编号
SalePrice
float
8
实际售价
SaleDate
smalldatetime
4
销售日期
4程序说明
(1)打开程序,选择“使用书店身份登录”,输入密码“111”,进入主对话框,如图所示:
图6主对话框
(2)在功能菜单下选择图书录入功能,添加一本新的图书信息,如图所示:
图7添加图书信息
(3)点击“返回”按钮后,系统会自动显示现有图书信息,如图所示:
图8 系统自动显示现有图书信息
(4)在功能菜单下进入图书销售对话框,卖出一本《C++教程》,如图5.4。点击返回按钮后,系统会显示当前所有图书剩余库存信息,如图所示:
图9 图书销售
(5)点击结束销售后,系统会自动显示当前所有图书的库存信息,《C++教程》的库存量已减少一本,如图所示:
图10完成销售后的库存信息
(6)在功能菜单下进入销售统计对话框,查询全部销售清单,并给出已售出图书总本数,如图所示:
图11查询所有图书销售清单
(7)在功能菜单下进入查询库存对话框,查询《魅力何来》这本书的库存信息,如图所示:
图12查询图书库存信息
(8)再售出《魅力何来》2本后,在功能菜单下进入售完图书列表功能,查询已售完的图书的信息如图所示:
图13 查询售完图书列表
(9)在出售图书时,若无对应图书信息或图书库存为零,将出售失败,并给出提示信息,如图所示:
图14图书销售失败
5效果及存在问题
程序还是存在一些不足之处。比如程序没有直接提供修改密码的功能,系统管理员密码保存在数据库的Pwd表中,若要修改密码,可以到数据库中直接修改。由于时间仓促,没有优化设计,还存在一些垃圾和重复代码,也没有进行全面的测试,需要进一步的改进。本系统规模小,实现的功能简单,但稍加改动和完善,完全可以应用到普通书店的销售管理中。
6结果分析及心得体会
本次课程设计完成的是图书销售管理系统,我基本完成了所要求的几个功能,包括图书录入、图书销售、销售统计、查询库存等功能。通过本次课程设计,自己对Visual C++6.0的基本知识有了一个很好的巩固和学习,特别是Visual C++6.0中的MFC,它的功能是非常强大的,使用它制作图形界面很方便。而且自己还进一步熟悉了SQL数据库的知识,包括建表、查询、修改等操作,以及学习了Visual C++6.0怎样连接数据库。
开始做这个课程设计的时候,感觉到自己只有一些理论知识,无法动手来操作。通过认真的学习来解决这一问题,这也提高了实际操作的能力。在编写程序的过程中,也发现自己还是存在着很多的缺点,对Visual C++6.0和MFC的知识和使用不是很熟悉,操作数据库也不熟练,还需要自己多加练习来达到熟练的目的,以后还要努力学习锻炼自己。首先要感谢的是本次课程设计的指导老师对我的耐心指导,我才顺利地完成了这次课程设计。可以说这很大程度上归功于老师的帮助,这也给了我很大的鼓励,使我有信心完成该题目。
另外还要感谢的就是我的同学们,在这次课程设计中他们给了我很多细心的帮助。
参考文献
[1] 揣锦华.面向对象程序设计与VC++实践. [M].西安电子科技大学出版社,2005
[2] 张建宏,汤练兵,马德骏.计算机程序设计基础. [M].科学出版社,2006
[3] 陈清华.Visual C++课程设计案例精选与编程指导. [M].东南大学出版社,2004
[4] 陈维兴、林小茶,《C++面向对象程序设计教程》.[M].清华大学出版社
[5] 谭浩强,《C语言程序设计》,清华大学出版社. [M].2000年.
[6] 陈维兴、陈昕、林小茶,《C++面向对象程序设计习题解答与实验指导》,[M].
清华大学出版社,2005年
[7] 刘振安、刘燕君、孙忱,《C++语言课程设计》,[M].机械工业出版社,2007年
[8] 严华峰. Visual C++课程设计案例精编. [M].北京:中国水利水电出版社,2002
[9] 张宏军,党留群,赵天巨.Visual C++ 6.0编程案例精解.[M].北京:电子工业出版社,2005
[10] 郑阿奇,丁有和.Visual C++教程.[M].北京:机械工业出版社,2006
附录:
BOOL RAddBookDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
GetBookGategory();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void RAddBookDlg::OnSave()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
if(!IsValidInput())
return ;
if(IDYES != AfxMessageBox("确定要保存吗?",MB_YESNO)) //放弃保存
return ;
if(SaveData())
{
AfxMessageBox("保存成功!");
//保存后重置数据
m_bHasNewBook = true;
OnReset();
GetDlgItem(IDC_BK_CATEGORY)->SetFocus();
}
else
AfxMessageBox("保存失败!");
bool RAddBookDlg::IsValidInput()
{
CString str = "0123456789";
if(m_strBookCategory.IsEmpty() || m_strBookCategory.FindOneOf(str) != -1)
{
AfxMessageBox("输入有误!图书类型不能为空或包含数字。");
GetDlgItem(IDC_BK_CATEGORY)->SetFocus();
return false;
}
if(m_strBookName.IsEmpty())
{
AfxMessageBox("输入有误!书名不能为空。");
GetDlgItem(IDC_BK_NAME)->SetFocus();
return false;
}
if(m_strAuthor.IsEmpty() || m_strAuthor.FindOneOf(str) != -1)
{
AfxMessageBox("输入有误!作者名称不能为空或包含数字。");
GetDlgItem(IDC_BK_AUTHOR)->SetFocus();
return false;
}
if(m_strPublisher.IsEmpty()|| m_strPublisher.FindOneOf(str) != -1)
{
AfxMessageBox("输入有误!出版社名称不能为空或包含数字。");
GetDlgItem(IDC_BK_PUBLISHER)->SetFocus();
return false;
}
if(m_dPurchase <= 0)
{
AfxMessageBox("图书进价应为正值!");
GetDlgItem(IDC_BK_PURCHASE)->SetFocus();
return false;
}
if(m_dPrice <= 0 )
{
AfxMessageBox("图书售价应为正值!");
GetDlgItem(IDC_BK_PRICE)->SetFocus();
return false;
}
if( m_lDiscount < 0 || m_lDiscount > 100)
{
AfxMessageBox("图书折扣应为0-100之间正值!");
GetDlgItem(IDC_BK_DISCOUNT)->SetFocus();
return false;
}
if(m_lStock <1)
{
AfxMessageBox("图书数量应为正值!");
GetDlgItem(IDC_BK_STOCK)->SetFocus();
return false;
}
if(m_strBarcode.IsEmpty() || m_strBarcode.GetLength() > 15)
{
AfxMessageBox("条形码应为15位整数!");
GetDlgItem(IDC_BK_BARCODE)->SetFocus();
return false;
}
// AfxMessageBox(m_strBookName + "\r\n" +
// m_strBookCategory + "\r\n" +
// m_strAuthor + "\r\n" +
// m_strPublisher + "\r\n" +
// m_strBarcode );
return true;
}
void RSaleBookDlg::OnOK()
{
// TODO: Add extra validation here
if(!m_bReadySale)
m_bReadySale = FindBook();
else
{
UpdateData(TRUE);
CString strMsg;
strMsg.Format("是否出售?\n 书名:%s\n 价格:%.2f”,m_strBookName
,m_dSalePrice);
if(IDYES == AfxMessageBox(strMsg,MB_YESNO))
{
ModifyStock(); //修改图书库存
SaveSaleRecord(); //记录销售记录
}
Init();
UpdateData(FALSE);
GetDlgItem(IDC_SBK_NAME)->SetFocus();
m_editDiscount.EnableWindow(FALSE);
}
//CDialog::OnOK();
}
bool RSaleBookDlg::FindBook()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE);
CString strSql ;
_variant_t var;
double dPurchase;
if(!m_strBookName.IsEmpty())
strSql.Format("SELECT * FROM BookInfo WHERE BookName = \"%s\" and Stock >0", m_strBookName);
else if(!m_strBarCode.IsEmpty())
strSql.Format("SELECT * FROM BookInfo WHERE BarCode = \"%s\" and Stock >0", m_strBarCode);
else
{
AfxMessageBox("请输入书名或条码!");
GetDlgItem(IDC_SBK_NAME)->SetFocus();
return false;
}
CRBookSaleApp* pApp = (CRBookSaleApp*)AfxGetApp();
try
{
pApp->m_pRecordset->Open(strSql.AllocSysString(),
pApp->m_pConnection.GetInterfacePtr() adLockOptimistic,
adCmdText);
if(pApp->m_pRecordset->adoEOF)
{
AfxMessageBox("查无此书!请输入书名或条码无误。");
pApp->m_pRecordset->Close();
return false;
}
var = pApp->m_pRecordset->GetCollect("BookID");
if(var.vt != NULL)
m_lBookID = var.lVal;
var = pApp->m_pRecordset->GetCollect("Discount");
if(var.vt != NULL)
m_lDiscount = var.lVal;
var = pApp->m_pRecordset->GetCollect("Price");
if(var.vt != NULL)
m_dPrice = var.dblVal;
var = pApp->m_pRecordset->GetCollect("Purchase");
if(var.vt != NULL)
dPurchase = var.dblVal;
var = pApp->m_pRecordset->GetCollect("CategoryID");
if(var.vt != NULL)
m_lCategory = var.lVal;
pApp->m_pRecordset->Close();
}
catch(_com_error * e)
{
AfxMessageBox(e->ErrorMessage());
}
m_editDiscount.EnableWindow(m_dPrice >= dPurchase);
m_lDiscount = (m_dPrice >= dPurchase) ? m_lDiscount :100; //售价小于进价时,不允许打折
m_dSalePrice = m_dPrice * (double(m_lDiscount)/100); //计算折后价
UpdateData(FALSE);
return true;
}
void CRBookSaleView::OnSaleReport()
{
// TODO: Add your command handler code here
RReportDlg dlg;
dlg.m_iReportType = m_iReportType ;
if(IDOK == dlg.DoModal())
{
m_iReportType = dlg.m_iReportType;
//设置销售报表标题
//前2个标题类型为用户模式和书店管理模式,故此处加2
int iTitleType = 0;
switch(m_iReportType)
{
case 0://图书类型统计
iTitleType = CATEGORY_REPORT_TITLE;
break; case 1://图书名称统计
iTitleType = BOOKNAME_REPORT_TITLE;
break;
case 2://图书作者统计
iTitleType = AUTHOR_REPORT_TITLE;
break;
case 3://出版社统计
iTitleType = PUBLISHER_REPORT_TITLE;
break;
case 4://全部销售记录统计
iTitleType = SALE_REPORT_TITLE;
break;
default:
break;
}
SetTitle(iTitleType);
ShowReport();
}
}
展开阅读全文