Parcourir la source

支持导出配置文件

AE86 il y a 3 ans
Parent
commit
897cc02a20

+ 9 - 0
dbsyncer-cache/src/main/java/org/dbsyncer/cache/CacheService.java

@@ -1,5 +1,7 @@
 package org.dbsyncer.cache;
 
+import java.util.Map;
+
 /**
  * @author AE86
  * @version 1.0.0
@@ -50,4 +52,11 @@ public interface CacheService {
      */
     <T> T get(String key, Class<T> valueType);
 
+    /**
+     * 获取缓存
+     *
+     * @return
+     */
+    Map<String, Object> getAll();
+
 }

+ 6 - 0
dbsyncer-cache/src/main/java/org/dbsyncer/cache/CacheServiceImpl.java

@@ -2,6 +2,7 @@ package org.dbsyncer.cache;
 
 import org.springframework.stereotype.Component;
 
+import java.util.Collections;
 import java.util.Map;
 import java.util.concurrent.ConcurrentHashMap;
 
@@ -40,4 +41,9 @@ public class CacheServiceImpl implements CacheService {
         return (T) cache.get(key);
     }
 
+    @Override
+    public Map<String, Object> getAll() {
+        return Collections.unmodifiableMap(cache);
+    }
+
 }

+ 0 - 4
dbsyncer-manager/src/main/java/org/dbsyncer/manager/template/impl/OperationTemplate.java

@@ -164,10 +164,6 @@ public final class OperationTemplate extends AbstractTemplate {
             index.remove(e);
         }
 
-        public List<String> subList(int fromIndex, int toIndex) {
-            return index.subList(fromIndex, toIndex);
-        }
-
         public int size() {
             return index.size();
         }

+ 31 - 0
dbsyncer-parser/src/main/java/org/dbsyncer/parser/logger/LogType.java

@@ -237,4 +237,35 @@ public interface LogType {
         }
     }
 
+    /**
+     * 缓存配置信息7
+     */
+    enum CacheLog implements LogType {
+        IMPORT("70", "导入配置"),
+        EXPORT("71", "导出配置");
+
+        private String type;
+        private String message;
+
+        CacheLog(String type, String message) {
+            this.type = type;
+            this.message = message;
+        }
+
+        @Override
+        public String getName() {
+            return "插件";
+        }
+
+        @Override
+        public String getType() {
+            return type;
+        }
+
+        @Override
+        public String getMessage() {
+            return message;
+        }
+    }
+
 }

+ 59 - 2
dbsyncer-web/src/main/java/org/dbsyncer/web/controller/config/ConfigController.java

@@ -1,7 +1,14 @@
 package org.dbsyncer.web.controller.config;
 
+import org.apache.commons.io.IOUtils;
 import org.dbsyncer.biz.ConfigService;
 import org.dbsyncer.biz.vo.RestResult;
+import org.dbsyncer.cache.CacheService;
+import org.dbsyncer.common.config.AppConfig;
+import org.dbsyncer.common.snowflake.SnowflakeIdWorker;
+import org.dbsyncer.common.util.JsonUtil;
+import org.dbsyncer.parser.logger.LogService;
+import org.dbsyncer.parser.logger.LogType;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -11,8 +18,12 @@ import org.springframework.web.bind.annotation.GetMapping;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.nio.charset.Charset;
 
 @Controller
 @RequestMapping("/config")
@@ -23,9 +34,22 @@ public class ConfigController {
     @Autowired
     private ConfigService configService;
 
+    @Autowired
+    private CacheService cacheService;
+
+    @Autowired
+    private LogService logService;
+
+    @Autowired
+    private AppConfig appConfig;
+
+    @Autowired
+    private SnowflakeIdWorker snowflakeIdWorker;
+
     @RequestMapping("")
     public String index(ModelMap model) {
         model.put("config", configService.getConfigModelAll());
+        model.put("fileSize", JsonUtil.objToJson(cacheService.getAll()).getBytes(Charset.defaultCharset()).length);
         return "config/config";
     }
 
@@ -42,8 +66,22 @@ public class ConfigController {
 
     @PostMapping(value = "/upload")
     @ResponseBody
-    public RestResult upload() {
+    public RestResult upload(MultipartFile[] files) {
         try {
+            if (files != null && files.length > 0) {
+                MultipartFile file = null;
+                for (int i = 0; i < files.length; i++) {
+                    file = files[i];
+                    if (file != null) {
+                        String filename = file.getOriginalFilename();
+                        // TODO checkFileSuffix(filename);
+                        logger.info(filename);
+                        String msg = String.format("导入配置文件%s。", filename);
+                        logger.info(msg);
+                        logService.log(LogType.CacheLog.IMPORT, msg);
+                    }
+                }
+            }
             return RestResult.restSuccess("ok");
         } catch (Exception e) {
             logger.error(e.getLocalizedMessage(), e.getClass());
@@ -53,7 +91,26 @@ public class ConfigController {
 
     @GetMapping("/download")
     public void download(HttpServletResponse response) {
-
+        String fileName = String.format("%s-%s-%s.json", appConfig.getName(), appConfig.getVersion(), snowflakeIdWorker.nextId());
+        response.setHeader("content-type", "application/octet-stream");
+        response.setHeader("Content-Disposition", String.format("attachment; filename=%s", fileName));
+        response.setContentType("application/octet-stream");
+        OutputStream outputStream = null;
+        try {
+            outputStream = response.getOutputStream();
+            String cache = JsonUtil.objToJson(cacheService.getAll());
+            byte[] bytes = cache.getBytes(Charset.defaultCharset());
+            int length = bytes.length;
+            String msg = String.format("导出配置文件%s,大小%dKB。", fileName, (length / 1024));
+            logger.info(msg);
+            logService.log(LogType.CacheLog.EXPORT, msg);
+            outputStream.write(bytes, 0, length);
+            outputStream.flush();
+        } catch (IOException e) {
+            logger.error(e.getMessage());
+        } finally {
+            IOUtils.closeQuietly(outputStream);
+        }
     }
 
 }

+ 44 - 3
dbsyncer-web/src/main/resources/public/config/config.html

@@ -12,9 +12,11 @@
 
         <!-- 操作 -->
         <div class="row">
-            <div class="col-md-12">
+            <div class="col-md-7">
                 <table class="table table-hover">
-                    <caption>配置列表([[${config?.size()} ?: 0]])</caption>
+                    <caption>配置列表([[${config?.size()} ?: 0]]),<a onClick="downLoad()" href="javascript:;"
+                                                                 th:title="'下载文件大小'+${#numbers.formatDecimal((fileSize / 1024),0 ,2)}+'KB'">下载</a>
+                    </caption>
                     <thead>
                     <tr>
                         <th>ID</th>
@@ -35,9 +37,48 @@
                     </tbody>
                 </table>
             </div>
+
+            <!-- 配置列表 -->
+            <div class="col-md-5">
+                <form id="uploadForm" class="form-horizontal" role="form">
+                    <div class="page-header">
+                        <h3>上传配置 <small>只支持 "json" 的文件扩展名.</small></h3>
+                    </div>
+
+                    <div class="form-group">
+                        <div class="file-loading">
+                            <input id="fileConfig" type="file" name="files" multiple="multiple"/>
+                        </div>
+                    </div>
+                </form>
+            </div>
+
         </div>
     </form>
 </div>
 
-<script th:src="@{/js/pwd/index.js}"></script>
+<script type="text/javascript">
+    $("#fileConfig").fileinput({
+        theme: 'fas',
+        language: 'zh',
+        uploadUrl: $basePath + '/config/upload',
+        enctype: 'multipart/form-data',
+        removeFromPreviewOnError: true, //当选择的文件不符合规则时,例如不是指定后缀文件、大小超出配置等,选择的文件不会出现在预览框中,只会显示错误信息
+        allowedFileExtensions: ['json'],
+        minFileCount: 0, //每次多次上载允许的最小文件数。如果设置为0,则表示文件数是可选的
+        maxFileCount: 5, //表示允许同时上传的最大文件个数 如果设置为0,则表示允许的文件数不受限制
+        showPreview: true,
+        showUpload: true,//不展示上传按钮
+        validateInitialCount: true,//是否在验证minFileCount和包含初始预览文件计数(服务器上载文件)maxFileCount
+    }).on("fileuploaded", function (event, data, previewId, index) {
+        if (!data.response.success) {
+            bootGrowl(data.response.resultValue, "danger");
+        }
+        doLoader("/config");
+    });
+
+    function downLoad() {
+        window.open($basePath + "/config/download");
+    }
+</script>
 </html>