<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">
        <PermissionButton
          button
          :disabled="loading"
          size="mini"
          type="primary"
          @click.native="handleOperation({ type: 'downloadTemplate' })"
          icon="el-icon-download"
          :perms="perms.add"
          style="margin-right: 16px"
        >
          下载导入模板</PermissionButton
        >

        <PermissionButton
          button
          type="primary"
          size="mini"
          @click.native="handleOperation({ type: 'viewImportRecord' })"
          icon="el-icon-document"
          plain
          :perms="perms.add"
          style="margin-right: 16px"
        >
          查看导入记录</PermissionButton
        >

        <PermissionButton
          button
          type="danger"
          size="mini"
          @click.native="handleOperation({ type: 'multiDelete' })"
          icon="el-icon-delete"
          plain
          :perms="perms.delete"
          style="margin-right: 16px"
          :disabled="isMultiDisabled"
        >
          批量删除</PermissionButton
        >
      </div>
      <div class="tools-item">
        <PermissionButton
          button
          perms="bizExhibition:add"
          type="primary"
          size="mini"
          @click.native="handleOperation({ type: 'add' })"
          icon="el-icon-plus"
          :perms="perms.add"
          style="margin-right: 16px"
          >添加</PermissionButton
        >
        <PermissionButton
          button
          perms="bizExhibition:add"
          type="success"
          size="mini"
          @click.native="handleOperation({ type: 'multiAdd' })"
          icon="el-icon-upload"
          :perms="perms.add"
          style="margin-right: 16px"
          >整量导入</PermissionButton
        >
      </div>
    </div>
    <div class="list">
      <el-tabs v-model="tabActive">
        <el-tab-pane label="待办" name="unPassed"></el-tab-pane>
        <el-tab-pane label="已审核通过" name="passed"></el-tab-pane>
      </el-tabs>
      <TablePage
        :data="getCurrentList().records"
        :tableTitle="getTitle"
        :operates="operates"
        hasMultiSelection
        :selectableFuction="selectableFuction"
        @handleSelectionChange="handleSelectionChange"
      >
        <template v-slot:status="{ scope }">
          <el-popconfirm
            :title="getStatusTitle(scope.status)"
            @confirm="handleChangeStatus(scope)"
          >
            <el-switch
              slot="reference"
              :value="Boolean(Number(scope.status))"
            ></el-switch>
          </el-popconfirm>
        </template>
        <template v-slot:displayType="{ scope }">
          {{ dicts.displayType[scope.type] }}
        </template>
        <template v-slot:checkStatus="{ scope }">
          <el-tag
            :type="
              $constantsTool.getTagTypeByValue('checkStatus', scope.checkStatus)
            "
            >{{
              $constantsTool.getLabelByValue("checkStatus", scope.checkStatus)
            }}</el-tag
          >
        </template>
        <template v-slot:faceImageUrl="{ scope }">
          <img
            :src="$getFullUrl(scope.faceImagePressUrl || scope.faceImageUrl)"
            alt="暂无图片"
            v-if="$getFullUrl(scope.faceImagePressUrl || scope.faceImageUrl)"
            style="cursor: pointer"
            width="100px"
            @click="handelPreviewImages(scope.faceImageUrl)"
          />
        </template>
        <template v-slot:themeType="{ scope }">
          {{ themeTypeCode(scope.themeType) }}
        </template>
        <template v-slot:operates="{ scope }">
          <TableOperation
            :operations="getOperations(scope)"
            :rawData="scope"
            @handleOperation="handleOperation"
          >
          </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>
    </div>
    <InfoEditDialog
      :form="form"
      :currentPageIds="currentPageIds"
      @handleClose="closeInfoEditDialog"
      @refresh="loadData"
      @changeDisplay="reloadDisplay"
      ref="InfoEditDialog"
    />
    <PreviewDialog ref="PreviewDialog" :info="curPreview" />
    <ImportRecordDialog ref="ImportRecordDialog" @reload="loadData" />

    <UploadListDialog
      :visible="multiUploadVisible"
      :filesList="filesList"
      @handleClose="handleMultiUploadClose"
      @handleCancel="handleMultiUploadCancel"
    />
    <UploadDialog
      ref="UploadDialog"
      :options="multiUploadOptions"
      @update="loadData"
    />

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

<script>
import {
  passedTitle,
  unPassedTitle,
  operates,
  editButton,
  editDisabledButton,
  deleteButton,
  previewButton,
} from "./configs/list";
import {
  getListPer,
  getListPerTemp,
  deleteDisplay,
  getDisplayById,
  deleteDisplayTemp,
  getDisplayByIdTemp,
  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 UploadDialog from "@/components/UploadDialog"; //上传弹窗
import { mapGetters } from "vuex";
import { themeTypeCode } from "./contants";
import { getToken } from "@/utils/auth";
import { importZip } from "@/utils/file";
import boutiqueTool from "@/utils/boutique";
import { searchConfig } from "./configs/list";
import perms from "./configs/perms";
export default {
  components: {
    InfoEditDialog,
    PreviewDialog,
    ImportRecordDialog,
    UploadListDialog,
    UploadDialog,
  },
  data() {
    return {
      perms,
      // （存放两份数据的目的是为了防止切换的时候分页被重置）
      //最终表
      list: {
        records: [],
        size: 10,
        current: 1,
        total: 0,
      },
      // 临时表
      listTemp: {
        records: [],
        size: 10,
        current: 1,
        total: 0,
      },
      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: {},
      currentPageIds: [], //当前的id数组，用于给详情页切换用
      multiUploadVisible: false, //控制批量上传弹窗显示
      filesList: [], //上传当中的文件队列
      uploadCount: 0, //处于上传中的文件数量，当等于fileList的时候就关闭弹窗，请求完毕一个就++
      cancelUploadArr: [], //保存每个文件上传接口对应的取消请求的函数[fn,fn,fn...]
      isUpLoading: false,
      tabActive: "unPassed",
      passedTitle,
      unPassedTitle,
      operates,
      curPreview: {}, //当前预览的对象
      searchParams: {}, //记录SearchForm中的搜索条件
      //批量上传的参数
      multiUploadOptions: {
        bizType: "biz_exhibition", //业务类型，文物、展览等biz_cultural_relic——文物，biz_exhibition——展览，如果是文物和展览批量上传必填，抠图不用填
        uploadUrl: process.env.VUE_APP_BASE_API + "/bizImport/importZip", //上传的地址，必填
      },
      multipleSelection: [],
    };
  },
  computed: {
    ...mapGetters(["dicts"]),
    tableOperations() {
      return operations;
    },
    getStatusTitle(status) {
      return (status) => {
        if (Number(status)) {
          return "是否确定要下架？";
        } else {
          return "是否确定要上架？";
        }
      };
    },
    isDisabled(checkStatus) {
      return (checkStatus) => {
        return checkStatus == "0";
        //在审核中和已通过，则不能使用提交审核、编辑及删除按钮
      };
    },
    getOperations(row) {
      return (row) => {
        if (this.tabActive == "passed") {
          return [previewButton, deleteButton];
        } else if (row.checkStatus == 0) {
          // 状态为审核中的禁用编辑
          return [editDisabledButton, previewButton, deleteButton];
        } else {
          return [editButton, previewButton, deleteButton];
        }
      };
    },
    getTitle() {
      return this.tabActive == "passed" ? this.passedTitle : this.unPassedTitle;
    },
    isMultiDisabled() {
      return this.multipleSelection.length === 0;
    },
  },

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

  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 = [];
      }
    },
    // 监听Tab值不同调取不同的接口
    tabActive(value) {
      this.resetPage();
      this.loadData();
      this.multipleSelection = [];
    },
  },
  methods: {
    // 清除分页到初始状态
    resetPage() {
      this.getCurrentList().current = 1;
    },
    // 设置两张表的数据
    setList(data) {
      if (this.tabActive === "passed") {
        this.list = data;
      } else {
        this.listTemp = data;
      }
    },
    // 获取当前加载的list
    getCurrentList() {
      const currentList =
        this.tabActive == "passed" ? this.list : this.listTemp;
      return currentList;
    },
    // 获取当前请求方法
    getCurrentRequest() {
      const currentRequest =
        this.tabActive == "passed" ? getListPer : getListPerTemp;
      return currentRequest;
    },
    // 获取当前预览请求
    getCurrentPreviewRequest() {
      const currentRequest =
        this.tabActive == "passed" ? getDisplayById : getDisplayByIdTemp;
      return currentRequest;
    },
    // 获取当前删除请求
    getCurrentDeleteRequest() {
      const currentRequest =
        this.tabActive == "passed" ? deleteDisplay : deleteDisplayTemp;
      return currentRequest;
    },

    async search(form) {
      // 记录搜索的参数
      this.searchParams = form;
      this.resetPage();
      this.loadData(form);
    },
    reset() {
      this.searchParams = {};
      this.loadData();
    },

    // 加载表格数据
    async loadData(form) {
      const { current, size } = this.getCurrentList();
      var params = {
        page: this.list.current,
        limit: this.list.size,
      };
      const queryParams = form || this.searchParams;
      if (Object.keys(queryParams)) {
        params = { ...params, ...queryParams };
      }
      const currentRequest = this.getCurrentRequest();
      const res = await currentRequest(params);
      if (res.code == 0) {
        this.setList(res.data);
      }
    },
    // 操作
    handleOperation(value, row) {
      switch (value.type) {
        case "add":
          this.$appCommon.openDialog(this, "InfoEditDialog");
        case "view":
          this.handleView(row);
          break;
        case "edit":
          this.handleEdit(row);
          break;
        case "delete":
          this.handleDelete(row);
          break;
        case "multiAdd":
          this.$appCommon.openDialog(this, "UploadDialog");
          break;
        case "downloadTemplate":
          this.handleDownloadTemplate();
          break;
        case "viewImportRecord":
          this.$appCommon.openDialog(this, "ImportRecordDialog");
          break;
        case "multiDelete":
          this.multiDelete();
          break;
      }
    },
    // 获取多选中的可被选择项目，true则可被选择
    selectableFuction(row, rowIndex) {
      // 除了审核中的，其他状态都可以删除
      const isApproval = 0;
      if (row.checkStatus !== isApproval) {
        return true;
      }
    },
    // 批量删除
    multiDelete() {
      const ids = this.multipleSelection.map((item) => {
        return item.exhibitionId;
      });
      const request = this.getCurrentDeleteRequest();
      const callback = this.loadData;
      this.$bizCommon.multiDelete(request, ids, callback);
    },

    // 预览展览
    async handleView(row) {
      if (row) {
        if (boutiqueTool.isBoutique(row.title)) {
          this.$message.info("精品展暂不支持预览！");
          return;
        }
        const request = this.getCurrentPreviewRequest();
        let res = await request({
          exhibitionId: row.exhibitionId,
        });
        if (res.data) {
          this.curPreview = res.data;
          this.$appCommon.openDialog(this, "PreviewDialog");
        } else {
          this.$message.error("暂无数据！");
        }
      }
    },

    // 编辑展览
    async handleEdit(row) {
      let editRes = await getDisplayByIdTemp({
        exhibitionId: row.exhibitionId,
      });
      this.form = editRes.data;
      this.$refs.InfoEditDialog.visible = true;
    },

    // 删除展览
    async handleDelete(row) {
      const request = this.getCurrentDeleteRequest();
      const deleteRes = await request([row.exhibitionId]);
      if (deleteRes.code === 0) {
        this.loadData();
        this.$message.success("删除成功！");
      }
    },

    //下载批量导入模板
    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) => {
        let status;
        let desc;
        if (res.data.code == 0) {
          status = "success";
          desc = "上传成功";
          this.$message.success(desc);
        } else {
          status = "warning";
          desc = "上传失败" + res.data.msg;
          this.$message.error(desc);
        }
        this.$set(this.filesList[index], "status", status);
        this.$set(this.filesList[index], "desc", desc);
        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 getDisplayByIdTemp({
        exhibitionId,
      });
      this.form = editRes.data;
      this.$refs.InfoEditDialog.submitLoading = false;
    },
    async handleChangeStatus(row) {
      const callback = this.loadData;
      this.$bizCommon.changeStatus(row, editDisplay, callback);
    },
    // 多选
    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!");
    },
    // 关闭编辑弹窗
    closeInfoEditDialog() {
      this.form = {};
    },
    // 关闭预览图片
    closeImgViewer() {
      this.imgViewerVisible = false;
    },
    // 预览图片
    handelPreviewImages(images) {
      this.imgViewerVisible = true;
      this.imgList = [images];
    },

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

    handleCopy() {
      this.copyDialogVisible = true;
    },

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

    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 = [];
    },

    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>
