在线一区二区三区高清视频,国产精品妇女一二三区,美女被遭强高潮网站在线播放,实拍各种胸走光见奶头

基于resumable.js和springboot上傳大文件顯示進(jìn)度條實例

時間:2025-05-14 15:48:55 類型:JS/JQUERY
字號:    

基于resumable.js的切片上傳大文件,且顯示進(jìn)度條(基于layui的進(jìn)度條), 并結(jié)合后臺使用springboot接收切片,合并切片的完整實例

1,  下載resumable.js 或使用 cdn引入js

        可以到https://www.bootcdn.cn/resumable.js/ 下載

2,    前端代碼 單個文件上傳顯示

<form class="layui-form" action="" lay-filter="addForm">
    <div class="layui-form-item">
        <label class="layui-form-label">文件上傳</label>

        <div class="layui-input-block">
            <div  class="layui-btn" id="uploadBigFile">
                <i class="layui-icon layui-icon-upload"></i> 選擇文件
            </div>
            <div class="layui-progress layui-hide" id="demo0" style="margin-top: 20px" lay-showPercent="true" lay-filter="file-upload-progress">
                <div class="layui-progress-bar" lay-percent="0%"></div>
            </div>
        </div>
    </div>

</form>
<script src="layui.js"></script>
<script src="resumable.js"></script>
<script>
    layui.config({
        base: '/vendor/layuiAdmin/res/' // 靜態(tài)資源所在路徑
    }).use(function(){
        let $ = layui.$
            ,layer = layui.layer
            ,element = layui.element;
        //基于Resumable.js
        const r = new Resumable({
            target: '/uploadFile',       // 后端分片上傳接口
            chunkSize: 1 * 1024 * 1024,      // 分片大?。J(rèn) 1MB)
            simultaneousUploads: 3,          // 并發(fā)請求數(shù)
            testChunks: false, // 不進(jìn)行測試分塊完整性檢查,以提高性能
            generateUniqueIdentifier: function(file) {
                // 提供自定義的文件唯一標(biāo)識符生成方法
                return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                    var r = (Math.random() * 16) | 0,
                        v = c == 'x' ? r : (r & 0x3) | 0x8;
                    return v.toString(16);
                });
            }
        });

        r.assignBrowse(document.getElementById('uploadBigFile'));
        // 文件添加到隊列時觸發(fā)
        r.on('fileAdded', function(file){
            console.log('File added', file);
            $("#demo0").removeClass('layui-hide')
            r.upload()
        });

        // 文件上傳開始時觸發(fā)
        r.on('fileProgress', function(file){
            // 渲染進(jìn)度條組件
            element.progress('file-upload-progress', Math.floor(file.progress() * 100) + '%'); // 設(shè)置 50% 的進(jìn)度
            //console.log('File progress', file.progress());
        });

        // 文件上傳成功時觸發(fā)
        r.on('fileSuccess', function(file, message){
            // console.log('File uploaded successfully', file, message);
            let obj = JSON.parse(message)
            console.log("新的文件名:" + obj.data)
        });

        // 文件上傳失敗時觸發(fā)
        r.on('fileError', function(file, message){
            console.log('File upload error', file, message);
        });

    });
</script>

3,   后臺springboot控制器代碼

@RestController

public class AdmUploadController {

    //配置的上傳目錄
    @Value("${web.uploadPath}")  
    private String uploadPath;

    //接收分片文件上傳
@PostMapping("uploadFile")
public R uploadFile(
        @RequestParam("resumableChunkNumber") int chunkNumber,
        @RequestParam("resumableTotalChunks") int totalChunks,
        @RequestParam("file") MultipartFile chunk,
        HttpServletRequest request) throws IOException {
    //表單body和url都會傳遞以下兩個參數(shù),參數(shù)接收會拼接
    String fileName = request.getParameter("resumableFilename");
    String identifier = request.getParameter("resumableIdentifier");
    // 目標(biāo)文件路徑,identifier是唯一的標(biāo)識符,用于存儲文件分片
    String  targetPath = uploadPath + identifier;
    File uploads = new File(targetPath);
    //創(chuàng)建臨時文件夾
    if (!uploads.exists()) {uploads.mkdirs();}

    System.out.println(targetPath+"/"+fileName + "." + chunkNumber);
    Path chunkPath = Paths.get(targetPath,fileName + "." + chunkNumber); // 分片文件路徑
    Files.copy(chunk.getInputStream(), chunkPath, StandardCopyOption.REPLACE_EXISTING);

    // 保存分片到服務(wù)器
    // 檢查是否所有分片都已上傳完畢,如果是,則合并分片文件到最終文件
    if (chunkNumber == totalChunks) {
        String newName = mergeChunks(targetPath, identifier, totalChunks,fileName); // 合并分片的方法實現(xiàn)見下文
        return R.builder().msg("All upload success").code(200).data(newName).build();
        // 所有分片上傳完畢,返回成功消息或進(jìn)行其他處理
    } else {
        return R.builder().msg("chunk upload success").code(200).build();
        // 分片上傳成功,返回成功消息或進(jìn)行其他處理
    }
}
private String  mergeChunks(String targetPath, String identifier, int totalChunks,String fileName) throws IOException {
    String suffix   = fileName.substring(fileName.lastIndexOf("."));
    String newName = UUID.randomUUID().toString().replace('-','_') + suffix;
    File mergedFile = new File(uploadPath + newName);
    // 最終存儲路徑并生成新的文件名
    try (FileOutputStream fos = new FileOutputStream(mergedFile, true)) {
        // 合并所有分片
        for (int i = 1; i <= totalChunks; i++) {
            File chunk = new File(targetPath + "/" + fileName + "." + i);
            Files.copy(chunk.toPath(), fos);
            chunk.delete();  // 刪除臨時分片
        }
        new File(targetPath).delete(); //刪除臨時存儲切片的目錄
        System.out.println("合并成功");
    } catch (IOException e) {
        System.out.println("合并失敗");
    }
    return newName;
}
        //刪除文件
        @GetMapping("delFile")
        public R delFile(String fileName){
            File file = new File(uploadPath + fileName);
            file.delete();
            return R.builder().msg("del success").code(200).build();
        }
}



@Data
@Builder
public class R {
    private String msg;
    private int code;
    private String data;
}


實際效果:

1.png2.png

3,    前端代碼 多個文件上傳顯示

<form class="layui-form" action="" lay-filter="addForm">
    <div class="layui-form-item">
        <label class="layui-form-label">文件上傳</label>

        <div class="layui-input-block">
            <div  class="layui-btn" id="uploadBigFile">
                <i class="layui-icon layui-icon-upload"></i> 選擇文件
            </div>
            <table class="layui-table" id="file-list">
                <thead><tr><th>文件名</th><th>文件大小</th><th>上傳狀態(tài)</th><th>操作</th></tr></thead>
                <tbody>
                </tbody>
            </table>
            <div class="layui-progress layui-hide" id="demo0" style="margin-top: 20px" lay-showPercent="true" lay-filter="file-upload-progress">
                <div class="layui-progress-bar" lay-percent="0%"></div>
            </div>
        </div>
    </div>

</form>
<script src="/vendor/layuiAdmin/res/layui/layui.js"></script>
<script src="/vendor/resumable.js"></script>
<script>
    layui.config({
        base: '/vendor/layuiAdmin/res/' // 靜態(tài)資源所在路徑
    }).use(function(){
        let $ = layui.$
            ,layer = layui.layer
            ,element = layui.element;
        //基于Resumable.js
        const r = new Resumable({
            target: '/adm/uploadFile',       // 后端分片上傳接口
            chunkSize: 2 * 1024 * 1024,      // 分片大?。J(rèn) 1MB)
            simultaneousUploads: 3,          // 并發(fā)請求數(shù)
            testChunks: false, // 不進(jìn)行測試分塊完整性檢查,以提高性能
            generateUniqueIdentifier: function(file) {
                // 提供自定義的文件唯一標(biāo)識符生成方法
                return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
                    var r = (Math.random() * 16) | 0,
                        v = c == 'x' ? r : (r & 0x3) | 0x8;
                    return v.toString(16);
                });
            }
        });

        r.assignBrowse(document.getElementById('uploadBigFile'));
        // 文件添加到隊列時觸發(fā)
        r.on('fileAdded', function(file){
            console.log('File added', file);
            let strTr = `<tr>
                             <td>${file.fileName}</td>
                             <td>${getfilesize(file.file.size)}</td>
                             <td>
                                <div class="layui-progress" lay-showPercent="true" lay-filter="${file.file.uniqueIdentifier}">
                                    <div class="layui-progress-bar" lay-percent="0%"></div>
                                </div>
                              </td>
                              <td>
                                    <input type="hidden" name="files" data-original="${file.fileName}" data-size="${getfilesize(file.file.size)}" id="${file.file.uniqueIdentifier}">
                                    <button type="button" class="layui-btn layui-bg-red layui-hide ${file.file.uniqueIdentifier} layui-btn-xs del_file">刪除</button>
                              </td>
                         </tr>`
            $("#file-list > tbody").append(strTr)
            element.render('progress', file.file.uniqueIdentifier);
            r.upload()
        });

        // 文件上傳開始時觸發(fā)
        r.on('fileProgress', function(file){
            // 渲染進(jìn)度條組件
            element.progress(file.file.uniqueIdentifier, Math.floor(file.progress() * 100) + '%');
            element.render('progress', file.file.uniqueIdentifier);
            //console.log('File progress', file.progress());
        });

        // 文件上傳成功時觸發(fā)
        r.on('fileSuccess', function(file, message){
            // console.log('File uploaded successfully', file, message);
            let obj = JSON.parse(message)
            console.log("新的文件名:" + obj.data)
            $("."+file.file.uniqueIdentifier).removeClass('layui-hide').data('filename',obj.data)
            $("#"+file.file.uniqueIdentifier).val(obj.data)
        });

        // 文件上傳失敗時觸發(fā)
        r.on('fileError', function(file, message){
            console.log('File upload error', file, message);
        });
        $(document).on("click",".del_file",function(){
            console.log("ok")
            let _this = $(this)
            let fileName = $(this).data('filename')
            $.get("/adm/delFile",{fileName},function(res){
                _this.parents('tr').remove();
            })
            return false;

        })

        function getfilesize(size) {
            if (!size)
                return "";

            var num = 1024.00; //byte

            if (size < num)
                return size + "B";
            if (size < Math.pow(num, 2))
                return (size / num).toFixed(2) + "K"; //kb
            if (size < Math.pow(num, 3))
                return (size / Math.pow(num, 2)).toFixed(2) + "M"; //M
            if (size < Math.pow(num, 4))
                return (size / Math.pow(num, 3)).toFixed(2) + "G"; //G
            return (size / Math.pow(num, 4)).toFixed(2) + "T"; //T
        }

    });
</script>

3.png

<