数据库课程设计(二)(文化遗产博物馆系统)

目录

4.系统实现

        1.数据库访问设计

        数据库连接与管理

 SQL语句查询与结果处理

 SQL语句添加与结果处理

 SQL语句修改与结果处理

SQL语句删除与结果处理

2.登录模块设计 

3.非物质文化遗产模块设计

界面设计

图片(内容未证实)

4.系统主模块设计

界面代码

图片(难以完全表达主题)

5.系统测试

查询

删除

添加 

修改


 

4.系统实现

        1.数据库访问设计

  •         数据库连接与管理
# 获取数据
        self.username = self.usernameEntry.get().strip()
        self.password = self.passwordEntry.get().strip()
        # print(self.username)
        # print(self.password)

        # 打开数据库连接
        db = pymysql.connect(host='localhost',
                             user='root',
                             password='Ls123456',
                             database='museum')
        # 使用cursor()方法获取操作游标
        cursor = db.cursor()

        # 读取数据

        sql = "SELECT password FROM admins where username = %s"
        cursor.execute(sql, (self.username,))
        result = cursor.fetchone()
        # print(result)
        if result is not None:
            result = result[0]
            if result == self.password:
                tkinter.messagebox.showinfo('通知', '管理员登录成功!')
                self.destroy()
                main.mainWindow()
        if result is None:
            sql_1 = "SELECT password FROM audience where username = %s"
            cursor.execute(sql_1, (self.username,))
            result_1 = cursor.fetchone()
            # print(result)
            if result_1 is not None:
                result_1 = result_1[0]
                if result_1 == self.password:
                    tkinter.messagebox.showinfo('通知', '登录成功!')
                    self.destroy()
                    main.mainWindow()

            if result_1 is None:
                isOK = tkinter.messagebox.askokcancel('通知', '用户名不存在,是否注册')
                if isOK:
                    self.destroy()
                    LARPackage.register.registerWindow()
  •  SQL语句查询与结果处理
query = "SELECT id, name, current_region, type, level, protection_unit FROM intangibleheritage WHERE 1=1"

        if self.selected_area != "全部":
            query += f" AND current_region = '{self.selected_area}'"
        if self.selected_type != "全部":
            query += f" AND type = '{self.selected_type}'"
        if self.selected_level != "全部":
            query += f" AND level = '{self.selected_level}'"
        if self.selected_unit != "全部":
            query += f" AND protection_unit = '{self.selected_unit}'"
        # if self.Entry_query_entry is not None:
        #     query += f" AND name LIKE '%{self.Entry_query_entry}%'"
        if self.inputEntry.get() != "项目名称" and self.inputEntry.get() is not None:
            query += f" AND name LIKE '%{self.inputEntry.get()}%'"

        # 连接数据库
        db = pymysql.connect(host='localhost',
                             user='root',
                             password='Ls123456',
                             database='museum')
        # 使用cursor()方法获取操作游标
        cursor = db.cursor()

        # 执行查询
        try:
            cursor.execute(query)
            result = cursor.fetchall()
            print(result)

            # 清空Treeview
            self.treeview.delete(*self.treeview.get_children())

            # 将查询结果填充到Treeview
            for row in result:
                self.treeview.insert("", "end", values=row)

        except Exception as e:
            print(f"查询错误:{e}")
        finally:
            cursor.close()
            db.close()
  •  SQL语句添加与结果处理
#名称
        if self.nameEntry is None:
            self.name = None
        else:
            self.name = self.nameEntry.get().strip()

        #类型
        if self.typeEntry is None:
            self.type = None
        else:
            self.type = self.typeEntry.get().strip()

        #等级
        if self.levelEntry is None:
            self.level = None
        else:
            self.level = self.levelEntry.get().strip()

        #发源地
        if self.current_regionEntry is None:
            self.current_region = None
        else:
            self.current_region = self.current_regionEntry.get().strip()

        #背景描述
        if self.backgroundEntry is None:
            self.background = None
        else:
            self.background = self.backgroundEntry.get().strip()

        #保护单位
        if self.protection_unitEntry is None:
            self.protection_unit = None
        else:
            self.protection_unit = self.protection_unitEntry.get().strip()

        #继承人
        if self.inheritorsEntry is None:
            self.inheritors = None
        else:
            self.inheritors = self.inheritorsEntry.get().strip()

        print(self.name, self.type, self.level, self.current_region, self.background, self.protection_unit,
              self.inheritors)

        # print(self.username)
        # print(self.password)

        isOK = tkinter.messagebox.askokcancel('通知', '确认添加吗?')
        if isOK:
            # 打开数据库连接
            db = pymysql.connect(host='localhost',
                                 user='root',
                                 password='Ls123456',
                                 database='museum')
            # 使用cursor()方法获取操作游标
            cursor = db.cursor()

            # 读取数据
            try:
                # 构建插入数据的SQL语句
                insert_sql = """
                INSERT INTO intangibleheritage (
                    name, type, level, current_region, background, protection_unit, inheritors
                ) VALUES (
                    %s, %s, %s, %s, %s, %s, %s
                )
                """

                # 使用元组将数据传递给execute方法,以防止SQL注入
                data_to_insert = (
                    self.name, self.type, self.level,
                    self.current_region, self.background,
                    self.protection_unit, self.inheritors
                )

                # 执行插入操作
                cursor.execute(insert_sql, data_to_insert)

                # 提交事务
                db.commit()
                tkinter.messagebox.showinfo('通知', '数据插入成功!')
                print("数据插入成功!")

            except pymysql.MySQLError as e:
                # 如果出现错误,回滚事务
                db.rollback()
                tkinter.messagebox.showinfo('通知', '数据插入失败!')
                print(f"数据插入失败: {e}")
            finally:
                # 关闭游标和数据库连接
                cursor.close()
                db.close()
  •  SQL语句修改与结果处理
# 名称
        if self.nameEntry is None:
            self.name = ""

        else:
            self.name = self.nameEntry.get().strip()

        # 类型
        if self.typeEntry is None:
            self.type = ""
        else:
            self.type = self.typeEntry.get().strip()

        # 等级
        if self.levelEntry is None:
            self.level = ""
        else:
            self.level = self.levelEntry.get().strip()

        # 发源地
        if self.current_regionEntry is None:
            self.current_region = ""
        else:
            self.current_region = self.current_regionEntry.get().strip()

        # 背景描述
        if self.backgroundEntry is None:
            self.background = ""
        else:
            self.background = self.backgroundEntry.get().strip()

        # 保护单位
        if self.protection_unitEntry is None:
            self.protection_unit = ""
        else:
            self.protection_unit = self.protection_unitEntry.get().strip()

        # 继承人
        if self.inheritorsEntry is None:
            self.inheritors = ""
        else:
            self.inheritors = self.inheritorsEntry.get().strip()

        print(self.name, self.type, self.level, self.current_region, self.background, self.protection_unit,
              self.inheritors)



        # print(self.username)
        # print(self.password)

        isOK = tkinter.messagebox.askokcancel('通知', '确认更新吗?')
        if isOK:
            # 打开数据库连接
            db = pymysql.connect(host='localhost',
                                user='root',
                                password='Ls123456',
                                database='museum')
            cursor = db.cursor()

            try:
                # 查询原始记录
                select_sql = "SELECT * FROM intangibleheritage WHERE id = %s"
                cursor.execute(select_sql, (self.id,))
                fetched_record = cursor.fetchone()

                # 确保查询到了记录
                if fetched_record:
                    original_record = dict(zip(('id', 'name', 'type', 'level', 'current_region', 'background',
                                                'protection_unit', 'inheritors'), fetched_record))
                    # 准备更新的数据列表,仅包含非空且与原值不同的项
                    update_fields = []  # 存储需要更新的字段名
                    update_values = []  # 存储对应的更新值
                    for field, new_value in [
                        ('name', self.name),
                        ('type', self.type),
                        ('level', self.level),
                        ('current_region', self.current_region),
                        ('background', self.background),
                        ('protection_unit', self.protection_unit),
                        ('inheritors', self.inheritors)
                    ]:
                        # 只有当新值不为空且与原值不同才添加到更新列表
                        if new_value and new_value != original_record[field]:
                            update_fields.append(field)
                            update_values.append(new_value)

                    # 添加id到列表末尾,用于WHERE条件
                    update_values.append(self.id)

                    # 构造动态的SET部分,只包括需要更新的字段
                    set_clause = ', '.join([f"{f} = %s" for f in update_fields])

                    # 构建完整的更新SQL
                    update_sql = f"""
                    UPDATE intangibleheritage
                    SET {set_clause}
                    WHERE id = %s
                    """

                    # 执行更新操作
                    cursor.execute(update_sql, update_values)  # 直接使用update_values
                    db.commit()
                    tkinter.messagebox.showinfo('通知', '数据更新成功!')
                    print("数据更新成功!")
                else:
                    print("未找到对应的记录。")

            except pymysql.MySQLError as e:
                db.rollback()
                tkinter.messagebox.showinfo('通知', '数据更新失败!')
                print(f"数据更新失败: {e}")
            finally:
                cursor.close()
                db.close()
  • SQL语句删除与结果处理
# 打开数据库连接
        db = pymysql.connect(host='localhost',
                             user='root',
                             password='Ls123456',
                             database='museum')
        # 使用cursor()方法获取操作游标
        cursor = db.cursor()

        # 读取数据

        sql = "SELECT username FROM admins"
        cursor.execute(sql)
        result = cursor.fetchall()
        print(result)

        for user in result:
            print(user[0])
            if user[0] == self.user:
                delete_item = tkinter.simpledialog.askinteger("删除", "请输入需要删除传承的编号:")
                if delete_item:
                    # print(delete_item)
                    isOK = tkinter.messagebox.askokcancel('通知', '确认删除吗?')
                    if isOK:
                        db = pymysql.connect(host='localhost',
                                             user='root',
                                             password='Ls123456',
                                             database='museum')
                        # 使用cursor()方法获取操作游标
                        cursor = db.cursor()

                        try:
                            # 注意:这里假设`delete_item`是要根据userName删除的,所以SQL中的占位符应该是用户名,但通常删除操作会基于ID更安全。
                            # 如果`delete_item`实际上是用户名,请确保这是预期的行为,否则可能需要调整为基于ID的删除逻辑。
                            sql_del = "DELETE FROM intangibleheritage WHERE id = %s"

                            # 执行删除操作,注意使用%操作符安全地插入变量到SQL语句中
                            cursor.execute(sql_del, (delete_item,))

                            # 提交到数据库执行
                            db.commit()
                            tkinter.messagebox.showinfo('通知', '数据删除成功!')
                            print("删除成功!")

                        except pymysql.MySQLError as e:
                            # 捕获具体的数据库错误,如权限、不存在的表或列等
                            print(f"数据库操作错误: {e}")
                        except Exception as e:
                            # 捕获其他所有异常
                            print(f"发生错误: {e}")
                        finally:
                            # 不论是否发生异常,都确保关闭游标和数据库连接
                            if cursor:
                                cursor.close()
                            if db:
                                db.close()
            else:
                tkinter.messagebox.showwarning("警告", "没有权限")

2.登录模块设计 

    def setupUI(self):
        self.mainLabel = Label(text="欢迎您进入登录页面")
        self.mainLabel.grid(row=0, columnspan=5)

        # 用户名
        self.username = Label(text='用户名:', borderwidth=3)
        self.username.grid(row=1, sticky=W)
        self.usernameEntry = Entry()
        self.usernameEntry.grid(row=1, column=1, columnspan=3)
        self.usernameEntry.focus_set()

        # 密码
        self.password = Label(text='密码:', borderwidth=3)
        self.password.grid(row=2, sticky=W)
        self.passwordEntry = Entry(show='*')
        self.passwordEntry.grid(row=2, column=1, columnspan=3)

        # 注册按钮
        self.registerButton = Button(text='登录', borderwidth=2, command=self.login)
        self.registerButton.grid(row=4, columnspan=5)

    def login(self):
        # 获取数据
        self.username = self.usernameEntry.get().strip()
        self.password = self.passwordEntry.get().strip()
        # print(self.username)
        # print(self.password)

        # 打开数据库连接
        db = pymysql.connect(host='localhost',
                             user='root',
                             password='Ls123456',
                             database='museum')
        # 使用cursor()方法获取操作游标
        cursor = db.cursor()

        # 读取数据

        sql = "SELECT password FROM admins where username = %s"
        cursor.execute(sql, (self.username,))
        result = cursor.fetchone()
        # print(result)
        if result is not None:
            result = result[0]
            if result == self.password:
                tkinter.messagebox.showinfo('通知', '管理员登录成功!')
                self.destroy()
                main.mainWindow()
        if result is None:
            sql_1 = "SELECT password FROM audience where username = %s"
            cursor.execute(sql_1, (self.username,))
            result_1 = cursor.fetchone()
            # print(result)
            if result_1 is not None:
                result_1 = result_1[0]
                if result_1 == self.password:
                    tkinter.messagebox.showinfo('通知', '登录成功!')
                    self.destroy()
                    main.mainWindow()

            if result_1 is None:
                isOK = tkinter.messagebox.askokcancel('通知', '用户名不存在,是否注册')
                if isOK:
                    self.destroy()
                    LARPackage.register.registerWindow()

 

3.非物质文化遗产模块设计

  • 界面设计
    def setupUI(self):
        # 风格设置
        self.Style01 = Style()
        self.Style01.configure("right.TPanedwindow")
        self.Style01.configure("left.TPanedwindow")

        # 左边:查询、TreeView
        self.Pane_left = PanedWindow(width=800, height=600, style="left.TPanedwindow")
        self.Pane_left.place(x=8, y=10)

        # 创建一个包含查询区域和Treeview的LabelFrame,并添加边框
        self.frame_container = LabelFrame(self.Pane_left, borderwidth=2, relief=GROOVE, text="查询结果", width=800,
                                          height=600)
        self.frame_container.pack(fill=BOTH, expand=True, pady=(10, 0))

        # 查询区域
        self.QueryFrame = Frame(self.frame_container)
        self.QueryFrame.grid(row=0, column=0, sticky=NSEW, padx=10, pady=10)

        # LabelFrame
        self.LabelFrame_query = LabelFrame(self.QueryFrame, text="非物质文化遗产", width=700, height=70)
        self.LabelFrame_query.pack(side=TOP, fill=X, padx=10, pady=10)

        # 设置特定列的间隔
        self.LabelFrame_query.columnconfigure(7, minsize=30)  # 在第四个下拉菜单与输入框之间增加间隔
        self.LabelFrame_query.columnconfigure(8, minsize=30)  # 在输入框与查询按钮之间增加间隔
        # 添加控件
        # 地区下拉菜单
        self.Label_area = Label(self.LabelFrame_query, text="地区:")
        self.Label_area.grid(row=1, column=0, sticky=W)

        # 定义下拉菜单的选项列表
        area_options = ["全部", "北京", "上海", "天津", "重庆", "黑龙江", "辽宁", "吉林", "河北",
                        "河南", "湖北", "湖南", "山东", "山西", "陕西", "安徽", "浙江", "江苏",
                        "福建", "广东", "海南", "四川", "云南", "贵州", "青海", "甘肃", "江西",
                        "台湾", "内蒙古自治区", "宁夏回族自治区", "新疆维吾尔自治区", "西藏自治区", "广西壮族自治区",
                        "香港特别行政区", "澳门特别行政区"]

        # 使用Combobox替换原来的Entry
        self.ComboBox_area = Combobox(self.LabelFrame_query, values=area_options, width=9)
        self.ComboBox_area.grid(row=1, column=1, sticky=W)

        # 设置默认值
        self.ComboBox_area.set("请选择地区")  # 默认显示的文本
        self.ComboBox_area.bind("<<ComboboxSelected>>", self.update_selected_area)

        # 类型下拉菜单
        self.Label_type = Label(self.LabelFrame_query, text="类型:")
        self.Label_type.grid(row=1, column=2, sticky=W)
        type_options = ["全部", "戏曲", "传统戏剧", "传统技艺", "传统体育"]  # 示例选项,请根据实际情况替换
        self.ComboBox_type = Combobox(self.LabelFrame_query, values=type_options, width=9)
        self.ComboBox_type.grid(row=1, column=3, sticky=W)
        self.ComboBox_type.set("请选择类型")
        self.ComboBox_type.bind("<<ComboboxSelected>>", self.update_selected_type)

        # 等级下拉菜单
        self.Label_level = Label(self.LabelFrame_query, text="等级:")
        self.Label_level.grid(row=1, column=4, sticky=W)
        level_options = ["全部", "国家级", "世界级", "地区级"]  # 示例选项,请根据实际情况替换
        self.ComboBox_level = Combobox(self.LabelFrame_query, values=level_options, width=9)
        self.ComboBox_level.grid(row=1, column=5, sticky=W)
        self.ComboBox_level.set("请选择等级")
        self.ComboBox_level.bind("<<ComboboxSelected>>", self.update_selected_level)

        # 保护单位下拉菜单
        self.Label_unit = Label(self.LabelFrame_query, text="保护单位:")
        self.Label_unit.grid(row=1, column=6, sticky=W)
        unit_options = ["全部", "中国文化和旅游部", "中国武术协会", "四川 文化和旅游厅"]  # 示例选项,请根据实际情况替换
        self.ComboBox_unit = Combobox(self.LabelFrame_query, values=unit_options, width=9)
        self.ComboBox_unit.grid(row=1, column=7, sticky=W)
        self.ComboBox_unit.set("请选择单位")
        self.ComboBox_unit.bind("<<ComboboxSelected>>", self.update_selected_unit)

        # 输入框
        self.inputEntry = Entry(self.LabelFrame_query, width=10)
        self.inputEntry.grid(row=1, column=11, sticky=W)
        self.inputEntry.insert(0, "项目名称")

        # 查询按钮
        self.Button_query = Button(self.LabelFrame_query, text="查询", width=4, command=self.query_action)
        self.Button_query.grid(row=1, column=14, sticky=W + E)

        # 创建Treeview展示框
        self.Treeview_frame = Frame(self.frame_container)
        self.Treeview_frame.grid(row=1, column=0, sticky=NSEW, padx=10, pady=10)

        # Treeview列配置
        self.treeview = Treeview(self.Treeview_frame, columns=("ID", "Name", "Area", "Type", "Level", "Unit"),
                                 show="headings")
        self.treeview.heading("ID", text="ID", anchor=CENTER)  # 文字居中对齐
        self.treeview.heading("Name", text="名称", anchor=CENTER)
        self.treeview.heading("Area", text="地区", anchor=CENTER)
        self.treeview.heading("Type", text="类型", anchor=CENTER)
        self.treeview.heading("Level", text="等级", anchor=CENTER)
        self.treeview.heading("Unit", text="保护单位", anchor=CENTER)

        # 设置列宽并居中文本
        self.treeview.column("#1", stretch=NO, width=70, anchor=CENTER)  # ID列宽度及居中
        self.treeview.column("#2", stretch=NO, width=120, anchor=CENTER)  # 名称列宽度及居中
        self.treeview.column("#3", stretch=NO, width=120, anchor=CENTER)  # Area列宽度及居中
        self.treeview.column("#4", stretch=NO, width=120, anchor=CENTER)  # Type列宽度及居中
        self.treeview.column("#5", stretch=NO, width=120, anchor=CENTER)  # Level列宽度及居中
        self.treeview.column("#6", stretch=NO, width=130, anchor=CENTER)  # Unit列宽度及居中

        # 绑定滚动条
        self.scrollbar = Scrollbar(self.Treeview_frame, orient=VERTICAL, command=self.treeview.yview)
        self.treeview.configure(yscrollcommand=self.scrollbar.set)
        self.scrollbar.pack(side=RIGHT, fill=Y)
        self.treeview.pack(side=LEFT, fill=BOTH, expand=True)

        # 调整查询区域和Treeview的大小
        self.frame_container.grid_columnconfigure(0, weight=1)
        self.frame_container.grid_rowconfigure(0, weight=1)
        self.QueryFrame.grid_columnconfigure(0, weight=1)
        self.Treeview_frame.grid_columnconfigure(0, weight=1)

        # 按钮区域
        self.ButtonFrame = Frame(self.Pane_left)
        self.ButtonFrame.pack(fill=X, pady=10)

        # 设置ButtonFrame的列配置,使得按钮之间有相等的间隔
        for i in range(4):  # 假设一共有4个按钮
            self.ButtonFrame.columnconfigure(i, weight=1, uniform="equal")  # uniform确保各列间距相等

        # 右边:按钮区域
        self.Button_add = Button(self.ButtonFrame, text="添加", command=self.add)
        self.Button_add.grid(row=0, column=0, padx=5, pady=5, sticky=W + E)

        self.Button_update = Button(self.ButtonFrame, text="修改", command=self.modify)
        self.Button_update.grid(row=0, column=1, padx=5, pady=5, sticky=W + E)

        self.Button_delete = Button(self.ButtonFrame, text="删除", command=self.delete)
        self.Button_delete.grid(row=0, column=2, padx=5, pady=5, sticky=W + E)

        self.Button_modify = Button(self.ButtonFrame, text="返回主界面", command=self.backMain)
        self.Button_modify.grid(row=0, column=3, padx=5, pady=5, sticky=W + E)
  • 图片(内容未证实)

4.系统主模块设计

  • 界面代码
class mainWindow(Tk):
    def __init__(self):
        super().__init__()
        self.title("文化传承博物馆系统")

        # 设置窗口大小并禁用调整大小
        self.resizable(False, False)

        # 获取屏幕宽度和高度
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()

        # 计算窗口在屏幕中央的位置
        window_width = 1090
        window_height = 585
        x_pos = (screen_width - window_width) // 2
        y_pos = (screen_height - window_height) // 2

        # 设置窗口大小和位置
        self.geometry(f"{window_width}x{window_height}+{x_pos}+{y_pos}")

        # 调用设置界面方法
        self.setupUI()

    def setupUI(self):
        # 创建主菜单
        self.menu = Menu(self)
        self.config(menu=self.menu)

        # 添加“个人中心”菜单及子项
        self.person_menu = Menu(self.menu, tearoff=0)
        self.person_menu.add_command(label="用户详情", command=self.details)
        self.person_menu.add_separator()
        self.person_menu.add_command(label="退出系统", command=self.quit)
        self.menu.add_cascade(label="个人中心", menu=self.person_menu)

        # 添加“学者”菜单及子项
        self.scholar_menu = Menu(self.menu, tearoff=0)
        self.scholar_menu.add_command(label="专家", command=self.experts)
        self.scholar_menu.add_command(label="继承人", command=self.inheritors)
        self.menu.add_cascade(label="学者", menu=self.scholar_menu)

        # 添加“内容”菜单及子项
        self.content_menu = Menu(self.menu, tearoff=0)
        self.content_menu.add_command(label="非物质文化遗产", command=self.ich)
        self.content_menu.add_command(label="物质文化遗产", command=self.tch)
        self.menu.add_cascade(label="内容", menu=self.content_menu)

        # 添加“帮助”菜单及子项
        self.help_menu = Menu(self.menu, tearoff=0)
        self.help_menu.add_command(label="关于", command=self.about)
        self.menu.add_cascade(label="帮助", menu=self.help_menu)

        self.Style01 = Style()
        self.Style01.configure("right.TPanedwindow")
        self.Style01.configure("left.TPanedwindow")
        self.Style01.configure("TButton", width=10)

        # Top_banner
        self.Lable_text = Label(text="欢迎使用文化遗产博物馆系统", font=("微软雅黑", 20))
        self.Lable_text.config(anchor=CENTER, justify=CENTER)
        self.Lable_text.pack()

        # 在此处添加图片
        image_path = "./img/2.jpeg"  # 请替换为您的图片路径
        image = Image.open(image_path)
        photo = ImageTk.PhotoImage(image)
        self.image_label = Label(self, image=photo)
        self.image_label.image = photo  # 保持对图片的引用,防止被垃圾回收器回收
        self.image_label.pack()


    def ich(self):
        self.destroy()
        ichPackage.ich.ichWindow()

    def tch(self):
        self.destroy()
        tch.tchWindow()

    def experts(self):
        self.destroy()
        expertPackage.expert.expertWindow()

    def inheritors(self):
        self.destroy()
        inheritorsPackage.inheritors.inheritorsWindow()

    def details(self):
        self.destroy()
        userPackage.details.detailsWindow()

    def about(self):
        tkinter.messagebox.showinfo('系统简介', '随着信息技术的飞速发展,互联网已经成为人们获取知识和信息的重要渠道。'
                                                '为了应对全球范围内工业化和现代化进程中对传统文化造成的冲击和破坏。'
                                                '在全球化和数字化的时代背景下,'
                                                '文化遗产保护与传承面临着新的机遇与挑战。为了更好地保护、传播和利用文化遗产资源,文化遗产博物馆系统应运而生。')
  • 图片(难以完全表达主题)

5.系统测试

  • 查询

  • 删除

 

  • 添加 

  • 修改

6. 代码链接

链接:https://pan.baidu.com/s/1tituxPWldGkVCbJXb2XJJQ 
提取码:te1g

  • 11
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值