基于Python+SQLServer实现(界面)书店销售管理管理子系统

news2024/11/15 17:33:58

书店销售管理管理子系统

一、设 计 总 说 明

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

图 4-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 管理员界面

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)。

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 文件

结论与展望

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

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

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

参考文献

  • 钱雪忠,李京. 数据库系统原理及应用[M]. 北京:北京邮电大学出版社,2010.
  • 钱雪忠,陈国俊. 数据库系统原理及应用实验指导[M]. 北京:北京邮电大学出版社,2010
  • Eric Matthes. Python 编程从入门到实践[M]. 北京:北京邮电出版社

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

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

相关文章

大数据新视界 --大数据大厂之 Reactjs 在大数据应用开发中的优势与实践

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

OpenHarmony(鸿蒙南向开发)——小型系统内核(LiteOS-A)【Perf调测】

往期知识点记录&#xff1a; 鸿蒙&#xff08;HarmonyOS&#xff09;应用层开发&#xff08;北向&#xff09;知识点汇总 鸿蒙&#xff08;OpenHarmony&#xff09;南向开发保姆级知识点汇总~ 持续更新中…… 基本概念 Perf为性能分析工具&#xff0c;依赖PMU&#xff08;Per…

UE学习篇ContentExample解读-----------Blueprint_Mouse_Interaction

文章目录 总览描述&#xff08;Blueprint_Mouse_Interaction&#xff09;阅览解析1、PlayerControler分析2、拖拽球蓝图分析&#xff1a;3、移动的立方体分析&#xff1a; 新概念总结致谢&#xff1a; 总览描述&#xff08;Blueprint_Mouse_Interaction&#xff09; 打开关卡后…

MySQL tinyint(1)类型数据在经过flink cdc同步到doris后只有0/1问题定位与解决

背景&#xff1a; 近期在负责公司数据仓库搭建事宜&#xff0c;踩了一些坑后&#xff0c;终于通了&#xff0c;目标报表也成功迁移到了新方案上&#xff0c;可在数据验收的时候发现&#xff0c;同一个订单查询出了多条记录&#xff0c;原本以为只是简单的left join出多条记录问…

植物检测系统源码分享

植物检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

Kubernetes调度单位Pod

Kubernetes调度单位Pod 1 Pod简介 不直接操作容器container。 一个 pod 可包含一或多个容器&#xff08;container&#xff09;&#xff0c;它们共享一个 namespace&#xff08;用户&#xff0c;网络&#xff0c;存储等&#xff09;&#xff0c;其中进程之间通过 localhost 本地…

Linux环境下安装部署MySQL8.0以上(内置保姆级教程) C语言

一、环境搭建、 1 、安装MySQL服务端与客户端 sudo apt-get install mysql-server //mysql服务端安装 。 &#xff08;现在只安装这一个就够了&#xff0c;包含了客户端的&#xff09; sudo apt-get install mysql-client //mysql客户端安装。 mysql服务器端程序&…

jmeter本身常用性能优化方法

第一种设置&#xff1a; 修改Jmeter.bat文件&#xff0c;调整JVM参数(修改jmeter本身的最小最大堆内存)&#xff0c;默认都是1个G set HEAP-Xms5g -Xmx5g -XX:MaxMetaspaceSize256m我的本机内存是8G&#xff0c;那最大可以设置870%(本机内存的70%)5.6g 这里我设置的5g 如果…

CSS的盒子模型(Box Model)

所有HTML元素都可以看作盒子&#xff0c;在CSS中盒子模型是用来设计和布局的&#xff0c;CSS盒子模型本质上是一个盒子&#xff0c;分装周围的HTML元素包括&#xff1a;外边距&#xff0c;边框&#xff0c;内边距和实际内容。 Margin&#xff08;外边距&#xff09; 清除边框…

CSS的弹性盒子模型(Flex box)

弹性盒子模型是CSS3的一种新的布局模式&#xff0c;弹性盒是一种当页面需要适应不同的屏幕大小以及设备类型时确保拥有合适的布局方式&#xff0c;引入弹性盒子模型的目的时提供更加有效的方式来对一个容器中的子元素进行排列&#xff0c;对齐和分配空白空间。 弹性盒子由弹性容…

Linux复习--网络基础(OSI七层、TCP三次握手与四次挥手、子网掩码计算)

一、ISO/OSI七层模型的分层与作用 1、ISO/OSI的七层模型 2、作用 应用层&#xff1a;为用户提供服务&#xff0c;给用户一个操作界面表示层&#xff1a;数据提供表示&#xff1b;加密&#xff1b;压缩&#xff1b;会话层&#xff1a;确定数据是否需要进行网络传递传输层&…

好用的idea方法分隔符插件

好用的idea方法分隔符插件

OpenCV特征检测(12)检测图像中的潜在角点函数preCornerDetect()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 计算用于角点检测的特征图。 该函数计算源图像的基于复杂空间导数的函数 dst ( D x src ) 2 ⋅ D y y src ( D y src ) 2 ⋅ D x x src − 2 …

OpenCV 3

模板匹配方法 尽量采用归一化的方法&#xff0c;因为它更加精细。 匹配效果展示 匹配单一图像 这是一段Python代码&#xff0c;主要使用了OpenCV库进行图像处理。这段代码的主要功能是通过模板匹配方法在一张大图中找到一个小图的位置。 具体来说&#xff1a; - 第一行的for…

项目实战:Qt+OSG爆破动力学仿真三维引擎测试工具v1.1.0(加载.K模型,子弹轨迹模拟动画,支持windows、linux、国产麒麟系统)

若该文为原创文章&#xff0c;转载请注明出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/142454993 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、Op…

验收测试:从需求到交付的全程把控!

在软件开发过程中&#xff0c;验收测试是一个至关重要的环节。它不仅是对软件质量的把关&#xff0c;也是对整个项目周期的全程把控。从需求分析到最终的软件交付&#xff0c;验收测试都需要严格进行&#xff0c;以确保软件能够符合预期的质量和性能要求。 一、需求分析阶段 在…

[uni-app]小兔鲜-01项目起步

项目介绍 效果演示 技术架构 创建项目 HBuilderX创建 下载HBuilderX编辑器 HBuilderX/创建项目: 选择模板/选择Vue版本/创建 安装插件: 工具/插件安装/uni-app(Vue3)编译器 vue代码不能直接运行在小程序环境, 编译插件帮助我们进行代码转换 绑定微信开发者工具: 指定微信开…

Linux 基本指令(二)

目录 1. more指令 2. less指令(重要) 3. head指令 4. tail指令 5. date指令 (1)可以通过选项来指定格式&#xff1a; ​编辑 (2)在设定时间方面 (3)时间戳 6. cal指令 7. find指令 8. grep指令 9. alias指令 10. zip指令与unzip指令 (1). zip指令 (2). unzip指令…

链表分割-----------lg

现有一链表的头指针 ListNode* pHead&#xff0c;给一定值x&#xff0c;编写一段代码将所有小于x的结点排在其余结点之前&#xff0c;且不能改变原来的数据顺序&#xff0c;返回重新排列后的链表的头指针。 我们可以假设x为36&#xff0c;则小于36都排在前边&#xff0c;>3…

桌面便签哪个好用?好用的便签软件推荐?

随着信息技术的发展&#xff0c;我们的生活方式也发生了翻天覆地的变化。从纸质笔记本到电子便签&#xff0c;这不仅仅是载体的转换&#xff0c;更是思维习惯的一次革新。在这个数字时代&#xff0c;如何利用科技工具来辅助我们更好地管理时间和信息&#xff0c;成为了值得探讨…