Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
nizhengjia888
gin-vue-admin
提交
640fb53f
G
gin-vue-admin
项目概览
nizhengjia888
/
gin-vue-admin
与 Fork 源项目一致
Fork自
FLIPPED-AURORA / gin-vue-admin
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
G
gin-vue-admin
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
640fb53f
编写于
1月 21, 2020
作者:
Mr.奇淼(
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
断点续传 开发中
上级
20ab5a8d
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
306 addition
and
14 deletion
+306
-14
QMPlusServer/controller/api/exa_breakpoint_continue.go
QMPlusServer/controller/api/exa_breakpoint_continue.go
+118
-0
QMPlusServer/controller/servers/breakpoint_continue.go
QMPlusServer/controller/servers/breakpoint_continue.go
+75
-0
QMPlusServer/init/initRouter/init_router.go
QMPlusServer/init/initRouter/init_router.go
+2
-1
QMPlusServer/init/registTable/regist_table.go
QMPlusServer/init/registTable/regist_table.go
+3
-1
QMPlusServer/middleware/cors.go
QMPlusServer/middleware/cors.go
+25
-0
QMPlusServer/model/dbModel/exa_breakpoint_continue.go
QMPlusServer/model/dbModel/exa_breakpoint_continue.go
+68
-0
QMPlusServer/model/sysModel/sys_user.go
QMPlusServer/model/sysModel/sys_user.go
+4
-4
QMPlusServer/router/exp_fileUploadAndDownload.go
QMPlusServer/router/exp_fileUploadAndDownload.go
+9
-6
QMPlusServer/tools/md5.go
QMPlusServer/tools/md5.go
+2
-2
未找到文件。
QMPlusServer/controller/api/exa_breakpoint_continue.go
0 → 100644
浏览文件 @
640fb53f
package
api
import
(
"fmt"
"gin-vue-admin/controller/servers"
"gin-vue-admin/model/dbModel"
"github.com/gin-gonic/gin"
"io/ioutil"
"strconv"
)
// @Tags ExaFileUploadAndDownload
// @Summary 断点续传到服务器
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file formData file true "断点续传示例"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"上传成功"}"
// @Router /fileUploadAndDownload/breakpointContinue [post]
func
BreakpointContinue
(
c
*
gin
.
Context
)
{
fileMd5
:=
c
.
Request
.
FormValue
(
"fileMd5"
)
fileName
:=
c
.
Request
.
FormValue
(
"fileName"
)
chunkMd5
:=
c
.
Request
.
FormValue
(
"chunkMd5"
)
chunkNumber
,
_
:=
strconv
.
Atoi
(
c
.
Request
.
FormValue
(
"chunkNumber"
))
chunkTotal
,
_
:=
strconv
.
Atoi
(
c
.
Request
.
FormValue
(
"chunkTotal"
))
_
,
FileHeader
,
err
:=
c
.
Request
.
FormFile
(
"file"
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
false
,
fmt
.
Sprintf
(
"%v"
,
err
),
gin
.
H
{})
}
else
{
f
,
err
:=
FileHeader
.
Open
()
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
false
,
fmt
.
Sprintf
(
"%v"
,
err
),
gin
.
H
{})
}
else
{
cen
,
_
:=
ioutil
.
ReadAll
(
f
)
defer
f
.
Close
()
if
flag
:=
servers
.
CheckMd5
(
cen
,
chunkMd5
);
flag
{
err
,
file
:=
new
(
dbModel
.
ExaFile
)
.
FindOrCreateFile
(
fileMd5
,
fileName
,
chunkTotal
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
false
,
fmt
.
Sprintf
(
"%v"
,
err
),
gin
.
H
{})
}
else
{
err
,
pathc
:=
servers
.
BreakPointContinue
(
cen
,
fileName
,
chunkNumber
,
chunkTotal
,
fileMd5
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
false
,
fmt
.
Sprintf
(
"%v"
,
err
),
gin
.
H
{})
}
else
{
err
=
file
.
CreateFileChunk
(
pathc
,
chunkNumber
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
false
,
fmt
.
Sprintf
(
"%v"
,
err
),
gin
.
H
{})
}
else
{
servers
.
ReportFormat
(
c
,
true
,
"切片创建成功"
,
gin
.
H
{})
}
}
}
}
else
{
}
}
}
}
// @Tags ExaFileUploadAndDownload
// @Summary 查找文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file params file true "查找文件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
// @Router /fileUploadAndDownload/findFile [post]
func
FindFile
(
c
*
gin
.
Context
)
{
fileMd5
:=
c
.
Query
(
"fileMd5"
)
fileName
:=
c
.
Query
(
"fileName"
)
chunkTotal
,
_
:=
strconv
.
Atoi
(
c
.
Query
(
"chunkTotal"
))
err
,
file
:=
new
(
dbModel
.
ExaFile
)
.
FindOrCreateFile
(
fileMd5
,
fileName
,
chunkTotal
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
false
,
fmt
.
Sprintf
(
"查找失败:%v"
,
err
),
gin
.
H
{})
}
else
{
servers
.
ReportFormat
(
c
,
true
,
"查找成功"
,
gin
.
H
{
"file"
:
file
})
}
}
// @Tags ExaFileUploadAndDownload
// @Summary 查找文件
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file params file true "查找文件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
// @Router /fileUploadAndDownload/findFile [post]
func
BreakpointContinueFinish
(
c
*
gin
.
Context
)
{
fileMd5
:=
c
.
Query
(
"fileMd5"
)
fileName
:=
c
.
Query
(
"fileName"
)
err
,
filePath
:=
servers
.
MakeFile
(
fileName
,
fileMd5
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
true
,
fmt
.
Sprintf
(
"文件创建失败:%v"
,
err
),
gin
.
H
{})
}
else
{
servers
.
ReportFormat
(
c
,
true
,
"文件创建成功"
,
gin
.
H
{
"filePath"
:
filePath
})
}
}
// @Tags ExaFileUploadAndDownload
// @Summary 删除切片
// @Security ApiKeyAuth
// @accept multipart/form-data
// @Produce application/json
// @Param file params file true "查找文件"
// @Success 200 {string} string "{"success":true,"data":{},"msg":"查找成功"}"
// @Router /fileUploadAndDownload/removeChunk [post]
func
RemoveChunk
(
c
*
gin
.
Context
)
{
fileMd5
:=
c
.
Query
(
"fileMd5"
)
fileName
:=
c
.
Query
(
"fileName"
)
filePath
:=
c
.
Query
(
"filePath"
)
err
:=
servers
.
RemoveChunk
(
fileMd5
)
err
=
new
(
dbModel
.
ExaFile
)
.
DeleteFileChunk
(
fileMd5
,
fileName
,
filePath
)
if
err
!=
nil
{
servers
.
ReportFormat
(
c
,
true
,
fmt
.
Sprintf
(
"缓存切片删除失败:%v"
,
err
),
gin
.
H
{})
}
else
{
servers
.
ReportFormat
(
c
,
true
,
"缓存切片删除成功"
,
gin
.
H
{})
}
}
QMPlusServer/controller/servers/breakpoint_continue.go
0 → 100644
浏览文件 @
640fb53f
package
servers
import
(
"gin-vue-admin/tools"
"io/ioutil"
"os"
"strconv"
)
// 前端传来文件片与当前片为什么文件的第几片
// 后端拿到以后比较次分片是否上传 或者是否为不完全片
// 前端发送每片多大
// 前端告知是否为最后一片且是否完成
const
breakpointDir
=
"./breakpointDir/"
const
finishDir
=
"./fileDir/"
func
BreakPointContinue
(
content
[]
byte
,
fileName
string
,
contentNumber
int
,
contentTotal
int
,
fileMd5
string
)
(
error
,
string
)
{
path
:=
breakpointDir
+
fileMd5
+
"/"
err
:=
os
.
MkdirAll
(
path
,
os
.
ModePerm
)
if
err
!=
nil
{
return
err
,
path
}
err
,
pathc
:=
makeFileContent
(
content
,
fileName
,
path
,
contentNumber
)
return
err
,
pathc
}
func
CheckMd5
(
content
[]
byte
,
chunkMd5
string
)
(
CanUpload
bool
)
{
fileMd5
:=
tools
.
MD5V
(
content
)
if
fileMd5
==
chunkMd5
{
return
true
// "可以继续上传"
}
else
{
return
false
// "切片不完整,废弃"
}
}
func
makeFileContent
(
content
[]
byte
,
fileName
string
,
FileDir
string
,
contentNumber
int
)
(
error
,
string
)
{
path
:=
FileDir
+
fileName
+
"_"
+
strconv
.
Itoa
(
contentNumber
)
f
,
err
:=
os
.
Create
(
path
)
defer
f
.
Close
()
if
err
!=
nil
{
return
err
,
path
}
else
{
_
,
err
=
f
.
Write
(
content
)
if
err
!=
nil
{
return
err
,
path
}
}
return
nil
,
path
}
func
MakeFile
(
fileName
string
,
FileMd5
string
)
(
error
,
string
)
{
rd
,
err
:=
ioutil
.
ReadDir
(
breakpointDir
+
FileMd5
)
if
err
!=
nil
{
return
err
,
finishDir
+
fileName
}
_
=
os
.
MkdirAll
(
finishDir
,
os
.
ModePerm
)
fd
,
_
:=
os
.
OpenFile
(
finishDir
+
fileName
,
os
.
O_RDWR
|
os
.
O_CREATE
|
os
.
O_APPEND
,
0644
)
for
k
,
_
:=
range
rd
{
content
,
_
:=
ioutil
.
ReadFile
(
breakpointDir
+
FileMd5
+
"/"
+
fileName
+
"_"
+
strconv
.
Itoa
(
k
))
_
,
err
=
fd
.
Write
(
content
)
if
err
!=
nil
{
_
=
os
.
Remove
(
finishDir
+
fileName
)
return
err
,
finishDir
+
fileName
}
}
defer
fd
.
Close
()
return
nil
,
finishDir
+
fileName
}
func
RemoveChunk
(
FileMd5
string
)
error
{
err
:=
os
.
RemoveAll
(
breakpointDir
+
FileMd5
)
return
err
}
QMPlusServer/init/initRouter/init_router.go
浏览文件 @
640fb53f
...
...
@@ -14,6 +14,7 @@ func InitRouter() *gin.Engine {
var
Router
=
gin
.
Default
()
//Router.Use(middleware.LoadTls()) // 打开就能玩https了
Router
.
Use
(
middleware
.
Logger
())
// 如果不需要日志 请关闭这里
Router
.
Use
(
middleware
.
Cors
())
// 跨域
Router
.
GET
(
"/swagger/*any"
,
ginSwagger
.
WrapHandler
(
swaggerFiles
.
Handler
))
ApiGroup
:=
Router
.
Group
(
""
)
// 方便统一添加路由组前缀 多服务器上线使用
//Router.Use(middleware.Logger())
...
...
@@ -26,6 +27,6 @@ func InitRouter() *gin.Engine {
router
.
InitWorkflowRouter
(
ApiGroup
)
// 工作流相关路由
router
.
InitCasbinRouter
(
ApiGroup
)
// 权限相关路由
router
.
InitJwtRouter
(
ApiGroup
)
// jwt相关路由
router
.
InitSystemRouter
(
ApiGroup
)
// system相关路由
router
.
InitSystemRouter
(
ApiGroup
)
// system相关路由
return
Router
}
QMPlusServer/init/registTable/regist_table.go
浏览文件 @
640fb53f
...
...
@@ -14,8 +14,10 @@ func RegistTable(db *gorm.DB) {
sysModel
.
SysApi
{},
sysModel
.
SysBaseMenu
{},
sysModel
.
JwtBlacklist
{},
dbModel
.
ExaFileUploadAndDownload
{},
sysModel
.
SysWorkflow
{},
sysModel
.
SysWorkflowStepInfo
{},
dbModel
.
ExaFileUploadAndDownload
{},
dbModel
.
ExaFile
{},
dbModel
.
ExaFileChunk
{},
)
}
QMPlusServer/middleware/cors.go
0 → 100644
浏览文件 @
640fb53f
package
middleware
import
(
"github.com/gin-gonic/gin"
"net/http"
)
// 处理跨域请求,支持options访问
func
Cors
()
gin
.
HandlerFunc
{
return
func
(
c
*
gin
.
Context
)
{
method
:=
c
.
Request
.
Method
c
.
Header
(
"Access-Control-Allow-Origin"
,
"*"
)
c
.
Header
(
"Access-Control-Allow-Headers"
,
"Content-Type,AccessToken,X-CSRF-Token, Authorization, Token"
)
c
.
Header
(
"Access-Control-Allow-Methods"
,
"POST, GET, OPTIONS"
)
c
.
Header
(
"Access-Control-Expose-Headers"
,
"Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type"
)
c
.
Header
(
"Access-Control-Allow-Credentials"
,
"true"
)
//放行所有OPTIONS方法
if
method
==
"OPTIONS"
{
c
.
AbortWithStatus
(
http
.
StatusNoContent
)
}
// 处理请求
c
.
Next
()
}
}
QMPlusServer/model/dbModel/exa_breakpoint_continue.go
0 → 100644
浏览文件 @
640fb53f
package
dbModel
import
(
"gin-vue-admin/init/qmsql"
"github.com/jinzhu/gorm"
)
type
ExaFile
struct
{
gorm
.
Model
FileName
string
FileMd5
string
FilePath
string
ExaFileChunk
[]
ExaFileChunk
ChunkTotal
int
IsFinish
bool
}
type
ExaFileChunk
struct
{
gorm
.
Model
ExaFileId
uint
FileChunkNumber
int
FileChunkPath
string
}
func
(
f
*
ExaFile
)
FileCreateComplete
(
FileMd5
string
,
FileName
string
,
FilePath
string
)
error
{
var
file
ExaFile
upDateFile
:=
make
(
map
[
string
]
interface
{})
upDateFile
[
"FilePath"
]
=
FilePath
upDateFile
[
"IsFinish"
]
=
true
err
:=
qmsql
.
DEFAULTDB
.
Where
(
"file_md5 = ? AND file_name = ?"
,
FileMd5
,
FileName
)
.
First
(
&
file
)
.
Updates
(
upDateFile
)
.
Error
return
err
}
func
(
f
*
ExaFile
)
FindOrCreateFile
(
FileMd5
string
,
FileName
string
,
ChunkTotal
int
)
(
err
error
,
file
ExaFile
)
{
var
cfile
ExaFile
cfile
.
FileMd5
=
FileMd5
cfile
.
FileName
=
FileName
cfile
.
ChunkTotal
=
ChunkTotal
notHaveSameMd5Finish
:=
qmsql
.
DEFAULTDB
.
Where
(
"file_md5 = ? AND is_finish = ?"
,
FileMd5
,
true
)
.
First
(
&
file
)
.
RecordNotFound
()
if
notHaveSameMd5Finish
{
err
=
qmsql
.
DEFAULTDB
.
Where
(
"file_md5 = ? AND file_name = ?"
,
FileMd5
,
FileName
)
.
Preload
(
"ExaFileChunk"
)
.
FirstOrCreate
(
&
file
,
cfile
)
.
Error
return
err
,
file
}
else
{
cfile
.
IsFinish
=
true
cfile
.
FilePath
=
file
.
FilePath
err
=
qmsql
.
DEFAULTDB
.
Create
(
&
cfile
)
.
Error
return
err
,
cfile
}
}
// 创建文件切片记录
func
(
f
*
ExaFile
)
CreateFileChunk
(
FileChunkPath
string
,
FileChunkNumber
int
)
error
{
var
chunk
ExaFileChunk
chunk
.
FileChunkPath
=
FileChunkPath
chunk
.
ExaFileId
=
f
.
ID
chunk
.
FileChunkNumber
=
FileChunkNumber
err
:=
qmsql
.
DEFAULTDB
.
Create
(
&
chunk
)
.
Error
return
err
}
// 删除文件切片记录
func
(
f
*
ExaFile
)
DeleteFileChunk
(
fileMd5
string
,
fileName
string
,
filePath
string
)
error
{
var
chunks
[]
ExaFileChunk
var
file
ExaFile
err
:=
qmsql
.
DEFAULTDB
.
Where
(
"file_md5 = ? AND file_name = ?"
,
fileMd5
,
fileName
)
.
First
(
&
file
)
.
Update
(
"IsFinish"
,
true
)
.
Update
(
"file_path"
,
filePath
)
.
Error
err
=
qmsql
.
DEFAULTDB
.
Where
(
"exa_file_id = ?"
,
file
.
ID
)
.
Delete
(
&
chunks
)
.
Unscoped
()
.
Error
return
err
}
QMPlusServer/model/sysModel/sys_user.go
浏览文件 @
640fb53f
...
...
@@ -35,7 +35,7 @@ func (u *SysUser) Regist() (err error, userInter *SysUser) {
return
errors
.
New
(
"用户名已注册"
),
nil
}
else
{
// 否则 附加uuid 密码md5简单加密 注册
u
.
Password
=
tools
.
MD5V
(
u
.
Password
)
u
.
Password
=
tools
.
MD5V
(
[]
byte
(
u
.
Password
)
)
u
.
UUID
=
uuid
.
NewV4
()
err
=
qmsql
.
DEFAULTDB
.
Create
(
u
)
.
Error
}
...
...
@@ -46,8 +46,8 @@ func (u *SysUser) Regist() (err error, userInter *SysUser) {
func
(
u
*
SysUser
)
ChangePassword
(
newPassword
string
)
(
err
error
,
userInter
*
SysUser
)
{
var
user
SysUser
//后期修改jwt+password模式
u
.
Password
=
tools
.
MD5V
(
u
.
Password
)
err
=
qmsql
.
DEFAULTDB
.
Where
(
"username = ? AND password = ?"
,
u
.
Username
,
u
.
Password
)
.
First
(
&
user
)
.
Update
(
"password"
,
tools
.
MD5V
(
newPassword
))
.
Error
u
.
Password
=
tools
.
MD5V
(
[]
byte
(
u
.
Password
)
)
err
=
qmsql
.
DEFAULTDB
.
Where
(
"username = ? AND password = ?"
,
u
.
Username
,
u
.
Password
)
.
First
(
&
user
)
.
Update
(
"password"
,
tools
.
MD5V
(
[]
byte
(
newPassword
)
))
.
Error
return
err
,
u
}
...
...
@@ -60,7 +60,7 @@ func (u *SysUser) SetUserAuthority(uuid uuid.UUID, AuthorityId string) (err erro
//用户登录
func
(
u
*
SysUser
)
Login
()
(
err
error
,
userInter
*
SysUser
)
{
var
user
SysUser
u
.
Password
=
tools
.
MD5V
(
u
.
Password
)
u
.
Password
=
tools
.
MD5V
(
[]
byte
(
u
.
Password
)
)
err
=
qmsql
.
DEFAULTDB
.
Where
(
"username = ? AND password = ?"
,
u
.
Username
,
u
.
Password
)
.
First
(
&
user
)
.
Error
if
err
!=
nil
{
return
err
,
&
user
...
...
QMPlusServer/router/exp_fileUploadAndDownload.go
浏览文件 @
640fb53f
...
...
@@ -2,16 +2,19 @@ package router
import
(
"gin-vue-admin/controller/api"
"gin-vue-admin/middleware"
"github.com/gin-gonic/gin"
)
func
InitFileUploadAndDownloadRouter
(
Router
*
gin
.
RouterGroup
)
{
FileUploadAndDownloadGroup
:=
Router
.
Group
(
"fileUploadAndDownload"
)
.
Use
(
middleware
.
JWTAuth
())
.
Use
(
middleware
.
CasbinHandler
())
//.Use(middleware.JWTAuth())
FileUploadAndDownloadGroup
:=
Router
.
Group
(
"fileUploadAndDownload"
)
//.Use(middleware.JWTAuth())
.Use(middleware.CasbinHandler())
{
FileUploadAndDownloadGroup
.
POST
(
"/upload"
,
api
.
UploadFile
)
// 上传文件
FileUploadAndDownloadGroup
.
POST
(
"/getFileList"
,
api
.
GetFileList
)
// 获取上传文件列表
FileUploadAndDownloadGroup
.
POST
(
"/deleteFile"
,
api
.
DeleteFile
)
// 删除指定文件
FileUploadAndDownloadGroup
.
POST
(
"/upload"
,
api
.
UploadFile
)
// 上传文件
FileUploadAndDownloadGroup
.
POST
(
"/getFileList"
,
api
.
GetFileList
)
// 获取上传文件列表
FileUploadAndDownloadGroup
.
POST
(
"/deleteFile"
,
api
.
DeleteFile
)
// 删除指定文件
FileUploadAndDownloadGroup
.
POST
(
"/breakpointContinue"
,
api
.
BreakpointContinue
)
// 断点续传
FileUploadAndDownloadGroup
.
GET
(
"/findFile"
,
api
.
FindFile
)
// 查询当前文件成功的切片
FileUploadAndDownloadGroup
.
POST
(
"/breakpointContinueFinish"
,
api
.
BreakpointContinueFinish
)
// 查询当前文件成功的切片
FileUploadAndDownloadGroup
.
POST
(
"/removeChunk"
,
api
.
RemoveChunk
)
// 查询当前文件成功的切片
}
}
QMPlusServer/tools/md5.go
浏览文件 @
640fb53f
...
...
@@ -5,8 +5,8 @@ import (
"encoding/hex"
)
func
MD5V
(
str
string
)
string
{
func
MD5V
(
str
[]
byte
)
string
{
h
:=
md5
.
New
()
h
.
Write
(
[]
byte
(
str
)
)
h
.
Write
(
str
)
return
hex
.
EncodeToString
(
h
.
Sum
(
nil
))
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录