mirror of
https://github.com/ClovertaTheTrilobita/cellpose-web.git
synced 2026-04-01 23:14:50 +00:00
feature(frontend): 新增测试用前端
refactor: 重构项目逻辑
This commit is contained in:
parent
28b3300de2
commit
03c484aa07
7 changed files with 50 additions and 8 deletions
1
.gitignore → backend/.gitignore
vendored
1
.gitignore → backend/.gitignore
vendored
|
|
@ -3,3 +3,4 @@ test_output
|
||||||
test_output/*
|
test_output/*
|
||||||
test_tif
|
test_tif
|
||||||
output
|
output
|
||||||
|
uploads
|
||||||
|
|
@ -1,9 +1,13 @@
|
||||||
from flask import Flask, send_from_directory, request, jsonify
|
from flask import Flask, send_from_directory, request, jsonify
|
||||||
import os, shutil, time, threading
|
import os, shutil, time, threading
|
||||||
from werkzeug.utils import secure_filename
|
from werkzeug.utils import secure_filename
|
||||||
|
from flask_cors import CORS
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
app = Flask(__name__)
|
app = Flask(__name__)
|
||||||
UPLOAD_DIR = "./uploads"
|
CORS(app)
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
|
UPLOAD_DIR = BASE_DIR / "uploads"
|
||||||
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
os.makedirs(UPLOAD_DIR, exist_ok=True)
|
||||||
|
|
||||||
def run_flask():
|
def run_flask():
|
||||||
|
|
@ -15,21 +19,21 @@ def index():
|
||||||
|
|
||||||
@app.route("/testdl")
|
@app.route("/testdl")
|
||||||
def test_download():
|
def test_download():
|
||||||
return send_from_directory("./test_output/2025-09-16-20-03-51", "img_overlay.png", as_attachment=True)
|
return send_from_directory("test_output/2025-09-16-20-03-51", "img_overlay.png", as_attachment=True)
|
||||||
|
|
||||||
@app.route("/dl/<timestamp>")
|
@app.route("/dl/<timestamp>")
|
||||||
def download(timestamp):
|
def download(timestamp):
|
||||||
input_dir = os.path.join("./output", timestamp)
|
input_dir = os.path.join("output", timestamp)
|
||||||
output_dir = os.path.join("./output/tmp", timestamp) # 不要加 .zip,make_archive 会自动加
|
output_dir = os.path.join("output/tmp", timestamp) # 不要加 .zip,make_archive 会自动加
|
||||||
os.makedirs("./output/tmp", exist_ok=True) # 确保 tmp 存在
|
os.makedirs("output/tmp", exist_ok=True) # 确保 tmp 存在
|
||||||
shutil.make_archive(output_dir, 'zip', input_dir)
|
shutil.make_archive(output_dir, 'zip', input_dir)
|
||||||
print(f"压缩完成: {output_dir}.zip")
|
print(f"压缩完成: {output_dir}.zip")
|
||||||
return send_from_directory("./output/tmp", f"{timestamp}.zip", as_attachment=True)
|
return send_from_directory("output/tmp", f"{timestamp}.zip", as_attachment=True)
|
||||||
|
|
||||||
|
|
||||||
@app.post("/upload")
|
@app.post("/upload")
|
||||||
def upload():
|
def upload():
|
||||||
files = request.files.getlist("files") # ← 前端用同一个键名多次 append
|
files = request.files.getlist("files")
|
||||||
saved = []
|
saved = []
|
||||||
for f in files:
|
for f in files:
|
||||||
if not f or f.filename == "":
|
if not f or f.filename == "":
|
||||||
6
backend/requirements.txt
Normal file
6
backend/requirements.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
numpy~=2.1.2
|
||||||
|
cellpose~=4.0.6
|
||||||
|
pillow~=11.0.0
|
||||||
|
sympy~=1.13.3
|
||||||
|
flask~=3.1.2
|
||||||
|
werkzeug~=3.1.3
|
||||||
31
frontend/index.html
Normal file
31
frontend/index.html
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<input id="fileInput" type="file" multiple />
|
||||||
|
<button id="uploadBtn">Upload</button>
|
||||||
|
<progress id="bar" max="100" value="0" style="width:300px;"></progress>
|
||||||
|
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
|
||||||
|
<script>
|
||||||
|
const API = "http://10.147.18.141:5000/upload";
|
||||||
|
|
||||||
|
document.getElementById("uploadBtn").addEventListener("click", async () => {
|
||||||
|
const input = document.getElementById("fileInput");
|
||||||
|
if (!input.files.length) return alert("请选择文件");
|
||||||
|
|
||||||
|
const fd = new FormData();
|
||||||
|
for (const f of input.files) fd.append("files", f);
|
||||||
|
|
||||||
|
const bar = document.getElementById("bar");
|
||||||
|
try {
|
||||||
|
const res = await axios.post(API, fd, {
|
||||||
|
onUploadProgress: (e) => {
|
||||||
|
if (e.total) bar.value = Math.round((e.loaded * 100) / e.total);
|
||||||
|
},
|
||||||
|
// 不要显式设置 Content-Type
|
||||||
|
});
|
||||||
|
alert("上传成功:" + JSON.stringify(res.data));
|
||||||
|
} catch (e) {
|
||||||
|
alert("上传失败:" + (e.response?.data?.message || e.message));
|
||||||
|
} finally {
|
||||||
|
bar.value = 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
Loading…
Reference in a new issue