<template>
  <div class="common-page device-manage">

    <div class="option page-row">
      <!--工具栏-->
      <div class="head-container">
        <!-- 搜索 -->
        <label class="el-form-item-label" style="font-weight: 500;">文件名</label>
        <el-input v-model="query.fileName" clearable size="small" placeholder="请输入文件名称" style="width:180px;"/>
        <label class="el-form-item-label" style="font-weight: 500;">上传时间</label>
        <el-date-picker
          v-model="query.modificationTime"
          type="datetimerange"
          value-format="yyyy-MM-dd HH:mm:ss"
          range-separator="至"
          :default-time="['00:00:00', '23:59:59']"
          start-placeholder="开始日期"
          end-placeholder="结束日期">
        </el-date-picker>
        <el-button size="mini" type="success" icon="el-icon-search" @click="toSearch">搜索</el-button>
        <el-button size="mini" icon="el-icon-refresh" @click="clearLimit">重置</el-button>
      </div>
    </div>

    <!-- 表格 -->
    <div class="panel-bottom page-row">
      <div class="ctin-box">
        <div class="content-within">
          <div class="content-fix">
            <div class="toolbar">
              <el-button slot="left" class="filter-item" size="mini" type="primary" icon="el-icon-upload"
                         @click="uploadVisible=true">上传
              </el-button>
            </div>
            <div class="content">
              <el-tabs v-model="query.type" @tab-click="loadData">
                <el-tab-pane label="Excel报表" name="excel"></el-tab-pane>
                <el-tab-pane label="三维模型" name="fbx"></el-tab-pane>
              </el-tabs>
              <el-table :data="tableData" v-loading="loading" border style="width:auto">
                <el-table-column prop="fileName" label="文件名" align="center"></el-table-column>
                <el-table-column prop="url" label="文件路由" align="center"></el-table-column>
                <el-table-column prop="modificationTime" label="上传时间" align="center"></el-table-column>
                <el-table-column label="操作" align="center" fixed="right">
                  <template slot-scope="scope">
                    <el-button v-if="query.type==='excel'" size="mini" type="text" icon="el-icon-view" @click="viewTable(scope.row)">编辑</el-button>
                    <el-button size="mini" type="text" icon="el-icon-download" @click="downloadFile(scope.row)">下载</el-button>
                    <el-button size="mini" type="text" icon="el-icon-delete" @click="toDelete(scope.row)">删除</el-button>
                    <el-button size="mini" type="text" icon="el-icon-tickets" @click="openLog(scope.row)">记录</el-button>
                  </template>
                </el-table-column>
              </el-table>
              <!--分页组件-->
              <el-pagination :total="total" :current-page="page" style="margin-top: 8px;"
                             layout="total, prev, pager, next, sizes" @size-change="sizeChange"
                             @current-change="pageChange"/>
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- 表单渲染 -->
    <el-dialog append-to-body :close-on-click-modal="false" :before-close="cancelForm" :visible.sync="visible" :title="openFile.fileName" width="1600px" top="1vh">
      <div v-if="openFile.isLoading" style="width: 100%;text-align: center">正在读取文件...</div>
      <div id="x-spreadsheet-excel"></div>
      <div slot="footer" class="dialog-footer" style="text-align: center">
        <el-button @click="cancelForm">关闭</el-button>
        <el-button type="primary" @click="updataEcxel">保存</el-button>
      </div>
    </el-dialog>
    <el-dialog append-to-body :close-on-click-modal="false" :before-close="cancelForm" :visible.sync="uploadVisible" title="文件上传" width="560px">
      <el-form ref="form" :model="form" size="small" label-width="80px">
        <!--   上传文件   -->
        <el-form-item label="">
          <el-upload
            ref="upload"
            :before-upload="beforeUpload"
            :auto-upload="false"
            :headers="headers"
            :on-change="handleFileChange"
            :on-success="handleSuccess"
            :on-error="handleError"
            action="/api/miningManagement/uploadExcelOrFbx"
            :data="{type:query.type}"
          >
            <div class="eladmin-upload"><i class="el-icon-upload"/> 添加文件</div>
            <div slot="tip" class="el-upload__tip">请上传{{ query.type }}文件，且不超过100M</div>
          </el-upload>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="text" @click="cancelForm">取消</el-button>
        <el-button :loading="loading" type="primary" @click="upload">确认</el-button>
      </div>
    </el-dialog>
    <el-dialog append-to-body :close-on-click-modal="false" :before-close="cancelForm" :visible.sync="logVisible" title="编辑日志" width="800px">
      <el-table :data="logData" border style="width:auto">
        <el-table-column prop="nickName" label="编辑人" align="center"></el-table-column>
        <el-table-column prop="phone" label="联系电话" align="center"></el-table-column>
        <el-table-column prop="updateTime" label="编辑时间" align="center"></el-table-column>
        <el-table-column prop="status" label="状态" align="center">
          <template slot-scope="scope">
            <span v-if="scope.row.status==='完成'" style="color:gray">{{scope.row.status}}</span>
            <span v-else style="color:forestgreen">{{scope.row.status}}</span>
          </template>
        </el-table-column>
      </el-table>
      <div slot="footer" class="dialog-footer" style="text-align: center">
        <el-button @click="cancelForm">关闭</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {getToken} from '@/utils/auth'
import Spreadsheet from "x-data-spreadsheet";
import 'x-data-spreadsheet/dist/locale/zh-cn';
import {Tools, HttpReq, Dates} from '@/assets/js/common.js';

export default {
  name: 'visitPeople',
  data() {
    return {
      colors: [{color: '#f56c6c', percentage: 20}, {color: '#e6a23c', percentage: 40}, {color: '#5cb87a', percentage: 60}, {color: '#1989fa', percentage: 80}, {color: '#6f7ad3', percentage: 100}],
      title: '',
      fileUploadApi: '',
      headers: {'Authorization': getToken()},
      visible: false,
      uploadVisible: false,
      logVisible: false,
      loading: false,
      query: {
        type: 'excel',
      },
      page: 1,
      size: 10,
      total: 0,
      tableData: [],
      openFile: {
        fileName: '',
        isLoading: false,
        percentage: 0
      },
      tabList: ['Sheet1'],
      activeTab: 'Sheet1',
      excelTableData: [],
      form: {},
      xs: null,
      fileSocketTimer: null,
      logData: []
    }
  },
  mounted() {
    this.$nextTick(() => {
      this.loadData()
    })
  },
  methods: {
    openLog(item) {
      this.logVisible = true
      HttpReq.truckDispatching.scQueryByUrl({url:item.url}).then((res) => {
        if (res.code == 200) {
          this.logData = res.data;
        }
      })
    },
    stox(wb) {
      var out = [];
      wb.SheetNames.forEach(function (name) {
        var o = {name: name, rows: {}};
        var ws = wb.Sheets[name];
        if (!ws || !ws["!ref"]) return;
        var range = XLSX.utils.decode_range(ws['!ref']);
        // sheet_to_json will lost empty row and col at begin as default
        range.s = {r: 0, c: 0};
        var aoa = XLSX.utils.sheet_to_json(ws, {
          raw: false,
          header: 1,
          range: range
        });
        aoa.forEach(function (r, i) {
          var cells = {};
          r.forEach(function (c, j) {
            cells[j] = {text: c};

            var cellRef = XLSX.utils.encode_cell({r: i, c: j});

            if (ws[cellRef] != null && ws[cellRef].f != null) {
              cells[j].text = "=" + ws[cellRef].f;
            }
          });
          o.rows[i] = {cells: cells};
        });
        o.rows.len = aoa.length;
        o.merges = [];
        (ws["!merges"] || []).forEach(function (merge, i) {
          //Needed to support merged cells with empty content
          if (o.rows[merge.s.r] == null) {
            o.rows[merge.s.r] = {cells: {}};
          }
          if (o.rows[merge.s.r].cells[merge.s.c] == null) {
            o.rows[merge.s.r].cells[merge.s.c] = {};
          }
          o.rows[merge.s.r].cells[merge.s.c].merge = [
            merge.e.r - merge.s.r,
            merge.e.c - merge.s.c
          ];
          o.merges[i] = XLSX.utils.encode_range(merge);
        });
        out.push(o);
      });
      return out;
    },
    xtos(sdata) {
      var out = XLSX.utils.book_new();
      sdata.forEach(function (xws) {
        var ws = {};
        var rowobj = xws.rows;
        var minCoord = {r: 0, c: 0}, maxCoord = {r: 0, c: 0};
        for (var ri = 0; ri < rowobj.len; ++ri) {
          var row = rowobj[ri];
          if (!row) continue;
          Object.keys(row.cells).forEach(function (k) {
            var idx = +k;
            if (isNaN(idx)) return;
            var lastRef = XLSX.utils.encode_cell({r: ri, c: idx});
            if (ri > maxCoord.r) maxCoord.r = ri;
            if (idx > maxCoord.c) maxCoord.c = idx;
            var cellText = row.cells[k].text, type = "s";
            if (!cellText) {
              cellText = "";
              type = "z";
            } else if (!isNaN(Number(cellText))) {
              cellText = Number(cellText);
              type = "n";
            } else if (cellText.toLowerCase() === "true" || cellText.toLowerCase() === "false") {
              cellText = Boolean(cellText);
              type = "b";
            }
            ws[lastRef] = {v: cellText, t: type};
            if (type == "s" && cellText[0] == "=") {
              ws[lastRef].f = cellText.slice(1);
            }
            if (row.cells[k].merge != null) {
              if (ws["!merges"] == null) ws["!merges"] = [];
              ws["!merges"].push({
                s: {r: ri, c: idx},
                e: {
                  r: ri + row.cells[k].merge[0],
                  c: idx + row.cells[k].merge[1]
                }
              });
            }
          });
        }
        ws["!ref"] = minCoord ? XLSX.utils.encode_range({
          s: minCoord,
          e: maxCoord
        }) : "A1";
        XLSX.utils.book_append_sheet(out, ws, xws.name);
      });
      return out;
    },
    blobToArrayBuffer(blob) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onerror = reject;
        reader.onload = () => {
          resolve(reader.result);
        };
        reader.readAsArrayBuffer(blob);
      });
    },
    updataEcxel() {
      HttpReq.truckDispatching.scUploadExcelByBase64({
        base64: XLSX.write(this.xtos(this.xs.getData()), {bookType: 'xlsx', type: 'base64'}),
        url: this.openFile.url
      }).then((res) => {
        this.$notify({
          title: res.msg,
          type: res.code === 200 ? 'success' : 'error',
          duration: 2500
        })
        if (res.code === 200) {
          this.cancelForm()
        }
      })
    },
    viewTable(item) {
      this.openFile = item
      HttpReq.truckDispatching.isTheFileLocked({
        url: this.openFile.url
      }).then((res) => {
        if (res.data) {
          return this.$notify({
            title: '文件已被锁定，暂时无法编辑',
            type: 'warning'
          })
        } else {
          this.visible = true
          this.reconnect();
          this.fileSocketTimer = setInterval(() => {
            this.reconnect();
          }, 15000);
          HttpReq.truckDispatching.downloadExcelOrFbx({url: item.url, type: this.query.type}).then((res) => {
            if(!this.xs){
              Spreadsheet.locale('zh-cn');
              this.xs = new Spreadsheet("#x-spreadsheet-excel", {
                view:{
                  width: () =>{return 1600},
                  height: () =>{return 800}
                },
                style: {
                  align: 'center',
                  valign: 'middle',
                }
              })
            }
            this.blobToArrayBuffer(res).then(arrayBuffer => {
              // 外部引用sheetjs提供全局变量XLSX
              let wb = XLSX.read(arrayBuffer)
              this.xs.loadData(this.stox(wb))
            })
          })
        }
      })
    },
    reconnect() {
      HttpReq.truckDispatching.setFileValidityPeriod({url: this.openFile.url}).then((res) => {})
    },
    toDelete(item) {
      this.$confirm(`确认删除文件：${item.fileName}?`, '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        HttpReq.truckDispatching.deleteExcelOrFbx({fileName: item.fileName, type: this.query.type}).then((res) => {
          this.$notify({
            title: res.msg,
            type: res.code === 200 ? 'success' : 'error',
            duration: 2500
          })
          if (res.code === 200) {
            this.loadData()
          }
        })
      }).catch(() => {
      })
    },
    download(text, name, suffix) {
      var link = document.createElement('a');
      link.style.display = 'none';
      link.href = URL.createObjectURL(new Blob([text], {type: this.query.type === 'excel' ? "application/vnd.ms-excel" : "application/octet-stream"}));
      link.setAttribute('download', name + '.' + suffix);
      document.body.appendChild(link);
      link.click();
      document.body.removeChild(link);
    },
    downloadFile(item) {
      if (item.isLoading) {
        return this.$notify({
          title: '正在下载该文件，请勿操作',
          type: 'info'
        })
      }
      item.isLoading = true
      item.percentage = 0
      let strArr = item.fileName.split('.')
      HttpReq.truckDispatching.downloadExcelOrFbx({url: item.url, type: this.query.type}).then((res) => {
        this.download(res, strArr[0], strArr[1] || 'xlsx')
        item.isLoading = false
      })
    },
    upload() {
      this.$refs.upload.submit()
    },
    handleFileChange(file) {

    },
    beforeUpload(file) {
      let isLt2M = true
      isLt2M = file.size / 1024 / 1024 < 100
      if (!isLt2M) {
        this.loading = false
        this.$message.error('上传文件大小不能超过 100MB!')
      }
      return isLt2M
    },
    handleSuccess(res, file, fileList) {
      this.$notify({
        title: res.msg,
        type: res.code === 200 ? 'success' : 'error',
        duration: 2500
      })
      if (res.code === 200) {
        this.cancelForm()
      }
    },
    // 监听上传失败
    handleError(e, file, fileList) {
      const msg = JSON.parse(e.message)
      this.$notify({
        title: msg.message,
        type: 'error',
        duration: 2500
      })
      this.loading = false
    },
    handleTabClick(tab, event) {
      console.log(tab, event);
    },
    loadData() {
      Object.keys(this.query).length !== 0 && Object.keys(this.query).forEach(item => {
        if (this.query[item] === null || this.query[item] === '') this.query[item] = undefined
      })
      HttpReq.truckDispatching.scFindAllExcelInfo(this.query).then((res) => {
        if (res.code == 200) {
          this.tableData = res.data;
        }
      })
    },
    cancelForm() {
      if (this.fileSocketTimer) {
        HttpReq.truckDispatching.deleteFileEditingTags({
          url: this.openFile.url
        }).then((res) => {
          clearInterval(this.fileSocketTimer);
          this.fileSocketTimer = null;
        })
      }
      this.visible = false
      this.uploadVisible = false
      this.logVisible = false
      if (this.$refs.upload) {
        this.$refs.upload.clearFiles()
      }
      this.loadData()
    },
    // 点击搜索
    toSearch() {
      this.page = 1;
      this.loadData();
    },
    // 重置搜索
    clearLimit() {
      this.query = {};
      this.loadData()
    },
    pageChange(e) {
      this.page = e
      this.loadData()
    },
    sizeChange(e) {
      this.page = 1
      this.size = e
      this.loadData()
    }
  },
  beforeDestroy() {
    if (this.fileSocketTimer) {
      clearInterval(this.fileSocketTimer);
      this.fileSocketTimer = null;
    }
  }
}
</script>

<style rel="stylesheet/scss" lang="scss" scoped>
.el-table .warning-row {
  background: oldlace;
}

.el-table .success-row {
  background: #f0f9eb;
}

.cell-input {
  //min-width: 220px;
}

.form-cell {
  margin: 0 !important;
  width: 100%;
}

.grid-content {
  //border: 1px solid rgba(100, 100, 100, 0.1);
  padding: 5px 30px;
}

.cell-box {
  min-width: 120px;
}

.cell-box .el-input__inner {
  border: 1px solid rgba(100, 100, 100, 0.1);
}

.cell-box .el-input.is-disabled .el-input__inner {
  border: 1px solid rgba(100, 100, 100, 0.1);
  background: white;
  cursor: text;
}

.cell-box .el-input.is-disabled .el-input__icon {
  cursor: text;
}

.cell-box .el-icon-arrow-up:before {
  content: '';
}

.mapcontainer {
  height: 30vh;
  width: 680px;
  overflow: hidden;
}

> > > .el-input__inner {
  border: 0;
}

> > > .el-input__inner[textcolor="red"] {
  color: #F00
}

> > > .el-dialog__body {
  padding: 0;
  margin: 0;
}
</style>
