/**version-1.0*/
let tmixins, tViewMixins, pmixins;
import axios from "axios";
import SparkMD5 from "spark-md5";
import settingConfig from "@/settings.js";

let imFun = {
  axios,
  SparkMD5,
};

tmixins = {
  name: "VabUpload",
  props: {
    auto: {
      type: Boolean,
      default: true,
    },
    url: {
      type: String,
      default: "/upload",
    },
    name: {
      type: String,
      default: "file",
    },
    limit: {
      type: Number,
      default: () => 100000,
    },
    size: {
      type: Number,
      default: 200,
    },
    accept: {
      type: String,
      default: "file",
    },
    chunkSize: {
      type: Number,
      default: 5, //5MB
    },
    confirmUpload: {
      type: Function,
    },
    pickPrivateProfile: {
      type: Boolean,
      default: true,
    },
    multi: {
      type: [String, Boolean],
      default: true,
    },
    uploadingLimit: {
      type: Number,
      default: 5, //5MB
    },
    isPartUpload: {
      type: Boolean,
      default: () => {
        return settingConfig.isPartUpload ?? true;
      },
    },
    autoConfirmAfterUpload: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      show: false,
      loading: false,
      dialogVisible: false,
      dialogImageUrl: "",
      action: "",
      headers: {},
      fileList: [],
      picture: "picture",
      allImgNum: 0,
      imgNum: 0,
      imgSuccessNum: 0,
      imgErrorNum: 0,
      typeList: null,
      title: this.$t2("上传", "components.VabUpload.title"),
      dialogFormVisible: false,
      data: {},
      fileViewDialogVisible: false,
      fileViewInfo: {},
      total: 0,
      video: null,
      btn: false,
      filePartMap: {},
      uploading: false,
      hasReadyFile: false,
      showLocalUploadBtn: false,
      showPrivateUploadBtn: false,
      showPrivateProfileDialog: false,
      pasteList: [],
      pasteAreaStatus: false,
      option: {},
      editFileIndex: -1,
      showFileNameDialog: false,
      editFileName: null,
      editFileSuffix: null,
      beforeUploadFlag: false,
      uploadUrl: null,
    };
  },
  beforeDestroy() {
    this.removePasteEvent();
  },
  filters: {
    btnText(btn) {
      return btn
        ? this.$t2("继续", "components.VabUpload.continue")
        : this.$t2("暂停", "components.VabUpload.pause");
    },
    totalText(total) {
      return total > 100 ? 100 : total;
    },
  },
  computed: {
    percentage() {
      if (this.allImgNum == 0) return 0;
      return ((this.imgNum / this.allImgNum, 2) * 100).toFixed(0);
    },
    fileMaxSize() {
      return this.formatFileSize(this.size * 1024 * 1024);
    },
    errorQuantity() {
      return this.fileList.filter((file) => file.status == "fail").length;
    },
    totalQuantity() {
      return this.fileList.length;
    },
    successQuantity() {
      return this.fileList.filter((file) => file.status == "success").length;
    },
    isMulti: function () {
      let isMulti = true;
      if (this.multi === "false" || this.multi === false || this.limit === 1) {
        isMulti = false;
      }
      return isMulti;
    },
  },
  methods: {
    updateUploadingStatus() {
      var target = this.$refs.upload;
      let uploading, hasReadyFile;
      if (target) {
        var fileList = target.uploadFiles;
        let n = fileList.find((item) => {
          // return item.percentage != 100;
          return item.status == "uploading" || item.status == "preUpload";
        });
        uploading = n == null ? false : true;

        let readyFiles = fileList.filter((file) => file.status == "ready");
        hasReadyFile = readyFiles.length > 0;
      } else {
        uploading = false;
        hasReadyFile = false;
      }

      this.uploading = uploading;
      this.hasReadyFile = hasReadyFile;
      this.checkPreUploadList();
      return uploading;
    },
    submitUpload() {
      let successDone = () => {
        this.$refs.upload.submit();
      };
      var files = this.$refs.upload.uploadFiles;
      let readyFiles = files.filter((file) => file.status == "ready");
      if (this.confirmUpload) {
        if (readyFiles.length) {
          this.confirmUpload({
            files: files,
            done: successDone,
          });
        }
      } else {
        successDone();
      }
    },
    handleProgress(event, file, fileList) {
      // this.loading = true
      // this.show = true
    },
    handleChange(file, fileList) {
      let maxSize = this.size * 1024 * 1024;
      if (file.size > maxSize) {
        fileList.map((item, index) => {
          if (item === file) {
            fileList.splice(index, 1);
          }
        });
        this.fileList = fileList;
        let errorText =
          "文件[" + file.name + "]大小超出限制" + this.fileMaxSize;
        this.$message({
          message: this.$t2(errorText, "components.VabUpload.warnMsg1", {
            fileName: file.name,
            fileMaxSize: this.fileMaxSize,
          }),
          type: "error",
          duration: 3 * 1000,
        });
        file.raw.status = "fail";
        return false;
      } else {
        this.fileList = fileList;
        this.allImgNum = fileList.length;
      }
      this.updateUploadingStatus();
    },
    handleSuccess(response, file, fileList) {
      if (file.percentage == 100) {
        this.imgNum = this.imgNum + 1;
        this.imgSuccessNum = this.imgSuccessNum + 1;
      }
      if (fileList.length === this.imgNum) {
        this.fileList = fileList;

      // 添加自动确认功能
    // 当所有文件上传完成且 autoConfirmAfterUpload 为 true 时，自动调用 submitImage 方法
        if (this.autoConfirmAfterUpload) {
          // 使用 nextTick 确保所有文件状态已更新
          this.$nextTick(() => {
            this.submitImage();
          });
          return; // 自动确认后直接返回，不执行后续的 setTimeout
        }

      }

      setTimeout(() => {
        this.loading = false;
        this.show = false;
      }, 1000);
      this.updateUploadingStatus();
    },
    handleError(err, file, fileList) {
      this.imgNum = this.imgNum + 1;
      this.imgErrorNum = this.imgErrorNum + 1;
      setTimeout(() => {
        this.loading = false;
        this.show = false;
      }, 1000);
      this.updateUploadingStatus();
    },
    handleRemove(file, fileList) {
      this.imgNum = this.imgNum - 1;
      this.allNum = this.allNum - 1;
      this.updateUploadingStatus();
    },
    handlePreview(file) {
      this.dialogImageUrl = file.url;
      this.dialogVisible = true;
    },
    handleExceed(files, fileList) {
      let errorMsg = `当前限制选择 ${this.limit} 个文件，本次选择了
             ${files.length}
             个文件`;
      this.$message({
        message: this.$t2(errorMsg, "components.VabUpload.warnMsg2", {
          limit: this.limit,
          size: files.length,
        }),
        type: "error",
        duration: 5 * 1000,
      });
    },
    handleShow(option) {
      this.title = this.$t2("上传", "components.VabUpload.title");
      // this.data = data;
      this.option = option;
      this.clearFileInfo();
      this.initPickUploadMode();
      this.pasteAreaStatus = false;
      this.dialogFormVisible = true;
      /*document.removeEventListener('paste', this.pasteEvent);
      document.addEventListener('paste', this.pasteEvent);*/

      this.removePasteEvent();
      this.addPasteEvent();
      if(!option.files?.length){
          this.initUploadUrl();
      }else{
        this.initUploadUrl(()=>{
          this.handleUpload(option.files)
        });
      }
    },
    handleUpload(fileRawList){
      let target = this.$refs.upload;
      let innerTarget = target.$refs["upload-inner"];
      if (fileRawList.length) {
        innerTarget.uploadFiles(fileRawList);
      }
    },
    addPasteEvent() {
      document.addEventListener("click", this.blurPasteEvent);
      document.addEventListener("paste", this.pasteEvent);
      /* if(this.option.copy){

      } */
    },
    removePasteEvent() {
      document.removeEventListener("click", this.blurPasteEvent);
      document.removeEventListener("paste", this.pasteEvent);
    },
    blurPasteEvent() {
      this.pasteAreaStatus = false;
    },
    handleClose() {
      let target = this.$refs.upload;
      (target.uploadFiles || []).forEach((uploadFile) => {
        if (uploadFile.status == "uploading" || uploadFile.status == "ready") {
          uploadFile.raw.abort &&
            uploadFile.raw.abort(
              this.$t2("取消上传", "components.VabUpload.cancelUpload")
            );
        }
      });
      this.picture = "picture";
      this.clearFileInfo();
      this.dialogFormVisible = false;
    },
    clearFileInfo() {
      this.fileList = [];
      this.allImgNum = 0;
      this.imgNum = 0;
      this.imgSuccessNum = 0;
      this.imgErrorNum = 0;
    },
    initUploadUrl(callback) {
      let mineUploadUrl = window.BASE_FILEURL;
      return this.$http({
        url: mineUploadUrl,
        method: "post",
        data: {
          isAuth: false,
        },
        success: (res) => {
          this.uploadUrl = res.objx;
          callback && callback();
        },
      });
    },
    handleBeforeUpload(file, checkFile, callback) {
      /*if (checkFile !== false) {
        let target = this.$refs.upload;
        let nFile = target.getFile(file);
        if (!nFile) {
          return false;
        }
      }
      let mineUploadUrl = window.BASE_FILEURL;
      return await this.$http({
        url: mineUploadUrl,
        method: 'post',
        data: {
          isAuth: false
        },
        success: res => {
          this.uploadUrl = res.objx;
          callback && callback()
        }
      });*/
      callback && callback();
    },
    formatFileSize(fileSize) {
      return formatFileSize(fileSize);
    },
    //自定义上传
    async uploadSectionFile(param, isCustom, uploadConfig) {
      if (!this.uploadUrl) {
        await this.initUploadUrl();
      }
      let that = this;
      var fileObj = param.file;

      let source;

      var form = new FormData();
      // 文件对象
      form.append("file", fileObj);

      let target = that.$refs.upload;
      let file = target ? target.getFile(fileObj) : null;
      if (file) {
        file.status = "uploading";
      }

      let isLoading = uploadConfig?.isLoading === true;
      var uploadUrl = this.uploadUrl;
      if (uploadUrl) {
        var abort;
        let config = {
          isLoading: isLoading,
          headers: {
            "Content-Type": "multipart/form-data",
          },
          cancelToken: new imFun.axios.CancelToken(function executor(c) {
            if (!isCustom) {
              abort = c;
              if (file) file.abort = c;
            }
          }),
          onUploadProgress: (progressEvent) => {
            if (isCustom || file) {
              // progressEvent.loaded:已上传文件大小
              // progressEvent.total:被上传文件的总大小
              progressEvent.percent = Math.floor(
                (progressEvent.loaded * 100) / progressEvent.total
              );
              if (!isCustom) {
                param.onProgress(progressEvent, fileObj);
              }
              uploadConfig &&
                uploadConfig.onProgress &&
                uploadConfig.onProgress(progressEvent, fileObj);
            }
          },
          failMsg: false,
        }; //添加请求头

        let req = this.$http
          .post(uploadUrl, form, config)
          .then((res1) => {
            uploadConfig &&
              uploadConfig.callback &&
              uploadConfig.callback(res1, fileObj);
            if (!isCustom) {
              if (res1.type == "success") {
                param.onSuccess(res1, fileObj);
              } else {
                // param.onError(new Error(res1.content || '上传异常'));
                this.handleFileError(
                  new Error(
                    res1.content ||
                      this.$t2(
                        "上传异常",
                        "components.VabUpload.uploadException"
                      )
                  ),
                  fileObj
                );
              }
            }
          })
          .catch((error, a, b, c) => {
            // let {err} = error;
            try {
              // param.onError(err, fileObj);
              if (!isCustom) {
                this.handleFileError(error, fileObj);
              }
              uploadConfig &&
                uploadConfig.error &&
                uploadConfig.error(error, fileObj);
            } catch (tt) {}
          });
        req.abort = () => {
          abort(this.$t2("取消上传", "components.VabUpload.cancelUpload"));
        };
        //return req;
      }
    },
    singerUpload(uploadConfig) {
      let onUploadProgress = uploadConfig.onUploadProgress;
      let success = uploadConfig.success;
      let file = uploadConfig.file;
      this.handleBeforeUpload(file, false, () => {
        this.uploadSectionFile(
          {
            file: file,
          },
          true,
          uploadConfig
        );
      });
    },
    //begin
    fileParse(file, type = "base64", callback) {
      /*return new Promise(resolve => {

      });*/
      let fileRead = new FileReader();
      if (type === "base64") {
        fileRead.readAsDataURL(file);
      } else if (type === "buffer") {
        fileRead.readAsArrayBuffer(file);
      }
      fileRead.onload = (ev) => {
        callback(ev.target.result);
        // resolve(ev.target.result);
      };
    },
    getFileMd5(file, callback){
      // 判断是否为大文件（例如大于10MB）
      const isLargeFile = file.size > 20 * 1024 * 1024;

      if (!isLargeFile) {
        this.fileParse(file,"buffer", (buffer)=>{
          let spark = new imFun.SparkMD5.ArrayBuffer();
          spark.append(buffer);
          let hash = spark.end();
          callback(hash)
        })
      }else{
        this.calculateFileMD5(file, callback)
      }
    },
    calculateFileMD5(file, callback) {
      const chunkSize = 16 * 1024 * 1024; // 2MB一块
      const chunks = Math.ceil(file.size / chunkSize);
      let currentChunk = 0;
      const spark = new imFun.SparkMD5.ArrayBuffer();
      const fileReader = new FileReader();

      // 处理读取错误
      fileReader.onerror = function() {
        console.error('文件读取错误');
        callback(null);
      };

      // 处理进度回调（可选）
      const onProgress = (progress) => {
        // 可以在这里更新进度条
        console.log('MD5计算进度: ' + Math.round(progress * 100) + '%');
      };

      // 递归读取下一块
      const loadNext = () => {
        const start = currentChunk * chunkSize;
        const end = Math.min(start + chunkSize, file.size);

        fileReader.readAsArrayBuffer(file.slice(start, end));
      };

      // 每块读取完成后的处理
      fileReader.onload = function(e) {
        spark.append(e.target.result);
        currentChunk++;

        // 更新进度
        // onProgress(currentChunk / chunks);

        // 继续读取下一块或完成
        if (currentChunk < chunks) {
          loadNext();
        } else {
          // 所有块读取完成，计算最终MD5
          const md5 = spark.end();
          callback(md5);
        }
      };

      // 开始处理
      loadNext();
    },
    changeFile(param) {
      if (!param.file || param.file.status == "fail") return;
      let target = this.$refs.upload;
      if (!target) return;
      let fileObj = target.getFile(param.file);
      fileObj.status = "preUpload";
      fileObj.param = {
        file: param.file,
        onSuccess: param.onSuccess,
        onProgress: param.onProgress,
        onError: param.onError,
      };
      this.checkPreUploadList();
    },
    checkPreUploadList() {
      let uploadingLimit = this.option.uploadingLimit || this.uploadingLimit;
      let target = this.$refs.upload;
      let fileList1 = (target.uploadFiles || []).filter((item) => {
        return item.status == "preUpload";
      });
      let fileList2 = (target.uploadFiles || []).filter((item) => {
        return item.status == "uploading";
      });
      if (fileList2.length < uploadingLimit && fileList1.length > 0) {
        let num = uploadingLimit - fileList2.length;
        if (num) {
          let toNum = Math.min(fileList1.length, num);
          for (let i = 0; i < toNum; i++) {
            let fileRaw = fileList1[i].raw;
            this.uploadFile(fileRaw);
          }
        }
      }
    },
    async uploadFile(file) {
      if (!file || file.status == "fail") return;
      let target = this.$refs.upload;
      if (!target) return;
      let fileObj = target.getFile(file);
      if (fileObj.status != "preUpload") return;
      if (!this.isPartUpload) {
        this.uploadSectionFile(fileObj.param);
        return;
      }

      if (!this.uploadUrl) {
        await this.initUploadUrl();
      }
      this.total = 0;
      target.handleProgress({ percent: 0 }, file);

      // 解析为BUFFER数据
      // 我们会把文件切片处理：把一个文件分割成为好几个部分（固定数量/固定大小）
      // 每一个切片有自己的部分数据和自己的名字
      // HASH_1.mp4
      // HASH_2.mp4
      // ...

      this.getFileMd5(file,  (md5) => {
        /* let spark = new imFun.SparkMD5.ArrayBuffer(),
          chunkSize = this.chunkSize * 1024 * 1024, // Read in chunks of 2MB
          chunks = Math.ceil(file.size / chunkSize),
          hash,
          suffix;
        spark.append(buffer);
        hash = spark.end(); */

        let chunkSize = this.chunkSize * 1024 * 1024, // Read in chunks of 2MB
        chunks = Math.ceil(file.size / chunkSize),
        hash = md5,
        suffix;

        let nameSplit = /\.([0-9a-zA-Z]+)$/i.exec(file.name);

        suffix = nameSplit && nameSplit.length > 1 ? nameSplit[1] : "";

        let checkUrl = this.uploadUrl.replace(
          "/docfile/upload",
          "/docfile/check"
        );
        let checkData = {
          name: file.name,
          md5: hash,
        };
        let abort;
        let checkReq = this.$http({
          url: checkUrl,
          method: "post",
          cancelToken: new imFun.axios.CancelToken(function executor(c) {
            abort = c;
            file.abort = c;
          }),
          data: checkData,
          failMsg: false,
          modal: false,
          callback: (res) => {
            if (res.type == "success") {
              let resData = res.objx || {};
              let chunkParam = {
                fullFile: file,
                chunkSize: chunkSize,
                chunks: chunks,
                chunkIndex: 0,
                md5: hash,
                uuid: resData.uuid,
              };
              file.chunkParam = chunkParam;

              this.sendRequest(file);
            } else {
              this.handleFileError(
                new Error(
                  res.content ||
                    this.$t2("上传异常", "components.VabUpload.uploadException")
                ),
                file
              );
            }
          },
          error: (e) => {
            this.handleFileError(e, file);
          },
        });
        checkReq.abort = () => {
          abort(this.$t2("取消上传", "components.VabUpload.cancelUpload"));
        };
      });
    },
    async sendRequest(fullFile) {
      let that = this;
      let uploadUrl = this.uploadUrl;
      let chunkParam = fullFile.chunkParam;
      let target = that.$refs.upload;
      let abort;
      let config = {
        headers: {
          "Content-Type": "multipart/form-data",
        },
        cancelToken: new imFun.axios.CancelToken(function executor(c) {
          /* let target = that.$refs.upload;
          let filem = target.getFile(file);
          abort = c;
          filem.abort = c; */
          abort = c;
          fullFile.abort = c;
        }),
        onUploadProgress: (progressEvent) => {
          if (!target || !fullFile) return;
          let file = target.getFile(fullFile);
          if (file) {
            // progressEvent.loaded:已上传文件大小
            // progressEvent.total:被上传文件的总大小
            let start = chunkParam.start;
            let uploadedSize =
              start +
              Math.floor(
                (chunkParam.currentSize * progressEvent.loaded) /
                  progressEvent.total
              );
            let percent = Math.floor((uploadedSize * 100) / fullFile.size);
            if (percent == 100) {
              percent = 99;
            }
            progressEvent.percent = percent;
            target.handleProgress(progressEvent, fullFile);
          }
        },
        failMsg: false,
        modal: false,
      }; //添加请求头

      let chunkIndex = chunkParam.chunkIndex;
      let chunkSize = chunkParam.chunkSize;
      var start = chunkIndex * chunkSize,
        end =
          start + chunkSize >= fullFile.size
            ? fullFile.size
            : start + chunkParam.chunkSize;
      chunkParam.currentSize = end - start;
      chunkParam.start = start;
      chunkParam.end = end;

      let preFormData = {
        file: fullFile.slice(start, end),
        name: fullFile.name,
        chunks: chunkParam.chunks,
        chunk: chunkIndex,
        md5: chunkParam.md5,
        uuid: chunkParam.uuid,
        fileSize: fullFile.size,
      };

      let formData = new FormData();
      Object.keys(preFormData).forEach((key) => {
        formData.append(key, preFormData[key]);
      });

      let req = this.$http
        .post(uploadUrl, formData, config)
        .then((res1) => {
          if (res1.type == "success") {
            if (preFormData.chunk + 1 >= preFormData.chunks) {
              let mergeData = {};
              Object.keys(preFormData).forEach((key) => {
                if (key != "file" && key != "chunk") {
                  mergeData[key] = preFormData[key];
                }
              });
              let _param = {
                mergeData: mergeData,
                chunkParam: chunkParam,
              };
              this.mergeFile(_param);
            } else {
              chunkParam.chunkIndex = chunkParam.chunkIndex + 1;
              this.sendRequest(fullFile);
            }
          } else {
            this.handleFileError(
              new Error(
                res1.content ||
                  this.$t2("上传异常", "components.VabUpload.uploadException")
              ),
              fullFile
            );
          }
          return res1;
        })
        .catch((err) => {
          try {
            if (!abort) {
              this.handleFileError(err, fullFile);
            }
          } catch (tt) {}
        });
      req.abort = () => {
        abort(this.$t2("取消上传", "components.VabUpload.cancelUpload"));
      };
    },
    mergeFile(param) {
      let mergeData = param.mergeData;
      let chunkParam = param.chunkParam;
      let fullFile = chunkParam.fullFile;
      let mergeUrl = this.uploadUrl.replace(
        "/docfile/upload",
        "/docfile/merge"
      );
      let target = this.$refs.upload;
      this.$http({
        url: mergeUrl,
        method: "post",
        data: mergeData,
        failMsg: false,
        modal: false,
        cancelToken: new imFun.axios.CancelToken(function executor(c) {
          if (fullFile) fullFile.abort = c;
        }),
        callback: (res) => {
          if (!target || !fullFile) return;
          if (res.type == "success") {
            let file = target.getFile(fullFile);
            if (file) {
              target.handleProgress(
                {
                  percent: 100,
                },
                fullFile
              );
              target.handleSuccess(res, fullFile);
            }
          } else {
            this.handleFileError(
              new Error(
                res.content ||
                  this.$t2("上传异常", "components.VabUpload.uploadException")
              ),
              fullFile
            );
          }
        },
        error: (e) => {
          if (!target || !fullFile) return;
          if (fullFile) {
            let file = target.getFile(fullFile);
            if (file) {
              this.handleFileError(e, fullFile);
            }
          }
        },
      });
    },
    handleBtn() {
      let target = this.$refs.upload;
      let fileList = (target.uploadFiles || []).filter((item) => {
        return item.status == "uploading" || item.status == "ready";
      });
      if (this.btn) {
        //断点续传
        this.abort = false;
        this.btn = false;
        fileList.forEach((uploadFile) => {
          let nextChunk = uploadFile.raw.nextChunk;
          this.sendRequest(uploadFile.raw.partList, nextChunk);
        });
      } else {
        //暂停上传
        fileList.forEach((uploadFile) => {
          uploadFile.raw.abort(
            this.$t2("取消上传", "components.VabUpload.cancelUpload")
          );
        });
        this.btn = true;
        this.abort = true;
      }
    },
    //end
    getShowImage(file, fileName) {
      fileName = fileName || file.name;
      if (this.$commonFileUtil.isPictureFile(fileName)) {
        return file.showUrl || file.url;
      } else {
        return this.$commonFileUtil.getFileIconRequire(fileName);
      }
    },
    removeFile(sfile) {
      var target = this.$refs.upload;
      var index;
      var fileList = target.uploadFiles;
      for (let i = 0; i < fileList.length; i++) {
        let file = fileList[i];
        if (sfile.uid == file.uid) {
          index = i;
          if (sfile.status == "uploading") {
            // file.status == 'delete'
            //target.abort(file);
            file.raw.abort &&
              file.raw.abort(
                this.$t2("取消上传", "components.VabUpload.cancelUpload")
              );
          }
          break;
        }
      }

      target.uploadFiles.splice(index, 1);
      this.handleChange(sfile, target.uploadFiles);
    },
    submitImage() {
      var target = this.$refs.upload;
      var fileList = target.uploadFiles;
      let fileInfos = [];
      let fileDatas = [];
      for (let i = 0; i < fileList.length; i++) {
        let file = fileList[i];
        if (file.status == "uploading") {
          this.$message({
            message: this.$t2(
              "文件上传中",
              "components.VabUpload.fileUploading"
            ),
            type: "error",
            duration: 2000,
          });
          return;
        }
        if (file.status == "success") {
          let fileData = file.response.objx;
          fileData.name = file.name;
          let fileInfo = {
            name: file.name,
            fileData: fileData,
            file: file.raw,
          };
          fileInfos.push(fileInfo);
          fileDatas.push(fileData);
        }
      }
      this.handleClose();
      this.$emit("callback", fileInfos, fileDatas);
      this.callback && this.callback(fileDatas, fileInfos);
    },
    showViewDialog(lineData) {
      var data = lineData.fileData ? lineData.fileData : lineData;

      let thumbnail = data ? data.thumbnail || "" : "";

      var realUrl = data.domain + data.url;
      var showUrl = "";
      let fileName = lineData ? lineData.name || "" : "";
      if (!this.$commonFileUtil.isPictureFile(fileName)) {
        showUrl = this.$commonFileUtil.getFileIconRequire(fileName);
      } else if (thumbnail) {
        showUrl = data.domain + thumbnail;
      } else {
        showUrl = data.domain + data.url;
      }

      var preName = "";
      var suffix = "";
      var i = fileName.lastIndexOf(".");
      if (i >= 0) {
        suffix = fileName.substring(i + 1, fileName.length).toLowerCase();
      }
      this.fileViewInfo = {
        realUrl: realUrl,
        showUrl: showUrl,
        fileName: fileName,
        suffix: suffix,
        data: data,
      };
      this.fileViewDialogVisible = true;
    },
    getShowUrl(attachment, field) {
      let showUrl = null;
      let typeStr = Object.prototype.toString.call(attachment);
      if (typeStr == "[object Object]") {
        let showField = field ? field : "medium";
        let fullUrl =
          attachment.domain +
          (attachment[showField] ? attachment[showField] : attachment.url);
        showUrl = this.$commonFileUtil.getShowUrl(fullUrl);
      } else {
        showUrl = this.$commonFileUtil.getShowUrl(attachment);
      }
      return showUrl;
    },
    addPrivateFiles(rows) {
      var target = this.$refs.upload;
      let uploadFiles = target.uploadFiles;
      let sourceSns = uploadFiles
        .filter((row) => {
          return !!(
            row.response &&
            row.response.objx &&
            row.response.objx.sourceSn
          );
        })
        .map((row) => row.response.objx.sourceSn);

      let newFiles = rows
        .filter((row) => !row.dirs && !sourceSns.includes(row.sn))
        .map((row) => {
          let item = {
            status: "success",
            name: row.fileName,
            size: row.fileSize,
            percentage: 100,
            uid: row.fileSn,
            raw: {
              lastModified: "",
              lastModifiedDate: new Date(),
              name: row.fileName,
              size: row.fileSize,
              type: "",
              uid: row.fileSn,
              webkitRelativePath: "",
            },
            response: {
              time: "",
              type: "success",
              objx: {
                thumbnail: row.thumbnail,
                extension: row.extension,
                large: row.large,
                fileSize: row.fileSize,
                domain: row.domain,
                source: row.source,
                medium: row.medium,
                url: row.url,
                sourceSn: row.sn,
              },
              content: "success",
              rmid: null,
            },
            url: row.domain + row.url,
            showUrl: this.getShowUrl(row),
          };
          return item;
        });
      uploadFiles.push(...newFiles);
    },
    confirmPrivateProfileDialog(rows) {
      this.addPrivateFiles(rows);
    },
    initPrivateUploadBt() {
      if (settingConfig.privateProfileCode && this.pickPrivateProfile) {
        this.$http({
          url: USER_PREFIX + "/file_store_area/getByCode",
          method: "post",
          data: { stringOne: settingConfig.privateProfileCode },
          failMsg: false,
          errorMsg: false,
          success: (res) => {
            this.showPrivateUploadBtn = res.objx ? true : false;
          },
        });
      } else {
        this.showPrivateUploadBtn = false;
      }
    },
    initPickUploadMode() {
      this.showLocalUploadBtn = false;
      this.showPrivateUploadBtn = false;
      this.$http({
        url: USER_PREFIX + "/system_parameter/getByCode",
        method: "post",
        data: { code: "pickUploadMode" },
        success: (res) => {
          let value = !res.objx || !res.objx.value ? "2" : res.objx.value;
          if (value == "0") {
            //启用本地上传，个人文档上传
            this.showLocalUploadBtn = true;
            this.initPrivateUploadBt();
          } else if (value == "1") {
            //启用个人文档上传
            this.initPrivateUploadBt();
          } else if (value == "2") {
            //启用本地上传
            this.showLocalUploadBtn = true;
          }
        },
      });
    },
    pasteEvent(e) {
      // e.preventDefault();
      e.stopPropagation();
      if (!this.pasteAreaStatus) {
        return;
      }
      if (!(e.clipboardData && e.clipboardData.items)) {
        return;
      }
      let files = Array.from(e.clipboardData.files);
      let getFileSuffix = this.$commonFileUtil.getFileSuffix;
      if (files.length) {
        let fileList = files.map((rawFile) => {
          let name = rawFile.name;
          let index = name.lastIndexOf(".");
          let fileSuffix = getFileSuffix(name);
          let fileName =
            index >= 0 ? name.substring(0, index).toString() : name.toString();
          let file = {
            name: rawFile.name,
            size: rawFile.size,
            raw: rawFile,
            showUrl: URL.createObjectURL(rawFile),
            fileName: fileName,
            fileSuffix: fileSuffix,
          };
          return file;
        });
        this.pasteList.push(...fileList);
      }
    },
    deletePasteFile(index) {
      this.pasteList.splice(index, 1);
    },
    confirmPasteFile() {
      let target = this.$refs.upload;
      let innerTarget = target.$refs["upload-inner"];
      let pasteList = this.$baseLodash.cloneDeep(this.pasteList);
      let files = pasteList.map((item) => {
        let name = item.name;
        let fileRaw = item.raw;
        fileRaw.fileName = name;
        return fileRaw;
      });
      innerTarget.uploadFiles(files);
      this.$nextTick(() => {
        target.uploadFiles.forEach((uploadFile) => {
          let fileRaw = uploadFile.raw;
          if (fileRaw.fileName) {
            uploadFile.name = fileRaw.fileName;
            delete fileRaw.fileName;
          }
        });
      });
      this.pasteList = [];
    },
    changeFileName(file) {
      if (file.fileSuffix) {
        file.name = (file.fileName + "." + file.fileSuffix).toString();
      } else {
        file.name = file.fileName.toString();
      }
    },
    handleFileError(err, rawFile) {
      let target = this.$refs.upload;
      if (!target) return;
      const file = target.getFile(rawFile);
      const fileList = target.uploadFiles;

      file.status = "fail";
      file.failMsg = err && err.message ? err.message : null;

      // fileList.splice(fileList.indexOf(file), 1);

      target.onError(err, file, target.uploadFiles);
      target.onChange(file, target.uploadFiles);
      this.updateUploadingStatus();
    },
    choosePasteArea(e) {
      e.stopPropagation();
      this.pasteAreaStatus = true;
    },
    openFileNameDialog(row, index) {
      this.editFileName = row.fileName?.toString();
      this.editFileSuffix = row.fileSuffix?.toString();
      this.editFileIndex = index;
      this.showFileNameDialog = true;
    },
    confirmFileNameDialog() {
      if (!this.editFileName) {
        this.$message({
          message: this.$t2("文件名不能为空", "components.VabUpload.warnMsg3"),
          type: "error",
          showClose: true,
          duration: 3000,
        });
        return;
      }
      let editFileIndex = this.editFileIndex;
      let file = this.pasteList[editFileIndex];
      file.fileName = this.editFileName.toString();
      file.name = (file.fileName + "." + file.fileSuffix).toString();
      this.showFileNameDialog = false;
    },
  },
};

tViewMixins = {
  props: {
    resultType: String,
    dataType: String,
    callback: Function,
    file: {
      type: [Array, Object, String],
    },
    multi: {
      type: [String, Boolean],
      default: true,
    },
    auto: {
      type: Boolean,
      default: true,
    },
    limit: {
      type: Number,
      default: 100000,
    },
    size: {
      type: Number,
      default: 200,
    },
    accept: {
      type: String,
      default: "file",
    },
    chunkSize: {
      type: Number,
      default: 5, //5MB
    },
    confirmUpload: {
      type: Function,
    },
    pickPrivateProfile: {
      type: Boolean,
      default: true,
    },
    uploadingLimit: {
      type: Number,
      default: 5, //5MB
    },
    isPartUpload: {
      type: Boolean,
      default: () => {
        return settingConfig.isPartUpload ?? true;
      }
    },
    autoConfirmAfterPasteUpload: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    return {
      attachments: [],
      pictureList: [],
      pictureDtoList: [],
      showPropertiesDialog: false,
      editAttachment: null,
      showViewer: false,
      chooseIndex: 0,
      fileServerInfo: {},
      model: null
    };
  },
  computed: {
    fileServerPreviewEnabled(){
      return this.getFileServerPreviewEnabled();
    },
    fileShowImageEnabled(){
      return this.getFileShowImageEnabled();
    },
    fileMaxSize() {
      return this.size;
    },
    showUploadBtn: function () {
      if (!this.isMulti) {
        return this.attachments.length == 0;
      } else {
        return this.limit ? this.limit > this.attachments.length : true;
      }
    },
    isMulti: function () {
      let isMulti = true;
      if (this.multi === "false" || this.multi === false || this.limit === 1) {
        isMulti = false;
      }
      return isMulti;
    },
  },
  watch: {
    file(val) {
      this.initFile();
    },
    attachments(val) {
      let that = this;
      let pictureList = [];
      let pictureDtoList = [];
      if (val) {
        val.forEach((item) => {
          if (item) {
            let typeStr = Object.prototype.toString.call(item);
            if (
              typeStr == "[object Object]" &&
              Object.keys(this.file).length > 0
            ) {
              if (that.$commonFileUtil.isPictureFile(item.url)) {
                pictureList.push(item.domain + item.url);
                pictureDtoList.push(item);
              }
            } else {
              if (that.$commonFileUtil.isPictureFile(item)) {
                pictureList.push(item);
                pictureDtoList.push(item);
              }
            }
          }
        });
      }
      this.pictureList = pictureList;
      this.pictureDtoList = pictureDtoList;
    },
  },
  created() {
    this.initFileServerInfo();
    this.initFile();
  },
  methods: {
    pasteEvent(e) {
      e.stopPropagation();
      if (!(e.clipboardData && e.clipboardData.items)) {
        return
      }
      let files = Array.from(e.clipboardData.files);
      if (files.length) {
        this.openUploadDialog(files, this.autoConfirmAfterPasteUpload)
      }
    },
    uploadEnterOver() {
      // if (this.isLoading) return;
      document.addEventListener('paste', this.pasteEvent);
    },
    uploadEnterLeave() {
      document.removeEventListener('paste', this.pasteEvent);
    },
    getFileServerPreviewEnabled(){
      let value =  window.$vueRoot.$store.getters.fileServerInfo?.fileServerPreviewEnabled ?? (settingConfig.fileServerPreviewEnabled ?? true);
      if(this.$attrs.fileServerPreviewEnabled!== null && this.$attrs.fileServerPreviewEnabled!== undefined){
        value = this.$attrs.fileServerPreviewEnabled
      }
      return value;
    },
    getFileShowImageEnabled(){
      let value =  window.$vueRoot.$store.getters.fileServerInfo?.fileShowImageEnabled ?? (settingConfig.fileShowImageEnabled ?? true);
      if(this.$attrs.fileShowImageEnabled!== null && this.$attrs.fileShowImageEnabled!== undefined){
        value = this.$attrs.fileShowImageEnabled
      }
      return value;
    },
    openUploadDialog(files,autoConfirmAfterUpload) {
      this.$baseUpload.open({
        files,
        autoConfirmAfterUpload,
        ...this.fileServerInfo,
        ...this._props,
        ...this.$attrs,
        limit: this.limit,
        multi: this.multi,
        accept: this.accept ? this.accept : "file",
        auto: this.auto,
        size: this.fileMaxSize,
        chunkSize: this.chunkSize,
        callback: this.fileConfirm,
        pickPrivateProfile: this.pickPrivateProfile,
        confirmUpload: this.confirmUpload,
        otherParams: this.$attrs,
      });
    },
    initFileServerInfo() {
      if (this.$attrs.model) {
        this.model = this.$attrs.model;
        // this.fileServerInfo = this.$attrs.fileServerInfo;
      } else {
        this.model = window.$vueRoot.$store.getters.fileServerInfo?.model ?? null;
        /* getFileServerInfo(this, (res) => {
          if (res) {
            let fileServerInfo = res;
            this.model = fileServerInfo.model
            this.fileServerInfo = fileServerInfo;
          }else{
            this.model = null;
            this.fileServerInfo = null;
          }
        }) */
      }
    },
    initFile() {
      if (this.file) {
        let typeStr = Object.prototype.toString.call(this.file);
        if (!this.dataType) {
          if (typeStr == "[object Array]") {
            this.attachments = this.file;
          } else if (
            typeStr == "[object Object]" &&
            Object.keys(this.file).length > 0
          ) {
            this.attachments = [this.file];
          } else {
            this.attachments = [];
          }
        } else {
          this.attachments = [this.file];
        }
      } else {
        this.attachments = [];
      }
    },
    deleteFile(index) {
      if (!this.$listeners.delete || this.$listeners.delete(index) !== false) {
        this.attachments.splice(index, 1);
        this.updatePropFile();
        this.$emit("afterDelete", this.attachments);
      }
    },
    fileConfirm(rows, fileInfos) {
      if (rows.length > 0) {
        if (this.isMulti) {
          let limit = this.limit;
          if (limit) {
            let oSize = this.file?.length ?? 0;
            let vailSize = limit - oSize;
            if (vailSize > 0) {
              rows = rows.length < vailSize ? rows : rows.slice(0, vailSize);
            } else {
              rows = [];
            }
          }
        } else {
          rows = [rows[0]];
        }

        let attachments = this.attachments;
        let dataType = this.dataType;
        let eRows = [];
        if (dataType != null) {
          eRows = rows.map((row) => {
            return row.domain + (row[dataType] || row["url"]);
          });
        } else {
          eRows = rows;
        }

        if (
          !this.$listeners.confirm ||
          this.$listeners.confirm(eRows, fileInfos) !== false
        ) {
          if (this.isMulti) {
            this.attachments = attachments.concat(eRows);
          } else {
            this.attachments = eRows;
          }
          this.updatePropFile();
          this.$emit("callback", eRows, fileInfos);
        }
      }
    },
    updatePropFile() {
      if (this.isMulti) {
        this.$emit("update:file", this.attachments);
      } else {
        let result =
          this.attachments && this.attachments.length
            ? this.attachments[0]
            : null;
        if (
          this.resultType == "Array" ||
          (this.multi !== "false" && this.multi !== false)
        ) {
          result = result ? [result] : [];
        }
        this.$emit("update:file", result);
      }
      this.handleChange();
    },
    handleChange() {
      this.$emit("change", this.attachments);
    },
    getRealPictureList(index) {
      let pictureIndex = -1;
      this.attachments.find((item, i) => {
        let typeStr = Object.prototype.toString.call(item);
        if (typeStr == "[object Object]") {
          if (this.$commonFileUtil.isPictureFile(item.url)) {
            pictureIndex++;
          }
        } else {
          if (this.$commonFileUtil.isPictureFile(item)) {
            pictureIndex++;
          }
        }
        return index == i;
      });
      return this.pictureList
        .slice(pictureIndex)
        .concat(this.pictureList.slice(0, pictureIndex));
    },
    getRealPictureDTOList() {
      let index = this.chooseIndex || 0;
      let pictureIndex = -1;
      this.attachments.find((item, i) => {
        let typeStr = Object.prototype.toString.call(item);
        if (typeStr == "[object Object]") {
          if (this.$commonFileUtil.isPictureFile(item.url)) {
            pictureIndex++;
          }
        } else {
          if (this.$commonFileUtil.isPictureFile(item)) {
            pictureIndex++;
          }
        }
        return index == i;
      });
      let res = this.pictureDtoList
        .slice(pictureIndex)
        .concat(this.pictureDtoList.slice(0, pictureIndex));
      return res;
    },
    openImagePreView(index) {
      // this.chooseIndex = index;
      let pictureIndex = -1;
      this.attachments.find((item, i) => {
        let typeStr = Object.prototype.toString.call(item);
        if (typeStr == "[object Object]") {
          if (this.$commonFileUtil.isPictureFile(item.url)) {
            pictureIndex++;
          }
        } else {
          if (this.$commonFileUtil.isPictureFile(item)) {
            pictureIndex++;
          }
        }
        return index == i;
      });
      this.chooseIndex = pictureIndex;
      this.showViewer = true;
    },
    openPropertiesDialog(attachment) {
      this.editAttachment = attachment;
      this.showPropertiesDialog = true;
    },
    closeViewer() {
      this.showViewer = false;
    },
    hasPreview(attachment) {
      let fileServerPreviewEnabled = this.getFileServerPreviewEnabled();
      let typeStr = Object.prototype.toString.call(attachment);
      let url =
        typeStr == "[object Object]"
          ? attachment.domain + attachment.url
          : attachment;
      if (fileServerPreviewEnabled) {
        return (
          this.$commonFileUtil.isPictureFile(url) ||
          this.$commonFileUtil.isPreviewFile(url)
        );
      } else {
        return this.$commonFileUtil.isPictureFile(url);
      }
    },
    openPreview(attachment, index) {
      let fileServerPreviewEnabled = this.getFileServerPreviewEnabled();
      let typeStr = Object.prototype.toString.call(attachment);
      let url =
        typeStr == "[object Object]"
          ? attachment.domain + attachment.url
          : attachment;
      if (this.$commonFileUtil.isPictureFile(url)) {
        this.openImagePreView(index);
      } else if (fileServerPreviewEnabled && this.$commonFileUtil.isPreviewFile(url)) {
        this.$openFilePreview(url);
      }
    },
    getAttachmentName(attachment) {
      let name = null;
      let typeStr = Object.prototype.toString.call(attachment);
      if (typeStr == "[object Object]") {
        name = attachment.name;
      } else {
        let url = attachment;
        if (url) {
          var i = url.lastIndexOf("/");
          if (i >= 0) {
            name = url.substring(i + 1, url.length);
          }
        }
      }
      return name;
    },
    getShowUrl(attachment, field) {
      let showUrl = null;
      let showImagePreview = this.getFileShowImageEnabled();
      let typeStr = Object.prototype.toString.call(attachment);
      if (typeStr == "[object Object]") {
        let showField = field ? field : "medium";
        let fullUrl = attachment.domain + (showImagePreview && attachment[showField] ? attachment[showField] : attachment.url);
        showUrl = this.$commonFileUtil.getShowUrl(fullUrl, showImagePreview);
      } else {
        showUrl = this.$commonFileUtil.getShowUrl(attachment, showImagePreview);
      }
      return showUrl;
    },
    downloadFile(attachment) {
      let typeStr = Object.prototype.toString.call(attachment);
      if (typeStr == "[object Object]") {
        this.$commonFileUtil.downloadFile(
          attachment.domain + attachment.url,
          attachment.name
        );
      } else {
        this.$commonFileUtil.downloadFile(attachment);
      }
    },
    formatFileSize(fileSize) {
      return formatFileSize(fileSize);
    },
  },
};

pmixins = {
  name: "propertiesDialog",
  components: {},
  created() {
    this.attachmentDTO = this.$attrs.editAttachment;
    this.current_prefix =
      this.attachmentDTO && this.attachmentDTO.serverName
        ? "/" + this.attachmentDTO.serverName
        : "";
  },
  mounted() {
    this.initTableM1();
  },
  data() {
    return {
      showDialog: true,
      falseValue: false,
      vxeOption: {},
      showContent: true,
      attachmentDTO: {},
      current_prefix: "",
    };
  },
  methods: {
    saveData() {
      this.$refs.editForm.validate((valid) => {
        if (valid) {
          this.$baseConfirm(
            this.$t2("您确定要保存吗？", "components.VabUpload.saveTip")
          ).then(() => {
            let formData = commonDataUtil.handleForm(this.attachmentDTO);

            var url = this.current_prefix + "/attachment/attribute/save";
            this.$http({
              url: url,
              method: "post",
              data: formData,
              isLoading: true,
              success: (res) => {
                this.$message({
                  message: res.content,
                  type: "success",
                  duration: 500,
                  onClose: (t) => {
                    this.reloadContent();
                  },
                });
              },
            });
          });
        }
      });
    },
    dialogClose() {
      this.$emit("update:visiable", false);
    },
    reloadContent() {
      this.getData();
    },
    getData() {
      this.$http({
        url: this.current_prefix + "/attachment/attribute/list",
        method: "post",
        data: {
          id: this.attachmentDTO.id,
        },
        isLoading: true,
        // modalStrictly: true,
        success: (res) => {
          this.$set(
            this.attachmentDTO,
            "attachmentAttributeDTOs",
            res.objx || []
          );
        },
      });
      this.getUserBasicInfos();
    },
    getUserBasicInfos() {
      let createBy = this.attachmentDTO.createBy;
      if (!!this.attachmentDTO._createBy || !createBy) return;
      this.$http({
        url: USER_PREFIX + `/userb/getUserBasicInfos`,
        method: "post",
        data: [createBy],
        isLoading: true,
        // modalStrictly: true,
        success: (res) => {
          let _createBy = createBy;
          if (res.objx?.length) {
            let nickName = res.objx[0].nickName;
            let queryCreateInfo =
              window.$vueRoot.$store.getters.queryCreateInfo || "0";
            if (nickName) {
              if (queryCreateInfo == "1") {
                _createBy = createBy + "(" + nickName + ")";
              } else if (queryCreateInfo == "2") {
                _createBy = nickName;
              }
            }
          }
          this.$set(this.attachmentDTO, "_createBy", _createBy);
        },
      });
    },
    initTableM1() {
      //明细
      var that = this;
      const tableRef = "table-m1";
      const tableOption = {
        vue: this,
        tableRef: tableRef,
        tableName: "components_vabUpload_propertiesDialog_list-m1",
        columns: [
          {
            type: "checkbox",
            fixed: "left",
            width: 48,
            resizable: false,
          },
          {
            title: this.$t2("属性名称", "components.VabUpload.attributeName"),
            field: "attributeName",
            width: 200,
            slots: {
              default: "attributeName",
            },
          },
          {
            title: this.$t2("属性值", "components.VabUpload.attributeValue"),
            field: "attributeValue",
            width: 200,
            slots: {
              default: "attributeValue",
            },
          },
          {
            width: 50,
            fixed: "right",
            title: "",
            sortable: false,
            slots: {
              default: "operate",
            },
          },
        ],
      };
      this.$vxeTableUtil.initVxeTable(tableOption).then((opts) => {
        this.vxeOption = opts;
      });
      this.getData();
    },
    addItem() {
      this.attachmentDTO.attachmentAttributeDTOs.push({});
    },
    formatFileSize(fileSize) {
      return formatFileSize(fileSize);
    },
  },
};

function getFileServerInfo(that, callback) {
  that.$http({
    url: USER_PREFIX + "/logic_param/getFileServerInfo",
    method: "post",
    data: {},
    failMsg: false,
    errorMsg: false,
    modal: false,
    success: (res) => {
      if (res.objx) {
        callback && callback(res.objx);
      } else {
        callback && callback();
      }
    },
    error: (err) => {
      callback && callback();
    },
  });
}

function formatFileSize(fileSize) {
  fileSize = fileSize || 0;
  if (fileSize < 1024) {
    return fileSize + "B";
  } else if (fileSize < 1024 * 1024) {
    var temp = fileSize / 1024;
    temp = temp.toFixed(2);
    return temp + "KB";
  } else if (fileSize < 1024 * 1024 * 1024) {
    var temp = fileSize / (1024 * 1024);
    temp = temp.toFixed(2);
    return temp + "MB";
  } else {
    var temp = fileSize / (1024 * 1024 * 1024);
    temp = temp.toFixed(2);
    return temp + "GB";
  }
}

export const mixins = tmixins;
export const viewMixins = tViewMixins;
export const propertiesMixins = pmixins;
