diff --git a/server/api/v1/exa_simple_uploader.go b/server/api/v1/exa_simple_uploader.go
new file mode 100644
index 00000000..5067299e
--- /dev/null
+++ b/server/api/v1/exa_simple_uploader.go
@@ -0,0 +1,87 @@
+package v1
+
+import (
+ "fmt"
+ "gin-vue-admin/global/response"
+ "gin-vue-admin/model"
+ "gin-vue-admin/service"
+ "gin-vue-admin/utils"
+ "github.com/gin-gonic/gin"
+)
+
+// @Tags SimpleUploader
+// @Summary 断点续传插件版示例
+// @Security ApiKeyAuth
+// @accept multipart/form-data
+// @Produce application/json
+// @Param file formData file true "断点续传插件版示例"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"上传成功"}"
+// @Router /simpleUploader/upload [post]
+func SimpleUploaderUpload(c *gin.Context) {
+ var chunk model.ExaSimpleUploader
+ _, header, err := c.Request.FormFile("file")
+ chunk.Filename = c.PostForm("filename")
+ chunk.ChunkNumber = c.PostForm("chunkNumber")
+ chunk.CurrentChunkSize = c.PostForm("currentChunkSize")
+ chunk.Identifier = c.PostForm("identifier")
+ chunk.TotalSize = c.PostForm("totalSize")
+ chunk.TotalChunks = c.PostForm("totalChunks")
+ var chunkDir = "./chunk/" + chunk.Identifier + "/"
+ hasDir, _ := utils.PathExists(chunkDir)
+ if !hasDir {
+ utils.CreateDir(chunkDir)
+ }
+ chunkPath := chunkDir + chunk.Filename + chunk.ChunkNumber
+ err = c.SaveUploadedFile(header, chunkPath)
+ if err != nil {
+ response.FailWithMessage(fmt.Sprintf("切片创建失败,%v", err), c)
+ return
+ }
+ chunk.CurrentChunkPath = chunkPath
+ err = service.SaveChunk(chunk)
+ if err != nil {
+ response.FailWithMessage(fmt.Sprintf("切片创建失败,%v", err), c)
+ return
+ } else {
+ response.Ok(c)
+ }
+}
+
+// @Tags SimpleUploader
+// @Summary 断点续传插件版示例
+// @Security ApiKeyAuth
+
+// @Produce application/json
+// @Param params md5 get "测试文件是否已经存在和判断已经上传过的切片"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /simpleUploader/checkFileMd5 [get]
+func CheckFileMd5(c *gin.Context) {
+ md5 := c.Query("md5")
+ err, chunks, isDone := service.CheckFileMd5(md5)
+ if err != nil {
+ response.FailWithMessage(fmt.Sprintf("md5读取失败,%v", err), c)
+ } else {
+ response.OkWithData(gin.H{
+ "chunks": chunks,
+ "isDone": isDone,
+ }, c)
+ }
+}
+
+// @Tags SimpleUploader
+// @Summary 合并文件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Param params md5 get "合并文件"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"合并成功"}"
+// @Router /simpleUploader/mergeFileMd5 [get]
+func MergeFileMd5(c *gin.Context) {
+ md5 := c.Query("md5")
+ fileName := c.Query("fileName")
+ err := service.MergeFileMd5(md5, fileName)
+ if err != nil {
+ response.FailWithMessage(fmt.Sprintf("md5读取失败,%v", err), c)
+ } else {
+ response.OkWithData(gin.H{}, c)
+ }
+}
diff --git a/server/db/20200815_update_patch.sql b/server/db/20200815_update_patch.sql
new file mode 100644
index 00000000..a7bdf5cd
--- /dev/null
+++ b/server/db/20200815_update_patch.sql
@@ -0,0 +1,27 @@
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/simpleUploader/upload', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/simpleUploader/checkFileMd5', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/simpleUploader/mergeFileMd5', 'GET', '', '', '');
+
+-- ----------------------------
+-- Table structure for exa_simple_uploaders
+-- ----------------------------
+DROP TABLE IF EXISTS `exa_simple_uploaders`;
+CREATE TABLE `exa_simple_uploaders` (
+ `chunk_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '当前切片标记',
+ `current_chunk_size` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '当前切片容量',
+ `current_chunk_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '切片本地路径',
+ `total_size` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '总容量',
+ `identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '文件标识(md5)',
+ `filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '文件名',
+ `total_chunks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '切片总数',
+ `is_done` tinyint(1) NULL DEFAULT NULL COMMENT '是否上传完成',
+ `file_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '文件本地路径'
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
+
+INSERT INTO `sys_apis` VALUES (100, '2020-08-15 12:10:55', '2020-08-15 12:10:55', NULL, NULL, '/simpleUploader/upload', '插件版分片上传', 'simpleUploader', 'POST');
+INSERT INTO `sys_apis` VALUES (101, '2020-08-15 19:53:53', '2020-08-15 19:53:53', NULL, NULL, '/simpleUploader/checkFileMd5', '文件完整度验证', 'simpleUploader', 'GET');
+INSERT INTO `sys_apis` VALUES (102, '2020-08-15 22:28:04', '2020-08-15 22:28:04', NULL, NULL, '/simpleUploader/mergeFileMd5', '上传完成合并文件', 'simpleUploader', 'GET');
+
+INSERT INTO `sys_authority_menus` VALUES ('888', 53);
+
+INSERT INTO `sys_base_menus` VALUES (53, '2020-08-15 11:41:49', '2020-08-15 11:43:15', NULL, 0, 19, 'simpleUploader', 'simpleUploader', 0, 'view/example/simpleUploader/simpleUploader', '断点续传(插件版)', 'upload', NULL, 6, 0, 0);
diff --git a/server/db/qmplus.sql b/server/db/qmplus.sql
index a8152f17..22ce817d 100644
--- a/server/db/qmplus.sql
+++ b/server/db/qmplus.sql
@@ -11,7 +11,7 @@
Target Server Version : 50640
File Encoding : 65001
- Date: 11/08/2020 23:22:30
+ Date: 15/08/2020 23:09:13
*/
SET NAMES utf8mb4;
@@ -176,6 +176,9 @@ INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/updateSysOper
INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/findSysOperationRecord', 'GET', '', '', '');
INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/getSysOperationRecordList', 'GET', '', '', '');
INSERT INTO `casbin_rule` VALUES ('p', '888', '/sysOperationRecord/deleteSysOperationRecordByIds', 'DELETE', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/simpleUploader/upload', 'POST', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/simpleUploader/checkFileMd5', 'GET', '', '', '');
+INSERT INTO `casbin_rule` VALUES ('p', '888', '/simpleUploader/mergeFileMd5', 'GET', '', '', '');
-- ----------------------------
-- Table structure for exa_customers
@@ -257,6 +260,22 @@ CREATE TABLE `exa_files` (
INDEX `idx_exa_files_deleted_at`(`deleted_at`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+-- ----------------------------
+-- Table structure for exa_simple_uploaders
+-- ----------------------------
+DROP TABLE IF EXISTS `exa_simple_uploaders`;
+CREATE TABLE `exa_simple_uploaders` (
+ `chunk_number` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '当前切片标记',
+ `current_chunk_size` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '当前切片容量',
+ `current_chunk_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '切片本地路径',
+ `total_size` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '总容量',
+ `identifier` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '文件标识(md5)',
+ `filename` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '文件名',
+ `total_chunks` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '切片总数',
+ `is_done` tinyint(1) NULL DEFAULT NULL COMMENT '是否上传完成',
+ `file_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL COMMENT '文件本地路径'
+) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
+
-- ----------------------------
-- Table structure for jwt_blacklists
-- ----------------------------
@@ -269,7 +288,7 @@ CREATE TABLE `jwt_blacklists` (
`jwt` text CHARACTER SET utf8 COLLATE utf8_general_ci NULL COMMENT 'jwt',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_jwt_blacklists_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 57 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for sys_apis
@@ -288,7 +307,7 @@ CREATE TABLE `sys_apis` (
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_apis_deleted_at`(`deleted_at`) USING BTREE,
INDEX `idx_sys_apis_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 106 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 103 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
-- ----------------------------
-- Records of sys_apis
@@ -356,6 +375,9 @@ INSERT INTO `sys_apis` VALUES (96, '2020-07-05 14:34:20', '2020-07-05 14:34:20',
INSERT INTO `sys_apis` VALUES (97, '2020-07-05 15:02:07', '2020-07-05 15:02:07', NULL, NULL, '/autoCode/getDB', '获取所有数据库', 'autoCode', 'GET');
INSERT INTO `sys_apis` VALUES (98, '2020-07-05 16:32:08', '2020-07-05 16:32:08', NULL, NULL, '/autoCode/getColume', '获取所选table的所有字段', 'autoCode', 'GET');
INSERT INTO `sys_apis` VALUES (99, '2020-07-07 15:59:53', '2020-07-07 15:59:53', NULL, NULL, '/sysOperationRecord/deleteSysOperationRecordByIds', '批量删除操作历史', 'sysOperationRecord', 'DELETE');
+INSERT INTO `sys_apis` VALUES (100, '2020-08-15 12:10:55', '2020-08-15 12:10:55', NULL, NULL, '/simpleUploader/upload', '插件版分片上传', 'simpleUploader', 'POST');
+INSERT INTO `sys_apis` VALUES (101, '2020-08-15 19:53:53', '2020-08-15 19:53:53', NULL, NULL, '/simpleUploader/checkFileMd5', '文件完整度验证', 'simpleUploader', 'GET');
+INSERT INTO `sys_apis` VALUES (102, '2020-08-15 22:28:04', '2020-08-15 22:28:04', NULL, NULL, '/simpleUploader/mergeFileMd5', '上传完成合并文件', 'simpleUploader', 'GET');
-- ----------------------------
-- Table structure for sys_authorities
@@ -417,6 +439,7 @@ INSERT INTO `sys_authority_menus` VALUES ('888', 42);
INSERT INTO `sys_authority_menus` VALUES ('888', 50);
INSERT INTO `sys_authority_menus` VALUES ('888', 51);
INSERT INTO `sys_authority_menus` VALUES ('888', 52);
+INSERT INTO `sys_authority_menus` VALUES ('888', 53);
INSERT INTO `sys_authority_menus` VALUES ('8881', 1);
INSERT INTO `sys_authority_menus` VALUES ('8881', 2);
INSERT INTO `sys_authority_menus` VALUES ('8881', 18);
@@ -460,7 +483,7 @@ CREATE TABLE `sys_base_menu_parameters` (
`value` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_sys_base_menu_parameters_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
+) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for sys_base_menus
@@ -492,7 +515,7 @@ CREATE TABLE `sys_base_menus` (
-- Records of sys_base_menus
-- ----------------------------
INSERT INTO `sys_base_menus` VALUES (1, '2019-09-19 22:05:18', '2020-05-30 15:43:06', NULL, 0, 0, 'dashboard', 'dashboard', 0, 'view/dashboard/index.vue', '仪表盘', 'setting', '仪表盘', 1, 0, 0);
-INSERT INTO `sys_base_menus` VALUES (2, '2019-09-19 22:06:17', '2020-05-10 21:31:50', NULL, 0, 0, 'about', 'about', 0, 'view/about/index.vue', '关于我们', 'info', '测试菜单', 7, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (2, '2019-09-19 22:06:17', '2020-08-11 23:26:21', NULL, 0, 0, 'about', 'about', 0, 'view/about/index.vue', '关于我们', 'info', '测试菜单', 7, 0, 0);
INSERT INTO `sys_base_menus` VALUES (3, '2019-09-19 22:06:38', '2020-04-24 10:16:43', NULL, 0, 0, 'admin', 'superAdmin', 0, 'view/superAdmin/index.vue', '超级管理员', 'user-solid', '超级管理员', 3, 0, 0);
INSERT INTO `sys_base_menus` VALUES (4, '2019-09-19 22:11:53', '2020-05-30 15:43:25', NULL, 0, 3, 'authority', 'authority', 0, 'view/superAdmin/authority/authority.vue', '角色管理', 's-custom', '角色管理', 1, 0, 0);
INSERT INTO `sys_base_menus` VALUES (5, '2019-09-19 22:13:18', '2020-04-30 17:45:27', NULL, 0, 3, 'menu', 'menu', 0, 'view/superAdmin/menu/menu.vue', '菜单管理', 's-order', '菜单管理', 2, 1, 0);
@@ -515,6 +538,7 @@ INSERT INTO `sys_base_menus` VALUES (45, '2020-04-29 17:19:34', '2020-07-04 18:2
INSERT INTO `sys_base_menus` VALUES (50, '2020-06-24 19:49:54', '2020-06-28 20:34:47', NULL, 0, 3, 'dictionary', 'dictionary', 0, 'view/superAdmin/dictionary/sysDictionary.vue', '字典管理', 'notebook-2', NULL, 5, 0, 0);
INSERT INTO `sys_base_menus` VALUES (51, '2020-06-24 19:51:33', '2020-06-28 20:35:04', NULL, 0, 3, 'dictionaryDetail/:id', 'dictionaryDetail', 1, 'view/superAdmin/dictionary/sysDictionaryDetail.vue', '字典详情', 's-order', NULL, 1, 0, 0);
INSERT INTO `sys_base_menus` VALUES (52, '2020-06-29 13:31:17', '2020-07-07 16:05:34', NULL, 0, 3, 'operation', 'operation', 0, 'view/superAdmin/operation/sysOperationRecord.vue', '操作历史', 'time', NULL, 6, 0, 0);
+INSERT INTO `sys_base_menus` VALUES (53, '2020-08-15 11:41:49', '2020-08-15 11:43:15', NULL, 0, 19, 'simpleUploader', 'simpleUploader', 0, 'view/example/simpleUploader/simpleUploader', '断点续传(插件版)', 'upload', NULL, 6, 0, 0);
-- ----------------------------
-- Table structure for sys_data_authority_id
@@ -636,12 +660,7 @@ CREATE TABLE `sys_operation_records` (
`resp` longtext CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NULL COMMENT '响应Body',
PRIMARY KEY (`id`) USING BTREE,
INDEX `idx_sys_operation_records_deleted_at`(`deleted_at`) USING BTREE
-) ENGINE = InnoDB AUTO_INCREMENT = 343 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
-
--- ----------------------------
--- Records of sys_operation_records
--- ----------------------------
-INSERT INTO `sys_operation_records` VALUES (342, '2020-08-11 23:21:30', '2020-08-11 23:21:30', NULL, '127.0.0.1', 'POST', '/authority/getAuthorityList', 200, 3906600, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36', '', '{\"page\":1,\"pageSize\":999}', 10, '{\"code\":0,\"data\":{\"list\":[{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-06-13T16:07:37+08:00\",\"DeletedAt\":null,\"authorityId\":\"888\",\"authorityName\":\"普通用户\",\"parentId\":\"0\",\"dataAuthorityId\":[{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-06-13T16:07:37+08:00\",\"DeletedAt\":null,\"authorityId\":\"888\",\"authorityName\":\"普通用户\",\"parentId\":\"0\",\"dataAuthorityId\":null,\"children\":null,\"menus\":null},{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-04-24T10:16:42+08:00\",\"DeletedAt\":null,\"authorityId\":\"8881\",\"authorityName\":\"普通用户子角色\",\"parentId\":\"888\",\"dataAuthorityId\":null,\"children\":null,\"menus\":null},{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-04-24T10:16:42+08:00\",\"DeletedAt\":null,\"authorityId\":\"9528\",\"authorityName\":\"测试角色\",\"parentId\":\"0\",\"dataAuthorityId\":null,\"children\":null,\"menus\":null}],\"children\":[{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-04-24T10:16:42+08:00\",\"DeletedAt\":null,\"authorityId\":\"8881\",\"authorityName\":\"普通用户子角色\",\"parentId\":\"888\",\"dataAuthorityId\":[],\"children\":[],\"menus\":null}],\"menus\":null},{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-04-24T10:16:42+08:00\",\"DeletedAt\":null,\"authorityId\":\"9528\",\"authorityName\":\"测试角色\",\"parentId\":\"0\",\"dataAuthorityId\":[{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-04-24T10:16:42+08:00\",\"DeletedAt\":null,\"authorityId\":\"8881\",\"authorityName\":\"普通用户子角色\",\"parentId\":\"888\",\"dataAuthorityId\":null,\"children\":null,\"menus\":null},{\"CreatedAt\":\"2020-04-04T11:44:56+08:00\",\"UpdatedAt\":\"2020-04-24T10:16:42+08:00\",\"DeletedAt\":null,\"authorityId\":\"9528\",\"authorityName\":\"测试角色\",\"parentId\":\"0\",\"dataAuthorityId\":null,\"children\":null,\"menus\":null}],\"children\":[],\"menus\":null}],\"total\":0,\"page\":1,\"pageSize\":999},\"msg\":\"操作成功\"}');
+) ENGINE = InnoDB AUTO_INCREMENT = 358 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin ROW_FORMAT = Compact;
-- ----------------------------
-- Table structure for sys_users
diff --git a/server/initialize/db_table.go b/server/initialize/db_table.go
index bf44f203..6ea6bb1b 100644
--- a/server/initialize/db_table.go
+++ b/server/initialize/db_table.go
@@ -21,6 +21,7 @@ func DBTables() {
model.ExaFileUploadAndDownload{},
model.ExaFile{},
model.ExaFileChunk{},
+ model.ExaSimpleUploader{},
model.ExaCustomer{},
model.SysOperationRecord{},
)
diff --git a/server/initialize/router.go b/server/initialize/router.go
index 5ba0a376..aac158ec 100644
--- a/server/initialize/router.go
+++ b/server/initialize/router.go
@@ -29,6 +29,7 @@ func Routers() *gin.Engine {
router.InitAuthorityRouter(ApiGroup) // 注册角色路由
router.InitApiRouter(ApiGroup) // 注册功能api路由
router.InitFileUploadAndDownloadRouter(ApiGroup) // 文件上传下载功能路由
+ router.InitSimpleUploaderRouter(ApiGroup) // 断点续传(插件版)
router.InitWorkflowRouter(ApiGroup) // 工作流相关路由
router.InitCasbinRouter(ApiGroup) // 权限相关路由
router.InitJwtRouter(ApiGroup) // jwt相关路由
@@ -38,6 +39,7 @@ func Routers() *gin.Engine {
router.InitSysDictionaryDetailRouter(ApiGroup) // 字典详情管理
router.InitSysDictionaryRouter(ApiGroup) // 字典管理
router.InitSysOperationRecordRouter(ApiGroup) // 操作记录
+
global.GVA_LOG.Info("router register success")
return Router
}
diff --git a/server/model/exa_simple_uploader.go b/server/model/exa_simple_uploader.go
new file mode 100644
index 00000000..2f7a2a17
--- /dev/null
+++ b/server/model/exa_simple_uploader.go
@@ -0,0 +1,13 @@
+package model
+
+type ExaSimpleUploader struct {
+ ChunkNumber string `json:"chunkNumber" gorm:"comment:'当前切片标记'"`
+ CurrentChunkSize string `json:"currentChunkSize" gorm:"comment:'当前切片容量'"`
+ CurrentChunkPath string `json:"currentChunkPath" gorm:"comment:'切片本地路径'"`
+ TotalSize string `json:"totalSize" gorm:"comment:'总容量'"`
+ Identifier string `json:"identifier" gorm:"comment:'文件标识(md5)'"`
+ Filename string `json:"filename" gorm:"comment:'文件名'"`
+ TotalChunks string `json:"totalChunks" gorm:"comment:'切片总数'"`
+ IsDone bool `json:"isDone" gorm:"comment:'是否上传完成'"`
+ FilePath string `json:"filePath" gorm:"comment:'文件本地路径'"`
+}
diff --git a/server/router/exa_simple_uploader.go b/server/router/exa_simple_uploader.go
new file mode 100644
index 00000000..7197d638
--- /dev/null
+++ b/server/router/exa_simple_uploader.go
@@ -0,0 +1,18 @@
+package router
+
+import (
+ "gin-vue-admin/api/v1"
+ "gin-vue-admin/middleware"
+ "github.com/gin-gonic/gin"
+)
+
+func InitSimpleUploaderRouter(Router *gin.RouterGroup) {
+ ApiRouter := Router.Group("simpleUploader").
+ Use(middleware.JWTAuth()).
+ Use(middleware.CasbinHandler())
+ {
+ ApiRouter.POST("upload", v1.SimpleUploaderUpload) // 上传功能
+ ApiRouter.GET("checkFileMd5", v1.CheckFileMd5) // 文件完整度验证
+ ApiRouter.GET("mergeFileMd5", v1.MergeFileMd5) // 合并文件
+ }
+}
diff --git a/server/service/exa_simple_uploader.go b/server/service/exa_simple_uploader.go
new file mode 100644
index 00000000..06f067cf
--- /dev/null
+++ b/server/service/exa_simple_uploader.go
@@ -0,0 +1,72 @@
+package service
+
+import (
+ "fmt"
+ "gin-vue-admin/global"
+ "gin-vue-admin/model"
+ "io/ioutil"
+ "os"
+ "strconv"
+)
+
+// 保存文件切片路径
+func SaveChunk(uploader model.ExaSimpleUploader) (err error) {
+ return global.GVA_DB.Create(uploader).Error
+}
+
+// 检查文件是否已经上传过
+func CheckFileMd5(md5 string) (err error, uploads []model.ExaSimpleUploader, isDone bool) {
+ err = global.GVA_DB.Find(&uploads, "identifier = ? AND is_done = ?", md5, false).Error
+ isDone = global.GVA_DB.First(&model.ExaSimpleUploader{}, "identifier = ? AND is_done = ?", md5, true).RecordNotFound()
+ return err, uploads, !isDone
+}
+
+// 合并文件
+func MergeFileMd5(md5 string, fileName string) (err error) {
+ finishDir := "./finish/"
+ dir := "./chunk/" + md5
+ //如果文件上传成功 不做后续操作 通知成功即可
+ notFinish := global.GVA_DB.First(&model.ExaSimpleUploader{}, "identifier = ? AND is_done = ?", md5, true).RecordNotFound()
+ if !notFinish {
+ return nil
+ }
+
+ //打开切片文件夹
+ rd, err := ioutil.ReadDir(dir)
+ _ = 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(dir + "/" + fileName + strconv.Itoa(k+1))
+ _, err = fd.Write(content)
+ if err != nil {
+ _ = os.Remove(finishDir + fileName)
+ }
+ }
+ //关闭文件
+ defer fd.Close()
+
+ if err != nil {
+ return err
+ }
+ //创建事务
+ tx := global.GVA_DB.Begin()
+ //删除切片信息
+ err = tx.Delete(&model.ExaSimpleUploader{}, "identifier = ? AND is_done = ?", md5, false).Error
+ // 添加文件信息
+ err = tx.Create(&model.ExaSimpleUploader{
+ Identifier: md5,
+ IsDone: true,
+ FilePath: finishDir + fileName,
+ Filename: fileName,
+ }).Error
+ if err != nil {
+ fmt.Println(err)
+ tx.Rollback()
+ }
+ tx.Commit()
+ //清除切片
+ err = os.RemoveAll(dir)
+ return
+}
diff --git a/web/package.json b/web/package.json
index e7a2c8d3..3930b412 100644
--- a/web/package.json
+++ b/web/package.json
@@ -27,6 +27,7 @@
"vue-particle-line": "^0.1.4",
"vue-quill-editor": "^3.0.6",
"vue-router": "^3.1.3",
+ "vue-simple-uploader": "^0.7.4",
"vuescroll": "^4.14.4",
"vuex": "^3.1.1",
"vuex-persist": "^2.1.0"
diff --git a/web/src/api/simpleUploader.js b/web/src/api/simpleUploader.js
new file mode 100644
index 00000000..7cfe7d6c
--- /dev/null
+++ b/web/src/api/simpleUploader.js
@@ -0,0 +1,36 @@
+
+
+import service from '@/utils/request'
+
+// @Tags SimpleUploader
+// @Summary 断点续传插件版示例
+// @Security ApiKeyAuth
+
+// @Produce application/json
+// @Param params md5 get "测试文件是否已经存在和判断已经上传过的切片"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"查询成功"}"
+// @Router /simpleUploader/checkFileMd5 [get]
+export const checkFileMd5 = (params) => {
+ return service({
+ url: "/simpleUploader/checkFileMd5",
+ method: 'get',
+ params
+ })
+}
+
+
+// @Tags SimpleUploader
+// @Summary 合并文件
+// @Security ApiKeyAuth
+// @Produce application/json
+// @Param params md5 get "合并文件"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"合并成功"}"
+// @Router /simpleUploader/mergeFileMd5 [get]
+export const mergeFileMd5 = (params) => {
+ return service({
+ url: "/simpleUploader/mergeFileMd5",
+ method: 'get',
+ params
+ })
+}
+
diff --git a/web/src/main.js b/web/src/main.js
index 4f1dea42..d9c33b43 100644
--- a/web/src/main.js
+++ b/web/src/main.js
@@ -51,6 +51,8 @@ import {auth} from '@/directive/auth'
// 按钮权限指令
auth(Vue)
+import uploader from 'vue-simple-uploader'
+Vue.use(uploader)
new Vue({
render: h => h(App),
diff --git a/web/src/view/example/simpleUploader/simpleUploader.vue b/web/src/view/example/simpleUploader/simpleUploader.vue
new file mode 100644
index 00000000..c9b40d0b
--- /dev/null
+++ b/web/src/view/example/simpleUploader/simpleUploader.vue
@@ -0,0 +1,163 @@
+
+
+
+
+ 拖拽文件至此或点击
+ 选择文件
+
+
+
+
+
+
+
+
\ No newline at end of file