基于Python+Mysql实现(WinForm)书店销售管理管理子系统【100010028】

news2024/11/20 6:23:00

书店销售管理管理子系统

一、设 计 总 说 明

现在社会随着计算机技术迅速发展与技术的逐渐成熟,信息技术已经使人们的生活发生深刻的变化。生活中的各种服务系统也使人们在生活中的联系日常销售活动方式发生了很大的变化,让效率较低的手工操作成为过去,而换成信息化自动化的计算机操作。本系统是针对某一小型书店而设计的书店管理信息系统,本 系统的后台数据库选择 SQL SERVER 2014 数据库,前台开发工具选择 PyCharm, QT 。

系统设计整个系统以满足用户需求为主旨,操作简便,界面友好、灵活、高效。安全性从多个设计层面得到了保障。本系统划分了三种不同权限的身份:管理员,销售员,顾客,对进行书店的销售管理,涵盖书店销售的基本运作规则。本文设计的书店销售管理系统可以帮助书店提高效率,进行调度管理,同时本系统为餐饮企业提供了一种新的经济理念,完善企业运作模式,从而从根本上推动国家第三产业的发展。

本文是严格按照数据库系统开发的原理,对书店销售管理系统进行系统需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施、系统运行维护等作了详细的阐述.

关键词:书店;管理;系统;python;mssql; QT

二、绪论

2.1 开发背景及目的意义

世纪是一个信息高速发展的时代,随着计算机技术的发展 , 人们的日常工作及生活已经离不开它了。数字化、网络化、电子化、自动化将成为未来社会人们的生活和工作的主节奏,人类也必将越来越依赖于数字技术。计算机的发展历程以及目前的应用状况和发展趋势 , 可以充分地相信电子科技将极大的改变我们的生活和工作方式,它带来的信息 技术革新所掀起的社会各领域的管理革命已波及到图书销售管理,信息化的管理系统将给图书销售带来更大的社会效益与经济效益。

本次课程设计不仅考察了我综合运用这一学期所学的相关知识的能力,也锻炼了我的实际动手能力,对于我以后工作能力的培养有着重要的意义;同时通过该题目的开发实施,可以掌握系统的设计与实现全过程,巩固我的专业理论知识与实际应用的结合,提高分析问题,解决问题的能力。

2.2 国内外现状

2.2.1 国内现状

现在有些书店的图书销售仍采用传统的手工操作,这样的操作方式具有诸多不便之处,并且原始的手工人力操作已经过时,这样的流程已不能满足日趋激烈的图书销售市场的需求。随着书店消费产品数量和种类的多样化,必须通过建立有效的销售管理信息系统,对所销售的书店的大量相关信息进行数据的录入和合理分类,方便工作人员的及时调用以及掌握不断更新的信息,也为消费者提供便利的消费氛围。

2.2.2 国外现状

很多书店均已采用一体化信息销售手段,对所销售的书店的相关信息进行数据的录入和合理分类,方便书店的销售管理

2.3 开发工具、语言及环境

2.3.1 pyCharm 简介

PyCharm 是一种 Python IDE,带有一整套可以帮助用户在使用 Python 语言开发时提高其效率的工具,比如调试、语法高亮、Project 管理、代码跳转、智能提示、自动完成、单元测试、版本控制等 。是 python 开发的首选。

2.3.2 ms SQL 简介

ms SQL 是指微软的 SQLServer 数据库服务器,它是一个数据库平台,提供数据库的从服务器到终端的完整的解决方案,其中数据库服务器部分,是一个数据库管理系统,用于建立、使用和维护数据库。SQL Server 一开始并不是微软自己研发的产品,而是当时为了要和 IBM 竞争时,与 Sybase 合作所产生的,其最早的发展者是 Sybase,同时微软也和 Sybase 合作过 SQL Server 4.2 版本的研发,微软亦将 SQL Server 4.2 移植到 Windows NT(当时为 3.1 版),在与 Sybase 终止合作关系后,自力开发出 SQL Server 6.0 版,往后的 SQL Server 即均由微软自行研发。

2.3.3 开发语言 python

本系统开发所用的开发语言是 python, 因为 python 有以下的特点:

面向对象:拥有大量的通用 API 支持,使得利用 python 开发各种应用程序,可以说是易如反掌.此外,在程序除错、修改、升级和增加新功能等方面,因其面向对象的特性,使得这些维护也变得非常容易.

异常处理机制:为了使 python 程式更稳定、更安全,python 引入了异常处理机制.能够在程序中产生异常情况的地方,执行相对应的处理,不至于因突发或意外的错误造成执行中断或是死机.通过这种异常处理,不仅能够清晰地掌握整个程序执行的流程,也使得程序的设计更为严谨.

多线程:可以免去后端通信的建立,通过创建新的线程实现对数据库数据更新的监视。

三、系统分析

3.1 系统需求分析

本次课程设计的题目是:书店销售管理子系统,其具体内容如下:

书店希望借助一个销售管理子系统实现对现有业务的管理。该书店目前采用会员制,顾客购买书籍累积达到一定金额后,凭购书发票可填表申请成为正式会员,会员在购书时享有一定折扣,折扣额度可变化。该书店不定期地会推出促销活动,要求图书的价格是可变更的。系统主要功能如下:

  • 图书入库管理:维护入库图书信息(如图书编号、书名、作者、价格、图书分类、出版社等),自动计算库存。

  • 图书查询统计:按图书分类,出版社、书名、作者等条件查询图书的详细信息。

  • 销售管理:销售过的图书都记录在销售列表中,方便统计收入。图书销售后,实时记录图书库存,按每天统计销售额、按每个月或季度统计销售额并生成报表,并能根据销售数量统计生成畅销书名单。

  • 书店会员管理:提供会员信息的维护功能,可设置会员等级,不同级别的会员享受不同的折扣,可以变更折扣额度。

  • 系统管理:包括参数设置、权限设置、更改密码等。用户包括系统管理员和销售人员。系统管理员维护整个系统的数据

3.2 系统目标

本系统要实现书店销售管理,实现书店销售的系统化,自动化和高效率。能够实现,图书管理,图书销售,销售统计,管理员对销售人员的管理,等功能,以及各角色的交互等。

3.3 系统功能

书店销售管理子系统的开发主要包括应用程序系统和后台数据库,应用程序系统要求界面友好,功能完备,易使用等特点.而后台数据库的数据要具有一致性、完整性、安全性.

3.3.1 前台应用程序

前台应用程序重在实现用户和系统的交互,在功能强大的同时,也要简洁和操作方便。目的是让调度环节更高效,在保证操作正确性的情况下,免去不必要的操作。

3.3.2 后台数据库

后台数据库在考虑前台访问操作简便的同时,提供强大的管理模式。数据库结构合理,完整,权限设计符合实际,安全性良好。

3.4 可行性分析

3.4.1 经济可行性分析

系统的经济可行性分析是指对组织的经济状况和投资能力进行分析,对系统的建设运营和维护费用进行估算,对系统建成后可能取得的社会及经济效益进行估计.

由于本系统作为平时的课程设计,所以在资金上几乎没有任何需求。

所以说在经济方面本系统的开发是完全可行的.

3.4.2 技术可行性分析

随着互联网和信息技术的发展,信息技术从根本上改变了人类社会的生产方式和生活方式,计算机的应用随处可见.书店销售管理子系统主要是对书店信息进行管理,实现增、删、改、查等功能。既然利用计算机管理是大势所趋,而开发一个书店销售管理又能够获得事半功倍的效果.并且,随着数据库管理系统的广泛应用以及可视化编程工具的出现,本系统便使用了 pyCharm 集成开发环境以及 PyQt5, QT 进行前台的开发,由于可视化模块比较强大,所以在系统的设计过程中不会有太大问题,同时本系统使用 ms SQL 对后台的数据进行操作,使得数据完整性得以保证,同时数据操作简单化.

以上这些都为开发一个餐饮管理系统提供了技术上的支持,所以说开发一个书店销售管理子系统在技术方面来讲是完全可行的.

3.4.3 操作可行性分析

本系统直观易懂,本身不是很复杂,使用非常方便,测试完毕后即可用于实际的管理.管理员经过简单的培训就可以熟练的使用,当进行数据修改时都有适当的提示,和消息确认,增加了人工错误的容错性。

综上所述,开发一个书店销售管理系统,在一定程度优化了书店的销售管理,因此开发这个书店销售管理系统是完全可行的.

3.5 数据流图

以下为本系统的数据流图

图 2-1 书店销售管理子系统数据流图

3.6 数据字典

数据字典是关于数据的信息的集合,也就是对数据流图中包含的所有元素的定义的集合,一般说来,数据字典应该由下列四类元素构成:数据元素,数据流,数据存储和数据处理.

3.6.1 数据元素

数据元素是不可再分的数据单位,一般而言,包括如下内容:数据项描述 ={数据项名,数据项含义说明,别名,数据类型,长度,取值范围,取值含义,与其他数据项的逻辑关系,数据项之间的联系}.其中,后两项定义了数据的完整性约束条件,用于数据校验.

本系统的数据元素具体见下文的数据库表.

3.6.2 数据存储

数据存储是数据结构停留或保存的地方.也是数据流的来源和去向之一,可以是手工文档或手工凭单,也可以是计算及文档.一般而言,应包括如下内容:{数据存储名,说明,编号,输入的数据流,输出的数据流,组成(数据结构),数据量,存取频度,存取方式}.

在这里插入图片描述

图 2-2 图书信息数据存储图

在这里插入图片描述

图 2-3 顾客信息数据存储图

在这里插入图片描述

图 2-4 销售人员信息数据存储图

在这里插入图片描述

图 2-5 管理员信息数据存储图

在这里插入图片描述

图 2-6 销售信息数据存储图
在这里插入图片描述

图 2-7 服务信息数据存储图

在这里插入图片描述

图 2-8 入库信息数据存储图

在这里插入图片描述

图 2-9 出库信息数据存储图

3.6.3 数据流

数据流是数据结构在系统内传输的路径.对数据流的描述通常包括如下内容:{数据流名,说明,编号,数据流来源,数据流去向,组成(数据结构)}.

3.6.4 数据处理

处理过程的具体处理逻辑通常在详细设计过程中用判定表或判定树来描述.在数据字典中,只无原则描述处理过程的说明性信息,通常包括以下内容:{处理过程名,说明,输入数据流,输出数据流,处理}.

在这里插入图片描述

图 2-10 图书管理数据处理图

在这里插入图片描述

图 2-11 销售人员管理数据处理图

在这里插入图片描述

图 2-12 图书销售、退货模块数据处理图
在这里插入图片描述

图 2-13 入库、出库模块数据处理图

在这里插入图片描述

图 2-14 顾客管理数据处理图

在这里插入图片描述

图 2-15 厨师分配数据处理图

在这里插入图片描述

图 2-16 厨师分配数据处理图

四、开发技术介绍

4.1 pymssql 介绍

python 在使用嵌入式 SQL 语言时,必须与数据库进行连接,如果不进行连接的话,嵌入在 python 中的 SQL 语句无法执行的,而 python 又不能自动与数据库相连,它需要在 pymssql 的帮助下与数据库建立连接.另外使用 pymssql 可以不用深入的了解所访问的数据库系统,而只是需要所访问的数据库名字,数据表名和字段即可对数据库进行访问 pymssql 是用于执行 SQL 的 python API。

4.1.1 配置环境

Pip install pymssql

4.1.2 连接 MSSQL

代码如下:

import pymssql
conn = pymssql.connect(
           host='127.0.0.1',
           user='123',
           password='123',
           database='s1',
       )
       cursor = conn.cursor()
                cursor.execute(SQL)
                cursor.close()
                conn.commit()
                conn.close()

4.2 PyQt5 介绍

PyQt5 是对 Qt 所有类的 Python 封装,即可以利用 Qt 的强大功能,也可以利用 Python 丰富的生态,同时能够结合 Python 简洁的语法进行操作,其结果就是使用 PyQt5 可以高效简单地开发出自己想要的程序

4.2.1 配置环境

Pip install PyQt5

五、系统设计

5.1 系统目标

本书店销售管理子系统基于 B/S 结构,可以做到信息的规范管理和快速查询,实现书店现代化销售、管理.本系统通过进入身份不同,实现不同的功能

5.2 系统功能划分

在这里插入图片描述

图 5-1 整体功能图

5.3 模块简介及功能

5.3.1 图书管理模块

管理员使用,能够实现图书的增、删、改、查,对图书进行批量操作,

图 4-2 图书管理

5.3.2 顾客管理模块

销售人员使用,添加临时顾客信息,会员信息添加、修改,查看

图 4-2 顾客管理

5.3.3 销售模块

对销售、退货的信息进行记录

5.3.4 图书查询模块

在此模块中,定义了不同的图书查询模块.

在这里插入图片描述

图 4-2 图书查询 图 4-2 销售记录查看

5.3.5 人员信息管理

管理员对销售人员进行管理(增、删、改、查),管理员修改密码,销售人员修改自己的密码

5.3.6 销售统计模块

对销售记录进行统计.

5.4 业务流程图

图 4-9 系统业务流程图

六、数据库设计

6.1 数据库概要设计

6.1.1 系统 E-R 图

系统 E-R 图可以将各个实体之间的关系显示出来,将各个实体间的属性依赖表示明白.

6.2 数据库逻辑设计

数据库的逻辑设计决定了数据库与其应用的整体性能和调优位置.根据上面的 E-R 图,进一步规范设计,得到本系统的关系模式,如下.

  • 图书(图书编号,书名,作者,价格,种类,出版社,库存量)
  • 顾客(顾客编号,姓名,性别,电话号码,出生日期,积分)
  • 售货员(售货员编号,姓名,性别,密码)
  • 管理员(管理员编号,姓名,性别,密码)
  • 售货记录(日期,单号,书号,会员号,售货员号,价格,数量,时间)
  • 退货记录(日期,单号,书号,会员号,售货员号,价格,数量,时间)
  • 入库记录(管理员号,书号,时间日期,数量)
  • 出库记录(管理员号,书号,时间日期,数量)

6.3 数据库物理设计

综合以上分析,要实现上面的所有功能模块,共需要设计八个表,它们分别是:图书信息表,顾客信息表,售货员信息表,管理员信息表,售货记录表,退货记录表,入库信息表,出库记录表

表 5-1 图书信息表(Book)

字段名描述数据类型数据长度NULLPrimarykey
Bno图书编号char10NY
Bname书名varchar20NN
Bauthor作者varchar20NN
Bprice价格moneyNN
Btype种类varchar10YN
Bpublish出版社varchar20YN
Bnum库存量intYN

表 5-2 顾客信息表(Menber)

字段名描述数据类型数据长度NULPrimarykey
Mno会员编号char15NY
Mname姓名varchar20YN
Msex性别char2YN
Mtel电话号码varchar11YN
Mbir出生日期DateYN
Mintegration积分IntYN

表 5-3 销售员表(SalesMan)

字段名描述数据类型数据长度NULLPrimarykey
SMno售货员编号char10NY
SMname姓名varchar20NN
SMsex性别char2YN
SMpassword密码varchar13YN

表 5-4 管理员表(Admonistrator)

字段名描述数据类型数据长度NULLPrimarykey
Ano管理员编号char10NY
Aname姓名varchar20NN
Asex性别char2YN
Apassword密码varchar13YN

表 5-5 销售表(SalesRecords)

字段名描述数据类型数据长度NULLPrimarykey
SRdate日期dateNY
SRno单号char10NY
Bno书号char10NY and F
Mno会员号char15NY and F
SMno售货员号char10NY and F
SRprice价格moneyYN
SRnum数量intYN
SRtime时间timeYN

表 5-6 退货表(cook)

字段名描述数据类型数据长度NULLPrimarykey
BRdate日期dateNY
BRno单号char10NY
Bno书号char10NY and F
Mno会员号char15NY and F
SMno售货员号char10NY and F
BRprice价格moneyYN
BRnum数量intYN
BRtime时间timeYN

表 5-7 图书入库表(ManageStockRecords)

字段名描述数据类型数据长度NULLPrimarykey
MSdatetime时间日期smalldatetimeNY
Ano管理员号char10NY and F
Bno书号date10NY and F
MSnum数量intYN

表 5-8 图书退货表(ManageBackRecords)

字段名描述数据类型数据长度NULLPrimarykey
MBdatetime时间日期smalldatetimeNY
Ano管理员号char10NY and F
Bno书号date10NY and F
MBnum数量intYN

七、数据库实施

7.1 数据库构建

7.1.1 数据说明表

表 6-1 数据说明表

编号数据表名称类型内容
1Book主表图书信息
2Member主表顾客信息
3SalesMan主表销售人员信息
4Administrator主表管理员信息
5SalesRecords主表销售信息
6BackRecords主表退货信息
7ManageStockRecords主表入库信息
8ManageBackRecords主表出库信息

7.1.2 数据库创建(使用 SQL 语句的数据库模型)

USE BookStore
CREATE TABLE Book(
    Bno CHAR(10) NOT NULL PRIMARY KEY,
    Bname NVARCHAR(20) NOT NULL,
    Bauthor VARCHAR(20) NOT NULL,
    Bprice MONEY NOT NULL,
    Btype VARCHAR(10),
    Bpublish VARCHAR(20),
    Bnum INT,
)
CREATE TABLE Member(
    Mno CHAR(15) NOT NULL PRIMARY KEY,
    Mname VARCHAR(20),
    Msex CHAR(2) CHECK (Msex IN('男','女')),
    Mtel VARCHAR(11),
    Mbir DATE,
    Mintegration INT,
)
CREATE TABLE SalesMan(
    SMno CHAR(10) NOT NULL PRIMARY KEY,
    SMname VARCHAR(20) NOT NULL,
    SMsex CHAR(2) CHECK (SMsex IN('男','女')),
    SMpassword VARCHAR(13),
)
CREATE TABLE Administrator(
    Ano CHAR(10) NOT NULL PRIMARY KEY,
    Aname VARCHAR(20) NOT NULL,
    Asex CHAR(2) CHECK (Asex IN('男','女')),
    Apassword VARCHAR(13),
)
CREATE TABLE SalesRecords(
    SRdate DATE NOT NULL,
    SRno CHAR(10) NOT NULL,
    Bno CHAR(10)  NOT NULL,
    Mno CHAR(15)  NOT NULL,
    SMno CHAR(10) NOT NULL,
    SRprice MONEY,
    SRnum INT,
    SRtime TIME,
    PRIMARY KEY(SRdate, SRno, Bno, Mno, SMno),
    CONSTRAINT FK_SR_Bno FOREIGN KEY(Bno) REFERENCES Book(Bno),
    CONSTRAINT FK_SR_Mno FOREIGN KEY(Mno) REFERENCES Member(Mno),
    CONSTRAINT FK_SR_SMno FOREIGN KEY(SMno) REFERENCES SalesMan(SMno),
)
CREATE TABLE BackRecords(
    BRdate DATE NOT NULL,
    BRno CHAR(10) NOT NULL,
    Bno CHAR(10)  NOT NULL,
    Mno CHAR(15)  NOT NULL,
    SMno CHAR(10) NOT NULL,
    BRprice MONEY,
    BRnum INT,
    BRtime TIME,
    PRIMARY KEY(SRdate, BRno, Bno, Mno, SMno),
    CONSTRAINT FK_BR_Bno FOREIGN KEY(Bno) REFERENCES Book(Bno),
    CONSTRAINT FK_BR_Mno FOREIGN KEY(Mno) REFERENCES Member(Mno),
    CONSTRAINT FK_BR_SMno FOREIGN KEY(SMno) REFERENCES SalesMan(SMno),
)
CREATE TABLE ManageStockRecords(
    MSdatetime SMALLDATETIME NOT NULL,
    Ano CHAR(10) NOT NULL,
    Bno CHAR(10) NOT NULL,
    MSnum INT,
    PRIMARY KEY( MSdatetime,Ano, Bno),
    CONSTRAINT FK_MS_Ano FOREIGN KEY(Ano) REFERENCES Administrator(Ano),
    CONSTRAINT FK_MS_Bno FOREIGN KEY(Bno) REFERENCES Book(Bno),
)
CREATE TABLE ManageBackRecords(
    MBdatetime SMALLDATETIME NOT NULL,
    Ano CHAR(10) NOT NULL,
    Bno CHAR(10) NOT NULL,
    MBnum INT,
    PRIMARY KEY(Mbdatetime, Ano,  Bno),
    CONSTRAINT FK_MB_Ano FOREIGN KEY(Ano) REFERENCES Administrator(Ano),
    CONSTRAINT FK_MB_Bno FOREIGN KEY(Bno) REFERENCES Book(Bno),
)
-- book
CREATE INDEX IX_Book_Bno ON Book(Bno)
CREATE INDEX IX_Book_Bname ON Book(Bname)
CREATE INDEX IX_Book_Bauthor ON Book(Bauthor)
CREATE INDEX IX_Book_Btype ON Book(Btype)
CREATE INDEX IX_Book_Bpublish ON Book(Bpublish)
-- member
CREATE INDEX IX_Member_Mno ON Member(Mno)
CREATE INDEX IX_Member_Mname ON Member(Mname)
CREATE INDEX IX_Member_Mtel ON Member(Mtel)
-- MSR MBR
CREATE INDEX IX_MSR_DateTime ON ManageStockRecords(MSdatetime)
CREATE INDEX IX_MBR_DateTime ON ManageBackRecords(MBdatetime)
-- BR SR
CREATE INDEX IX_SR_Date ON SalesRecords(SRdate)
CREATE INDEX IX_BR_Date ON BackRecords(BRdate)
--触发器
CREATE TRIGGER TG_SR_ADD
    ON SalesRecords
    AFTER INSERT
    AS
    UPDATE Book SET Bnum = Bnum - inserted.SRnum
    FROM Book, inserted
    WHERE Book.Bno = inserted.Bno

CREATE TRIGGER TG_BR_DEC
    ON BackRecords
    AFTER INSERT
    AS
    UPDATE Book SET Bnum=Bnum + inserted.BRnum
    FROM Book,inserted
    WHERE Book.Bno = inserted.Bno

CREATE TRIGGER TG_MSR_ADD
    ON ManageStockRecords
    AFTER INSERT
    AS
    UPDATE Book SET Bnum=Bnum + inserted.MSnum
    FROM Book,inserted
    WHERE Book.Bno = inserted.Bno

CREATE TRIGGER TG_MBR_DEC
    ON ManageBackRecords
    AFTER INSERT
    AS
    UPDATE Book SET Bnum=Bnum - inserted.MBnum
    FROM Book,inserted
    WHERE Book.Bno = inserted.Bno

CREATE TRIGGER TG_MemI_ADD
    ON SalesRecords
    AFTER INSERT
    AS
    UPDATE Member SET Mintegration=Mintegration + inserted.SRnum * inserted.SRprice
    FROM Member,inserted
    WHERE Member.Mno = inserted.Mno

CREATE TRIGGER TG_MemI_DEC
    ON BackRecords
    AFTER INSERT
    AS
    UPDATE Member SET Mintegration=Mintegration - inserted.BRnum * inserted.BRprice
    FROM Member,inserted
    WHERE Member.Mno = inserted.Mno

7.2 数据库迁移和导入方案

7.2.1 数据库迁移

通过 msSQL 中相应的数据库进行分离,得到数据文件.方便迁移

7.2.2 数据库导入

把相应文件附加到数据库

八、系统界面设计和后台代码

8.1 系统界面设计

本系统的界面主要用 QT + PyQt5 等技术,力求界面美观大方、友好易用.详细如下:

8.1.1 登录模块界面

该界面为系统的登陆窗口,要求输入账号、密码、或直接以游客方式进入.。如图 7-1:

图 7-1 登陆界面

8.1.2 管理员界面

该界面为管理员界面,是管理员登录后进入的界面,其中有六个小界面,每个界面能够完成相应的功能。如图 7-2 ~7-6:

图 7-2 管理员界面

图 7-3 图 7-4

图 7-5 图 7-6

图 7-6

图 7-7

8.1.3 售货员界面

为售货员使用的界面,点击对应键即可进入实现对应功能的界面,如图 7-7

8.1.4 图书查找界面

该界面为图书查找界面,也是游客能够直接进入的界面。通过该界面能够通过不同的方式快速搜索图书,并显示在表格中,最多 50 条,(如图 7-8),若多于 50 条,则可通过点击显示所有查看数据(图 7-9)

图 7-7 图快搜索界面

图 7-9 显示所有数据界面

8.1.5 图书管理模块界面

图书管理模块包括(图 7-10):图书的增加(7-12),删除(7-13),修改(图 7-11)功能,能与图书搜索界面共存(图 7-11),快速定位图书。通过控制按键的隐藏、显示方便实现对应的功能

图 7-10 全图功能

图 7-11 修改功能及查询并列

图 7-12 添加 图 7-13 删除

8.1.6 销售人员管理模块

销售人员管理模块包括(图 7-14):销售人员的增加,删除,修改功能,能与销售人员显示界面共存。通过控制按键的隐藏、显示方便实现对应的功能,具体布局与图书管理模块类似

图 7-14 添加

8.1.7 信息查看模块

该模块为管理员查看对应信息的模块,点击对应按钮即可在表中显视对应的信(图 7-6)。

8.1.8 购买模块

该模块为购买模块,也是系统的一个核心模块(图 7-15),在该模块实现购买图书功能,点击对应书号即可显示对应的书籍信息,输入书号也会根据是否会员及会员信息生成一个黑夜的单价,生成默认的数量 1。输入完成后会进入数据的合理性检查,若数据输入错误,则清空当前输入的数据。若输入的书号已存在,则在原书号的数量上加 1。数据无法隔行输入。自却生成单号、时间,存入数据库

图 7-14 添加

8.1.9 退货模块

顾客退货,输入基本退货信息,录入退货信息(7-15)。

图 7-15 退货

8.2 主要模块代码

8.2.1 数据处理

参数处理,把对应的参数处理成 SQL 语句

@staticmethod
def insert_parameter_deal(where, *args):
    """

    :param self:
    :param where: str 插入的表名
    :param args: 插入参数列表
    :return: str 嵌入语句,可直接使用
    """
    # print("参数处理", where, args)
    exc = "INSERT INTO " + where + " VALUES " + str(args)
    print("参数处理", exc)
    return str(exc)
@staticmethod
def select_parmeter_deal(table_name, ** kwargs):
    """
    查询参数处理

    :param table_name:表名
    :param kwargs: a = b and a1 = b1 and a2 = b2
    :return:
    """
    a = 'SELECT * FROM ' + table_name + " WHERE "
    b = ' 1 = 1 '
    for i in kwargs:
        b = b + ' AND ' +  str(i) + ' = ' + str(kwargs[i])


    return  a + b
@staticmethod
def updata_parmeter_deal(table_name='', set={}, where={}):

    update = "UPDATE " + table_name + ' SET '
    a = ''
    for i, j in set.items():
        a = a + ', ' + (str(i)) + ' = ' + DbDesignBase.str_add_quotation(str(j))
    a = a + '  WHERE '
    b = ''
    for i, j in where.items():
        b = b + ', ' + (str(i)) + ' = ' + DbDesignBase.str_add_quotation(str(j))

    a = re.sub(r"^, ", ' ', a)
    b = re.sub(r"^, ", ' ', b)
    return update + a + b
@staticmethod
def delete_parmeter_deal(table_name, ** kwargs):
    a = 'DELETE FROM ' + table_name + " WHERE "
    b = ' 1 = 1'
    print(kwargs)
    for i in kwargs:
        b = b + ' AND ' + str(i) + ' = ' + str(kwargs[i])

    return a + b

	数据有效性判断,判断输入数据是否正确

@staticmethod
def is_money(string):
    if re.match(r'^[1-9][0-9]*$|^[1-9][0-9]*\.[0-9]+$|^0\.[0-9]+$', str(string)):
        return True
    else:
        return False

@staticmethod
def is_no(string):
    if re.match(r'^\d{4,11}$', str(string)):
        return True
    else:
        return False

@staticmethod
def is_sale_num(string):
    if re.match(r'^[1-9]\d{0,2}$', str(string)):
        return True
    else:
        return False

@staticmethod
def is_tel(string):
    if  re.match(r'^1\d{10}$|^\d{7,8}$', str(string)):
        return True
    else:
        return False

@staticmethod
def is_name(string):
    if re.match(r'^[\u4e00-\u9fa5]{2,4}$', str(string)):
        return True
    else:
        return False

@staticmethod
def is_num(string):
    if re.match((r'^[1-9]\d*$'), str(string)):
        return True
    else:
        return False
@staticmethod
def insert_data_check_book(Bno, Bname, Bauthor, Bprice, Btype, Bpublish, Bnum):
    flag = 0
    if re.match(r'^\d{4,11}$',Bno):
        flag |= 1 << 0
        # print('Bno')
    if re.match(r'\S', Bname):
        flag |= 1 << 1
        # print('Bname')
    if re.match(r'\S', Bauthor):
        flag |= 1 << 2
        # print('Bauthor')
    if re.match(r'^[1-9][0-9]*$|^[1-9][0-9]*\.[0-9]+$|^0\.[0-9]+$',Bprice):
        flag |= 1 << 3
        # print('Bprice')

    type = r'^经典名著$|^专业图书类$|^古典文学$|^外国文学$|^现当代文学$|^历史地理类$|^哲学类$|^社会科学类$|^玄幻文学$|^儿童文学$'
    if re.match(type, Btype):
        flag |= 1 << 4
        # print('Btype')

    if re.match(r'\S+出版社$', Bpublish):
        flag |= 1 << 5
        # print('Bpublish')
    if re.match(r'0$|[1-9]\d*$', Bnum):
        flag |= 1 << 6
        # print('Bnum')
    if flag == 0x7F :
        flag = 0xff
    print(flag)
    return flag

8.2.2 登录模块

确认登录系统的身份

def login(self):
    print("login")
    type = 0
    if self.time == 10:
        print("root")
        type = self.WIN_EXTERN_ROOT
    elif self.radioButton_Admini.isChecked():
        print("Admini")
        type = self.WIN_EXTERN_ADMINI
    elif self.radioButton_cust.isChecked():
        print("Salesman")
        type = self.WIN_EXTERN_SALEMAN

    username = self.username.text()
    password = self.password.text()

    if username == '' and password == '':
        self.time += 1
        self.label_warning.clear()
        if self.time == 5:
            self.pushButton_hide.setEnabled(True)
        elif self.time > 5:
            self.pushButton_hide.setEnabled(False)
            self.time = 0
        return 0
    # 连按处理
    import time
    counter =  time.perf_counter()
    space_time =  counter - self.perf_counter
    print(space_time)
    if space_time < 1.5:
        return 0

    self.perf_counter = counter
    import DbSelect
    Db = DbSelect.DbSelect()
    if type == self.WIN_EXTERN_ADMINI:
        # 管理员
        Db.select_administrator()

    elif type == self.WIN_EXTERN_SALEMAN:
        # 销售员
        Db.select_salesman()

    elif type == self.WIN_EXTERN_ROOT:
        # sa 帐户
        if username == 'sa' and password == '123':
            return type

    table_date = Db.cursor_data_to_list()
    for i in table_date:
        if i[0].strip() == username and i[3].strip() == password:
            self.label_warning.setText("登录成功")
            return type

    self.label_warning.setText("用户名或密码错误,请重新输入")
    self.time = 0
    return 0

8.2.3 图书管理模块

实现图书的增删改

def on_pushButton_del_released(self):
    print('on_pushButton_del_released')
    bno = self.lineEdit_bno_3.text()
    if bno == '':
        return
    self.pushButton_del.setEnabled(False)
    flag = self.dialog_yes_no("是否删除?", "确认")
    if flag is True:
        if self.dbcur.delete_book(bno):
            self.dialog_text("删除成功","提示窗")
            self.data_clear_widget_3()
            self.pushButton_del.setEnabled(False)
        else:
            self.dialog_text("删除失败 可能存在外键限制","提示窗")

def on_pushButton_add_released(self):
    print("on_pushButton_add_released")
    self.pushButton_add.setEnabled(False)
    flag = self.dialog_yes_no("是否添加","提示")
    if flag is True:
        flag = self.dbcur.book_insert(
            self.lineEdit_bno.text().strip(),
            self.lineEdit_bname.text().strip(),
            self.lineEdit_bauthor.text().strip(),
            self.lineEdit_bprice.text().strip(),
            self.comboBox_btype.currentText().strip(),
            self.lineEdit_bpublish.text().strip(),
            self.lineEdit_bnum.text().strip(),
        )
        if flag is True:
            self.dialog_text("添加成功", "提示")
            self.widget_3.setEnabled(True)
        else:
            self.dialog_text("添回失败 可能主键冲突", "提示")
    else:
        self.pushButton_add.setEnabled(True)
def on_pushButton_change_released(self):
    print('on_puchButton_change_released')
    self.pushButton_change.setEnabled(False)
    set = self.get_set_parmeter()
    print(set)
    if len(set) == 0:
        self.dialog_text("内容未做变更", '提示')
    else:
        if self.dialog_yes_no("确认修改", "确认") is True:
            updata = self.dbcur.updata_parmeter_deal('Book', set, {'Bno':self.lineEdit_bno.text().strip()})
            # print(updata)
            if self.dbcur.update_run_exec(updata):
                self.dialog_text("修改成功", '提示')
            else:
                self.dialog_text("修改失败", '提示')
        else:
            self.widget.setEnabled(True)
            self.pushButton_pre_view.show()
            self.pushButton_pre_view_cancel.hide()

8.2.4 图书购买模块

def buy_deal(self):
	# 购买操作处理

    self.dbcur.select_run_exec("SELECT  TOP 1 * FROM SalesRecords ORDER BY SRdate DESC")
    table = self.dbcur.cursor_data_to_list()
    crrurent_date = str(QDateTime.toPyDateTime(self.dateTimeEdit_buy.dateTime()).date())
    crrurent_time = str(QDateTime.toPyDateTime(self.dateTimeEdit_buy.dateTime()).time())
    last_data = table[0][0]

    if crrurent_date == last_data:
        # 当天存在记录
        srno = int(table[0][1])
        print("srno", srno)
        srno = srno + 1
        srno = '000000' + str(srno)
        srno = srno[len(srno) - 6:]
        mno = ''
        if self.checkBox_buy_is_member.isChecked():
            mno = self.mno
        else:
            x = crrurent_date.split('-')
            mno = 'C' + x[0] + x[1] + x[2] + srno
            print("mno", mno, srno)
            exec = "INSERT INTO Member VALUES ( '" + mno + "', NULL, NULL, NULL, NULL, NULL)"
            self.dbcur.insert("Member", exec)
    else:
        # 当前不存在
        srno = '000001'
        if self.checkBox_buy_is_member.isChecked():
            mno = self.mno
        else:
            x = crrurent_date.split('-')
            mno = 'C' + x[0] + x[1] + x[2] + srno
            exec = "INSERT INTO Member VALUES ( '" + mno + "', NULL, NULL, NULL, NULL, NULL)"
            self.dbcur.insert("Member", exec)
    for i in self.buy_book:
        if i[0]:
            self.dbcur.sales_records_insert(srno, i[0], mno, self.sMno, i[1], i[2], crrurent_time, crrurent_date,)


def on_tableWidget_buy_info_currentCellChanged(self,i, j, m, n):
    # 表格信息处理
print('on_tableWidget_buy_info_currentCellChanged', i, j, m, n)
    self.label_buy_input_hint.setText("")
    if m == -1:
        return

    if m != 0 :
        # 本行上一行数据为空  无法输入数据
        item = self.tableWidget_buy_info.item(m - 1, 0)
        if item is None or str(item.text()) == '':
            if self.tableWidget_buy_info.item(m, n) is not None:
                self.tableWidget_buy_info.item(m, n).setText('')
            return
        elif item.text()=="":
            return
        # 本行第一列内容为空 无法输入数据
        item = self.tableWidget_buy_info.item(m, 0)
        if item is None or item.text().strip == '':
            if self.tableWidget_buy_info.item(m ,n) is not None:
                self.tableWidget_buy_info.item(m, n).setText('')
            return

    item = self.tableWidget_buy_info.item(m, n)
    if item is None or item.text() == '':
        # self.dialog_text("未输入数据")
        self.label_buy_input_hint.setText("未输入数据")
        return

    if n == 0:
        # 书号
        if j == 0 or m != i:
            pass
        else:
            # 输入书号后输入
            bno = item.text()
            bno = self.dbcur.str_add_quotation(bno)
            print(bno)
            exec = self.dbcur.select_parmeter_deal('Book', Bno = bno)
            self.dbcur.run_exec(exec)
            table = self.dbcur.select_cursor_data_to_list()
            if len(table):
                # 书号存在
                # print(table)
                for i in range(50):
                    item = self.tableWidget_buy_info.item(i, 0)
                    if item == None or item.text() == '' or i == m:
                        # 书籍未输入过
                        self.buy_book[m][0] = item.text()
                        bprice = float(table[0][3])
                        bprice = bprice * self.discount / 10
                        item = QtWidgets.QTableWidgetItem(str(bprice)) # 单价
                        self.tableWidget_buy_info.setItem(m, 1, item)
                        self.buy_book[m][1] = item.text()
                        item = QtWidgets.QTableWidgetItem('1')         # 数量
                        self.tableWidget_buy_info.setItem(m, 2, item)
                        self.buy_book[m][2] = item.text()
                        self.buy_book[m][3] = table[0][3]
                        break
                    elif str(item.text()).strip() == str(table[0][0]).strip():
                        print(item.text(), table[0][0])
                        # 本书已经输入过
                        bnum = int(self.tableWidget_buy_info.item(i, 2).text())
                        bnum = bnum + 1
                        self.tableWidget_buy_info.item(i, 2).setText(str(bnum))
                        self.tableWidget_buy_info.item(m, 0).setText('')
                        self.buy_book[i][2] = bnum
                        break
            else:
                self.label_buy_input_hint.setText("该书不存在")
                self.tableWidget_buy_info.item(m,n).setText('')
    elif n == 1:
        # 金额
        bprice = item.text()
        if self.dbcur.is_money(bprice):
            self.buy_book[m][n] = bprice
        else:
            self.label_buy_input_hint.setText("金额输入格式错误")
            item.setText('')
    elif n == 2:
        # 数量
        bnum = item.text()
        if self.dbcur.is_sale_num(bnum):
            self.buy_book[m][n] = bnum
        else:
            self.label_buy_input_hint.setText("数量格式错误或数量过大")
            item.setText('')
    # print(self.buy_book)
    money = self.cal_all_price()
    self.label_buy_allprice.setText(str("%.2f"%money))

8.2.5 密码修改模块

def on_pushButton_ensure_released(self):
    print('on_pushButton_ensure_released')
    if self.lineEdit_new1.text()!=self.lineEdit_new2.text():
        self.dialog_text('再次输入密码不一样')
        return

    elif self.lineEdit_old.text()!=self.tabel[0][3]:
        self.dialog_text('旧密码错误')
        return
    else:
        if self.dialog_yes_no("确认修改?"):
            exec = self.dbcur.updata_parmeter_deal('SalesMan',
                                       {'SMpassword':self.lineEdit_new1.text()},
                                        {'SMno':self.tabel[0][0]})
            if self.dbcur.update_run_exec(exec):
                self.dialog_text("修改成功")
                self.init()
            else:
                self.dialog_text('修改失败')
        else:
            pass

九、安装使用和说

安装说明

安装 python

要求使用 python3,python 可能存在部分问题

安装插件

pip install PyQt5, 用于生成 UI

pip install pymssql 用于连接数据库

附加数据库

运行文件内的 SQL 文件。

运行

运行文件内的 main.py 文件

结论与展望

本系统完成了任务书中要求的全部内容。参考任务书。

系统还存在着一些缺陷,功能并不是十分完善. 如果还有更多时间可以维护和修改的话,我希望能实现后端通信,因为本项目各个角色的交互方式主要是依赖监听数据库变化进行的,这在用户多的时候,并发性会降低。

在今后的研究学习中,将会对以上问题进行改进,并且对整个框架精益求精,进一步满足用户需求,使开发更具有意义。

♻️ 资源

在这里插入图片描述

大小: 1.19MB
➡️ 资源下载:https://download.csdn.net/download/s1t16/87248124

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/81942.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

年网络安全观察报告 地域分布

执行摘要 从 1987 年 9 月 14 日&#xff0c;中国向世界发出第一封电子邮件 到如今&#xff0c;中国的互联网发展已过去整整 31 个年头。从消费互联、产业互联到万物互联&#xff0c;互联网正在加速改变我们的交流方式和交易方式&#xff0c;一次次 004.重塑了国家的经济形态和…

Java单例模式的写法及作用介绍

在创建型设计模式中&#xff0c;我们第一个学习的是单例模式&#xff08;Singleton Pattern&#xff09;&#xff0c;这是设计模式中最简单的模式之一。 单例是什么意思呢&#xff1f; 单例就是单实例的意思&#xff0c;即在系统全局&#xff0c;一个类只创建一个对象&#x…

友嘉银行坎坷的云原生之路

随着数字化浪潮的来临&#xff0c;云原生技术越来越火。云原生技术的持续更新&#xff0c;无一不在催促传统行业重塑业务体系以及产业生态的转型升级。说到云原生&#xff0c;目前已被认为是云计算最重要的发展方向&#xff0c;它拥有更优雅的架构、更灵活的调度、更完善的治理…

QT—常用窗口部件

一、QLabel 新建一个QWidget项目&#xff0c;设置基类为QWidget 1.显示文本 调用setText函数编辑要显示的文本&#xff0c;传入一个const QString类型的参数 例如&#xff1a; ui->TxtLabel->setText("Label文本&#xff0c;12345678"); 其中TxtLabel是一…

web大作业 web前端课程设计 web前端课程设计代码 web课程设计 HTML网页制作代码

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

【Android Room 库基础入门】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录一、前言二、Room 主要组件三、Room 基础入门3.1 引入 Room 库到项目3.2 Room 使用示例3.2.1 定义数据实体类3.3.2 定义数据访问对象&#xff08;DAO&#xff09;3.3…

如何成为一名IT咨询顾问?

咨询顾问这个工作&#xff0c;很多人都很羡慕&#xff0c;在别人看来咨询顾问的工作时间自由&#xff0c;可以到处出差和旅游&#xff0c;能够认识企业各种层面的人&#xff0c;见多识广。实际情况真的这么轻松吗&#xff1f;什么样的人适合做咨询顾问&#xff1f;做咨询顾问需…

《计算机网络》2022年期末试卷

《计算机网络》期末试卷2022年A卷

synchronized 关键字

文章目录一、synchronized 的特性互斥可重入二、 synchronized 使用示例三、 java标准库的线程安全类四、 死锁可重入死锁相互争夺锁哲学家就餐问题死锁的四个必要条件一、synchronized 的特性 互斥 synchronized 会起到互斥效果, 某个线程执行到某个对象的 synchronized 中时…

亚马逊、ebay测评自养号新手应该要怎么做?

如今很多的跨境卖家开始在深入了解测评自养号这块&#xff0c;都想在运营上减低一些成本&#xff0c;多增加一些利润。对于整个测评工作来说&#xff0c;测评技术可谓是非常核心的一个环节&#xff0c;多学习&#xff0c;不要浮躁&#xff0c;这样才能让我们不断提高自己的测评…

Android 3D 魔方游戏的设计与开发

Android 3D 魔方游戏的设计与开发 5.1 Feature 定义 魔方是一个有趣的益智游戏&#xff0c;相信很多人都玩过。本次毕业设计&#xff0c;欲完成的主要的功能如下&#xff1a; &#xff08;1&#xff09; 开始游戏&#xff1a;开始一个新的游戏 &#xff08;2&#xff09; 返…

Java项目:食品检测管理系统(java+SSM+JavaScript+layui+Mysql)

源码获取&#xff1a;俺的博客首页 "资源" 里下载&#xff01; 项目介绍 本项目后台食品检测管理系统&#xff1b; &#xff08;1&#xff09;用户管理&#xff1a;用户登录、验证。 &#xff08;2&#xff09;任务管理&#xff1a;添加任务、检品受理。 &#xff0…

数学基础从高一开始4、集合的基本运算2

数学基础从高一开始3、集合的基本运算2 目录 数学基础从高一开始3、集合的基本运算2 补集 例2&#xff1a; 总结&#xff1a; 补集 这里补集的符号我打不出来&#xff0c;这里就截图给大家看了啊。 下图是补集的语言表达&#xff0c;图形表达以及符号表达方式&#xff1a…

在无需分叉的情况下模拟任何 SIGHASH 标志

我们开发了一种新颖的方法来模拟任何 SIGHASH 标志&#xff0c;只需在智能合约中编写逻辑即可。它不需要更改协议&#xff0c;因此比每次构思新用例时通过分叉添加硬编码标志更实用和灵活。 SIGHASH 标志 SIGHASH 标志决定交易的哪一部分由签名者签名。具体来说&#xff0c;它…

Redis分布式锁那点事

锁超时问题 在redis分布式锁中&#xff0c;如果线程A加锁成功了&#xff0c;但是由于业务功能耗时时间很长&#xff0c;超过了设置的超时时间&#xff0c;这时候redis会自动释放线程A加的锁。通常我们加锁的目的是&#xff1a;为了防止访问临界资源时&#xff0c;出现数据异常…

【Python学习记录】Numpy广播机制(broadcast)

✨ 博客主页&#xff1a;小小马车夫的主页 ✨ 所属专栏&#xff1a;Python学习记录 文章目录一、什么是Numpy广播机制二、Numpy广播应用三、Numpy广播规则一、什么是Numpy广播机制 在Numpy、tensorflow、pytorch中数组有一种广播机制(broadcast), 就是针对两个不同形状的数组进…

【Linux】Linux调试器-gdb使用及git命令行

大家好我是沐曦希&#x1f495; 文章目录一.预备知识1.背景2.Linux默认行为3.debug和release区别二.使用三.使用git命令行一.预备知识 1.背景 程序的发布方式有两种&#xff0c;debug模式和release模式Linux gcc/g出来的二进制程序&#xff0c;默认是release模式要使用gdb调试…

前端vue面试题(持续更新中)

Watch中的deep:true是如何实现的 当用户指定了 watch 中的deep属性为 true 时&#xff0c;如果当前监控的值是数组类型。会对对象中的每一项进行求值&#xff0c;此时会将当前 watcher存入到对应属性的依赖中&#xff0c;这样数组中对象发生变化时也会通知数据更新 源码相关 g…

Android 10.0 Launcher3双层(抽屉)高斯模糊(毛玻璃)背景功能的实现

1.概述 在进行定制开发的功能需求方面,Launcher3的需求也挺多的,单双层抽屉高斯模糊毛玻璃背景功能也是一个需求功能,最近按照功能需求来开发 双层抽屉高斯模糊毛玻璃效果背景的功能 效果图如图: 2. Launcher3双层(抽屉)高斯模糊(毛玻璃)背景功能的实现的核心代码 package…

基于Python logging 实现日志功能模块(即拿即用)

基于Python实现日志功能模块 在项目开发过程,日志文件是十分重要的,尤其对于程序员后期排查软件问题、发现问题bug及使用记录等更是非常重要。 本文使用部分软件版本如下: PyCharm 2019.3 Python 3.7.3 logging 0.5.1.2 logging logging 模块中包含为应用程序和库实现灵…