From d6e1c45e8b681f8d5b0a4796a36d4b45fadce646 Mon Sep 17 00:00:00 2001
From: Eason010212 <1371033826@qq.com>
Date: Sun, 22 Jun 2025 15:32:36 +0800
Subject: [PATCH] update-file-storage
---
js/projects.js | 300 +++++++++++++++++++++++++++++++++----------------
mixio.js | 6 +-
2 files changed, 204 insertions(+), 102 deletions(-)
diff --git a/js/projects.js b/js/projects.js
index 99e6eed..eed639e 100644
--- a/js/projects.js
+++ b/js/projects.js
@@ -4205,115 +4205,217 @@ setInterval(function(){
}
}, 30000)
-
+storDia = false
function open_storage(){
var editForm = $('
' +
+ '
' +
+ '
')
+
+ tableContainer.append(actionBar)
+ tableContainer.append(fileTable)
+ editForm.append(tableContainer)
+
// Bottom section
var bottomDiv = $('
')
var cancelEdit = $('
')
bottomDiv.append(cancelEdit)
editForm.append(bottomDiv)
- var modifyDia = dialog({
- content: editForm[0],
- cancel: false
- })
+ var selectedFiles = [];
+
+ // Function to trigger file download
+ function downloadFile(filename) {
+ let url = "store/" + globalUserName + "/" + globalProjectName + "/" + filename;
+ let a = document.createElement('a');
+ a.href = url;
+ a.download = filename;
+ document.body.appendChild(a);
+ a.click();
+ document.body.removeChild(a);
+ }
+
+ var sync_stor = function(){
+ $('#fileTableBody').empty()
+ selectedFiles = [];
+ $('#deleteSelected').prop('disabled', true);
+ $('#downloadSelected').prop('disabled', true);
+ $('#selectAll').prop('checked', false);
+
+ $.getJSON('getImgStore', {
+ 'projectName': globalProjectName
+ }, function(res) {
+ if(res.length == 0) {
+ $('#fileTableBody').append('
| 暂无存储文件 |
')
+ return;
+ }
+
+ for (let ri = 0; ri < res.length; ri++) {
+ let filename = res[ri];
+ let url = "store/" + globalUserName + "/" + globalProjectName + "/" + filename;
+ let isText = filename.endsWith('.txt');
+ let timeStamp;
+ if(filename.split("_").length>1) {
+ timeStamp = parseInt(filename.split("_")[1].split('.')[0])
+ } else {
+ timeStamp = parseInt(filename.split('.')[0]);
+ }
+ let timeString = new Date(timeStamp).toLocaleString();
+ let fileType = isText ? '文本' : '图片';
+
+ let row = $('
|
');
+
+ // Checkbox
+ row.append('
| ');
+
+ // Filename
+ row.append('
' + filename + ' | ');
+
+ // Type
+ row.append('
' + fileType + ' | ');
+
+ // Date
+ row.append('
' + timeString + ' | ');
+
+ // Size (placeholder - you might need to get actual file size from server)
+ row.append('
-- | ');
+
+ // Actions
+ let actionCell = $('
| ');
+
+ // Download button (added for each file)
+ let downloadBtn = $('
');
+ downloadBtn.click(function() {
+ downloadFile(filename);
+ });
+ actionCell.append(downloadBtn);
+
+ if (isText) {
+ let viewBtn = $('
');
+ viewBtn.click(function() {
+ $.ajax({
+ url: url,
+ success: function(content) {
+ let textDialog = dialog({
+ content: $('
')[0],
+ cancel: true,
+ cancelValue: '关闭'
+ });
+ textDialog.showModal();
+ }
+ });
+ });
+ actionCell.append(viewBtn);
+ } else {
+ let viewBtn = $('
');
+ viewBtn.click(function() {
+ let fullDialog = dialog({
+ content: $('
')[0],
+ cancel: true,
+ cancelValue: '关闭'
+ });
+ fullDialog.showModal();
+ });
+ actionCell.append(viewBtn);
+ }
+
+ let deleteBtn = $('
');
+ deleteBtn.click(function() {
+ if(confirm('确定要删除此文件吗?')) {
+ $.getJSON('deleteImgStore', {
+ 'projectName': globalProjectName,
+ 'filename': filename
+ }, function() {
+ sync_stor();
+ });
+ }
+ });
+ actionCell.append(deleteBtn);
+
+ row.append(actionCell);
+ $('#fileTableBody').append(row);
+ }
+
+ // Add checkbox event handlers
+ $('.fileCheckbox').change(function() {
+ let filename = $(this).data('filename');
+ if($(this).is(':checked')) {
+ if(!selectedFiles.includes(filename)) {
+ selectedFiles.push(filename);
+ }
+ } else {
+ selectedFiles = selectedFiles.filter(f => f !== filename);
+ $('#selectAll').prop('checked', false);
+ }
+ $('#deleteSelected').prop('disabled', selectedFiles.length === 0);
+ $('#downloadSelected').prop('disabled', selectedFiles.length === 0);
+ });
+ });
+ }
+
+ sync_stor();
+
+ client.on('message', function(topic, msg) {
+ if(topic.split("/")[2][0] == "$")
+ sync_stor();
+ });
+
+ if(!storDia)
+ storDia = dialog({
+ content: editForm[0],
+ cancel: false
+ });
cancelEdit.click(function() {
- modifyDia.close().remove()
- })
+ storDia.close();
+ });
- modifyDia.showModal()
+ storDia.showModal();
+
+ // Select all checkbox
+ $('#selectAll').change(function() {
+ $('.fileCheckbox').prop('checked', $(this).is(':checked')).trigger('change');
+ });
+
+ // Delete selected button
+ $('#deleteSelected').click(function() {
+ if(selectedFiles.length === 0) return;
+
+ if(confirm('确定要删除选中的 ' + selectedFiles.length + ' 个文件吗?')) {
+ let deletePromises = selectedFiles.map(filename => {
+ return $.getJSON('deleteImgStore', {
+ 'projectName': globalProjectName,
+ 'filename': filename
+ });
+ });
+
+ Promise.all(deletePromises).then(() => {
+ sync_stor();
+ });
+ }
+ });
+
+ // Download selected button
+ $('#downloadSelected').click(function() {
+ if(selectedFiles.length === 0) return;
+
+ // Download each file one by one
+ selectedFiles.forEach(filename => {
+ downloadFile(filename);
+ });
+ });
}
\ No newline at end of file
diff --git a/mixio.js b/mixio.js
index e152e48..319cc1f 100644
--- a/mixio.js
+++ b/mixio.js
@@ -833,7 +833,7 @@ var mixioServer = async function() {
var topic = packet.topic.split('/')
var payload = String(packet.payload)
if (topic.length == 3) {
- if(topic[2] == 'storage') {
+ if(topic[2][0] == '$') {
// 判断是否是base64, 开头为data:image/***;base64, ***可以为png,bmp,jpg,jpeg,gif,svg,ico
const allowFormats = ['png', 'bmp', 'jpg', 'jpeg', 'gif', 'svg', 'ico'];
const base64Reg = /^data:image\/(\w+);base64,/;
@@ -842,7 +842,7 @@ var mixioServer = async function() {
// 是base64
const format = match[1];
const timeStamp = Date.now();
- const fileName = `${timeStamp}.${format}`;
+ const fileName = topic[2] + '_' + `${timeStamp}.${format}`;
const filePath = path.join('store', topic[0], topic[1], fileName);
const base64Data = payload.replace(base64Reg, '');
const buffer = Buffer.from(base64Data, 'base64');
@@ -851,7 +851,7 @@ var mixioServer = async function() {
} else {
// 全部明文存为txt
const timeStamp = Date.now();
- const fileName = `${timeStamp}.txt`;
+ const fileName = topic[2] + '_' + `${timeStamp}.txt`;
const filePath = path.join('store', topic[0], topic[1], fileName);
fs.mkdirSync(path.dirname(filePath), { recursive: true});
fs.writeFileSync(filePath, payload);