一、需求分析
总体来说,就是一个在游泳馆使用的进销存管理软件,记录商品的入库、出库情况,以及统计销售的金额等~
整个系统有三类用户,系统管理员、公司管理员和公司销售员,系统管理员负责录入公司信息以及分配用户,每个公司的话,都有管理员和销售员之分,销售员只能看到销售界面,就负责出库,管理员负责库存管理、员工管理、销售统计等等~
还是有很多细节需要处理的,比如一个老板有多个游泳门店,每个门店的数据都需要隔离处理,这就需要有一个公司的概念~比如需要对员工进行管理,主要是因为销售的金额需要计入员工的提成~
这里我用mindmanager把需求梳理了一下:
二、界面设计
因为只有我一个人开发,而且我是完全没有前端经验的小白,所以没指望自己能把前端做的很好,界面设计尽量简洁,后面有时间再去慢慢优化即可~
界面设计没有用任何软件,就是和需求方在纸上简单绘制了一下,毕竟这是个帮忙的事情,能用就行~~
界面就不在这里贴了,别的帖子里面有
其中有个细节是,入库的操作只在“库存管理”界面里面完成,比如新录入了商品,同时录入数量,已有商品的新进入库操作,利用修改商品数量的方式来完成,但是后台数据库会记录每一次的数量变化,这样统计的时候,才能看到期初库存和期末库存~
三、数据库设计
根据需求设计了数据库表
这些表基本够用了,入库表主要是用于数据统计的~
四、技术路线的选择
1. 编程语言 Python
python-3.10.5-amd64.exe
链接:https://pan.baidu.com/s/1e6CrqfCKAhMDmU-vY13AmQ
提取码:nu9t
2. 编程IDE VS
VSCodeUserSetup-x64-1.69.2.exe
链接:https://pan.baidu.com/s/1865J6QZQqpjpkadnthwp4A
提取码:adm8
这两个官方都可以随便下载,我也放到了百度网盘,有需要的可以自行下载,下载之后一步一步安装即可,安装Python的时候注意最后一步,选择“同时配置好环境变量”,这样比较方便
3. 前端
前端也打算用Python来写,查了很多的python库,大家比较推荐的是wxpython和QPython,之前接触过一点点的QT,确实非常强大,但是库比较重量级,自己写的这个东西明显配不上QT,又详细调研了一下wxpython,就是它了!
这个组件支持界面拖拽式编写,就是可视化的GUI,这个简直太又好了,小白轻松上手,需要安装一个软件wxFormBuilder
链接:https://pan.baidu.com/s/1L6c9rNxj8Dz0XTWtppXIrw
提取码:pgz9
安装过程非常简单,不再赘述
打开之后的界面如下:
使用非常容易上手,先新建一个project,再创建一个Form,大的架子就搭出来了
frame里面放上layout,layout根据需要进行选择,横竖可以在右侧的参数区域进行设置
接下来非常关键,在layout里面先放panel,再放具体的组件,每个panel可以设计不同的背景色,这样设计出来的界面比较有层次~比如我的登录界面全部展开如下所示:
设计好界面之后,点击Python标签,得到代码:
# -*- coding: utf-8 -*-
###########################################################################
## Python code generated with wxFormBuilder (version 3.10.1-0-g8feb16b3)
## http://www.wxformbuilder.org/
##
## PLEASE DO *NOT* EDIT THIS FILE!
###########################################################################
import wx
import wx.xrc
###########################################################################
## Class loginFrame
###########################################################################
class loginFrame ( wx.Frame ):
def __init__( self, parent ):
wx.Frame.__init__ ( self, parent, id = wx.ID_ANY, title = u"MGLite系统登陆", pos = wx.DefaultPosition, size = wx.Size( 500,300 ), style = wx.DEFAULT_FRAME_STYLE|wx.TAB_TRAVERSAL )
self.SetSizeHints( wx.DefaultSize, wx.DefaultSize )
self.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVEBORDER ) )
bSizer1 = wx.BoxSizer( wx.VERTICAL )
self.loginPanel = wx.Panel( self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL )
self.loginPanel.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_INACTIVEBORDER ) )
bSizer12 = wx.BoxSizer( wx.VERTICAL )
self.ddd1 = wx.StaticText( self.loginPanel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0 )
self.ddd1.Wrap( -1 )
self.ddd1.SetFont( wx.Font( wx.NORMAL_FONT.GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, wx.EmptyString ) )
bSizer12.Add( self.ddd1, 0, wx.ALL, 5 )
self.ddd = wx.StaticText( self.loginPanel, wx.ID_ANY, u"MGLite进销存管理系统", wx.DefaultPosition, wx.DefaultSize, 0 )
self.ddd.Wrap( -1 )
self.ddd.SetFont( wx.Font( 20, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD, False, wx.EmptyString ) )
bSizer12.Add( self.ddd, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
bSizer411 = wx.BoxSizer( wx.HORIZONTAL )
self.usernamelabel11 = wx.StaticText( self.loginPanel, wx.ID_ANY, u"角色 ", wx.DefaultPosition, wx.DefaultSize, 0 )
self.usernamelabel11.Wrap( -1 )
bSizer411.Add( self.usernamelabel11, 0, wx.ALL, 5 )
m_choice31Choices = []
self.m_choice31 = wx.Choice( self.loginPanel, wx.ID_ANY, wx.DefaultPosition, wx.Size( 150,-1 ), m_choice31Choices, 0 )
self.m_choice31.SetSelection( 0 )
bSizer411.Add( self.m_choice31, 0, wx.ALL, 5 )
bSizer12.Add( bSizer411, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 )
bSizer4 = wx.BoxSizer( wx.HORIZONTAL )
self.usernamelabel = wx.StaticText( self.loginPanel, wx.ID_ANY, u"用户名 ", wx.DefaultPosition, wx.DefaultSize, 0 )
self.usernamelabel.Wrap( -1 )
bSizer4.Add( self.usernamelabel, 0, wx.ALL, 5 )
self.usernametext = wx.TextCtrl( self.loginPanel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 150,-1 ), 0 )
bSizer4.Add( self.usernametext, 0, wx.ALL, 5 )
bSizer12.Add( bSizer4, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 )
bSizer5 = wx.BoxSizer( wx.HORIZONTAL )
self.passwordlabel = wx.StaticText( self.loginPanel, wx.ID_ANY, u"密码 ", wx.DefaultPosition, wx.DefaultSize, 0 )
self.passwordlabel.Wrap( -1 )
bSizer5.Add( self.passwordlabel, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
self.passwordtext = wx.TextCtrl( self.loginPanel, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size( 150,-1 ), wx.TE_PASSWORD|wx.TE_PROCESS_ENTER )
bSizer5.Add( self.passwordtext, 0, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 5 )
bSizer12.Add( bSizer5, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 )
bSizer41 = wx.BoxSizer( wx.HORIZONTAL )
self.usernamelabel1 = wx.StaticText( self.loginPanel, wx.ID_ANY, u"公司 ", wx.DefaultPosition, wx.DefaultSize, 0 )
self.usernamelabel1.Wrap( -1 )
bSizer41.Add( self.usernamelabel1, 0, wx.ALL, 5 )
m_choice3Choices = []
self.m_choice3 = wx.Choice( self.loginPanel, wx.ID_ANY, wx.DefaultPosition, wx.Size( 150,-1 ), m_choice3Choices, 0 )
self.m_choice3.SetSelection( 0 )
bSizer41.Add( self.m_choice3, 0, wx.ALL, 5 )
bSizer12.Add( bSizer41, 0, wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.login = wx.Button( self.loginPanel, wx.ID_ANY, u"登 录", wx.DefaultPosition, wx.DefaultSize, 0 )
self.login.SetForegroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHTTEXT ) )
self.login.SetBackgroundColour( wx.SystemSettings.GetColour( wx.SYS_COLOUR_HIGHLIGHT ) )
bSizer12.Add( self.login, 0, wx.ALL|wx.ALIGN_CENTER_HORIZONTAL, 5 )
self.loginPanel.SetSizer( bSizer12 )
self.loginPanel.Layout()
bSizer12.Fit( self.loginPanel )
bSizer1.Add( self.loginPanel, 1, wx.EXPAND |wx.ALL, 5 )
self.SetSizer( bSizer1 )
self.Layout()
self.Centre( wx.BOTH )
# Connect Events
self.passwordtext.Bind( wx.EVT_TEXT_ENTER, self.loginFunction )
self.login.Bind( wx.EVT_BUTTON, self.loginFunction )
def __del__( self ):
pass
# Virtual event handlers, override them in your derived class
def loginFunction( self, event ):
event.Skip()
在vscode中,新建一个py文件,并把代码粘贴进去,注意之后这段代码对你来说就是一个黑盒子,除非报错,否则每次修改就从GUI里面改,改完之后再贴回来
再新建一个py文件,调用这个界面
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from asyncio.windows_events import NULL
from calendar import setfirstweekday
import wx
import loginFrame
import pymysql
class CalcFrame(loginFrame.loginFrame):
def __init__(self,parent, id=-1):
loginFrame.loginFrame.__init__(self,parent)
app = wx.App(False)
frame = CalcFrame(None)
frame.Show(True)
start the applications
app.MainLoop()
运行就可以了!
4. 数据库 MySQL
建议安装的是 mysql-installer-community-5.7.39.0.msi
链接:https://pan.baidu.com/s/14io2k-OVYWHrpI08q-fD5w
提取码:gwzo
安装过程挺麻烦的,会有各种依赖,检测完依赖之后,点击全部安装就行了
MySQL对应的GUI操作软件,很多人会选择Navicat,但是注册比较难,你懂的。。。所以我选了相对友好的SQLYog,注册码百度一大堆
链接:https://pan.baidu.com/s/1cU5g4N1k5rxGqW6_4iLevw
提取码:we9c
这基本上就是全部的技术路线了~~