<template>
  <div class="app-container">
    <el-card>
      <div class="batch-import-counting">
        <el-divider content-position="left">批量导入计抛</el-divider>
        <el-alert
          :closable="false"
          type="info">
          <div class="info-text">
            <span class="font-size">根据指定模板文件进行计抛导入，点击此处</span><el-link type="primary" class="font-size">
              <a href="http://wms.xingyunyi.cn/Data/Template/volumnWeightTemplate.xlsx" target="_blank" rel="noopener noreferrer">
                下载模板
              </a>
            </el-link>
          </div>
        </el-alert>
        <el-form class="define-form" inline>
          <el-form-item>
            <el-upload
              ref="importUploadRef"
              action="/"
              accept=".xlsx"
              :disabled="confirmLoading"
              :multiple="false"
              :auto-upload="false"
              :show-file-list="false"
              :on-change="uploadSuccess"
            >
              <el-button type="primary" plain :loading="confirmLoading" size="small">选择文件</el-button>
            </el-upload>
          </el-form-item>
          <el-form-item>
            <el-button type="warning" size="small" @click="hanleRefreshError">批量错误重试</el-button>
          </el-form-item>
        </el-form>
        <div class="count-warp" v-show="batchListSource.length > 0">
          <div v-if="countingNum.totalNum > 0">
            <div>
              批量导入计泡总数量：<span class="total">{{ countingNum.totalNum }}</span>
              , 导入计泡失败数量：<span class="error">{{ countingNum.errorNum }}</span>
              , 导入计泡成功数量：<span class="success">{{ countingNum.successNum }}</span>
            </div>
          </div>
          <div v-else>
            <div>
              批量导入计泡总数量：<span class="total">{{ countingNum.totalNum }}</span>
            </div>
          </div>
        </div>
        <vxe-table
          border
          :data="batchListSource"
          :row-config="{isHover: true}"
          :row-class-name="rowClassName"
          :height="tableHeight"
          :header-row-style="{
            background: '#E6F7FF',
            borderRight: '1px solid #ccc',
          }"
          :scroll-y="{enabled: false}"
          :column-config="{ resizable: true }"
        >
          <vxe-column title="提交时间" field="CreateTime" :min-width="150" />
          <vxe-column title="中转单号" field="TransferNumber" :min-width="260" />
          <vxe-column title="长" field="ChannelLength" :min-width="100" />
          <vxe-column title="宽" field="ChannelWidth" :min-width="100" />
          <vxe-column title="高" field="ChannelHeight" :min-width="100" />
          <vxe-column title="抛重" field="VolumnWeight" :min-width="100" />
          <vxe-column title="提示内容" field="ResultMessage" :min-width="280">
            <template #default="{ row }">
              <div v-show="row.ResultMessage !== '-'">
                {{ row.ResultMessage }}
              </div>
              <el-button
                type="text"
                v-show="row.ResultMessage === '-'"
                :loading="row.ResultMessage === '-'"
              />
            </template>
          </vxe-column>
        </vxe-table>
      </div>
    </el-card>
    <el-dialog
      title="计抛列表数据"
      width="1000px"
      top="6vh"
      custom-class="counting-list-form"
      :before-close="closeDialogCounting"
      :close-on-click-modal="false"
      :visible.sync="dialogCounting"
    >
      <el-form ref="costListFormRef">
        <vxe-table
          border
          show-overflow
          :data="countingThrowingData"
          :edit-config="{ trigger: 'click', mode: 'cell' }"
          :scroll-y="{enabled: false}"
          :column-config="{ resizable: true }">
          <vxe-column field="TransferNumber" :min-width="260" title="中转单号" :edit-render="{ autofocus: '.el-input__inner' }">
            <template #edit="r">
              <el-input v-model="r.row.TransferNumber" />
            </template>
          </vxe-column>
          <vxe-column field="ChannelLength" :width="120" title="长" :edit-render="{ autofocus: '.el-input__inner' }">
            <template #edit="r">
              <el-input v-model="r.row.ChannelLength" />
            </template>
          </vxe-column>
          <vxe-column field="ChannelWidth" :width="120" title="宽" :edit-render="{ autofocus: '.el-input__inner' }">
            <template #edit="r">
              <el-input v-model="r.row.ChannelWidth" />
            </template>
          </vxe-column>
          <vxe-column field="ChannelHeight" :width="120" title="高" :edit-render="{ autofocus: '.el-input__inner' }">
            <template #edit="r">
              <el-input v-model="r.row.ChannelHeight" />
            </template>
          </vxe-column>
          <vxe-column field="VolumnWeight" :width="120" title="抛重" :edit-render="{ autofocus: '.el-input__inner' }">
            <template #edit="r">
              <el-input v-model="r.row.VolumnWeight" />
            </template>
          </vxe-column>
        </vxe-table>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="closeDialogCounting">取 消</el-button>
        <el-button type="primary" :loading="confirmLoading" @click="hanleSubmitCounting">导入计抛</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import { getToken } from '@/utils/auth'
import { deepClone, defineThrottle, getCurrentDateTime } from '@/utils';
import XLSX from 'xlsx';
import axios from 'axios';

export default {
  name: 'BatchImportCounting',
  data() {
    return {
      header: { Authorization: 'token ' + getToken() },
      loading: false,
      countingThrowingList: [],
      countingThrowingData: [],
      dialogCounting: false,
      batchListSource: [],
      confirmLoading: false,
      countingNum: {//汇总数量
        totalNum: 0,
        errorNum: 0,
        successNum: 0
      },
      tableHeight: 480,
      throttledResize: null,
      saveServiceVolumnWeightUrl: process.env.VUE_APP_BASE_API + "/order/SaveServiceVolumnWeight"
    }
  },
  mounted() {
    this.createThrottledResize()
    window.addEventListener('resize', this.throttledResize)
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.throttledResize)
  },
  deactivated() {
    window.removeEventListener('resize', this.throttledResize)
  },
  methods: {
    // 计算表格的高度
    getTableHeight: function() {
      const tableHeight = window.innerHeight - 330
      this.tableHeight = tableHeight <= 480 ? 480 : tableHeight
    },
    createThrottledResize() {
      this.getTableHeight()
      this.throttledResize = defineThrottle(this.getTableHeight, 1000); // 使用lodash的throttle方法，设置节流的时间间隔为500ms
    },
    onDownload() {
      window.open('http://wms.xingyunyi.cn/Data/Template/volumnWeightTemplate.xlsx', '_blank');
    },
    // 上传xlsx文件
    uploadSuccess(file) {
      const _this = this
      // 处理文件选择的逻辑
      const excelFile = file.raw;
      const isXlsx = excelFile.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
      if (!isXlsx) {
        this.$message({ message: '只能上传 xlsx 文件！', type: 'error' })
        return
      }
      // 导入状态和文件信息
      _this.confirmLoading = true
      // 构建fileReader对象
      const fileReader = new FileReader()
      // 该事件为读取完成时触发
      fileReader.onload = function (ev) {
        try {
          const data = new Uint8Array(ev.target.result);
          const workbook = XLSX.read(data, { type: 'array' });
          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];
          const jsonData = XLSX.utils.sheet_to_json(worksheet, { header: 1, defval: '' });
          // 规定这个表头
          const headers = jsonData[0]
          const isHead = _this.checkArrayHead(headers)
          if (!isHead) {
            _this.$message({ message: 'Excel表头顺序必须是（中转单号、长、宽、抛重、计泡系数）！', type: 'error' })
            return false
          }
          const merges = worksheet['!merges'];
          if (merges) {
            merges.forEach((mergeCell) => {
              const { s, e } = mergeCell;
              const mergedCellValue = jsonData[s.r][s.c]; // 获取合并单元格的值
              // 将合并单元格的值应用到所有合并的单元格中
              for (let row = s.r; row <= e.r; row++) {
                for (let col = s.c; col <= e.c; col++) {
                  jsonData[row][col] = mergedCellValue;
                }
              }
            });
          }
          _this.countingThrowingList = jsonData
          const paramsCountingThrowings = deepClone(jsonData)
          paramsCountingThrowings.shift()
          _this.countingThrowingData = _this.dealCountingThrowing(paramsCountingThrowings)
          _this.hanleOpenEditCounting()
        } catch (e) {
          _this.$message({ message: e, type: 'warning' })
        } finally {
          _this.confirmLoading = false
        }
      }
      // 读取数据
      fileReader.readAsArrayBuffer(excelFile)
    },
    // 校验表头
    checkArrayHead(arr) {
      if (arr && arr.length !== 5) return false
      const xlsxHead = ["中转单号", "长", "宽", "高", "抛重"]
      if (arr.every((item, index) => item === xlsxHead[index])) {
        return true;
      } else {
        return false;
      }
    },
    dealCountingThrowing(array) {
      if (!Array.isArray(array) && array.length === 0) return []
      const result = [];
      // 遍历原始数组
      array.forEach(arrItem => {
        const TransferNumber = arrItem[0] || '';
        const ChannelLength = arrItem[1] || '';
        const ChannelWidth = arrItem[2] || '';
        const ChannelHeight = arrItem[3] || '';
        const VolumnWeight = arrItem[4] || '';
        result.push({
          TransferNumber,
          ChannelLength,
          ChannelWidth,
          ChannelHeight,
          VolumnWeight
        })
      });
      return result
    },
    // 表格错误样式
    rowClassName({ row }) {
      if(row.ResultState === 500) return 'error-bg'
    },
    // 错误排序
    countingOrderSortList() {
      this.batchListSource = this.batchListSource.sort((a, b) => {
        // 根据错误排序
        if (a.ResultState === 500 && b.ResultState === 200) {
          return -1;
        } else if (a.ResultState === 200 && b.ResultState === 500) {
          return 1;
        } else {
          // 根据时间排序
          return new Date(b.CreateTime) - new Date(a.CreateTime);
        }
      });
      const errorList = this.batchListSource.filter(item => item.ResultState === 500)
      this.countingNum.errorNum = errorList.length
      const successList = this.batchListSource.filter(item => item.ResultState === 200)
      this.countingNum.successNum = successList.length
    },
    // 请求
    getCancelOrder(rowData, rowIndex) {
      return new Promise((resolve) => {
        if(rowData.TransferNumber) {
          // 初始化时间
          const createTime = getCurrentDateTime()
          this.$set(this.batchListSource[rowIndex], 'CreateTime', createTime);
          const currentIndex = this.batchListSource.findIndex((i) => i.id === rowData.id)
          const data = {
            TrackingNumber: rowData.TransferNumber,
            Length: rowData.ChannelLength,
            Width: rowData.ChannelWidth,
            Height: rowData.ChannelHeight,
            VolumnWeight: rowData.VolumnWeight,
          }
          axios({
            method: 'post',
            url: this.saveServiceVolumnWeightUrl,
            data: JSON.stringify(data),
            headers: { 'token': getToken(), 'Content-Type': 'application/json' },
          }).then(result => {
            const res = result.data
            if(res.success && currentIndex >= 0) {
              this.$set(this.batchListSource[currentIndex], 'ResultState', 200);
              this.$set(this.batchListSource[currentIndex], 'ResultMessage', '导入成功');
            } else {
              this.$set(this.batchListSource[currentIndex], 'ResultMessage', res.message);
              this.$set(this.batchListSource[currentIndex], 'ResultState', 500);
            }
          }).catch(error => {
            const msg = error.response ? (error.response.data.message || error.response.data.errors || error.response.data) : error
            if(currentIndex >= 0) {
              this.$set(this.batchListSource[currentIndex], 'ResultMessage', msg);
              this.$set(this.batchListSource[currentIndex], 'ResultState', 500);
            }
          }).finally(() => {
            if(currentIndex >= 0) {
              // 更新时间
              const createTime = getCurrentDateTime()
              this.$set(this.batchListSource[currentIndex], 'CreateTime', createTime);
              this.countingOrderSortList()
              resolve(true)
            }
          })
        }
      })
    },
    // 错误重试
    async hanleRefreshError() {
      const isEvery = this.batchListSource.every(item => item.ResultState === 200)
      if(isEvery) {
        this.$message({
          type: 'warning',
          message: '暂无中转单号重试'
        })
        return
      }
      try {
        this.confirmLoading = true
        // 同步
        for await (const [rowIndex, rowData] of this.batchListSource.entries()) {
          if(rowData.ResultState === 500) {
            await this.getCancelOrder(rowData, rowIndex)
          }
        }
      } catch (error) {
        console.error(error);
      } finally {
        this.confirmLoading = false
      }
    },
    // 批量导入计泡
    async updateBatchCountingOrder() {
      if(this.batchListSource.length === 0) {
        this.$message({
          type: 'warning',
          message: '暂无中转单号导入'
        })
        return
      }
      try {
        this.confirmLoading = true
        const list = this.batchListSource.map((item, index) => {
          if(item.TransferNumber) {
            item.id = `${index}_transferNumber`
            item.CreateTime = '-'
            item.ResultMessage = '-'
          }
          return item
        }) || []
        this.batchListSource = list
        // 同步
        for await (const [rowIndex, rowData] of list.entries()) {
          if (rowData.TransferNumber) {
            await this.getCancelOrder(rowData, rowIndex)
          }
        }
      } catch (error) {
        console.error(error);
      } finally {
        this.confirmLoading = false
      }
    },
    // 显示隐藏
    hanleOpenEditCounting() {
      this.dialogCounting = true
    },
    closeDialogCounting() {
      this.dialogCounting = false
    },
    // 确定
    hanleSubmitCounting() {
      this.$confirm('是否确认进行批量导入计泡?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.batchListSource = this.countingThrowingData
        this.countingNum.totalNum = this.batchListSource.length
        this.closeDialogCounting()
        this.updateBatchCountingOrder()
      })
    }
  }
}
</script>

<style lang="scss" scoped>
  .batch-import-counting {
    .info-text {
      display: inline-flex;
      padding: 6px 0;
      .font-size {
        font-size: 15px;
      }
    }
    .define-form {
      margin: 10px 0;
      .el-form-item {
        margin-bottom: 0;
      }
    }
    .count-warp {
      padding-bottom: 10px;
      line-height: 1.3;
      font-size: 14px;
      font-weight: bold;
      color: #606266;

      .total {
        font-size: 17px;
        color: #1A73E8;
      }
      .error {
        font-size: 17px;
        color: red;
      }
      .success {
        font-size: 17px;
        color: #67C23A;
      }
    }
  }
</style>
