数据库期末作业,Python+sqlserver的学生成绩管理系统

        数据库期末要写一个程序连接本地数据库并实现一个功能,选了个学生成绩管理系统.

        代码和数据库脚本奉上.

        链接:提取码: 56tk 

需求分析

用户登录,注册

学生能够查看自己成绩,修改自己密码

老师能够选择自己教授的课程进行成绩登记,以及通过学号和课程查找批改成绩,和修改密码

就是三个对于数据库的增删查改,第一波先设计数据库.

数据库设计

表结构

先设计用户登录账号密码表,就四个属性,账号(主键)密码编号和权限.另外应该把老师和学生分开放的,但是期末作业,怎么快怎么来.

CREATE TABLE [dbo].[systemusers](
	[useid] [varchar](20) NOT NULL,
	[usepass] [varchar](20) NOT NULL,
	[sno] [varchar](20) NOT NULL,
	[type] [int] NOT NULL,
 CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED 
(
	[useid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

ALTER TABLE [dbo].[systemusers]  WITH CHECK ADD  CONSTRAINT [FK_user_user] FOREIGN KEY([useid])
REFERENCES [dbo].[systemusers] ([useid])
GO

ALTER TABLE [dbo].[systemusers] CHECK CONSTRAINT [FK_user_user]
GO


那么然后就开始设计学生表,学生就要带学号(用户编号,主键),姓名,专业,科目,成绩.

CREATE TABLE [dbo].[Student](
	[sno] [varchar](20) NOT NULL,
	[sname] [varchar](20) NOT NULL,
	[smajor] [varchar](20) NOT NULL,
	[cname] [varchar](20) NOT NULL,
	[igrade] [int] NULL,
 CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
(
	[sno] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

随后是老师表,有老师编号,教学科目,教师编号.

CREATE TABLE [dbo].[Teacher](
	[sno] [varchar](20) NOT NULL,
	[sname] [varchar](20) NOT NULL,
	[cname] [varchar](20) NOT NULL,
 CONSTRAINT [PK_Teacher] PRIMARY KEY CLUSTERED 
(
	[sno] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

理论上来说应该再设计一个课程表和成绩表,以满足更高范式,但是偷偷懒这样也能用

目前数据库表就设计的差不多了,随便填几个数据就能用了.

数据库用户

数据库用户还是要创建一个,用ssms直接建立就好了,映射到我们需要的数据库上,叫什么都可以自己编

pyhton代码

登录页面

数据库连接

首先要连接上我们的数据库,这里使用python的mssql包来连接我们的sqlserver.

def sqlconnect():##数据库连接
    server = "(local)"
    user = "python"
    password = "*******"
    database = "MyDb"
    global conn 
    conn= pymssql.connect(server, user, password, database,autocommit=True,charset='GBK')
    global cursor 
    cursor= conn.cursor()
    if  not cursor:
        tkinter.messagebox.showerror(title='错误',
        message='数据库连接失败')  # 信息错误弹窗,点击确定返回值为 ok
        exit(0)

通过通过connect方法,获取数据库的连接对象conn,随后获取conn的游标对象,类似于字节流,对于数据库的操作都要通过cursor对象提交给数据库,随后数据库执行.

登录页面

页面的布局设计,使用tkinker进行布局,设计比较简陋,如有需要可以自己改.

先初始化Tkinker,随后通过布局,使页面居中,随后连接数据库,按键函数为登录和注册.

留了两个Label控件,用于获取输入.

root = Tk()             #初始化Tk()
root.title('英才大学学生成绩管理系统')
root.resizable(0,0)
screenWidth = root.winfo_screenwidth()  # 获取显示区域的宽度
screenHeight = root.winfo_screenheight()  # 获取显示区域的高度
width = 300  # 设定窗口宽度
height = 200  # 设定窗口高度
left = (screenWidth - width) / 2
top = (screenHeight - height) / 2
# 宽度x高度+x偏移+y偏移
# 在设定宽度和高度的基础上指定窗口相对于屏幕左上角的偏移位置
root.geometry("%dx%d+%d+%d" % (width, height, left, top))
sqlconnect()
iser=1
useid=Entry(root)
usepass=Entry(root,show='*')
id=Label(root,text='账号')
pas=Label(root,text='密码')
id.place(x=40,y=0)
pas.place(x=40,y=20)
useid.pack()
usepass.pack()
login=Button(root,text='登录',command=lg,width=5)
login.place(x=80,y=50)
enroll=Button(root,text='注册',command=er,width=5)
enroll.place(x=160,y=50)
root.mainloop()

效果图就这样

登录功能

登录功能就挺简单了,用户提交账号密码后查询数据库,有数据就登录成功,无数据或者密码错误就提示不正确.

def lg():##登录
    id=useid.get()
    password=usepass.get()
    selectsql="select * from systemusers where useid ='{}'".format(id)
    cursor.execute(selectsql)
    data=cursor.fetchall()
    try:
        if len(data)==1 and data[0][0]==id and str(data[0][1])==password:
            mess1=Label(root,text='登录成功',font=('Arial', 12),width=15, height=2)
            mess1.pack()
            root.destroy()
            root.quit()
            root.mainloop()
            system.work(data[0][2],data[0][3])
        else:
            tkinter.messagebox.showerror(title='错误',
		message='账号或者密码错误')  # 信息错误弹窗,点击确定返回值为 ok
    except :
        pass
    else:
        root.mainloop()

点击登录以后,Label获取输入,随后将输入格式化,提交查询,数据库返回一个元组结果,因为限定用户名为主键不能重复,所有返回元组只有一行,那我们根据表结构对数据进行比对即可,需要注意的是,数据库中返回类型和表中类型一直,表中char,varchar类型返回为字符类型结果,int类型也返回整形结果,部分需要转换.

如果比对正确,那么进入另一个页面.不正确就跳出错误弹窗

注册设计

注册设计也偷懒了,应该注册完然后补全信息的,但是我只留了注册的窗口,没有留在学生表中补全信息的功能,也就是说新注册的用户如果学生表中没有对应的学号数据的话是查不到成绩的.

def isregisterd():
    id=useid1.get()
    passw=usepass1.get()
    no=sno1.get()
    print(len(id))
    if is_ok(id) and is_ok(passw) and is_ok(no) :
        selectsql="select * from systemusers where sno ='{}'".format(no)
        cursor.execute(selectsql)
        data=cursor.fetchall()
        try:
            if  no==data[0][2] :
                tkinter.messagebox.showerror(title='错误',
		message='已经注册过了')  # 信息错误弹窗,点击确定返回值为 ok
        except :
            try:
                selectsql="select * from systemusers where useid ='{}'".format(id)
                cursor.execute(selectsql)
                data=cursor.fetchall()
                if  id==data[0][0] :
                    tkinter.messagebox.showerror(title='错误',
		message='账号重复')  # 信息错误弹窗,点击确定返回值为 ok
            except:
                try:
                    selectsql="insert into systemusers values('{}','{}','{}',0)".format(id,passw,no)
                    cursor.execute(selectsql)
                    conn.commit()
                    display_rigmessage()
                    
                except :
                    display_errormessage()

                else:
                    enr.destroy()
                    enr.mainloop()
        else:
            enr.mainloop()
    else :
        tkinter.messagebox.showerror(title='错误',
		message='输入不合法')  # 信息错误弹窗,点击确定返回值为 ok
        enr.mainloop()
        
def er():##注册
    global iser
    if  iser==1:
        iser-=1
        global enr
        enr=Tk()
        enr.resizable(0,0)
        enr.title('注册')
        screenWidth = enr.winfo_screenwidth()  # 获取显示区域的宽度
        screenHeight = enr.winfo_screenheight()  # 获取显示区域的高度
        width = 300  # 设定窗口宽度
        height = 200  # 设定窗口高度
        left = (screenWidth - width) / 2
        top = (screenHeight - height) / 2
        enr.geometry("%dx%d+%d+%d" % (width, height, left, top))
        mess1=Label(enr,text='输入信息(仅限学生注册)',font=('Arial', 10),width=20, height=2)
        mess2=Label(enr,text='账号')
        mess3=Label(enr,text='密码')
        mess4=Label(enr,text='学号')
        catch=Button(enr,text='点击注册',command=isregisterd)
        global useid1
        useid1=Entry(enr)
        global usepass1
        usepass1=Entry(enr)
        global sno1
        sno1=Entry(enr)
        useid1.place(x=80,y=30)
        usepass1.place(x=80,y=50)
        sno1.place(x=80,y=70)
        mess1.place(x=70,y=0)
        mess2.place(x=50,y=30)
        mess3.place(x=50,y=50)
        mess4.place(x=50,y=70)
        catch.place(x=120,y=110)
        enr.focus_force() #新窗口获得焦点
        enr.mainloop()
    else :
        enr.focus_force() #新窗口获得焦点

isregisterd功能就和名字差不多,检测该用户,学号是否已经注册,对要注册的账号进行查询,如果重复就提示账号重复或者学号已注册.

er函数为组成页面,最开始使用一个全局变量,防止注册窗口多开,这里更应该检测er窗口是否存在的,但是使用全局变量简单一点,带来一个问题就是注册窗口叉掉以后不能再打开.

工作页面

root页面在登录成功后便销毁,防止工作页面多开.

学生和老师页面都是基于work类上的

class work(object):
    def __init__(self,sno,type):
        self.__sno=sno
        self.__type=type
        self.__newpass=None
        self.__havepasschs=FALSE
        server = "(local)"
        user = "python"
        password = "py031125"
        database = "MyDb"
        global conn 
        conn= pymssql.connect(server, user, password, database,autocommit=True,charset='utf8')
        global cursor 
        cursor= conn.cursor()
        if  not cursor:
            exit(0)
            ###完善自身信息############################################################################
        if type==1:
            cursor.execute("select sname from Teacher where sno ='{}'".format(sno))
            name=cursor.fetchall()[0][0].encode('latin1').decode('gbk')
        else :
            try:
                cursor.execute("select sname from Student where sno ='{}'".format(sno))
                name=cursor.fetchall()[0][0].encode('latin1').decode('gbk')
            except :
                tkinter.messagebox.showerror(title='错误',
		    message='没有选课信息')  # 信息错误弹窗,点击确定返回值为 ok
                exit(0)
        self.__name=name
        cursor.execute("select usepass from systemusers where sno ='{}'".format(sno))
        passw=cursor.fetchall()[0][0]
        self.__passw=passw
        global scr
        scr= Tk() 
        scr.resizable(0,0)
        global canvas
        canvas= Canvas(scr, width=600,height=400,bd=0, highlightthickness=0)
        scr.title('用户{}登录成功'.format(name))
        screenWidth = scr.winfo_screenwidth()  # 获取显示区域的宽度
        screenHeight = scr.winfo_screenheight()  # 获取显示区域的高度
        width = 600  # 设定窗口宽度
        height = 400  # 设定窗口高度
        left = (screenWidth - width) / 2
        top = (screenHeight - height) / 2
        # 宽度x高度+x偏移+y偏移
        # 在设定宽度和高度的基础上指定窗口相对于屏幕左上角的偏移位置
        scr.geometry("%dx%d+%d+%d" % (width, height, left, top))
        imgpath= 'beij.gif'
        img = Image.open(imgpath)
        global photo
        photo = ImageTk.PhotoImage(img)
        canvas.create_image(300, 200, image=photo)
        canvas.pack()
        if self.__type==0 :
            self.stud()
            scr.mainloop()################################ok
        ###################################################老师系统
            1.#修改密码#
            2.#登成绩
            3.#查看成绩
        elif self.__type==1:
            self.teach()
            scr.mainloop()
            
        ##sql="select type from systemusers where sno ='{}'".format(sno)
        ##print(sql)
        ##cursor.execute(sql)
    

上个页面传来的编号和权限参数,初始化work类,根据不同权限判断学生和老师,给不同功能按键

学生页面

效果如下,前端确实没怎么学,布局确实不太好看.

def stud(self):
        text=Text(scr,width=400,height=70)
        canvas.create_window(350, 85, width=400, height=70,window=text)
        stubutton1=Button(scr,text='查看成绩',command=self.__showgrade,width=100,height=40)
        stubutton2=Button(scr,text='修改密码',command=self.__changepass,width=100,height=40)
        canvas.create_window(80, 70, width=100, height=40,window=stubutton1)
        canvas.create_window(80, 120, width=100, height=40,window=stubutton2)
        scr.mainloop()

通过两个按钮可以调用查看成绩和密码的函数

def __showgrade(self):
        stutext=Text(scr,width=400,height=70)
        canvas.create_window(350, 85, width=400, height=70,window=stutext)
        cursor.execute("select * from Student where sno='{}'".format(self.__sno))
        data=cursor.fetchall()
        for i in range(len(data)):
            stutext.insert(END,'\n学号:'+data[0][0]+'\n姓名:'+data[0][1].encode('latin1').decode('gbk')+'\n专业:'+data[0][2].encode('latin1').decode('gbk')+'\n科目:'+data[0][3].encode('latin1').decode('gbk')+'\n成绩:'+str(data[0][4]))
        scr.mainloop()
 
 def __changepass(self):
        if self.__havepasschs == FALSE:
            self.__havepasschs=TRUE
            global passchs 
            passchs=Tk()
            passchs.resizable(0,0)
            passchs.title('密码修改')
            screenWidth = passchs.winfo_screenwidth()  # 获取显示区域的宽度
            screenHeight = passchs.winfo_screenheight()  # 获取显示区域的高度
            width = 300  # 设定窗口宽度
            height = 200  # 设定窗口高度
            left = (screenWidth - width) / 2
            top = (screenHeight - height) / 2
            # 宽度x高度+x偏移+y偏移
            # 在设定宽度和高度的基础上指定窗口相对于屏幕左上角的偏移位置
            passchs.geometry("%dx%d+%d+%d" % (width, height, left, top))
            mess1=Label(passchs,text='修改密码',font=('Arial', 10),width=20, height=2)
            mess2=Label(passchs,text='原密码')
            mess3=Label(passchs,text='新密码')
            mess4=Label(passchs,text='确认新密码')
            global oldpass
            oldpass=Entry(passchs)
            global newpass
            newpass=Entry(passchs)
            global realpass
            realpass=Entry(passchs,show='*')
            oldpass.place(x=80,y=30)
            newpass.place(x=80,y=50)
            realpass.place(x=80,y=70)
            mess1.place(x=70,y=0)
            mess2.place(x=30,y=30)
            mess3.place(x=30,y=50)
            mess4.place(x=10,y=70)
            passchs.focus_force()
            passchs.after(500,self.cpassget)
        else :
            passchs.focus_force()
def cpassget(self):
        old=oldpass.get()
        new=newpass.get()
        real=realpass.get()
        if is_ok(old) and is_ok(new) and is_ok(real) :
            if old==self.__passw and new==real and real!=old:
                self.__newpass=new
                ts1=Label(passchs,text="密码正确",width=8,height=1,justify='left')
                ts1.place(x=230,y=30)
                ts2=Label(passchs,text="密码确认",width=8,height=1,justify='left')
                ts2.place(x=230,y=70)
                ts3=Label(passchs,text="密码不重复",width=8,height=1,justify='left')
                ts3.place(x=230,y=50)
                catch=Button(passchs,text='点击更改',command=self.__realchange)
                catch.place(x=120,y=110)
            else :
                if old!=self.__passw :
                    ts1=Label(passchs,text="密码错误",width=8,height=1,justify='left')
                    ts1.place(x=230,y=30)

                elif old==self.__passw :
                    ts1=Label(passchs,text="密码正确",width=8,height=1,justify='left')
                    ts1.place(x=230,y=30)

                if new!=real :
                    ts2=Label(passchs,text="密码未确认",width=8,height=1,justify='left')
                    ts2.place(x=230,y=70)

                elif new==real :
                    ts2=Label(passchs,text="密码确认",width=8,height=1,justify='left')
                    ts2.place(x=230,y=70)

                if old!=new :
                    ts3=Label(passchs,text="密码不重复",width=8,height=1,justify='left')
                    ts3.place(x=230,y=50)
                    
                elif old==new :
                    ts3=Label(passchs,text="密码重复",width=8,height=1,justify='left')
                    ts3.place(x=230,y=50)

            passchs.after(500,self.cpassget)
        else :
            passchs.after(500,self.cpassget)

这里通过递归页面延时来检测原密码,新密码和确认密码的合法性,最后,确认都合法以后给出修改按键.

老师页面 

def teach(self):
        tbutton1=Button(scr,text='编辑成绩',command=self.__grditgrade,width=100,height=40)
        tbutton3=Button(scr,text='录入成绩',command=self.__setgrade,width=100,height=40)
        tbutton2=Button(scr,text='修改密码',command=self.__changepass,width=100,height=40)
        canvas.create_window(80, 70, width=100, height=40,window=tbutton1)
        canvas.create_window(80, 120, width=100, height=40,window=tbutton3)
        canvas.create_window(80, 170, width=100, height=40,window=tbutton2)

修改密码功能和学生的一样,不给出.

录入成绩

 def __setgrade(self):
        global sno
        global ssub
        global sgrade
        global sbutton4
        global smess4
        global smess3
        global smess2
        global smess1
        global front
        global back
        self.pos=1
        self.__clean()
        front=Button(scr,text='下一个',command=lambda :self.__choice(1,self.pos))
        back=Button(scr,text="前一个",command=lambda :self.__choice(-1,self.pos))
        sno=Entry(scr)
        ssub=Entry(scr)
        sgrade=Entry(scr)
        smess1=Label(scr,text='学号:',bg='white')
        smess3=Label(scr,text='成绩:',bg='white')
        smess2=Label(scr,text='科目:',bg='white')
        smess4=Label(scr,text='请先输入要录入的科目',bg='white')
        sbutton4=Button(scr,text='点击查询',command=self.__beginset,width=80,height=40)
        canvas.create_window(300, 70, width=120, height=20,window=ssub)
        canvas.create_window(200, 70, width=30, height=20,window=smess2)
        canvas.create_window(300, 30, width=180, height=40,window=smess4)
        canvas.create_window(300, 220, width=80, height=40,window=sbutton4)

    def __showeve(self):
        global teach
        teach=ssub.get()
        smess2.destroy()
        smess4.destroy()
        sbutton4.destroy()
        ssub.destroy()
        canvas.create_window(200, 120, width=30, height=20,window=smess1)
        canvas.create_window(200, 170, width=30, height=20,window=smess3)
        canvas.create_window(300, 170, width=120, height=20,window=sgrade)
        canvas.create_window(300, 120, width=120, height=20,window=sno)
        sql="select * from Student where cname ='{}'".format(teach)
        cursor.execute(sql)
        global data
        data=cursor.fetchall()
        print(len(data))
        sno.insert(0,data[0][0])
        sgrade.insert(0,data[0][4])
        canvas.create_window(250, 220, width=80, height=40,window=back)
        canvas.create_window(350, 220, width=80, height=40,window=front)
        scr.mainloop()

    def __choice(self,f,pos):
        set=int(sgrade.get())
        if set >100 or set <0 :
            tkinter.messagebox.showerror(title='错误',
                message='不能这样打分11111')  # 信息错误弹窗,点击确定返回值为 ok
        else:
            try:
                sql="update Student set igrade ={} where sno='{}' and cname='{}'".format(sgrade.get(),sno.get(),teach)
                cursor.execute(sql)
            except :
                tkinter.messagebox.showerror(title='错误',
                message='出了点问题1111')  # 信息错误弹窗,点击确定返回值为 ok
        self.pos=pos+f
        try:
            sno.delete(0,END)
            sgrade.delete(0,END)
            sno.insert(0,data[pos][0])
            sgrade.insert(0,data[pos][4])
        except :
            tkinter.messagebox.showerror(title='错误',
                message='到头了')  # 信息错误弹窗,点击确定返回值为 ok
            self.teach()

    def __beginset(self):
        global teach
        teach=ssub.get()
        sbutton4.destroy()
        flag=0
        sql="select * from Teacher where sno ='{}'".format(self.__sno)
        cursor.execute(sql)
        for i in cursor.fetchall():
            t=i[2].encode('latin1').decode('gbk')
            if t==teach :
                flag=1
        if flag==1:
            self.__showeve()
        else :
            tkinter.messagebox.showerror(title='错误',
                message='您未教该科目')  # 信息错误弹窗,点击确定返回值为 ok

首先通过要录入成绩的科目查询该老是是否教授该科目,如果是则显示学号以及成绩,然后进行顺序修改,通过按键进行录入学号成绩的移动,同时判断分数合法性.

修改成绩

def __grditgrade(self):
        global gno
        global gsub
        global ggrade
        global gmess1
        global gmess2
        global gmess3
        global gmess4
        global gbutton4
        global gButton5
        self.__clean()
        gno=Entry(scr)
        gsub=Entry(scr)
        ggrade=Entry(scr)
        gmess1=Label(scr,text='学号:',bg='white')
        gmess2=Label(scr,text='科目:',bg='white')
        gmess3=Label(scr,text='成绩:',bg='white')
        gmess4=Label(scr,text='请先输入要编辑的学生学号科目',bg='white')
        gbutton4=Button(scr,text='点击查询',command=self.__getinfstu,width=80,height=40)
        gButton5=Button(scr,text="点击提交",command=self.__commitgrade,width=80,height=40)
        canvas.create_window(200, 70, width=30, height=20,window=gmess1)
        canvas.create_window(200, 120, width=30, height=20,window=gmess2)
        canvas.create_window(200, 170, width=30, height=20,window=gmess3)
        canvas.create_window(300, 30, width=180, height=40,window=gmess4)
        canvas.create_window(300, 70, width=120, height=20,window=gno)
        canvas.create_window(300, 120, width=120, height=20,window=gsub)
        canvas.create_window(300, 170, width=120, height=20,window=ggrade)
        canvas.create_window(300, 220, width=80, height=40,window=gbutton4)

    def __getinfstu(self):
        ggrade.delete(0,END)
        sno=gno.get()
        subname=gsub.get()
        print(sno,subname)
        if is_ok(sno)  :
            try:
                cursor.execute("SELECT * FROM Student where sno='{}' and cname='{}'".format(sno,subname))
                data=cursor.fetchall()
                print(data)
                ggrade.insert(0,str(data[0][4]))
                
                canvas.create_window(300, 270, width=80, height=40,window=gButton5)
            except:
                tkinter.messagebox.showerror(title='错误',
        message='好像出了点问题,要不再试试?')  # 信息错误弹窗,点击确定返回值为 ok
        else:
            tkinter.messagebox.showerror(title='错误',
            message='错误输入')  # 信息错误弹窗,点击确定返回值为 ok
        

    def __commitgrade(self):
        newgrade=int(ggrade.get())
        if newgrade>100 or newgrade<0 :
            tkinter.messagebox.showwarning(title='???',
        message='分不是这样打的')  # 信息错误弹窗,点击确定返回值为 ok
        else :
            try:
                sql="update Student set igrade ={} where sno='{}' and cname='{}'".format(ggrade.get(),gno.get(),gsub.get())
                print(sql)
                cursor.execute(sql)
                tkinter.messagebox.showinfo(title='成功',
                message='更改成功') 
                self.__grditgrade()
            except :
                tkinter.messagebox.showerror(title='错误',
                message='出了点问题')  # 信息错误弹窗,点击确定返回值为 ok

首先通过学生学号科目查询,如果查询到就可以点击提交修改,没有则返回错误弹窗

总结

属于是数据库大作业最后几天赶工,以前也没试过带数据库的作业,最后写出来这个,可能写的不是太好但是作为学习的一部分也发出来

链接: https://pan.baidu.com/s/1fsc-vWNJhwCbAG94x_EfoA提取码: 56tk 复制这段内容后打开百度网盘手机App,操作更方便哦

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值