基于Python的书店销售管理系统

设 计 总 说 明
现在社会随着计算机技术迅速发展与技术的逐渐成熟,信息技术已经使人们的生活发生深刻的变化。生活中的各种服务系统也使人们在生活中的联系日常销售活动方式发生了很大的变化,让效率较低的手工操作成为过去,而换成信息化自动化的计算机操作。本系统是针对某一小型书店而设计的书店管理信息系统,本 系统的后台数据库选择 SQL SERVER 2014 数据库,前台开发工具选择 PyCharm, QT 。
系统设计整个系统以满足用户需求为主旨,操作简便,界面友好、灵活、高效。安全性从多个设计层面得到了保障。本系统划分了三种不同权限的身份:管理员,销售员,顾客,对进行书店的销售管理,涵盖书店销售的基本运作规则。本文设计的书店销售管理系统可以帮助书店提高效率,进行调度管理,同时本系统为餐饮企业提供了一种新的经济理念,完善企业运作模式,从而从根本上推动国家第三产业的发展。
本文是严格按照数据库系统开发的原理,对书店销售管理系统进行系统需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库实施、系统运行维护等作了详细的阐述.

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

目 录
设 计 总 说 明 I
目 录 i
第1章 绪论 1
1.1 开发背景及目的意义 1
1.2 国内外现状 1
1.2.1 国内现状 1
1.2.2 国外现状 1
1.3 开发工具、语言及环境 1
1.3.1 pyCharm 简介 1
1.3.2 msSQL简介 1
1.3.3 开发语言python 1
第2章 系统分析 3
2.1 系统需求分析 3
2.2 系统目标 3
2.3 系统功能 3
2.3.1 前台应用程序 3
2.3.2 后台数据库 3
2.4 可行性分析 3
2.4.1 经济可行性分析 3
2.4.2 技术可行性分析 3
2.4.3 操作可行性分析 4
2.5 数据流图 4
2.6数据字典 4
2.6.1 数据元素 4
2.6.2数据存储 5
2.6.3 数据流 6
2.6.4 数据处理 6
第3章开发技术介绍 8
3.1 pymssql介绍 8
3.1.1 配置环境 8
3.1.2 连接MSSQL 8
3.2 PyQt5介绍 8
3.2.1 配置环境 8
第4章 系统设计 9
4.1 系统目标 9
4.2 系统功能划分 9
4.2 模块简介及功能 9
4.2.1 图书管理模块 9
4.2.2 顾客管理模块 10
4.2.3 销售模块 10
4.3.4 图书查询模块 10
4.3.5 人员信息管理 10
4.3.6 销售统计模块 10
4.3 业务流程图 11
第5章 数据库设计 13
5.1 数据库概要设计 13
5.1.1系统E-R图 13
5.2数据库逻辑设计 13
5.3 数据库物理设计 13
第6章 数据库实施 17
6.1 数据库构建 17
6.1.1 数据说明表 17
6.1.2 数据库创建(使用SQL语句的数据库模型) 17
6.2 数据库迁移和导入方案 20
6.2.1数据库迁移 20
6.2.2数据库导入 20
第7章 系统界面设计和后台代码 21
7.1 系统界面设计 21
7.1.1 登录模块界面 21
7.1.2 管理员界面 21
7.1.3售货员界面 22
7.1.4图书查找界面 23
7.1.5 图书管理模块界面 24
7.1.6 销售人员管理模块 25
7.1.7 信息查看模块 25
7.1.8 购买模块 25
7.1.9 退货模块 26
7.2 主要模块代码 27
7.2.1 数据处理 27
7.2.2 登录模块 29
7.2.3 图书管理模块 30
7.2.4 图书购买模块 31
7.2.5 密码修改模块 33
第8章 安装使用和说明 34
8.1安装说明 34
8.1.1安装python 34
8.1.2安装插件 34
8.1.3附加数据库 34
8.1.4运行 34
第9章 结论与展望 35
9.1 结论 35
9.2 不足之处及未来展望 35
参考文献 36
第2章 系统分析
2.1 系统需求分析
本次课程设计的题目是:书店销售管理子系统,其具体内容如下:
书店希望借助一个销售管理子系统实现对现有业务的管理。该书店目前采用会员制,顾客购买书籍累积达到一定金额后,凭购书发票可填表申请成为正式会员,会员在购书时享有一定折扣,折扣额度可变化。该书店不定期地会推出促销活动,要求图书的价格是可变更的。系统主要功能如下:
★ 图书入库管理:维护入库图书信息(如图书编号、书名、作者、价格、图书分类、出版社等),自动计算库存。
★ 图书查询统计:按图书分类,出版社、书名、作者等条件查询图书的详细信息。
★ 销售管理:销售过的图书都记录在销售列表中,方便统计收入。图书销售后,实时记录图书库存,按每天统计销售额、按每个月或季度统计销售额并生成报表,并能根据销售数量统计生成畅销书名单。
★ 书店会员管理:提供会员信息的维护功能,可设置会员等级,不同级别的会员享受不同的折扣,可以变更折扣额度。
★ 系统管理:包括参数设置、权限设置、更改密码等。用户包括系统管理员和销售人员。系统管理员维护整个系统的数据
2.2 系统目标
本系统要实现书店销售管理,实现书店销售的系统化,自动化和高效率。能够实现,图书管理,图书销售,销售统计,管理员对销售人员的管理,等功能,以及各角色的交互等。
2.3 系统功能
书店销售管理子系统的开发主要包括应用程序系统和后台数据库,应用程序系统要求界面友好,功能完备,易使用等特点.而后台数据库的数据要具有一致性、完整性、安全性.
2.3.1 前台应用程序
前台应用程序重在实现用户和系统的交互,在功能强大的同时,也要简洁和操作方便。目的是让调度环节更高效,在保证操作正确性的情况下,免去不必要的操作。
2.3.2 后台数据库
后台数据库在考虑前台访问操作简便的同时,提供强大的管理模式。数据库结构合理,完整,权限设计符合实际,安全性良好。

7.2 主要模块代码
7.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
7.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
7.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()

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

7.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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 5
    点赞
  • 110
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值