2023年9月20日18:20:14

master
zhangmeng 2023-09-20 18:20:33 +08:00
parent 17c4c219ac
commit ccf04aca91
7 changed files with 313 additions and 8 deletions

View File

@ -28,22 +28,20 @@ package com.zhangmeng.tools.controller;
import com.zhangmeng.tools.utils.ImagePath; import com.zhangmeng.tools.utils.ImagePath;
import com.zhangmeng.tools.utils.ResourcesUtils; import com.zhangmeng.tools.utils.ResourcesUtils;
import javafx.beans.property.SimpleDoubleProperty; import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections; import javafx.collections.FXCollections;
import javafx.collections.ObservableList; import javafx.collections.ObservableList;
import javafx.event.ActionEvent; import javafx.event.ActionEvent;
import javafx.fxml.FXML; import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader; import javafx.fxml.FXMLLoader;
import javafx.geometry.Pos; import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene; import javafx.scene.Scene;
import javafx.scene.control.*; import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SplitPane;
import javafx.scene.image.Image; import javafx.scene.image.Image;
import javafx.scene.image.ImageView; import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane; import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox; import javafx.scene.layout.HBox;
import javafx.scene.paint.Paint; import javafx.scene.paint.Paint;
import javafx.scene.text.Font; import javafx.scene.text.Font;
@ -610,4 +608,12 @@ public class HomeController implements Serializable {
public void log_console_menu_item(ActionEvent actionEvent) { public void log_console_menu_item(ActionEvent actionEvent) {
load_small_tools(18); load_small_tools(18);
} }
public void edit_plus_code_menu_item(ActionEvent actionEvent) {
load_small_tools(19);
}
public void minio_upload_menu_item(ActionEvent actionEvent) {
load_small_tools(20);
}
} }

View File

@ -0,0 +1,178 @@
package com.zhangmeng.tools.controller;
import cn.hutool.crypto.digest.DigestUtil;
import com.zhangmeng.tools.utils.AlertUtils;
import com.zhangmeng.tools.utils.EncryptUtils;
import com.zhangmeng.tools.utils.ImagePath;
import com.zhangmeng.tools.utils.MinioUtils;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.stage.DirectoryChooser;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
/**
*
*
* @author zhangmeng
* @version 1.0
* @date 202391515:19:58
*/
@Slf4j
public class MinioUploadController {
@FXML
public TextField endpoint;
@FXML
public TextField accessKey;
@FXML
public TextField secretKey;
@FXML
public TextField bucket;
@FXML
public ImageView iv;
@FXML
public Button file_choose;
@FXML
public Button upload;
@FXML
public TextField file_path;
@FXML
public void initialize() {
file_choose.setText(null);
ImageView iv = new ImageView(new Image(ImagePath.path(ImagePath.ImagePathType.IMAGE_FILE)));
iv.setPreserveRatio(true);
iv.setFitWidth(18);
file_choose.setGraphic(iv);
file_choose.setOnAction(event -> choose_file());
//默认值
endpoint.setText("http://192.168.1.14:9000");
accessKey.setText("minioadmin");
secretKey.setText("minioadmin");
bucket.setText("mediafiles");
upload.setOnAction(event -> {
if (endpoint.getText().length() == 0) {
AlertUtils.alert_warning("endpoint不能为空!");
return;
}
if (accessKey.getText().length() == 0) {
AlertUtils.alert_warning("accessKey不能为空!");
return;
}
if (secretKey.getText().length() == 0) {
AlertUtils.alert_warning("secretKey不能为空!");
return;
}
if (bucket.getText().length() == 0) {
AlertUtils.alert_warning("bucket不能为空!");
return;
}
File file = new File(file_path.getText());
String extension = FilenameUtils.getExtension(file.getName());
if (extension.equals("jpg") || extension.equals("png")) {
images_upload();
}
if (extension.equals("mp4") || extension.equals("avi")) {
videos_upload();
}
});
}
public void videos_upload() {
File file = new File(file_path.getText());
MinioUtils.getInstance(endpoint.getText(), accessKey.getText(), secretKey.getText());
try {
MinioUtils.FileChunkReader filereader = new MinioUtils.FileChunkReader(file.toPath(), 1024 * 1024 * 10);
byte[] chunk;
int i = 0;
while ((chunk = filereader.readNextChunk()) != null) {
// process the chunk
String fileMd5 = DigestUtil.md5Hex(chunk);
//判断分块是否存在
if (!MinioUtils.checkChunk(fileMd5, i, bucket.getText())) {
//得到分块文件的目录路径
String chunkFileFolderPath = MinioUtils.getChunkFileFolderPath(fileMd5);
//得到分块文件的路径
String chunkFilePath = chunkFileFolderPath + i;
try {
//将文件存储至minIO
MinioUtils.addMediaFilesToMinIO(chunk, bucket.getText(), chunkFilePath, "application/octet-stream");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
//合并分块
String fileExt = "";
String mergeFilePath = MinioUtils.getFilePathByMd5(filereader.getMd5(),fileExt);
try {
//上传文件到minIO
MinioUtils.addMediaFilesToMinIO(filereader.getFile().getAbsolutePath(), bucket.getText(), mergeFilePath);
log.debug("合并文件上传MinIO完成{}", filereader.getFile().getAbsolutePath());
} catch (Exception e) {
e.printStackTrace();
log.error("合并文件时上传文件出错");
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void images_upload() {
File file = new File(file_path.getText());
MinioUtils.getInstance(endpoint.getText(), accessKey.getText(), secretKey.getText());
try {
byte[] bytes = FileUtils.readFileToByteArray(file);
String md5Hex = DigestUtil.md5Hex(bytes);
String contentType = Files.probeContentType(file.toPath());
String extension = FilenameUtils.getExtension(file.getName());
MinioUtils.addMediaFilesToMinIO(bytes, bucket.getText(), md5Hex + "." + extension, contentType);
} catch (IOException e) {
e.printStackTrace();
}
}
public void choose_file() {
Stage stage = (Stage) file_choose.getScene().getWindow();
FileChooser dc = new FileChooser();
dc.setTitle("文件选择");
dc.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("图片类型", "*.jpg", "*.png"));
File file = dc.showOpenDialog(stage);
if (file != null) {
String path = file.getAbsolutePath();
file_path.setText(path);
log.info("base64---file:{}", path);
iv.setImage(new Image(file.getPath()));
}
}
}

View File

@ -86,6 +86,8 @@ public class SmallToolsController {
private AnchorPane file_edit; private AnchorPane file_edit;
private AnchorPane layui_form_gen; private AnchorPane layui_form_gen;
private AnchorPane log_console; private AnchorPane log_console;
private AnchorPane editPlusCode;
private AnchorPane minioUpload;
@FXML @FXML
private ListView<ResourcesUtils.SmallTools> listView; private ListView<ResourcesUtils.SmallTools> listView;
@ -431,10 +433,57 @@ public class SmallToolsController {
} }
log_console(flag); log_console(flag);
} }
if (newValue.getIndex() == 19) {
if (editPlusCode != null) {
flag = true;
}
editPlusCode(flag);
}
if (newValue.getIndex() == 20) {
if (minioUpload != null) {
flag = true;
}
minioUpload(flag);
}
} }
}); });
} }
private void minioUpload(boolean flag) {
//默认选择第一个
listView.getSelectionModel().select(20);
if (!flag) {
try {
root = FXMLLoader.load(ResourcesUtils.getResource("minio-upload"));
} catch (IOException e) {
e.printStackTrace();
}
minioUpload = root;
} else {
root = minioUpload;
}
common_method();
}
private void editPlusCode(boolean flag) {
//默认选择第一个
listView.getSelectionModel().select(19);
if (!flag) {
try {
root = FXMLLoader.load(ResourcesUtils.getResource("edit_plus_code"));
} catch (IOException e) {
e.printStackTrace();
}
editPlusCode = root;
} else {
root = editPlusCode;
}
common_method();
}
private void log_console(boolean flag) { private void log_console(boolean flag) {
//默认选择第一个 //默认选择第一个
listView.getSelectionModel().select(18); listView.getSelectionModel().select(18);
@ -506,6 +555,8 @@ public class SmallToolsController {
case File_Edit -> new Image("image/编辑.png"); case File_Edit -> new Image("image/编辑.png");
case LayUI_Form_Gen -> new Image("image/layui.png"); case LayUI_Form_Gen -> new Image("image/layui.png");
case LogConsole -> new Image("image/layui.png"); case LogConsole -> new Image("image/layui.png");
case EditPlusCode -> new Image("image/layui.png");
case MinioUpload -> new Image("image/layui.png");
}; };
} }

View File

@ -19,7 +19,41 @@ import java.nio.file.StandardOpenOption;
public class MinioUtils { public class MinioUtils {
public static void getInstance(String endpoint, String accessKey, String secretKey) { public static void getInstance(String endpoint, String accessKey, String secretKey) {
minioClient(endpoint, accessKey, secretKey);
if (minioClient == null){
minioClient(endpoint, accessKey, secretKey);
}
}
public static String getFilePathByMd5(String fileMd5, String fileExt) {
return fileMd5.substring(0, 1) + "/" + fileMd5.substring(1, 2) + "/" + fileMd5 + "/" + fileMd5 + fileExt;
}
public static boolean checkChunk(String fileMd5, int chunkIndex,String bucket_name) {
//得到分块文件目录
String chunkFileFolderPath = getChunkFileFolderPath(fileMd5);
//得到分块文件的路径
String chunkFilePath = chunkFileFolderPath + chunkIndex;
//文件流
InputStream fileInputStream = null;
try {
fileInputStream = minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucket_name)
.object(chunkFilePath)
.build());
if (fileInputStream != null) {
//分块已存在
return true;
}
} catch (Exception e) {
e.printStackTrace();
}
//分块未存在
return false;
} }
public static class FileChunkReader implements AutoCloseable { public static class FileChunkReader implements AutoCloseable {
@ -220,7 +254,7 @@ public class MinioUtils {
public static void test(String path){ public static void test(String path){
try (MinioUtils.FileChunkReader reader = new MinioUtils.FileChunkReader(Path.of(path), chunkSize);) { // 1MB chunk size try (FileChunkReader reader = new FileChunkReader(Path.of(path), chunkSize);) { // 1MB chunk size
byte[] chunk; byte[] chunk;
//扩展名 //扩展名
String extName = reader.getExtension(); String extName = reader.getExtension();

View File

@ -134,6 +134,8 @@ public class ResourcesUtils {
File_Edit("文件编辑器", 16), File_Edit("文件编辑器", 16),
LayUI_Form_Gen("layui-from 表单生成", 17), LayUI_Form_Gen("layui-from 表单生成", 17),
LogConsole("日志输出", 18), LogConsole("日志输出", 18),
EditPlusCode("edit-plus注册码", 19),
MinioUpload("minio-upload文件上传", 20),
; ;
SmallTools(String title, int index) { SmallTools(String title, int index) {

View File

@ -52,6 +52,8 @@
<MenuItem mnemonicParsing="false" text="文件编辑器" onAction="#file_edit_menu_item"/> <MenuItem mnemonicParsing="false" text="文件编辑器" onAction="#file_edit_menu_item"/>
<MenuItem mnemonicParsing="false" text="LayUI表单代码生成" onAction="#layui_form_gen_menu_item"/> <MenuItem mnemonicParsing="false" text="LayUI表单代码生成" onAction="#layui_form_gen_menu_item"/>
<MenuItem mnemonicParsing="false" text="日志输出" onAction="#log_console_menu_item"/> <MenuItem mnemonicParsing="false" text="日志输出" onAction="#log_console_menu_item"/>
<MenuItem mnemonicParsing="false" text="EditPlus注册码生成" onAction="#edit_plus_code_menu_item"/>
<MenuItem mnemonicParsing="false" text="minio文件上传" onAction="#minio_upload_menu_item"/>
</items> </items>
</Menu> </Menu>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ProgressBar?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane prefHeight="649.0" prefWidth="1200.0" style="-fx-background-color: 1px;" xmlns="http://javafx.com/javafx/19" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.zhangmeng.tools.controller.MinioUploadController">
<children>
<Label layoutX="265.0" layoutY="72.0" text="endpoint:" />
<TextField fx:id="endpoint" layoutX="344.0" layoutY="68.0" prefHeight="25.0" prefWidth="612.0" />
<TextField fx:id="accessKey" layoutX="344.0" layoutY="125.0" prefHeight="25.0" prefWidth="612.0" />
<TextField fx:id="secretKey" layoutX="344.0" layoutY="181.0" prefHeight="25.0" prefWidth="612.0" />
<Label layoutX="263.0" layoutY="129.0" text="accessKey:" />
<Label layoutX="264.0" layoutY="185.0" text="secretKey:" />
<Label layoutX="278.0" layoutY="242.0" text="bucket:" />
<TextField fx:id="bucket" layoutX="344.0" layoutY="238.0" prefHeight="25.0" prefWidth="612.0" />
<Label layoutX="284.0" layoutY="308.0" text="文件:" />
<AnchorPane layoutX="344.0" layoutY="317.0" prefHeight="153.0" prefWidth="227.0" style="-fx-border-color: gray;-fx-border-width: 1px">
<children>
<ImageView fx:id="iv" fitHeight="153.0" fitWidth="227.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<Button fx:id="file_choose" layoutX="623.0" layoutY="382.0" mnemonicParsing="false" text="文件选择" />
<Button fx:id="upload" layoutX="752.0" layoutY="382.0" mnemonicParsing="false" text="上传" />
<ProgressBar layoutX="263.0" layoutY="539.0" prefHeight="7.0" prefWidth="746.0" progress="0.0" />
<Label layoutX="209.0" layoutY="534.0" text="进度:" />
<TextField fx:id="file_path" layoutX="623.0" layoutY="317.0" prefHeight="25.0" prefWidth="331.0" />
</children>
</AnchorPane>