需求:有这样一个需求,通过找D盘中图片,然后进行预览。当点击的是文件夹则能进入到下一级,如果点击的是图片则进行显示预览。java部分看不懂,就粘贴了一部分。
前端代码;
css部分:
<style>
#files button {
margin-right: 10px;
background-color: #0b4180;
color: white;
}
#files button:hover {
background-color: #00B83F;
color: #0C0C0C;
}
#file-list li:hover {
cursor: pointer;
color: red;
}
#showImg {
width: 400px;
height: 400px;
}
</style>
<div id="files">
<h1>文件浏览</h1>
<button id="backfirst">返回上一级</button>
<button id="closeImg">关闭图片</button>
<ul id="file-list"></ul>
<img id="showImg" style="display: none;">
</div>
JS部分:
const baseURL = 'http://localhost:15112/browse/'; // 修改为你的后端服务器地址,(注:这里服务器路径我删了一部分)
let currentPathStack = ['files']; // 使用栈来记录当前路径
$(document).ready(function () {
fetchFiles();
});
function fetchFiles() {
const path = currentPathStack[currentPathStack.length - 1]; // 获取当前路径
console.log('当前路径:', path)
$.ajax({
type: 'GET',
url: `${baseURL}${path}`,
success: function (data) {
const fileList = $('#file-list');
fileList.empty(); // 清空之前的列表
console.log('原始数据', data)
data.forEach(item => {
const li = $('<li></li></br>');
li.text(item.name);
li.on('click', function (e) {
//e.stopPropagation(); // 阻止事件冒泡,防止点击 li 时触发 ul 的点击事件
if (item.directory == true) {
currentPathStack.push(`${path}-${item.name}`); // 将当前文件夹路径推入栈中
$('#backfirst').prop('disabled', false); // 启用返回按钮
$('#showImg').hide();
$('#closeImg').hide();
fetchFiles(); // 递归调用以加载新目录的内容
} else if (item.directory == false) {
$('#showImg').attr('src', `data:image/jpeg;base64,${item.data}`);
$('#showImg').show(); // 显示图片
// 显示关闭图片的按钮
$('#closeImg').show();
}
});
fileList.append(li);
});
// 如果栈中不止一个元素(即不在根目录),则启用返回按钮
$('#backfirst').prop('disabled', currentPathStack.length <= 1);
},
error: function (error) {
console.error('请求失败:', error);
}
});
}
// 返回上一级目录
$('#backfirst').click(function () {
if (!$(this).is(':disabled')) { // 确保按钮没有被禁用
currentPathStack.pop(); // 弹出当前路径
// 在返回上一级目录时,隐藏图片并隐藏关闭按钮
$('#showImg').hide();
$('#closeImg').hide();
fetchFiles(); // 加载上一级目录的内容
}
});
// 关闭图片按钮的点击事件
$('#closeImg').click(function () {
// 隐藏图片并隐藏关闭按钮
$('#showImg').hide();
$('#closeImg').hide();
});
后端部分:
controller.java文件夹
@GetMapping("/browse/{path:.+}")
@ResponseBody
public List<FileItem> browse(@PathVariable String path) throws IOException {
File dir = new File("D:\\"+path.replaceAll("-","/"));//这里用-转为/,我直接用斜杠不行,所以后端直接转换了一下,就能用了
List<FileItem> items = new ArrayList<>();
for (File file : dir.listFiles()) {
if (file.isDirectory()) {
items.add(new FileItem(file.getName(), true, file.getAbsolutePath()));
} else {
items.add(new FileItem(file.getName(), false, encodeImageToBase64(file)));
}
}
return items;
}
private String encodeImageToBase64(File imageFile) throws IOException {
// 将图片文件转换为Base64编码的字符串
try (FileInputStream fis = new FileInputStream(imageFile)) {
byte[] buffer = new byte[1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
baos.write(buffer, 0, bytesRead);
}
byte[] imageBytes = baos.toByteArray();
return Base64.getEncoder().encodeToString(imageBytes);
}
}
fileItem.java文件夹
public class FileItem {
String name;
boolean isDirectory;
String data; // 对于图片,存储Base64编码的字符串;对于文件夹,存储路径
public FileItem(String name, boolean isDirectory, String data) {
this.name = name;//文件及文件夹名字
this.isDirectory = isDirectory;//判断是文件夹还是文件(图片)
this.data = data;//路径
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isDirectory() {
return isDirectory;
}
public void setDirectory(boolean directory) {
isDirectory = directory;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
}
效果图:
在这里插入图片描述