# networkDisk **Repository Path**: Weihao_Yang/network-disk ## Basic Information - **Project Name**: networkDisk - **Description**: qt + Mysql 搭建的网盘客户端及服务端的实现 - **Primary Language**: C++ - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 2 - **Forks**: 0 - **Created**: 2023-03-14 - **Last Updated**: 2024-09-02 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 网盘设计 用于创建网盘,用户可以登录,然后将文件上传到服务器、重服务器中下载文件、和好友对话聊天,或者对其传输文件 ## 1. 数据库设计 1. 密码表 1. uid,用户ID,唯一标识符 1. uName,用户名称,用于登录 1. password,用户密码,用于登录 2. 好友表 1. id,表索引 2. uid,好友关系的甲方ID 3. friendid,好友关系的乙方ID 3. 记录表 1. id,表索引 2. type,操作类型,聊天,下载文件,上传文件,分享文件,删除文件 3. uid,操作方id 4. aid,接受方id,可能是上传到服务器,接收方id就为0 4. 文件表 1. id,表索引 2. uid,上传用户 3. fileName,文件名称 4. filePath,文件存储目录 5. fileSize,文件大小 6. updateTime,文件上传时间 7. downloadCount, 文件下载次数 5. 消息表 1. id,表索引 2. uid,发送方id 3. acid,接收方id 4. new,消息信息 ## 2. 页面设计 ### 1. 登录页面 仿照Tim登录页面设计 打开程序就链接数据库,当用户点击登录时,查询密码表,匹配uid和密码是否匹配 关于记住密码和自动登录,使用文件的形式 登录成功后: 1. 当用户点击记住密码时,将这次登录的uid,密码写入到文件中(这里是将上面的文件先读取,将这次登录的用户名密码写入到文件的最前面,为保证下次打开时读取文件第一条用户信息,然后写入到用户名密码框中) 2. 当用户没有选择记住密码时,直接将用户名进行保存 ### 2. 主页面 #### 2.1 用户信息 用户信息的显示使用group box里面放置几个标签,用于显示 #### 2.2 好友列表 好友列表使用ToolBox,每个项采用自定义Widget,UserWidget,这里的UserWidget显示用户名,用户上传文件数,在在线状态 当双击用户Widget时,将右侧的TabWidget跳转到对话页面,建立与好友的对话 2.3 对话TabWidget 对话TabWidget是在一个大的TabWidget中的,其中包含了主页Widget,对话Widge,下载Widget 这里的对话TabWidget是自定义Widget,重写了dragEnterEvent(),dragLeaveEvent(),mouseReleaseEvent()。方便用户将本地的文件拖入页面以通过对话Widget来将文件传输给好友 ##### 2.3.1 对话的实现 这里是想法 1. ~~与用户的对话存到数据库中,每次登录后从数据库中读取信息然后显示~~ 2. ~~创建socket,每个用户登录,然后点击好友时就尝试连接socket,然后进行通话,并将数据传入数据库中~~ 3. 编写服务器程序,每两个用户进行链接都连接到服务器中,然后都向服务器发送数据,其中传递要发送的uid,服务器再转发给指定用户,并将发送的消息传入数据库 (我感觉是这个比较靠谱) - [x] ~~是否要考虑要对话的双方都要连接到服务端~~ - [x] 对与单方面连接到服务器的发送的消息应该如何处理 * 对与消息的数据库就要进行修改 * 我在想,是不是要对整个数据库进行修改,每个用户都创建一个表,用于保存和其好友的聊天信息(好像不用) - [x] 发送给服务端的数据格式应该是什么样的 * 发送方id\r接受方id\r发送消息\r发送时间\r状态信息 * 然后接收方按照\r来进行spilt获取每个部分信息,最后写入到数据库中,返回信息 - [ ] 服务端收到信息该如何处理 - [x] 发送方可能发送的是消息,即文本信息,直接经过分割获取信息直接传入数据库中 对于文本消息,发送方会将发送发id和接收方id加上发送的内容,一并发送给服务端,服务端再进行切割,取得双方的信息 - [ ] 发送方可能发送的是文件,该如何处理? - [ ] 传递的消息中应该包含消息的类型,服务端根据消息的类型来选择将消息写入到哪个数据库表中 - [ ] 对于文件类型是不是要传递很多的消息,包括文件的大小,文件名,文件路径,这相对于纯文本消息是有很大区别的,这该如何处理 这就需要将消息类型放到最前面,针对于不同的消息采用不同的字符串分割方式 - [x] 双击是否就进行socket连接? - [x] 什么时候断开连接? 用户双击另一个用户时重新建立对话时,断开上一个连接,或者用户关闭界面 - [x] 如何断开连接? TcpScoket中有一个disconnectFromHost,可以从host中断开连接,并触发disconnected信号 - [x] 用户点击同一个用户多次如何处理? 用户双击时都会先将窗体的名称进行修改,则可以在修改前先判断这次点击的userWidget中的sendName和acceptName组成的字符串是否和主窗体的字符串一致即可 4. 各界面之间值的传递是个问题? - [x] 传递的值是用户名还是用户uid? - [x] 如果传递的是uid,用户名该如何显示到界面上? 那就用户名和uid都传过去,在第一次初始化好友列表的时候,绑定每个好友,其Widget都有发送发id,发送方name,接收方id,接收方name - [x] ~~数据库什么时候连接,每次用户点击对话都进行一次数据库连接断开?~~ - [x] 当用户打开界面时,数据库一直连着? 因为是在服务端将用户对话信息写入到数据库中的,所以打开用户界面时,就要连接数据库,切换用户仅仅是切换userWidget,这样其中的参数就不同,从而可以向数据库中写入 5. 发送方如何显示刚刚发送的,和以前发送的消息? - [x] ~~自定义一个widget?然后再将结果放到Widget中,最后在TabWidget中添加一个Frame,一一添加到其中,按照垂直排列~~ - [x] ~~如何定义这个widget?~~ - [x] 采用textbrowser的方式承接发送的消息 - [x] 这个browser既可以显示文字也可以显示图片,包括很多的文字格式,大小,相当于浏览器界面,可插入html代码来显示 - [x] 对于以前的消息的处理 - [x] 采用查询数据库的方式,将new中的消息,与这次消息匹配的两个用户消息经过时间排序进行添加到界面中。 - [x] 这个更新应在切换界面的时候就进行,而不是在用户点击发送时发生 - [x] 还需要将前面建立连接的好友对话填充的消息进行清空 6. 数据库中还有关于当前消息的状态信息, 即当接收方双击了用户,即表示接收方已经接收到了当前信息,状态位置为1,默认为0 - [x] 如何实现? 用户双击好友时,既显示自己发送的信息,也显示好友发送的信息 这个在客户端方进行修改 - [x] ~~是否要在好友列表处显示有未读消息的个数?就像qq一样?~~ - [x] ~~如何实现?~~ 可以创建一个label,放在UserWidget中,然后利用QPainter将其绘制为圆形,然后在用户点击该ToolButton时,就去数据库中查询,status为0的消息的个数,然后再设置改label的文字 思路大概就是这样,我就不实现了 #### 2.4 文件页面 ​ 3/23日着手 1. 打算显示用户上传的文件 2. 用户双击文件就会进行下载,并跳转到下载页面 3. 要解决的问题 - [ ] 如何能获取上传文件的文件图标 ​ 之前在进行用户对话的时候就尝试获取拖入界面中应用程序的图标了,但是没有成功 ​ QDropEvent->mimeData()->text()获得的是以file:////开头的文件,要想传递给QFileInfo要将其去除 ​ 想法: 1. 自己创建一种label,用户每个文件的显示都是对应文件的图标 1. 然后这了label按照网格式排序 1. 用户登录时就从数据库中查询文件,并创建一个label来承接文件类型 - [ ] 那么是不是file文件中要保存文件类型? - [ ] 对于文件类型是不是还要保存文件图标图片到服务器上,对应文件使用对应的图标? 想法: ​ 对于保存上传文件的服务器搭建在windows端? ​ 然后用户连接不同的服务器? ​ 还是服务端依然在linux,然后上传时需要将文件图标一并上传? 4. 用户拖入窗口,进行上传文件