# lfs **Repository Path**: sunhacker/lfs ## Basic Information - **Project Name**: lfs - **Description**: 凌夕文件管理系统是基于SpringBoot3.x+Mybatis+Mybatis-Plus+VUE3+Element Plus开发的文件管理系统,支持单文件上传、分片上传,视频上传完成后,可以根据视频转码配置转成对于的视频格式,文档上传完成后,会转成pdf文件,目前支持word、excel、ppt、wps、text、rtf文件转成pdf。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 80 - **Created**: 2024-03-11 - **Last Updated**: 2024-03-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 凌夕文件管理系统是基于SpringBoot3.x+Mybatis+Mybatis-Plus+VUE3+Element Plus开发的文件管理系统, 支持单文件上传、分片上传,视频上传完成后,可以根据视频转码配置转成对应的视频格式(mp4、m3u8),文档上传完成后,会转成pdf文件, 支持word、excel、ppt、wps、text、rtf文件转成pdf。 支持音视频、图片、文档在线预览、下载、重命名、移动文件夹、删除等操作,支持文件分类查看。 前端git地址[]():[https://gitee.com/lxinet/lfs-vue](https://gitee.com/lxinet/lfs-vue) # 环境支持 数据库:mysql 缓存:redis 文件服务器:nginx 部署前需修改application.yml文件中的mysql和redis信息,需要部署nginx服务作为文件服务器,nginx配置可查看“本地存储”章节内容 # 开发框架 ## 后端 springboot3.x+mybatis+mybatis-plus ## 前端 vue3+element-plus+vite # 系统配置 ## 文件大小限制 默认支持2G文件上传,如果需要调整,修改application.yml中的以下2个参数: ```yaml spring: servlet: multipart: #单个文件最大限制 max-file-size: 2048MB #总上传文件总大小 max-request-size: 2048MB ``` ## 视频水印 视频水印只支持图片水印,要开启视频水印,需要先将视频水印图片放在项目目录下。 水印文件固定路径:/resources/static/watermark.png 可以开启、关闭水印,可以设置水印位置,具体可以看以下水印的配置信息。 ```yaml config: video: #视频水印,水印图片固定在位置:/resources/static/watermark.png watermark: #开启/关闭水印,true 开启,false 关闭 enable: true #水印位置 TOP_LEFT 左上角,TOP_RIGHT 右上角,BOTTOM_LEFT 左下角,BOTTOM_RIGHT 右下角 location: TOP_LEFT #x、y为对应4个角的距离,不能为负数,负数可能会报错 offset-x: 100 offset-y: 100 ``` ## 文档水印 文档水印只有在转成pdf后才可以添加水印,文档只能添加文字水印,可以配置当前时间。 可以开启、关闭水印,可以设置水印位置,具体可以看以下水印的配置信息。 ```yaml config: document: watermark: #开启/关闭水印,true 开启,false 关闭 enable: true #开启水印加上当前时间 time-enable: true #时间格式,yyyy 年、MM 月、dd 日、HH 小时、mm 分钟、ss 秒 time-format: yyyy-MM-dd HH:mm:ss #水印内容,如果开启时间,会在内容后面加上时间 content: 凌夕文件管理系统 #文字大小 font-size: 12 #行距 row-space: 100 #列距 col-space: 150 #透明度 alpha: 0.1 ``` ## 文件存储 文件存储支持本地文件存储和minio存储(还未完善,如果有需要,可以继续完善该功能),在application.yml中可以设置存储类型 ```yaml config: file-server: #文件服务,local/minio,local本地文件服务,minio minio服务 type: local ``` ### 本地存储 #### 存储目录和访问配置 本地存储需要配置本地存储文件路径(绝对路径)和本地文件预览地址,需要使用nginx配置file-dir的访问服务,preview-url为nginx配置的域名和端口。 ```yaml config: file-server: local: #本地文件上传路径 file-dir: /Users/zcx/develop/lfs/uploadFile #本地文件预览地址 preview-url: http://127.0.0.1:8918 ``` #### nginx配置 ```nginx server { listen 8918; server_name localhost; location ~ .*\.ts { root /Users/zcx/develop/lfs/uploadFile; } location ~ .*/thum/.* { root /Users/zcx/develop/lfs/uploadFile; } location / { root /Users/zcx/develop/lfs/uploadFile; index index.html index.htm; if ($arg_oper = "down") { add_header Content-Disposition "attachment;filename=$arg_filename"; } secure_link $arg_secret,$arg_expire; secure_link_md5 e9eaa184ac1b4068829edb4f3ea978f4$uri$arg_expire; if ($secure_link = "") { return 403; } if ($secure_link = "0") { return 403; } } } ``` #### 防盗链配置 防盗链需要配置密钥和有效期时间,需要nginx配置配合,nginx配置可以查看上节nginx配置,配置的密钥需要和nginx中的密钥一致。 ```yaml config: file-server: local: #密钥 secret: e9eaa184ac1b4068829edb4f3ea978f4 # 防盗链st有效时长(秒) st-effective-time: 86400 ``` ### minio存储(未完善) 需要配置minio服务相关信息,如下: ```yaml config: file-server: minio: access-key: HgiCBQslp8LDfNyWuTOj secret-key: 65Quqe4SR881xrs9je9A4vjRNtoWmkYvtT78mL9b url: http://127.0.0.1:9000 bucket-name: test ``` # 文件上传 目前未限制文件上传格式,如果有需要,可以增加限制。 每个上传ID只能上传一个文件,如果上传多个文件用同一个上传ID,会导致上传失败。 ## 本地文件存储 - 原文件:{config.file-server.local.file-dir}/files/{uuid+后缀} 如:/Users/zcx/develop/lfs/uploadFile/files/0cc01a75-399a-446c-8b26-902e95178856.mp4 - 视频转码文件:{config.file-server.local.file-dir}/trans/video/{uuid+后缀} 如:/Users/zcx/develop/lfs/uploadFile/trans/video/8ab4b994-a4a8-42f6-8b1d-55e6abbb123c.mp4 - 文档转码文件:{config.file-server.local.file-dir}/trans/document/{uuid+后缀} 如:/Users/zcx/develop/lfs/uploadFile/trans/document/8ab4b994-a4a8-42f6-8b1d-55e6abbb123c.mp4 - 视频hls文件: {config.file-server.local.file-dir}/trans/hls/uuid/video.m3u8 {config.file-server.local.file-dir}/trans/hls/uuid/video_{分片编号}.ts 如:/Users/zcx/develop/lfs/uploadFile/trans/hls/65498aa0-5b0e-4959-9127-fc1f57cc98d4/video.m3u8 /Users/zcx/develop/lfs/uploadFile/trans/hls/65498aa0-5b0e-4959-9127-fc1f57cc98d4/video_0.ts > 注:一个视频hls文件会有m3u8和ts两种文件格式,m3u8文件一个,ts文件若干个,每个ts文件有10秒视频,ts文件编号从0开始 - 视频封面文件:{config.file-server.local.file-dir}/thum/原文件md5值/截取图片所在秒数.jpg 如:/Users/zcx/develop/lfs/uploadFile/thum/db94fba515e9c0dc7cb20dbf06bc410c/1.jpg ## 文件分片上传流程 ### 正常流程 ![](./imgs/upload_file_flow.jpeg) ### 秒传 ![](./imgs/fast_upload_file_flow.jpeg) # 接口 ## 获取token 地址:/getToken 请求方式:POST 请求参数: - appId:YbcKSAlou6UREvkwJmTx - appSecret:95NmdotNX939f4gk7vTd3cHkMd8LhBcSzPn50G8c 响应数据: ```json { "code":0, "msg":"操作成功", "data":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiIiLCJpYXQiOjE3MDY1MDgwOTYsImV4cCI6MTcwNjUyMjQ5NiwiYXBwSWQiOiJMZ2lDQlFzbHA4TERmTnlXdWpNbyJ9.2sAq09kEpV7teYwqIa6CxRwzAQSVrv2TeMYy5A9NS_8" } ``` ## 上传初始化(秒传) 地址:/file/uploadInit 请求方式:POST header参数:token 请求参数: - dirId:文件夹id - fileName:文件名 - md5:文件md5 响应数据: - 正常上传: ```json { "code": 0, "data": { "upload": { //上传id,秒传时,不返回上传id "uploadId": "a0dacab1-7a04-4c5c-b751-46cea30ee974", //是否跳过上传,如果为true,说明秒传,不需要再调用上传文件接口,并且会返回文件id(fileId),如果为false,走正常上传流程 "skip": false, //文件id "fileId": 0 }, //服务当前使用的上传服务,local本地文件服务,minio minio服务 "fileServerType": "local" } } ``` - 秒传: ```json { "code": 0, "data": { "upload": { //上传id,秒传时,不返回上传id "uploadId": "", //是否跳过上传,如果为true,说明秒传,不需要再调用上传文件接口,并且会返回文件id(fileId),如果为false,走正常上传流程 "skip": true, //文件id "fileId": 1747524994864275458 }, "fileServerType": "local" } } ``` ## 上传文件/分片 地址:/file/upload 请求方式:POST header参数:token 请求参数: - file: 文件 - chunkNumber: 当前分片编号 - chunkTotal: 总分片数 - fileName: 文件名 - uploadId: 上传id,初始化接口获取到的上传id - dirId:文件夹id 响应数据: - 上传分片 ```json { "code":0, "msg":"分片上传完成", "data":0 } ``` - 合并完成 ```json { "code":0, "msg":"合并完成", "data":"1745604715384700930" } ``` ## 创建文件夹 地址:/file/dirAdd 请求方式:POST header参数:token 请求参数: - dirId:上级文件夹id - name:文件夹名称 响应数据: ```json { "code": 0, "msg": "操作成功" } ``` ## 文件/文件夹重命名 地址:/file/rename 请求方式:POST header参数:token 请求参数: - id:文件id - name:文件/文件夹新名字 响应数据: ```json { "code": 0, "msg": "操作成功" } ``` ## 获取文件列表(分页) 地址:/file/list 请求方式:GET header参数:token 请求参数: - dirId:所在文件夹id - pageNo:当前第几页,默认1 - pageSize:每页数量,默认10 响应数据: ```json { "code": 0, "msg": "操作成功", "data": { "records": [ { "id": "1750762969215533058", "name": "新建文件夹", "isDir": 1, "dirId": "0", "fileSize": "0", "duration": "0", "transStatus": 0, "createTime": "2024-01-26 06:09:54", "thumUrl": "", "fileType": 0 }, { "id": "1747889182539296769", "name": "6c26d76632e5b05779e3f2bc91e8aedf.m4v", "isDir": 0, "dirId": "0", "fileSize": "60221473", "suffix": ".m4v", "md5": "a67c7577e464acf66a802a2dddf2ee39", "duration": "31", "transStatus": 1, "createTime": "2024-01-18 07:50:29", "fileUrl": "http://127.0.0.1:8918/files/515f4fa8-0f1e-47b3-9f04-b922c9ab0371.m4v", "fileTransUrls": [ "http://127.0.0.1:8918/trans/hls/a62aaf96-07d4-42fd-b5e2-bc86cc61e73d/video.m3u8" ], "thumUrl": "http://127.0.0.1:8918/thum/a67c7577e464acf66a802a2dddf2ee39/1.jpg" } ], "total": "32", "size": "10", "current": "1", "pages": "4" } } ``` 参数说明: - id:文件ID - name:文件名 - isDir:是否文件名,0是文件,1是文件夹 - dirId:所在文件夹id - fileSize:文件大小(B) - suffix:文件后缀 - md5:文件md5 - duration:视频为时长(秒),文档为转pdf后的页数,其他文件为0 - transStatus:转码状态,0 正在转码,1 转码成功,2 部分转码成功,3 转码失败,4 不需要转码,5 不支持转码,6 取消转码 - createTime:上传时间,格式:yyyy-MM-dd HH:mm:ss - fileUrl:原文件地址 - fileTransUrls:转码后的文件列表(根据开启的转码模板数量而定) - thumUrl:文件封面地址 ## 获取文件详情 地址:/file/detail/ 请求方式:GET header参数:token 响应数据: ```json { "code": 0, "msg": "操作成功", "data": { "id": "1759776044321124353", "name": "文件管理系统.pptx", "isDir": 0, "dirId": "0", "fileSize": "2659028", "suffix": ".pptx", "md5": "269059d792de04d14ce3354d76b9d617", "duration": "25", "transStatus": 1, "createTime": "2024-02-20 03:04:38", "previewUrl": "http://127.0.0.1:8918/trans/document/39f8d3fa-fcea-4a1b-aefc-f916eca0d559.pdf?st=gy7dPuGlh2Io4mIQ-eCPQQ&e=1709703848", "progressList": [ { "id": "1759776044639891458", "fileTransId": "1759776224541978625", "progress": 100.0, "format": "pdf", "transStatus": 1, "startTime": "1708398278757", "endTime": "1708398321706", "previewUrl": "http://127.0.0.1:8918/trans/document/39f8d3fa-fcea-4a1b-aefc-f916eca0d559.pdf?st=gy7dPuGlh2Io4mIQ-eCPQQ&e=1709703848", "fileSize": "34518359" } ], "thumUrl": "http://127.0.0.1:8918/thum/269059d792de04d14ce3354d76b9d617/1.jpg?st=esCMdzh-HZeqA29W1fFUIA&e=1709703848", "fileType": 3, "pdfWatermark": "凌夕文件管理系统 2024-03-06 13:39:08" } } ``` 参数说明: - id:文件ID - name:文件名 - isDir:是否文件夹,0不是,1是文件夹 - dirId:文件所在文件夹id,最上层目录,为0 - fileSize:文件大小(B) - suffix:文件后缀 - md5:文件md5 - duration:视频为时长(秒),文档为转pdf后的页数,其他文件为0 - transStatus:转码状态,0 正在转码,1 转码成功,2 部分转码成功,3 转码失败,4 不需要转码,5 不支持转码,6 取消转码 - createTime:上传时间,格式:yyyy-MM-dd HH:mm:ss - thumUrl:文件封面地址 - fileType:文件大的类型,1为视频,2为文档 - previewUrl:文件预览地址 - pdfWatermark:pdf文件预览的水印内容,用element-plus实现页面水印 - progressList:转码进度列表,转码中和部分转码成功才会有该值,其他情况不会有该值,如果是视频,可能会多个进度,文档就一个进度,如果多个进度,当前转码进度需要取平均值 - id:转码进度id - fileTransId:转码后文件id - progress:转码进度 - format:转码格式 - transStatus:转码状态,0 正在转码,1 转码成功,2 部分转码成功,3 转码失败,4 不需要转码,5 不支持转码,6 取消转码 - startTime:开始转码时间(时间戳,毫秒) - endTime:结束转码时间(时间戳,毫秒) - previewUrl:转码后的文件预览地址 - fileSize:转码后的文件大小(B) ## 删除文件/文件夹 > 如果删除文件夹,文件夹下的文件和文件夹都会被删除 地址:/file/delete 请求方式:GET header参数:token 请求参数: - id:文件/文件夹id 响应数据: ```json { "code": 0, "msg": "操作成功" } ``` ## 获取转码模板列表 地址:/transTemplate/list 请求方式:GET header参数:token 请求参数:无 响应数据: ```json { "code": 0, "msg": "操作成功", "data": [ { "id": 1746778020070301697, "name": "普清", "status": 0, "width": 0, "height": 1080, "format": "m3u8", "frameRate": 20, "bitRate": 2000, "codec": "h264", "audioCodec": "aac", "audioChannel": 2, "audioBitRate": 112, "audioSampleRate": 8000, "createTime": "2024-01-15 06:15:08" } ] } ``` 参数说明: - id:模板ID - name:模板名称 - status:状态,是否开启转码,0 关闭,1 开启 - width:分辨率(宽) - height:分辨率(高) - format:转码输出格式 - frameRate:视频帧率 - codec:视频编解码器 - bitRate:视频比特率(码率) - audioBitRate:音频比特率(码率) - audioSampleRate:音频采样率 - audioChannel:音频声道 - audioCodec:音频编解码器 ## 新增/更新转码模板 地址:/transTemplate/save 请求方式:POST header参数:token 请求参数: - id:模板ID,新增时不要传该参数,是否有id参数是区分新增、更新操作 - name:模板名称 - width:分辨率(宽),如:1920 - height:分辨率(高),如:1080 - format:转码输出格式,可选:mp4、m3u8 - frameRate:视频帧率,可选:15、20、25、30、40、50、60 - codec:视频编解码器,可选:H264 - bitRate:视频比特率(码率),可选:500、800、1200、2000、3000、5000、8000 - audioBitRate:音频比特率(码率),可选:16、32、48、64、80、96、112、128、160、192、224、256、320、384、448、512 - audioSampleRate:音频采样率,可选:8000、11025、12000、16000、22050、24000、32000、44100、48000、64000、88200、96000 - audioChannel:音频声道,可选:1、2 - audioCodec:音频编解码器,可选:aac - waterMarkId:水印模板id 响应数据: ```json { "code": 0, "msg": "操作成功" } ``` ## 关闭/开启转码模板 地址:/transTemplate/updateStatus 请求方式:POST header参数:token 请求参数: - id:模板ID,新增时不要传该参数,是否有id参数是区分新增、更新操作 - status:状态,是否开启转码,0 关闭,1 开启 响应数据: - 成功 ```json { "code": 0, "msg": "操作成功" } ``` - 失败 ```json { "code": 1007, "msg": "视频转码模板不存在" } ``` ## 删除转码模板 地址:/transTemplate/delete 请求方式:POST header参数:token 请求参数: - id:模板ID 响应数据: - 成功 ```json { "code": 0, "msg": "操作成功" } ``` ## 文件上传成功后缩略图列表 文件上传后,如果马上调用该接口,可能返回的列表是空的,因为生成缩略图需要时间,可能需要几秒钟,所以在显示缩略图列表选择页面,如果获取到的数据是空的,最好重试几次,直到获取到数据、或者超时给用户提示。 地址:/file/thumList 请求方式:GET header参数:token 请求参数: - md5:文件md5 响应数据: - 成功 ```json { "code": 0, "msg": "操作成功", "data": [ { "id": 1747079912013021186, "fileUrl": "http://127.0.0.1:8918/thum/db94fba515e9c0dc7cb20dbf06bc410c/1.jpg", "duration": 1 } ] } ``` ## 更新文件缩略图 地址:/file/updateFileThum 请求方式:POST header参数:token 请求参数: - fileId:文件id - thumId:缩略图id 响应数据: ```json { "code": 0, "msg": "操作成功" } ``` ## 手动转码 地址:/file/manualTranscode 请求方式:POST header参数:token 请求参数: - fileId:文件id 响应数据: - 成功 ```json { "code": 0, "msg": "操作成功" } ``` - 失败 ```json { "code": 1012, "msg": "该文件不支持转码" } ``` ## 转码列表 地址:/transProgress/list 请求方式:GET header参数:token 请求参数: - pageNo:当前第几页,默认1 - pageSize:每页数量,默认10 响应数据: ```json { "code": 0, "msg": "操作成功", "data": { "records": [ { "id": "1749360770384216065", "fileId": "1749360770249998339", "fileTransId": "1749360775123779586", "progress": 100.0, "format": "pdf", "transStatus": 1, "startTime": "1705915083869", "endTime": "1705915085036", "fileName": "常用软件.xlsx", "createTime": "2024-01-22 09:18:03" } ], "total": "26", "size": "10", "current": "1", "pages": "3" } } ``` 参数说明: - id:转码ID - fileId:文件id - fileName:文件名 - fileTransId:转码后的文件id - progress:转码进度,0-100 - format:转码输出格式 - transStatus:转码状态,0 正在转码,1 转码成功,3 转码失败 - startTime:开始转码时间(时间戳) - endTime:完成转码时间(时间戳),进行中为0,如要计算进行中转码时长,使用当前时间进行计算 - createTime:创建转码时间,创建转码时,不一定马上开始转码了,开始转码时间要看startTime # 转码配置 ## 模板名称 设置模板名称 name ## 视频 ### 分辨率 分辨率可以设置宽和高,宽和高至少设置1个,另一个可以设置,也可以设置为0,如果设置为0,自动根据原视频宽高计算。 分辨率设置的是PAR(图像纵横比),默认未指定sar或者dar时,dar不会变,sar会被设置为跟par比例一样,所以转码的视频比例也不会变,宽度根据高度自动计算,即指定的宽度无效。 - PAR图像纵横比:PAR=(每行像素数)/(每列像素数)=分辨率 - SAR样点纵横比:SAR=(像素的宽)/(像素的高)。像素不一定都是正方形的。 - DAR显示纵横比:一般说的16:9和4:3指的是DAR。DAR=(每行像素数像素的宽)/(每列像素数像素的高),即DAR=PAR*SAR 480p=标清=640x480 720p=高清=1280×720p 1080p=蓝光=1920x1080p 2K=1440P=2560x1440 4K=2160P=3840x2160 8K=4320P= 7680×4320 高度默认:1080 宽度默认:0(自动计算) ### 转码格式 - 选项:mp4、m3u8 - 默认:mp4 ### 视频帧率 视频帧率是用于测量显示帧数的量度。所谓的测量单位为每秒显示帧数(Frames per Second,简:FPS)或"赫兹"(Hz) - 选项:15、20、25、30、40、50、60 - 默认:30 ### 视频比特率(码率 kbps) 通常也叫码率是指单位时间内传送的比特(bit)数,单位为bps(bit per second) - 选项:500、800、1200、2000、3000、5000、8000 - 默认:1200 ### 编解码器 H264通常也被称之为H264/AVC(或者H.264/MPEG-4 AVC或MPEG-4/H.264 AVC),H264有高效的视频压缩算法来压缩视频的占用空间,提高存储和传输的效率,在获得有效的压缩效果的同时,使得压缩过程引起的失真最小。H264是目前较为主流的编码标准。 - 选项:h264 - 默认:h264 ### 封面截图 每个md5的视频文件,会截取10张封面用来选择,截图规则是分别取第1、3、5、7秒、视频时长/2秒、视频时长/2 + 2秒、倒数第7、5、3、1秒的画面。 截图格式为jpg图片。 ## 音频 ### 编解码器 目前音频基本都用AAC编码,因为这个编码目前来说压缩率高,而且音质损失极底。 - 选项:aac - 默认:aac ### 声道 单声道:是指一个声音的通道,把来自不同方位的音频信号混合后统一由录音器材把它记录下来,再由一个扬声器进行重放(没有左右声道之分)。早期的收音机都是单声道的,耳机就一个耳朵。 双声道:是指有两个声音的通道,双声道是在空间放置两个互成一定角度的扬声器,每个扬声器单独由一个声道提供信号。双声道是二路输入,二路输出,但不一定是立体声。(左右声道都只有一路的信号输入),也称为双声道混和声。 - 选项:1、2 - 默认:2 ### 音频码率(音频比特率) 一般普通音质码率大致在80~164kbps左右,HQ高音质192~320kbps左右,SQ无损800~1500kbps左右,CD及其它无压缩音质数值过万甚至更高。 普通音质转成无损音质,并不是成了无损音乐,反而体积增大了,这就是所谓假无损。 - 选项:16、32、48、64、80、96、112、128、160、192、224、256、320、384、448、512 - 默认:128 ### 音频采样率 音频采样率是指录音设备在一秒钟内对声音信号的采样次数,它决定了数字音频信号的分辨率。采样率的单位通常是赫兹(Hz)。采样率越高,理论上能够捕捉到的声音细节越多,从而产生的声音质量也更高。 - 选项:8000、11025、12000、16000、22050、24000、32000、44100、48000、64000、88200、96000 - 默认:48000 - 部分说明: 8000 Hz:电话所用采样率, 对于人的说话已经足够 11025 Hz:电话所用采样率 22050 Hz:无线电广播所用采样率 32000 Hz:miniDV 数码视频 camcoRDer、DAT (LP mode)所用采样率 44100 Hz:音频 CD, 也常用于 MPEG-1 音频(VCD, SVCD, MP3)所用采样率 48000 Hz:miniDV、数字电视、DVD、DAT、电影和专业音频所用的数字声音所用采样率 96000 Hz:DVD-Audio、一些 LPCM DVD 音轨、BD-ROM(蓝光盘)音轨、和 HD-DVD (高清晰度 DVD)音轨所用所用采样率 # 转码 ## 转码流程 ![](./imgs/trans_flow.jpeg)