-- 如果数据库已存在则删除
DROP DATABASE IF EXISTS ComputerSalesDB;

-- 创建新数据库
CREATE DATABASE ComputerSalesDB;

-- 使用新创建的数据库
USE ComputerSalesDB;

-- 1. 创建商品表
CREATE TABLE goods (
gID CHAR(6) PRIMARY KEY,
gNAME VARCHAR(10) NOT NULL,
gKIDS VARCHAR(6),
gUNIT INT,
gPRICE INT
);

-- 2. 创建供应商表
CREATE TABLE provider (
pID CHAR(6) PRIMARY KEY,
pNAME VARCHAR(10) NOT NULL,
pACC CHAR(19),
pADD VARCHAR(8)
);

-- 3. 创建仓库表
CREATE TABLE store (
sID CHAR(6) PRIMARY KEY,
sADD VARCHAR(8),
sLEAD VARCHAR(4)
);

-- 4. 创建门店表(移到assistant表之前)
CREATE TABLE shop (
shID CHAR(6) PRIMARY KEY,
shNAME VARCHAR(10) NOT NULL,
shADD VARCHAR(8)
);

-- 5. 创建营业员表
CREATE TABLE assistant (
aID CHAR(6) PRIMARY KEY,
aNAME VARCHAR(4) NOT NULL,
aFEAT INT,
shID CHAR(6),
FOREIGN KEY (shID) REFERENCES shop(shID)
);

-- 6. 创建管理员表
CREATE TABLE manager (
mID CHAR(6) PRIMARY KEY,
mNAME VARCHAR(4) NOT NULL,
mFEAT INT
);

-- 7. 创建采购员表
CREATE TABLE shopper (
shopperID CHAR(6) PRIMARY KEY,
shopperNAME VARCHAR(4) NOT NULL,
shopperFEAT INT
);

-- 8. 创建采购关系表
CREATE TABLE Buy (
bID CHAR(6),
gID CHAR(6),
shopperID CHAR(6),
bQUA CHAR(10),
bTIME DATETIME,
PRIMARY KEY(bID, gID, shopperID),
FOREIGN KEY (gID) REFERENCES goods(gID),
FOREIGN KEY (shopperID) REFERENCES shopper(shopperID)
);

-- 9. 创建进货关系表
CREATE TABLE Stock (
stockID CHAR(6),
sID CHAR(6),
shID CHAR(6),
stockQUA CHAR(10),
stockTIME DATETIME,
PRIMARY KEY(stockID, sID, shID),
FOREIGN KEY (sID) REFERENCES store(sID),
FOREIGN KEY (shID) REFERENCES shop(shID)
);

-- 10. 创建销售关系表
CREATE TABLE Sell (
sellID CHAR(6),
aID CHAR(6),
gID CHAR(6),
sellQUA CHAR(10),
sellTIME DATETIME,
PRIMARY KEY(sellID, aID, gID),
FOREIGN KEY (aID) REFERENCES assistant(aID),
FOREIGN KEY (gID) REFERENCES goods(gID)
);

-- 11. 创建配送关系表
CREATE TABLE Send (
sendID CHAR(6),
shID CHAR(6),
sendNAME VARCHAR(10),
sendQUA CHAR(10),
sendTIME DATETIME,
PRIMARY KEY(sendID, shID),
FOREIGN KEY (shID) REFERENCES shop(shID)
);

-- 12. 创建存储关系表
CREATE TABLE Storage (
sID CHAR(6),
gID CHAR(6),
storageQUA INT,
storageTIME DATETIME,
safetystorageQUA CHAR(10),
PRIMARY KEY(sID, gID),
FOREIGN KEY (sID) REFERENCES store(sID),
FOREIGN KEY (gID) REFERENCES goods(gID)
);

-- 创建索引
CREATE INDEX idx_goods_name ON goods(gNAME);
CREATE INDEX idx_shop_name ON shop(shNAME);
CREATE INDEX idx_sell_time ON Sell(sellTIME);
CREATE INDEX idx_stock_time ON Stock(stockTIME);

-- 创建触发器
DELIMITER //
CREATE TRIGGER before_sell_insert
BEFORE INSERT ON Sell
FOR EACH ROW
BEGIN
IF NOT EXISTS (SELECT 1 FROM goods WHERE gID = NEW.gID) THEN
SIGNAL SQLSTATE '45000'
SET MESSAGE_TEXT = '商品不存在';
END IF;
END//
DELIMITER ;

-- 创建视图
CREATE VIEW sales_summary AS
SELECT
g.gNAME,
COUNT(*) as total_sales,
SUM(CAST(s.sellQUA AS UNSIGNED)) as total_quantity
FROM Sell s
JOIN goods g ON s.gID = g.gID
GROUP BY g.gID, g.gNAME;

-- 创建用户和授权(如果需要)
CREATE USER 'salesadmin'@'localhost' IDENTIFIED BY 'password123';
GRANT ALL PRIVILEGES ON ComputerSalesDB.* TO 'salesadmin'@'localhost';
FLUSH PRIVILEGES;

1. 一、绪论

2. 二、系统分析

(一)用例图、分角色功能图

用例图

分角色功能图

营业员

管理员

采购员

(二)数据需求—数据流图

3. 三、系统设计

3.1.1. (一)概念结构设计-ER图系统功能模块图

er 图

商品

供应商

仓库

门店

采购员

管理员

营业员

整体

画板

(二)系统功能模块图

流程图如此下:

3.1.1.1.

3.1.2. (三)逻辑结构设计-关系模式-表

3.1.3. 电脑表(goods)

字段名 数据类型 约束 说明
商品编号 CHAR(6) 主键 gID
商品名称 VARCHAR(10) 非空 gNAME
商品类别 VARCHAR(6) gKIDS
数量单位 INT >0 gUNIT
单价 INT >=0 gPRICE

3.1.4. 供应商表(provider)

字段名 数据类型 约束 说明
供应商编号 CHAR(6) 主键 pID
供应商名称 VARCHAR(10) 非空 pNAME
供应商账户 CHAR(19) pACC
供应商地址 VARCHAR(8) pADD

3.1.5. 仓库表(store)

字段名 数据类型 约束 说明
仓库编号 CHAR(6) 主键 sID
仓库地址 VARCHAR(8) sADD
负责人 VARCHAR(4) sLEAD

3.1.6. 门店表(shop)

字段名 数据类型 约束 说明
门店编号 CHAR(6) 主键 shID
门店名称 VARCHAR(10) 非空 shNAME
门店地址 VARCHAR(8) shADD

3.1.7. 营业员表(assistant)

字段名 数据类型 约束 说明
营业员编号 CHAR(6) 主键 aID
营业员姓名 VARCHAR(4) 非空 aNAME
营业员业绩 INT aFEAT
所属门店编号 CHAR(6) 外键->门店表(门店编号) shID

3.1.8. 管理员表(manager)

字段名 数据类型 约束 说明
管理员编号 CHAR(6) 主键 mID
管理员姓名 VARCHAR(4) 非空 mNAME
管理员业绩 INT mFEAT

3.1.9. 采购员表(shopper)

字段名 数据类型 约束 说明
采购员编号 CHAR(6) 主键 shopperID
采购员姓名 VARCHAR(4) 非空 shopperNAME
采购员业绩 INT shopperFEAT

3.2. 关系表

3.2.1. 采购关系表(Buy)

字段名 数据类型 约束 说明
采购编号 CHAR(6) 主键 bID
商品编号 CHAR(6) 主键, 外键->商品表(商品编号) gID
采购员编号 CHAR(6) 主键, 外键->采购员表(采购员编号) shopperID
采购数量 CHAR(10) 非空 bQUA
采购时间 DATETIME 非空 bTIME

3.2.2. 进货关系表(Stock)

字段名 数据类型 约束 说明
进货编号 CHAR(6) 主键 stockID
仓库编号 CHAR(6) 主键, 外键->仓库表(仓库编号) sID
门店编号 CHAR(6) 主键, 外键->门店表(门店编号) shID
进货数量 CHAR(10) 非空 stockQUA
进货时间 DATETIME 非空 stockTIME

3.2.3. 销售关系表(Sell)

字段名 数据类型 约束 说明
销售编号 CHAR(6) 主键 sellID
营业员编号 CHAR(6) 主键, 外键->营业员表(营业员编号) aID
商品编号 CHAR(6) 主键, 外键->商品表(商品编号) gID
销售数量 CHAR(10) 非空 sellQUA
销售时间 DATETIME 非空 sellTIME

3.2.4. 配送关系表(Send)

字段名 数据类型 约束 说明
配送编号 CHAR(6) 主键 sendID
门店编号 CHAR(6) 主键, 外键->门店表(门店编号) shID
配送人 VARCHAR(10) sendNAME
配送数量 CHAR(10) 非空 sendQUA
配送时间 DATETIME 非空 sendTIME

3.2.5. 库存关系表(Storage)

字段名 数据类型 约束 说明
仓库编号 CHAR(6) 主键, 外键->仓库表(仓库编号) sID
商品编号 CHAR(6) 主键, 外键->商品表(商品编号) gID
库存数量 INT 非空, >=0 storageQUA
入库时间 DATETIME 非空 storageTIME
安全库存量 CHAR(10) 非空 safetystorageQUA

3.3. 四、系统实现(程序流程图,实现的界面)数据库连接

import tkinter as tk  
from tkinter import ttk, messagebox
import mysql.connector
from datetime import datetime

class LoginSystem:
def __init__(self):
self.root = tk.Tk()
self.root.title("电脑销售管理系统")
self.root.geometry("400x500")

# 数据库连接
try:
self.conn = mysql.connector.connect(
host="localhost",
user="salesadmin",
password="password123",
database="ComputerSalesDB"
)
self.cursor = self.conn.cursor()
except mysql.connector.Error as err:
messagebox.showerror("数据库连接错误", f"错误: {err}")
return

# 创建主框架
self.main_frame = ttk.Frame(self.root, padding="10")
self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))

# 用户类型选择
self.user_type = tk.StringVar(value="manager")
self.create_user_type_radio()

# 创建登录界面
self.create_login_widgets()

# 切换按钮
self.toggle_button = ttk.Button(
self.main_frame,
text="切换到注册",
command=self.toggle_login_register
)
self.toggle_button.grid(row=6, column=0, columnspan=2, pady=10)

self.is_login = True # 标记当前是登录还是注册界面

def create_user_type_radio(self):
"""创建用户类型选择单选按钮"""
type_frame = ttk.LabelFrame(self.main_frame, text="用户类型", padding="5")
type_frame.grid(row=0, column=0, columnspan=2, pady=10, sticky="ew")

ttk.Radiobutton(
type_frame,
text="管理员",
variable=self.user_type,
value="manager"
).grid(row=0, column=0, padx=5)

ttk.Radiobutton(
type_frame,
text="营业员",
variable=self.user_type,
value="assistant"
).grid(row=0, column=1, padx=5)

ttk.Radiobutton(
type_frame,
text="采购员",
variable=self.user_type,
value="shopper"
).grid(row=0, column=2, padx=5)

def create_login_widgets(self):
"""创建登录界面组件"""
# 用户ID
ttk.Label(self.main_frame, text="用户ID:").grid(row=1, column=0, pady=5)
self.id_entry = ttk.Entry(self.main_frame)
self.id_entry.grid(row=1, column=1, pady=5)

# 用户名
ttk.Label(self.main_frame, text="用户名:").grid(row=2, column=0, pady=5)
self.name_entry = ttk.Entry(self.main_frame)
self.name_entry.grid(row=2, column=1, pady=5)

# 提交按钮
self.submit_button = ttk.Button(
self.main_frame,
text="登录",
command=self.handle_submit
)
self.submit_button.grid(row=5, column=0, columnspan=2, pady=10)

def toggle_login_register(self):
"""切换登录和注册界面"""
self.is_login = not self.is_login
if self.is_login:
self.toggle_button.config(text="切换到注册")
self.submit_button.config(text="登录")
else:
self.toggle_button.config(text="切换到登录")
self.submit_button.config(text="注册")

def handle_submit(self):
"""处理登录或注册提交"""
user_id = self.id_entry.get().strip()
user_name = self.name_entry.get().strip()
user_type = self.user_type.get()

if not user_id or not user_name:
messagebox.showerror("错误", "请填写所有字段!")
return

if self.is_login:
self.handle_login(user_id, user_name, user_type)
else:
self.handle_register(user_id, user_name, user_type)

def handle_login(self, user_id, user_name, user_type):
"""处理登录逻辑"""
try:
# 根据用户类型选择对应的表
table_name = self.get_table_name(user_type)
id_field = self.get_id_field(user_type)
name_field = self.get_name_field(user_type)

# 执行登录查询
query = f"SELECT * FROM {table_name} WHERE {id_field} = %s AND {name_field} = %s"
self.cursor.execute(query, (user_id, user_name))
result = self.cursor.fetchone()

if result:
messagebox.showinfo("成功", "登录成功!")
self.open_main_window(user_type, user_id, user_name)
else:
messagebox.showerror("错误", "用户名或ID错误!")

except mysql.connector.Error as err:
messagebox.showerror("数据库错误", f"错误: {err}")

def handle_register(self, user_id, user_name, user_type):
"""处理注册逻辑"""
try:
# 根据用户类型选择对应的表
table_name = self.get_table_name(user_type)
id_field = self.get_id_field(user_type)
name_field = self.get_name_field(user_type)

# 检查用户是否已存在
check_query = f"SELECT * FROM {table_name} WHERE {id_field} = %s"
self.cursor.execute(check_query, (user_id,))
if self.cursor.fetchone():
messagebox.showerror("错误", "该ID已被注册!")
return

# 执行注册
insert_query = f"INSERT INTO {table_name} ({id_field}, {name_field}) VALUES (%s, %s)"
self.cursor.execute(insert_query, (user_id, user_name))
self.conn.commit()

messagebox.showinfo("成功", "注册成功!")

except mysql.connector.Error as err:
messagebox.showerror("数据库错误", f"错误: {err}")

def get_table_name(self, user_type):
"""获取用户类型对应的表名"""
return {
"manager": "manager",
"assistant": "assistant",
"shopper": "shopper"
}[user_type]

def get_id_field(self, user_type):
"""获取用户类型对应的ID字段名"""
return {
"manager": "mID",
"assistant": "aID",
"shopper": "shopperID"
}[user_type]

def get_name_field(self, user_type):
"""获取用户类型对应的名称字段名"""
return {
"manager": "mNAME",
"assistant": "aNAME",
"shopper": "shopperNAME"
}[user_type]

def open_main_window(self, user_type, user_id, user_name):
"""打开主窗口"""
# 创建新窗口
main_window = tk.Toplevel(self.root)
main_window.title(f"电脑销售管理系统 - {user_type}")
main_window.geometry("800x600")

# 显示欢迎信息
welcome_label = ttk.Label(
main_window,
text=f"欢迎, {user_name} ({user_id})",
font=('Helvetica', 12, 'bold')
)
welcome_label.pack(pady=20)

# 根据用户类型创建不同的功能按钮
if user_type == "manager":
self.create_manager_widgets(main_window)
elif user_type == "assistant":
self.create_assistant_widgets(main_window)
elif user_type == "shopper":
self.create_shopper_widgets(main_window)

def create_manager_widgets(self, window):
"""创建管理员界面组件"""
ttk.Button(window, text="查看销售统计", command=lambda: self.show_sales_statistics()).pack(pady=5)
ttk.Button(window, text="管理用户", command=lambda: self.manage_users()).pack(pady=5)
ttk.Button(window, text="库存管理", command=lambda: self.manage_inventory()).pack(pady=5)

def create_assistant_widgets(self, window):
"""创建营业员界面组件"""
ttk.Button(window, text="销售登记", command=lambda: self.register_sale()).pack(pady=5)
ttk.Button(window, text="查询商品", command=lambda: self.search_goods()).pack(pady=5)
ttk.Button(window, text="查看个人销售记录", command=lambda: self.view_personal_sales()).pack(pady=5)

def create_shopper_widgets(self, window):
"""创建采购员界面组件"""
ttk.Button(window, text="采购登记", command=lambda: self.register_purchase()).pack(pady=5)
ttk.Button(window, text="查看库存", command=lambda: self.view_inventory()).pack(pady=5)
ttk.Button(window, text="供应商管理", command=lambda: self.manage_providers()).pack(pady=5)

def run(self):
"""运行应用"""
self.root.mainloop()

if __name__ == "__main__":
app = LoginSystem()
app.run()

此处为语雀卡片,点击链接查看