{"version":3,"file":"naive-upload.min.cjs","sources":["../../../src/Model/RunMode.ts","../../../src/Model/Layout.ts","../../../src/Model/RGBAColor.ts","../../../src/Model/Settings.ts","../../../src/Piece/FileInput.vue3.vue","../../../src/Model/FileType.ts","../../../src/Piece/SelectedFileInfo.vue3.vue","../../../src/Layout/Card/index.vue3.vue","../../../src/Layout/Detailedly/index.vue3.vue","../../../src/Layout/index.vue3.vue","../../../src/Layout/Card/info.vue3.vue","../../../src/Layout/Detailedly/info.vue3.vue","../../../src/Layout/info.vue3.vue","../../../src/Piece/SingleUpload.vue3.vue","../../../src/Piece/DropFileInput.vue3.vue","../../../src/Extention/DraggingHelper.ts","../../../src/Piece/MultipleUpload.vue3.vue","../../../src/Extention/UploadError.ts","../../../src/Model/RawFile.ts","../../../src/Extention/FileTypeHelper.ts","../../../src/Model/SelectedFile.ts","../../../src/Extention/SimpleGuid.ts","../../../src/Extention/FileSizeHelper.ts","../../../src/Model/ChunkFile.ts","../../../src/Extention/HashWorkerScript.js","../../../src/Extention/FileReadHelper.ts","../../../src/Model/HashWorkerMessageType.ts","../../../src/Extention/HashHelper.ts","../../../src/Model/UploadWorkerMessageType.ts","../../../src/Model/PreUploadChunkFileState.ts","../../../src/Extention/UploadWorkerScript.ts","../../../src/Extention/UploadHelper.ts","../../../src/Core/NaiveUpload.ts","../../../src/index.vue3.vue","../../../src/Extention/DefaultApiService.ts","../../../src/export.vue3.ts"],"sourcesContent":["﻿/**\r\n * 上传组件运行模式\r\n *\r\n * @author LCTR\r\n * @date 2022-06-24\r\n */\r\nexport enum RunMode {\r\n    /**\r\n     * 添加文件后会自动校验，自动上传\r\n     */\r\n    全自动 = 'AT',\r\n\r\n    /**\r\n     * 添加文件后需要主动调用校验方法以及上传方法\r\n     */\r\n    手动挡 = 'MT',\r\n\r\n    /**\r\n     * 添加文件后会自动校验，但需要主动调用上传方法\r\n     */\r\n    半自动 = 'AMT'\r\n}","﻿/**\r\n * 上传组件布局\r\n *\r\n * @author LCTR\r\n * @date 2022-06-24\r\n */\r\nexport enum Layout {\r\n    卡片 = 'Card',\r\n    清单 = 'Detailedly'\r\n}","/**\r\n * 有透明度的RGB颜色值\r\n *\r\n * @author LCTR\r\n * @date 2022-12-05\r\n */\r\nexport default class RGBAColor {\r\n    /**\r\n     * @param r 红色值\r\n     * @param g 绿色值\r\n     * @param b 蓝色值\r\n     * @param a 色彩空间\r\n     */\r\n    constructor(r: number, g: number, b: number, a: number) {\r\n        this.r = r;\r\n        this.g = g;\r\n        this.b = b;\r\n        this.a = a;\r\n    }\r\n\r\n    /**\r\n    * 红色值\r\n    */\r\n    r: number;\r\n\r\n    /**\r\n    * 绿色值\r\n    */\r\n    g: number;\r\n\r\n    /**\r\n    * 蓝色值\r\n    */\r\n    b: number;\r\n\r\n    /**\r\n    * 色彩空间\r\n    */\r\n    a: number;\r\n\r\n    /**\r\n     * 序列化\r\n     */\r\n    toString: (this: RGBAColor) => string = () => `rgba(${this.r}, ${this.g}, ${this.b}, ${this.a})`;\r\n\r\n    /**\r\n     * @param rgba {r 红色值, g 绿色值, b 蓝色值, a 色彩空间}\r\n     */\r\n    public static convertFrom(rgba: { r: number, g: number, b: number, a: number }): RGBAColor {\r\n        return new RGBAColor(rgba.r, rgba.g, rgba.b, rgba.a);\r\n    }\r\n}","﻿import { RunMode } from \"../Model/RunMode\";\r\nimport { Layout } from \"../Model/Layout\";\r\nimport RGBAColor from \"./RGBAColor\";\r\n\r\n\r\n/**\r\n * 文件上传组件设置\r\n *\r\n * @author LCTR\r\n * @date 2022-06-24\r\n */\r\nexport default class Settings {\r\n    /**\r\n     * 设置\r\n     *\r\n     * @param action 此方法的参数为当前示例\r\n     */\r\n    public readonly build: (action: (model: Settings) => void) => Settings = (action) => {\r\n        action(this);\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * 设置\r\n     *\r\n     * @param action 此方法的参数为当前示例\r\n     */\r\n    public readonly setup: (this: Settings, action: (model: Settings) => void) => Settings = (action) => {\r\n        action(this);\r\n        return this;\r\n    };\r\n\r\n    /**\r\n     * 默认设置\r\n     */\r\n    public static default: () => Settings = () => new Settings();\r\n\r\n    /**\r\n     * 默认设置\r\n     */\r\n    public static defaultWithConfigCode: (configCode: string) => Settings = (configCode: string) => {\r\n        return new Settings().setup(x => x.configCode = configCode);\r\n    }\r\n\r\n    /**\r\n     * 文件上传配置编码\r\n     *\r\n     * @默认值 default\r\n     */\r\n    configCode: string = 'default';\r\n\r\n    /**\r\n     * 文件上传并发数\r\n     *\r\n     * @默认值 3\r\n     */\r\n    concurrentFile: number = 3;\r\n\r\n    /**\r\n     * 分片文件上传并发数\r\n     *\r\n     * @默认值 3\r\n     */\r\n    concurrentChunkFile: number = 3;\r\n\r\n    /**\r\n     * 小贴士\r\n     *\r\n     * @默认值 单击或拖动文件到此区域即可上传\r\n     */\r\n    tip: string = '单击或拖动文件到此区域即可上传';\r\n\r\n    /**\r\n     * 布局\r\n     *\r\n     * @默认值 Layout.卡片\r\n     */\r\n    layout: Layout = Layout.卡片;\r\n\r\n    /**\r\n     * 运行模式\r\n     *\r\n     * @默认值 RunMode.全自动\r\n     */\r\n    runMode: RunMode = RunMode.全自动;\r\n\r\n    /**\r\n     * 是否启用文件切片\r\n     *\r\n     * @默认值 true\r\n     */\r\n    enableChunk: boolean = true;\r\n\r\n    /**\r\n     * 切片规格（文件字节数）\r\n     *\r\n     * @默认值 2097152（即为2 * 1024 * 1024 = 2MB）\r\n     */\r\n    chunkSize: number = 2097152;\r\n\r\n    /**\r\n     * 发生错误时的重试次数\r\n     *\r\n     * @默认值 3\r\n     */\r\n    retry: number = 3;\r\n\r\n    /**\r\n     * 是否启用Web Worker\r\n     * <p>在浏览器不支持时此设置不会生效</P>\r\n     *\r\n     * @默认值 true\r\n     */\r\n    enableWorker: boolean = true;\r\n\r\n    /**\r\n     * 只读模式\r\n     *\r\n     * @默认值 false\r\n     */\r\n    readonly: boolean = false;\r\n\r\n    /**\r\n     * 调试模式\r\n     */\r\n    debug: boolean = false;\r\n\r\n    /**\r\n     * 显示错误信息\r\n     */\r\n    alertErrorInfo: boolean = false;\r\n\r\n    /**\r\n     * 启用拖动排序功能\r\n     *\r\n     * @默认值 true\r\n     */\r\n    enableDrag: boolean = true;\r\n\r\n    /**\r\n     * 校验状态的颜色\r\n     * \r\n     * @默认值 new RGBAColor(255, 235, 59, 0.5)\r\n     */\r\n    statusCheckingColor: RGBAColor = new RGBAColor(255, 235, 59, 0.5);\r\n\r\n    /**\r\n     * 上传状态的颜色\r\n     * \r\n     * @默认值 new RGBAColor(144, 206, 255, 0.5)\r\n     */\r\n    statusUploadingColor: RGBAColor = new RGBAColor(144, 206, 255, 0.5);\r\n\r\n    /**\r\n     * 暂停状态的颜色\r\n     * \r\n     * @默认值 new RGBAColor(158, 158, 158, 0.5)\r\n     */\r\n    statusPausedColor: RGBAColor = new RGBAColor(158, 158, 158, 0.5);\r\n\r\n    /**\r\n     * 暂停状态副标题的颜色\r\n     * \r\n     * @默认值 new RGBAColor(244, 154, 3, 0.5)\r\n     */\r\n    statusPausedSubColor: RGBAColor = new RGBAColor(244, 154, 3, 0.5);\r\n\r\n    /**\r\n     * 完成状态的颜色\r\n     * \r\n     * @默认值 new RGBAColor(76, 175, 80, 0.1)\r\n     */\r\n    statusDoneColor: RGBAColor = new RGBAColor(76, 175, 80, 0.1);\r\n\r\n    /**\r\n     * 完成状态副标题的颜色\r\n     * \r\n     * @默认值 new RGBAColor(3, 169, 244, 0.5)\r\n     */\r\n    statusDoneSubColor: RGBAColor = new RGBAColor(3, 169, 244, 0.5);\r\n\r\n    /**\r\n     * 错误状态的颜色\r\n     * \r\n     * @默认值 new RGBAColor(255, 0, 30, 0.35)\r\n     */\r\n    statusErrorColor: RGBAColor = new RGBAColor(255, 0, 30, 0.35);\r\n\r\n    /**\r\n     * 错误状态副标题的颜色\r\n     * \r\n     * @默认值 new RGBAColor(232, 31, 31, 0.5)\r\n     */\r\n    statusErrorSubColor: RGBAColor = new RGBAColor(232, 31, 31, 0.5);\r\n\r\n    /**\r\n     * 准备拖动时的动画颜色\r\n     * \r\n     * @默认值 new RGBAColor(255, 152, 0, 0.8)\r\n     */\r\n    dragReadyColor: RGBAColor = new RGBAColor(255, 152, 0, 0.8);\r\n\r\n    /**\r\n     * 拖动时的动画颜色\r\n     * \r\n     * @默认值 new RGBAColor(255, 152, 0, 0.5)\r\n     */\r\n    dragMovingColor: RGBAColor = new RGBAColor(255, 152, 0, 0.5);\r\n\r\n    /**\r\n     * 结束拖动时的动画颜色\r\n     * \r\n     * @默认值 new RGBAColor(255, 87, 34, 0.8)\r\n     */\r\n    dragOverColor: RGBAColor = new RGBAColor(255, 87, 34, 0.8);\r\n\r\n    /**\r\n     * 准备开始拖动的时间（单位ms）\r\n     * \r\n     * @默认值 1500\r\n     */\r\n    dragPreparationTime: number = 1500;\r\n\r\n    /**\r\n     * 拖动时变换位置的等待时间（单位ms）\r\n     * \r\n     * @默认值 1300\r\n     */\r\n    dragChangePositionTime: number = 1300;\r\n}","<template>\r\n  <div\r\n    class=\"upload-btn\"\r\n    v-on:click=\"chosingFile\"\r\n    :title=\"upload.getSettings().tip\"\r\n  >\r\n    <div @click.stop=\"() => {}\">\r\n      <input\r\n        type=\"file\"\r\n        :multiple=\"upload.getConfig().upperLimit > 1\"\r\n        :ref=\"setFileInputRef\"\r\n        :accept=\"upload.getAllowedTypes()\"\r\n        v-on:change=\"choseFile\"\r\n      />\r\n    </div>\r\n    <div class=\"upload-box-content\">\r\n      <slot></slot>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ComponentPublicInstance, inject, reactive } from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({});\r\n\r\n// 文件选择框引用对象\r\nlet fileInputRef: HTMLInputElement;\r\n\r\n/**\r\n * 设置文件选择框引用对象\r\n *\r\n * @param el 引用对象\r\n */\r\nconst setFileInputRef = (el: Element | ComponentPublicInstance | null) => {\r\n  if (el) fileInputRef = el as HTMLInputElement;\r\n};\r\n\r\n/**\r\n * 选择文件\r\n *\r\n * @param e\r\n */\r\nconst chosingFile = (e: MouseEvent) => {\r\n  if (upload.limited()) return;\r\n\r\n  //隐式触发文件选择事件\r\n  fileInputRef?.click();\r\n};\r\n\r\n/**\r\n * 已选择文件\r\n *\r\n * @param {any} e\r\n */\r\nconst choseFile = (e: Event) => {\r\n  if (fileInputRef && fileInputRef.files)\r\n    for (let i = 0; i < fileInputRef.files.length; i++) {\r\n      upload.append(fileInputRef.files[i]);\r\n    }\r\n\r\n  //清空\r\n  if (fileInputRef) fileInputRef.value = \"\";\r\n};\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Piece: File Input Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>","/**\r\n * 文件类型\r\n *\r\n * @author LCTR\r\n * @date 2022-09-21\r\n */\r\nexport enum FileType {\r\n    电子文档 = '电子文档',\r\n    电子表格 = '电子表格',\r\n    文本文件 = '文本文件',\r\n    图片 = '图片',\r\n    音频 = '音频',\r\n    视频 = '视频',\r\n    压缩包 = '压缩包',\r\n    未知 = '未知',\r\n    外链资源 = '外链资源'\r\n}","<template>\r\n  <div\r\n    :class=\"renderData.container.style()\"\r\n    :style=\"renderData.container.styleVar()\"\r\n    :title=\"renderData.container.info()\"\r\n    v-on:mouseenter=\"mouseEnter\"\r\n    v-on:mouseleave=\"mouseLeave\"\r\n    v-on:mousedown=\"mouseDown\"\r\n    v-on:mouseup=\"mouseUp\"\r\n    :ref=\"setContainerRef\"\r\n  >\r\n    <div v-if=\"!props.selectedFile.canceled\" class=\"item-body\">\r\n      <div class=\"item-image\">\r\n        <img\r\n          :src=\"props.selectedFile.thumbnail\"\r\n          loading=\"lazy\"\r\n          :alt=\"props.selectedFile.fullname()\"\r\n        />\r\n      </div>\r\n\r\n      <span class=\"item-tools\" v-if=\"renderData.tools.show()\">\r\n        <span\r\n          class=\"upload-icon icon-rename\"\r\n          title=\"重命名\"\r\n          v-on:click=\"rename()\"\r\n          v-if=\"renderData.rename.enable() && !upload.getSettings().readonly\"\r\n        ></span>\r\n        <span\r\n          class=\"upload-icon icon-view\"\r\n          title=\"查看\"\r\n          v-if=\"renderData.view.enable()\"\r\n          v-on:click=\"view()\"\r\n        ></span>\r\n        <span\r\n          class=\"upload-icon icon-download\"\r\n          title=\"保存\"\r\n          v-if=\"renderData.save.enable()\"\r\n          v-on:click=\"save()\"\r\n        ></span>\r\n        <span\r\n          class=\"upload-icon icon-remove\"\r\n          title=\"删除\"\r\n          v-on:click=\"remove()\"\r\n          v-if=\"!upload.getSettings().readonly\"\r\n        ></span>\r\n      </span>\r\n\r\n      <slot\r\n        :selectedFile=\"props.selectedFile\"\r\n        :rename=\"renderData.rename\"\r\n        :funs=\"{\r\n          setRenameInputRef: setRenameInputRef,\r\n          renameKeydown: renameKeydown,\r\n          renameDone: renameDone,\r\n        }\"\r\n        :loading=\"renderData.loading\"\r\n      ></slot>\r\n\r\n      <div v-if=\"props.selectedFile.paused\" class=\"item-sub sub-paused\">\r\n        暂停\r\n      </div>\r\n      <div\r\n        v-if=\"props.selectedFile.done && !upload.getSettings().readonly\"\r\n        class=\"item-sub sub-done\"\r\n      >\r\n        完成\r\n      </div>\r\n      <div v-if=\"props.selectedFile.error\" class=\"item-sub sub-error\">错误</div>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport {\r\n  ComponentPublicInstance,\r\n  getCurrentInstance,\r\n  inject,\r\n  reactive,\r\n} from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\nimport SelectedFile from \"../Model/SelectedFile\";\r\nimport { FileType } from \"../Model/FileType\";\r\n\r\n// 获取vue实例\r\nconst { proxy } = getCurrentInstance() as any;\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 鼠标悬浮\r\n   */\r\n  hover: false,\r\n\r\n  /**\r\n   * 容器\r\n   */\r\n  container: {\r\n    /**\r\n     * 样式\r\n     */\r\n    style: (): string =>\r\n      `item-container ${\r\n        props.selectedFile.done && !upload.getSettings().readonly\r\n          ? \" item-done\"\r\n          : \"\"\r\n      } ${props.selectedFile.error ? \" item-error\" : \"\"} ${\r\n        renderData.hover &&\r\n        !renderData.rename.active &&\r\n        !props.selectedFile.checking &&\r\n        !props.selectedFile.uploading &&\r\n        !props.readyDrag &&\r\n        !props.startDrag\r\n          ? \" item-hover\"\r\n          : \"\"\r\n      } ${props.selectedFile.checking ? \" item-checking\" : \"\"} ${\r\n        props.selectedFile.uploading ? \" item-uploading\" : \"\"\r\n      } ${props.selectedFile.canceled ? \" item-canceled\" : \"\"} ${\r\n        props.selectedFile.paused ? \" item-paused\" : \"\"\r\n      } ${props.readyDrag ? \" item-ready-drag\" : \"\"} ${\r\n        props.dragging ? \" item-dragging\" : \"\"\r\n      } ${props.dragover ? \" item-drag-over\" : \"\"}`,\r\n    /**\r\n     * 容器样式中的变量\r\n     */\r\n    styleVar: (): Record<string, string> => {\r\n      return {\r\n        \"--statusCheckingColor\": upload\r\n          .getSettings()\r\n          .statusCheckingColor.toString(),\r\n        \"--statusUploadingColor\": upload\r\n          .getSettings()\r\n          .statusUploadingColor.toString(),\r\n        \"--statusPausedColor\": upload\r\n          .getSettings()\r\n          .statusPausedColor.toString(),\r\n        \"--statusPausedSubColor\": upload\r\n          .getSettings()\r\n          .statusPausedSubColor.toString(),\r\n        \"--statusDoneColor\": upload.getSettings().statusDoneColor.toString(),\r\n        \"--statusDoneSubColor\": upload\r\n          .getSettings()\r\n          .statusDoneSubColor.toString(),\r\n        \"--statusErrorColor\": upload.getSettings().statusErrorColor.toString(),\r\n        \"--statusErrorSubColor\": upload\r\n          .getSettings()\r\n          .statusErrorSubColor.toString(),\r\n\r\n        \"--dragPreparationTime\": `${(\r\n          upload.getSettings().dragPreparationTime / 1000\r\n        ).toFixed(2)}s`,\r\n        \"--dragChangePositionTime\": `${(\r\n          upload.getSettings().dragChangePositionTime / 1000\r\n        ).toFixed(2)}s`,\r\n        \"--dragReadyColor\": upload.getSettings().dragReadyColor.toString(),\r\n        \"--dragMovingColor\": upload.getSettings().dragMovingColor.toString(),\r\n        \"--dragOverColor\": upload.getSettings().dragOverColor.toString(),\r\n      };\r\n    },\r\n\r\n    /**\r\n     * 信息\r\n     */\r\n    info: () =>\r\n      `${props.selectedFile.done ? \"上传成功\" : \"\"} ${\r\n        props.selectedFile.error ? props.selectedFile.errorMessage : \"\"\r\n      } ${props.selectedFile.paused ? \"已暂停\" : \"\"}`,\r\n  },\r\n\r\n  /**\r\n   * 加载层\r\n   */\r\n  loading: {\r\n    /**\r\n     * 显示/隐藏\r\n     */\r\n    show: () =>\r\n      !renderData.rename.active &&\r\n      (props.selectedFile.checking || props.selectedFile.uploading),\r\n\r\n    /**\r\n     * 信息\r\n     */\r\n    info: () =>\r\n      `${\r\n        props.selectedFile.checking\r\n          ? \"扫描中...\" + props.selectedFile.percent + \"%\"\r\n          : \"\"\r\n      } ${\r\n        props.selectedFile.uploading\r\n          ? \"上传中...\" + props.selectedFile.percent + \"%\"\r\n          : \"\"\r\n      }`,\r\n  },\r\n\r\n  /**\r\n   * 工具栏\r\n   */\r\n  tools: {\r\n    /**\r\n     * 显示/隐藏\r\n     */\r\n    show: () =>\r\n      renderData.hover &&\r\n      props.dragging === false &&\r\n      !renderData.rename.active &&\r\n      !props.selectedFile.checking &&\r\n      !props.selectedFile.uploading,\r\n  },\r\n\r\n  /**\r\n   * 重命名\r\n   */\r\n  rename: {\r\n    /**\r\n     * 启用/禁用\r\n     */\r\n    enable: () => !props.selectedFile.uploading,\r\n\r\n    /**\r\n     * 正在重命名\r\n     */\r\n    active: false,\r\n\r\n    /**\r\n     * 值\r\n     */\r\n    value: \"\",\r\n  },\r\n\r\n  /**\r\n   * 浏览\r\n   */\r\n  view: {\r\n    /**\r\n     * 启用/禁用\r\n     */\r\n    enable: () => {\r\n      switch (props.selectedFile.fileType) {\r\n        case FileType.图片:\r\n        case FileType.音频:\r\n          return props.selectedFile.extensionLower !== \".flac\";\r\n        case FileType.视频:\r\n          return true;\r\n        case FileType.文本文件:\r\n          return true;\r\n        case FileType.电子文档:\r\n          return (\r\n            props.selectedFile.extensionLower === \".pdf\" ||\r\n            props.selectedFile.extensionLower === \".doc\" ||\r\n            props.selectedFile.extensionLower === \".docx\"\r\n          );\r\n        default:\r\n          return false;\r\n      }\r\n    },\r\n  },\r\n\r\n  /**\r\n   * 保存\r\n   */\r\n  save: {\r\n    /**\r\n     * 启用/禁用\r\n     */\r\n    enable: () => {\r\n      return true;\r\n    },\r\n  },\r\n});\r\n\r\n/**\r\n * 组件属性\r\n */\r\nconst props = defineProps<{\r\n  key: number;\r\n\r\n  /**\r\n   * 选择的文件\r\n   */\r\n  selectedFile: SelectedFile;\r\n\r\n  /**\r\n   * 准备拖动\r\n   */\r\n  readyDrag?: boolean;\r\n\r\n  /**\r\n   * 拖动操作已开始\r\n   */\r\n  startDrag?: boolean;\r\n\r\n  /**\r\n   * 正在拖动\r\n   */\r\n  dragging?: boolean;\r\n\r\n  /**\r\n   * 和拖动元素重叠\r\n   */\r\n  dragover?: boolean;\r\n}>();\r\n\r\n/**\r\n * 组件自定义事件\r\n */\r\nconst emit = defineEmits<{\r\n  /**\r\n   * 设置容器引用对象\r\n   *\r\n   * @param e\r\n   * @param el 容器引用对象\r\n   */\r\n  (e: \"setContainerRef\", el: HTMLDivElement): void;\r\n\r\n  /**\r\n   * 按下鼠标的事件\r\n   *\r\n   * @param e\r\n   * @param event\r\n   */\r\n  (e: \"mouseDown\", event: MouseEvent): void;\r\n\r\n  /**\r\n   * 松开鼠标的事件\r\n   *\r\n   * @param e\r\n   * @param event\r\n   */\r\n  (e: \"mouseUp\", event: MouseEvent): void;\r\n\r\n  /**\r\n   * 鼠标进入的事件\r\n   *\r\n   * @param e\r\n   * @param event\r\n   */\r\n  (e: \"mouseEnter\", event: MouseEvent): boolean;\r\n\r\n  /**\r\n   * 鼠标离开的事件\r\n   *\r\n   * @param e\r\n   * @param event\r\n   */\r\n  (e: \"mouseLeave\", event: MouseEvent): void;\r\n}>();\r\n\r\n/**\r\n * 文件重命名输入框\r\n */\r\nlet renameInputRef: HTMLInputElement;\r\n\r\n/**\r\n * 设置文件选择框引用对象\r\n *\r\n * @param el 引用对象\r\n */\r\nconst setContainerRef = (el: Element | ComponentPublicInstance | null) => {\r\n  el ? emit(\"setContainerRef\", el as HTMLDivElement) : !1;\r\n};\r\n\r\n/**\r\n * 设置重命名输入框引用对象\r\n *\r\n * @param el 引用对象\r\n */\r\nconst setRenameInputRef = (el: Element | ComponentPublicInstance | null) => {\r\n  if (el) renameInputRef = el as HTMLInputElement;\r\n};\r\n\r\n/**\r\n * 鼠标进入的事件\r\n *\r\n * @param event\r\n */\r\nconst mouseEnter = (event: MouseEvent) => {\r\n  if (props.readyDrag || props.startDrag) {\r\n    emit(\"mouseEnter\", event);\r\n    renderData.hover = false;\r\n  } else renderData.hover = true;\r\n};\r\n\r\n/**\r\n * 鼠标离开的事件\r\n *\r\n * @param event\r\n */\r\nconst mouseLeave = (event: MouseEvent) => {\r\n  if (props.readyDrag || props.startDrag) emit(\"mouseLeave\", event);\r\n\r\n  renderData.hover = false;\r\n};\r\n\r\n/**\r\n * 按下鼠标的事件\r\n *\r\n * @param event\r\n */\r\nconst mouseDown = (event: MouseEvent) => {\r\n  emit(\"mouseDown\", event);\r\n};\r\n\r\n/**\r\n * 松开鼠标的事件\r\n *\r\n * @param event\r\n */\r\nconst mouseUp = (event: MouseEvent) => {\r\n  emit(\"mouseUp\", event);\r\n};\r\n\r\n/**\r\n * 重命名\r\n */\r\nconst rename = () => {\r\n  renderData.rename.active = true;\r\n\r\n  proxy.$nextTick(() => {\r\n    if (renameInputRef) renameInputRef.focus();\r\n  });\r\n};\r\n\r\n/**\r\n * 确认重命名\r\n *\r\n * @param {any} event\r\n */\r\nconst renameKeydown = (event: KeyboardEvent) => {\r\n  if (event.key == \"Enter\") {\r\n    renameDone();\r\n  }\r\n};\r\n\r\n/**\r\n * 重命名结束\r\n */\r\nconst renameDone = () => {\r\n  upload\r\n    .rename(props.selectedFile.token!, renderData.rename.value)\r\n    .then(() => {\r\n      renderData.rename.active = false;\r\n    })\r\n    .catch(() => {\r\n      renderData.rename.active = false;\r\n    });\r\n};\r\n\r\n/**\r\n * 查看\r\n */\r\nconst view = () => {\r\n  const file = upload.getRawFile(props.selectedFile);\r\n  const bodyStyle =\r\n    \"margin:0px;text-align: center;display: flex;flex-direction: row;justify-content: center;align-items: center\";\r\n\r\n  switch (props.selectedFile.fileType) {\r\n    case FileType.图片:\r\n      let winImage = window.open();\r\n      winImage?.document.write(\r\n        `<head><title>${props.selectedFile.fullname()}</title></head><body style=\"${bodyStyle};background-color: black;\"><img style=\"max-width: 100%;max-height: 100%;\" src=\"${\r\n          file.objectURL\r\n        }\" alt=\"${props.selectedFile.fullname()}\"></body>`\r\n      );\r\n      break;\r\n    case FileType.音频:\r\n      if (props.selectedFile.extensionLower === \".flac\") return;\r\n\r\n      let winAudio = window.open();\r\n      winAudio?.document.write(\r\n        `<head><title>${props.selectedFile.fullname()}</title></head><body style=\"${bodyStyle};background-color: black;\"><audio style=\"max-width: 100%;max-height: 100%;\" src=\"${\r\n          file.objectURL\r\n        }\" controls=\"controls\">抱歉, 暂不支持</audio></body>`\r\n      );\r\n      break;\r\n    case FileType.视频:\r\n      let winVideo = window.open();\r\n      winVideo?.document.write(\r\n        `<head><title>${props.selectedFile.fullname()}</title></head><body style=\"${bodyStyle};background-color: black;\"><video style=\"max-width: 100%;max-height: 100%;\" src=\"${\r\n          file.objectURL\r\n        }\" controls=\"controls\">抱歉, 暂不支持</video></body>`\r\n      );\r\n      break;\r\n    default:\r\n      let win = window.open();\r\n      win?.document.write(\r\n        `<head><title>${props.selectedFile.fullname()}</title></head><body style=\"${bodyStyle};\"><object style=\"max-width: 100%;max-height: 100%;\" data=\"${\r\n          file.objectURL\r\n        }\" type=\"${\r\n          props.selectedFile.extensionLower === \".txt\"\r\n            ? \"text/plain\"\r\n            : props.selectedFile.extensionLower === \".pdf\"\r\n            ? \"application/pdf\"\r\n            : \"application/octet-stream\"\r\n        }\" width=\"100%\" height=\"100%\"><iframe src=\"${\r\n          file.objectURL\r\n        }\" width=\"100%\" height=\"100%\" ></iframe></object></body>`\r\n      );\r\n      break;\r\n  }\r\n};\r\n\r\n/**\r\n * 保存\r\n */\r\nconst save = () => {\r\n  const file = upload.getRawFile(props.selectedFile);\r\n\r\n  const a = document.createElement(\"a\");\r\n  a.style.display = \"none\";\r\n  a.href = upload.getDownloadUrl(props.selectedFile)!;\r\n  if (file.file) a.download = props.selectedFile.fullname();\r\n  document.body.appendChild(a);\r\n  a.click();\r\n  document.body.removeChild(a);\r\n};\r\n\r\n/**\r\n * 删除\r\n */\r\nconst remove = () => {\r\n  upload.remove(props.selectedFile.token!);\r\n};\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Piece: Selected File Info Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n","<template>\r\n  <div class=\"upload-container independent\">\r\n    <slot name=\"uploadContainer\"></slot>\r\n\r\n    <div class=\"upload-list\">\r\n      <slot name=\"listContainer\"></slot>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { inject } from \"vue-demi\";\r\nimport NaiveUpload from \"../../Core/NaiveUpload\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Layout: Card Index Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n\r\n<style scoped lang=\"scss\" type=\"text/scss\">\r\n@import \"index.vue3.scss\";\r\n</style>","<template>\r\n  <div class=\"upload-container independent\">\r\n    <slot name=\"uploadContainer\"></slot>\r\n\r\n    <div class=\"upload-list\">\r\n      <slot name=\"listContainer\"></slot>\r\n    </div>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { inject } from \"vue-demi\";\r\nimport NaiveUpload from \"../../Core/NaiveUpload\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Layout: Detailedly Index Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n\r\n<style scoped lang=\"scss\" type=\"text/scss\">\r\n@import \"index.vue3.scss\";\r\n</style>","<template>\r\n  <div v-if=\"!renderData.loading\">\r\n    <component :is=\"renderData.currentThemeIndex\">\r\n      <template #uploadContainer>\r\n        <slot name=\"uploadContainer\"></slot>\r\n      </template>\r\n\r\n      <template #listContainer>\r\n        <slot name=\"listContainer\"></slot>\r\n      </template>\r\n    </component>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { inject, reactive, ShallowRef, shallowRef } from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\nimport Card from \"../Layout/Card/index.vue3.vue\";\r\nimport Detailedly from \"../Layout/Detailedly/index.vue3.vue\";\r\nimport { Layout } from \"../Model/Layout\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 加载状态\r\n   */\r\n  loading: true,\r\n\r\n  /**\r\n   * 当前的主题组件\r\n   */\r\n  currentThemeIndex: null as ShallowRef<any> | null,\r\n});\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  const changLayout = (layout?: Layout) => {\r\n    renderData.loading = true;\r\n    switch (layout) {\r\n      case Layout.卡片:\r\n        renderData.currentThemeIndex = shallowRef(Card);\r\n        break;\r\n      case Layout.清单:\r\n        renderData.currentThemeIndex = shallowRef(Detailedly);\r\n        break;\r\n    }\r\n    renderData.loading = false;\r\n\r\n    upload.getSettings().debug\r\n      ? console.debug(\"Layout: Index Component(vue3) 已变更\")\r\n      : !1;\r\n  };\r\n\r\n  //注册布局变更事件\r\n  upload.registerLayoutChanged(changLayout);\r\n\r\n  //初始化布局\r\n  changLayout(upload.getSettings().layout);\r\n\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Layout: Index Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n","<template>\r\n  <div class=\"item-info\">\r\n    <span\r\n      class=\"single-text-omitted item-name\"\r\n      :title=\"\r\n        props.slotProps.selectedFile.fileType +\r\n        '\\r\\n' +\r\n        props.slotProps.selectedFile.size +\r\n        '\\r\\n' +\r\n        props.slotProps.selectedFile.fullname()\r\n      \"\r\n      v-html=\"props.slotProps.selectedFile.fullname()\"\r\n      v-if=\"!props.slotProps.rename.active\"\r\n    ></span>\r\n    <input\r\n      class=\"item-rename-input\"\r\n      type=\"text\"\r\n      v-if=\"props.slotProps.rename.active\"\r\n      v-model=\"props.slotProps.rename.value\"\r\n      :ref=\"props.slotProps.funs.setRenameInputRef\"\r\n      v-on:keydown=\"props.slotProps.funs.renameKeydown($event)\"\r\n      v-on:blur=\"props.slotProps.funs.renameDone()\"\r\n    />\r\n  </div>\r\n\r\n  <div\r\n    class=\"item-loading\"\r\n    v-if=\"props.slotProps.loading.show()\"\r\n    :style=\"renderData.lodingStyle()\"\r\n    :title=\"props.slotProps.loading.info()\"\r\n  ></div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ComponentPublicInstance, inject, reactive } from \"vue-demi\";\r\nimport NaiveUpload from \"../../Core/NaiveUpload\";\r\nimport SelectedFile from \"../../Model/SelectedFile\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 选择的文件排序值映射表\r\n   */\r\n  selectedFileSortMap: upload.getSelectedFileSortMap() as Map<number, number>,\r\n\r\n  /**\r\n   *加载层样式\r\n   */\r\n  lodingStyle: (): string => {\r\n    return `${\r\n      props.slotProps.selectedFile.checking\r\n        ? upload.getGradientStyle(\r\n            \"conic\",\r\n            \"rgba(255, 236, 201, 0.5)\",\r\n            props.slotProps.selectedFile.percent,\r\n            props.slotProps.selectedFile.virtualPercent\r\n          )\r\n        : \"\"\r\n    } ${\r\n      props.slotProps.selectedFile.uploading\r\n        ? upload.getGradientStyle(\r\n            \"conic\",\r\n            \"rgba(144, 206, 255, 0.5)\",\r\n            props.slotProps.selectedFile.percent,\r\n            props.slotProps.selectedFile.virtualPercent\r\n          )\r\n        : \"\"\r\n    } ${\r\n      props.slotProps.selectedFile.paused\r\n        ? upload.getGradientStyle(\r\n            \"conic\",\r\n            \"rgba(158, 158, 158, 0.5)\",\r\n            props.slotProps.selectedFile.percent,\r\n            props.slotProps.selectedFile.virtualPercent\r\n          )\r\n        : \"\"\r\n    }`;\r\n  },\r\n});\r\n\r\n/**\r\n * 组件属性\r\n */\r\nconst props = defineProps<{\r\n  /**\r\n   * 插槽属性\r\n   */\r\n  slotProps: {\r\n    /**\r\n     * 选择的文件\r\n     */\r\n    selectedFile: SelectedFile;\r\n\r\n    /**\r\n     * 重命名\r\n     */\r\n    rename: {\r\n      /**\r\n       * 启用/禁用\r\n       */\r\n      enable: () => boolean;\r\n\r\n      /**\r\n       * 正在重命名\r\n       */\r\n      active: boolean;\r\n\r\n      /**\r\n       * 值\r\n       */\r\n      value: string;\r\n    };\r\n\r\n    /**\r\n     * 方法\r\n     */\r\n    funs: {\r\n      /**\r\n       * 设置重命名输入框引用对象\r\n       *\r\n       * @param el 引用对象\r\n       */\r\n      setRenameInputRef: (el: Element | ComponentPublicInstance | null) => void;\r\n\r\n      /**\r\n       * 确认重命名\r\n       *\r\n       * @param {any} event\r\n       */\r\n      renameKeydown: (event: KeyboardEvent) => void;\r\n\r\n      /**\r\n       * 重命名结束\r\n       */\r\n      renameDone: () => void;\r\n    };\r\n\r\n    /**\r\n     * 加载层\r\n     */\r\n    loading: {\r\n      /**\r\n       * 显示/隐藏\r\n       */\r\n      show: () => boolean;\r\n\r\n      /**\r\n       * 信息\r\n       */\r\n      info: () => string;\r\n    };\r\n  };\r\n}>();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Layout: Card Info Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>","<template>\r\n  <div class=\"item-info\">\r\n    <span class=\"single-text-omitted item-name\">\r\n      名称：<span\r\n        :title=\"props.slotProps.selectedFile.fullname()\"\r\n        v-html=\"props.slotProps.selectedFile.fullname()\"\r\n        v-if=\"!props.slotProps.rename.active\"\r\n      ></span>\r\n      <input\r\n        class=\"item-rename-input\"\r\n        type=\"text\"\r\n        v-if=\"props.slotProps.rename.value\"\r\n        v-model=\"props.slotProps.selectedFile.newName\"\r\n        :ref=\"props.slotProps.funs.setRenameInputRef\"\r\n        v-on:keydown=\"props.slotProps.funs.renameKeydown($event)\"\r\n        v-on:blur=\"props.slotProps.funs.renameDone()\"\r\n      />\r\n    </span>\r\n\r\n    <span class=\"single-text-omitted item-size\">\r\n      大小：<span\r\n        :title=\"props.slotProps.selectedFile.size\"\r\n        v-html=\"props.slotProps.selectedFile.size\"\r\n      ></span>\r\n    </span>\r\n\r\n    <span class=\"single-text-omitted item-filetype\">\r\n      类型：<span\r\n        :title=\"props.slotProps.selectedFile.fileType\"\r\n        v-html=\"props.slotProps.selectedFile.fileType\"\r\n      ></span>\r\n    </span>\r\n  </div>\r\n\r\n  <div\r\n    class=\"item-loading\"\r\n    v-if=\"props.slotProps.loading.show()\"\r\n    :style=\"renderData.lodingStyle()\"\r\n    :title=\"props.slotProps.loading.info()\"\r\n  ></div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { ComponentPublicInstance, inject, reactive } from \"vue-demi\";\r\nimport NaiveUpload from \"../../Core/NaiveUpload\";\r\nimport SelectedFile from \"../../Model/SelectedFile\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 选择的文件排序值映射表\r\n   */\r\n  selectedFileSortMap: upload.getSelectedFileSortMap() as Map<number, number>,\r\n\r\n  /**\r\n   *加载层样式\r\n   */\r\n  lodingStyle: (): string => {\r\n    return `${\r\n      props.slotProps.selectedFile.checking\r\n        ? upload.getGradientStyle(\r\n            \"linear\",\r\n            \"rgba(255, 236, 201, 0.5)\",\r\n            props.slotProps.selectedFile.percent,\r\n            props.slotProps.selectedFile.virtualPercent\r\n          )\r\n        : \"\"\r\n    } ${\r\n      props.slotProps.selectedFile.uploading\r\n        ? upload.getGradientStyle(\r\n            \"linear\",\r\n            \"rgba(144, 206, 255, 0.5)\",\r\n            props.slotProps.selectedFile.percent,\r\n            props.slotProps.selectedFile.virtualPercent\r\n          )\r\n        : \"\"\r\n    } ${\r\n      props.slotProps.selectedFile.paused\r\n        ? upload.getGradientStyle(\r\n            \"linear\",\r\n            \"rgba(158, 158, 158, 0.5)\",\r\n            props.slotProps.selectedFile.percent,\r\n            props.slotProps.selectedFile.virtualPercent\r\n          )\r\n        : \"\"\r\n    }`;\r\n  },\r\n});\r\n\r\n/**\r\n * 组件属性\r\n */\r\nconst props = defineProps<{\r\n  /**\r\n   * 插槽属性\r\n   */\r\n  slotProps: {\r\n    /**\r\n     * 选择的文件\r\n     */\r\n    selectedFile: SelectedFile;\r\n\r\n    /**\r\n     * 重命名\r\n     */\r\n    rename: {\r\n      /**\r\n       * 启用/禁用\r\n       */\r\n      enable: () => boolean;\r\n\r\n      /**\r\n       * 正在重命名\r\n       */\r\n      active: boolean;\r\n\r\n      /**\r\n       * 值\r\n       */\r\n      value: string;\r\n    };\r\n\r\n    /**\r\n     * 方法\r\n     */\r\n    funs: {\r\n      /**\r\n       * 设置重命名输入框引用对象\r\n       *\r\n       * @param el 引用对象\r\n       */\r\n      setRenameInputRef: (el: Element | ComponentPublicInstance | null) => void;\r\n\r\n      /**\r\n       * 确认重命名\r\n       *\r\n       * @param {any} event\r\n       */\r\n      renameKeydown: (event: KeyboardEvent) => void;\r\n\r\n      /**\r\n       * 重命名结束\r\n       */\r\n      renameDone: () => void;\r\n    };\r\n\r\n    /**\r\n     * 加载层\r\n     */\r\n    loading: {\r\n      /**\r\n       * 显示/隐藏\r\n       */\r\n      show: () => boolean;\r\n\r\n      /**\r\n       * 信息\r\n       */\r\n      info: () => string;\r\n    };\r\n  };\r\n}>();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Layout: Detailedly Info Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>","<template>\r\n  <div v-if=\"!renderData.loading\">\r\n    <component :is=\"renderData.currentThemeInfo\" :slotProps=\"props.slotProps\">\r\n    </component>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport {\r\n  ComponentPublicInstance,\r\n  inject,\r\n  reactive,\r\n  ShallowRef,\r\n  shallowRef,\r\n} from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\nimport Card from \"../Layout/Card/info.vue3.vue\";\r\nimport Detailedly from \"../Layout/Detailedly/info.vue3.vue\";\r\nimport SelectedFile from \"../Model/SelectedFile\";\r\nimport { Layout } from \"../Model/Layout\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 加载状态\r\n   */\r\n  loading: true,\r\n\r\n  /**\r\n   * 当前的主题组件\r\n   */\r\n  currentThemeInfo: null as ShallowRef<any> | null,\r\n});\r\n\r\n/**\r\n * 组件属性\r\n */\r\nconst props = defineProps<{\r\n  /**\r\n   * 插槽属性\r\n   */\r\n  slotProps: {\r\n    /**\r\n     * 选择的文件\r\n     */\r\n    selectedFile: SelectedFile;\r\n\r\n    /**\r\n     * 重命名\r\n     */\r\n    rename: {\r\n      /**\r\n       * 启用/禁用\r\n       */\r\n      enable: () => boolean;\r\n\r\n      /**\r\n       * 正在重命名\r\n       */\r\n      active: boolean;\r\n\r\n      /**\r\n       * 值\r\n       */\r\n      value: string;\r\n    };\r\n\r\n    /**\r\n     * 方法\r\n     */\r\n    funs: {\r\n      /**\r\n       * 设置重命名输入框引用对象\r\n       *\r\n       * @param el 引用对象\r\n       */\r\n      setRenameInputRef: (el: Element | ComponentPublicInstance | null) => void;\r\n\r\n      /**\r\n       * 确认重命名\r\n       *\r\n       * @param {any} event\r\n       */\r\n      renameKeydown: (event: KeyboardEvent) => void;\r\n\r\n      /**\r\n       * 重命名结束\r\n       */\r\n      renameDone: () => void;\r\n    };\r\n\r\n    /**\r\n     * 加载层\r\n     */\r\n    loading: {\r\n      /**\r\n       * 显示/隐藏\r\n       */\r\n      show: () => boolean;\r\n\r\n      /**\r\n       * 信息\r\n       */\r\n      info: () => string;\r\n    };\r\n  };\r\n}>();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  const changLayout = (layout?: Layout) => {\r\n    renderData.loading = true;\r\n    switch (upload.getSettings().layout) {\r\n      case Layout.卡片:\r\n        renderData.currentThemeInfo = shallowRef(Card);\r\n        break;\r\n      case Layout.清单:\r\n        renderData.currentThemeInfo = shallowRef(Detailedly);\r\n        break;\r\n    }\r\n    renderData.loading = false;\r\n\r\n    upload.getSettings().debug\r\n      ? console.debug(\"Layout: Info Component(vue3) 已变更\")\r\n      : !1;\r\n  };\r\n\r\n  //注册布局变更事件（index中已进行监听）\r\n  // upload.registerLayoutChanged(changLayout);\r\n\r\n  //初始化布局\r\n  changLayout();\r\n\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Layout: Info Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n","<template>\r\n  <layout-index>\r\n    <template v-if=\"!upload.getSettings().readonly\" v-slot:uploadContainer>\r\n      <file-input\r\n        v-if=\"!upload.anyFile()\"\r\n        class=\"upload-box-container single\"\r\n        :title=\"upload.getConfig().explain\"\r\n      >\r\n        <p class=\"upload-icon icon-select-file\"></p>\r\n      </file-input>\r\n    </template>\r\n\r\n    <template v-slot:listContainer>\r\n      <selected-file-info\r\n        v-for=\"sortKey in upload.getSelectedFileSortMap().size\"\r\n        :key=\"sortKey\"\r\n        :selectedFile=\"upload.getSelectedFile(sortKey)\"\r\n        v-slot=\"slotProps\"\r\n      >\r\n        <layout-info\r\n          class=\"item-info-container\"\r\n          :slotProps=\"slotProps\"\r\n        ></layout-info>\r\n      </selected-file-info>\r\n    </template>\r\n  </layout-index>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { inject } from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\nimport FileInput from \"../Piece/FileInput.vue3.vue\";\r\nimport SelectedFileInfo from \"../Piece/SelectedFileInfo.vue3.vue\";\r\nimport LayoutIndex from \"../Layout/index.vue3.vue\";\r\nimport LayoutInfo from \"../Layout/info.vue3.vue\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Piece: Single Upload Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n","<template>\r\n  <div\r\n    :class=\"upload.getSelectCLass()\"\r\n    v-on:drop=\"dropFile\"\r\n    v-on:dragover=\"allowDrop\"\r\n    :title=\"upload.getSelectFileAlarmInfo()\"\r\n  >\r\n    <file-input>\r\n      <slot></slot>\r\n    </file-input>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { inject } from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\nimport FileInput from \"../Piece/FileInput.vue3.vue\";\r\n\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 允许拖动/阻止冒泡事件\r\n *\r\n * @param {any} e\r\n */\r\nconst allowDrop = (e: DragEvent) => {\r\n  e.preventDefault();\r\n};\r\n\r\n/**\r\n * 拖动文件\r\n *\r\n * @param {any} e\r\n */\r\nconst dropFile = (e: DragEvent) => {\r\n  e.preventDefault();\r\n  if (e.dataTransfer)\r\n    for (let i = 0; i < e.dataTransfer.files.length; i++) {\r\n      upload.append(e.dataTransfer.files[i]);\r\n    }\r\n};\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Piece: Drop File Input Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n","/**\r\n * 拖动！\r\n *\r\n * @author LCTR\r\n * @date 2022-10-14\r\n */\r\nexport default class DraggingHelper {\r\n    /**\r\n     * 容器元素\r\n     */\r\n    private containerEl?: HTMLElement;\r\n\r\n    /**\r\n     * 目标元素\r\n     */\r\n    private el?: HTMLElement;\r\n\r\n    /**\r\n     * 拖动标识\r\n     */\r\n    private flag: boolean = false;\r\n\r\n    /**\r\n     * X轴原坐标\r\n     */\r\n    private x: number = 0;\r\n\r\n    /**\r\n     * Y轴原坐标\r\n     */\r\n    private y: number = 0;\r\n\r\n    /**\r\n     * 当前X轴坐标\r\n     */\r\n    private currentX: number = 0;\r\n\r\n    /**\r\n     * 当前Y轴坐标\r\n     */\r\n    private currentY: number = 0;\r\n\r\n    /**\r\n     * 当前X轴偏移量\r\n     */\r\n    private offsetX: number = 0;\r\n\r\n    /**\r\n     * 当前Y轴偏移量\r\n     */\r\n    private offsetY: number = 0;\r\n\r\n    /**\r\n     * X轴滚动量\r\n     */\r\n    private scrollX: number = 0;\r\n\r\n    /**\r\n     * Y轴滚动量\r\n     */\r\n    private scrollY: number = 0;\r\n\r\n    /**\r\n     * X轴当前位移距离\r\n     */\r\n    private transX: number = 0;\r\n\r\n    /**\r\n     * Y轴当前位移距离\r\n     */\r\n    private transY: number = 0;\r\n\r\n    /**\r\n     * X轴上次位移距离\r\n     */\r\n    private lastTransX: number = 0;\r\n\r\n    /**\r\n     * Y轴上次位移时间\r\n     */\r\n    private lastTransY: number = 0;\r\n\r\n    /**\r\n     * 堆叠顺序\r\n     */\r\n    private zIndex: string = '';\r\n\r\n    /**\r\n     * 位置\r\n     */\r\n    private position: string = '';\r\n\r\n    /**\r\n     * 位移\r\n     */\r\n    private transform: string = '';\r\n\r\n    /**\r\n     * 更改位移属性的最小位移量\r\n     */\r\n    private transLate: number = 1;\r\n\r\n    /**\r\n     * 判断是否回归原位时的误差值\r\n     */\r\n    private readonly restoreError: number[] = [20, 10];\r\n\r\n    /**\r\n     * 移动鼠标\r\n     *\r\n     * @param event 事件\r\n     */\r\n    private mouseMove?: (event: MouseEvent) => void;\r\n\r\n    /**\r\n     * 移动鼠标\r\n     *\r\n     * @param event 事件\r\n     */\r\n    private scroll?: (event: Event) => void;\r\n\r\n    /**\r\n     * 改变位置\r\n     *\r\n     * @param clientX\r\n     * @param clientY\r\n     */\r\n    private moving(this: DraggingHelper, clientX: number, clientY: number) {\r\n        this.currentX = clientX;\r\n        this.currentY = clientY;\r\n\r\n        if (this.checkRestore()) {\r\n            this.transX = 0;\r\n            this.transY = 0;\r\n\r\n            this.el!.style.transform = this.transform;\r\n        } else {\r\n            this.transX = this.currentX - this.x + this.scrollX + this.offsetX;\r\n            this.transY = this.currentY - this.y + this.scrollY + this.offsetY;\r\n\r\n            if (Math.abs(this.transX - this.lastTransX) >= this.transLate\r\n                || Math.abs(this.transY - this.lastTransY) >= this.transLate) {\r\n                this.el!.style.transform = `translate(${this.transX}px, ${this.transY}px)`;\r\n            }\r\n        }\r\n\r\n        this.lastTransX = this.transX;\r\n        this.lastTransY = this.transY;\r\n    }\r\n\r\n    /**\r\n     * 检查是否拖动到了原本的位置\r\n     */\r\n    private checkRestore(): boolean {\r\n        return DraggingHelper.equalError(this.x, this.currentX, this.restoreError[0])\r\n            && DraggingHelper.equalError(this.y, this.currentY, this.restoreError[1]);\r\n    }\r\n\r\n    /**\r\n     * 是否相等\r\n     *\r\n     * @param current 当前值\r\n     * @param target 要比较的值\r\n     * @param error 误差范围（如error=5，则为±5）\r\n     */\r\n    private static equalError(current: number, target: number, error: number): boolean {\r\n        return target + error >= current && target - error <= current;\r\n    }\r\n\r\n    /**\r\n     * 获取实例\r\n     *\r\n     * @param containerEl 容器元素\r\n     * @param el 目标元素\r\n     */\r\n    public static getInstance(containerEl: HTMLElement, el: HTMLElement): DraggingHelper {\r\n        let helper = new DraggingHelper();\r\n        helper.el = el;\r\n        helper.containerEl = containerEl;\r\n        return helper;\r\n    }\r\n\r\n    /**\r\n     * 开始拖动\r\n     *\r\n     * @param clientX X轴坐标\r\n     * @param clientY Y轴坐标\r\n     * @param handlerMoving 监听移动 event 鼠标移动事件对象\r\n     */\r\n    public start(this: DraggingHelper, clientX: number, clientY: number, handlerMoving?: ((event: MouseEvent) => void)) {\r\n        this.flag = true;\r\n        //开始拖动时记录原始属性\r\n        this.currentX = clientX;\r\n        this.currentY = clientY;\r\n        this.save();\r\n\r\n        // this.el.style.zIndex = '999';\r\n        // this.el.style.position = 'relative';\r\n\r\n        let handlerMovingFlag = false;\r\n\r\n        this.mouseMove = (event: MouseEvent) => {\r\n            if (!this.flag || handlerMovingFlag)\r\n                return;\r\n\r\n            event.preventDefault();\r\n\r\n            handlerMovingFlag = true;\r\n\r\n            this.moving(event.clientX, event.clientY);\r\n\r\n            handlerMoving && handlerMoving(event);\r\n\r\n            handlerMovingFlag = false;\r\n        };\r\n\r\n        this.containerEl!.addEventListener('mousemove', this.mouseMove);\r\n\r\n        this.scroll = (event: Event) => {\r\n            this.scrollX = this.containerEl!.scrollLeft;\r\n            this.scrollY = this.containerEl!.scrollTop;\r\n        };\r\n\r\n        this.containerEl!.addEventListener('scroll', this.scroll);\r\n    }\r\n\r\n    /**\r\n     * 设置偏移量\r\n     *\r\n     * @param x X轴偏移量\r\n     * @param y Y轴偏移量\r\n     */\r\n    public offset(this: DraggingHelper, x: number, y: number) {\r\n        this.offsetX = x;\r\n        this.offsetY = y;\r\n    }\r\n\r\n    /**\r\n     * 保存当前的位置\r\n     */\r\n    public save(this: DraggingHelper) {\r\n        this.x = this.currentX;\r\n        this.y = this.currentY;\r\n        this.zIndex = this.el!.style.zIndex;\r\n        this.position = this.el!.style.position;\r\n        this.transform = this.el!.style.transform;\r\n    }\r\n\r\n    /**\r\n     * 复原\r\n     */\r\n    public restore(this: DraggingHelper) {\r\n        this.flag = false;\r\n        this.x = this.currentX;\r\n        this.y = this.currentY;\r\n        this.el!.style.zIndex = this.zIndex;\r\n        this.el!.style.position = this.position;\r\n        this.el!.style.transform = this.transform;\r\n    };\r\n\r\n    /**\r\n     * 结束拖动\r\n     *\r\n     * @param restore 是否还原\r\n     */\r\n    public end(this: DraggingHelper, restore: boolean) {\r\n        if (restore)\r\n            this.restore();\r\n        this.containerEl!.removeEventListener('mousemove', this.mouseMove!);\r\n        this.containerEl!.removeEventListener('scroll', this.scroll!);\r\n    }\r\n}","<template>\r\n  <layout-index>\r\n    <template v-if=\"!upload.getSettings().readonly\" v-slot:uploadContainer>\r\n      <drop-file-input class=\"upload-box-container\">\r\n        <p class=\"upload-icon icon-inbox\"></p>\r\n        <p class=\"upload-text\" v-html=\"upload.getConfig().explain\"></p>\r\n        <p class=\"upload-hint\" v-html=\"upload.getSettings().tip\"></p>\r\n        <div class=\"upload-error-list pretty-scrollbar\">\r\n          <p\r\n            class=\"error-info\"\r\n            v-for=\"(error, index) in renderData.errors\"\r\n            :key=\"index\"\r\n          >\r\n            {{ error }}\r\n          </p>\r\n        </div>\r\n      </drop-file-input>\r\n    </template>\r\n\r\n    <template v-slot:listContainer>\r\n      <div\r\n        class=\"scroll-container pretty-scrollbar\"\r\n        :ref=\"setListRef\"\r\n        v-on:mouseenter=\"renderData.scrollLock = true\"\r\n        v-on:mouseleave=\"renderData.scrollLock = false\"\r\n      >\r\n        <TransitionGroup name=\"fade\">\r\n          <selected-file-info\r\n            v-for=\"sortKey in upload.getSelectedFileSortMap().size\"\r\n            :key=\"upload.getSelectedFileSortMap().get(sortKey) ?? -1\"\r\n            :selectedFile=\"upload.getSelectedFile(sortKey)\"\r\n            :readyDrag=\"renderData.readyDraggingSortKey === sortKey\"\r\n            :startDrag=\"renderData.currentDraggingSortKey !== null\"\r\n            :dragging=\"renderData.currentDraggingSortKey === sortKey\"\r\n            :dragover=\"\r\n              renderData.lastDraggingSortKey === sortKey &&\r\n              renderData.currentDraggingSortKey !== sortKey\r\n            \"\r\n            @setContainerRef=\"(el) => setContainerRef(sortKey, el)\"\r\n            @mouseDown=\"(event) => containerMouseDown(sortKey, event)\"\r\n            @mouseUp=\"(event) => containerMouseUp(sortKey, event)\"\r\n            @mouseEnter=\"(event) => containerMouseEnter(sortKey, event)\"\r\n            @mouseLeave=\"(event) => containerMouseLeave(sortKey, event)\"\r\n            v-slot=\"slotProps\"\r\n          >\r\n            <layout-info\r\n              class=\"item-info-container\"\r\n              :slotProps=\"slotProps\"\r\n            ></layout-info>\r\n          </selected-file-info>\r\n        </TransitionGroup>\r\n      </div>\r\n    </template>\r\n  </layout-index>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport {\r\n  reactive,\r\n  inject,\r\n  getCurrentInstance,\r\n  ComponentPublicInstance,\r\n} from \"vue-demi\";\r\nimport NaiveUpload from \"../Core/NaiveUpload\";\r\nimport DropFileInput from \"../Piece/DropFileInput.vue3.vue\";\r\nimport SelectedFileInfo from \"../Piece/SelectedFileInfo.vue3.vue\";\r\nimport LayoutIndex from \"../Layout/index.vue3.vue\";\r\nimport LayoutInfo from \"../Layout/info.vue3.vue\";\r\nimport SelectedFile from \"../Model/SelectedFile\";\r\nimport DraggingHelper from \"../Extention/DraggingHelper\";\r\n\r\n// 获取vue实例\r\nconst { proxy } = getCurrentInstance() as any;\r\n//注入文件上传工具实例\r\nconst upload = (inject(\"upload\") as () => NaiveUpload)();\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 锁定滚动条\r\n   */\r\n  scrollLock: false,\r\n\r\n  /**\r\n   * 准备拖动的索引\r\n   */\r\n  readyDraggingSortKey: null as number | null,\r\n\r\n  /**\r\n   * 当前正在拖动中的索引\r\n   */\r\n  currentDraggingSortKey: null as number | null,\r\n\r\n  /**\r\n   * 上一个接收拖动对象的索引\r\n   */\r\n  lastDraggingSortKey: null as number | null,\r\n\r\n  /**\r\n   * 异常信息\r\n   */\r\n  errors: [] as string[],\r\n});\r\n\r\n/**\r\n * 列表容器引用对象\r\n */\r\nlet listContainerRef: HTMLDivElement;\r\n\r\n/**\r\n * 容器引用对象集合\r\n */\r\nlet containerRefMap = new Map<number, HTMLDivElement>();\r\n\r\n/**\r\n * 拖动排序功能\r\n */\r\nlet drag4sort = {\r\n  /**\r\n   * 延时开启拖动功能的计时器\r\n   */\r\n  startTick: null as NodeJS.Timeout | null,\r\n\r\n  /**\r\n   * 延时更改排序的计时器\r\n   */\r\n  changeTick: null as NodeJS.Timeout | null,\r\n\r\n  /**\r\n   * 当前拖动对象\r\n   */\r\n  draggingHelper: null as DraggingHelper | null,\r\n\r\n  /**\r\n   * 延时开启拖动功能\r\n   *\r\n   * @param sortKey\r\n   * @param clientX\r\n   * @param clientY\r\n   */\r\n  ready2start: (sortKey: number, clientX: number, clientY: number) => {\r\n    if (!upload.getSettings().enableDrag) {\r\n      upload.getSettings().debug\r\n        ? console.debug(\r\n            \"Piece: Multiple Upload Component(vue3) 未启用拖动排序功能\"\r\n          )\r\n        : !1;\r\n      return;\r\n    }\r\n    if (upload.getSelectedFileList(false).length <= 1) return;\r\n\r\n    drag4sort.startTick = setTimeout(() => {\r\n      //准备拖动\r\n      renderData.readyDraggingSortKey = sortKey;\r\n\r\n      drag4sort.startTick = setTimeout(() => {\r\n        if (!listContainerRef) return;\r\n        renderData.readyDraggingSortKey = null;\r\n        //开始拖动\r\n        renderData.currentDraggingSortKey = sortKey;\r\n        drag4sort.draggingHelper = DraggingHelper.getInstance(\r\n          listContainerRef,\r\n          containerRefMap.get(renderData.currentDraggingSortKey)!\r\n        );\r\n        drag4sort.draggingHelper.start(clientX, clientY);\r\n\r\n        //将拖动元素置于其他元素的底层\r\n        containerRefMap.forEach((item: HTMLDivElement, key: number) => {\r\n          if (key !== renderData.currentDraggingSortKey)\r\n            item.style.zIndex = \"1\";\r\n        });\r\n      }, upload.getSettings().dragPreparationTime);\r\n    }, 500);\r\n  },\r\n\r\n  /**\r\n   * 延时重新排序\r\n   *\r\n   * @param sortKey\r\n   */\r\n  ready2change: (sortKey: number) => {\r\n    renderData.lastDraggingSortKey = sortKey;\r\n\r\n    if (renderData.currentDraggingSortKey === renderData.lastDraggingSortKey)\r\n      return;\r\n\r\n    //TODO 自动将列表容器滚动至当前正在拖动的文件之处（注：此功能会和延迟重新排序功能冲突，暂不启用）\r\n    // if (containerRefMap.get(renderData.lastDraggingSortKey).offsetTop + containerRefMap.get(renderData.lastDraggingSortKey).clientHeight + 20 > listContainerRef.clientHeight) {\r\n    // listContainerRef.scrollTop = containerRefMap.get(renderData.lastDraggingSortKey).offsetTop + containerRefMap.get(renderData.lastDraggingSortKey).clientHeight * 2 + 20 - listContainerRef.clientHeight;//containerRefMap.get(renderData.lastDraggingSortKey).offsetTop + containerRefMap.get(renderData.lastDraggingSortKey).clientHeight + 20 > listContainerRef.clientHeight ? containerRefMap.get(renderData.lastDraggingSortKey).offsetTop - listContainerRef.offsetTop - 20 : 0;\r\n    // drag4sort.draggingHelper.offset(0, listContainerRef.scrollTop);\r\n    // console.debug('scrollTop', listContainerRef.scrollTop);\r\n    // }\r\n\r\n    drag4sort.changeTick = setTimeout(() => {\r\n      //重新排序\r\n      upload.changeSort(\r\n        renderData.currentDraggingSortKey!,\r\n        renderData.lastDraggingSortKey!\r\n      );\r\n      drag4sort.end();\r\n    }, upload.getSettings().dragChangePositionTime);\r\n  },\r\n\r\n  /**\r\n   * 取消重新排序\r\n   */\r\n  cancelChange: () => {\r\n    drag4sort.changeTick && clearTimeout(drag4sort.changeTick);\r\n    renderData.lastDraggingSortKey = null;\r\n  },\r\n\r\n  /**\r\n   * 结束拖动并复原容器位置\r\n   */\r\n  end: () => {\r\n    drag4sort.startTick && clearTimeout(drag4sort.startTick);\r\n    drag4sort.changeTick && clearTimeout(drag4sort.changeTick);\r\n    renderData.readyDraggingSortKey = null;\r\n\r\n    if (!drag4sort.draggingHelper) return;\r\n\r\n    //结束拖动并复原位置\r\n    drag4sort.draggingHelper.end(true);\r\n    drag4sort.draggingHelper = null;\r\n\r\n    //恢复其他元素的zIndex\r\n    containerRefMap.forEach((item: HTMLDivElement, key: number) => {\r\n      if (key !== renderData.currentDraggingSortKey) item.style.zIndex = \"\";\r\n    });\r\n\r\n    renderData.lastDraggingSortKey = null;\r\n    renderData.currentDraggingSortKey = null;\r\n  },\r\n};\r\n\r\n/**\r\n * 设置列表引用对象\r\n *\r\n * @param el 引用对象\r\n */\r\nconst setListRef = (el: Element | ComponentPublicInstance | null) => {\r\n  el ? (listContainerRef = el as HTMLDivElement) : !1;\r\n};\r\n\r\n/**\r\n * 设置文件选择框引用对象\r\n *\r\n * @param sortKey\r\n * @param el 引用对象\r\n */\r\nconst setContainerRef = (sortKey: number, el: HTMLDivElement) => {\r\n  if (!listContainerRef) return;\r\n\r\n  containerRefMap.set(sortKey, el);\r\n};\r\n\r\n/**\r\n * 按下鼠标的事件\r\n *\r\n * @param sortKey\r\n * @param event\r\n */\r\nconst containerMouseDown = (sortKey: number, event: MouseEvent) => {\r\n  drag4sort.ready2start(sortKey, event.clientX, event.clientY);\r\n};\r\n\r\n/**\r\n * 松开鼠标的事件\r\n *\r\n * @param sortKey\r\n * @param event\r\n */\r\nconst containerMouseUp = (sortKey: number, event: MouseEvent) => {\r\n  drag4sort.end();\r\n};\r\n\r\n/**\r\n * 鼠标进入的事件\r\n *\r\n * @param sortKey\r\n * @param event\r\n */\r\nconst containerMouseEnter = (sortKey: number, event: MouseEvent) => {\r\n  drag4sort.ready2change(sortKey);\r\n};\r\n\r\n/**\r\n * 鼠标离开的事件\r\n *\r\n * @param sortKey\r\n * @param event\r\n */\r\nconst containerMouseLeave = (sortKey: number, event: MouseEvent) => {\r\n  drag4sort.cancelChange();\r\n};\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  /**\r\n   * 滚动列表，将正在校验和正在上传的文件显示在当前的可视区域中\r\n   *\r\n   * @param files 当前的文件集合（已排序）\r\n   */\r\n  const scroll = (files: SelectedFile[]) => {\r\n    if (renderData.scrollLock || files.length == 0) return;\r\n\r\n    //等待页面元素已渲染完成\r\n    proxy.$nextTick(() => {\r\n      let container: HTMLDivElement | null = null;\r\n\r\n      let findChecking = false;\r\n\r\n      for (let i = 0; i < files.length; i++) {\r\n        let file = files[i];\r\n\r\n        if (!findChecking && file.checking) {\r\n          findChecking = true;\r\n          container = containerRefMap.get(i)!;\r\n        }\r\n\r\n        if (file.uploading) {\r\n          container = containerRefMap.get(i)!;\r\n          break;\r\n        }\r\n      }\r\n\r\n      if (!container) return;\r\n\r\n      //列表容器滚动至当前正在处理中的文件之处\r\n      if (listContainerRef)\r\n        listContainerRef.scrollTop =\r\n          container.offsetTop - listContainerRef.offsetTop - 20;\r\n    });\r\n  };\r\n\r\n  //注册选择的文件集合变更事件\r\n  upload.registerSelectedFileListChanged(scroll);\r\n\r\n  const alertError = (error: Error) => {\r\n    renderData.errors.push(error.message);\r\n    setTimeout(() => {\r\n      renderData.errors.shift();\r\n    }, 5000);\r\n  };\r\n\r\n  //注册提示异常的事件\r\n  if (upload.getSettings().alertErrorInfo)\r\n    upload.registerAlertError(alertError);\r\n\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Piece: Multiple Upload Component(vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n","/**\r\n * 异常信息\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class UploadError extends Error {\r\n    /**\r\n     *\r\n     * @param message 异常消息\r\n     * @param innerError 内部异常\r\n     */\r\n    constructor(message: string, innerError?: Error) {\r\n        super(message);\r\n        this.innerError = innerError;\r\n    }\r\n\r\n    private static consoleWriteWithIndex(e: Error, index: number) {\r\n        console.error(`第${index}层错误`, e);\r\n        e instanceof UploadError && e.innerError && UploadError.consoleWriteWithIndex(e.innerError, ++index);\r\n    }\r\n\r\n    /**\r\n     * 内部异常\r\n     */\r\n    public innerError?: Error;\r\n\r\n    /**\r\n     * 控制台输出\r\n     *\r\n     * @param e\r\n     */\r\n    public static consoleWrite(e: Error) {\r\n        UploadError.consoleWriteWithIndex(e, 1);\r\n    }\r\n}","﻿import ChunkFile from \"../Model/ChunkFile\";\r\nimport { IUserFileInfo } from \"../Model/IUserFileInfo\";\r\n\r\n/**\r\n * 源文件\r\n *\r\n * @author LCTR\r\n * @date 2022-06-24\r\n */\r\nexport default class RawFile {\r\n    /**\r\n     *\r\n     * @param file 源文件\r\n     */\r\n    constructor(file: File | null) {\r\n        if (file == null)\r\n            return;\r\n\r\n        this.file = file;\r\n        this.size = file.size;\r\n        this.objectURL = URL.createObjectURL(file);\r\n    }\r\n\r\n    /**\r\n     * 文件\r\n     */\r\n    file?: File;\r\n\r\n    /***\r\n     * 字节数\r\n     */\r\n    size: number = 0;\r\n\r\n    /**\r\n     * 文件校验时文件数据读取到的位置\r\n     */\r\n    checkPosition: number = 0;\r\n\r\n    /**\r\n     * 文件上传时文件数据读取到的位置\r\n     */\r\n    uploadPosition: number = 0;\r\n\r\n    /**\r\n     * 资源地址\r\n     */\r\n    objectURL?: string;\r\n\r\n    /**\r\n     * 哈希值\r\n     */\r\n    md5: string | null = null;\r\n\r\n    /**\r\n     * 文件拓展名\r\n     */\r\n    extension?: string;\r\n\r\n    /**\r\n     * 文件重命名\r\n     */\r\n    name?: string;\r\n\r\n    /**\r\n     * 需要切片处理\r\n     *\r\n     * @默认值 false\r\n     */\r\n    needSection: boolean = false;\r\n\r\n    /**\r\n     * 分片规格\r\n     */\r\n    specs?: number;\r\n\r\n    /**\r\n     * 分片文件上传标识\r\n     */\r\n    key?: string;\r\n\r\n    /**\r\n     * 切片集合\r\n     */\r\n    chunks: ChunkFile[] = [];\r\n\r\n    /**\r\n     * 切片索引队列\r\n     */\r\n    chunkIndexQueue: number[] = [];\r\n\r\n    /**\r\n     * 用户文件信息\r\n     */\r\n    userFileInfo?: IUserFileInfo;\r\n\r\n    /**\r\n     * 文件上传配置编码\r\n     */\r\n    configCode?: string;\r\n\r\n    /**\r\n     * 文件令牌\r\n     */\r\n    token?: string;\r\n\r\n    /**\r\n     * 回显的数据\r\n     */\r\n    echo: boolean = false;\r\n}","import { FileType } from \"../Model/FileType\";\r\n\r\n\r\n/**\r\n * 文件类型帮助类\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class FileTypeHelper {\r\n    /**\r\n     * 获取文件类型\r\n     *\r\n     * @param extension 文件扩展名(示例：.jpg)\r\n     * @return 文件类型\r\n     */\r\n    public static getByExtension(extension: string): FileType {\r\n        switch (extension) {\r\n            case \".webp\":\r\n            case \".jpg\":\r\n            case \".png\":\r\n            case \".ioc\":\r\n            case \".bmp\":\r\n            case \".gif\":\r\n            case \".tif\":\r\n            case \".tga\":\r\n            case \".jpeg\":\r\n                return FileType.图片;\r\n            case \".mp2\":\r\n            case \".ac3\":\r\n            case \".mp3\":\r\n            case \".m4a\":\r\n            case \".m4r\":\r\n            case \".mmf\":\r\n            case \".ogg\":\r\n            case \".amr\":\r\n            case \".aac\":\r\n            case \".vqf\":\r\n            case \".wma\":\r\n            case \".ape\":\r\n            case \".wav\":\r\n            case \".flac\":\r\n            case \".cda\":\r\n            case \".dts\":\r\n                return FileType.音频;\r\n            case \".swf\":\r\n            case \".3gp\":\r\n            case \".3g2\":\r\n            case \".mp4\":\r\n            case \".mpeg\":\r\n            case \".mpg\":\r\n            case \".dat\":\r\n            case \".mov\":\r\n            case \".vob\":\r\n            case \".qt\":\r\n            case \".rm\":\r\n            case \".asf\":\r\n            case \".avi\":\r\n            case \".navi\":\r\n            case \".divx\":\r\n            case \".flv\":\r\n            case \".f4v\":\r\n            case \".qsv\":\r\n            case \".wmv\":\r\n            case \".mkv\":\r\n            case \".rmvb\":\r\n            case \".webm\":\r\n                return FileType.视频;\r\n            case \".xls\":\r\n            case \".xlsx\":\r\n            case \".csv\":\r\n                return FileType.电子表格;\r\n            case \".pdf\":\r\n            case \".doc\":\r\n            case \".docx\":\r\n                return FileType.电子文档;\r\n            case \".txt\":\r\n            case \".js\":\r\n            case \".css\":\r\n            case \".cs\":\r\n            case \".html\":\r\n            case \".vue\":\r\n            case \".ts\":\r\n            case \".xml\":\r\n            case \".json\":\r\n                return FileType.文本文件;\r\n            case \".zip\":\r\n            case \".rar\":\r\n            case \".7z\":\r\n                return FileType.压缩包;\r\n            default:\r\n                return FileType.未知;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取文件类型\r\n     *\r\n     * @param mimetype 内容类型\r\n     * @return 文件类型\r\n     */\r\n    public static getByMIME(mimetype: string): FileType {\r\n        const mimetypeLower = mimetype.toLocaleLowerCase();\r\n        if (mimetypeLower.indexOf('image/', 0) != -1)\r\n            return FileType.图片;\r\n        else if (mimetypeLower.indexOf('audio/', 0) != -1)\r\n            return FileType.音频;\r\n        else if (mimetypeLower.indexOf('video/', 0) != -1)\r\n            return FileType.视频;\r\n        else if (mimetypeLower.indexOf('text/', 0) != -1)\r\n            return FileType.文本文件;\r\n        else {\r\n            switch (mimetype) {\r\n                case \"application/ogg\":\r\n                    return FileType.音频;\r\n                case \"application/mp4\":\r\n                    return FileType.视频;\r\n                case \"application/vnd.ms-excel\":\r\n                case \"vnd.openxmlformats-officedocument.spreadsheetml.sheet\":\r\n                    return FileType.电子表格;\r\n                case \"application/pdf\":\r\n                case \"application/msword\":\r\n                case \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\":\r\n                    return FileType.电子文档;\r\n                case \"application/json\":\r\n                case \"application/javascript\":\r\n                    return FileType.文本文件;\r\n                case \"application/x-tar\":\r\n                case \"application/zip\":\r\n                case \"application/x-compressed\":\r\n                case \"application/x-zip-compressed\":\r\n                    return FileType.压缩包;\r\n                default:\r\n                    return FileType.未知;\r\n            }\r\n        }\r\n    }\r\n}","﻿import { FileType } from \"../Model/FileType\";\r\nimport FileTypeHelper from \"../Extention/FileTypeHelper\";\r\n\r\n/**\r\n * 选定的文件\r\n *\r\n * @author LCTR\r\n * @date 2022-06-24\r\n */\r\nexport default class SelectedFile {\r\n    /**\r\n     *\r\n     * @param file 文件\r\n     */\r\n    constructor(file: File) {\r\n        const pointIndex = file.name.lastIndexOf('.');\r\n        this.name = file.name.substring(0, pointIndex);\r\n        this.extension = file.name.substring(pointIndex);\r\n        this.extensionLower = this.extension?.toLowerCase();\r\n        this.fileType = file.type ? FileTypeHelper.getByMIME(file.type) : FileTypeHelper.getByExtension(this.extension);\r\n    }\r\n\r\n    /**\r\n     * 源文件索引\r\n     */\r\n    rawIndex?: number;\r\n\r\n    /**\r\n     * 文件名\r\n     */\r\n    name: string;\r\n\r\n    /**\r\n     * 重新命名的文件名\r\n     */\r\n    newName?: string;\r\n\r\n    /**\r\n     * 拓展名\r\n     * 包括前缀(.)\r\n     */\r\n    extension: string;\r\n\r\n    /**\r\n     * 完整文件名\r\n     */\r\n    fullname = (): string => `${this.name ?? ''}${this.extension ?? ''}`;\r\n\r\n    /**\r\n     * 拓展名全小写\r\n     * 包括前缀(.)\r\n     */\r\n    extensionLower: string;\r\n\r\n    /**\r\n     * 文件大小\r\n     */\r\n    size: string = '';\r\n\r\n    /**\r\n     * 文件类型\r\n     *\r\n     * @默认值 FileType.未知\r\n     */\r\n    fileType: FileType = FileType.未知;\r\n\r\n    /**\r\n     * 缩略图\r\n     *\r\n     * @默认值 /filetypes/empty.png\r\n     */\r\n    thumbnail: string = '/filetypes/empty.png';\r\n\r\n    /**\r\n     * 类名\r\n     */\r\n    class: string[] = [];\r\n\r\n    /**\r\n     * 正在校验MD5\r\n     */\r\n    checking: boolean = false;\r\n\r\n    /**\r\n     * 已校验MD5\r\n     */\r\n    checked: boolean = false;\r\n\r\n    /**\r\n     * 正在上传\r\n     */\r\n    uploading: boolean = false;\r\n\r\n    /**\r\n     * 已上传\r\n     */\r\n    uploaded: boolean = false;\r\n\r\n    /**\r\n     * 处理完毕\r\n     */\r\n    done: boolean = false;\r\n\r\n    /**\r\n     * 重试次数\r\n     */\r\n    reTry: number = 0;\r\n\r\n    /**\r\n     * 发生异常\r\n     */\r\n    error: boolean = false;\r\n\r\n    /**\r\n     * 异常信息\r\n     */\r\n    errorMessage?: string;\r\n\r\n    /**\r\n     * 真实进度（百分比）\r\n     */\r\n    percent: number = 0;\r\n\r\n    /**\r\n     * 虚拟进度（百分比）\r\n     */\r\n    virtualPercent: number = 0;\r\n\r\n    /**\r\n     * 暂停前的真实进度（百分比）\r\n     */\r\n    percentBeforPaused: number = 0;\r\n\r\n    /**\r\n     * 暂停前的虚拟进度（百分比）\r\n     */\r\n    virtualPercentBeforPaused: number = 0;\r\n\r\n    /**\r\n     * 已暂停\r\n     */\r\n    paused: boolean = false;\r\n\r\n    /**\r\n     * 已取消\r\n     */\r\n    canceled: boolean = false;\r\n\r\n    /**\r\n     * 文件令牌\r\n     */\r\n    token?: string;\r\n\r\n    /**\r\n     * 回显的数据\r\n     */\r\n    echo: boolean = false;\r\n}","/**\r\n * 唯一标识\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class SimpleGuid {\r\n    private static s4(): string {\r\n        return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1);\r\n    }\r\n\r\n    /**\r\n     * 生成新的唯一标识\r\n     */\r\n    public static new(): string {\r\n        return `${SimpleGuid.s4()}${SimpleGuid.s4()}-${SimpleGuid.s4()}-${SimpleGuid.s4()}-${SimpleGuid.s4()}-${SimpleGuid.s4()}${SimpleGuid.s4()}${SimpleGuid.s4()}`;\r\n    }\r\n}","/**\r\n * 文件大小帮助类\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class FileSizeHelper {\r\n    /**\r\n     * 格式名\r\n     */\r\n    private static readonly formats: string[] = [\r\n        \"KB\",\r\n        \"MB\",\r\n        \"GB\",\r\n        \"TB\",\r\n        \"PB\",\r\n        \"EB\",\r\n        \"ZB\",\r\n        \"YB\"];\r\n\r\n    /**\r\n     * 获取文件大小描述信息\r\n     *\r\n     * @param length 文件字节数\r\n     * @param unit      单位\r\n     * @param precision 精度\r\n     * @return 文件大小描述信息\r\n     */\r\n    public static getSize(length: number,\r\n        unit: number = 1024,\r\n        precision: number = 2): string {\r\n        if (length <= 0) return \"0 KB\";\r\n\r\n        for (let i: number = 0; i < FileSizeHelper.formats.length; i++) {\r\n            let value = length / Math.pow(unit, i + 1);\r\n\r\n            if (value < unit)\r\n                return `${value.toFixed(precision)} ${FileSizeHelper.formats[i]}`;\r\n        }\r\n\r\n        return `${(length / Math.pow(unit, FileSizeHelper.formats.length)).toFixed(precision)} ${FileSizeHelper.formats[FileSizeHelper.formats.length - 1]}`;\r\n    }\r\n}","﻿/**\r\n * 切片文件\r\n *\r\n * @author LCTR\r\n * @date 2022-06-24\r\n */\r\nexport default class ChunkFile {\r\n    /**\r\n     *\r\n     * @param index 索引\r\n     * @param blob 二进制数据\r\n     */\r\n    constructor(index: number, blob: Blob) {\r\n        this.index = index;\r\n        this.blob = blob;\r\n        this.size = blob.size;\r\n    }\r\n\r\n    /***\r\n     * 索引\r\n     */\r\n    index: number;\r\n\r\n    /***\r\n     * 二进制数据\r\n     */\r\n    blob: Blob;\r\n\r\n    /***\r\n     * 字节数\r\n     */\r\n    size: number;\r\n\r\n    /**\r\n     * 文件校验时文件数据读取到的位置\r\n     */\r\n    checkPosition: number = 0;\r\n\r\n    /***\r\n     * 哈希值\r\n     */\r\n    md5: string | null = null;\r\n\r\n    /**\r\n     * 强制上传\r\n     */\r\n    forced: boolean = false;\r\n\r\n    /**\r\n     * 正在校验MD5\r\n     */\r\n    checking: boolean = false;\r\n\r\n    /**\r\n     * 已校验MD5\r\n     */\r\n    checked: boolean = false;\r\n\r\n    /**\r\n     * 正在上传\r\n     */\r\n    uploading: boolean = false;\r\n\r\n    /**\r\n     * 已上传\r\n     */\r\n    uploaded: boolean = false;\r\n\r\n    /***\r\n     * 处理完毕\r\n     */\r\n    done: boolean = false;\r\n\r\n    /**\r\n     * 发生异常\r\n     */\r\n    error: boolean = false;\r\n\r\n    /**\r\n     * 异常信息\r\n     */\r\n    errorMessage?: string;\r\n}","/**\r\n * 哈希值计算WebWorker脚本\r\n *\r\n * @author LCTR\r\n * @date 2022-09-30\r\n */\r\nconst worker = () => {\r\n    \"use strict\";\r\n    let add32 = function (a, b) {\r\n        return a + b & 4294967295\r\n    }, hex_chr = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"a\", \"b\", \"c\", \"d\", \"e\", \"f\"];\r\n\r\n    function cmn(q, a, b, x, s, t) {\r\n        a = add32(add32(a, q), add32(x, t));\r\n        return add32(a << s | a >>> 32 - s, b)\r\n    }\r\n\r\n    function md5cycle(x, k) {\r\n        let a = x[0], b = x[1], c = x[2], d = x[3];\r\n        a += (b & c | ~b & d) + k[0] - 680876936 | 0;\r\n        a = (a << 7 | a >>> 25) + b | 0;\r\n        d += (a & b | ~a & c) + k[1] - 389564586 | 0;\r\n        d = (d << 12 | d >>> 20) + a | 0;\r\n        c += (d & a | ~d & b) + k[2] + 606105819 | 0;\r\n        c = (c << 17 | c >>> 15) + d | 0;\r\n        b += (c & d | ~c & a) + k[3] - 1044525330 | 0;\r\n        b = (b << 22 | b >>> 10) + c | 0;\r\n        a += (b & c | ~b & d) + k[4] - 176418897 | 0;\r\n        a = (a << 7 | a >>> 25) + b | 0;\r\n        d += (a & b | ~a & c) + k[5] + 1200080426 | 0;\r\n        d = (d << 12 | d >>> 20) + a | 0;\r\n        c += (d & a | ~d & b) + k[6] - 1473231341 | 0;\r\n        c = (c << 17 | c >>> 15) + d | 0;\r\n        b += (c & d | ~c & a) + k[7] - 45705983 | 0;\r\n        b = (b << 22 | b >>> 10) + c | 0;\r\n        a += (b & c | ~b & d) + k[8] + 1770035416 | 0;\r\n        a = (a << 7 | a >>> 25) + b | 0;\r\n        d += (a & b | ~a & c) + k[9] - 1958414417 | 0;\r\n        d = (d << 12 | d >>> 20) + a | 0;\r\n        c += (d & a | ~d & b) + k[10] - 42063 | 0;\r\n        c = (c << 17 | c >>> 15) + d | 0;\r\n        b += (c & d | ~c & a) + k[11] - 1990404162 | 0;\r\n        b = (b << 22 | b >>> 10) + c | 0;\r\n        a += (b & c | ~b & d) + k[12] + 1804603682 | 0;\r\n        a = (a << 7 | a >>> 25) + b | 0;\r\n        d += (a & b | ~a & c) + k[13] - 40341101 | 0;\r\n        d = (d << 12 | d >>> 20) + a | 0;\r\n        c += (d & a | ~d & b) + k[14] - 1502002290 | 0;\r\n        c = (c << 17 | c >>> 15) + d | 0;\r\n        b += (c & d | ~c & a) + k[15] + 1236535329 | 0;\r\n        b = (b << 22 | b >>> 10) + c | 0;\r\n        a += (b & d | c & ~d) + k[1] - 165796510 | 0;\r\n        a = (a << 5 | a >>> 27) + b | 0;\r\n        d += (a & c | b & ~c) + k[6] - 1069501632 | 0;\r\n        d = (d << 9 | d >>> 23) + a | 0;\r\n        c += (d & b | a & ~b) + k[11] + 643717713 | 0;\r\n        c = (c << 14 | c >>> 18) + d | 0;\r\n        b += (c & a | d & ~a) + k[0] - 373897302 | 0;\r\n        b = (b << 20 | b >>> 12) + c | 0;\r\n        a += (b & d | c & ~d) + k[5] - 701558691 | 0;\r\n        a = (a << 5 | a >>> 27) + b | 0;\r\n        d += (a & c | b & ~c) + k[10] + 38016083 | 0;\r\n        d = (d << 9 | d >>> 23) + a | 0;\r\n        c += (d & b | a & ~b) + k[15] - 660478335 | 0;\r\n        c = (c << 14 | c >>> 18) + d | 0;\r\n        b += (c & a | d & ~a) + k[4] - 405537848 | 0;\r\n        b = (b << 20 | b >>> 12) + c | 0;\r\n        a += (b & d | c & ~d) + k[9] + 568446438 | 0;\r\n        a = (a << 5 | a >>> 27) + b | 0;\r\n        d += (a & c | b & ~c) + k[14] - 1019803690 | 0;\r\n        d = (d << 9 | d >>> 23) + a | 0;\r\n        c += (d & b | a & ~b) + k[3] - 187363961 | 0;\r\n        c = (c << 14 | c >>> 18) + d | 0;\r\n        b += (c & a | d & ~a) + k[8] + 1163531501 | 0;\r\n        b = (b << 20 | b >>> 12) + c | 0;\r\n        a += (b & d | c & ~d) + k[13] - 1444681467 | 0;\r\n        a = (a << 5 | a >>> 27) + b | 0;\r\n        d += (a & c | b & ~c) + k[2] - 51403784 | 0;\r\n        d = (d << 9 | d >>> 23) + a | 0;\r\n        c += (d & b | a & ~b) + k[7] + 1735328473 | 0;\r\n        c = (c << 14 | c >>> 18) + d | 0;\r\n        b += (c & a | d & ~a) + k[12] - 1926607734 | 0;\r\n        b = (b << 20 | b >>> 12) + c | 0;\r\n        a += (b ^ c ^ d) + k[5] - 378558 | 0;\r\n        a = (a << 4 | a >>> 28) + b | 0;\r\n        d += (a ^ b ^ c) + k[8] - 2022574463 | 0;\r\n        d = (d << 11 | d >>> 21) + a | 0;\r\n        c += (d ^ a ^ b) + k[11] + 1839030562 | 0;\r\n        c = (c << 16 | c >>> 16) + d | 0;\r\n        b += (c ^ d ^ a) + k[14] - 35309556 | 0;\r\n        b = (b << 23 | b >>> 9) + c | 0;\r\n        a += (b ^ c ^ d) + k[1] - 1530992060 | 0;\r\n        a = (a << 4 | a >>> 28) + b | 0;\r\n        d += (a ^ b ^ c) + k[4] + 1272893353 | 0;\r\n        d = (d << 11 | d >>> 21) + a | 0;\r\n        c += (d ^ a ^ b) + k[7] - 155497632 | 0;\r\n        c = (c << 16 | c >>> 16) + d | 0;\r\n        b += (c ^ d ^ a) + k[10] - 1094730640 | 0;\r\n        b = (b << 23 | b >>> 9) + c | 0;\r\n        a += (b ^ c ^ d) + k[13] + 681279174 | 0;\r\n        a = (a << 4 | a >>> 28) + b | 0;\r\n        d += (a ^ b ^ c) + k[0] - 358537222 | 0;\r\n        d = (d << 11 | d >>> 21) + a | 0;\r\n        c += (d ^ a ^ b) + k[3] - 722521979 | 0;\r\n        c = (c << 16 | c >>> 16) + d | 0;\r\n        b += (c ^ d ^ a) + k[6] + 76029189 | 0;\r\n        b = (b << 23 | b >>> 9) + c | 0;\r\n        a += (b ^ c ^ d) + k[9] - 640364487 | 0;\r\n        a = (a << 4 | a >>> 28) + b | 0;\r\n        d += (a ^ b ^ c) + k[12] - 421815835 | 0;\r\n        d = (d << 11 | d >>> 21) + a | 0;\r\n        c += (d ^ a ^ b) + k[15] + 530742520 | 0;\r\n        c = (c << 16 | c >>> 16) + d | 0;\r\n        b += (c ^ d ^ a) + k[2] - 995338651 | 0;\r\n        b = (b << 23 | b >>> 9) + c | 0;\r\n        a += (c ^ (b | ~d)) + k[0] - 198630844 | 0;\r\n        a = (a << 6 | a >>> 26) + b | 0;\r\n        d += (b ^ (a | ~c)) + k[7] + 1126891415 | 0;\r\n        d = (d << 10 | d >>> 22) + a | 0;\r\n        c += (a ^ (d | ~b)) + k[14] - 1416354905 | 0;\r\n        c = (c << 15 | c >>> 17) + d | 0;\r\n        b += (d ^ (c | ~a)) + k[5] - 57434055 | 0;\r\n        b = (b << 21 | b >>> 11) + c | 0;\r\n        a += (c ^ (b | ~d)) + k[12] + 1700485571 | 0;\r\n        a = (a << 6 | a >>> 26) + b | 0;\r\n        d += (b ^ (a | ~c)) + k[3] - 1894986606 | 0;\r\n        d = (d << 10 | d >>> 22) + a | 0;\r\n        c += (a ^ (d | ~b)) + k[10] - 1051523 | 0;\r\n        c = (c << 15 | c >>> 17) + d | 0;\r\n        b += (d ^ (c | ~a)) + k[1] - 2054922799 | 0;\r\n        b = (b << 21 | b >>> 11) + c | 0;\r\n        a += (c ^ (b | ~d)) + k[8] + 1873313359 | 0;\r\n        a = (a << 6 | a >>> 26) + b | 0;\r\n        d += (b ^ (a | ~c)) + k[15] - 30611744 | 0;\r\n        d = (d << 10 | d >>> 22) + a | 0;\r\n        c += (a ^ (d | ~b)) + k[6] - 1560198380 | 0;\r\n        c = (c << 15 | c >>> 17) + d | 0;\r\n        b += (d ^ (c | ~a)) + k[13] + 1309151649 | 0;\r\n        b = (b << 21 | b >>> 11) + c | 0;\r\n        a += (c ^ (b | ~d)) + k[4] - 145523070 | 0;\r\n        a = (a << 6 | a >>> 26) + b | 0;\r\n        d += (b ^ (a | ~c)) + k[11] - 1120210379 | 0;\r\n        d = (d << 10 | d >>> 22) + a | 0;\r\n        c += (a ^ (d | ~b)) + k[2] + 718787259 | 0;\r\n        c = (c << 15 | c >>> 17) + d | 0;\r\n        b += (d ^ (c | ~a)) + k[9] - 343485551 | 0;\r\n        b = (b << 21 | b >>> 11) + c | 0;\r\n        x[0] = a + x[0] | 0;\r\n        x[1] = b + x[1] | 0;\r\n        x[2] = c + x[2] | 0;\r\n        x[3] = d + x[3] | 0\r\n    }\r\n\r\n    function md5blk(s) {\r\n        let md5blks = [], i;\r\n        for (i = 0; i < 64; i += 4) {\r\n            md5blks[i >> 2] = s.charCodeAt(i) + (s.charCodeAt(i + 1) << 8) + (s.charCodeAt(i + 2) << 16) + (s.charCodeAt(i + 3) << 24)\r\n        }\r\n        return md5blks\r\n    }\r\n\r\n    function md5blk_array(a) {\r\n        let md5blks = [], i;\r\n        for (i = 0; i < 64; i += 4) {\r\n            md5blks[i >> 2] = a[i] + (a[i + 1] << 8) + (a[i + 2] << 16) + (a[i + 3] << 24)\r\n        }\r\n        return md5blks\r\n    }\r\n\r\n    function md51(s) {\r\n        let n = s.length, state = [1732584193, -271733879, -1732584194, 271733878], i, length, tail, tmp,\r\n            lo, hi;\r\n        for (i = 64; i <= n; i += 64) {\r\n            md5cycle(state, md5blk(s.substring(i - 64, i)))\r\n        }\r\n        s = s.substring(i - 64);\r\n        length = s.length;\r\n        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        for (i = 0; i < length; i += 1) {\r\n            tail[i >> 2] |= s.charCodeAt(i) << (i % 4 << 3)\r\n        }\r\n        tail[i >> 2] |= 128 << (i % 4 << 3);\r\n        if (i > 55) {\r\n            md5cycle(state, tail);\r\n            for (i = 0; i < 16; i += 1) {\r\n                tail[i] = 0\r\n            }\r\n        }\r\n        tmp = n * 8;\r\n        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);\r\n        lo = parseInt(tmp[2], 16);\r\n        hi = parseInt(tmp[1], 16) || 0;\r\n        tail[14] = lo;\r\n        tail[15] = hi;\r\n        md5cycle(state, tail);\r\n        return state\r\n    }\r\n\r\n    function md51_array(a) {\r\n        let n = a.length, state = [1732584193, -271733879, -1732584194, 271733878], i, length, tail, tmp,\r\n            lo, hi;\r\n        for (i = 64; i <= n; i += 64) {\r\n            md5cycle(state, md5blk_array(a.subarray(i - 64, i)))\r\n        }\r\n        a = i - 64 < n ? a.subarray(i - 64) : new Uint8Array(0);\r\n        length = a.length;\r\n        tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];\r\n        for (i = 0; i < length; i += 1) {\r\n            tail[i >> 2] |= a[i] << (i % 4 << 3)\r\n        }\r\n        tail[i >> 2] |= 128 << (i % 4 << 3);\r\n        if (i > 55) {\r\n            md5cycle(state, tail);\r\n            for (i = 0; i < 16; i += 1) {\r\n                tail[i] = 0\r\n            }\r\n        }\r\n        tmp = n * 8;\r\n        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);\r\n        lo = parseInt(tmp[2], 16);\r\n        hi = parseInt(tmp[1], 16) || 0;\r\n        tail[14] = lo;\r\n        tail[15] = hi;\r\n        md5cycle(state, tail);\r\n        return state\r\n    }\r\n\r\n    function rhex(n) {\r\n        let s = \"\", j;\r\n        for (j = 0; j < 4; j += 1) {\r\n            s += hex_chr[n >> j * 8 + 4 & 15] + hex_chr[n >> j * 8 & 15]\r\n        }\r\n        return s\r\n    }\r\n\r\n    function hex(x) {\r\n        let i;\r\n        for (i = 0; i < x.length; i += 1) {\r\n            x[i] = rhex(x[i])\r\n        }\r\n        return x.join(\"\")\r\n    }\r\n\r\n    if (hex(md51(\"hello\")) !== \"5d41402abc4b2a76b9719d911017c592\") {\r\n        add32 = function (x, y) {\r\n            let lsw = (x & 65535) + (y & 65535), msw = (x >> 16) + (y >> 16) + (lsw >> 16);\r\n            return msw << 16 | lsw & 65535\r\n        }\r\n    }\r\n    if (typeof ArrayBuffer !== \"undefined\" && !ArrayBuffer.prototype.slice) {\r\n        (function () {\r\n            function clamp(val, length) {\r\n                val = val | 0 || 0;\r\n                if (val < 0) {\r\n                    return Math.max(val + length, 0)\r\n                }\r\n                return Math.min(val, length)\r\n            }\r\n\r\n            ArrayBuffer.prototype.slice = function (from, to) {\r\n                let length = this.byteLength, begin = clamp(from, length), end = length, num, target,\r\n                    targetArray, sourceArray;\r\n                if (to !== undefined) {\r\n                    end = clamp(to, length)\r\n                }\r\n                if (begin > end) {\r\n                    return new ArrayBuffer(0)\r\n                }\r\n                num = end - begin;\r\n                target = new ArrayBuffer(num);\r\n                targetArray = new Uint8Array(target);\r\n                sourceArray = new Uint8Array(this, begin, num);\r\n                targetArray.set(sourceArray);\r\n                return target\r\n            }\r\n        })()\r\n    }\r\n\r\n    function toUtf8(str) {\r\n        if (/[\\u0080-\\uFFFF]/.test(str)) {\r\n            str = unescape(encodeURIComponent(str))\r\n        }\r\n        return str\r\n    }\r\n\r\n    function utf8Str2ArrayBuffer(str, returnUInt8Array) {\r\n        let length = str.length, buff = new ArrayBuffer(length), arr = new Uint8Array(buff), i;\r\n        for (i = 0; i < length; i += 1) {\r\n            arr[i] = str.charCodeAt(i)\r\n        }\r\n        return returnUInt8Array ? arr : buff\r\n    }\r\n\r\n    function arrayBuffer2Utf8Str(buff) {\r\n        return String.fromCharCode.apply(null, new Uint8Array(buff))\r\n    }\r\n\r\n    function concatenateArrayBuffers(first, second, returnUInt8Array) {\r\n        let result = new Uint8Array(first.byteLength + second.byteLength);\r\n        result.set(new Uint8Array(first));\r\n        result.set(new Uint8Array(second), first.byteLength);\r\n        return returnUInt8Array ? result : result.buffer\r\n    }\r\n\r\n    function hexToBinaryString(hex) {\r\n        let bytes = [], length = hex.length, x;\r\n        for (x = 0; x < length - 1; x += 2) {\r\n            bytes.push(parseInt(hex.substr(x, 2), 16))\r\n        }\r\n        return String.fromCharCode.apply(String, bytes)\r\n    }\r\n\r\n    function SparkMD5() {\r\n        this.reset()\r\n    }\r\n\r\n    SparkMD5.prototype.append = function (str) {\r\n        this.appendBinary(toUtf8(str));\r\n        return this\r\n    };\r\n    SparkMD5.prototype.appendBinary = function (contents) {\r\n        this._buff += contents;\r\n        this._length += contents.length;\r\n        let length = this._buff.length, i;\r\n        for (i = 64; i <= length; i += 64) {\r\n            md5cycle(this._hash, md5blk(this._buff.substring(i - 64, i)))\r\n        }\r\n        this._buff = this._buff.substring(i - 64);\r\n        return this\r\n    };\r\n    SparkMD5.prototype.end = function (raw) {\r\n        let buff = this._buff, length = buff.length, i,\r\n            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ret;\r\n        for (i = 0; i < length; i += 1) {\r\n            tail[i >> 2] |= buff.charCodeAt(i) << (i % 4 << 3)\r\n        }\r\n        this._finish(tail, length);\r\n        ret = hex(this._hash);\r\n        if (raw) {\r\n            ret = hexToBinaryString(ret)\r\n        }\r\n        this.reset();\r\n        return ret\r\n    };\r\n    SparkMD5.prototype.reset = function () {\r\n        this._buff = \"\";\r\n        this._length = 0;\r\n        this._hash = [1732584193, -271733879, -1732584194, 271733878];\r\n        return this\r\n    };\r\n    SparkMD5.prototype.getState = function () {\r\n        return { buff: this._buff, length: this._length, hash: this._hash.slice() }\r\n    };\r\n    SparkMD5.prototype.setState = function (state) {\r\n        this._buff = state.buff;\r\n        this._length = state.length;\r\n        this._hash = state.hash;\r\n        return this\r\n    };\r\n    SparkMD5.prototype.destroy = function () {\r\n        delete this._hash;\r\n        delete this._buff;\r\n        delete this._length\r\n    };\r\n    SparkMD5.prototype._finish = function (tail, length) {\r\n        let i = length, tmp, lo, hi;\r\n        tail[i >> 2] |= 128 << (i % 4 << 3);\r\n        if (i > 55) {\r\n            md5cycle(this._hash, tail);\r\n            for (i = 0; i < 16; i += 1) {\r\n                tail[i] = 0\r\n            }\r\n        }\r\n        tmp = this._length * 8;\r\n        tmp = tmp.toString(16).match(/(.*?)(.{0,8})$/);\r\n        lo = parseInt(tmp[2], 16);\r\n        hi = parseInt(tmp[1], 16) || 0;\r\n        tail[14] = lo;\r\n        tail[15] = hi;\r\n        md5cycle(this._hash, tail)\r\n    };\r\n    SparkMD5.hash = function (str, raw) {\r\n        return SparkMD5.hashBinary(toUtf8(str), raw)\r\n    };\r\n    SparkMD5.hashBinary = function (content, raw) {\r\n        let hash = md51(content), ret = hex(hash);\r\n        return raw ? hexToBinaryString(ret) : ret\r\n    };\r\n    SparkMD5.ArrayBuffer = (function () {\r\n        this.reset()\r\n    });\r\n    SparkMD5.ArrayBuffer.prototype.append = function (arr) {\r\n        let buff = concatenateArrayBuffers(this._buff.buffer, arr, true), length = buff.length, i;\r\n        this._length += arr.byteLength;\r\n        for (i = 64; i <= length; i += 64) {\r\n            md5cycle(this._hash, md5blk_array(buff.subarray(i - 64, i)))\r\n        }\r\n        this._buff = i - 64 < length ? new Uint8Array(buff.buffer.slice(i - 64)) : new Uint8Array(0);\r\n        return this\r\n    };\r\n    SparkMD5.ArrayBuffer.prototype.end = function (raw) {\r\n        let buff = this._buff, length = buff.length,\r\n            tail = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], i, ret;\r\n        for (i = 0; i < length; i += 1) {\r\n            tail[i >> 2] |= buff[i] << (i % 4 << 3)\r\n        }\r\n        this._finish(tail, length);\r\n        ret = hex(this._hash);\r\n        if (raw) {\r\n            ret = hexToBinaryString(ret)\r\n        }\r\n        this.reset();\r\n        return ret\r\n    };\r\n    SparkMD5.ArrayBuffer.prototype.reset = function () {\r\n        this._buff = new Uint8Array(0);\r\n        this._length = 0;\r\n        this._hash = [1732584193, -271733879, -1732584194, 271733878];\r\n        return this\r\n    };\r\n    SparkMD5.ArrayBuffer.prototype.getState = function () {\r\n        let state = SparkMD5.prototype.getState.call(this);\r\n        state.buff = arrayBuffer2Utf8Str(state.buff);\r\n        return state\r\n    };\r\n    SparkMD5.ArrayBuffer.prototype.setState = function (state) {\r\n        state.buff = utf8Str2ArrayBuffer(state.buff, true);\r\n        return SparkMD5.prototype.setState.call(this, state)\r\n    };\r\n    SparkMD5.ArrayBuffer.prototype.destroy = SparkMD5.prototype.destroy;\r\n    SparkMD5.ArrayBuffer.prototype._finish = SparkMD5.prototype._finish;\r\n    SparkMD5.ArrayBuffer.hash = function (arr, raw) {\r\n        let hash = md51_array(new Uint8Array(arr)), ret = hex(hash);\r\n        return raw ? hexToBinaryString(ret) : ret\r\n    };\r\n\r\n    const sparkMD5 = new SparkMD5.ArrayBuffer();\r\n\r\n    onmessage = (event) => {//: MessageEvent<IHashWorkerMessage<ArrayBuffer | void>>\r\n        switch (event.data.type) {\r\n            //HashWorkerMessageType.下行_附加数据\r\n            case 'DOWN_APPEND_DATA':\r\n                const data = event.data.data;//as ArrayBuffer;\r\n                sparkMD5.append(data);\r\n                break;\r\n            //HashWorkerMessageType.下行_获取结果\r\n            case 'DOWN_GET_RESULT':\r\n                postMessage(JSON.parse(JSON.stringify({\r\n                    type: 'UP_RESULT',//HashWorkerMessageType.上行_结果,\r\n                    data: sparkMD5.end(false)// as string\r\n                })));//as IHashWorkerMessage<string>\r\n                return;\r\n            //HashWorkerMessageType.下行_重置\r\n            case 'DOWN_RESET':\r\n                sparkMD5.reset();\r\n                break;\r\n            //HashWorkerMessageType.下行_关闭\r\n            case 'DOWN_CLOSE':\r\n                close();\r\n                break;\r\n        }\r\n\r\n        postMessage(JSON.parse(JSON.stringify({\r\n            type: 'UP_ACK',//HashWorkerMessageType.上行_应答\r\n        })));//as IHashWorkerMessage<void>\r\n    }\r\n};\r\nexport const HashWorkerScript = new Blob([`(${worker.toString()})()`]);","﻿/**\r\n * 文件读取帮助类\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class FileReadHelper {\r\n    constructor() {\r\n        if ('undefined' === typeof FileReader) {\r\n            throw new Error('当前浏览器不支持FileReader.');\r\n        }\r\n        this.Reader = new FileReader();\r\n    }\r\n\r\n    /**\r\n     * 读取器\r\n     */\r\n    private readonly Reader: FileReader;\r\n\r\n    /**\r\n     * 读取数据\r\n     *\r\n     * @param blob\r\n     */\r\n    public async readAsArrayBuffer(this: FileReadHelper, blob: Blob): Promise<ArrayBuffer> {\r\n        return new Promise<ArrayBuffer>((resolve, reject) => {\r\n            this.Reader.onload = event => {\r\n                const buffer = event.target!.result as ArrayBuffer;\r\n                resolve(buffer);\r\n            }\r\n\r\n            this.Reader.onerror = event => {\r\n                reject(event);\r\n            }\r\n\r\n            this.Reader.readAsArrayBuffer(blob);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 关闭\r\n     */\r\n    public close(this: FileReadHelper) {\r\n        this.Reader.abort();\r\n    }\r\n}","/**\r\n * 哈希值计算WebWorker传输信息类型\r\n *\r\n * @author LCTR\r\n * @date 2022-09-30\r\n */\r\nexport enum HashWorkerMessageType {\r\n    下行_附加数据 = 'DOWN_APPEND_DATA',\r\n    下行_获取结果 = 'DOWN_GET_RESULT',\r\n    下行_重置 = 'DOWN_RESET',\r\n    下行_关闭 = 'DOWN_CLOSE',\r\n    上行_应答 = 'UP_ACK',\r\n    上行_结果 = 'UP_RESULT'\r\n}","import SparkMD5 from \"spark-md5\";\r\nimport { HashWorkerScript } from \"./HashWorkerScript\";\r\nimport UploadError from \"../Extention/UploadError\";\r\nimport FileReadHelper from \"../Extention/FileReadHelper\";\r\nimport { IHashWorkerMessage } from \"../Model/IHashWorkerMessage\";\r\nimport { HashWorkerMessageType } from \"../Model/HashWorkerMessageType\";\r\nimport RawFile from \"../Model/RawFile\";\r\nimport { IProgress } from \"../Model/IProgress\";\r\nimport ChunkFile from \"../Model/ChunkFile\";\r\n\r\n\r\n/**\r\n * 哈希值计算帮助类\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class HashHelper {\r\n    constructor(enableWorker: boolean,\r\n        debug: boolean) {\r\n        this.debug = debug;\r\n        this.enableWorker = enableWorker;\r\n        this.workerSupported = 'undefined' !== typeof Worker;\r\n        this.enableWorker && this.debug ? console.debug(`HashHelper > WebWoeker ${(this.workerSupported ? '已启用' : '未启用（当前浏览器不支持）')}`) : !1;\r\n    }\r\n\r\n    /**\r\n     * 是否启用Worker\r\n     * 默认启用（如果浏览器支持的话）\r\n     */\r\n    private readonly enableWorker: boolean;\r\n\r\n    /**\r\n     * 浏览器是否支持Web Worker\r\n     */\r\n    private readonly workerSupported: boolean;\r\n\r\n    /**\r\n     * 调试模式\r\n     */\r\n    private readonly debug: boolean;\r\n\r\n    /**\r\n     * Spark计算单元\r\n     */\r\n    private sparkUnits: any[] = [];\r\n\r\n    /**\r\n     * 子线程计算单元\r\n     */\r\n    private workerUnits: {\r\n        worker: Worker, used: boolean\r\n    }[] = [];\r\n\r\n    /**\r\n     * 分片文件处理队列\r\n     * */\r\n    private chunkHandlerQueue: ChunkFile[] = [];\r\n\r\n    /**\r\n     * 分片文件处理方法\r\n     */\r\n    private chunkHandler: boolean[] = [];\r\n\r\n    /**\r\n     * 已完成\r\n     */\r\n    private finished: boolean = false;\r\n\r\n    /**\r\n     * 已取消\r\n     */\r\n    private canceled: boolean = false;\r\n\r\n    /**\r\n     * 已暂停\r\n     */\r\n    private paused: boolean = false;\r\n\r\n    /**\r\n     * 等待继续的回调\r\n     */\r\n    private waitToContinue: (((value: boolean | PromiseLike<boolean>) => void) | null)[] = [];\r\n\r\n    /**\r\n     * 文件数据读取器\r\n     */\r\n    private fileReaders: FileReadHelper[] = [];\r\n\r\n    /**\r\n     * 直接校验分片文件\r\n     *\r\n     * @param file\r\n     * @param handlerIndex 主索引\r\n     * @param onProgress\r\n     * @return md5 返回的是主索引对应的计算单元的计算结果\r\n     */\r\n    private async checkFile(\r\n        this: HashHelper,\r\n        file: RawFile | ChunkFile,\r\n        handlerIndex: number,\r\n        onProgress: (progress: IProgress) => void): Promise<string | void> {\r\n        return new Promise<string | void>(async (resolve, reject) => {\r\n            //文件\r\n            const xFile = file as { checkPosition: number, size: number, blob: Blob, file?: File };\r\n            if (file instanceof RawFile)\r\n                xFile.blob = xFile.file!;\r\n\r\n            //分片进度\r\n            let progress: IProgress = { preLoaded: 0, loaded: 0, total: file.size };\r\n            onProgress(progress);\r\n\r\n            //校验完整的文件，每次计算1MB的数据\r\n            const bufferSize = 1024 * 1024;\r\n            while (xFile.checkPosition < xFile.size) {\r\n                //取消校验则直接结束处理\r\n                if (this.canceled) {\r\n                    await this.reset();\r\n                    resolve();\r\n                    break;\r\n                }\r\n\r\n                //暂停则等待通知\r\n                if (this.paused) {\r\n                    const wait = async () => {\r\n                        return new Promise<boolean>((resolve, reject) => {\r\n                            this.waitToContinue[handlerIndex] = resolve;\r\n                        });\r\n                    }\r\n\r\n                    this.debug ? console.debug('HashHelper > 已暂停', handlerIndex) : !1;\r\n\r\n                    //等待继续\r\n                    const flag = await wait();\r\n\r\n                    this.waitToContinue[handlerIndex] = null;\r\n\r\n                    this.debug ? console.debug('HashHelper > 已恢复', handlerIndex) : !1;\r\n\r\n                    if (!flag) {\r\n                        //返回false则表示停止执行\r\n                        resolve();\r\n                        return;\r\n                    }\r\n                }\r\n\r\n                const blob = xFile.blob.slice(xFile.checkPosition, Math.min(xFile.checkPosition + bufferSize, xFile.size));\r\n                xFile.checkPosition += blob.size;\r\n\r\n                progress.preLoaded += blob.size;\r\n                onProgress(progress);\r\n\r\n                //追加数据\r\n                await this.appendData(blob, handlerIndex);\r\n\r\n                progress.loaded += blob.size;\r\n                onProgress(progress);\r\n            }\r\n\r\n            //获取计算结果\r\n            resolve(await this.getResult(handlerIndex));\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 追加数据\r\n     *\r\n     * @param blob 数据\r\n     * @param handlerIndex\r\n     */\r\n    private async appendData(this: HashHelper, blob: Blob, handlerIndex: number): Promise<void> {\r\n        let buffer = await this.fileReaders[handlerIndex].readAsArrayBuffer(blob);\r\n\r\n        const message = { type: HashWorkerMessageType.下行_附加数据, data: buffer } as IHashWorkerMessage<ArrayBuffer>;\r\n\r\n        if (this.workerSupported) {\r\n            await this.workerPostMessage(handlerIndex, message);\r\n        } else {\r\n            this.sparkUnits[handlerIndex].append(buffer);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取当前计算的结果\r\n     *\r\n     * @param handlerIndex\r\n     */\r\n    private async getResult(this: HashHelper, handlerIndex: number): Promise<string> {\r\n        const message = { type: HashWorkerMessageType.下行_获取结果 } as IHashWorkerMessage<void>;\r\n\r\n        if (this.workerSupported) {\r\n            return await this.workerPostMessage(handlerIndex, message) as string;\r\n        } else {\r\n            return this.sparkUnits[handlerIndex].end();\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 全部重置\r\n     */\r\n    private async reset(this: HashHelper) {\r\n        if (this.enableWorker && this.workerSupported) {\r\n            for (let i = 0; i < this.workerUnits.length; i++) {\r\n                await this.resetByIndex(i);\r\n            }\r\n        } else {\r\n            for (let i = 0; i < this.sparkUnits.length; i++) {\r\n                await this.resetByIndex(i);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 重置\r\n     *\r\n     * @param handlerIndex\r\n     */\r\n    private async resetByIndex(this: HashHelper, handlerIndex: number) {\r\n        if (this.enableWorker && this.workerSupported) {\r\n            if (!this.workerUnits[handlerIndex].used)\r\n                return;\r\n            await this.workerPostMessage(handlerIndex, { type: HashWorkerMessageType.下行_重置 } as IHashWorkerMessage<void>);\r\n            this.debug ? console.debug('HashHelper > WebWoeker子线程计算单元 已重置', Object.assign({}, this.workerUnits[handlerIndex])) : !1;\r\n        } else {\r\n            this.sparkUnits[handlerIndex].reset();\r\n            this.debug ? console.debug('HashHelper > Spark计算单元 已重置', Object.assign({}, this.sparkUnits[handlerIndex])) : !1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 关闭\r\n     *\r\n     * @param handlerIndex 索引\r\n     */\r\n    private async closeByIndex(this: HashHelper, handlerIndex: number) {\r\n        this.fileReaders[handlerIndex].close();\r\n        this.debug ? console.debug('HashHelper > FileReadHelper 已关闭', Object.assign({}, this.fileReaders[handlerIndex])) : !1;\r\n\r\n        if (this.enableWorker && this.workerSupported) {\r\n            await this.workerPostMessage(handlerIndex, { type: HashWorkerMessageType.下行_关闭 } as IHashWorkerMessage<void>);\r\n            this.debug ? console.debug('HashHelper > WebWoeker子线程计算单元 已关闭', Object.assign({}, this.workerUnits[handlerIndex])) : !1;\r\n        } else {\r\n            this.sparkUnits[handlerIndex].destroy();\r\n            this.debug ? console.debug('HashHelper > Spark计算单元 已关闭', Object.assign({}, this.sparkUnits[handlerIndex])) : !1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 发送数据给WebWorker\r\n     *\r\n     * @param handlerIndex\r\n     * @param data\r\n     */\r\n    private async workerPostMessage(\r\n        this: HashHelper,\r\n        handlerIndex: number,\r\n        data: IHashWorkerMessage<ArrayBuffer | void>): Promise<string | void> {\r\n\r\n        let unit = this.workerUnits[handlerIndex];\r\n        unit.used = true;\r\n\r\n        return new Promise<string | void>((resolve, reject) => {\r\n            //接收回调\r\n            unit.worker.onmessage = (event: MessageEvent<IHashWorkerMessage<string | void>>) => {\r\n                switch (event.data.type) {\r\n                    case HashWorkerMessageType.上行_结果:\r\n                        resolve(event.data.data as string);\r\n                        break;\r\n                    case HashWorkerMessageType.上行_应答:\r\n                    default:\r\n                        resolve();\r\n                }\r\n            }\r\n\r\n            //监听异常\r\n            unit.worker.onerror = event => {\r\n                unit.used = false;\r\n                reject(new UploadError('WebWorker异常', event.error));\r\n            };\r\n            unit.worker.onmessageerror = (event: MessageEvent) => {\r\n                unit.used = false;\r\n                reject(new UploadError(`WebWorker通讯错误，${event.data}`));\r\n            };\r\n\r\n            //发送数据\r\n            if (data.type === HashWorkerMessageType.下行_附加数据)\r\n                unit.worker.postMessage(data, [data.data as ArrayBuffer]);\r\n            else\r\n                unit.worker.postMessage(JSON.parse(JSON.stringify(data)));\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 获取实例\r\n     *\r\n     * @param concurrent 并发数量\r\n     * @param enableWorker 是否启用Worker\r\n     * @param debug 调试模式\r\n     */\r\n    public static async getInstance(\r\n        concurrent: number = 1,\r\n        enableWorker: boolean = true,\r\n        debug: boolean = false): Promise<HashHelper> {\r\n        return new Promise<HashHelper>((resolve) => {\r\n            let helper = new HashHelper(enableWorker, debug);\r\n\r\n            //创建文件读取实例和分片处理方法的状态\r\n            while (helper.fileReaders.length < concurrent) {\r\n                helper.fileReaders.push(new FileReadHelper());\r\n                helper.chunkHandler.push(false);\r\n                helper.waitToContinue.push(null);\r\n                helper.debug ? console.debug('HashHelper > FileReadHelper 已创建', Object.assign({}, helper.fileReaders[helper.fileReaders.length - 1])) : !1;\r\n            }\r\n\r\n            //如果支持并且启用WebWorker，则使用脚本创建虚拟文件后后再创建WebWorker\r\n            if (helper.enableWorker && helper.workerSupported) {\r\n                window.URL = window.URL || window.webkitURL;\r\n                for (let i = 0; i < concurrent; i++) {\r\n                    helper.workerUnits.push({\r\n                        worker: new Worker(window.URL.createObjectURL(HashWorkerScript)),\r\n                        used: false\r\n                    });\r\n                    helper.debug ? console.debug('HashHelper > WebWoeker子线程计算单元 已创建', Object.assign({}, helper.workerUnits[i].worker)) : !1;\r\n                }\r\n            } else {\r\n                while (helper.sparkUnits.length < concurrent) {\r\n                    helper.sparkUnits.push(new SparkMD5.ArrayBuffer());\r\n                    helper.debug ? console.debug('HashHelper > Spark计算单元 已创建', Object.assign({}, helper.sparkUnits[helper.sparkUnits.length - 1])) : !1;\r\n                }\r\n            }\r\n\r\n            resolve(helper);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 处理文件\r\n     *\r\n     * @param file 文件\r\n     * @param onProgress 监听进度\r\n     */\r\n    public async handler(\r\n        this: HashHelper,\r\n        file: RawFile,\r\n        onProgress: (progress: IProgress) => void): Promise<void> {\r\n        return new Promise<void>(async (resolve, reject) => {\r\n            this.debug ? console.debug('HashHelper 开始处理', Object.assign({}, file)) : !1;\r\n\r\n            /**\r\n             * 整体进度\r\n             */\r\n            let progress: IProgress = { preLoaded: 0, loaded: 0, total: file.size * 2 };\r\n\r\n            /**\r\n             * 处理进度\r\n             *\r\n             * @param current_progress 当前的进度\r\n             * @param last_progress 上次的进度\r\n             */\r\n            const handlerProgress = (current_progress: IProgress, last_progress: IProgress) => {\r\n                progress.preLoaded += (current_progress.preLoaded - last_progress.preLoaded);\r\n                progress.loaded += (current_progress.loaded - last_progress.loaded);\r\n\r\n                last_progress.preLoaded = current_progress.preLoaded;\r\n                last_progress.loaded = current_progress.loaded;\r\n\r\n                onProgress(progress);\r\n            }\r\n\r\n            /**\r\n             * 计算整个文件的md5值\r\n             */\r\n            const calcFile = async () => {\r\n                /**\r\n                 * 上次的进度\r\n                 */\r\n                let last_progress: IProgress = { preLoaded: 0, loaded: 0, total: file.size };\r\n\r\n                try {\r\n                    file.md5 = await this.checkFile(\r\n                        file,\r\n                        0,\r\n                        (current_progress: IProgress) => {\r\n                            handlerProgress(current_progress, last_progress);\r\n                        }) ?? null;\r\n                } catch (e) {\r\n                    reject(e);\r\n                }\r\n            }\r\n\r\n            /**\r\n             * 校验结束\r\n             */\r\n            const done = () => {\r\n                this.finished = true;\r\n                this.debug ? console.debug('HashHelper 处理结束', Object.assign({}, file)) : !1;\r\n                resolve();\r\n            }\r\n\r\n            await calcFile();\r\n\r\n            //无需分片处理则直接结束\r\n            if (!file.needSection) {\r\n                done();\r\n                return;\r\n            }\r\n\r\n            /**\r\n             * 计算分片文件\r\n             */\r\n            const calc = async () => {\r\n                if (this.finished)\r\n                    return;\r\n\r\n                if (this.chunkHandlerQueue.length === 0) {\r\n                    for (let i = 0; i < this.chunkHandler.length; i++) {\r\n                        if (this.chunkHandler[i]) {\r\n                            return;\r\n                        }\r\n                    }\r\n\r\n                    //所有分片全部校验完毕\r\n                    done();\r\n                    return;\r\n                }\r\n\r\n                let handlerIndex: number | null = null;\r\n                for (let i = 0; i < this.chunkHandler.length; i++) {\r\n                    if (!this.chunkHandler[i]) {\r\n                        handlerIndex = i;\r\n                        break;\r\n                    }\r\n                }\r\n\r\n                if (handlerIndex == null) {\r\n                    this.debug ? console.debug(`HashHelper 已达到最大并发数：${this.chunkHandler.length}，当前队列长度：${this.chunkHandlerQueue.length}`, Object.assign({}, file)) : !1;\r\n                    return;\r\n                }\r\n\r\n                this.chunkHandler[handlerIndex] = true;\r\n\r\n                /**\r\n                 * 校验下一个分片文件\r\n                 */\r\n                const next = () => {\r\n                    onProgress(progress);\r\n\r\n                    //取消上传则直接结束处理\r\n                    if (this.canceled) {\r\n                        this.reset().then(resolve).catch(resolve);\r\n                        return;\r\n                    }\r\n\r\n                    this.chunkHandler[handlerIndex!] = false;\r\n\r\n                    calc();\r\n                };\r\n\r\n                //当前处理中的分片文件\r\n                const chunk = this.chunkHandlerQueue.shift()!;\r\n\r\n                //如已校验过了则直接跳过\r\n                if (chunk.checked) {\r\n                    progress.preLoaded += chunk.size;\r\n                    progress.loaded += chunk.size;\r\n                    onProgress(progress);\r\n                    next();\r\n                    return;\r\n                }\r\n\r\n                /**\r\n                 * 上次的进度\r\n                 */\r\n                let last_progress: IProgress = { preLoaded: 0, loaded: 0, total: chunk.size };\r\n\r\n                onProgress(progress);\r\n\r\n                //校验分片文件\r\n                chunk.md5 = await this.checkFile(\r\n                    chunk,\r\n                    handlerIndex,\r\n                    (current_progress: IProgress) => {\r\n                        handlerProgress(current_progress, last_progress);\r\n                    }) ?? null;\r\n\r\n                next();\r\n            }\r\n\r\n            /**\r\n             * 添加至队列\r\n             */\r\n            const push = (chunk: ChunkFile) => {\r\n                this.chunkHandlerQueue.push(chunk);\r\n                calc();\r\n            }\r\n\r\n            //校验所有分片文件\r\n            for (const chunk of file.chunks) {\r\n                push(chunk);\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 取消\r\n     */\r\n    public async cancel(this: HashHelper) {\r\n        this.canceled = true;\r\n        if (this.paused) {\r\n            //如果已暂停，则先通知取消执行\r\n            this.paused = false;\r\n            for (const item of this.waitToContinue) {\r\n                item && item(false);\r\n            }\r\n        }\r\n        this.debug ? console.debug('HashHelper 已取消') : !1;\r\n    }\r\n\r\n    /**\r\n     * 暂停\r\n     */\r\n    public async pause(this: HashHelper) {\r\n        this.paused = true;\r\n        this.debug ? console.debug('HashHelper 已暂停') : !1;\r\n    }\r\n\r\n    /**\r\n     * 恢复\r\n     */\r\n    public async continue(this: HashHelper) {\r\n        this.paused = false;\r\n        for (const item of this.waitToContinue) {\r\n            item && item(true);\r\n        }\r\n        this.debug ? console.debug('HashHelper 已恢复') : !1;\r\n    }\r\n\r\n    /**\r\n     * 关闭\r\n     */\r\n    public async close(this: HashHelper) {\r\n        if (this.enableWorker && this.workerSupported) {\r\n            for (let i = 0; i < this.workerUnits.length; i++) {\r\n                await this.closeByIndex(i);\r\n            }\r\n        } else {\r\n            for (let i = 0; i < this.sparkUnits.length; i++) {\r\n                await this.closeByIndex(i);\r\n            }\r\n        }\r\n        this.debug ? console.debug('HashHelper 已关闭') : !1;\r\n    }\r\n}","/**\r\n * 文件上传WebWorker传输信息类型\r\n *\r\n * @author LCTR\r\n * @date 2022-09-27\r\n */\r\nexport enum UploadWorkerMessageType {\r\n    下行_上传 = 'DOWN_UPLOAD',\r\n    下行_取消 = 'DOWN_CANCEL',\r\n    下行_关闭 = 'DOWN_CLOSE',\r\n    上行_进度 = 'UP_PROGRESS',\r\n    上行_取消 = 'UP_CANCEL',\r\n    上行_完成 = 'UP_COMPLETED',\r\n    上行_失败 = 'UP_FAILED',\r\n    上行_超时 = 'UP_TIMEOUT',\r\n}","/**\r\n * 预备上传分片文件状态\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport enum PreUploadChunkFileState {\r\n    允许上传 = \"允许上传\",\r\n    推迟上传 = \"推迟上传\",\r\n    跳过 = \"跳过\",\r\n    全部跳过 = \"全部跳过\"\r\n}","﻿import { IUploadWorkerMessage } from \"../Model/IUploadWorkerMessage\";\r\nimport { IUploadWorkerFileMessage } from \"../Model/IUploadWorkerFileMessage\";\r\nimport { IProgress } from \"../Model/IProgress\";\r\nimport { IUserFileInfo } from \"../Model/IUserFileInfo\";\r\n\r\n\r\n/**\r\n * 文件上传WebWorker脚本\r\n *\r\n * @author LCTR\r\n * @date 2022-09-27\r\n */\r\nconst worker = () => {\r\n    let currentRequest: XMLHttpRequest;\r\n\r\n    /**\r\n     * 上传\r\n     *\r\n     * @param url 接口地址\r\n     * @param headers 请求头\r\n     * @param buffer 数据\r\n     */\r\n    const upload = (url: string, headers: Map<string, string>, buffer: ArrayBuffer) => {\r\n        //创建请求实例\r\n        const request = new XMLHttpRequest();\r\n        //设置内容类型\r\n        request.overrideMimeType('application/octet-stream');\r\n        //设置请求头\r\n        if (headers)\r\n            for (const key of headers.keys()) {\r\n                request.setRequestHeader(key, headers.get(key) ?? '');\r\n            }\r\n        //文件上传进度\r\n        request.upload.onprogress = event => {\r\n            postMessage({\r\n                //UploadWorkerMessageType.上行_进度\r\n                type: 'UP_PROGRESS',\r\n                data: {\r\n                    preLoaded: event.total,\r\n                    total: event.total,\r\n                    loaded: event.loaded\r\n                } as IProgress\r\n            } as IUploadWorkerMessage<IProgress>);\r\n        };\r\n        //取消上传\r\n        request.onabort = event => {\r\n            postMessage({\r\n                //UploadWorkerMessageType.上行_取消\r\n                type: 'UP_CANCEL',\r\n                data: {\r\n                    preLoaded: event.total,\r\n                    total: event.total,\r\n                    loaded: event.loaded\r\n                } as IProgress\r\n            } as IUploadWorkerMessage<IProgress>);\r\n        };\r\n        request.onreadystatechange = () => {\r\n            if (request.readyState === 4 && request.status === 200) {\r\n                //上传成功\r\n                postMessage({\r\n                    //UploadWorkerMessageType.上行_完成\r\n                    type: 'UP_COMPLETED',\r\n                    data: JSON.parse(request.response)\r\n                } as IUploadWorkerMessage<IUserFileInfo | null>);\r\n            }\r\n        };\r\n        //上传失败\r\n        request.onerror = event => {\r\n            postMessage({\r\n                //UploadWorkerMessageType.上行_失败\r\n                type: 'UP_FAILED',\r\n                data: {\r\n                    preLoaded: event.total,\r\n                    total: event.total,\r\n                    loaded: event.loaded\r\n                } as IProgress\r\n            } as IUploadWorkerMessage<IProgress>);\r\n        };\r\n        //上传超时\r\n        request.ontimeout = event => {\r\n            postMessage({\r\n                //UploadWorkerMessageType.上行_超时\r\n                type: 'UP_TIMEOUT',\r\n                data: {\r\n                    preLoaded: event.total,\r\n                    total: event.total,\r\n                    loaded: event.loaded\r\n                } as IProgress\r\n            } as IUploadWorkerMessage<IProgress>);\r\n        };\r\n        //请求接口地址\r\n        request.open('POST', url, true);\r\n        //发送数据\r\n        request.send(buffer);\r\n        currentRequest = request;\r\n    }\r\n\r\n    onmessage = (event: MessageEvent<IUploadWorkerMessage<IUploadWorkerFileMessage | void>>) => {\r\n        // console.debug(event.data);\r\n        switch (event.data.type) {\r\n            //UploadWorkerMessageType.下行_上传:\r\n            case 'DOWN_UPLOAD':\r\n                const data_upload = event.data.data as IUploadWorkerFileMessage;\r\n                upload(data_upload.url, data_upload.headers, data_upload.buffer);\r\n                break;\r\n            //UploadWorkerMessageType.下行_取消:\r\n            case 'DOWN_CANCEL':\r\n                currentRequest && currentRequest.readyState !== 4 && currentRequest.abort();\r\n                break;\r\n            //UploadWorkerMessageType.下行_关闭:\r\n            case 'DOWN_CLOSE':\r\n                close();\r\n                break;\r\n        }\r\n    }\r\n};\r\nexport const UploadWorkerScript = new Blob([`(${worker.toString()})()`]);","﻿import ChunkFile from \"../Model/ChunkFile\";\r\nimport UploadError from \"../Extention/UploadError\";\r\nimport RawFile from \"../Model/RawFile\";\r\nimport { IApiService } from \"../Core/IApiService\";\r\nimport { Canceler } from \"axios\";\r\nimport { IUserFileInfo } from \"../Model/IUserFileInfo\";\r\nimport { UploadWorkerMessageType } from \"../Model/UploadWorkerMessageType\";\r\nimport { IPreUploadFileResponse } from \"../Model/IPreUploadFileResponse\";\r\nimport { IProgress } from \"../Model/IProgress\";\r\nimport { PreUploadChunkFileState } from \"../Model/PreUploadChunkFileState\";\r\nimport { IPreUploadChunkFileResponse } from \"../Model/IPreUploadChunkFileResponse\";\r\nimport { UploadWorkerScript } from \"../Extention/UploadWorkerScript.js\";\r\nimport { IUploadWorkerMessage } from \"../Model/IUploadWorkerMessage\";\r\nimport { IUploadWorkerFileMessage } from \"../Model/IUploadWorkerFileMessage\";\r\nimport FileReadHelper from \"../Extention/FileReadHelper\";\r\n\r\n\r\n/**\r\n * 文件上传帮助类\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class UploadHelper {\r\n    constructor(enableWorker: boolean,\r\n        apiService: IApiService,\r\n        debug: boolean) {\r\n        this.debug = debug;\r\n        this.enableWorker = enableWorker;\r\n        this.workerSupported = 'undefined' !== typeof Worker;\r\n        this.apiService = apiService;\r\n        this.enableWorker && this.debug ? console.debug(`UploadHelper > WebWoeker ${(this.workerSupported ? '已启用' : '未启用（当前浏览器不支持）')}`) : !1;\r\n    }\r\n\r\n    /**\r\n     * 是否启用Worker\r\n     * 默认启用（如果浏览器支持的话）\r\n     */\r\n    private readonly enableWorker: boolean;\r\n\r\n    /**\r\n     * 浏览器是否支持Web Worker\r\n     */\r\n    private readonly workerSupported: boolean;\r\n\r\n    /**\r\n     * 调试模式\r\n     */\r\n    private readonly debug: boolean;\r\n\r\n    /**\r\n     * 接口服务\r\n     */\r\n    private apiService: IApiService;\r\n\r\n    /**\r\n     * 取消令牌\r\n     */\r\n    private cancelTokenList: Map<String, Canceler> = new Map<String, Canceler>();\r\n\r\n    /**\r\n     * 子线程上传单元\r\n     */\r\n    private workerUnits: {\r\n        worker: Worker, used: boolean\r\n    }[] = [];\r\n\r\n    /**\r\n     * 分片文件处理队列\r\n     * */\r\n    private chunkHandlerQueue: ChunkFile[] = [];\r\n\r\n    /**\r\n     * 分片文件处理方法\r\n     */\r\n    private chunkHandler: boolean[] = [];\r\n\r\n    /**\r\n     * 推迟次数\r\n     * <p>如果所有分片文件都需要推迟，则忽略推迟操作，直接首个分片文件</p>\r\n     * <p>同时推迟次数清零</p>\r\n     */\r\n    private delayTimes: number = 0;\r\n\r\n    /**\r\n     * 已完成\r\n     */\r\n    private finished: boolean = false;\r\n\r\n    /**\r\n     * 已取消\r\n     */\r\n    private canceled: boolean = false;\r\n\r\n    /**\r\n     * 已暂停\r\n     */\r\n    private paused: boolean = false;\r\n\r\n    /**\r\n     * 等待继续的回调\r\n     */\r\n    private waitToContinue: (((value: boolean | PromiseLike<boolean>) => void) | null)[] = [];\r\n\r\n    /**\r\n     * 文件数据读取器\r\n     */\r\n    private fileReaders: FileReadHelper[] = [];\r\n\r\n    /**\r\n     * 直接上传文件\r\n     *\r\n     * @param file\r\n     * @param onProgress\r\n     * @return 用户文件信息\r\n     */\r\n    private async uploadFile(\r\n        this: UploadHelper,\r\n        file: RawFile,\r\n        onProgress: (progress: IProgress) => void): Promise<IUserFileInfo> {\r\n        const userFileInfo = await this.apiService.singleFile(file.configCode!, file.file!, file.name, onProgress, cancelToken => {\r\n            this.cancelTokenList.set(file.md5!, cancelToken);\r\n        });\r\n        this.cancelTokenList.delete(file.md5!);\r\n        return userFileInfo;\r\n    }\r\n\r\n    /**\r\n     * 直接上传分片文件\r\n     *\r\n     * @param handlerIndex\r\n     * @param validation\r\n     * @param chunk\r\n     * @param onProgress\r\n     */\r\n    private async uploadChunkFile(\r\n        this: UploadHelper,\r\n        handlerIndex: number,\r\n        validation: IPreUploadChunkFileResponse,\r\n        chunk: ChunkFile,\r\n        onProgress: (progress: IProgress) => void): Promise<void> {\r\n        await this.apiService.singleChunkFile(validation.key, chunk.md5!, chunk.blob, onProgress, cancelToken => {\r\n            this.cancelTokenList.set(chunk.md5!, cancelToken);\r\n        });\r\n        this.cancelTokenList.delete(chunk.md5!);\r\n    }\r\n\r\n    /**\r\n     * 使用WebWorker上传文件\r\n     *\r\n     * @param file\r\n     * @param onProgress\r\n     */\r\n    private async useWorkerUploadFile(\r\n        this: UploadHelper,\r\n        file: RawFile,\r\n        onProgress: (progress: IProgress) => void): Promise<IUserFileInfo> {\r\n        return new Promise<IUserFileInfo>(async (resolve, reject) => {\r\n            let buffer: ArrayBuffer;\r\n            try {\r\n                buffer = await this.fileReaders[0].readAsArrayBuffer(file.file!);\r\n            } catch (e) {\r\n                reject(e);\r\n                return;\r\n            }\r\n\r\n            try {\r\n                const requestParams = this.apiService.getSingleFileByArrayBufferRequestParams(file.configCode!, file.file!.type, file.extension!, file.name);\r\n\r\n                const userFileInfo = await this.workerPostMessage(0, {\r\n                    type: UploadWorkerMessageType.下行_上传,\r\n                    data: {\r\n                        url: requestParams.urlWithParams,\r\n                        headers: requestParams.headers,\r\n                        buffer: buffer\r\n                    } as IUploadWorkerFileMessage\r\n                } as IUploadWorkerMessage<IUploadWorkerFileMessage>, onProgress, false) as IUserFileInfo;\r\n\r\n                resolve(userFileInfo);\r\n                return\r\n            } catch (e) {\r\n                reject(e);\r\n                return;\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 使用WebWorker分片文件\r\n     *\r\n     * @param handlerIndex\r\n     * @param validation 预先上传的验证结果\r\n     * @param chunk\r\n     * @param onProgress\r\n     */\r\n    private async useWorkerUploadChunkFile(\r\n        this: UploadHelper,\r\n        handlerIndex: number,\r\n        validation: IPreUploadChunkFileResponse,\r\n        chunk: ChunkFile,\r\n        onProgress: (progress: IProgress) => void) {\r\n        return new Promise<void>(async (resolve, reject) => {\r\n            let buffer: ArrayBuffer;\r\n            try {\r\n                buffer = await this.fileReaders[handlerIndex].readAsArrayBuffer(chunk.blob);\r\n            } catch (e) {\r\n                reject(e);\r\n                return;\r\n            }\r\n\r\n            try {\r\n                const requestParams = this.apiService.getSingleChunkFileByArrayBufferRequestParams(validation.key, chunk.md5!);\r\n                await this.workerPostMessage(\r\n                    handlerIndex,\r\n                    {\r\n                        type: UploadWorkerMessageType.下行_上传,\r\n                        data: {\r\n                            url: requestParams.urlWithParams,\r\n                            headers: requestParams.headers,\r\n                            buffer: buffer\r\n                        } as IUploadWorkerFileMessage\r\n                    } as IUploadWorkerMessage<IUploadWorkerFileMessage>, onProgress, true);\r\n            } catch (e) {\r\n                reject(e);\r\n                return;\r\n            }\r\n\r\n            resolve();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 发送数据给WebWorker\r\n     *\r\n     * @param handlerIndex\r\n     * @param data\r\n     * @param onProgress\r\n     * @param chunkFile 是否为分片文件\r\n     */\r\n    private async workerPostMessage(\r\n        this: UploadHelper,\r\n        handlerIndex: number,\r\n        data: IUploadWorkerMessage<IUploadWorkerFileMessage | void>,\r\n        onProgress?: (progress: IProgress) => void,\r\n        chunkFile?: boolean): Promise<IUserFileInfo | void> {\r\n\r\n        let unit = this.workerUnits[handlerIndex];\r\n        unit.used = true;\r\n\r\n        return new Promise<IUserFileInfo | void>((resolve, reject) => {\r\n            //接收回调\r\n            unit.worker.onmessage = (event: MessageEvent<IUploadWorkerMessage<IProgress | IUserFileInfo | void>>) => {\r\n                switch (event.data.type) {\r\n                    case UploadWorkerMessageType.上行_进度:\r\n                        const data_progress1 = event.data.data as IProgress;\r\n                        onProgress && onProgress({\r\n                            preLoaded: data_progress1.preLoaded,\r\n                            total: data_progress1.total,\r\n                            loaded: data_progress1.loaded\r\n                        } as IProgress);\r\n                        break;\r\n                    case UploadWorkerMessageType.上行_取消:\r\n                        const data_progress2 = event.data.data as IProgress;\r\n                        onProgress && onProgress({\r\n                            preLoaded: data_progress2.preLoaded,\r\n                            total: data_progress2.total,\r\n                            loaded: data_progress2.loaded\r\n                        } as IProgress);\r\n                        unit.used = false;\r\n                        reject(new UploadError('上传操作已取消'));\r\n                        break;\r\n                    case UploadWorkerMessageType.上行_完成:\r\n                        unit.used = false;\r\n                        try {\r\n                            const data_userFileInfo = chunkFile ? this.apiService.getUserFileInfoFromSingleChunkFileByArrayBufferResponse(event.data.data) : this.apiService.getUserFileInfoFromSingleFileByArrayBufferResponse(event.data.data);\r\n                            resolve(data_userFileInfo);\r\n                        } catch (e: any) {\r\n                            reject(new UploadError('上传失败', e));\r\n                        }\r\n                        break;\r\n                    case UploadWorkerMessageType.上行_失败:\r\n                        const data_progress3 = event.data.data as IProgress;\r\n                        onProgress && onProgress({\r\n                            preLoaded: data_progress3.preLoaded,\r\n                            total: data_progress3.total,\r\n                            loaded: data_progress3.loaded\r\n                        } as IProgress);\r\n                        unit.used = false;\r\n                        reject(new UploadError('上传失败'));\r\n                        break;\r\n                    case UploadWorkerMessageType.上行_超时:\r\n                        const data_progress4 = event.data.data as IProgress;\r\n                        onProgress && onProgress({\r\n                            preLoaded: data_progress4.preLoaded,\r\n                            total: data_progress4.total,\r\n                            loaded: data_progress4.loaded\r\n                        } as IProgress);\r\n                        unit.used = false;\r\n                        reject(new UploadError('上传操作处理超时'));\r\n                        break;\r\n                    default:\r\n                        reject(new UploadError(`未知的UploadWorkerMessageType: ${event.data.type}.`));\r\n                }\r\n            }\r\n\r\n            //监听异常\r\n            unit.worker.onerror = event => {\r\n                unit.used = false;\r\n                reject(new UploadError('WebWorker发生错误', event.error));\r\n            };\r\n            unit.worker.onmessageerror = (event: MessageEvent) => {\r\n                unit.used = false;\r\n                reject(new UploadError(`WebWorker通讯错误，${event.data}`));\r\n                return;\r\n            };\r\n\r\n            //发送数据\r\n            if (data.type === UploadWorkerMessageType.下行_上传)\r\n                unit.worker.postMessage(data, [(data.data as IUploadWorkerFileMessage).buffer]);\r\n            else\r\n                unit.worker.postMessage(JSON.parse(JSON.stringify(data)));\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 关闭\r\n     *\r\n     * @param handlerIndex 索引\r\n     */\r\n    private async closeByIndex(this: UploadHelper, handlerIndex: number) {\r\n        this.fileReaders[handlerIndex].close();\r\n        this.debug ? console.debug('UploadHelper > FileReadHelper 已关闭', Object.assign({}, this.fileReaders[handlerIndex])) : !1;\r\n\r\n        if (this.enableWorker && this.workerSupported) {\r\n            await this.workerPostMessage(handlerIndex, { type: UploadWorkerMessageType.下行_关闭 } as IUploadWorkerMessage<void>);\r\n            this.debug ? console.debug('UploadHelper > WebWoeker子线程计算单元 已关闭', Object.assign({}, this.workerUnits[handlerIndex].worker)) : !1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取实例\r\n     *\r\n     * @param concurrent 并发数量\r\n     * @param enableWorker 是否启用Worker\r\n     * @param apiService 接口服务\r\n     * @param debug 调试模式\r\n     */\r\n    public static async getInstance(\r\n        concurrent: number,\r\n        enableWorker: boolean = true,\r\n        apiService: IApiService,\r\n        debug: boolean = false): Promise<UploadHelper> {\r\n        return new Promise<UploadHelper>((resolve) => {\r\n            let helper = new UploadHelper(enableWorker, apiService, debug);\r\n\r\n            //创建文件读取实例\r\n            while (helper.fileReaders.length < concurrent) {\r\n                helper.fileReaders.push(new FileReadHelper());\r\n                helper.chunkHandler.push(false);\r\n                helper.waitToContinue.push(null);\r\n                helper.debug ? console.debug('UploadHelper > FileReadHelper 已创建', Object.assign({}, helper.fileReaders[helper.fileReaders.length - 1])) : !1;\r\n            }\r\n\r\n            //如果支持并且启用WebWorker，则使用脚本创建虚拟文件后后再创建WebWorker\r\n            if (helper.enableWorker && helper.workerSupported) {\r\n                window.URL = window.URL || window.webkitURL;\r\n                for (let i = 0; i < concurrent; i++) {\r\n                    helper.workerUnits.push({\r\n                        worker: new Worker(window.URL.createObjectURL(UploadWorkerScript)),\r\n                        used: false\r\n                    });\r\n                    helper.debug ? console.debug('UploadHelper > WebWoeker子线程计算单元 已创建', Object.assign({}, helper.workerUnits[i].worker)) : !1;\r\n                }\r\n            }\r\n\r\n            resolve(helper);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 处理文件\r\n     *\r\n     * @param file 文件\r\n     * @param onProgress 监听进度\r\n     */\r\n    public async handler(\r\n        this: UploadHelper,\r\n        file: RawFile,\r\n        onProgress: (progress: IProgress) => void): Promise<void> {\r\n        return new Promise<void>(async (resolve, reject) => {\r\n            this.debug ? console.debug('UploadHelper 开始处理', Object.assign({}, file)) : !1;\r\n\r\n            /**\r\n             * 上传结束\r\n             */\r\n            const done = () => {\r\n                this.finished = true;\r\n                this.debug ? console.debug('UploadHelper 处理结束', Object.assign({}, file)) : !1;\r\n                resolve();\r\n            }\r\n\r\n            //文件MD5校验\r\n            let validation: IPreUploadFileResponse;\r\n            try {\r\n                if (file.needSection)\r\n                    validation = await this.apiService.preUploadFile(\r\n                        file.configCode!,\r\n                        file.md5!,\r\n                        file.file!.type,\r\n                        file.extension!,\r\n                        file.file!.size.toString(),\r\n                        file.name,\r\n                        true,\r\n                        file.specs,\r\n                        file.chunks.length);\r\n                else\r\n                    validation = await this.apiService.preUploadFile(\r\n                        file.configCode!,\r\n                        file.md5!,\r\n                        file.file!.type,\r\n                        file.extension!,\r\n                        file.file!.size.toString(),\r\n                        file.name,\r\n                        false);\r\n            } catch (e) {\r\n                reject(e);\r\n                return;\r\n            }\r\n\r\n            if (validation.uploaded) {\r\n                this.debug ? console.debug('UploadHelper 忽略已上传过的文件', Object.assign({}, file)) : !1;\r\n                file.userFileInfo = validation.userFileInfo;\r\n                done();\r\n                return;\r\n            }\r\n\r\n            if (file.needSection) {\r\n                /**\r\n                 * 整体进度\r\n                 */\r\n                let progress: IProgress = { preLoaded: 0, loaded: 0, total: file.size };\r\n\r\n                /**\r\n                 * 上传分片文件\r\n                 */\r\n                const upload = async () => {\r\n                    if (this.finished)\r\n                        return;\r\n\r\n                    if (this.chunkHandlerQueue.length === 0) {\r\n                        for (let i = 0; i < this.chunkHandler.length; i++) {\r\n                            if (this.chunkHandler[i]) {\r\n                                return;\r\n                            }\r\n                        }\r\n\r\n                        //所有分片全部上传完毕\r\n                        try {\r\n                            file.userFileInfo = await this.apiService.uploadChunkFileFinished(\r\n                                file.configCode!,\r\n                                file.md5!,\r\n                                file.specs!,\r\n                                file.chunks.length,\r\n                                file.file!.type,\r\n                                file.extension,\r\n                                file.name);\r\n\r\n                            done();\r\n                        } catch (e) {\r\n                            reject(e);\r\n                        }\r\n                        return;\r\n                    }\r\n\r\n                    let handlerIndex: number | null = null;\r\n                    for (let i = 0; i < this.chunkHandler.length; i++) {\r\n                        if (!this.chunkHandler[i]) {\r\n                            handlerIndex = i;\r\n                            break;\r\n                        }\r\n                    }\r\n\r\n                    if (handlerIndex == null) {\r\n                        this.debug ? console.debug(`HashHelper 已达到最大并发数：${this.chunkHandler.length}，当前队列长度：${this.chunkHandlerQueue.length}`, Object.assign({}, file)) : !1;\r\n                        return;\r\n                    }\r\n\r\n                    this.chunkHandler[handlerIndex] = true;\r\n\r\n                    /**\r\n                     * 上传下一个分片文件\r\n                     */\r\n                    const next = () => {\r\n                        onProgress(progress);\r\n\r\n                        //取消上传则直接结束处理\r\n                        if (this.canceled) {\r\n                            resolve();\r\n                            return;\r\n                        }\r\n\r\n                        //暂停则等待通知\r\n                        if (this.paused) {\r\n                            const wait = async () => {\r\n                                return new Promise<boolean>((resolve, reject) => {\r\n                                    this.waitToContinue[handlerIndex!] = resolve;\r\n                                });\r\n                            }\r\n\r\n                            this.debug ? console.debug('UploadHelper > 已暂停', handlerIndex) : !1;\r\n\r\n                            //等待继续\r\n                            wait().then((flag: boolean) => {\r\n                                this.waitToContinue[handlerIndex!] = null;\r\n\r\n                                this.debug ? console.debug('UploadHelper > 已恢复', handlerIndex) : !1;\r\n\r\n                                if (!flag) {\r\n                                    //返回false则表示停止执行\r\n                                    resolve();\r\n                                    return;\r\n                                }\r\n\r\n                                this.chunkHandler[handlerIndex!] = false;\r\n                                upload();\r\n                            });\r\n                        } else {\r\n                            this.chunkHandler[handlerIndex!] = false;\r\n                            upload();\r\n                        }\r\n                    };\r\n\r\n                    //当前处理中的分片文件\r\n                    const chunk = this.chunkHandlerQueue.shift()!;\r\n\r\n                    //如已上传过了则直接跳过\r\n                    if (chunk.uploaded) {\r\n                        progress.preLoaded += chunk.size;\r\n                        progress.loaded += chunk.size;\r\n                        onProgress(progress);\r\n                        next();\r\n                        return;\r\n                    }\r\n\r\n                    /**\r\n                     * 分片进度\r\n                     */\r\n                    let chunk_progress: IProgress = { preLoaded: chunk.size, loaded: 0, total: chunk.size };\r\n\r\n                    /**\r\n                     * 处理分片进度\r\n                     *\r\n                     * @param _chunk_progress\r\n                     */\r\n                    const handlerProgress = (_chunk_progress: IProgress) => {\r\n                        progress.loaded += (_chunk_progress.loaded - chunk_progress.loaded);\r\n\r\n                        chunk_progress.loaded = _chunk_progress.loaded;\r\n\r\n                        onProgress(progress);\r\n                    }\r\n\r\n                    let validation: IPreUploadChunkFileResponse;\r\n                    try {\r\n                        validation = await this.apiService.preUploadChunkFile(\r\n                            file.md5!,\r\n                            chunk.md5!,\r\n                            chunk.index,\r\n                            file.specs!,\r\n                            chunk.forced);\r\n                    } catch (e) {\r\n                        reject(e);\r\n                        return;\r\n                    }\r\n\r\n                    progress.preLoaded! += chunk_progress.preLoaded;\r\n                    onProgress(progress);\r\n\r\n                    /**\r\n                     * 继续上传\r\n                     * */\r\n                    const proceed = async () => {\r\n                        if (this.workerSupported) {\r\n                            await this.useWorkerUploadChunkFile(handlerIndex!, validation, chunk, handlerProgress);\r\n                        } else {\r\n                            await this.uploadChunkFile(handlerIndex!, validation, chunk, handlerProgress);\r\n                        }\r\n                    };\r\n\r\n                    switch (validation.state) {\r\n                        case PreUploadChunkFileState.允许上传:\r\n                            await proceed();\r\n                            break;\r\n                        case PreUploadChunkFileState.全部跳过:\r\n                            this.chunkHandlerQueue.length = 0;\r\n                            return;\r\n                        case PreUploadChunkFileState.推迟上传:\r\n                            this.chunkHandlerQueue.push(chunk);\r\n\r\n                            this.delayTimes++;\r\n                            if (this.delayTimes >= this.chunkHandlerQueue.length) {\r\n                                this.delayTimes = 0;\r\n                                chunk.forced = true;\r\n                            }\r\n                            break;\r\n                        case PreUploadChunkFileState.跳过:\r\n                            handlerProgress({ preLoaded: chunk.size, loaded: chunk.size, total: chunk.size });\r\n                            break;\r\n                    }\r\n\r\n                    next();\r\n                }\r\n\r\n                /**\r\n                 * 添加至队列\r\n                 */\r\n                const push = (chunk: ChunkFile) => {\r\n                    this.chunkHandlerQueue.push(chunk);\r\n                    upload();\r\n                }\r\n\r\n                for (let chunk of file.chunks) {\r\n                    push(chunk);\r\n                }\r\n            } else {\r\n                try {\r\n                    if (this.workerSupported) {\r\n                        file.userFileInfo = await this.useWorkerUploadFile(file, onProgress);\r\n                    } else {\r\n                        file.userFileInfo = await this.uploadFile(file, onProgress);\r\n                    }\r\n\r\n                    done();\r\n                } catch (e) {\r\n                    reject(e);\r\n                }\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 取消\r\n     */\r\n    public async cancel(this: UploadHelper) {\r\n        this.canceled = true;\r\n        if (this.paused) {\r\n            //如果已暂停，则先通知取消执行\r\n            this.paused = false;\r\n            for (const item of this.waitToContinue) {\r\n                item && item(false);\r\n            }\r\n        }\r\n\r\n        //取消当前所有进行中的请求\r\n        if (this.enableWorker && this.workerSupported) {\r\n            for (let i = 0; i < this.workerUnits.length; i++) {\r\n                if (!this.workerUnits[i].used)\r\n                    continue;\r\n                await this.workerPostMessage(i, { type: UploadWorkerMessageType.下行_取消 } as IUploadWorkerMessage<void>);\r\n                this.debug ? console.debug('UploadHelper > WebWoeker子线程计算单元 已取消', Object.assign({}, this.workerUnits[i].worker)) : !1;\r\n            }\r\n        } else {\r\n            this.cancelTokenList.forEach(cancelToken => {\r\n                cancelToken();\r\n            });\r\n        }\r\n\r\n        this.debug ? console.debug('UploadHelper 已取消') : !1;\r\n    }\r\n\r\n    /**\r\n     * 暂停\r\n     */\r\n    public async pause(this: UploadHelper) {\r\n        this.paused = true;\r\n        this.debug ? console.debug('UploadHelper 已暂停') : !1;\r\n    }\r\n\r\n    /**\r\n     * 恢复\r\n     */\r\n    public async continue(this: UploadHelper) {\r\n        this.paused = false;\r\n        for (const item of this.waitToContinue) {\r\n            item && item(true);\r\n        }\r\n        this.debug ? console.debug('UploadHelper 已恢复') : !1;\r\n    }\r\n\r\n    /**\r\n     * 关闭\r\n     */\r\n    public async close(this: UploadHelper) {\r\n        //关闭所有的文件数据读取器\r\n        if (this.enableWorker && this.workerSupported) {\r\n            for (let i = 0; i < this.workerUnits.length; i++) {\r\n                await this.closeByIndex(i);\r\n            }\r\n        } else {\r\n            for (let i = 0; i < this.fileReaders.length; i++) {\r\n                await this.closeByIndex(i);\r\n            }\r\n        }\r\n\r\n        this.debug ? console.debug('UploadHelper 已关闭') : !1;\r\n    }\r\n}","import { reactive, watch } from \"vue-demi\";\r\nimport { IApiService } from \"../Core/IApiService\";\r\nimport { IConfig } from \"../Model/IConfig\";\r\nimport Settings from \"../Model/Settings\";\r\nimport UploadError from \"../Extention/UploadError\";\r\nimport RawFile from \"../Model/RawFile\";\r\nimport SelectedFile from \"../Model/SelectedFile\";\r\nimport SimpleGuid from \"../Extention/SimpleGuid\";\r\nimport { IUserFileInfo } from \"../Model/IUserFileInfo\";\r\nimport { FileType } from \"../Model/FileType\";\r\nimport FileSizeHelper from \"../Extention/FileSizeHelper\";\r\nimport ChunkFile from \"../Model/ChunkFile\";\r\nimport { RunMode } from \"../Model/RunMode\";\r\nimport HashHelper from \"../Extention/HashHelper\";\r\nimport UploadHelper from \"../Extention/UploadHelper\";\r\nimport { IProgress } from \"../Model/IProgress\";\r\nimport { IOpenApi } from \"../Extention/IOpenApi\";\r\nimport { Layout } from \"../Model/Layout\";\r\n\r\n/**\r\n * 初级上传工具\r\n *\r\n * @author LCTR\r\n * @date 2022-09-22\r\n */\r\nexport default class NaiveUpload {\r\n    /**\r\n     *\r\n     * @param settings 设置\r\n     * @param apiService 接口服务\r\n     */\r\n    constructor(settings: Settings, apiService: IApiService) {\r\n        this.settings = this.reactive(settings);\r\n        this.apiService = apiService;\r\n        this.rawFileList = this.reactive([] as RawFile[]);\r\n        this.selectedFileList = this.reactive([] as SelectedFile[]);\r\n        this.selectedFileSortMap = this.reactive(new Map<number, number>());\r\n    }\r\n\r\n    /**\r\n     * 用于设置数据对象的双向绑定\r\n     */\r\n    private readonly reactive: any = reactive;\r\n\r\n    /**\r\n     * 设置\r\n     */\r\n    private readonly settings: Settings;\r\n\r\n    /**\r\n     * 接口服务\r\n     */\r\n    private readonly apiService: IApiService;\r\n\r\n    /**\r\n     * 文件上传配置\r\n     */\r\n    private config?: IConfig;\r\n\r\n    /**\r\n     * 源文件集合\r\n     */\r\n    private readonly rawFileList: RawFile[];\r\n\r\n    /**\r\n     * 选择的文件集合\r\n     */\r\n    private readonly selectedFileList: SelectedFile[];\r\n\r\n    /**\r\n     * 选择的文件排序值映射表\r\n     *\r\n     * <p>key：排序值，value：selectedFileList中的索引</p>\r\n     */\r\n    private readonly selectedFileSortMap: Map<number, number>;\r\n\r\n    /**\r\n     * 校验文件队列\r\n     * 数据项为this.SelectedFileList的索引\r\n     */\r\n    private checkQueue: number[] = [];\r\n\r\n    /**\r\n     * 当前正在校验中的文件数量\r\n     */\r\n    private checkHandlerCount = 0;\r\n\r\n    /**\r\n     * 上传文件队列\r\n     * 数据项为this.SelectedFileList的索引\r\n     */\r\n    private uploadQueue: number[] = [];\r\n\r\n    /**\r\n     * 暂停文件\r\n     * key：数据项为this.SelectedFileList的索引，value：{step：0：校验步骤、1：上传步骤，helper：实例，continue：是否已恢复}\r\n     */\r\n    private pausedQueue: Map<number, { step: number, helper?: HashHelper | UploadHelper, continue?: boolean }> = new Map<number, { step: number, helper?: HashHelper | UploadHelper, continue?: boolean }>();\r\n\r\n    /**\r\n     * 当前正在上传中的文件数量\r\n     */\r\n    private uploadHandlerCount = 0;\r\n\r\n    /**\r\n     * 追加文件后返回的文件令牌和selectedFileList索引映射表\r\n     */\r\n    private tokenWithIndex: Map<String, number> = new Map<String, number>();\r\n\r\n    /**\r\n     * 布局变更后执行\r\n     *\r\n     * @param layout 布局\r\n     */\r\n    private layoutChanged: ((layout: Layout) => void)[] = [];\r\n\r\n    /**\r\n     * 配置变更后执行\r\n     *\r\n     * @param config 配置\r\n     */\r\n    private configChanged: ((config: IConfig) => void)[] = [];\r\n\r\n    /**\r\n     * 选择的文件集合变更后执行\r\n     *\r\n     * @param files 当前的文件集合（已排序）\r\n     */\r\n    private selectedFileListChanged: ((files: SelectedFile[]) => void)[] = [];\r\n\r\n    /**\r\n     * 文件排序值映射表变更后执行\r\n     *\r\n     * @param sortMap 当前的文件排序值映射表\r\n     */\r\n    private selectedFileSortMapChanged: ((sortMap: Map<number, number>) => void)[] = [];\r\n\r\n    /**\r\n     * 用户文件信息集合变更后执行\r\n     *\r\n     * @param userFileInfoList 当前的用户文件信息集合（已排序）\r\n     */\r\n    private userFileInfoListChanged: ((userFileInfoList: IUserFileInfo[]) => void)[] = [];\r\n\r\n    /**\r\n     * 提示异常\r\n     *\r\n     * @param error 异常\r\n     */\r\n    private alertError: ((error: Error) => void)[] = [];\r\n\r\n    /**\r\n     * 文件校验前执行\r\n     *\r\n     * @param file 文件\r\n     * @returns 是否保留该文件\r\n     */\r\n    private beforeCheck?: (file: File) => Promise<boolean>;\r\n\r\n    /**\r\n     * 文件校验结束后执行\r\n     *\r\n     * @param rawFile 文件\r\n     */\r\n    private afterCheck?: (rawFile: RawFile) => Promise<void>;\r\n\r\n    /**\r\n     * 文件校验全部校验结束后执行\r\n     *\r\n     * @param rawFileList 文件集合\r\n     */\r\n    private afterCheckAll?: (rawFileList: RawFile[]) => Promise<void>;\r\n\r\n    /**\r\n     * 文件上传后执行\r\n     *\r\n     * @param rawFile 文件\r\n     */\r\n    private afterUpload?: (rawFile: RawFile) => Promise<void>;\r\n\r\n    /**\r\n     * 所有文件上传后执行\r\n     * <p>此方法将会异步执行</p>\r\n     *\r\n     * @param rawFileList 文件集合\r\n     */\r\n    private afterUploadAll?: (rawFileList: RawFile[]) => Promise<void>;\r\n\r\n    /**\r\n     * 发生异常后执行\r\n     * <p>此方法将会异步执行</p>\r\n     *\r\n     * @param error 异常\r\n     */\r\n    private handlerError?: (error: Error) => Promise<void>;\r\n\r\n    /**\r\n     * 更新文件上传配置\r\n     */\r\n    private updateConfig(this: NaiveUpload): Promise<void> {\r\n        return new Promise<void>((resolve, reject) => {\r\n            this.apiService.config(this.settings.configCode).then(config => {\r\n                this.config = this.reactive(config);\r\n                this.settings.debug ? console.debug('配置已变更:', Object.assign({}, this.config)) : !1;\r\n                resolve();\r\n            }).catch(e => {\r\n                reject(new UploadError('更新文件上传配置错误', e));\r\n            });\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 监听配置的变化\r\n     */\r\n    private watchSettings(this: NaiveUpload) {\r\n        //文件上传配置变更\r\n        watch(() => this.settings.configCode,\r\n            async (current, last) => {\r\n                if (current != last) {\r\n                    await this.updateConfig();\r\n                    this.configChanged?.forEach(x => x(this.config!));\r\n                }\r\n            });\r\n\r\n        //布局变更\r\n        watch(() => this.settings.layout,\r\n            async (current, last) => {\r\n                if (current != last)\r\n                    this.layoutChanged?.forEach(x => x(current));\r\n            });\r\n\r\n        //文件变更\r\n        watch(() => this.selectedFileList,\r\n            async (current, last) => {\r\n                this.selectedFileListChanged?.forEach(x => x(this.getSelectedFileList(true)));\r\n            },\r\n            { deep: true });\r\n\r\n        // //文件排序值映射表变更\r\n        // watch(() => this.selectedFileSortMap,\r\n        //     async (current, last) => {\r\n        //         console.warn(this.selectedFileSortMap);\r\n        //         this.selectedFileSortMapChanged?.forEach(x => x(this.getSelectedFileSortMap()));\r\n        //     },\r\n        //     { deep: true });\r\n    }\r\n\r\n    /**\r\n     * 文件排序值映射表变更\r\n     */\r\n    private selectedFileSortMapChangedTrigger() {\r\n        this.selectedFileSortMapChanged?.forEach(x => x(this.getSelectedFileSortMap()));\r\n    }\r\n\r\n    /**\r\n     * 用户文件信息集合变更后执行\r\n     */\r\n    private userFileInfoListChangedTrigger() {\r\n        this.userFileInfoListChanged?.forEach(x => x(this.getUserFileInfoList(true)));\r\n    }\r\n\r\n    /**\r\n     * 追加文件\r\n     *\r\n     * @param file\r\n     */\r\n    private appendFile(this: NaiveUpload, file: File) {\r\n        //将文件推送至处理队列，并生成token\r\n        let push = (file: File, newFile: SelectedFile) => {\r\n            const token = SimpleGuid.new();\r\n            let rawFile = new RawFile(file);\r\n            rawFile.name = newFile.name;\r\n            rawFile.extension = newFile.extension;\r\n            rawFile.configCode = this.config!.code;\r\n            rawFile.token = token;\r\n            this.rawFileList.push(rawFile);\r\n\r\n            newFile.rawIndex = this.rawFileList.length - 1;\r\n            newFile.token = token;\r\n\r\n            this.tokenWithIndex.set(token, this.selectedFileList.length);\r\n\r\n            this.selectedFileList.push(newFile);\r\n\r\n            this.selectedFileSortMap.set(this.selectedFileSortMap.size + 1, this.selectedFileList.length - 1);\r\n            this.selectedFileSortMapChangedTrigger();\r\n\r\n            this.handleFile(this.selectedFileList.length - 1);\r\n\r\n            this.settings.debug ? console.debug('已添加文件', Object.assign({}, rawFile)) : !1;\r\n        };\r\n\r\n        //是否已为重复的文件\r\n        if (this.selectedFileList.filter(x =>\r\n            !x.canceled\r\n            && this.rawFileList[x.rawIndex!].file?.name == file.name)\r\n            .length > 0) {\r\n            this.settings.debug ? console.debug('重复的文件', file) : !1;\r\n            return;\r\n        }\r\n\r\n        //判断文件数量是否已超过限制\r\n        if (this.limited()) {\r\n            this.throwError(new UploadError(`当前只允许上传${this.getConfig().upperLimit}个文件`));\r\n            return;\r\n        }\r\n\r\n        //获取文件后缀名\r\n        const extension = file.name.substring(file.name.lastIndexOf('.'));\r\n\r\n        //判断文件类型是否合法\r\n        if (this.config!.allowedTypeList.length !== 0) {\r\n            let flag = false;\r\n            for (const type of this.config!.allowedTypeList) {\r\n                if (type != null && type.length > 0 && ((type[0] === '.' && type.toLowerCase() === extension.toLowerCase()) || new RegExp(type.replace('/*', '//*'), 'gi').test(file.type))) {\r\n                    flag = true;\r\n                    break;\r\n                }\r\n            }\r\n            if (!flag) {\r\n                console.warn(extension, file.type);\r\n                this.throwError(new UploadError('文件类型不合法'));\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (this.config!.prohibitedTypeList.length !== 0) {\r\n            for (const type of this.config!.prohibitedTypeList) {\r\n                if (type != null && type.length > 0 && ((type[0] === '.' && type.toLowerCase() === extension.toLowerCase()) || new RegExp(type.replace('/*', '//*'), 'gi').test(file.type))) {\r\n                    console.warn(type, extension, file.type);\r\n                    this.throwError(new UploadError('文件类型不合法'));\r\n                    return;\r\n                }\r\n            }\r\n        }\r\n\r\n        //判断文件大小是否合法\r\n        if (this.config!.lowerSingleSize && this.config!.lowerSingleSize > file.size) {\r\n            this.throwError(new UploadError(`文件不可小于${FileSizeHelper.getSize(this.config!.lowerSingleSize)}`));\r\n            return;\r\n        }\r\n\r\n        if (this.config!.upperSingleSize && this.config!.upperSingleSize < file.size) {\r\n            this.throwError(new UploadError(`文件不可大于${FileSizeHelper.getSize(this.config!.upperSingleSize)}`));\r\n            return;\r\n        }\r\n\r\n        if (this.config!.upperTotalSize && this.config!.upperTotalSize < this.totalSize() + file.size) {\r\n            this.throwError(new UploadError(`所有文件的总大小不可大于${FileSizeHelper.getSize(this.config!.upperTotalSize)}`));\r\n            return;\r\n        }\r\n\r\n        let selectedFile = new SelectedFile(file);\r\n\r\n        //触发文件校验前执行的回调事件\r\n        if (this.beforeCheck) {\r\n            const before = this.beforeCheck(file);\r\n            if (before && before.then) {\r\n                before.then(flag => {\r\n                    if (flag)\r\n                        push(file, selectedFile);\r\n                });\r\n            }\r\n        } else\r\n            push(file, selectedFile);\r\n    }\r\n\r\n    /**\r\n     * 追加以前上传过的文件\r\n     *\r\n     * @param id\r\n     */\r\n    private appendUploadedFile(this: NaiveUpload, id: string): Promise<void> {\r\n        return new Promise<void>(async (resolve, reject) => {\r\n            let userFileInfo: IUserFileInfo;\r\n\r\n            try {\r\n                userFileInfo = await this.apiService.getUserFile(id);\r\n\r\n                const token = SimpleGuid.new();\r\n                let rawFile = new RawFile(null);\r\n                rawFile.size = parseInt(userFileInfo.bytes);\r\n                rawFile.name = userFileInfo.name;\r\n                rawFile.extension = userFileInfo.extension;\r\n                rawFile.configCode = this.config!.code;\r\n                rawFile.echo = true;\r\n                rawFile.token = token;\r\n                rawFile.userFileInfo = userFileInfo;\r\n                rawFile.objectURL = this.apiService.getUserFileBrowseUrl(userFileInfo.id);\r\n                this.rawFileList.push(rawFile);\r\n\r\n                let file = <File>{ name: `${userFileInfo.name}${userFileInfo.extension}` };\r\n                let selectedFile = new SelectedFile(file);\r\n                selectedFile.rawIndex = this.rawFileList.length - 1;\r\n                selectedFile.echo = true;\r\n                selectedFile.checked = true;\r\n                selectedFile.uploaded = true;\r\n                selectedFile.done = true;\r\n                selectedFile.canceled = false;\r\n                selectedFile.thumbnail = this.apiService.getUserFilePreviewUrl(userFileInfo.id, 100, 100);\r\n                selectedFile.fileType = userFileInfo.fileType;\r\n                selectedFile.size = userFileInfo.size;\r\n                selectedFile.token = token;\r\n\r\n                this.tokenWithIndex.set(token, this.selectedFileList.length);\r\n\r\n                this.selectedFileList.push(selectedFile);\r\n\r\n                this.selectedFileSortMap.set(this.selectedFileSortMap.size + 1, this.selectedFileList.length - 1);\r\n                this.selectedFileSortMapChangedTrigger();\r\n\r\n                this.settings.debug ? console.debug('已添加历史文件', id, Object.assign({}, rawFile), Object.assign({}, selectedFile)) : !1;\r\n\r\n                resolve();\r\n            } catch (e: any) {\r\n                reject(new UploadError('获取用户文件信息失败', e));\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 获取文件类型\r\n     *\r\n     * @param selectedFile\r\n     */\r\n    private getFileType(this: NaiveUpload, selectedFile: SelectedFile): Promise<void> {\r\n        return new Promise<void>(async (resolve) => {\r\n            let file: RawFile;\r\n            if (selectedFile.rawIndex == -1) {\r\n                file = <RawFile>{\r\n                    file: <File><unknown>{ type: null }\r\n                };\r\n            } else\r\n                file = this.getRawFile(selectedFile);\r\n\r\n            try {\r\n                selectedFile.fileType = file.file!.type === null\r\n                    || file.file!.type === ''\r\n                    || file.file!.type === 'application/octet-stream'\r\n                    ? await this.apiService.getFileTypeByExtension(selectedFile.extensionLower)\r\n                    : await this.apiService.getFileTypeByMIME(file.file!.type);\r\n            } catch (e) {\r\n                selectedFile.fileType = FileType.未知;\r\n            }\r\n\r\n            resolve();\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 检查图像\r\n     *\r\n     * @param {any} selectedFile\r\n     */\r\n    private checkImage(this: NaiveUpload, selectedFile: SelectedFile) {\r\n        if (selectedFile.fileType === FileType.未知) {\r\n            selectedFile.thumbnail = this.apiService.getUnknowFileTypeImageUrl();\r\n            return;\r\n        }\r\n\r\n        if (selectedFile.fileType !== FileType.图片)\r\n            return;\r\n\r\n        const objectURL = this.getRawFile(selectedFile).objectURL;\r\n        if (objectURL)\r\n            selectedFile.thumbnail = objectURL;\r\n    }\r\n\r\n    /**\r\n     * 获取原始文件\r\n     *\r\n     * @param selectedFile\r\n     */\r\n    getRawFile(this: NaiveUpload, selectedFile: SelectedFile) {\r\n        return this.rawFileList[selectedFile.rawIndex!];\r\n    }\r\n\r\n    /**\r\n     * 文件切片\r\n     *\r\n     * @param selectedFile\r\n     */\r\n    private getChunks(this: NaiveUpload, selectedFile: SelectedFile) {\r\n        let file = this.getRawFile(selectedFile);\r\n        if (file.size > this.settings.chunkSize) {\r\n            file.needSection = true;\r\n            file.specs = this.settings.chunkSize;\r\n        } else\r\n            return;\r\n\r\n        let count = 0;\r\n        while (count < file.size) {\r\n            //切片索引添加至队列\r\n            file.chunkIndexQueue.push(file.chunks.length);\r\n\r\n            file.chunks.push(new ChunkFile(file.chunks.length, file.file!.slice(count, count + this.settings.chunkSize)));\r\n\r\n            count += this.settings.chunkSize;\r\n        }\r\n\r\n        this.settings.debug ? console.debug('文件已切片处理', Object.assign({}, file)) : !1;\r\n    }\r\n\r\n    /**\r\n     * 处理文件\r\n     *\r\n     * @param selectedFileIndex 索引\r\n     */\r\n    private handleFile(this: NaiveUpload, selectedFileIndex: number) {\r\n        const selectedFile = this.selectedFileList[selectedFileIndex];\r\n\r\n        //获取文件类型对应的预览图地址\r\n        selectedFile.thumbnail = this.apiService.getFileTypeImageUrl(selectedFile.extensionLower);\r\n\r\n        //获取文件类型并更新预览地址为图片的预览地址\r\n        this.getFileType(selectedFile).then(() => {\r\n            this.checkImage(selectedFile);\r\n        });\r\n\r\n        //获取文件大小的描述信息\r\n        selectedFile.size = FileSizeHelper.getSize(this.getRawFile(selectedFile).size);\r\n\r\n        //如果启用分片上传，则先将文件进行切片处理\r\n        if (this.settings.enableChunk)\r\n            this.getChunks(selectedFile);\r\n\r\n        //推送至md5校验队列\r\n        this.pushToCheckQueue(selectedFileIndex);\r\n    }\r\n\r\n    /**\r\n     * 推送至校验队列\r\n     *\r\n     * @param selectedFileIndex\r\n     */\r\n    private pushToCheckQueue(this: NaiveUpload, selectedFileIndex: number) {\r\n        this.checkQueue.push(selectedFileIndex);\r\n\r\n        if (this.settings.runMode === RunMode.全自动\r\n            || this.settings.runMode === RunMode.半自动)\r\n            this.checkMD5();\r\n    }\r\n\r\n    /**\r\n     * 推送至上传队列\r\n     *\r\n     * @param selectedFileIndex\r\n     */\r\n    private pushToUploadQueue(this: NaiveUpload, selectedFileIndex: number) {\r\n        this.uploadQueue.push(selectedFileIndex);\r\n\r\n        if (this.settings.runMode == RunMode.全自动)\r\n            this.upload();\r\n    }\r\n\r\n    /**\r\n     * 开始校验MD5\r\n     */\r\n    private async checkMD5(this: NaiveUpload) {\r\n        if (this.checkHandlerCount >= this.settings.concurrentFile || this.checkQueue.length === 0) {\r\n            this.checkQueue.length != 0 && this.settings.debug ? console.debug(`NaiveUpload 文件校验 已达到最大并发数：${this.settings.concurrentFile}，当前队列长度：${this.checkQueue.length}`) : !1;\r\n\r\n            //当前正在校验中的文件已达上限或全部文件都已校验结束，此方法将会直接结束\r\n            if (this.checkHandlerCount == 0 && this.checkQueue.length === 0 && this.afterCheckAll) {\r\n                //触发文件校验全部校验结束后执行的回调事件\r\n                if (this.afterCheckAll)\r\n                    await this.afterCheckAll(this.rawFileList);\r\n            }\r\n            return;\r\n        }\r\n\r\n        this.checkHandlerCount++;\r\n\r\n        /**\r\n         * 校验下一个文件\r\n         */\r\n        const next = () => {\r\n            this.checkHandlerCount--;\r\n\r\n            if (this.afterCheck) {\r\n                //触发单个文件校验结束后执行的回调事件\r\n                const after = this.afterCheck(rawFile);\r\n                if (after && after.then) {\r\n                    after.then(() => {\r\n                        this.checkMD5();\r\n                    });\r\n                    return;\r\n                }\r\n            }\r\n\r\n            this.settings.debug ? console.debug('校验下一个文件') : !1;\r\n\r\n            this.checkMD5();\r\n        };\r\n\r\n        /**\r\n         * 暂停\r\n         *\r\n         * @param helper 实例\r\n         */\r\n        const pause = (helper?: HashHelper) => {\r\n            if (this.pausedQueue.has(selectedFileIndex!))\r\n                this.pausedQueue.get(selectedFileIndex!)!.continue = false;\r\n            else\r\n                this.pausedQueue.set(selectedFileIndex!, { step: 0, helper: helper });\r\n            helper && helper.pause();\r\n\r\n            helper && this.settings.debug ? console.debug('HashHelper Instance 已暂停', Object.assign({}, hashHelper)) : !1;\r\n\r\n            //保存暂停前的进度\r\n            selectedFile.virtualPercentBeforPaused = selectedFile.virtualPercent;\r\n            selectedFile.percentBeforPaused = selectedFile.percent;\r\n\r\n            this.settings.debug ? console.debug('暂停校验文件', Object.assign({}, rawFile)) : !1;\r\n\r\n            next();\r\n        }\r\n\r\n        /**\r\n         * 恢复\r\n         *\r\n         * @param helper 实例\r\n         */\r\n        const continue_ = async (helper: HashHelper) => {\r\n            await helper.continue();\r\n\r\n            this.settings.debug ? console.debug('HashHelper Instance 已恢复', Object.assign({}, hashHelper)) : !1;\r\n\r\n            this.settings.debug ? console.debug('恢复校验文件', Object.assign({}, rawFile)) : !1;\r\n        }\r\n\r\n        /**\r\n         * 取消\r\n         */\r\n        const cancel = (helper?: HashHelper) => {\r\n            helper && helper.cancel();\r\n\r\n            helper && this.settings.debug ? console.debug('HashHelper Instance 已取消', Object.assign({}, hashHelper)) : !1;\r\n\r\n            this.settings.debug ? console.debug('取消校验文件', Object.assign({}, rawFile)) : !1;\r\n\r\n            next();\r\n        }\r\n\r\n        //获取并移除列首的文件索引\r\n        const selectedFileIndex = this.checkQueue.shift();\r\n        const selectedFile = this.selectedFileList[selectedFileIndex!];\r\n        const rawFile = this.getRawFile(selectedFile);\r\n\r\n        //如果文件已被删除则直接处理下一个\r\n        if (selectedFile.canceled) {\r\n            cancel();\r\n            return;\r\n        }\r\n\r\n        //如果文件已被暂停则取消校验并推送至暂停队列\r\n        if (selectedFile.paused) {\r\n            pause();\r\n            next();\r\n            return;\r\n        }\r\n\r\n        selectedFile.checking = true;\r\n\r\n        //获取md5校验帮助类实例\r\n        let hashHelper: HashHelper | null = null;\r\n        if (this.pausedQueue.has(selectedFileIndex!)) {\r\n            //获取暂停前的实例\r\n            hashHelper = this.pausedQueue.get(selectedFileIndex!)!.helper as HashHelper;\r\n            //从暂停集合中删除\r\n            this.pausedQueue.delete(selectedFileIndex!);\r\n\r\n            if (hashHelper) {\r\n                this.settings.debug ? console.debug('HashHelper Instance 已获取（暂停前的实例）', Object.assign({}, hashHelper)) : !1;\r\n\r\n                //恢复\r\n                await continue_(hashHelper);\r\n\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (hashHelper == null) {\r\n            hashHelper = await HashHelper.getInstance(this.settings.concurrentChunkFile, this.settings.enableWorker, this.settings.debug);\r\n            this.settings.debug ? console.debug('HashHelper Instance 已创建', Object.assign({}, hashHelper)) : !1;\r\n        }\r\n\r\n        /**\r\n         * 关闭\r\n         */\r\n        const close = () => {\r\n            hashHelper!.close();\r\n\r\n            this.settings.debug ? console.debug('HashHelper Instance 已关闭', Object.assign({}, hashHelper)) : !1;\r\n        }\r\n\r\n        try {\r\n            this.settings.debug ? console.debug('开始校验文件', Object.assign({}, rawFile)) : !1;\r\n\r\n            await hashHelper.handler(rawFile, (progress: IProgress) => {\r\n                NaiveUpload.calcPercent(selectedFile, progress);\r\n\r\n                //如果文件已被删除则取消校验\r\n                if (selectedFile.canceled)\r\n                    cancel();\r\n\r\n                //如果文件已被暂停则挂起校验操作并推送至暂停队列等待恢复通知\r\n                if (selectedFile.paused) {\r\n                    pause(hashHelper!);\r\n                }\r\n            });\r\n\r\n            if (selectedFile.canceled)\r\n                return;\r\n\r\n            selectedFile.virtualPercent = 100;\r\n            selectedFile.percent = 100;\r\n            selectedFile.checking = false;\r\n            selectedFile.checked = true;\r\n\r\n            this.settings.debug ? console.debug('文件校验结束', Object.assign({}, rawFile)) : !1;\r\n\r\n            //推送至上传队列\r\n            this.pushToUploadQueue(selectedFileIndex!);\r\n        } catch (e: any) {\r\n            const error = new UploadError('文件校验失败.', e);\r\n            this.checkError(selectedFileIndex!, `${error.message} ${e.message}`, true, error);\r\n        }\r\n\r\n        close();\r\n\r\n        next();\r\n    }\r\n\r\n    /**\r\n     * 开始上传已经校验过了的文件\r\n     */\r\n    private async upload(this: NaiveUpload) {\r\n        if (this.config!.lowerTotalSize && this.config!.lowerTotalSize > this.totalSize()) {\r\n            this.throwError(new UploadError(`所有文件的总大小不可小于${FileSizeHelper.getSize(this.config!.lowerTotalSize)}`));\r\n            return;\r\n        }\r\n\r\n        //如果当前正在上传中的文件已达上限，则此方法将会直接结束\r\n        if (this.uploadHandlerCount >= this.settings.concurrentFile) {\r\n            this.settings.debug ? console.debug(`NaiveUpload 文件上传 已达到最大并发数：${this.settings.concurrentFile}，当前队列长度：${this.uploadQueue.length}`) : !1;\r\n            return;\r\n        }\r\n\r\n        if (this.uploadQueue.length === 0) {\r\n            //触发文件上传全部结束后执行的回调事件\r\n            if (this.checkHandlerCount === 0 && this.uploadHandlerCount === 0 && this.afterUploadAll)\r\n                this.afterUploadAll(this.getRawFileList(true));\r\n            return;\r\n        }\r\n\r\n        this.uploadHandlerCount++;\r\n\r\n        /**\r\n         * 上传下一个文件\r\n         */\r\n        const next = (done: boolean) => {\r\n            this.uploadHandlerCount--;\r\n\r\n            if (done && this.afterUpload) {\r\n                //触发单个文件上传结束后执行的回调事件\r\n                const after = this.afterUpload(rawFile);\r\n                if (after && after.then) {\r\n                    after.then(() => {\r\n                        this.upload();\r\n                        return;\r\n                    });\r\n                }\r\n            }\r\n\r\n            this.settings.debug ? console.debug('上传下一个文件') : !1;\r\n\r\n            this.upload();\r\n        };\r\n\r\n        /**\r\n         * 暂停\r\n         *\r\n         * @param helper 实例\r\n         */\r\n        const pause = (helper?: UploadHelper) => {\r\n            if (this.pausedQueue.has(selectedFileIndex!))\r\n                this.pausedQueue.get(selectedFileIndex!)!.continue = false;\r\n            else\r\n                this.pausedQueue.set(selectedFileIndex!, { step: 1, helper: helper });\r\n\r\n            helper && helper.pause();\r\n\r\n            helper && this.settings.debug ? console.debug('UploadHelper Instance 已暂停', Object.assign({}, uploadHelper)) : !1;\r\n\r\n            //保存暂停前的进度\r\n            selectedFile.virtualPercentBeforPaused = selectedFile.virtualPercent;\r\n            selectedFile.percentBeforPaused = selectedFile.percent;\r\n\r\n            this.settings.debug ? console.debug('暂停上传文件', Object.assign({}, rawFile)) : !1;\r\n\r\n            next(false);\r\n        }\r\n\r\n        /**\r\n         * 恢复\r\n         *\r\n         * @param helper 实例\r\n         */\r\n        const continue_ = async (helper: UploadHelper) => {\r\n            await helper.continue();\r\n\r\n            this.settings.debug ? console.debug('UploadHelper Instance 已恢复', Object.assign({}, uploadHelper)) : !1;\r\n\r\n            this.settings.debug ? console.debug('恢复上传文件', Object.assign({}, rawFile)) : !1;\r\n        }\r\n\r\n        /**\r\n         * 取消\r\n         */\r\n        const cancel = (helper?: UploadHelper) => {\r\n            helper && helper.cancel();\r\n\r\n            helper && this.settings.debug ? console.debug('UploadHelper Instance 已取消', Object.assign({}, uploadHelper)) : !1;\r\n\r\n            this.settings.debug ? console.debug('取消上传文件', Object.assign({}, rawFile)) : !1;\r\n\r\n            next(false);\r\n        }\r\n\r\n        //获取并移除列首的文件索引\r\n        const selectedFileIndex = this.uploadQueue.shift();\r\n        const selectedFile = this.selectedFileList[selectedFileIndex!];\r\n        const rawFile = this.getRawFile(selectedFile);\r\n\r\n        //如果文件已被删除则直接处理下一个\r\n        if (selectedFile.canceled) {\r\n            cancel();\r\n            return;\r\n        }\r\n\r\n        //如果文件已被暂停则取消校验并推送至暂停队列\r\n        if (selectedFile.paused) {\r\n            pause();\r\n            return;\r\n        }\r\n\r\n        selectedFile.uploading = true;\r\n        selectedFile.virtualPercent = 0;\r\n        selectedFile.percent = 0;\r\n\r\n        //获取文件上传帮助类实例\r\n        let uploadHelper: UploadHelper | null = null;\r\n        if (this.pausedQueue.has(selectedFileIndex!)) {\r\n            //获取暂停前的实例\r\n            uploadHelper = this.pausedQueue.get(selectedFileIndex!)!.helper as UploadHelper;\r\n            //从暂停集合中删除\r\n            this.pausedQueue.delete(selectedFileIndex!);\r\n\r\n            if (uploadHelper) {\r\n                this.settings.debug ? console.debug('UploadHelper Instance 已获取（暂停前的实例）', Object.assign({}, uploadHelper)) : !1;\r\n\r\n                //恢复\r\n                await continue_(uploadHelper);\r\n\r\n                return;\r\n            }\r\n        }\r\n\r\n        if (uploadHelper == null) {\r\n            uploadHelper = await UploadHelper.getInstance(this.settings.concurrentChunkFile, this.settings.enableWorker, this.apiService, this.settings.debug);\r\n            this.settings.debug ? console.debug('UploadHelper Instance 已创建', Object.assign({}, uploadHelper)) : !1;\r\n        }\r\n\r\n        /**\r\n         * 关闭\r\n         */\r\n        const close = () => {\r\n            uploadHelper!.close();\r\n\r\n            this.settings.debug ? console.debug('UploadHelper Instance 已关闭', Object.assign({}, uploadHelper)) : !1;\r\n        }\r\n\r\n        try {\r\n            this.settings.debug ? console.debug('开始上传文件', Object.assign({}, rawFile)) : !1;\r\n\r\n            await uploadHelper.handler(rawFile, (progress: IProgress) => {\r\n                NaiveUpload.calcPercent(selectedFile, progress);\r\n\r\n                //如果文件已被删除则取消上传\r\n                if (selectedFile.canceled)\r\n                    cancel();\r\n\r\n                //如果文件已被暂停则挂起上传操作并推送至暂停队列等待恢复通知\r\n                if (selectedFile.paused && this.rawFileList[selectedFile.rawIndex!].needSection) {\r\n                    pause(uploadHelper!);\r\n                }\r\n            });\r\n\r\n            if (selectedFile.canceled)\r\n                return;\r\n\r\n            selectedFile.name = rawFile.userFileInfo!.name;\r\n            selectedFile.extension = rawFile.userFileInfo!.extension;\r\n            selectedFile.extensionLower = rawFile.userFileInfo!.extension?.toLowerCase();\r\n            selectedFile.size = rawFile.userFileInfo!.size;\r\n            selectedFile.fileType = rawFile.userFileInfo!.fileType;\r\n            selectedFile.virtualPercent = 100;\r\n            selectedFile.percent = 100;\r\n            selectedFile.uploading = false;\r\n            selectedFile.uploaded = true;\r\n            selectedFile.done = true;\r\n\r\n            this.settings.debug ? console.debug('文件上传结束', Object.assign({}, rawFile)) : !1;\r\n\r\n            this.checkImage(selectedFile);\r\n\r\n            this.userFileInfoListChangedTrigger();\r\n        } catch (e: any) {\r\n            const error = new UploadError('文件上传失败.', e);\r\n            this.uploadError(selectedFileIndex!, `${error.message} ${e.message}`, true, error);\r\n        }\r\n\r\n        close();\r\n\r\n        next(true);\r\n    }\r\n\r\n    /**\r\n     * 计算进度\r\n     *\r\n     * @param selectedFile 文件\r\n     * @param progress 进度\r\n     */\r\n    private static calcPercent(selectedFile: SelectedFile, progress: IProgress) {\r\n        const virtualPercent = parseFloat((progress.preLoaded / progress.total * 100).toFixed(2));\r\n        const percent = parseFloat((progress.loaded / progress.total * 100).toFixed(2));\r\n        if (selectedFile.virtualPercentBeforPaused < virtualPercent)\r\n            selectedFile.virtualPercent = virtualPercent;\r\n        if (selectedFile.percentBeforPaused < percent)\r\n            selectedFile.percent = percent;\r\n    }\r\n\r\n    /**\r\n     * 抛出异常\r\n     *\r\n     * @param error\r\n     */\r\n    private throwError(this: NaiveUpload, error: Error) {\r\n        this.settings.debug ? console.debug('发生异常', error) : !1;\r\n        this.alertError.forEach(x => x(error));\r\n        if (this.handlerError)\r\n            this.handlerError(error);\r\n    }\r\n\r\n    /**\r\n     * 异常\r\n     *\r\n     * @param selectedFileIndex\r\n     * @param message 异常信息\r\n     * @param retry 是否允许重试\r\n     * @param done 回调\r\n     */\r\n    private error(this: NaiveUpload,\r\n        selectedFileIndex: number,\r\n        message: string,\r\n        retry: boolean,\r\n        done: (selectedFileIndex: number) => void | null) {\r\n        const selectedFile = this.selectedFileList[selectedFileIndex];\r\n\r\n        if (!retry || selectedFile.reTry - 1 >= this.settings.retry) {\r\n            selectedFile.error = true;\r\n            selectedFile.errorMessage = message;\r\n            return;\r\n        }\r\n\r\n        //等待重试\r\n        selectedFile.reTry++;\r\n\r\n        setTimeout(() => {\r\n            done && done(selectedFileIndex);\r\n        }, 1500);\r\n    }\r\n\r\n    /**\r\n     * 校验时异常\r\n     *\r\n     * @param selectedFileIndex\r\n     * @param message 说明\r\n     * @param retry 是否允许重试\r\n     * @param e 异常\r\n     */\r\n    private checkError(this: NaiveUpload,\r\n        selectedFileIndex: number,\r\n        message: string,\r\n        retry: boolean,\r\n        e?: Error) {\r\n        e && UploadError.consoleWrite(e);\r\n\r\n        const selectedFile = this.selectedFileList[selectedFileIndex];\r\n        selectedFile.checking = false;\r\n        selectedFile.uploading = false;\r\n        this.error(selectedFileIndex, message, retry, (_selectedFileIndex) => {\r\n            this.pushToCheckQueue(_selectedFileIndex);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 上传时异常\r\n     *\r\n     * @param selectedFileIndex\r\n     * @param message 说明\r\n     * @param retry 是否允许重试\r\n     * @param e 异常\r\n     */\r\n    private uploadError(this: NaiveUpload,\r\n        selectedFileIndex: number,\r\n        message: string,\r\n        retry: boolean,\r\n        e?: Error) {\r\n        e && UploadError.consoleWrite(e);\r\n\r\n        const selectedFile = this.selectedFileList[selectedFileIndex];\r\n        selectedFile.uploading = false;\r\n        this.error(selectedFileIndex, message, retry, (_selectedFileIndex) => {\r\n            this.pushToUploadQueue(_selectedFileIndex);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 文件重命名\r\n     *\r\n     * @param selectedFile\r\n     * @param rename 文件重命名\r\n     */\r\n    private async renameByIndex(this: NaiveUpload,\r\n        selectedFile: SelectedFile,\r\n        rename: string): Promise<void> {\r\n        return new Promise<void>((resolve) => {\r\n            let rawFile = this.getRawFile(selectedFile);\r\n\r\n            const done = (success: boolean) => {\r\n                if (success) {\r\n                    selectedFile.name = rename;\r\n                    rawFile.name = selectedFile.name;\r\n                    if (selectedFile.uploaded)\r\n                        rawFile.userFileInfo!.name = selectedFile.name;\r\n                }\r\n\r\n                resolve();\r\n            }\r\n\r\n            if (selectedFile.uploaded) {\r\n                this.apiService.rename(rawFile.userFileInfo!.id, rename).then(() => {\r\n                    done(true);\r\n                }).catch(e => {\r\n                    this.handlerError && this.handlerError(new UploadError(`文件重命名失败：${e.message}`, e));\r\n                    done(false);\r\n                });\r\n            } else\r\n                done(true);\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 恢复处理\r\n     *\r\n     * @param index\r\n     */\r\n    private continueByIndex(this: NaiveUpload, index: number) {\r\n        //取消暂停状态\r\n        this.selectedFileList[index].paused = false;\r\n\r\n        if (!this.pausedQueue.has(index) || this.pausedQueue.get(index)!.continue)\r\n            return;\r\n\r\n        //判断文件暂停时正处于哪一步，并重新添加至队列\r\n        const data = this.pausedQueue.get(index)!;\r\n        switch (data.step) {\r\n            case 0:\r\n                this.checkQueue.push(index);\r\n                break;\r\n            case 1:\r\n                this.uploadQueue.push(index);\r\n                break;\r\n            default:\r\n                return;\r\n        }\r\n\r\n        //已恢复\r\n        data.continue = true;\r\n    }\r\n\r\n    /**\r\n     * 获取实例\r\n     *\r\n     * @param settings 设置\r\n     * @param apiService 接口服务\r\n     */\r\n    public static async getInstance(settings: Settings, apiService: IApiService): Promise<NaiveUpload> {\r\n        return new Promise<NaiveUpload>(async (resolve, reject) => {\r\n            try {\r\n                let upload = new NaiveUpload(settings, apiService);\r\n                upload.watchSettings();\r\n                await upload.updateConfig();\r\n                resolve(upload);\r\n            } catch (e: any) {\r\n                reject(new UploadError('获取上传工具实例时发生异常', e));\r\n            }\r\n        });\r\n    }\r\n\r\n    /**\r\n     * 获取设置\r\n     */\r\n    public getSettings(this: NaiveUpload): Settings {\r\n        return this.settings;\r\n    }\r\n\r\n    /**\r\n     * 获取文件上传配置\r\n     */\r\n    public getConfig(this: NaiveUpload): IConfig {\r\n        return this.config!;\r\n    }\r\n\r\n    /**\r\n     * 校验队列中的文件\r\n     */\r\n    public checkNow(this: NaiveUpload): void {\r\n        this.checkMD5();\r\n    }\r\n\r\n    /**\r\n     * 上传队列中的文件\r\n     */\r\n    public uploadNow(this: NaiveUpload): void {\r\n        this.upload();\r\n    }\r\n\r\n    /**\r\n     * 暂停\r\n     *\r\n     * @param token 追加文件后返回的文件令牌，未设置此参数时暂停全部\r\n     */\r\n    public pause(this: NaiveUpload, token?: string): void {\r\n        if (token) {\r\n            const index = this.tokenWithIndex.get(token)!;\r\n            if (index == -1)\r\n                return;\r\n\r\n            if (!this.selectedFileList[index].done)\r\n                this.selectedFileList[index].paused = true;\r\n        } else\r\n            for (let file of this.selectedFileList) {\r\n                if (!file.done)\r\n                    file.paused = true;\r\n            }\r\n    }\r\n\r\n    /**\r\n     * 恢复\r\n     *\r\n     * @param token 追加文件后返回的文件令牌，未设置此参数时恢复全部\r\n     */\r\n    public continue(this: NaiveUpload, token?: string): void {\r\n        if (token) {\r\n            const index = this.tokenWithIndex.get(token)!;\r\n            if (index == -1)\r\n                return;\r\n\r\n            this.continueByIndex(index);\r\n        } else {\r\n            for (let index = 0; index < this.selectedFileList.length; index++) {\r\n                this.continueByIndex(index);\r\n            }\r\n        }\r\n\r\n        //开始处理\r\n        this.checkNow();\r\n        this.uploadNow();\r\n    }\r\n\r\n    /**\r\n     * 删除\r\n     *\r\n     * @param token 追加文件后返回的文件令牌\r\n     */\r\n    public remove(this: NaiveUpload, token: string) {\r\n        const index = this.tokenWithIndex.get(token)!;\r\n        if (index == -1)\r\n            return;\r\n        this.selectedFileList[index].canceled = true;\r\n\r\n        this.userFileInfoListChangedTrigger();\r\n    }\r\n\r\n    /**\r\n     * 清空\r\n     */\r\n    public clean(this: NaiveUpload) {\r\n        for (let file of this.selectedFileList) {\r\n            file.canceled = true;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 重置\r\n     */\r\n    public reset(this: NaiveUpload) {\r\n        this.checkQueue.length = 0;\r\n        this.uploadQueue.length = 0;\r\n        this.rawFileList.length = 0;\r\n        this.selectedFileList.length = 0;\r\n        this.tokenWithIndex.clear();\r\n    }\r\n\r\n    /**\r\n     * 获取开放的接口\r\n     */\r\n    public getOpenApi(this: NaiveUpload): IOpenApi {\r\n        return {\r\n            startCheck: () => {\r\n                for (let i = 0; i < this.settings.concurrentFile; i++)\r\n                    this.checkNow();\r\n            },\r\n\r\n            startUpload: () => {\r\n                for (let i = 0; i < this.settings.concurrentFile; i++)\r\n                    this.uploadNow();\r\n            },\r\n\r\n            pause: (token?: string) => {\r\n                this.pause(token);\r\n            },\r\n\r\n            continue: (token?: string) => {\r\n                this.continue(token);\r\n            },\r\n\r\n            remove: (token: string) => {\r\n                this.remove(token);\r\n            },\r\n\r\n            clean: () => {\r\n                this.clean();\r\n            },\r\n\r\n            finished: (): boolean => {\r\n                return this.checkQueue.length === 0 && this.uploadQueue.length === 0 && this.pausedQueue.size === 0;\r\n            },\r\n\r\n            getUserFileInfoList: (): IUserFileInfo[] => {\r\n                return this.getUserFileInfoList(true);\r\n            }\r\n        } as IOpenApi;\r\n    }\r\n\r\n    /**\r\n     * 文件重命名\r\n     *\r\n     * @param token  追加文件后返回的文件令牌\r\n     * @param rename 文件重命名\r\n     */\r\n    public async rename(this: NaiveUpload,\r\n        token: string,\r\n        rename: string): Promise<void> {\r\n        const index = this.tokenWithIndex.get(token)!;\r\n        if (index == -1)\r\n            throw new UploadError('文件已被移除');\r\n\r\n        let selectedFile = this.selectedFileList[index];\r\n\r\n        return this.renameByIndex(selectedFile, rename);\r\n    }\r\n\r\n    /**\r\n     * 获取下载地址\r\n     *\r\n     * @param selectedFile 选择的文件\r\n     * @return 下载地址\r\n     */\r\n    public getDownloadUrl(this: NaiveUpload, selectedFile: SelectedFile): string | null {\r\n        const rawFile = this.rawFileList[selectedFile.rawIndex!];\r\n        return rawFile.file ? rawFile.objectURL ?? null : this.apiService.getDownloadUrl(rawFile.userFileInfo!.id, selectedFile.name);\r\n    }\r\n\r\n    /**\r\n     * 选择的文件列表是否有有效的数据\r\n     */\r\n    public anyFile(this: NaiveUpload): boolean {\r\n        return this.selectedFileList.filter(data => !data.canceled).length !== 0;\r\n    }\r\n\r\n    /**\r\n     * 获取选择文件时要显示的警告信息\r\n     */\r\n    public getSelectFileAlarmInfo(this: NaiveUpload): string {\r\n        if (!this.config!.upperLimit)\r\n            return '';\r\n\r\n        return this.selectedFileList.length < this.config!.upperLimit ? `还可添加个${this.config!.upperLimit - this.selectedFileList.length}文件` : `文件数量已达上限`;\r\n    }\r\n\r\n    /**\r\n     * 获取文件选择框类名\r\n     */\r\n    public getSelectCLass(this: NaiveUpload): string {\r\n        return this.limited() ? 'item-limited' : '';\r\n    }\r\n\r\n    /**\r\n     * 获取全部允许的类型\r\n     */\r\n    public getAllowedTypes(this: NaiveUpload): string {\r\n        return this.config!.allowedTypeList.join(', ');\r\n    }\r\n\r\n    /**\r\n     * 是否已达上限\r\n     *\r\n     * @return true: 已达上限\r\n     */\r\n    public limited(this: NaiveUpload): boolean {\r\n        return !!this.config!.upperLimit && this.selectedFileList.filter(data => !data.canceled).length >= this.config!.upperLimit;\r\n    }\r\n\r\n    /**\r\n     * 当前文件总大小\r\n     *\r\n     * @return size: 字节数\r\n     */\r\n    public totalSize(this: NaiveUpload): number {\r\n        let size = 0;\r\n        for (const selectedFile of this.selectedFileList) {\r\n            if (!selectedFile.canceled)\r\n                size += this.rawFileList[selectedFile.rawIndex!].size;\r\n        }\r\n        return size;\r\n    }\r\n\r\n    /**\r\n     * 追加文件\r\n     *\r\n     * @param file 文件\r\n     */\r\n    public append(this: NaiveUpload, file: File) {\r\n        this.appendFile(file);\r\n    }\r\n\r\n    /**\r\n     * 追加以前上传过的文件\r\n     *\r\n     * @param id 标识\r\n     */\r\n    public async appendById(this: NaiveUpload, id: string): Promise<void> {\r\n        return this.appendUploadedFile(id);\r\n    }\r\n\r\n    /**\r\n     * 更改排序值\r\n     *\r\n     * @param currentIndex 当前排序值\r\n     * @param targetIndex 目标排序值\r\n     */\r\n    public changeSort(this: NaiveUpload, currentIndex: number, targetIndex: number) {\r\n        if (currentIndex == targetIndex)\r\n            return;\r\n\r\n        const current = this.selectedFileSortMap.get(currentIndex)!;\r\n\r\n        if (currentIndex > targetIndex) {\r\n            for (let i = currentIndex; i > targetIndex; i--) {\r\n                setInterval(() => {\r\n\r\n                }, 100);\r\n                this.selectedFileSortMap.set(i, this.selectedFileSortMap.get(i - 1)!);\r\n            }\r\n        } else {\r\n            for (let i = currentIndex; i < targetIndex; i++) {\r\n                this.selectedFileSortMap.set(i, this.selectedFileSortMap.get(i + 1)!);\r\n            }\r\n        }\r\n\r\n        this.selectedFileSortMap.set(targetIndex, current);\r\n        this.selectedFileSortMapChangedTrigger();\r\n    }\r\n\r\n    /**\r\n     * 注册布局变更后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public registerLayoutChanged(this: NaiveUpload, even: (layout: Layout) => void) {\r\n        this.layoutChanged.push(even);\r\n    }\r\n\r\n    /**\r\n     * 注册配置变更后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public registerConfigChanged(this: NaiveUpload, even: (config: IConfig) => void) {\r\n        this.configChanged.push(even);\r\n    }\r\n\r\n    /**\r\n     * 注册选择的文件集合变更后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public registerSelectedFileListChanged(this: NaiveUpload, even: (files: SelectedFile[]) => void) {\r\n        this.selectedFileListChanged.push(even);\r\n    }\r\n\r\n    /**\r\n     * 注册选择的文件排序值映射表变更后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public registerSelectedFileSortMapChanged(this: NaiveUpload, even: (sortMap: Map<number, number>) => void) {\r\n        this.selectedFileSortMapChanged.push(even);\r\n    }\r\n\r\n    /**\r\n     * 注册用户文件信息集合变更后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public registerUserFileInfoListChanged(this: NaiveUpload, even: (userFileInfoList: IUserFileInfo[]) => void) {\r\n        this.userFileInfoListChanged.push(even);\r\n    }\r\n\r\n    /**\r\n     * 注册提示异常的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public registerAlertError(this: NaiveUpload, even: (error: Error) => void) {\r\n        this.alertError.push(even);\r\n    }\r\n\r\n    /**\r\n     * 设置文件校验前执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public setupBeforeCheck(this: NaiveUpload, even: (file: File) => Promise<boolean>) {\r\n        this.beforeCheck = even;\r\n    }\r\n\r\n    /**\r\n     * 设置文件校验结束后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public setupAfterCheck(this: NaiveUpload, even: (rawFile: RawFile) => Promise<void>) {\r\n        this.afterCheck = even;\r\n    }\r\n\r\n    /**\r\n     * 设置文件校验全部校验结束后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public setupAfterCheckAll(this: NaiveUpload, even: (rawFileList: RawFile[]) => Promise<void>) {\r\n        this.afterCheckAll = even;\r\n    }\r\n\r\n    /**\r\n     * 设置文件上传后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public setupAfterUpload(this: NaiveUpload, even: (rawFile: RawFile) => Promise<void>) {\r\n        this.afterUpload = even;\r\n    }\r\n\r\n    /**\r\n     * 设置所有文件上传后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public setupAfterUploadAll(this: NaiveUpload, even: (rawFileList: RawFile[]) => Promise<void>) {\r\n        this.afterUploadAll = even;\r\n    }\r\n\r\n    /**\r\n     * 设置发生异常后执行的函数\r\n     *\r\n     * @param even\r\n     */\r\n    public setupHandlerError(this: NaiveUpload, even: (error: Error) => Promise<void>) {\r\n        this.handlerError = even;\r\n    }\r\n\r\n    /**\r\n     * 获取当前选择的文件数量\r\n     */\r\n    public getSelectedFileCount(this: NaiveUpload): number {\r\n        return this.selectedFileList.filter(x => !x.canceled).length;\r\n    }\r\n\r\n    /**\r\n     * 获取当前选择的文件排序值映射表\r\n     */\r\n    public getSelectedFileSortMap(this: NaiveUpload): Map<number, number> {\r\n        return this.selectedFileSortMap;\r\n    }\r\n\r\n    /**\r\n     * 获取当前所有选择的文件集合\r\n     *\r\n     * @param sort 是否需要排序\r\n     */\r\n    public getSelectedFileList(this: NaiveUpload, sort: boolean): SelectedFile[] {\r\n        if (!sort)\r\n            return this.selectedFileList.filter(x => !x.canceled);\r\n\r\n        const result = [] as SelectedFile[];\r\n        for (let i = 1; i <= this.selectedFileSortMap.size; i++) {\r\n            const selectedFile = this.selectedFileList[this.selectedFileSortMap.get(i)!];\r\n\r\n            if (!selectedFile.canceled)\r\n                result.push(selectedFile);\r\n        }\r\n        return result;\r\n    }\r\n\r\n    /**\r\n     * 获取当前所有文件集合\r\n     *\r\n     * @param sort 是否需要排序\r\n     */\r\n    public getRawFileList(this: NaiveUpload, sort: boolean): RawFile[] {\r\n        return this.getSelectedFileList(sort).map(x => this.rawFileList[x.rawIndex!]);\r\n    }\r\n\r\n    /**\r\n     * 获取当前所有的用户文件信息集合\r\n     *\r\n     * @param sort 是否需要排序\r\n     */\r\n    public getUserFileInfoList(this: NaiveUpload, sort: boolean): IUserFileInfo[] {\r\n        return this.getRawFileList(sort).filter(item => item.userFileInfo).map(item => item.userFileInfo!);\r\n    }\r\n\r\n    /**\r\n     * 获取选择的文件\r\n     *\r\n     * @param sortKey 排序值\r\n     */\r\n    public getSelectedFile(this: NaiveUpload, sortKey: number): SelectedFile {\r\n        return this.selectedFileList[this.selectedFileSortMap.get(sortKey)!];\r\n    }\r\n\r\n    /**\r\n     * 获取渐变色样式\r\n     * @param {string} type 类型 conic锥形渐变,linear线性渐变\r\n     * @param {string} color 颜色\r\n     * @param {number} value1 值1\r\n     * @param {number} value2 值2\r\n     */\r\n    public getGradientStyle(type: string, color: string, value1: number, value2: number): string {\r\n        switch (type) {\r\n            default:\r\n            case 'conic':\r\n                return `\r\nbackground: conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;\r\nbackground: -moz-conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;\r\nbackground: -o-conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;\r\nbackground: -webkit-conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;`;\r\n            case 'linear':\r\n                return `\r\nbackground: linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;\r\nbackground: -moz-linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;\r\nbackground: -o-linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;\r\nbackground: -webkit-linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%;`;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取渐变色样式\r\n     * @param {string} type 类型 conic锥形渐变,linear线性渐变\r\n     * @param {string} color 颜色\r\n     * @param {number} value1 值1\r\n     * @param {number} value2 值2\r\n     */\r\n    public getGradientStyleObject(type: string, color: string, value1: number, value2: number): Array<Record<string, string>> {\r\n        switch (type) {\r\n            default:\r\n            case 'conic':\r\n                return [\r\n                    { 'background': `conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` },\r\n                    { 'background': `-moz-conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` },\r\n                    { 'background': `-o-conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` },\r\n                    { 'background': `-webkit-conic-gradient(${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` }];\r\n            case 'linear':\r\n                return [\r\n                    { 'background': `linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` },\r\n                    { 'background': `-moz-linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` },\r\n                    { 'background': `-o-linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` },\r\n                    { 'background': `-webkit-linear-gradient(to right, ${color} ${value1}%, transparent ${value2}%)  repeat scroll 0% 0%` }];\r\n        }\r\n    }\r\n}\r\n","<!--\r\n初级上传组件\r\n\r\n支持大文件上传、多文件上传、文件秒传、断点续传，以及文件数量校验、文件大小校验、文件类型校验\r\n\r\n@author LCTR\r\n@date 2022-09-22\r\n-->\r\n\r\n<template>\r\n  <div v-if=\"!renderData.loading\">\r\n    <component :is=\"renderData.currentUpload\"></component>\r\n  </div>\r\n</template>\r\n\r\n<script setup lang=\"ts\">\r\nimport { provide, reactive, ShallowRef, shallowRef } from \"vue-demi\";\r\nimport Settings from \"./Model/Settings\";\r\nimport { IApiService } from \"./Core/IApiService\";\r\nimport SingleUpload from \"./Piece/SingleUpload.vue3.vue\";\r\nimport MultipleUpload from \"./Piece/MultipleUpload.vue3.vue\";\r\nimport NaiveUpload from \"./Core/NaiveUpload\";\r\nimport RawFile from \"./Model/RawFile\";\r\nimport { IOpenApi } from \"./Extention/IOpenApi\";\r\nimport { IConfig } from \"./Model/IConfig\";\r\nimport { IUserFileInfo } from \"./Model/IUserFileInfo\";\r\n\r\nlet upload = null as NaiveUpload | null;\r\n//注册文件上传工具实例\r\nprovide(\"upload\", () => upload);\r\n\r\n/**\r\n * 渲染数据\r\n */\r\nlet renderData = reactive({\r\n  /**\r\n   * 加载状态\r\n   */\r\n  loading: true,\r\n\r\n  /**\r\n   * 当前的上传组件\r\n   */\r\n  currentUpload: null as ShallowRef<any> | null,\r\n});\r\n\r\n/**\r\n * 组件属性\r\n */\r\nconst props = withDefaults(\r\n  defineProps<{\r\n    /**\r\n     * 已上传的文件Id集合\r\n     * <p>只读</p>\r\n     */\r\n    modelValue?: string[];\r\n\r\n    /**\r\n     * 设置\r\n     */\r\n    settings?: Settings;\r\n\r\n    /**\r\n     * 接口服务\r\n     */\r\n    apiService: IApiService;\r\n\r\n    /**\r\n     * 只读模式\r\n     */\r\n    readonly?: boolean;\r\n  }>(),\r\n  {\r\n    modelValue: () => [] as string[],\r\n    settings: () => {\r\n      return Settings.default();\r\n    },\r\n    readonly: false,\r\n  }\r\n);\r\n\r\n/**\r\n * 组件自定义事件\r\n */\r\nconst emit = defineEmits<{\r\n  /**\r\n   * 更新用户文件信息Id集合\r\n   *\r\n   * @param e\r\n   * @param ids 用户文件信息Id集合\r\n   */\r\n  (e: \"update:modelValue\", ids: string[]): void;\r\n\r\n  /**\r\n   * 设置组件开放的接口\r\n   *\r\n   * @param e\r\n   * @param openApi 组件开放的接口\r\n   */\r\n  (e: \"setOpenApi\", openApi: IOpenApi): void;\r\n\r\n  /**\r\n   * 文件校验前执行\r\n   *\r\n   * @param e\r\n   * @param file 文件\r\n   * @returns 是否处理并上传该文件\r\n   */\r\n  (e: \"beforeCheck\", file: File): Promise<boolean>;\r\n\r\n  /**\r\n   * 文件校验结束后执行\r\n   *\r\n   * @param e\r\n   * @param rawFile 文件\r\n   */\r\n  (e: \"afterCheck\", rawFile: RawFile): Promise<void>;\r\n\r\n  /**\r\n   * 文件校验全部校验结束后执行\r\n   *\r\n   * @param e\r\n   * @param rawFiles 文件集合\r\n   */\r\n  (e: \"afterCheckAll\", rawFiles: RawFile[]): Promise<void>;\r\n\r\n  /**\r\n   * 文件上传后执行\r\n   *\r\n   * @param e\r\n   * @param rawFile 文件\r\n   */\r\n  (e: \"afterUpload\", rawFile: RawFile): Promise<void>;\r\n\r\n  /**\r\n   * 所有文件上传后执行\r\n   * <p>此方法不会等待</p>\r\n   *\r\n   * @param e\r\n   * @param rawFiles 文件集合\r\n   */\r\n  (e: \"afterUploadAll\", rawFiles: RawFile[]): Promise<void>;\r\n\r\n  /**\r\n   * 组件异常\r\n   *\r\n   * @param e\r\n   * @param error 异常\r\n   */\r\n  (e: \"error\", error: Error): Promise<void>;\r\n}>();\r\n\r\n/**\r\n * 初始化方法\r\n */\r\n(async () => {\r\n  if (props.apiService == null)\r\n    throw new Error(\"必须设置一个IApiService的实现类\");\r\n\r\n  //获取文件上传工具实例\r\n  if (props.readonly) props.settings.readonly = true;\r\n\r\n  try {\r\n    upload = await NaiveUpload.getInstance(props.settings, props.apiService);\r\n  } catch (e: any) {\r\n    emit(\"error\", e);\r\n    return;\r\n  }\r\n\r\n  upload.getSettings().debug\r\n    ? console.debug(\"NaiveUpload Instance 已创建\", Object.assign({}, upload))\r\n    : !1;\r\n\r\n  //设置各个回调事件\r\n  upload.setupBeforeCheck((file: File) => {\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"BeforeCheck => \", Object.assign({}, file))\r\n      : !1;\r\n    return emit(\"beforeCheck\", file) === undefined\r\n      ? new Promise<boolean>((resolve) => {\r\n          resolve(true);\r\n        })\r\n      : emit(\"beforeCheck\", file);\r\n  });\r\n  upload.setupAfterCheck((rawFile: RawFile) => {\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"AfterCheck => \", Object.assign({}, rawFile))\r\n      : !1;\r\n    return emit(\"afterCheck\", rawFile);\r\n  });\r\n  upload.setupAfterCheckAll((rawFileList: RawFile[]) => {\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"AfterCheckAll => \", Object.assign({}, rawFileList))\r\n      : !1;\r\n    return emit(\"afterCheckAll\", rawFileList);\r\n  });\r\n  upload.setupAfterUpload((rawFile: RawFile) => {\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"AfterUpload => \", Object.assign({}, rawFile))\r\n      : !1;\r\n\r\n    return emit(\"afterUpload\", rawFile);\r\n  });\r\n  upload.setupAfterUploadAll((rawFileList: RawFile[]) => {\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"AfterUploadAll => \", Object.assign({}, rawFileList))\r\n      : !1;\r\n    return emit(\"afterUploadAll\", rawFileList);\r\n  });\r\n  upload.setupHandlerError((error: Error) => {\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"HandlerError => \", Object.assign({}, error))\r\n      : !1;\r\n    return emit(\"error\", error);\r\n  });\r\n\r\n  const changConfig = (config?: IConfig) => {\r\n    renderData.loading = true;\r\n    //根据文件数量上限配置相应的上传组件\r\n    if (upload!.getConfig().upperLimit == 1)\r\n      renderData.currentUpload = shallowRef(SingleUpload);\r\n    else renderData.currentUpload = shallowRef(MultipleUpload);\r\n\r\n    renderData.loading = false;\r\n    upload!.getSettings().debug\r\n      ? console.debug(\"Layout：index Component 已变更\")\r\n      : !1;\r\n  };\r\n\r\n  //注册配置变更事件\r\n  upload.registerConfigChanged(changConfig);\r\n\r\n  //初始化\r\n  changConfig();\r\n\r\n  const changValue = (userFileInfoList: IUserFileInfo[]) => {\r\n    props.modelValue.splice(0, props.modelValue.length);\r\n    userFileInfoList.forEach((x) => props.modelValue.push(x.id));\r\n\r\n    emit(\"update:modelValue\", props.modelValue);\r\n\r\n    upload!.getSettings().debug\r\n      ? console.debug(\r\n          \"ModelValue UserFileIdList => \",\r\n          Object.assign({}, props.modelValue)\r\n        )\r\n      : !1;\r\n  };\r\n\r\n  //注册文件信息变更事件\r\n  upload.registerUserFileInfoListChanged(changValue);\r\n\r\n  //设置组件开放的接口\r\n  emit(\"setOpenApi\", upload.getOpenApi());\r\n\r\n  //添加之前已上传过的文件\r\n  if (props.modelValue && props.modelValue.length > 0) {\r\n    for (const id of props.modelValue) {\r\n      await upload.appendById(id);\r\n    }\r\n  }\r\n\r\n  renderData.loading = false;\r\n\r\n  upload.getSettings().debug\r\n    ? console.debug(\"Naive Upload Component(Vue3) 已加载\")\r\n    : !1;\r\n})();\r\n</script>\r\n\r\n<style lang=\"scss\" type=\"text/scss\">\r\n@import \"index.scss\";\r\n</style>\r\n","import { Canceler } from \"axios\";\r\nimport { IApiService } from \"../Core/IApiService\";\r\nimport { FileType } from \"../Model/FileType\";\r\nimport { IConfig } from \"../Model/IConfig\";\r\nimport { IPreUploadChunkFileResponse } from \"../Model/IPreUploadChunkFileResponse\";\r\nimport { IPreUploadFileResponse } from \"../Model/IPreUploadFileResponse\";\r\nimport { IProgress } from \"../Model/IProgress\";\r\nimport { IUserFileInfo } from \"../Model/IUserFileInfo\";\r\nimport FileTypeHelper from \"./FileTypeHelper\";\r\n\r\n\r\n/**\r\n * 默认接口服务实现类\r\n * <p>此为抽象类，部分接口方法需要对接项目的后端接口</p>\r\n * \r\n * @author LCTR\r\n * @date 2022-11-07\r\n */\r\nexport default abstract class DefaultApiService implements IApiService {\r\n    abstract config(code: string): Promise<IConfig>;\r\n\r\n    getFileTypeByExtension(extension: string): Promise<FileType> {\r\n        return Promise.resolve(FileTypeHelper.getByExtension(extension));\r\n    }\r\n\r\n    getFileTypeByMIME(mimetype: string): Promise<FileType> {\r\n        return Promise.resolve(FileTypeHelper.getByMIME(mimetype));\r\n    }\r\n\r\n    getFileTypeImageUrl(extension: string): string {\r\n        return `/filetypes/${(extension ?? '.empty').substring(1)}.png`;\r\n    }\r\n\r\n    getUnknowFileTypeImageUrl(): string {\r\n        return '/filetypes/empty.png';\r\n    }\r\n\r\n    abstract rename(id: string, fileName: string): Promise<void>;\r\n\r\n    abstract getDownloadUrl(id: string, rename: string): string;\r\n\r\n    abstract getUserFile(id: string): Promise<IUserFileInfo>;\r\n\r\n    abstract getUserFilePreviewUrl(id: string, width?: number | undefined, height?: number | undefined, time?: string | undefined): string;\r\n\r\n    abstract getUserFileBrowseUrl(id: string): string;\r\n\r\n    abstract preUploadFile(configCode: string, md5: string, type: string, extension: string, length: string, filename?: string | undefined, section?: boolean | undefined, specs?: number | undefined, total?: number | undefined): Promise<IPreUploadFileResponse>;\r\n\r\n    abstract singleFile(configCode: string, file: File, filename?: string | undefined, onProgress?: ((progress: IProgress) => void) | undefined, setupCancelToken?: ((cancelToken: Canceler) => void) | undefined): Promise<IUserFileInfo>;\r\n    abstract getSingleFileByArrayBufferRequestParams(configCode: string, type: string, extension: string, filename?: string | undefined): { urlWithParams: string; headers: Map<string, string>; };\r\n    abstract getUserFileInfoFromSingleFileByArrayBufferResponse(response: any): IUserFileInfo;\r\n\r\n    abstract preUploadChunkFile(file_md5: string, md5: string, index: number, specs: number, forced?: boolean | undefined): Promise<IPreUploadChunkFileResponse>;\r\n    abstract singleChunkFile(key: string, md5: string, file: Blob, onProgress?: ((progress: IProgress) => void) | undefined, setupCancelToken?: ((cancelToken: Canceler) => void) | undefined): Promise<void>;\r\n    abstract getSingleChunkFileByArrayBufferRequestParams(key: string, md5: string): { urlWithParams: string; headers: Map<string, string>; };\r\n    abstract getUserFileInfoFromSingleChunkFileByArrayBufferResponse(response: any): IUserFileInfo;\r\n    abstract uploadChunkFileFinished(configCode: string, file_md5: string, specs: number, total: number, type?: string | undefined, extension?: string | undefined, filename?: string | undefined): Promise<IUserFileInfo>;\r\n}","import NaiveUpload from './index.vue3.vue';\r\nimport type { App, Plugin } from \"vue-demi\";\r\n\r\nconst installer: Plugin = {\r\n    install(app: App) {\r\n        app.component(\"naive-upload\", NaiveUpload);\r\n    },\r\n};\r\n\r\n// type SFCWithInstall<T> = T & Plugin;\r\n// const withInstall = <T>(component: Component) => {\r\n//     (component as SFCWithInstall<T>).install = (app: App) => {\r\n//         //注册组件\r\n//         app.component(\"naive-upload\", component);\r\n//     }\r\n//     return component as SFCWithInstall<T>;\r\n// }\r\n\r\n// export const installer = withInstall(NaiveUpload);\r\n\r\n/**\r\n * 用于全局注册组件\r\n */\r\nexport default installer;\r\n\r\n/**\r\n * 用于按需引用\r\n */\r\nexport {\r\n    /**\r\n     * 文件上传组件\r\n     */\r\n    NaiveUpload\r\n};\r\n\r\nexport * from './export.base';"],"names":["RunMode","Layout","RGBAColor","r","g","b","a","__publicField","rgba","_Settings","action","Settings","configCode","x","upload","inject","reactive","fileInputRef","setFileInputRef","el","chosingFile","e","choseFile","i","FileType","proxy","getCurrentInstance","renderData","props","renameInputRef","setContainerRef","emit","setRenameInputRef","mouseEnter","event","mouseLeave","mouseDown","mouseUp","rename","renameKeydown","renameDone","view","file","bodyStyle","winImage","winAudio","winVideo","win","save","remove","changLayout","layout","shallowRef","Card","Detailedly","allowDrop","dropFile","DraggingHelper","clientX","clientY","current","target","error","containerEl","helper","handlerMoving","handlerMovingFlag","y","restore","listContainerRef","containerRefMap","drag4sort","sortKey","item","key","setListRef","containerMouseDown","containerMouseUp","containerMouseEnter","containerMouseLeave","scroll","files","container","findChecking","alertError","UploadError","message","innerError","index","RawFile","FileTypeHelper","extension","mimetype","mimetypeLower","SelectedFile","_a","_b","pointIndex","SimpleGuid","_FileSizeHelper","length","unit","precision","value","FileSizeHelper","ChunkFile","blob","worker","hex_chr","md5cycle","k","c","d","md5blk","s","md5blks","md5blk_array","md51","n","state","tail","tmp","lo","hi","md51_array","rhex","j","hex","clamp","val","from","to","begin","end","num","targetArray","sourceArray","toUtf8","str","utf8Str2ArrayBuffer","returnUInt8Array","buff","arr","arrayBuffer2Utf8Str","concatenateArrayBuffers","first","second","result","hexToBinaryString","bytes","SparkMD5","contents","raw","ret","content","hash","sparkMD5","data","HashWorkerScript","FileReadHelper","resolve","reject","buffer","HashWorkerMessageType","HashHelper","enableWorker","debug","handlerIndex","onProgress","xFile","progress","bufferSize","wait","flag","concurrent","handlerProgress","current_progress","last_progress","calcFile","done","calc","next","chunk","push","UploadWorkerMessageType","PreUploadChunkFileState","currentRequest","url","headers","request","data_upload","UploadWorkerScript","UploadHelper","apiService","userFileInfo","cancelToken","validation","requestParams","chunkFile","data_progress1","data_progress2","data_userFileInfo","data_progress3","data_progress4","chunk_progress","_chunk_progress","proceed","NaiveUpload","settings","config","watch","last","newFile","token","rawFile","type","selectedFile","before","id","objectURL","count","selectedFileIndex","after","pause","hashHelper","continue_","cancel","close","uploadHelper","virtualPercent","percent","retry","_selectedFileIndex","success","size","currentIndex","targetIndex","even","sort","color","value1","value2","provide","rawFileList","changConfig","SingleUpload","MultipleUpload","changValue","userFileInfoList","DefaultApiService","installer","app"],"mappings":"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"}