<template>
  <div class="app-container" v-loading="loading">
    <div class="top-bar">
      <SearchBar :config="searchConfig" @search="search" @reset="reset" />
    </div>
    <div class="tools">
      <div class="tools-item">
        <el-button
          :disabled="loading"
          size="mini"
          type="primary"
          @click.native="handleOperation({ type: 'downloadTemplate' })"
          icon="el-icon-download"
        >
          下载导入模板</el-button
        >

        <el-button
          type="primary"
          size="mini"
          @click.native="handleOperation({ type: 'viewImportRecord' })"
          icon="el-icon-document"
          plain
        >
          查看导入记录</el-button
        >
      </div>
      <div class="tools-item">
        <el-button
          type="primary"
          size="mini"
          @click.native="handleOperation({ type: 'add' })"
          icon="el-icon-plus"
        >
          添加</el-button
        >
        <el-upload
          class="upload-button"
          :action="importZipUrl"
          :headers="headers"
          accept=".zip"
          :show-file-list="false"
          :before-upload="handleUpload"
          :on-success="handleSuccess"
          multiple
        >
          <el-button
            type="success"
            size="mini"
            @click.native="handleOperation({ type: 'multiAdd' })"
            icon="el-icon-upload"
          >
            整量导入</el-button
          >
        </el-upload>
      </div>
    </div>
    <TablePage
      :data="list.records"
      :tableTitle="tableTitle"
      :operates="tableOperates"
    >
      <template v-slot:status="data">
        <el-popconfirm
          :title="getStatusTitle(data.scope.status)"
          @confirm="handleChangeStatus(data.scope)"
          v-if="!isDisabledStatusbtn(data.scope.checkStatus)"
        >
          <el-switch
            slot="reference"
            :disabled="isDisabledStatusbtn(data.scope.checkStatus)"
            :value="Boolean(Number(data.scope.status))"
          ></el-switch>
        </el-popconfirm>
        <el-switch
          slot="reference"
          :disabled="isDisabledStatusbtn(data.scope.checkStatus)"
          :value="Boolean(Number(data.scope.status))"
          v-else
        ></el-switch>
      </template>
      <template v-slot:displayType="data">
        {{ dicts.displayType[data.scope.type] }}
      </template>
      <template v-slot:checkStatus="data">
        <!-- {{ data.scope.checkStatus }} -->
        <el-tag type="primary" v-if="data.scope.checkStatus == 0">
          审核中
        </el-tag>
        <el-tag type="success" v-if="data.scope.checkStatus == 1">
          已通过
        </el-tag>
        <el-tag type="danger" v-if="data.scope.checkStatus == -2">
          已驳回
        </el-tag>
        <el-tag type="warning" v-if="data.scope.checkStatus == -1">
          待提交
        </el-tag>
      </template>
      <template v-slot:faceImageUrl="data">
        <img
          :src="
            $getFullUrl(data.scope.faceImagePressUrl || data.scope.faceImageUrl)
          "
          alt="暂无图片"
          v-if="
            $getFullUrl(data.scope.faceImagePressUrl || data.scope.faceImageUrl)
          "
          style="cursor: pointer"
          width="100px"
          @click="handelPreviewImages(data.scope.faceImageUrl)"
        />
      </template>
      <template v-slot:themeType="data">
        {{ themeTypeCode(data.scope.themeType) }}
      </template>
      <template v-slot:operates="scope">
        <TableOperation
          :operations="tableOperations"
          :rawData="scope.scope.row"
          @handleOperation="handleOperation"
          :disabled="isDisabled(scope.scope.row.checkStatus)"
        >
        </TableOperation>
      </template>
    </TablePage>
    <el-pagination
      style="margin: 16px 0"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="Number(list.current)"
      :page-sizes="[10, 20, 50, 100]"
      :page-size="Number(list.size)"
      layout="total, sizes, prev, pager, next, jumper"
      :total="Number(list.total)"
      class="pagination"
    >
    </el-pagination>
    <InfoEditDialog
      :visible="editDialogVisible"
      :form="form"
      :currentPageIds="currentPageIds"
      @handleClose="handleClose"
      @refresh="loadData"
      @changeDisplay="reloadDisplay"
      ref="InfoEditDialog"
    />
    <PreviewDialog
      v-if="Object.keys(curPreviewObj).length > 0"
      :visible="previewDialogVisible"
      :displayDetail="curPreviewObj"
      @handleClose="handleClosePreviewDialog"
    />
    <ImportRecordDialog
      :visible="importRecordVisible"
      @reload="loadData"
      @handleClose="handleImportRecordClose"
    />

    <UploadListDialog
      :visible="multiUploadVisible"
      :filesList="filesList"
      @handleClose="handleMultiUploadClose"
      @handleCancel="handleMultiUploadCancel"
    />

    <el-image-viewer
      v-if="imgViewerVisible"
      :on-close="closeImgViewer"
      :url-list="imgList"
    />
  </div>
</template>

<script>
import { title, operates, operations } from "./configs/list";
import {
  getListPer,
  deleteDisplay,
  getDisplayById,
  editDisplay,
} from "@/api/display";
import InfoEditDialog from "./components/InfoEditDialog";
import PreviewDialog from "./components/PreviewDialog";
import ImportRecordDialog from "./components/ImportRecordDialog";
import UploadListDialog from "./components/UploadListDialog";
import { mapGetters } from "vuex";
import { themeTypeCode } from "./contants";
import { getToken } from "@/utils/auth";
import { importZip } from "@/utils/file";
import { titles } from "@/utils/boutiqueTitles";
import { searchConfig } from "./configs/list";
export default {
  components: {
    InfoEditDialog,
    PreviewDialog,
    SearchBar,
    ImportRecordDialog,
    UploadListDialog,
  },
  data() {
    let that = this;
    return {
      list: {
        record: [],
        size: 10,
        current: 1,
        total: 0,
      },
      searchForm: {
        name: "",
        status: "",
      },
      searchConfig,
      editDialogVisible: false,
      isAdd: true,
      form: {
        title: "", //标题
        type: "", //	类别(待定)--枚举值（社会、生活等）
        displayCharacter: "1", //展览性质(精品展2、布展1、文物展3)--此处填写布展类别
        keyword: "", //	关键词
        deptId: "", //展览单位id--暂填入用户自己的单位
        regionCode: "", //	所在地域--暂填入用户自己的地区
        intro: "", //展览介绍,
        themeType: "1", //模板主题--前端枚举
        literature: "", //关联文献。id1,id2,id3--接口查询
        remark: "", //备注
        status: 1, //上下架状态(0-下架，1-上架）
        faceImage: "", //	封面（图片1张)
        images: "", //展览图片
        videos: "", //展览视频
        audios: "", //展览音频
        exhibitionUnits: [], //布展单元
      },
      loading: false,
      imgViewerVisible: false,
      previewDialogVisible: false,
      copyDialogVisible: false,
      previewVideos: [],
      displayTypes: {},
      curPreviewObj: {}, //当前预览的对象
      currentPageIds: [], //当前的id数组，用于给详情页切换用
      importZipUrl: process.env.VUE_APP_BASE_API + "/bizImport/importZip",
      headers: {
        authorization: getToken(),
      },
      multiUploadVisible: false, //控制批量上传弹窗显示
      importRecordVisible: false, //上传记录
      filesList: [], //上传当中的文件队列
      uploadCount: 0, //处于上传中的文件数量，当等于fileList的时候就关闭弹窗，请求完毕一个就++
      cancelUploadArr: [], //保存每个文件上传接口对应的取消请求的函数[fn,fn,fn...]
      isUpLoading: false,
    };
  },
  computed: {
    ...mapGetters(["dicts"]),
    tableTitle() {
      return title;
    },
    tableOperates() {
      return operates;
    },
    tableOperations() {
      return operations;
    },
    getStatusTitle(status) {
      return (status) => {
        if (Number(status)) {
          return "是否确定要下架？";
        } else {
          return "是否确定要上架？";
        }
      };
    },

    isDisabled(checkStatus) {
      return (checkStatus) => {
        return checkStatus == "0";
        //在审核中和已通过，则不能使用提交审核、编辑及删除按钮
      };
    },

    isDisabledStatusbtn(checkStatus) {
      //待提交、审核中，不能使用上下架
      return (checkStatus) => {
        return checkStatus == "0" || checkStatus == "-1";
      };
    },
  },

  async created() {
    await this.$store.dispatch("dict/getDictList", ["displayType"]);
    this.loadData();
  },

  //watch部分
  watch: {
    //监听弹窗变化
    multiUploadVisible(val) {
      //弹窗关闭记得清空，开启执行批量上传
      if (val) {
        for (let i = 0; i < this.filesList.length; i++) {
          this.uploadSelf(this.filesList[i].file, i); //弹窗显示的时候，就根据文件队列的数量调用上传接口
        }
      } else {
        //弹窗关闭，还原数据到初始位置
        this.filesList = [];
        this.uploadCount = 0;
        this.cancelUploadArr = [];
      }
    },
  },
  methods: {
    async search(form) {
      var params = {
        page: 1,
        limit: this.list.size,
        ...form,
      };
      if (params.status == "") {
        delete params.status;
      }
      let res = await getListPer(params);
      if (res.code == 0) {
        this.list = res.data;
        this.currentPageIds = this.list.records.map((item) => {
          return item.exhibitionId;
        });
      }
    },
    reset() {
      this.loadData();
    },

    // 加载表格数据
    async loadData() {
      var params = {
        page: this.list.current,
        limit: this.list.size,
      };
      let res = await getListPer(params);
      if (res.code == 0) {
        this.list = res.data;
        this.currentPageIds = this.list.records.map((item) => {
          return item.exhibitionId;
        });
      }
    },

    async handleOperation(value, row) {
      switch (value.type) {
        case "add":
          this.editDialogVisible = true;
        case "view":
          if (row) {
            if (titles.includes(row.title)) {
              this.$message.info("精品展暂不支持预览！");
              return;
            }
            this.previewDialogVisible = true;
            let res = await getDisplayById({ exhibitionId: row.exhibitionId });
            this.curPreviewObj = res.data;
          }
          break;
        case "edit":
          let editRes = await getDisplayById({
            exhibitionId: row.exhibitionId,
          });
          this.form = editRes.data;
          this.editDialogVisible = true;
          break;
        case "delete":
          let deleteRes = await deleteDisplay([row.exhibitionId]);
          if (deleteRes.code === 0) {
            this.loadData();
            this.$message.success("删除成功！");
          }
          break;
        case "multiAdd":
          // debugger
          // this.multiUploadVisible = true;
          // console.log("this.multiUploadVisible", this.multiUploadVisible);

          break;

        case "downloadTemplate":
          this.handleDownloadTemplate();
          break;
        case "viewImportRecord":
          this.importRecordVisible = true;
          break;
      }
    },

    //下载批量导入模板
    handleDownloadTemplate() {
      this.loading = true;
      let a = document.createElement("a");
      a.href = "/files/zip/displayImportTemplate.zip";
      a.download = "展览整量导入模板.zip";
      a.style.display = "none";
      document.body.appendChild(a);
      a.click();
      a.remove();
      this.loading = false;
    },

    uploadSelf(file, index) {
      let formData = new FormData();
      formData.append("type", "biz_exhibition");
      formData.append("zipFile", file);
      importZip(
        formData,
        (progressEvent) => this.uploadUnderWayCallback(progressEvent, index),
        (c) => this.cancelCallBack(c, index)
      ).then((res) => {
        if (res.data.code == 0) {
          this.$set(this.filesList[index], "status", "success");
          this.$set(this.filesList[index], "desc", "上传成功");
          this.$message.success("文件" + file.name + "上传成功！");
          this.loadData();
        } else {
          this.$set(this.filesList[index], "status", "warning");
          this.$set(this.filesList[index], "desc", "上传失败" + res.data.msg);
          this.$message.error("上传失败:" + res.data.msg);
          this.loadData();
        }
      });
    },

    // 文件上传进度回调
    uploadUnderWayCallback(progressEvent, index) {
      let completeVal =
        (progressEvent.loaded / progressEvent.total) * 100 - 1 || 0; //处理成组件库进度组件需要的格式
      this.$set(this.filesList[index], "percent", Math.floor(completeVal)); //直接改变数组某一项不是响应式的，因此我们需要用到这个api，将其响应式化，添加到数组中
    },

    // 文件取消回调
    cancelCallBack(c, index) {
      this.$set(this.cancelUploadArr, index, c); //添加取消队列中，关闭弹窗批量取消
      this.uploadCount = 0;
    },

    handleMultiUploadClose() {
      // 文件列表中如果Status为null，则代表有仍在上传中
      let isUpLoading = false;
      this.filesList.map((item) => {
        if (item.status == null) {
          isUpLoading = true;
          return;
        }
      });
      let title = isUpLoading ? "当前有上传任务，是否取消上传" : "确认关闭？";
      let confirmButtonText = isUpLoading ? "关闭并取消上传" : "确定";
      let cancelButtonText = isUpLoading ? "否" : "取消";
      let that = this;
      this.$confirm(title, "提示", {
        confirmButtonText,
        cancelButtonText,
        type: "warning",
      })
        .then(() => {
          // 点击取消上传
          if (that.isUpLoading) {
            this.handleCancelAllUpLoad();
            this.$message.warning("已取消上传！");
          }
          this.multiUploadVisible = false; //最后关闭
        })
        .catch(() => {
          console.log("用户取消操作");
        });
    },

    handleMultiUploadCancel(index) {
      if (this.cancelUploadArr[index]) {
        this.cancelUploadArr[index](); //取消上传
        this.cancelUploadArr.splice(index, 1); //从取消队列中删除
      }
      if (this.filesList[index]) {
        this.filesList.splice(index, 1);
      }
      this.$message.info("已取消上传！");
    },

    handleCancelAllUpLoad() {
      this.cancelUploadArr.forEach((cancelCallBack) => cancelCallBack()); //批量取消上传
    },

    handleSuccess(res) {
      res.Success && this.$Message.success("上传成功"); //提示
      // this.processModal = false; //成功后关闭弹窗
      this.filesList = [];
    },

    async reloadDisplay(exhibitionId) {
      this.$refs.InfoEditDialog.submitLoading = true;
      this.$refs.InfoEditDialog.loadingText = "加载中...";
      let editRes = await getDisplayById({
        exhibitionId,
      });
      this.form = editRes.data;
      this.$refs.InfoEditDialog.submitLoading = false;
    },
    async handleChangeStatus(row) {
      const { status } = row;
      let newStatus = status === "0" ? "1" : "0";
      const params = {
        ...row,
        status: newStatus,
      };
      let res = await editDisplay(params);
      if (res.code == 0) {
        this.loadData();
        this.$message.success("修改成功！");
      }
    },
    // 多选
    handleSelectionChange(val) {
      this.multipleSelection = val;
    },

    // 改变页容量
    handleSizeChange(value) {
      this.list.size = value;
      this.loadData();
    },

    // 改变当前显示页
    handleCurrentChange(value) {
      this.list.current = value;
      this.loadData();
    },

    // 搜索
    onSubmitSearch() {
      console.log("submit!");
    },
    // 关闭Dialog
    handleClose() {
      this.editDialogVisible = false;
      this.form = {
        status: 1,
        faceImage: "", //	封面（图片1张)
        images: "", //展览图片
        videos: "", //展览视频
        audios: "", //展览音频
        exhibitionUnits: [], //布展单元
      };
    },
    // 关闭预览图片
    closeImgViewer() {
      this.imgViewerVisible = false;
    },
    // 预览图片
    handelPreviewImages(images) {
      this.imgViewerVisible = true;
      this.imgList = [images];
    },

    handleClosePreviewDialog() {
      this.previewDialogVisible = false;
    },

    handleCopy() {
      this.copyDialogVisible = true;
    },
    handleCloseCopyDialog() {
      this.copyDialogVisible = false;
    },
    async handleCopySelect(value) {
      const { exhibitionId } = value;
      let res = await getDisplayById({ exhibitionId });
      delete res.data.exhibitionId;
      this.form = { ...res.data };
      this.editDialogVisible = true;
      console.log("this.form", this.form);
    },

    themeTypeCode(code) {
      return themeTypeCode[code];
    },

    // // 文件个数超出
    // handleExceed() {
    //   this.$message.error(`超出上传文件个数,请删除以后再上传！`);
    // },
    handleUpload(file) {
      this.multiUploadVisible = true; //显示弹窗
      this.filesList.push({
        file,
        name: file.name,
        size: file.size,
        status: null,
        desc: null,
      });
      return false; //阻止自动上传
    },

    handleSuccess(res) {
      res.Success && this.$Message.success("上传成功"); //提示
      // this.processModal = false; //成功后关闭弹窗
      this.filesList = [];
    },

    handleImportRecordClose() {
      this.importRecordVisible = false;
    },

    handleMultiUploadClose() {
      // 文件列表中如果Status为null，则代表有仍在上传中
      let isUpLoading = false;
      this.filesList.map((item) => {
        if (item.status == null) {
          isUpLoading = true;
          return;
        }
      });
      let title = isUpLoading ? "当前有上传任务，是否取消上传" : "确认关闭？";
      let confirmButtonText = isUpLoading ? "关闭并取消上传" : "确定";
      let cancelButtonText = isUpLoading ? "否" : "取消";
      let that = this;
      this.$confirm(title, "提示", {
        confirmButtonText,
        cancelButtonText,
        type: "warning",
      })
        .then(() => {
          // 点击取消上传
          if (that.isUpLoading) {
            this.handleCancelAllUpLoad();
            this.$message.warning("已取消上传！");
          }
          this.multiUploadVisible = false; //最后关闭
        })
        .catch(() => {
          console.log("用户取消操作");
        });
    },

    handleMultiUploadCancel(index) {
      if (this.cancelUploadArr[index]) {
        this.cancelUploadArr[index](); //取消上传
        this.cancelUploadArr.splice(index, 1); //从取消队列中删除
      }
      if (this.filesList[index]) {
        this.filesList.splice(index, 1);
      }
      this.$message.info("已取消上传！");
    },

    handleCancelAllUpLoad() {
      this.cancelUploadArr.forEach((cancelCallBack) => cancelCallBack()); //批量取消上传
    },
  },
};
</script>

<style lang="scss" scoped>
.top-bar {
  display: flex;
  justify-content: space-between;
  flex-direction: column;
  height: 68px;
}

.tools {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 14px;

  .tools-item {
    display: flex;

    &:last-child {
      justify-content: flex-end;
    }
  }

  .upload-button {
    margin: 0 10px;
  }
}
</style>
