فهرست منبع

完成上传用户应用的前后端开发

niujiuru 1 هفته پیش
والد
کامیت
e29a176427
4فایلهای تغییر یافته به همراه131 افزوده شده و 1 حذف شده
  1. 70 0
      web-ui.service/page6_handler.go
  2. 4 0
      web-ui.service/web/pages/page6.html
  3. 52 1
      web-ui.service/web/static/js/page6.js
  4. 5 0
      web-ui.service/web_route.go

+ 70 - 0
web-ui.service/page6_handler.go

@@ -0,0 +1,70 @@
+package main
+
+import (
+	"io"
+	"net/http"
+	"os"
+	"path/filepath"
+	"strings"
+
+	"hnyfkj.com.cn/rtu/linux/baseapp"
+)
+
+const maxUploadSize = 1 << 30 // 1GB
+
+func uploadUserAPP(w http.ResponseWriter, r *http.Request) {
+	if r.Method != http.MethodPost {
+		http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
+		return
+	}
+
+	r.Body = http.MaxBytesReader(w, r.Body, maxUploadSize)
+
+	err := r.ParseMultipartForm(maxUploadSize)
+	if err != nil {
+		http.Error(w, "解析上传文件失败: "+err.Error(), http.StatusBadRequest)
+		return
+	}
+
+	file, header, err := r.FormFile("file")
+	if err != nil {
+		http.Error(w, "获取上传文件失败: "+err.Error(), http.StatusBadRequest)
+		return
+	}
+	defer file.Close()
+
+	if !strings.HasSuffix(strings.ToLower(header.Filename), ".tar.gz") {
+		http.Error(w, "只允许上传 tar.gz 类型的文件", http.StatusBadRequest)
+		return
+	}
+
+	path := filepath.Join("/tmp", filepath.Base(header.Filename))
+
+	err = saveUploadFile(file, path)
+	if err != nil {
+		http.Error(w, "保存上传文件失败: "+err.Error(), http.StatusInternalServerError)
+		return
+	}
+
+	baseapp.Logger.Infof(
+		"[上传文件成功] 上传文件名: %s, 上传文件大小: %d 字节, 本地存储路径: %s",
+		header.Filename, header.Size, path)
+
+	w.WriteHeader(http.StatusOK)
+}
+
+func saveUploadFile(src io.Reader, path string) error {
+	dst, err := os.Create(path)
+	if err != nil {
+		return err
+	}
+	defer dst.Close()
+
+	_, err = io.Copy(dst, src)
+	if err != nil {
+		os.Remove(path)
+		return err
+	}
+
+	return nil
+}

+ 4 - 0
web-ui.service/web/pages/page6.html

@@ -61,6 +61,10 @@
               <span class="label">上传时间:</span>
               <span class="value" id="bvar4">--</span>
             </div>
+            <div class="app-info">
+              <span class="label">操作状态:</span>
+              <span class="value" id="bvar5">--</span>
+            </div>
           </div>
         </div>
         <div class="card">

+ 52 - 1
web-ui.service/web/static/js/page6.js

@@ -1,4 +1,9 @@
+let userAppUploading = false;
+
 function onBtn1Click() {
+  if (userAppUploading) {
+    return;
+  }
   document.getElementById("userAppFile").click();
 }
 
@@ -9,11 +14,57 @@ function uploadUserAppFile(input) {
     return;
   }
 
-  if (!file.name.endsWith(".tar.gz")) {
+  if (!file.name.toLowerCase().endsWith(".tar.gz")) {
     alert("只允许上传 tar.gz 类型的文件");
     input.value = "";
     return;
   }
+
+  userAppUploading = true;
+
+  let formData = new FormData();
+  formData.append("file", file);
+
+  let xhr = new XMLHttpRequest();
+  xhr.open("POST", "/api/app-install/uploadUserAPP", true);
+  xhr.timeout = 600000; // 10分钟
+
+  xhr.upload.onprogress = function(e) {
+    if (!e.lengthComputable) {
+      return;
+    }
+
+    let percent = Math.floor(e.loaded * 100 / e.total);
+    setText("bvar5", "正在上传 " + file.name + " (" + percent + "%)", "page6");
+  };
+
+  xhr.onload = function() {
+    userAppUploading = false;
+    input.value = "";
+
+    if (xhr.status !== 200) {
+      setText("bvar5", "上传失败: " + xhr.responseText, "page6");
+      return;
+    }
+
+    setText("bvar5", "上传完成,等待下一步处理", "page6");
+  };
+
+  xhr.onerror = function() {
+    userAppUploading = false;
+    input.value = "";
+
+    setText("bvar5", "上传失败,请检查网络连接", "page6");
+  };
+
+  xhr.ontimeout = function() {
+    userAppUploading = false;
+    input.value = "";
+
+    setText("bvar5", "上传超时,请稍后重新尝试", "page6");
+  };
+
+  xhr.send(formData);
 }
 
 function initPage6() {

+ 5 - 0
web-ui.service/web_route.go

@@ -174,6 +174,11 @@ var routes = []Route{
 	},
 
 	{
+		"/api/app-install/uploadUserAPP",
+		uploadUserAPP,
+	},
+
+	{
 		"/api/ssh/ws",
 		sshWSHandler,
 	},