# image-CloudDisk **Repository Path**: gu-zhaowei/image-cloud-disk ## Basic Information - **Project Name**: image-CloudDisk - **Description**: image-CloudDisk是一个Vue练手项目,由个人开发者负责维护,旨在向前端初学者和Vue使用者提供真实的项目开发经验。 - **Primary Language**: JavaScript - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 23 - **Created**: 2021-10-08 - **Last Updated**: 2022-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 项目详细文档 --- # 项目信息 ## 1.这是一个什么项目? image-CloudDisk是一个Vue练手项目,由个人开发者负责维护,旨在向前端初学者和Vue使用者提供**真实的项目开发经验**。 在客户端,我们提供了完整的源代码,各位可以结合示例代码,开发自己的客户端。 在服务器端,我们提供大量的真实API,并附带翔实的接口文档。 ![项目展示](https://alonepluto.info/api/cloud/i1.jpg) ![项目展示](https://alonepluto.info/api/cloud/i2.jpg) ## 2.我能学到什么? iamge-CloudDisk是一个照片和视频的云盘管理程序,通过学习开发这一前端项目,我们相信你会对如下内容有深入理解: * Vue组件通信 * Vue生命周期 * Vue组件化开发 * 事件总线与状态管理 * 异步请求与事件循环 * promise async/await * 前端处理二进制数据 * 大文件分片上传 * 前端分页与后端分页 * 缩略图与canvas * 网络通信与请求头 * ... ## 3.项目完成后,可以把项目部署到服务器吗? 对于正在求职的开发者,我们可以提供一个有限时间的域名地址和服务器空间,让你的项目在线上真正跑起来,提高面试通过几率。 你可以联系我们,只要你的项目功能完整,界面优美,我们就可以将你的项目部署到服务器。 # 接口文档 ## 一、调用前必读 ### 1. 项目技术栈 * 前端框架:Vue2.x * 后端框架:Koa * UI库:Vuetify https://vuetifyjs.com/zh-Hans/getting-started/installation/ * 图标库:Material Design https://material.iconhelper.cn/ * 数据库:mysql ### 2.费用 服务器由项目维护者提供,维护开源项目不易,请大家珍惜资源 ### 3.仓库管理 欢迎向仓库issue你的想法、建议和代码 如果你愿意参与到这个项目中,我们非常欢迎 扫码联系项目维护者: ![weixin](https://alonepluto.info/api/cloud/weixin.jpeg) ## 二、基本配置 ### 1. baseURL 在这里,我们提供一个基础的网络请求地址,接下来的所有url都以此地址为baseURL ```javascript baseURL:'https://alonepluto.info/api/cloud/v1' ``` 如果你使用了axios,那么你可以在实例中使用baseURL ```javascript const instance = axios.create({ baseURL:'https://alonepluto.info/api/cloud/v1', timeout:3000 }) ``` ### 2. SecretKey 为了防止接口被恶意调用,节约服务器资源,调用**所有接口均需向服务器传递SecretKey(/test接口除外)**,你需要在发送网络请求时,设置自定义请求头SecretKey,下面以axios为例: ```javascript axios({ method:'get' url:'/login', //设置请求头,建议使用拦截器自动添加请求头 headers:{ SecretKey:'e8feJD8fje9jfkellppzw80eYmTTs' } }) ``` **你可以向项目维护者索要最新的SecretKey** ### 3. token 前后端通信通过token保持登录状态 登录成功后,服务器端会向前端返回一个token值,后续前端发起网络请求时,均需向服务器传递token(/test接口除外),以验证身份。无token或token过期,则网络请求失败。 服务器端拦截网络请求的请求头,通过Authorization字段获取token值,因此,前端发起网络请求时,需要设置请求头,下面以axios为例: ```javascript axios({ method:'post' url:'/edit', //设置请求头,建议使用拦截器自动添加请求头 headers:{ Authorization:'gkrlkoxg5ffFE89vjke77HJK' } }) ``` ### 4.静态资源的下载 在客户端,点击一个图片或视频链接,可直接下载资源,而不是在一个新窗口打开资源,这极大简化了开发者从服务器下载静态资源的步骤,开发者无需再编写额外的业务代码 ```javascript //客户端 //将资源url赋值给a标签,点击后可直接下载 const a = document.createElement("a"); a.setAttribute("href", this.file.file_src); a.click(); ``` ```javascript //服务器端 //响应类型为通用文件类型 ctx.set("content-type", "application/octet-stream"); //要求浏览器下载文件,而不是在浏览器中进行展示 ctx.set( "Content-Disposition", `attachment;filename=${ctx.url.split("/").pop()}` ); ``` 实现这一功能的关键在于服务器端设置了特殊的响应头,它强制要求浏览器直接下载资源,而不需要打开它 **如果你不了解nodejs可忽略这部分内容,你只需要知道,请求服务器端静态资源,会直接下载该资源** ### 5.网络测试接口 服务器暴露了一个网络测试接口,接口地址:'/test',请求方法:'get',如果请求test接口返回如下内容,说明服务器工作正常 ```javascript { code:825, message:'网络通信正常' } ``` * test接口通常用于前后端通信调试,无实际业务意义 ## 三、API ### A. 登录接口 #### 1.登录 * 说明:用于用户登录 * 接口地址:'/login/login' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------------- | -------- | ------ | -------- | ---------------------- | | user_name | 用户名 | String | 是 | user_name:'admin' | | user_password | 用户密码 | String | 是 | user_password:'123456' | * 返回值 ```javascript { //服务器自定义状态码 code:802, //响应结果 message:'登录成功', //响应数据 data:{ //用户详细信息 user:{}, //令牌,用于后续请求服务器数据时验证身份 token:'e8Vufe8JFKLEV9989je8Vhkf8v', //用户收藏夹列表 folders:[] } } ``` #### 2.注册 * 说明:用于新用户注册 * 接口地址:'/login/signin' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------------- | ---------------------------------- | ------ | -------- | ----------- | | user_name | 用户名 | String | 是 | - | | user_password | 用户密码 | String | 是 | - | | user_question | 用户密保问题 | String | 否 | - | | user_answer | 密保问题答案 | String | 否 | - | | mock | **服务器虚拟10天的数据,建议使用** | String | 否 | mock:'mock' | * 返回值 ```javascript { //服务器自定义状态码 code:820, //响应结果 message:'注册成功', } ``` * 提示: 1. 建议用户密码使用MD5加密后再传输 2. 注册用户名必须唯一 3. 服务器会对用户名进行验证,对于长度错误、使用非法字符或者重名的用户名会拒绝注册,因此,发起网络请求前,开发者最好先行对用户名进行验证 4. 建议开发者在开发注册功能时设置密保问题和答案,否则密码重置功能不可用 #### 3.校验用户名 * 说明:用于新用户注册时,请求服务器验证用户名是否已存在 * 接口地址:'/login/checkname' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | ---------- | ------ | -------- | ---- | | user_name | 用户注册名 | String | 是 | - | * 返回值: ```javascript { //服务器自定义状态码 code:810, //响应结果 message:'验证成功,用户名可用', } ``` * 提示: 为了良好的用户体验,前端最好在发起注册请求前,先行验证用户输入的注册名是否在服务器已存在 你可以在用户名输入框失去焦点时请求此接口 #### 4.重置密码 * 说明:用于用户忘记登录密码时,重置密码 * 接口地址:'/login/resetpassword' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------------- | ---------- | ------ | -------- | ---- | | user_name | 用户名 | String | 是 | - | | user_password | 用户新密码 | String | 是 | - | * 返回值: ```javascript { //服务器自定义状态码 code:808, //响应结果 message:'操作成功', } ``` #### 5.获取密保问题列表 * 说明:获取由服务器提供的密保问题列表,当然,你也可以自己设置一个密保问题,不过这不是一个好的选择 * 接口地址:'/login/getquestions', * 请求方法:'get' * 参数:无 * 返回值: ```javascript { //服务器自定义状态码 code:800, //响应结果 message:'查询成功,返回结果', //密保问题列表 data:[ "你最想去的星球?", "你最喜欢的一本书?", "你最讨厌的水果?", "你最难忘的人?" ] } ``` #### 6.获取用户密保问题和答案 * 说明:获取用户预先设置的密保问题和答案,用以重置密码时验证用户身份 * 接口地址:'/login/getuserquestion' * 请求方法:'get', * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | ------ | ------ | -------- | ---- | | user_name | 用户名 | String | 是 | - | * 返回值: ```javascript { //服务器自定义状态码 code:800, //响应结果 message:'查询成功,返回结果', //密保问题列表 data:{ user_question:'你最讨厌的水果?', user_answer:'榴莲' } } ``` ### B. 数据接口 #### 1.请求时间戳分页数据 * 说明:请求时间戳功能的数据 * 接口地址:'/data/getTimelineDataLimit' * 请求方法:'get' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------ | ---------------- | ------ | -------- | ---- | | page | 请求第几页数据 | Number | 是 | 0 | | limit | 每页显示几条数据 | Number | 是 | | * 返回值: ```javascript { code:800, message:'查询成功,返回结果', data:[ [{...},{...},{...}], [{...}], [{...},{...}], ... ] } ``` * 提示: 返回的数据为一个二维数组,每个数组中储存相同日期上传的所有图片和视频,数组元素按时间降序排列 #### 2.请求时间戳全部数据 * 说明:以时间戳的方法获取全部数据 * 接口地址:'/data/getTimelineData' * 请求方法:'get' * 参数:无 * 返回值: ```javascript { code:800, message:'查询成功,返回结果', data:[ [{...},{...},{...}], [{...}], [{...},{...}], ... ] } ``` #### 3.请求全部图片数据 * 说明:一次性请求用户上传的所有图片格式的数据 * 接口地址:'/data/getImageData' * 请求方法:'get' * 参数:无 * 返回值: ```javascript { code:800, message:'查询成功,返回结果', data:[ {...}, {...}, ... ] } ``` * 提示: 返回的是一个一维数组,所有的数据按时间降序排列 #### 4.请求全部视频数据 * 说明:一次性请求用户上传的所有视频格式的数据 * 接口地址:'/data/getvideoData' * 请求方法:'get' * 参数:无 * 返回值: ```javascript { code:800, message:'查询成功,返回结果', data:[ {...}, {...}, ... ] } ``` * 提示: 返回的是一个一维数组,所有的数据按时间降序排列 #### 5.分页请求全部数据 * 说明:灵活地按照资源类型分页请求数据 * 接口地址:'/data/getDataLimit' * 请求方法:'get', * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------ | ---------- | ------ | -------- | ---------------------------------------------------- | | type | 资源类型 | String | 否 | 默认值all,即同时请求图片和视频,可选值为image和video | | page | 分页 | Number | 是 | - | | limit | 每页数据量 | Number | 是 | - | #### 6.请求特定日期的数据 * 说明:请求特定日期的数据 * 接口地址:'/data/getDateData' * 请求方法:'get' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | -------- | ------ | -------- | --------------------------- | | date_list | 日期数组 | Array | 是 | ['2021/06/02','2021/06/03'] | * 返回值 ```javascript { code:800, message:'查询成功,返回结果', data:[ {'2021/06/02':[{...},{...}]}, {'2021/06/03':[{...}]} ] } ``` * 提示: 响应结果为数组,数组元素为以查询日期为键的键值对 #### 7.数据统计 * 说明:获取用户上传的图片的数量、视频的数量、上传文件的总大小 * 接口地址:'/data/getCounter' * 请求方法:'get' * 参数:无 * 返回值: ```javascript { code:800, message:'查询成功,返回结果', data:{ image:20, video:15, size:9866234 } } ``` #### 8.创建收藏夹 * 说明: * 接口地址:'/data/foundfolder' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ----------- | ---------- | ------ | -------- | ---- | | folder_name | 收藏夹名称 | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` #### 9.删除收藏夹 * 说明:删除用户收藏夹 * 接口地址:'/data/deleteFolder' * 请求方法:'delete' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ----------- | ---------- | ------ | -------- | ---- | | folder_name | 收藏夹名称 | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` #### 10.将文件添加到收藏夹 * 说明:将图片或视频添加到用户已创建的收藏夹 * 接口地址:'/data/addFolder' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ----------- | ---------------- | ------ | -------- | ---- | | file_id | 文件ID | String | 是 | - | | file_folder | 添加到哪个收藏夹 | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` #### 11.删除文件 * 说明: * 接口地址:'/data/deleteFile' * 请求方法:'delete' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------- | ------ | ------ | -------- | ---- | | file_id | 文件ID | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` #### 12.文件重命名 * 说明:删除单个文件 * 接口地址:'/data/renameFile' * 请求方法:'put' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | ---------- | ------ | -------- | ---- | | file_id | 文件ID | String | 是 | - | | file_name | 文件新名称 | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` #### 13.批量删除文件 * 说明:批量删除文件 * 接口地址:'/data/bulkDelete' * 请求方法:'delete' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | ------------------ | ------ | -------- | ---- | | file_list | 要删除的文件ID数组 | Array | 是 | - | * 返回值: ```javascript { code:814, message:'批量删除成功', //响应数据为成功删除的文件ID列表 data:[ '1658938495', '1690697063' ] } ``` #### 14.请求收藏夹数据 * 说明:统计同一个收藏夹下的图片和视频的数量 * 接口地址:'/data/getFolderData' * 请求方法:'get' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------ | ---------- | ------ | -------- | ---- | | folder | 收藏夹名称 | String | 是 | - | * 返回值: ```javascript { code:800, message:'查询成功,返回结果', //返回统计结果和明细 data:{ counter:{ image:4, video:2 }, result:[ {...}, {...}, ... ] } } ``` #### 15.编辑备忘 * 说明:编辑备忘内容 * 接口地址:'/data/editMemo' * 请求方法:'put' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | -------- | ------ | -------- | ---- | | file_id | 文件ID | String | 是 | - | | file_memo | 备忘内容 | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` ### C. 上传接口 #### 1.上传 * 说明:文件上传接口 * 接口地址:'/upload/upload' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------ | ---------------- | ------ | -------- | ---- | | hash | 文件唯一性标识符 | String | 是 | - | | index | 文件切片索引 | String | 是 | - | | chunk | 文件切片 | Binary | 是 | - | * 返回值: ```javascript { //服务器自定义状态码 code:812, //响应结果 message:'上传成功', } ``` * 提示: 1. 切片大小不可超过2MB,否则服务器拒绝上传 2. 请使用FormData上传文件 #### 2.合并 * 说明:切片全部上传后,请求此接口,可将切片重新合并成图像 * 接口地址:'/upload/completed' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | --------- | -------------------------- | ------ | -------- | ----------------------------- | | hash | 文件唯一性标识符 | String | 是 | | | chunkNum | 切片总数量 | Number | 是 | | | file_name | 文件名称 | String | 是 | i-1.jpg | | file_size | 文件大小 | Number | 是 | | | file_type | 文件类型 | String | 是 | image/jpeg、video/mp4 | | file_mini | 文件缩略图,base64编码格式 | String | 是 | data:image/png;base64,iVB.... | * 返回值: ```javascript { code:808, messge:'操作成功', data:{ //文件ID file_id:165689452888, //文件名 file_name:'i-2.jpg', //文件服务器地址 file_src:'http://127.0.0.1:3000/static/162656911656/image/origin/i-2.jpg', //缩略图服务器地址 file_mini:'http://127.0.0.1:3000/static/162656911656/image/mini/e5feb634f48.png', //文件所有者ID file_owner:162656911656, //文件上传年份 file_year:2021, //文件上传月份 file_month:05, //文件上传日期 file_day:12, //文件上传完整时间 file_time:2021/05/12, //文件大小 file_size:85625, //文件类型 file_type:'image/jpg' } } ``` ### D. 用户接口 #### 1.上传头像 * 说明:将一张头像图片上传到服务器 * 接口地址:'/user/uploadAvatar' * 请求方法:'post' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ----------- | ------------ | ------ | -------- | ---- | | user_avatar | 用户头像图片 | File | 是 | - | * 返回值: ```javascript { code:812, message:'上传成功' } ``` * 提示: 1. 头像大小不可超过20KB,否则服务器拒绝上传 #### 2.修改密码 * 说明:用户修改登录密码 * 接口地址:'/user/changePassword' * 请求方法:'put' * 参数: | 参数名 | 说明 | 值类型 | 是否必选 | 示例 | | ------------- | ---------- | ------ | -------- | ---- | | user_password | 用户新密码 | String | 是 | - | * 返回值: ```javascript { code:808, message:'操作成功' } ``` #### 3.编辑密保问题 * 说明:编辑用户密保问题和答案 * 接口地址:'/user/editQuestion' * 请求方法:'post' * 参数: | 参数值 | 说明 | 值类型 | 是否必选 | 示例 | | ------------- | ------------ | ------ | -------- | ---- | | user_question | 用户密保问题 | String | 是 | - | | user_answer | 密保问题答案 | String | 是 | - | * 返回值: ```javascript { code:808. message:'操作成功' } ```