超市进销存管理系统基于Python的Tkinter+SQLite3设计(第25节)


随着社会的发展,为了满足人们的生活需求,大街小巷出现了越来越多的综合型超市,这些超市为我们的生活提供了极大的便利。超市每天都会有数以百计的商品进进出出,库存在不断变化,销售数据每天都在增加,为了更好地管理超市,利用Python可以快速构建一个智能的进销存管理系统。

1、超市进销存管理系统介绍

Python作为目前最为流行和实用的编程语言之一,广泛应用于各类信息管理系统设计,可以帮助我们有效地存储、检索、管理和分析数据。本节教程将介绍如何使用Python的Tkinter库结合SQLite3数据库来设计一个超市进销存管理系统。其中,Python的Tkinter库提供了直观的GUI图形用户界面,而SQLite3是一个轻量级的数据库系统,适合小型应用,无需安装和配置,开箱即用。

本系统分为管理员和员工两个角色,员工账号登录系统后可以查看员工的个人信息、商品信息和采购信息;管理员账号登录系统后,有权限编辑所有的信息,包括添加、修改、删除和导出信息等功能,支持将信息列表中的数据导出到Excel文件中。注意:管理员默认账号为“admin”,密码为“admin123”。员工账号默认为员工的工号,密码为“123456”。每次添加新员工信息时,数据库会自动创建新的员工账号,新员工账号默认为新员工的工号,密码默认为“123456”。每次添加新的员工信息后,即可通过新工号登录系统,查看新员工个人的信息。

首次启动该系统时,会在当前脚本工作目录下创建一个名为“manage.db”的数据库文件,并自动在数据库文件中创建名为“users”、“employee”和“commodity”三个数据库表,用于保存账号信息、员工信息和商品信息,系统默认会向users表中插入一个管理员账号和两个员工账号信息,员工账号默认为员工的工号。系统同样默认会向employee和commodity两个表中分别插入两条完整的员工信息和商品信息,以供参考。

在信息列表中,通过右击鼠标可以删除单条信息,也可以点击界面中的“删除”按钮,删除指定信息。在信息列表中还可以通过左键双击鼠标,直接打开修改信息的页面,也可以点击界面中的“修改”按钮,修改指定信息。

2、超市进销存管理系统界面演示

超市进销存管理系统基于Python的Tkinter+SQLite3设计

超市进销存管理系统基于Python的Tkinter+SQLite3设计

超市进销存管理系统基于Python的Tkinter+SQLite3设计

超市进销存管理系统基于Python的Tkinter+SQLite3设计

超市进销存管理系统基于Python的Tkinter+SQLite3设计

3、代码实现

(1)安装pandas库

首先,确保你已经安装了pandas库。如果还没有安装,可以通过pip安装:

pip install pandas

(2)超市进销存管理系统,完整代码如下所示:

动手练一练:

import os, pandas, sqlite3, webbrowser
import tkinter as tk
from tkinter import ttk, messagebox, filedialog

# 获取当前脚本文件所在的目录
script_directory = os.path.dirname(os.path.abspath(__file__))
# 将当前脚本文件所在的目录设置为工作目录
os.chdir(script_directory)

database_file = "manage.db"  # 定义数据库文件为“manage.db”
admin_name = "admin"  # 定义管理员登录账号为“admin”
admin_password = "admin123"  # 定义管理员登录密码为“admin123”
employee_password = "123456"  # 定义员工登录密码为“123456”

# 连接到数据库(如果数据库不存在,则会自动创建)
try:
    if not os.path.exists(database_file):
        # 创建数据库连接,插入测试数据
        def create_db():
            # 使用with语句自动管理数据库连接的生命周期
            with sqlite3.connect(database_file) as conn:
                connection = conn.cursor()

                # 创建账号表,用于存储账号和密码
                connection.execute('''
                    CREATE TABLE IF NOT EXISTS users (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    username TEXT UNIQUE NOT NULL,
                    password TEXT NOT NULL,
                    category TEXT NOT NULL CHECK(category IN ('employee', 'admin'))
                )''')

                # 创建员工信息表
                connection.execute('''
                    CREATE TABLE IF NOT EXISTS employee (
                    Enumber TEXT PRIMARY KEY,
                    Ename TEXT NOT NULL,
                    Egender TEXT NOT NULL,
                    Eage TEXT NOT NULL,
                    Edepartment TEXT NOT NULL,
                    Eposition TEXT NOT NULL,
                    Emobile TEXT NOT NULL)
                ''')

                # 添加测试账号和密码,包括一个管理员账号和2个员工账号
                users_data = [
                    (admin_name, admin_password, 'admin'),
                    ('123', employee_password, 'employee'),
                    ('456', employee_password, 'employee')
                ]

                # 使用元组列表将默认的账号和密码插入users表中
                connection.executemany('INSERT INTO users (username, password, category) VALUES (?, ?, ?)', users_data)

                # 添加测试员工数据
                employee_data = [
                    ('123', '张三', '男', '25', '财务部', '会计', '123456789'),
                    ('456', '李四', '女', '30', '销售部', '理货员', '123456789')
                ]

                # 使用元组列表将默认的员工信息插入employee表中
                connection.executemany('INSERT INTO employee VALUES (?, ?, ?, ?, ?, ?, ?)', employee_data)

                # 创建商品信息表
                connection.execute('''
                    CREATE TABLE IF NOT EXISTS commodity (
                    Cnumber TEXT PRIMARY KEY,
                    Cname TEXT NOT NULL,
                    Ccategory TEXT NOT NULL,
                    Cprice TEXT NOT NULL,
                    Cspecifications TEXT NOT NULL,
                    Csupplier TEXT NOT NULL,
                    Cinventory TEXT NOT NULL)
                ''')

                # 添加测试商品数据
                commodity_data = [
                    ('1', '苹果', '水果', '5', '大', 'xx供应商', '100kg'),
                    ('2', '土豆', '蔬菜', '5', '小', 'xx供应商', '100kg')
                ]

                # 使用元组列表将默认的商品信息插入commodity表中
                connection.executemany('INSERT INTO commodity VALUES (?, ?, ?, ?, ?, ?, ?)', commodity_data)

                conn.commit()  # 提交事务以保存数据库的更改
            conn.close()   # 关闭连接
        # 执行插入数据
        create_db()
except:
    pass

# 定义成功提示框
def show_sucess(window, txt):
    add = tk.Toplevel(window)
    add.title("成功")
    screen_width, screen_height = add.maxsize()
    # 窗口的宽和高
    width = 240
    height = 100
    centre = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
                            (screen_height - height) / 2)
    add.geometry(centre)
    tk.Label(add, text=f'{txt}', font=('黑体', 14)).pack(pady=10)

    def confirmm():
        add.destroy()

    # 确定按钮
    tk.Button(add, text='确定', font=('黑体', 12), width=10, command=confirmm).pack(pady=10)

# 定义错误提示框
def show_error(window, txt):
    add = tk.Toplevel(window)
    add.title("错误")
    screen_width, screen_height = add.maxsize()
    # 窗口的宽和高
    width = 240
    height = 100
    centre = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
                            (screen_height - height) / 2)
    add.geometry(centre)
    tk.Label(add, text=f'{txt}', font=('黑体', 14)).pack(pady=10)

    def confirmm():
        add.destroy()

    # 确定按钮
    tk.Button(add, text='确定', font=('黑体', 12), width=10, command=confirmm).pack(pady=10)

# 定义信息提示框
def show_info(window, txt):
    add = tk.Toplevel(window)
    add.title("提示")
    screen_width, screen_height = add.maxsize()
    # 窗口的宽和高
    width = 500
    height = 100
    centre = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
                            (screen_height - height) / 2)
    add.geometry(centre)
    tk.Label(add, text=f'{txt}', font=('黑体', 14)).pack(pady=10)

    def confirmm():
        add.destroy()

    # 确定按钮
    tk.Button(add, text='确定', font=('黑体', 12), width=10, command=confirmm).pack(pady=10)

# 验证用户账号登录操作
def check_user(username, password):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute(
            "SELECT username, category FROM users WHERE username=? AND password=?",
            (username, password)
        )
        result = cursor.fetchone()
    conn.close()   # 关闭连接
    if result:
        return {'success': True, 'username': result[0], 'category': result[1]}
    return {'success': False, 'message': '用户名或密码错误'}

# 添加新员工信息时,自动创建新员工账号
def add_user(username, password, category):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO users (username, password, category) VALUES (?, ?, ?)",
            (username, password, category)
        )
        conn.commit()  # 提交事务以保存数据库的更改
        return True
    conn.close()   # 关闭连接

# 从数据库中获取所有的员工信息
def search_all_employee():
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM employee")
        columns = [column[0] for column in cursor.description]
        employee = [dict(zip(columns, row)) for row in cursor.fetchall()]
        conn.commit()  # 提交事务以保存数据库的更改
        return employee
    conn.close()   # 关闭连接

# 根据工号获取员工信息
def search_employee_id(employee_id):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM employee WHERE Enumber=?", (employee_id,))
        columns = [column[0] for column in cursor.description]
        employee = cursor.fetchone()
        conn.commit()  # 提交事务以保存数据库的更改
        return dict(zip(columns, employee)) if employee else None
    conn.close()   # 关闭连接

# 根据工号或者员工姓名搜索员工信息
def search_employee(keyword):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute(
            "SELECT * FROM employee WHERE Enumber LIKE ? OR Ename LIKE ?",
            (f'%{keyword}%', f'%{keyword}%')
        )
        columns = [column[0] for column in cursor.description]
        employee = [dict(zip(columns, row)) for row in cursor.fetchall()]
        return employee
    conn.close()   # 关闭连接

# 添加员工信息
def add_employee(employee_data):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO employee VALUES (?, ?, ?, ?, ?, ?, ?)",
            (
                employee_data['Enumber'],
                employee_data['Ename'],
                employee_data['Egender'],
                employee_data['Eage'],
                employee_data['Edepartment'],
                employee_data['Eposition'],
                employee_data['Emobile'],
            )
        )
        conn.commit()  # 提交事务以保存数据库的更改
        return True
    conn.close()   # 关闭连接

# 更新员工信息
def update_employee(employee_id, new_data):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        # 创建更新语句
        set_clause = []
        params = []
        for field, value in new_data.items():
            set_clause.append(f"{field}=?")
            params.append(value)
        params.append(employee_id)
        cursor.execute(
            f"UPDATE employee SET {', '.join(set_clause)} WHERE Enumber=?",
            params
        )
        conn.commit()  # 提交事务以保存数据库的更改
        return cursor.rowcount > 0
    conn.close()   # 关闭连接

# 删除员工信息,同时删除保存的登录账号
def delete_employee(employee_id):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute("DELETE FROM employee WHERE Enumber=?", (employee_id,))
        cursor.execute("DELETE FROM users WHERE username=?", (employee_id,))
        conn.commit()  # 提交事务以保存数据库的更改
        return cursor.rowcount > 0
    conn.close()   # 关闭连接

# 从数据库中获取所有的商品信息
def search_all_commodity():
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM commodity")
        columns = [column[0] for column in cursor.description]
        commodity = [dict(zip(columns, row)) for row in cursor.fetchall()]
        conn.commit()  # 提交事务以保存数据库的更改
        return commodity
    conn.close()   # 关闭连接

# 根据商品编号获取商品信息
def search_commodity_id(commodity_id):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute("SELECT * FROM commodity WHERE Cnumber=?", (commodity_id,))
        columns = [column[0] for column in cursor.description]
        commodity = cursor.fetchone()
        conn.commit()  # 提交事务以保存数据库的更改
        return dict(zip(columns, commodity)) if commodity else None
    conn.close()   # 关闭连接

# 根据商品编号或者商品名称搜索商品信息
def search_commodity(keyword):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute(
            "SELECT * FROM commodity WHERE Cnumber LIKE ? OR Cname LIKE ?",
            (f'%{keyword}%', f'%{keyword}%')
        )
        columns = [column[0] for column in cursor.description]
        commodity = [dict(zip(columns, row)) for row in cursor.fetchall()]
        return commodity
    conn.close()   # 关闭连接

# 添加商品信息
def add_commodity(commodity_data):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute(
            "INSERT INTO commodity VALUES (?, ?, ?, ?, ?, ?, ?)",
            (
                commodity_data['Cnumber'],
                commodity_data['Cname'],
                commodity_data['Ccategory'],
                commodity_data['Cprice'],
                commodity_data['Cspecifications'],
                commodity_data['Csupplier'],
                commodity_data['Cinventory'],
            )
        )
        conn.commit()  # 提交事务以保存数据库的更改
        return True
    conn.close()   # 关闭连接

# 更新商品信息
def update_commodity(commodity_id, new_data):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        # 创建更新语句
        set_clause = []
        params = []
        for field, value in new_data.items():
            set_clause.append(f"{field}=?")
            params.append(value)
        params.append(commodity_id)
        cursor.execute(
            f"UPDATE commodity SET {', '.join(set_clause)} WHERE Cnumber=?",
            params
        )
        conn.commit()  # 提交事务以保存数据库的更改
        return cursor.rowcount > 0
    conn.close()   # 关闭连接

# 删除商品信息
def delete_commodity(commodity_id):
    # 使用with语句自动管理数据库连接的生命周期
    with sqlite3.connect(database_file) as conn:
        cursor = conn.cursor()
        cursor.execute("DELETE FROM commodity WHERE Cnumber=?", (commodity_id,))
        conn.commit()  # 提交事务以保存数据库的更改
        return cursor.rowcount > 0
    conn.close()   # 关闭连接

# 定义管理类,处理数据的增、删、改、查
class ControlData:
    # 添加员工信息
    def add_employee(self, employee_data):
        # 添加新员工信息时,自动创建新员工账号
        add_user(employee_data['Enumber'], employee_password, 'employee')
        return add_employee(employee_data)
    # 获取所有员工信息
    def search_all_employee(self):
        return search_all_employee()
    # 根据工号获取员工信息
    def search_employee_id(self, employee_id):
        return search_employee_id(employee_id)
    # 根据工号或姓名搜索员工
    def search_employee(self, keyword):
        return search_employee(keyword)
    # 更新员工信息
    def update_employee(self, employee_id, new_data):
        return update_employee(employee_id, new_data)
    # 删除员工信息
    def delete_employee(self, employee_id):
        return delete_employee(employee_id)
    # 添加商品信息
    def add_commodity(self, commodity_data):
        return add_commodity(commodity_data)
    # 获取所有商品信息
    def search_all_commodity(self):
        return search_all_commodity()
    # 根据商品编号获取商品信息
    def search_commodity_id(self, commodity_id):
        return search_commodity_id(commodity_id)
    # 根据商品编号或商品名称搜索商品
    def search_commodity(self, keyword):
        return search_commodity(keyword)
    # 更新商品信息
    def update_commodity(self, commodity_id, new_data):
        return update_commodity(commodity_id, new_data)
    # 删除商品信息
    def delete_commodity(self, commodity_id):
        return delete_commodity(commodity_id)

# 定义用户账号管理类,处理用户登录和权限
class Users:
    # 验证用户登录
    def authenticate(self, username, password):
        return check_user(username, password)
    # 添加新用户
    def add_user(self, username, password, category):
        return add_user(username, password, category)

# 定义登录窗口页面
class UserLogin:
    def __init__(self, success_login):
        self.success_login = success_login
        self.user_manager = Users()

        self.app = tk.Tk()
        self.app.title("超市进销存管理系统 - 登录")

        # 设置窗口背景颜色
        self.app.config(bg='#95e8fd')

        # 设置窗口居中
        window_width = 500
        window_height = 340
        screen_width = self.app.winfo_screenwidth()
        screen_height = self.app.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        self.app.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        self.app.resizable(width=False, height=False)

        # 主界面创
        self.main_widgets()

    # 创建登录界面控件
    def main_widgets(self):
        # 鼠标点击时,清除Entry控件中的提示信息
        def on_entry_click(event):
            if event.widget.get() == '请输入用户名' or event.widget.get() == '请输入密码':
                event.widget.delete(0, tk.END)  # 删除默认文本
                event.widget.config(fg='black')  # 更改文本颜色为黑色

        # 鼠标离开时,在Entry控件中显示提示信息
        def on_focus_out(event):
            if event.widget.get() == '':
                if event.widget == self.username_entry:
                    event.widget.insert(0, '请输入用户名')
                elif event.widget == self.password_entry:
                    event.widget.insert(0, '请输入密码')
                event.widget.config(fg='gray')  # 更改文本颜色为灰色

        # 在上面放置标题
        label1 = tk.Label(self.app, text='欢迎使用', font=('宋体', 20, 'bold'), bg='#95e8fd', justify=tk.CENTER)
        label1.place(x = 60, y = 20, width = 400, height = 50)

        label2 = tk.Label(self.app, text='超市进销存管理系统', font=('宋体', 20, 'bold'), bg='#95e8fd', justify=tk.CENTER)
        label2.place(x = 50, y = 80, width = 400, height = 50)


        # 在下面设计登录窗口
        tk.Label(self.app, text="用户名:", font = ('宋体', 15), width = 15, bg='#95e8fd').place(x = 65, y = 160, anchor = 'nw')
        self.username_entry = tk.Entry(self.app, highlightthickness=1, font=('宋体', 15), bg = "white", width=20)
        self.username_entry.place(x = 190, y = 160, anchor = 'nw')
        self.username_entry.insert(0, '请输入用户名')  # 插入默认文本
        self.username_entry.config(fg='gray')  # 设置文本颜色为灰色
        self.username_entry.bind('<FocusIn>', on_entry_click)
        self.username_entry.bind('<FocusOut>', on_focus_out)

        tk.Label(self.app, text="密码:", font = ('宋体', 15), width = 15, bg='#95e8fd').place(x = 65, y = 210, anchor = 'nw')
        self.password_entry = tk.Entry(self.app, highlightthickness=1,font=('宋体', 15), bg = "white", width=20)
        self.password_entry.place(x = 190, y = 210, anchor = 'nw')
        self.password_entry.insert(0, '请输入密码')  # 插入默认文本
        self.password_entry.config(fg='gray')  # 设置文本颜色为灰色
        self.password_entry.bind('<FocusIn>', on_entry_click)
        self.password_entry.bind('<FocusOut>', on_focus_out)

        button_login = tk.Button(self.app, text="登录", font=('宋体', 15), bg="#56cdff", width=20, command=self.login)
        button_login.place(x = 150, y = 270, anchor = 'nw')

    # 检查输入的账号和密码是否正确
    def login(self):
        username = self.username_entry.get().strip()
        password = self.password_entry.get().strip()

        # 判断输入的用户名和密码不能为空
        if not username or not password:
            messagebox.showerror("错误", "用户名和密码不能为空!")
            return

        result = self.user_manager.authenticate(username, password)
        if result['success']:
            messagebox.showinfo(title="登录成功", message=f"欢迎登录超市进销存管理系统,{username}!")
            self.app.destroy()
            self.success_login(result['username'], result['category'])
        else:
            messagebox.showerror("错误", result['message'])

    # 显示登录窗口
    def run(self):
        self.app.mainloop()

# 员工登录界面,每个员工只能查看自己的个人信息、商品信息和采购信息
class EmployWindow:
    def __init__(self, username):
        self.username = username
        self.manager_control = ControlData()

        self.app = tk.Tk()
        self.app.title(f"超市进销存管理系统-{username}员工登录")

        # 设置窗口居中
        window_width = 880
        window_height = 400
        screen_width = self.app.winfo_screenwidth()
        screen_height = self.app.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        self.app.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        self.app.resizable(width=False, height=False)

        # 窗口样式配置
        self.style = ttk.Style()
        self.set_styles()

        # 简单映射
        self.employee_id = username
        self.main_widgets()

    # 定义样式函数
    def set_styles(self):
        # 设置主题为clam
        self.style.theme_use('clam')

        # 组件基础样式配置
        self.style.configure('TFrame', background='#F3F3F3')
        self.style.configure('TLabel', background='#F3F3F3',
                             foreground='#605E5C')
        self.style.configure('TEntry', fieldbackground='#FFFFFF',
                             bordercolor='#CCCCCC', relief='solid')
        self.style.configure('TButton', padding=3, relief='flat',
                             background='#0078D4',
                             font=('宋体', 12),
                             foreground='white')
        self.style.map('TButton',
                       background=[('active', '#004da3'), ('disabled', '#E0E0E0')],
                       foreground=[('disabled', '#A0A0A0')])
        self.style.configure('TLabelframe', bordercolor='#D0D0D0',
                             relief='groove', padding=10, background='#F3F3F3')
        self.style.configure('TLabelframe.Label', padding=10, foreground='#0078D4', font=('宋体', 14, 'bold'), background='#F3F3F3')

    # 创建员工界面控件
    def main_widgets(self):
        # 主框架
        main_frame = tk.Frame(self.app)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 左侧信息面板
        information_frame = ttk.LabelFrame(main_frame, text=f"{self.username}-员工个人信息")
        information_frame.pack(side=tk.LEFT, fill=tk.Y, padx=5, pady=5)

        # 获取员工信息
        employee_data = self.manager_control.search_employee_id(self.employee_id)
        if not employee_data:
            show_error(self.app, "找不到对应的员工信息!")
            self.app.destroy()
            return

        # 显示员工信息
        tk.Label(information_frame, text=f"工号: {employee_data['Enumber']}").pack(anchor=tk.W, pady=5)
        tk.Label(information_frame, text=f"姓名: {employee_data['Ename']}").pack(anchor=tk.W, pady=5)
        tk.Label(information_frame, text=f"性别: {employee_data['Egender']}").pack(anchor=tk.W, pady=5)
        tk.Label(information_frame, text=f"年龄: {employee_data['Eage']}").pack(anchor=tk.W, pady=5)
        tk.Label(information_frame, text=f"部门: {employee_data['Edepartment']}").pack(anchor=tk.W, pady=5)
        tk.Label(information_frame, text=f"职务: {employee_data['Eposition']}").pack(anchor=tk.W, pady=5)
        tk.Label(information_frame, text=f"手机号码: {employee_data['Emobile']}").pack(anchor=tk.W, pady=5)

        # 右侧功能面板
        view_frame = tk.Frame(main_frame)
        view_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True, padx=5, pady=5)

        # 员工列表区域
        employee_list_frame = ttk.LabelFrame(view_frame)
        employee_list_frame.pack(fill=tk.X, pady=10)

        # 利用Treeview控件显示员工列表
        tree = ttk.Treeview(employee_list_frame, columns=('Enumber', 'Ename', 'Egender', 'Eage', 'Edepartment', 'Eposition', 'Emobile'), show='headings')
        tree.heading('Enumber', text='工号')
        tree.heading('Ename', text='姓名')
        tree.heading('Egender', text='性别')
        tree.heading('Eage', text='年龄')
        tree.heading('Edepartment', text='部门')
        tree.heading('Eposition', text='职务')
        tree.heading('Emobile', text='手机号码')

        tree.column('Enumber', width=80, anchor="center")
        tree.column('Ename', width=80, anchor="center")
        tree.column('Egender', width=60, anchor="center")
        tree.column('Eage', width=60, anchor="center")
        tree.column('Edepartment', width=80, anchor="center")
        tree.column('Eposition', width=80, anchor="center")
        tree.column('Emobile', width=120, anchor="center")
        tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 刷新员工列表
        tree.insert('', 'end', values=(employee_data['Enumber'], 
                                       employee_data['Ename'],
                                       employee_data['Egender'],
                                       employee_data['Eage'],
                                       employee_data['Edepartment'],
                                       employee_data['Eposition'],
                                       employee_data['Emobile']))

        # 创建滚动条控件
        scrollbar = ttk.Scrollbar(employee_list_frame, orient=tk.VERTICAL)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.config(command=tree.yview)

        # 功能按钮
        button_frame = ttk.Frame(view_frame)
        button_frame.pack(fill=tk.X, pady=10)

        ttk.Button(button_frame, text="查看商品信息", command=self.commodity_widgets).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="查看采购信息", command=lambda:show_info(self.app, "请自行添加代码,更多教程请进入www.pyhint.com学习")).pack(side=tk.LEFT, padx=5)
        ttk.Button(button_frame, text="退出系统", command=self.app.destroy).pack(side=tk.LEFT, padx=5)

    # 创建商品信息显示页面
    def commodity_widgets(self):
        # 主框架
        self.commodity_window = tk.Toplevel(self.app)
        self.commodity_window.title('商品信息')

        # 设置窗口居中
        window_width = 700
        window_height = 630
        screen_width = self.commodity_window.winfo_screenwidth()
        screen_height = self.commodity_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        self.commodity_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        self.commodity_window.resizable(width=False, height=False)

        commodity_frame = ttk.Frame(self.commodity_window)
        commodity_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 顶部标题框架
        top_frame = tk.Frame(commodity_frame, padx=10, pady=5)
        top_frame.pack(fill=tk.X, padx=5, pady=5)
        top_Label = tk.Label(top_frame, text="商品信息管理", font=("宋体", 20), width=30)
        top_Label.pack(fill=tk.X, expand=True)

        # 商品信息列表面板
        list_frame = ttk.LabelFrame(commodity_frame, text="所有商品信息列表")
        list_frame.pack(fill=tk.X, padx=5, pady=5)

        # 搜索框架
        search_frame = ttk.Frame(list_frame)
        search_frame.pack(fill=tk.X, pady=10)

        self.search_commodity_entry = ttk.Entry(search_frame)
        self.search_commodity_entry.pack(side=tk.LEFT)
        ttk.Button(search_frame, text="搜索", command=self.search_commodity).pack(side=tk.LEFT, padx=5)

        # 创建“汇总”信息,显示商品信息的数量
        self.count = tk.Text(search_frame, relief=tk.FLAT, bg='#f0f0f0', font=10, width=2, height=1)
        self.count.pack(side=tk.RIGHT)
        total_label = tk.Label(search_frame, text='汇总:', font=10)
        total_label.pack(side=tk.RIGHT)

        # 利用Treeview控件显示商品列表
        self.list_tree = ttk.Treeview(list_frame, columns=('Cnumber', 'Cname', 'Ccategory', 'Cprice', 'Cspecifications', 'Csupplier', 'Cinventory'), show='headings')
        self.list_tree.heading('Cnumber', text='商品编号')
        self.list_tree.heading('Cname', text='商品名称')
        self.list_tree.heading('Ccategory', text='类别')
        self.list_tree.heading('Cprice', text='单价')
        self.list_tree.heading('Cspecifications', text='商品规格')
        self.list_tree.heading('Csupplier', text='供应商')
        self.list_tree.heading('Cinventory', text='库存')

        self.list_tree.column('Cnumber', width=80, anchor="center")
        self.list_tree.column('Cname', width=80, anchor="center")
        self.list_tree.column('Ccategory', width=80, anchor="center")
        self.list_tree.column('Cprice', width=80, anchor="center")
        self.list_tree.column('Cspecifications', width=80, anchor="center")
        self.list_tree.column('Csupplier', width=120, anchor="center")
        self.list_tree.column('Cinventory', width=80, anchor="center")
        self.list_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 创建滚动条控件
        scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.list_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.list_tree.yview)

        # 刷新商品列表
        self.refresh_commodity()

        # 商品详细信息
        detail_frame = ttk.LabelFrame(commodity_frame, text="商品详细信息")
        detail_frame.pack(fill=tk.X, pady=5)

        self.detail_text = tk.Text(detail_frame, width=20, height=8)
        self.detail_text.pack(fill=tk.BOTH, expand=True)

        # 关闭窗口框架
        help_frame = ttk.Frame(commodity_frame)
        help_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=10)

        ttk.Button(help_frame, text="关闭商品信息窗口", command=self.commodity_window.destroy).pack(side=tk.LEFT, padx=5)

        # 当鼠标或键盘操作选中商品列表中的某一行时,会触发该事件对应的处理函数
        self.list_tree.bind('<<TreeviewSelect>>', self.on_commodity_selected)

    # 刷新商品列表
    def refresh_commodity(self):
        # 清空当前列表
        for item in self.list_tree.get_children():
            self.list_tree.delete(item)

        # 添加商品数据
        commodity_data = self.manager_control.search_all_commodity()
        for commodity in commodity_data:
            self.list_tree.insert('', 'end', values=(
                commodity['Cnumber'],
                commodity['Cname'],
                commodity['Ccategory'],
                commodity['Cprice'],
                commodity['Cspecifications'],
                commodity['Csupplier'],
                commodity['Cinventory'],
            ))
        # “汇总”统计输出
        self.count.delete(1.0, tk.END)
        self.count.insert(tk.END, len(self.list_tree.get_children()))

    # 搜索商品
    def search_commodity(self):
        keyword = self.search_commodity_entry.get().strip()
        if not keyword:
            # 刷新商品列表
            self.refresh_commodity()
            return

        # 清空当前列表
        for item in self.list_tree.get_children():
            self.list_tree.delete(item)

        # 添加搜索结果
        commodity_data = self.manager_control.search_commodity(keyword)
        for commodity in commodity_data:
            self.list_tree.insert('', 'end', values=(
                commodity['Cnumber'],
                commodity['Cname'],
                commodity['Ccategory'],
                commodity['Cprice'],
                commodity['Cspecifications'],
                commodity['Csupplier'],
                commodity['Cinventory'],
            ))

        # “汇总”统计输出
        self.count.delete(1.0, tk.END)
        self.count.insert(tk.END, len(self.list_tree.get_children()))

    # 鼠标选择商品时显示该商品详细信息
    def on_commodity_selected(self, event):
        selected_item = self.list_tree.selection()
        if not selected_item:
            return

        commodity_id = self.list_tree.item(selected_item)['values'][0]
        commodity = self.manager_control.search_commodity_id(commodity_id)

        if commodity:
            information = f"商品编号: {commodity['Cnumber']}\n"
            information += f"商品名称: {commodity['Cname']}\n"
            information += f"类别: {commodity['Ccategory']}\n"
            information += f"单价: {commodity['Cprice']}\n"
            information += f"商品规格: {commodity['Cspecifications']}\n"
            information += f"供应商: {commodity['Csupplier']}\n"
            information += f"库存: {commodity['Cinventory']}"

            self.detail_text.delete(1.0, tk.END)
            self.detail_text.insert(tk.END, information)

    # 显示员工窗口
    def run(self):
        self.app.mainloop()

# 创建管理员界面,管理员账号可以管理所有信息包括员工信息和商品信息等
class AdminWindow:
    def __init__(self, username):
        self.username = username
        self.manager_control = ControlData()

        self.app = tk.Tk()
        self.app.title(f"超市进销存管理系统(管理员)-{username}管理员登录")

        # 设置窗口居中
        window_width = 830
        window_height = 520
        screen_width = self.app.winfo_screenwidth()
        screen_height = self.app.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        self.app.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        self.app.resizable(width=False, height=False)

        # 窗口样式配置
        self.style = ttk.Style()
        self.set_styles()

        # 主界面创建
        self.ManagerPage()
        # 将窗口关闭事件与confirm_close函数关联
        self.app.protocol("WM_DELETE_WINDOW", self.confirm_close)

    # 点击关闭窗口触发函数
    def confirm_close(self):
        if messagebox.askokcancel("退出", "你确定要退出吗?"):  # 弹出确认对话框
            self.app.destroy()  # 点击确定后关闭窗口

    # 定义样式函数
    def set_styles(self):
        # 设置主题为clam
        self.style.theme_use('clam')

        # 组件基础样式配置
        self.style.configure('TFrame', background='#F3F3F3')
        self.style.configure('TLabel', background='#F3F3F3',
                             foreground='#605E5C')
        self.style.configure('TEntry', fieldbackground='#FFFFFF',
                             bordercolor='#CCCCCC', relief='solid')
        self.style.configure('TButton', padding=3, relief='flat',
                             background='#0078D4',
                             font=('宋体', 12),
                             foreground='white')
        self.style.map('TButton',
                       background=[('active', '#004da3'), ('disabled', '#E0E0E0')],
                       foreground=[('disabled', '#A0A0A0')])
        self.style.configure('TLabelframe', bordercolor='#D0D0D0',
                             relief='groove', padding=10, background='#F3F3F3')
        self.style.configure('TLabelframe.Label', padding=10, foreground='#0078D4', font=('宋体', 14, 'bold'), background='#F3F3F3')

    def ManagerPage(self):
        # 添加商品操作按钮控件,用于修改或显示商品信息
        Button1_Add = tk.Button(self.app, text = '员工信息', bg = '#56cdff', font = ('黑体', 15), command = self.employee, width = 20)
        Button1_Add.place(x = 40, y = 30, anchor = 'nw')
        Button2_Del = tk.Button(self.app, text = '商品信息', bg = '#56cdff', font = ('黑体', 15), command = self.commodity, width = 20)
        Button2_Del.place(x = 40, y = 90, anchor = 'nw')
        Button3_Mod = tk.Button(self.app, text = '采购信息', bg = '#56cdff', font = ('黑体', 15), command = self.buy, width = 20)
        Button3_Mod.place(x = 40, y = 150, anchor = 'nw')
        Button4_Ser = tk.Button(self.app, text = '供应商信息', bg = '#56cdff', font = ('黑体', 15), command = self.supplier, width = 20)
        Button4_Ser.place(x = 40, y = 210, anchor = 'nw')
        Button5_Show = tk.Button(self.app, text = '会员信息', bg = '#56cdff', font = ('黑体', 15), command = self.member, width = 20)
        Button5_Show.place(x = 40, y = 270, anchor = 'nw')
        Button6_Exit = tk.Button(self.app, text = '关于程序', bg = '#56cdff', font = ('黑体', 15), command = self.index_about, width = 20)
        Button6_Exit.place(x = 40, y = 330, anchor = 'nw')
        Button6_Exit = tk.Button(self.app, text = '本程序讲解', bg = '#56cdff', font = ('黑体', 15), command = help_window, width = 20)
        Button6_Exit.place(x = 40, y = 390, anchor = 'nw')
        Button6_Exit = tk.Button(self.app, text = '退出', bg = '#56cdff', font = ('黑体', 15), command = self.index_quit, width = 20)
        Button6_Exit.place(x = 40, y = 450, anchor = 'nw')

        # 创建一个Text控件,用于输出程序说明信息
        txt = '''                 
                >>>欢迎使用超市进销存管理系统<<<
            说明:本程序是一个基于Python开发的超市进销存管理系统。
            使用了Python的Tkinter库构建GUI图形用户界面,并结合SQLite3库进行数据存储。
            运行该程序时,默认会在当前工作目录下创建一个名为“manage.db”的数据库文件,用于存储所有信息。
            支持查询、添加、修改、删除信息,并且支持将数据列表导出到Excel文件中。
            管理员账号在员工信息页面或商品信息页面,鼠标双击任意一行,即可实现编辑信息的功能,鼠标右键点击任意一行,会显示“删除”按钮。
            '''
        Show_result = tk.Text(self.app, spacing1=2, spacing2=2, spacing3=2, wrap='word', font=10, width=40, height=10)
        Show_result.place(x = "280", y = "30", width = "500", height = "456")
        Show_result.insert(tk.END, txt)

    def employee(self): # 员工信息
        self.admin_employee()

    def commodity(self): # 商品信息
        self.admin_commodity()

    def buy(self): # 采购信息
        show_info(self.app, "请自行添加代码,更多教程请进入www.pyhint.com学习")

    def supplier(self):# 供应商信息
        show_info(self.app, "请自行添加代码,更多教程请进入www.pyhint.com学习")

    def member(self): # 会员信息
        show_info(self.app, "请自行添加代码,更多教程请进入www.pyhint.com学习")

    # 关于本程序
    def index_about(self):
        program_about()

    # 退出-销毁界面
    def index_quit(self):
        self.app.destroy()

    # 创建员工信息管理控件
    def admin_employee(self):
        self.admin_employee_window = tk.Toplevel(self.app)
        self.admin_employee_window.title('员工信息管理')

        # 设置窗口居中
        window_width = 800
        window_height = 660
        screen_width = self.admin_employee_window.winfo_screenwidth()
        screen_height = self.admin_employee_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        self.admin_employee_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        self.admin_employee_window.resizable(width=False, height=False)

        # 主框架
        main_frame = tk.Frame(self.admin_employee_window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 顶部标题框架
        top_frame = tk.Frame(main_frame, padx=10, pady=5)
        top_frame.pack(fill=tk.X, padx=5, pady=5)
        top_Label = tk.Label(top_frame, text="员工信息管理", font=("宋体", 20), width=30)
        top_Label.pack(fill=tk.X, expand=True)

        # 员工信息列表面板
        list_frame = ttk.LabelFrame(main_frame, text="所有员工信息列表")
        list_frame.pack(fill=tk.X, padx=5, pady=5)

        # 搜索框架
        search_frame = ttk.Frame(list_frame)
        search_frame.pack(fill=tk.X, pady=10)

        self.search_employee_entry = ttk.Entry(search_frame)
        self.search_employee_entry.pack(side=tk.LEFT)
        ttk.Button(search_frame, text="搜索", command=self.search_employee).pack(side=tk.LEFT, padx=5)

        # 创建“汇总”信息,显示员工信息的数量
        self.employee_count = tk.Text(search_frame, relief=tk.FLAT, bg='#f0f0f0', font=10, width=2, height=1)
        self.employee_count.pack(side=tk.RIGHT)
        total_label = tk.Label(search_frame, text='汇总:', font=10)
        total_label.pack(side=tk.RIGHT)

        # 利用Treeview控件显示员工列表
        self.employee_tree = ttk.Treeview(list_frame, columns=('Enumber', 'Ename', 'Egender', 'Eage', 'Edepartment', 'Eposition', 'Emobile'), show='headings')
        self.employee_tree.heading('Enumber', text='工号')
        self.employee_tree.heading('Ename', text='姓名')
        self.employee_tree.heading('Egender', text='性别')
        self.employee_tree.heading('Eage', text='年龄')
        self.employee_tree.heading('Edepartment', text='部门')
        self.employee_tree.heading('Eposition', text='职务')
        self.employee_tree.heading('Emobile', text='手机号码')

        self.employee_tree.column('Enumber', width=80, anchor="center")
        self.employee_tree.column('Ename', width=80, anchor="center")
        self.employee_tree.column('Egender', width=60, anchor="center")
        self.employee_tree.column('Eage', width=60, anchor="center")
        self.employee_tree.column('Edepartment', width=80, anchor="center")
        self.employee_tree.column('Eposition', width=80, anchor="center")
        self.employee_tree.column('Emobile', width=120, anchor="center")
        self.employee_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 刷新员工列表
        self.refresh_employee()

        # 创建滚动条控件
        scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.employee_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.employee_tree.yview)

        # 当鼠标或键盘操作选中员工列表中的某一行时,会触发该事件对应的处理函数
        self.employee_tree.bind('<<TreeviewSelect>>', self.on_employee_selected)

        # 鼠标双击员工信息列表任意一行,可以触发修改员工信息页面
        def on_double_click(event):
            # 获取被双击的项的IID
            iid = self.employee_tree.focus()
            if iid == '':
                return  # 如果没有选中任何一行,则直接返回

            # 选中指定的行
            self.employee_tree.selection_set((iid,))
            self.edit_employee()

        # 绑定鼠标双击事件
        self.employee_tree.bind("<Double-1>", on_double_click)

        # 鼠标右键点击员工信息列表任意一行,就会显示“删除该员工”按钮
        def on_right_click(event):
            # 获取当前焦点项的iid
            iid = self.employee_tree.focus()
            # 选中指定的行
            self.employee_tree.selection_set((iid,))

            if iid:
                # 弹出菜单选项
                menu = tk.Menu(self.employee_tree, tearoff=0)
                menu.add_command(label="删除该员工", command=self.delete_employee)
                menu.tk_popup(event.x_root, event.y_root)

        # 绑定鼠标右键点击事件
        self.employee_tree.bind("<Button-3>", on_right_click)

        # 员工操作按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=5)

        ttk.Button(button_frame, text="显示所有员工信息", command=self.refresh_employee).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="添加员工", command=self.add_employee).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="修改员工", command=self.edit_employee).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="删除员工", command=self.delete_employee).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="导出以上员工信息", command=self.export_employee).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="关闭窗口", command=self.admin_employee_window.destroy).pack(side=tk.LEFT, padx=6)

        # 员工信息面板
        information_frame = ttk.Frame(main_frame)
        information_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 员工详细信息
        detail_frame = ttk.LabelFrame(information_frame, text="员工详细信息")
        detail_frame.pack(fill=tk.X, pady=5)

        self.detail_text = tk.Text(detail_frame, width=20, height=8)
        self.detail_text.pack(fill=tk.BOTH, expand=True)

        # 关于程序讲解
        help_frame = ttk.Frame(information_frame)
        help_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=5)

        ttk.Button(help_frame, text="关于本程序", command=program_about).pack(side=tk.LEFT, padx=6)
        ttk.Button(help_frame, text="本程序讲解", command=help_window).pack(side=tk.LEFT, padx=6)

        self.admin_employee_window.mainloop()

    # 刷新员工列表
    def refresh_employee(self):
        # 清空当前列表
        for item in self.employee_tree.get_children():
            self.employee_tree.delete(item)

        # 添加员工数据
        employee_data = self.manager_control.search_all_employee()
        for employee in employee_data:
            self.employee_tree.insert('', 'end', values=(
                employee['Enumber'],
                employee['Ename'],
                employee['Egender'],
                employee['Eage'],
                employee['Edepartment'],
                employee['Eposition'],
                employee['Emobile'],
            ))
        # “汇总”统计输出
        self.employee_count.delete(1.0, tk.END)
        self.employee_count.insert(tk.END, len(self.employee_tree.get_children()))

    # 搜索员工
    def search_employee(self):
        keyword = self.search_employee_entry.get().strip()
        if not keyword:
            # 刷新员工列表
            self.refresh_employee()
            return

        # 清空当前列表
        for item in self.employee_tree.get_children():
            self.employee_tree.delete(item)

        # 添加搜索结果
        employee_data = self.manager_control.search_employee(keyword)
        for employee in employee_data:
            self.employee_tree.insert('', 'end', values=(
                employee['Enumber'],
                employee['Ename'],
                employee['Egender'],
                employee['Eage'],
                employee['Edepartment'],
                employee['Eposition'],
                employee['Emobile'],
            ))

        # “汇总”统计输出
        self.employee_count.delete(1.0, tk.END)
        self.employee_count.insert(tk.END, len(self.employee_tree.get_children()))

    # 鼠标选择员工时显示该员工详细信息
    def on_employee_selected(self, event):
        selected_item = self.employee_tree.selection()
        if not selected_item:
            return

        employee_id = self.employee_tree.item(selected_item)['values'][0]
        employee = self.manager_control.search_employee_id(employee_id)

        if employee:
            information = f"工号: {employee['Enumber']}\n"
            information += f"姓名: {employee['Ename']}\n"
            information += f"性别: {employee['Egender']}\n"
            information += f"年龄: {employee['Eage']}\n"
            information += f"部门: {employee['Edepartment']}\n"
            information += f"职务: {employee['Eposition']}\n"
            information += f"手机号码: {employee['Emobile']}"

            self.detail_text.delete(1.0, tk.END)
            self.detail_text.insert(tk.END, information)

    # 添加员工方法
    def add_employee(self):
        add_window = tk.Toplevel(self.admin_employee_window)
        add_window.title("添加员工")

        # 设置窗口居中
        window_width = 500
        window_height = 520
        screen_width = add_window.winfo_screenwidth()
        screen_height = add_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        add_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        add_window.resizable(width=False, height=False)

        # 创建标题标签控件
        Show_result = tk.Label(add_window, text=">>>添加员工信息<<<", bg = "white", fg = "black", font = ("宋体", 18), bd = '0', anchor = 'center')
        Show_result.place(x = 50, y = 30, width = 400, height = 50)

        # 工号
        tk.Label(add_window, text="工号(不可重复):", font = ('宋体', 12), width = 15).place(x = 75, y = 100, anchor = 'nw')
        id_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        id_entry.place(x = 210, y = 100, anchor = 'nw')

        # 姓名
        tk.Label(add_window, text="姓名:", font = ('宋体', 12), width = 15).place(x = 75, y = 150, anchor = 'nw')
        name_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        name_entry.place(x = 210, y = 150, anchor = 'nw')

        # 性别
        tk.Label(add_window, text="性别:", font = ('宋体', 12), width = 15).place(x = 75, y = 200, anchor = 'nw')
        Egender_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Egender_entry.place(x = 210, y = 200, anchor = 'nw')

        # 年龄
        tk.Label(add_window, text="年龄:", font = ('宋体', 12), width = 15).place(x = 75, y = 250, anchor = 'nw')
        Eage_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Eage_entry.place(x = 210, y = 250, anchor = 'nw')

        # 部门
        tk.Label(add_window, text="部门:", font = ('宋体', 12), width = 15).place(x = 75, y = 300, anchor = 'nw')
        Edepartment_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Edepartment_entry.place(x = 210, y = 300, anchor = 'nw')

        # 职务
        tk.Label(add_window, text="职务:", font = ('宋体', 12), width = 15).place(x = 75, y = 350, anchor = 'nw')
        Eposition_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Eposition_entry.place(x = 210, y = 350, anchor = 'nw')

        # 手机号码
        tk.Label(add_window, text="手机号码:", font = ('宋体', 12), width = 15).place(x = 75, y = 400, anchor = 'nw')
        Emobile_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Emobile_entry.place(x = 210, y = 400, anchor = 'nw')

        # 保存员工信息
        def save_employee():
            employee_data = {
                'Enumber': id_entry.get(),
                'Ename': name_entry.get(),
                'Egender': Egender_entry.get(),
                'Eage': Eage_entry.get(),
                'Edepartment': Edepartment_entry.get(),
                'Eposition': Eposition_entry.get(),
                'Emobile': Emobile_entry.get()
            }
            # 从字典中获取所有的值到列表中
            employee_list = list(employee_data.values())
            # 检查每个输入框是否为空
            for result in employee_list:
                if not result:
                    show_error(self.app, "输入的内容不能为空!")
                    return
            id = str(id_entry.get())
            data = search_employee_id(id)
            if not data:
                self.manager_control.add_employee(employee_data)
                show_sucess(self.app, "添加成功!")
                add_window.destroy()
                # 刷新员工列表
                self.refresh_employee()
            else:
                show_error(self.app, "工号已存在!")

        # 定义“保存”按钮
        save_button = ttk.Button(add_window, text="保存", command=save_employee, width=15)
        save_button.place(x = 105, y = 450, anchor = 'nw')

        # 定义“取消”按钮
        cancel_button = ttk.Button(add_window, text="取消", command=add_window.destroy, width=15)
        cancel_button.place(x = 280, y = 450, anchor = 'nw')

    # 修改员工信息
    def edit_employee(self):
        selected_item = self.employee_tree.selection()
        if not selected_item:
            show_error(self.app, "请先选择一个员工!")
            return
        employee_id = self.employee_tree.item(selected_item)['values'][0]
        employee = self.manager_control.search_employee_id(employee_id)
        if not employee:
            show_error(self.app, "找不到该员工!")
            return

        modify_window = tk.Toplevel(self.admin_employee_window)
        modify_window.title("修改员工信息")

        # 设置窗口居中
        window_width = 500
        window_height = 520
        screen_width = modify_window.winfo_screenwidth()
        screen_height = modify_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        modify_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        modify_window.resizable(width=False, height=False)

        # 创建标题标签控件
        Show_result = tk.Label(modify_window, text=">>>修改员工信息<<<", bg = "white", fg = "black", font = ("宋体", 18), bd = '0', anchor = 'center')
        Show_result.place(x = 50, y = 30, width = 400, height = 50)

        # 工号(不可编辑)
        tk.Label(modify_window, text="工号(不可修改):", font = ('宋体', 12), width = 15).place(x = 75, y = 100, anchor = 'nw')
        Employ_ID = tk.StringVar()
        Employ_ID.set(employee['Enumber'])
        number_entry = tk.Entry(modify_window, show = None, font = ('宋体', 15), textvariable = Employ_ID, width = 20)
        number_entry.place(x = 210, y = 100, anchor = 'nw')

        # 设置默认值为相应的工号,工号不可改变
        def on_key_release(event):
            if event.widget.get():
                event.widget.delete(0, tk.END)
                event.widget.insert(0, employee['Enumber'])

        # 使用bind绑定函数,当用户释放任意按键时,绑定的回调函数会被触发。
        number_entry.bind('<KeyRelease>', on_key_release)

        # 姓名
        tk.Label(modify_window, text="姓名:", font = ('宋体', 12), width = 15).place(x = 75, y = 150, anchor = 'nw')
        name_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        name_entry.insert(0, employee['Ename'])
        name_entry.place(x = 210, y = 150, anchor = 'nw')

        # 性别
        tk.Label(modify_window, text="性别:", font = ('宋体', 12), width = 15).place(x = 75, y = 200, anchor = 'nw')
        Egender_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Egender_entry.insert(0, employee['Egender'])
        Egender_entry.place(x = 210, y = 200, anchor = 'nw')

        # 年龄
        tk.Label(modify_window, text="年龄:", font = ('宋体', 12), width = 15).place(x = 75, y = 250, anchor = 'nw')
        Eage_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Eage_entry.insert(0, employee['Eage'])
        Eage_entry.place(x = 210, y = 250, anchor = 'nw')

        # 部门
        tk.Label(modify_window, text="部门:", font = ('宋体', 12), width = 15).place(x = 75, y = 300, anchor = 'nw')
        Edepartment_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Edepartment_entry.insert(0, employee['Edepartment'])
        Edepartment_entry.place(x = 210, y = 300, anchor = 'nw')

        # 职务
        tk.Label(modify_window, text="职务:", font = ('宋体', 12), width = 15).place(x = 75, y = 350, anchor = 'nw')
        Eposition_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Eposition_entry.insert(0, employee['Eposition'])
        Eposition_entry.place(x = 210, y = 350, anchor = 'nw')

        # 手机号码
        tk.Label(modify_window, text="手机号码:", font = ('宋体', 12), width = 15).place(x = 75, y = 400, anchor = 'nw')
        Emobile_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Emobile_entry.insert(0, employee['Emobile'])
        Emobile_entry.place(x = 210, y = 400, anchor = 'nw')

        # 更新员工信息
        def update_employee():
            new_data = {
                'Ename': name_entry.get(),
                'Egender':Egender_entry.get(),
                'Eage':Eage_entry.get(),
                'Edepartment':Edepartment_entry.get(),
                'Eposition':Eposition_entry.get(),
                'Emobile':Emobile_entry.get()
            }

            # 从字典中获取所有的值到列表中
            employee_list = list(new_data.values())
            # 检查每个输入框是否为空
            for result in employee_list:
                if not result:
                    show_error(self.app, "输入的内容不能为空!")
                    return
            if self.manager_control.update_employee(employee['Enumber'], new_data):
                show_sucess(self.app, "员工信息更新成功!")
                modify_window.destroy()
                # 刷新员工列表
                self.refresh_employee()
                self.on_employee_selected(None)
            else:
                show_error(self.app, "更新失败!")

        # 保存按钮
        save_button = ttk.Button(modify_window, text="保存", command=update_employee, width=15)
        save_button.place(x = 105, y = 450, anchor = 'nw')

        # 取消按钮
        cancel_button = ttk.Button(modify_window, text="取消", command=modify_window.destroy, width=15)
        cancel_button.place(x = 280, y = 450, anchor = 'nw')

    # 删除员工
    def delete_employee(self):
        selected_item = self.employee_tree.selection()
        if not selected_item:
            show_error(self.app, "请先选择一个员工!")
            return

        employee_id = self.employee_tree.item(selected_item)['values'][0]
        employee_name = self.employee_tree.item(selected_item)['values'][1]

        add = tk.Toplevel(self.app)
        add.title("确认")
        screen_width, screen_height = add.maxsize()
        # 窗口的宽和高
        width = 240
        height = 150
        centre = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
                                (screen_height - height) / 2)
        add.geometry(centre)
        tk.Label(add, text="确定要删除该员工吗?", font=('黑体', 14)).place(x=20, y=15)
        tk.Label(add, text=f"“{employee_name}”", font=('黑体', 14)).place(x=70, y=50)

        def confirmm():
            if self.manager_control.delete_employee(employee_id):
                show_sucess(self.app,"员工删除成功!")
                # 刷新员工列表
                self.refresh_employee()
                self.detail_text.delete(1.0, tk.END)
                add.destroy()
            else:
                show_error(self.app, "删除失败!")

        def cancel():
            add.destroy()

        # 确定按钮
        tk.Button(add, text='确定', font=('黑体', 12), width=10, command=confirmm).place(x=20, y=100)

        # 取消按钮
        tk.Button(add, text='取消', font=('黑体', 12), width=10, command=cancel).place(x=130, y=100)

    # 获取当前项的所有列值组成的元组
    def all_employee_rows(self):
            rows = []
            for item in self.employee_tree.get_children():
                row = self.employee_tree.item(item, 'values')
                rows.append(row)
            return rows

    # 导出员工信息到指定Excel表格
    def export_employee(self):
        export_result = self.all_employee_rows()
        if not any(len(employee_list[0]) > 0 for employee_list in export_result):
            show_error(self.app, "没有数据可导出")
            return
        try:
            # 自定义列名
            columns = ['工号', '姓名', '性别', '年龄', '部门', '职务', '手机号码']
            # 将数据转换为DataFrame
            df = pandas.DataFrame(export_result, columns=columns)
            save_path = filedialog.asksaveasfilename(
                defaultextension=".xlsx",
                filetypes=[("Excel文件", "*.xlsx")])
            if save_path:
                df.to_excel(save_path, index=False)
                show_sucess(self.app, "导出成功!")
        except PermissionError:
            show_error(self.app, "Excel文件被占用,请关闭文件后重试")
        except Exception as e:
            show_error(self.app, f"导出失败:{str(e)}")

    # 创建商品信息管理控件
    def admin_commodity(self):
        self.admin_commodity_window = tk.Toplevel(self.app)
        self.admin_commodity_window.title('商品信息管理')

        # 设置窗口居中
        window_width = 800
        window_height = 660
        screen_width = self.admin_commodity_window.winfo_screenwidth()
        screen_height = self.admin_commodity_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        self.admin_commodity_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        self.admin_commodity_window.resizable(width=False, height=False)

        # 主框架
        main_frame = tk.Frame(self.admin_commodity_window)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)

        # 顶部标题框架
        top_frame = tk.Frame(main_frame, padx=10, pady=5)
        top_frame.pack(fill=tk.X, padx=5, pady=5)
        top_Label = tk.Label(top_frame, text="商品信息管理", font=("宋体", 20), width=30)
        top_Label.pack(fill=tk.X, expand=True)

        # 商品信息列表面板
        list_frame = ttk.LabelFrame(main_frame, text="所有商品信息列表")
        list_frame.pack(fill=tk.X, padx=5, pady=5)

        # 搜索框架
        search_frame = ttk.Frame(list_frame)
        search_frame.pack(fill=tk.X, pady=10)

        self.search_commodity_entry = ttk.Entry(search_frame)
        self.search_commodity_entry.pack(side=tk.LEFT)
        ttk.Button(search_frame, text="搜索", command=self.search_commodity).pack(side=tk.LEFT, padx=5)

        # 创建“汇总”信息,显示商品信息的数量
        self.commodity_count = tk.Text(search_frame, relief=tk.FLAT, bg='#f0f0f0', font=10, width=2, height=1)
        self.commodity_count.pack(side=tk.RIGHT)
        total_label = tk.Label(search_frame, text='汇总:', font=10)
        total_label.pack(side=tk.RIGHT)

        # 利用Treeview控件显示商品列表
        self.commodity_tree = ttk.Treeview(list_frame, columns=('Cnumber', 'Cname', 'Ccategory', 'Cprice', 'Cspecifications', 'Csupplier', 'Cinventory'), show='headings')
        self.commodity_tree.heading('Cnumber', text='商品编号')
        self.commodity_tree.heading('Cname', text='商品名称')
        self.commodity_tree.heading('Ccategory', text='类别')
        self.commodity_tree.heading('Cprice', text='单价')
        self.commodity_tree.heading('Cspecifications', text='商品规格')
        self.commodity_tree.heading('Csupplier', text='供应商')
        self.commodity_tree.heading('Cinventory', text='库存')

        self.commodity_tree.column('Cnumber', width=80, anchor="center")
        self.commodity_tree.column('Cname', width=80, anchor="center")
        self.commodity_tree.column('Ccategory', width=80, anchor="center")
        self.commodity_tree.column('Cprice', width=80, anchor="center")
        self.commodity_tree.column('Cspecifications', width=80, anchor="center")
        self.commodity_tree.column('Csupplier', width=120, anchor="center")
        self.commodity_tree.column('Cinventory', width=80, anchor="center")
        self.commodity_tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)

        # 刷新商品列表
        self.refresh_commodity()

        # 创建滚动条控件
        scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL)
        scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
        self.commodity_tree.configure(yscrollcommand=scrollbar.set)
        scrollbar.config(command=self.commodity_tree.yview)

        # 当鼠标或键盘操作选中商品列表中的某一行时,会触发该事件对应的处理函数
        self.commodity_tree.bind('<<TreeviewSelect>>', self.on_commodity_selected)

        # 鼠标双击商品信息列表任意一行,可以触发修改商品信息页面
        def on_double_click(event):
            # 获取被双击的项的IID
            iid = self.commodity_tree.focus()
            if iid == '':
                return  # 如果没有选中任何一行,则直接返回

            # 选中指定的行
            self.commodity_tree.selection_set((iid,))
            self.edit_commodity()

        # 绑定鼠标双击事件
        self.commodity_tree.bind("<Double-1>", on_double_click)

        # 鼠标右键点击商品信息列表任意一行,就会显示“删除该商品”按钮
        def on_right_click(event):
            # 获取当前焦点项的iid
            iid = self.commodity_tree.focus()
            # 选中指定的行
            self.commodity_tree.selection_set((iid,))

            if iid:
                # 弹出菜单选项
                menu = tk.Menu(self.commodity_tree, tearoff=0)
                menu.add_command(label="删除该商品", command=self.delete_commodity)
                menu.tk_popup(event.x_root, event.y_root)

        # 绑定鼠标右键点击事件
        self.commodity_tree.bind("<Button-3>", on_right_click)

        # 商品操作按钮
        button_frame = ttk.Frame(main_frame)
        button_frame.pack(fill=tk.X, pady=5)

        ttk.Button(button_frame, text="显示所有商品信息", command=self.refresh_commodity).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="添加商品", command=self.add_commodity).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="修改商品", command=self.edit_commodity).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="删除商品", command=self.delete_commodity).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="导出以上商品信息", command=self.export_commodity).pack(side=tk.LEFT, padx=6)
        ttk.Button(button_frame, text="关闭窗口",  command=self.admin_commodity_window.destroy).pack(side=tk.LEFT, padx=6)

        # 左侧信息面板
        information_frame = ttk.Frame(main_frame)
        information_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True, padx=10, pady=5)

        # 商品详细信息
        detail_frame = ttk.LabelFrame(information_frame, text="商品详细信息")
        detail_frame.pack(fill=tk.X, pady=5)

        self.detail_text = tk.Text(detail_frame, width=20, height=8)
        self.detail_text.pack(fill=tk.BOTH, expand=True)

        # 关于程序讲解
        help_frame = ttk.Frame(information_frame)
        help_frame.pack(side=tk.BOTTOM, fill=tk.X, pady=5)

        ttk.Button(help_frame, text="关于本程序", command=program_about).pack(side=tk.LEFT, padx=6)
        ttk.Button(help_frame, text="本程序讲解", command=help_window).pack(side=tk.LEFT, padx=6)

        self.admin_commodity_window.mainloop()

    # 刷新商品列表
    def refresh_commodity(self):
        # 清空当前列表
        for item in self.commodity_tree.get_children():
            self.commodity_tree.delete(item)

        # 添加商品数据
        commodity_data = self.manager_control.search_all_commodity()
        for commodity in commodity_data:
            self.commodity_tree.insert('', 'end', values=(
                commodity['Cnumber'],
                commodity['Cname'],
                commodity['Ccategory'],
                commodity['Cprice'],
                commodity['Cspecifications'],
                commodity['Csupplier'],
                commodity['Cinventory'],
            ))
        # “汇总”统计输出
        self.commodity_count.delete(1.0, tk.END)
        self.commodity_count.insert(tk.END, len(self.commodity_tree.get_children()))

    # 搜索商品
    def search_commodity(self):
        keyword = self.search_commodity_entry.get().strip()
        if not keyword:
            # 刷新商品列表
            self.refresh_commodity()
            return

        # 清空当前列表
        for item in self.commodity_tree.get_children():
            self.commodity_tree.delete(item)

        # 添加搜索结果
        commodity_data = self.manager_control.search_commodity(keyword)
        for commodity in commodity_data:
            self.commodity_tree.insert('', 'end', values=(
                commodity['Cnumber'],
                commodity['Cname'],
                commodity['Ccategory'],
                commodity['Cprice'],
                commodity['Cspecifications'],
                commodity['Csupplier'],
                commodity['Cinventory'],
            ))

        # “汇总”统计输出
        self.commodity_count.delete(1.0, tk.END)
        self.commodity_count.insert(tk.END, len(self.commodity_tree.get_children()))

    # 鼠标选择商品时显示该商品详细信息
    def on_commodity_selected(self, event):
        selected_item = self.commodity_tree.selection()
        if not selected_item:
            return

        commodity_id = self.commodity_tree.item(selected_item)['values'][0]
        commodity = self.manager_control.search_commodity_id(commodity_id)

        if commodity:
            information = f"商品编号: {commodity['Cnumber']}\n"
            information += f"商品名称: {commodity['Cname']}\n"
            information += f"类别: {commodity['Ccategory']}\n"
            information += f"单价: {commodity['Cprice']}\n"
            information += f"商品规格: {commodity['Cspecifications']}\n"
            information += f"供应商: {commodity['Csupplier']}\n"
            information += f"库存: {commodity['Cinventory']}"

            self.detail_text.delete(1.0, tk.END)
            self.detail_text.insert(tk.END, information)

    # 添加商品方法
    def add_commodity(self):
        add_window = tk.Toplevel(self.admin_commodity_window)
        add_window.title("添加商品")

        # 设置窗口居中
        window_width = 550
        window_height = 530
        screen_width = add_window.winfo_screenwidth()
        screen_height = add_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        add_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        add_window.resizable(width=False, height=False)

        # 创建标题标签控件
        Show_result = tk.Label(add_window, text=">>>添加商品信息<<<", bg = "white", fg = "black", font = ("宋体", 18), bd = '0', anchor = 'center')
        Show_result.place(x = 70, y = 30, width = 400, height = 50)

        # 商品编号
        tk.Label(add_window, text="商品编号(不可重复):", font = ('宋体', 12), width = 25).place(x = 55, y = 110, anchor = 'nw')
        id_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        id_entry.place(x = 250, y = 110, anchor = 'nw')

        # 商品名称
        tk.Label(add_window, text="商品名称:", font = ('宋体', 12), width = 25).place(x = 55, y = 160, anchor = 'nw')
        name_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        name_entry.place(x = 250, y = 160, anchor = 'nw')

        # 类别
        tk.Label(add_window, text="类别:", font = ('宋体', 12), width = 25).place(x = 55, y = 210, anchor = 'nw')
        Ccategory_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Ccategory_entry.place(x = 250, y = 210, anchor = 'nw')

        # 单价
        tk.Label(add_window, text="单价:", font = ('宋体', 12), width = 25).place(x = 55, y = 260, anchor = 'nw')
        Cprice_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Cprice_entry.place(x = 250, y = 260, anchor = 'nw')

        # 商品规格
        tk.Label(add_window, text="商品规格:", font = ('宋体', 12), width = 25).place(x = 55, y = 310, anchor = 'nw')
        Cspecifications_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Cspecifications_entry.place(x = 250, y = 310, anchor = 'nw')

        # 供应商
        tk.Label(add_window, text="供应商:", font = ('宋体', 12), width = 25).place(x = 55, y = 360, anchor = 'nw')
        Csupplier_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Csupplier_entry.place(x = 250, y = 360, anchor = 'nw')

        # 库存
        tk.Label(add_window, text="库存:", font = ('宋体', 12), width = 25).place(x = 55, y = 410, anchor = 'nw')
        Cinventory_entry = tk.Entry(add_window, font = ('宋体', 15), width = 20)
        Cinventory_entry.place(x = 250, y = 410, anchor = 'nw')

        # 保存商品信息
        def save_commodity():
            commodity_data = {
                'Cnumber': id_entry.get(),
                'Cname': name_entry.get(),
                'Ccategory': Ccategory_entry.get(),
                'Cprice': Cprice_entry.get(),
                'Cspecifications': Cspecifications_entry.get(),
                'Csupplier': Csupplier_entry.get(),
                'Cinventory': Cinventory_entry.get()
            }
            # 从字典中获取所有的值到列表中
            commodity_list = list(commodity_data.values())
            # 检查每个输入框是否为空
            for result in commodity_list:
                if not result:
                    show_error(self.app, "输入的内容不能为空!")
                    return
            id = str(id_entry.get())
            data = search_commodity_id(id)
            if not data:
                self.manager_control.add_commodity(commodity_data)
                show_sucess(self.app, "添加成功!")
                add_window.destroy()
                # 刷新商品列表
                self.refresh_commodity()
            else:
                show_error(self.app, "商品编号已存在!")

        # 定义“保存”按钮
        save_button = ttk.Button(add_window, text="保存", command=save_commodity, width=15)
        save_button.place(x = 105, y = 460, anchor = 'nw')

        # 定义“取消”按钮
        cancel_button = ttk.Button(add_window, text="取消", command=add_window.destroy, width=15)
        cancel_button.place(x = 280, y = 460, anchor = 'nw')

    # 修改商品信息
    def edit_commodity(self):
        selected_item = self.commodity_tree.selection()
        if not selected_item:
            show_error(self.app, "请先选择一个商品!")
            return
        commodity_id = self.commodity_tree.item(selected_item)['values'][0]
        commodity = self.manager_control.search_commodity_id(commodity_id)
        if not commodity:
            show_error(self.app, "找不到该商品!")
            return

        modify_window = tk.Toplevel(self.admin_commodity_window)
        modify_window.title("修改商品信息")

        # 设置窗口居中
        window_width = 550
        window_height = 530
        screen_width = modify_window.winfo_screenwidth()
        screen_height = modify_window.winfo_screenheight()
        x = (screen_width - window_width) / 2
        y = (screen_height - window_height) / 2
        modify_window.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
        modify_window.resizable(width=False, height=False)

        # 创建标题标签控件
        Show_result = tk.Label(modify_window, text=">>>修改商品信息<<<", bg = "white", fg = "black", font = ("宋体", 18), bd = '0', anchor = 'center')
        Show_result.place(x = 70, y = 30, width = 400, height = 50)

        # 商品(不可编辑)
        tk.Label(modify_window, text="商品编号(不可修改):", font = ('宋体', 12), width = 25).place(x = 55, y = 100, anchor = 'nw')
        Employ_ID = tk.StringVar()
        Employ_ID.set(commodity['Cnumber'])
        number_entry = tk.Entry(modify_window, show = None, font = ('宋体', 15), textvariable = Employ_ID, width = 20)
        number_entry.place(x = 250, y = 100, anchor = 'nw')

        # 设置默认值为相应的商品,商品不可改变
        def on_key_release(event):
            if event.widget.get():
                event.widget.delete(0, tk.END)
                event.widget.insert(0, commodity['Cnumber'])

        # 使用bind绑定函数,当用户释放任意按键时,绑定的回调函数会被触发。
        number_entry.bind('<KeyRelease>', on_key_release)

        # 商品名称
        tk.Label(modify_window, text="商品名称:", font = ('宋体', 12), width = 25).place(x = 55, y = 160, anchor = 'nw')
        name_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        name_entry.insert(0, commodity['Cname'])
        name_entry.place(x = 250, y = 160, anchor = 'nw')

        # 类别
        tk.Label(modify_window, text="类别:", font = ('宋体', 12), width = 25).place(x = 55, y = 210, anchor = 'nw')
        Ccategory_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Ccategory_entry.insert(0, commodity['Ccategory'])
        Ccategory_entry.place(x = 250, y = 210, anchor = 'nw')

        # 单价
        tk.Label(modify_window, text="单价:", font = ('宋体', 12), width = 25).place(x = 55, y = 260, anchor = 'nw')
        Cprice_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Cprice_entry.insert(0, commodity['Cprice'])
        Cprice_entry.place(x = 250, y = 260, anchor = 'nw')

        # 商品规格
        tk.Label(modify_window, text="商品规格:", font = ('宋体', 12), width = 25).place(x = 55, y = 310, anchor = 'nw')
        Cspecifications_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Cspecifications_entry.insert(0, commodity['Cspecifications'])
        Cspecifications_entry.place(x = 250, y = 310, anchor = 'nw')

        # 供应商
        tk.Label(modify_window, text="供应商:", font = ('宋体', 12), width = 25).place(x = 55, y = 360, anchor = 'nw')
        Csupplier_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Csupplier_entry.insert(0, commodity['Csupplier'])
        Csupplier_entry.place(x = 250, y = 360, anchor = 'nw')

        # 库存
        tk.Label(modify_window, text="库存:", font = ('宋体', 12), width = 25).place(x = 55, y = 410, anchor = 'nw')
        Cinventory_entry = tk.Entry(modify_window, font = ('宋体', 15), width = 20)
        Cinventory_entry.insert(0, commodity['Cinventory'])
        Cinventory_entry.place(x = 250, y = 410, anchor = 'nw')

        # 更新商品信息
        def update_commodity():
            new_data = {
                'Cname': name_entry.get(),
                'Ccategory':Ccategory_entry.get(),
                'Cprice':Cprice_entry.get(),
                'Cspecifications':Cspecifications_entry.get(),
                'Csupplier':Csupplier_entry.get(),
                'Cinventory':Cinventory_entry.get()
            }

            # 从字典中获取所有的值到列表中
            commodity_list = list(new_data.values())
            # 检查每个输入框是否为空
            for result in commodity_list:
                if not result:
                    show_error(self.app, "输入的内容不能为空!")
                    return
            if self.manager_control.update_commodity(commodity['Cnumber'], new_data):
                show_sucess(self.app, "商品信息更新成功!")
                modify_window.destroy()
                # 刷新商品列表
                self.refresh_commodity()
                self.on_commodity_selected(None)
            else:
                show_error(self.app, "更新失败!")

        # 保存按钮
        save_button = ttk.Button(modify_window, text="保存", command=update_commodity, width=15)
        save_button.place(x = 105, y = 460, anchor = 'nw')

        # 取消按钮
        cancel_button = ttk.Button(modify_window, text="取消", command=modify_window.destroy, width=15)
        cancel_button.place(x = 280, y = 460, anchor = 'nw')

    # 删除商品
    def delete_commodity(self):
        selected_item = self.commodity_tree.selection()
        if not selected_item:
            show_error(self.app, "请先选择一个商品!")
            return

        commodity_id = self.commodity_tree.item(selected_item)['values'][0]
        commodity_name = self.commodity_tree.item(selected_item)['values'][1]

        add = tk.Toplevel(self.app)
        add.title("确认")
        screen_width, screen_height = add.maxsize()
        # 窗口的宽和高
        width = 240
        height = 150
        centre = '%dx%d+%d+%d' % (width, height, (screen_width - width) / 2,
                                (screen_height - height) / 2)
        add.geometry(centre)
        tk.Label(add, text="确定要删除该商品吗?", font=('黑体', 14)).place(x=20, y=15)
        tk.Label(add, text=f"“{commodity_name}”", font=('黑体', 14)).place(x=70, y=50)

        def confirmm():
            if self.manager_control.delete_commodity(commodity_id):
                show_sucess(self.app,"商品删除成功!")
                # 刷新商品列表
                self.refresh_commodity()
                self.detail_text.delete(1.0, tk.END)
                add.destroy()
            else:
                show_error(self.app, "删除失败!")

        def cancel():
            add.destroy()

        # 确定按钮
        tk.Button(add, text='确定', font=('黑体', 12), width=10, command=confirmm).place(x=20, y=100)

        # 取消按钮
        tk.Button(add, text='取消', font=('黑体', 12), width=10, command=cancel).place(x=130, y=100)

    # 获取当前项的所有列值组成的元组
    def all_commodity_rows(self):
            rows = []
            for item in self.commodity_tree.get_children():
                row = self.commodity_tree.item(item, 'values')
                rows.append(row)
            return rows

    # 导出商品信息到指定Excel表格
    def export_commodity(self):
        export_result = self.all_commodity_rows()
        if not any(len(commodity_list[0]) > 0 for commodity_list in export_result):
            show_error(self.app, "没有数据可导出")
            return
        try:
            # 自定义列名
            columns = ['商品编号', '商品名称', '类别', '单价', '商品规格', '供应商', '库存']
            # 将数据转换为DataFrame
            df = pandas.DataFrame(export_result, columns=columns)
            save_path = filedialog.asksaveasfilename(
                defaultextension=".xlsx",
                filetypes=[("Excel文件", "*.xlsx")])
            if save_path:
                df.to_excel(save_path, index=False)
                show_sucess(self.app, "导出成功!")
        except PermissionError:
            show_error(self.app, "Excel文件被占用,请关闭文件后重试")
        except Exception as e:
            show_error(self.app, f"导出失败:{str(e)}")

    # 显示管理员窗口
    def run(self):
        self.app.mainloop()

# 关于程序页面
def program_about():
    about = tk.Tk()
    about.title('关于程序')

    # 设置窗口居中
    window_width = 450
    window_height = 520
    screen_width = about.winfo_screenwidth()
    screen_height = about.winfo_screenheight()
    x = (screen_width - window_width) / 2
    y = (screen_height - window_height) / 2
    about.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y))
    about.resizable(width=False, height=False)

    about_frame = tk.Frame(about, width=490, height=520)
    about_frame.pack()
    tk.Label(about_frame, text='超市进销存管理系统', font=("宋体", 16)).place(x=150, y=20)
    tk.Label(about_frame, text='使用编程语言:Python', font=("宋体", 14)).place(x=50, y=70)
    tk.Label(about_frame, text='使用数据库:SQLite3数据库', font=("宋体", 14)).place(x=50, y=120)
    tk.Label(about_frame, text='数据库文件:manage.db', font=("宋体", 14)).place(x=50, y=170)
    tk.Label(about_frame, text='修改信息:在信息列表直接双击鼠标', font=("宋体", 14)).place(x=50, y=220)
    tk.Label(about_frame, text='删除信息:在信息列表右击鼠标', font=("宋体", 14)).place(x=50, y=270)
    tk.Label(about_frame, text='导出信息方式:导出到Excel文件内', font=("宋体", 14)).place(x=50, y=320)
    tk.Label(about_frame, text='管理员登录方式:请用管理员账号登录', font=("宋体", 14)).place(x=50, y=370)
    tk.Label(about_frame, text='员工登录方式:请用员工账号登录', font=("宋体", 14)).place(x=50, y=420)
    tk.Label(about_frame, text='创作者:www.pyhint.com', font=("宋体", 14)).place(x=50, y=470)
    about.mainloop()

# 程序讲解页面
def help_window():
    webbrowser.open("https://www.pyhint.com/article/158.html")

# 登录成功后,判断账号如果是员工账号则进入员工界面,如果是管理员账号则进入管理员界面
def success_login(username, category):
    if category == 'employee':
        employee_enter = EmployWindow(username)
        employee_enter.run()
    elif category == 'admin':
        admin_enter = AdminWindow(username)
        admin_enter.run()

# 当前模块直接被执行
if __name__ == "__main__":
    # 创建登录窗口
    login_window = UserLogin(success_login)
    login_window.run()