<template>
  <div>
    <Modal
      v-model="modal.isShow"
      :title="options.title?options.title:'信息导出'"
      :mask-closable="false"
    >
      <h4 slot="header">{{options.title?options.title:'信息导出'}}</h4>
      <div v-if="getData" center>暂无数据导出</div>
      <Row style="margin-bottom:10px;" v-if="!getData">
        <Row style="padding:5px;" v-for="(exportItem,index) in exportArr" :key="index">
          <Col span="20">
            <Progress :percent="exportItem.percent"></Progress>
          </Col>
          <Col span="4">
            <Button
              type="primary"
              size="small"
              style="float:right"
              :disabled=" exportItem.percent == 100 ? false : true"
              @click="_export( exportItem.export )"
            >确认导出</Button>
          </Col>
        </Row>
      </Row>
      <div slot="footer"></div>
    </Modal>
  </div>
</template>
<script>
import XLSX from "xlsx";
import "xlsx/dist/xlsx.full.min.js";
import saveAs from "file-saver/FileSaver.min.js";
import filters from "../filter";
import moment from "moment";

export default {
  data() {
    return {
      modal: {
        isShow: false,
      },
      getData: false,
      limitNumber: 30000, // 单个excel上限数据量
      totalCount: 0,
      exportArr: [],
      changeObj: {},
      provinceList: [],
    };
  },
  methods: {
    show(flag) {
      this.modal.isShow = flag;
      this.totalCount = 0;
      this.exportArr = [];
      this.changeObj = {};
      if (flag) {
        this.startExport();
      }
    },

    startExport() {
      let _this = this;
      this.options.columns.forEach((item) => {
        if (item.filter) {
          this.changeObj[item.prop] = item.filter;
        }
      });
      let params = this.options.params;
      params.pageIndex = 1;
      params.pageSize = 500;
      this.getData = false;
      this.$http.get(`api/${this.options.api}`, { params }).then((res) => {
        if (res.body.status === "SUCCEED" || !!res.body.status) {
          if (res.body.totalCount < 1) {
            this.getData = true;
            return;
          }
          this.getData = false;
          this.totalCount = res.body.totalCount;
          let pageNum = Math.ceil(this.totalCount / params.pageSize);
          let excelNum = Math.ceil(this.totalCount / this.limitNumber);
          for (let i = 0; i < excelNum; i++) {
            this.exportArr.push({
              export: [],
              percent: 0,
            });
          }
          let datas = res.body.datas || res.body.data;
          if (!!this.options.special) {
            datas.forEach((item, index) => {
              item = { ...item, ...item[this.options.special] };
              this.$set(datas, index, item);
            });
          }
          // 添加额外数据
          if (!!this.options.addData) {
            datas.forEach((item, index) => {
              item = {...this.options.addData,...item}
              this.$set(datas, index, item);
            });
          }

          datas.forEach((item) => {
            for (let key in this.changeObj) {
              if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){
                item[key]+='';
                // item[key] = filters[this.changeObj[key]](item[key]);
              }
              if (!!item[key]) {
                item[key] = filters[this.changeObj[key]](item[key]);
              }
            }
            if (!!this.options.otherFunction) {
              this.options.otherFunction(item);
            }
          });

          this.exportArr[0].export.push(...datas);
          if (pageNum === 1) {
            this.exportArr[0].percent = 100;
            // this._export(datas);
          } else {
            params.pageIndex = 2;
            if (excelNum == 1) {
              //一个Excel表
              this.circleGetSingExc(params);
            } else {
              //多个Excel表
              this.circleGet(params);
            }
          }
        }
      });
    },

    /* 循环下载 单个Excel表*/
    circleGetSingExc(params) {
      this.$http.get(`api/${this.options.api}`, { params }).then((res) => {
        if (res.body.status === "SUCCEED" || !!res.body.status) {
          let datas = res.body.datas || res.body.data;
          if (!!this.options.special) {
            datas.forEach((item, index) => {
              item = { ...item, ...item[this.options.special] };
              this.$set(datas, index, item);
            });
          }

          datas.forEach((item) => {
            for (let key in this.changeObj) {
              if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){
                item[key]+='';
              }
              if (!!item[key]) {
                item[key] = filters[this.changeObj[key]](item[key]);
              }
            }
            if (!!this.options.otherFunction) {
              this.options.otherFunction(item);
            }
          });
          this.exportArr[0].export.push(...datas);
          if (params.pageIndex * params.pageSize < this.totalCount) {
            this.exportArr[0].percent = Math.ceil(
              ((params.pageIndex * params.pageSize) / this.totalCount) * 100
            );
            params.pageIndex++;
            this.circleGetSingExc(params);
          } else {
            this.exportArr[0].percent = 100;
          }
        }
      });
    },

    /* 循环下载 多个Excel表*/
    circleGet(params, single) {
      let _index = Math.ceil(
        (params.pageIndex * params.pageSize) / this.limitNumber
      ); //当前第几个EXCEL表格
      this.$http.get(`api/${this.options.api}`, { params }).then((res) => {
        if (res.body.status === "SUCCEED" || !!res.body.status) {
          let datas = res.body.datas || res.body.data;

          if (!!this.options.special) {
            datas.forEach((item, index) => {
              item = { ...item, ...item[this.options.special] };
              this.$set(datas, index, item);
            });
          }
          datas.forEach((item) => {
            for (let key in this.changeObj) {
              if(key == 'turnOnLightAtNight' || key == 'wearSeatbelt'){
                item[key]+='';
              }
              if (!!item[key]) {
                item[key] = filters[this.changeObj[key]](item[key]);
              }
            }
            if (!!this.options.otherFunction) {
              this.options.otherFunction(item);
            }
          });
          this.exportArr[_index - 1].export.push(...datas);
          if (params.pageIndex * params.pageSize < this.totalCount) {
            this.exportArr[_index - 1].percent = Math.ceil(
              (this.exportArr[_index - 1].export.length / this.limitNumber) *
                100
            );
            params.pageIndex++;
            this.circleGet(params);
          } else {
            this.exportArr[_index - 1].percent = 100;
          }
        }
      });
    },

    // 省份
    getProvinceList() {
      let _this = this;
      _this.$http
        .get("api/findProvincesAndCities", {
          params: { keywords: "中国", level: "COUNTRY", sub: 2 },
        })
        .then(function (res) {
          if (res.body.status && res.body.data[0]) {
            _this.provinceList = res.body.data[0].divisions;
          }
        });
    },

    // 性别切换
    genderChange(gender) {
      if (gender === "M") {
        return "男";
      } else if (gender === "F") {
        return "女";
      }
    },

    // 省份切换
    searchByprovinceCode: function (provinceCode) {
      for (let i in this.provinceList) {
        if (this.provinceList[i].id == provinceCode) {
          return this.provinceList[i].name;
        }
      }
    },

    // 城市切换
    searchByCityCode: function (cityCode) {
      for (let i in this.provinceList) {
        for (let j in this.provinceList[i].divisions) {
          if (this.provinceList[i].divisions[j].id == cityCode) {
            return this.provinceList[i].divisions[j].name;
          }
        }
      }
    },

    _export(data) {
      console.log(data)
      let _this = this;
      let returnArr = [];
      let columns = this.options.columns;
      let tempArr = [];
      columns.forEach((item) => tempArr.push(item.label));
      returnArr.push(tempArr);
      data.forEach((item) => {
        item.provinceCode = _this.searchByprovinceCode(item.provinceCode);
        item.cityCode = _this.searchByCityCode(item.cityCode);
        item.gender = _this.genderChange(item.gender);
        // item.saleDate = moment(item.saleDate).format("YYYY-MM-DD");
        item.serviceDate = item.serviceDate;
        let keyArr = [];
        columns.forEach((col) => keyArr.push(item[col.prop]));
        returnArr.push(keyArr);
      });
      const wopts = { bookType: "xlsx", bookSST: false, type: "binary" };
      const wb = { SheetNames: ["Sheet1"], Sheets: {}, Props: {} };
      let objName = this.options.name ? this.options.name : "车主信息列表";
      wb.Sheets["Sheet1"] = XLSX.utils.aoa_to_sheet(returnArr);
      saveAs.saveAs(
        new Blob([s2ab(XLSX.write(wb, wopts))], {
          type: "application/octet-stream",
        }),
        objName + "." + (wopts.bookType == "biff2" ? "xls" : wopts.bookType)
      );
      function s2ab(s) {
        if (typeof ArrayBuffer !== "undefined") {
          var buf = new ArrayBuffer(s.length);
          var view = new Uint8Array(buf);
          for (var i = 0; i != s.length; ++i) view[i] = s.charCodeAt(i) & 0xff;
          return buf;
        } else {
          var buf = new Array(s.length);
          for (var i = 0; i != s.length; ++i) buf[i] = s.charCodeAt(i) & 0xff;
          return buf;
        }
      }
    },
  },

  created() {
    this.getProvinceList();
  },

  props: ["options"],
};
</script>

freeman_Tian
12 声望2 粉丝