|
@@ -61,13 +61,14 @@
|
|
|
|
|
|
import { Vue, Component, Ref } from "vue-property-decorator";
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
-//@ts-ignore
|
|
|
+// @ts-ignore
|
|
|
import SparkMD5 from "spark-md5";
|
|
|
+import Bus from "@/utils/bus.ts";
|
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
-//@ts-ignore
|
|
|
+// @ts-ignore
|
|
|
import uploader from "vue-simple-uploader";
|
|
|
-import Bus from "@/utils/bus.ts";
|
|
|
import { AppModule } from "@/store/modules/app";
|
|
|
+import { mergeModelFile, deleteModelFileList } from "@/api/modelapi";
|
|
|
import { getUploadId, mergeMultipart } from "@/api/imageservice";
|
|
|
|
|
|
// import request from "@/api/model/file.js";
|
|
@@ -76,7 +77,7 @@ import { getUploadId, mergeMultipart } from "@/api/imageservice";
|
|
|
name: "GlobalUploader",
|
|
|
})
|
|
|
export default class extends Vue {
|
|
|
- @Ref("uploader") readonly uploader!: uploader;
|
|
|
+ @Ref("uploader") readonly uploaderComponent!: uploader;
|
|
|
|
|
|
// 中英文按钮映射
|
|
|
private fileStatusText: any = {
|
|
@@ -114,13 +115,22 @@ export default class extends Vue {
|
|
|
// accept: ACCEPT_CONFIG.getAll()
|
|
|
};
|
|
|
|
|
|
- private panelShow = false; // 选择文件后,展示上传panel
|
|
|
- private collapse = false;
|
|
|
+ private panelShow = true; // 选择文件后,展示上传panel
|
|
|
+ private collapse = true;
|
|
|
+
|
|
|
+ // Uploader实例
|
|
|
+ get uploader() {
|
|
|
+ return this.uploaderComponent.uploader;
|
|
|
+ }
|
|
|
|
|
|
get uploaderList(): any[] {
|
|
|
return AppModule.uploaderList;
|
|
|
}
|
|
|
|
|
|
+ private setUploaderList(list: any[]) {
|
|
|
+ AppModule.SetUploaderList(list);
|
|
|
+ }
|
|
|
+
|
|
|
mounted() {
|
|
|
// 刷新或关闭浏览器提示
|
|
|
window.addEventListener("beforeunload", (e) => {
|
|
@@ -192,12 +202,18 @@ export default class extends Vue {
|
|
|
Bus.$emit("fileAdded");
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 文件上传中监听回调
|
|
|
+ */
|
|
|
private onFileProgress(rootFile: any, file: any, chunk: any) {
|
|
|
console.log(`上传中 ${file.name},chunk:${chunk.startByte / 1024 / 1024} ~ ${chunk.endByte / 1024 / 1024}`);
|
|
|
}
|
|
|
|
|
|
- private onFileSuccess(rootFile: any, file: any, response: any, chunk: any) {
|
|
|
- console.log(chunk);
|
|
|
+ /**
|
|
|
+ * 文件上传成功后的监听回调
|
|
|
+ * @info 每片上传成功后都会触发,检查所有分片是否都上传完成,完成后调用合并接口
|
|
|
+ */
|
|
|
+ private async onFileSuccess(rootFile: any, file: any, response: any) {
|
|
|
let res = JSON.parse(response);
|
|
|
|
|
|
// 服务器自定义的错误(即虽返回200,但是是错误的情况),这种错误是Uploader无法拦截的
|
|
@@ -214,51 +230,59 @@ export default class extends Vue {
|
|
|
this.statusSet(file.id, "merging");
|
|
|
if (file.file.modelId) {
|
|
|
//模型文件合并专用接口
|
|
|
- request.mergeModelFile({ ModelId: file.file.modelId, UploadId: file.file.uploadId, Md5: file.file.md5 }, (res) => {
|
|
|
+ const res = await mergeModelFile({ ModelId: file.file.modelId, UploadId: file.file.uploadId, Md5: file.file.md5 });
|
|
|
+ // 文件合并成功
|
|
|
+ if (res.Result === "success") {
|
|
|
Bus.$emit("modelStatusChange");
|
|
|
- // 文件合并成功
|
|
|
Bus.$emit("fileSuccess");
|
|
|
this.statusRemove(file.id);
|
|
|
- });
|
|
|
+ }
|
|
|
} else {
|
|
|
- mergeMultipart(
|
|
|
- {
|
|
|
- systemId: file.file.systemId ? file.file.systemId : "revit",
|
|
|
- secret: file.file.secret ? file.file.secret : "63afbef6906c342b",
|
|
|
- uploadId: file.file.uploadId,
|
|
|
- },
|
|
|
- (res) => {
|
|
|
- // 文件合并成功
|
|
|
- Bus.$emit("fileSuccess");
|
|
|
- this.statusRemove(file.id);
|
|
|
- }
|
|
|
- );
|
|
|
+ const res = await mergeMultipart({
|
|
|
+ systemId: file.file.systemId ? file.file.systemId : "revit",
|
|
|
+ secret: file.file.secret ? file.file.secret : "63afbef6906c342b",
|
|
|
+ uploadId: file.file.uploadId,
|
|
|
+ });
|
|
|
+ // 文件合并成功
|
|
|
+ if (res.Result === "success") {
|
|
|
+ Bus.$emit("fileSuccess");
|
|
|
+ this.statusRemove(file.id);
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
- // 不需要合并
|
|
|
} else {
|
|
|
+ // 不需要合并
|
|
|
Bus.$emit("fileSuccess");
|
|
|
console.log("上传成功");
|
|
|
}
|
|
|
}
|
|
|
- onFileError(rootFile, file, response, chunk) {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 文件上传失败回调
|
|
|
+ */
|
|
|
+ private onFileError(rootFile: any, file: any, response: any) {
|
|
|
this.$message({
|
|
|
message: response,
|
|
|
type: "error",
|
|
|
});
|
|
|
}
|
|
|
- onFileRemoved(file) {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 文件移除回调
|
|
|
+ */
|
|
|
+ private async onFileRemoved(file: any) {
|
|
|
this.uploaderList.splice(
|
|
|
this.uploaderList.findIndex((item) => {
|
|
|
return item.id == file.id;
|
|
|
}, 1)
|
|
|
);
|
|
|
this.setUploaderList(this.uploaderList);
|
|
|
+ // 未上传完成的模型文件,调用模型删除回滚
|
|
|
if (file.modelId && !file.isComplete()) {
|
|
|
- request.deleteModelFileList({ Id: file.modelId, Force: true }, (res) => {
|
|
|
+ const res = await deleteModelFileList({ Id: file.modelId, Force: true });
|
|
|
+ if (res.Result === "success") {
|
|
|
console.log("删除错误模型:", file.modelId);
|
|
|
Bus.$emit("modelStatusChange");
|
|
|
- });
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -266,9 +290,11 @@ export default class extends Vue {
|
|
|
* 计算md5,实现断点续传及秒传
|
|
|
* @param file
|
|
|
*/
|
|
|
- computeMD5(file) {
|
|
|
+ private computeMD5(file: any) {
|
|
|
let fileReader = new FileReader();
|
|
|
let time = new Date().getTime();
|
|
|
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
+ // @ts-ignore
|
|
|
let blobSlice = File.prototype.slice || File.prototype.mozSlice || File.prototype.webkitSlice;
|
|
|
let currentChunk = 0;
|
|
|
const chunkSize = 1 * 1024 * 1024;
|
|
@@ -281,7 +307,7 @@ export default class extends Vue {
|
|
|
|
|
|
loadNext();
|
|
|
|
|
|
- fileReader.onload = (e) => {
|
|
|
+ fileReader.onload = (e: any) => {
|
|
|
spark.append(e.target.result);
|
|
|
|
|
|
if (currentChunk < chunks) {
|
|
@@ -290,8 +316,8 @@ export default class extends Vue {
|
|
|
|
|
|
// 实时展示MD5的计算进度
|
|
|
this.$nextTick(() => {
|
|
|
- document.getElementsByClassName(`myStatus_${file.id}`)[0].innerText =
|
|
|
- "校验MD5 " + ((currentChunk / chunks) * 100).toFixed(0) + "%";
|
|
|
+ let dom: HTMLElement = document.getElementsByClassName(`myStatus_${file.id}`)[0] as HTMLElement;
|
|
|
+ dom.innerText = "校验MD5 " + ((currentChunk / chunks) * 100).toFixed(0) + "%";
|
|
|
// $(`.myStatus_${file.id}`).text('校验MD5 '+ ((currentChunk/chunks)*100).toFixed(0)+'%')
|
|
|
});
|
|
|
} else {
|
|
@@ -302,7 +328,7 @@ export default class extends Vue {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- fileReader.onerror = function () {
|
|
|
+ fileReader.onerror = () => {
|
|
|
this.error(`文件${file.name}读取出错,请检查该文件`);
|
|
|
file.cancel();
|
|
|
};
|
|
@@ -315,7 +341,7 @@ export default class extends Vue {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- computeMD5Success(md5, file) {
|
|
|
+ private computeMD5Success(md5: number, file: any) {
|
|
|
// 将自定义参数直接加载uploader实例的opts上
|
|
|
console.log(this.uploader);
|
|
|
// Object.assign(this.uploader.opts, {
|
|
@@ -329,19 +355,25 @@ export default class extends Vue {
|
|
|
|
|
|
// file.resume();//继续上传文件
|
|
|
// 调用依赖中继续上传的方法达到状态刷新的目的(原生点击继续上传按钮)
|
|
|
- document.querySelector(`.file_${file.id} .uploader-file-resume`).click();
|
|
|
+ let dom: HTMLElement | null = document.querySelector(`.file_${file.id} .uploader-file-resume`);
|
|
|
+ dom?.click();
|
|
|
this.statusRemove(file.id);
|
|
|
}
|
|
|
|
|
|
- //获取文件参数
|
|
|
- getFileQuery(file, chunk) {
|
|
|
+ /**
|
|
|
+ * 获取文件参数
|
|
|
+ */
|
|
|
+ private getFileQuery(file: any) {
|
|
|
return {
|
|
|
uploadId: file.file.uploadId,
|
|
|
md5: file.file.md5,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- fileListShow() {
|
|
|
+ /**
|
|
|
+ * 显示文件列表
|
|
|
+ */
|
|
|
+ private fileListShow() {
|
|
|
this.collapse = this.collapse ? false : true;
|
|
|
|
|
|
// let $list = $('#global-uploader .file-list');
|
|
@@ -359,7 +391,11 @@ export default class extends Vue {
|
|
|
// // this.collapse = false;
|
|
|
// }
|
|
|
}
|
|
|
- close() {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 关闭文件上传器弹窗
|
|
|
+ */
|
|
|
+ private close() {
|
|
|
if (this.uploader.isUploading()) {
|
|
|
this.$alert("您有文件正在上传,关闭会中断上传,是否继续?", "提示", {
|
|
|
confirmButtonText: "确定",
|
|
@@ -371,7 +407,6 @@ export default class extends Vue {
|
|
|
this.uploader.files = [];
|
|
|
this.setUploaderList([]);
|
|
|
Bus.$emit("modelStatusChange");
|
|
|
- } else {
|
|
|
}
|
|
|
},
|
|
|
});
|
|
@@ -386,8 +421,8 @@ export default class extends Vue {
|
|
|
* @param id
|
|
|
* @param status
|
|
|
*/
|
|
|
- statusSet(id, status) {
|
|
|
- let statusMap = {
|
|
|
+ private statusSet(id: string, status: string) {
|
|
|
+ let statusMap: any = {
|
|
|
md5: {
|
|
|
text: "校验MD5",
|
|
|
bgc: "#fff",
|
|
@@ -414,7 +449,7 @@ export default class extends Vue {
|
|
|
node.appendChild(text);
|
|
|
node.setAttributeNode(att);
|
|
|
node.style.backgroundColor = `${statusMap[status].bgc}`;
|
|
|
- document.querySelector(`.file_${id} .uploader-file-status`).appendChild(node);
|
|
|
+ document.querySelector(`.file_${id} .uploader-file-status`)?.appendChild(node);
|
|
|
|
|
|
// $(`<p class="myStatus_${id}"></p>`).appendTo(`.file_${id} .uploader-file-status`).css({
|
|
|
// 'position': 'absolute',
|
|
@@ -427,14 +462,14 @@ export default class extends Vue {
|
|
|
// }).text(statusMap[status].text);
|
|
|
});
|
|
|
}
|
|
|
- statusRemove(id) {
|
|
|
+ private statusRemove(id: string) {
|
|
|
this.$nextTick(() => {
|
|
|
- let dom = document.getElementsByClassName(`myStatus_${id}`)[0];
|
|
|
- dom.parentNode.removeChild(dom);
|
|
|
+ let dom: Node = document.getElementsByClassName(`myStatus_${id}`)[0];
|
|
|
+ dom.parentNode?.removeChild(dom);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- error(msg) {
|
|
|
+ private error(msg: string) {
|
|
|
this.$notify({
|
|
|
title: "错误",
|
|
|
message: msg,
|
|
@@ -450,7 +485,7 @@ export default class extends Vue {
|
|
|
position: fixed;
|
|
|
z-index: 101;
|
|
|
top: auto;
|
|
|
- right: 15px;
|
|
|
+ right: 10px;
|
|
|
bottom: 0;
|
|
|
|
|
|
.uploader-app {
|
|
@@ -496,7 +531,7 @@ export default class extends Vue {
|
|
|
> li {
|
|
|
background-color: #fff;
|
|
|
}
|
|
|
- :v-deep .uploader-file-info i {
|
|
|
+ ::v-deep .uploader-file-info i {
|
|
|
display: none;
|
|
|
}
|
|
|
::v-deep .status_style {
|