<template>
  <div>
    <custom-modal v-model="visible" :width="1200" title="Load Data From File">
      <!-- 支持 File System Access 的情况 -->
      <a-table
        v-if="canUseFilePicker"
        :dataSource="list"
        :columns="columns"
        :pagination="false"
        bordered
        :scroll="{ y: 450 }"
      >
        <template slot="sampleData" slot-scope="text, record, index">
          <div
            class="file-name file-ellipsis"
            :title="text && text.fileName"
            @dblclick="useFilePicker('sampleFileName', record, index)"
          >
            {{ text && text.fileName }}
          </div>
        </template>
        <template slot="gasBkData" slot-scope="text, record, index">
          <div
            :class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
            :title="text && text.fileName"
            @dblclick="useFilePicker('gasFileName', record, index)"
          >
            {{ text && text.fileName }}
          </div>
        </template>
        <template slot="detBkData" slot-scope="text, record, index">
          <div
            :class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
            :title="text && text.fileName"
            @dblclick="useFilePicker('detFileName', record, index)"
          >
            {{ text && text.fileName }}
          </div>
        </template>
        <template slot="qcData" slot-scope="text, record, index">
          <div
            :class="['file-ellipsis', text && text.file ? '' : 'file-name-color']"
            :title="text && text.fileName"
            @dblclick="useFilePicker('qcFileName', record, index)"
          >
            {{ text && text.fileName }}
          </div>
        </template>
        <template slot="status" slot-scope="text, record">
          <template v-if="record.sampleFileName">
            <span
              class="status"
              :class="
                record.fileType == 'B' &&
                !(record.gasFileName && record.gasFileName.file && record.detFileName && record.detFileName.file)
                  ? 'status_false'
                  : 'status_true'
              "
            ></span>
          </template>
        </template>
      </a-table>
      <!-- 不支持 File System Access 的情况 -->
      <a-table
        v-else
        :data-source="list"
        :columns="columns"
        :loading="loading_list"
        :pagination="false"
        bordered
        :scroll="{ y: 450 }"
      >
        <template slot="sampleData" slot-scope="text, record">
          <div class="file-name file-ellipsis" :title="text" @dblclick="handleFileSelect('_S_', record)">
            {{ text }}
          </div>
          <!-- <phd-select type="file" @change="handleFileChange(record, 'sampleData', $event)" @select="handleFileSelect" :title="text && text.fileName">
            {{ text }}
          </phd-select> -->
        </template>
        <template slot="gasBkData" slot-scope="text, record">
          <div
            :class="['file-ellipsis', !record.gasFileStatus ? 'file-name-color' : '']"
            :title="text"
            @dblclick="handleFileSelect('_G_', record)"
          >
            {{ text }}
          </div>
        </template>
        <template slot="detBkData" slot-scope="text, record">
          <div
            :class="['file-ellipsis', !record.detFileStatus ? 'file-name-color' : '']"
            :title="text"
            @dblclick="handleFileSelect('_D_', record)"
          >
            {{ text }}
          </div>
        </template>
        <template slot="qcData" slot-scope="text, record">
          <div
            :class="['file-ellipsis', !record.qcFileStatus ? 'file-name-color' : '']"
            :title="text"
            @dblclick="handleFileSelect('_Q_', record)"
          >
            {{ text }}
          </div>
        </template>
        <template slot="status" slot-scope="text, record">
          <span
            :class="[
              (record.detFileStatus && record.gasFileStatus && record.qcFileStatus) ||
              (record.sampleFileName && !record.gasFileName && !record.detFileName && !record.qcFileName) ||
              (record.sampleSystemType == 'C' && record.sampleFileName)
                ? 'status_true'
                : 'status_false',
              'status',
            ]"
          ></span>
        </template>
      </a-table>

      <!-- 底部按钮 -->
      <template slot="custom-footer">
        <a-space>
          <a-upload
            v-if="!canUseFilePicker"
            accept=".PHD,.phd"
            :custom-request="handleUpload"
            :multiple="true"
            :show-upload-list="false"
            :before-upload="beforeUpload"
          >
            <a-button type="primary" :loading="uploading"> Upload </a-button>
          </a-upload>
          <a-button type="primary" @click="handleReset">Reset</a-button>
          <a-button :loading="isUploadingZip" type="primary" @click="handleLoad">Load</a-button>
          <a-button type="warn" @click="handleCancel">Cancel</a-button>
        </a-space>
      </template>
      <!-- 底部按钮结束 -->
    </custom-modal>
    <a-modal v-model="visible_file" :width="1200" title="File List" :maskClosable="false" @cancel="cancelFileModale">
      <a-spin :spinning="loading_file">
        <div style="position: relative; padding-bottom: 40px; height: 460px; overflow: hidden">
          <a-row type="flex" style="margin-bottom: 15px">
            <a-col flex="400px">
              <a-input placeholder="search..." v-model="searchName" />
            </a-col>
            <a-col flex="108px">
              <a-button class="search-btn" type="primary" @click="onSearchFileName">
                <img src="@/assets/images/global/search.png" alt="" />
                Search
              </a-button>
            </a-col>
          </a-row>
          <a-table
            v-if="tableType == 'multiple'"
            :data-source="list_file"
            :columns="columns_file"
            :pagination="false"
            :customRow="customRow"
            :row-selection="{ selectedRowKeys: selectedRowKeys, onChange: onSelectChange }"
            :scroll="{ y: 330 }"
          >
          </a-table>
          <custom-table
            v-if="tableType == 'single'"
            rowKey="id"
            size="middle"
            :columns="columns_file"
            :list="list_file"
            :pagination="false"
            :selectedRowKeys.sync="selectedRowKeys_edit"
            :selectionRows.sync="selectionRows_edit"
          >
          </custom-table>
          <a-pagination
            size="small"
            v-model="ipagination.current"
            :pageSize="ipagination.pageSize"
            :page-size-options="ipagination.pageSizeOptions"
            show-size-changer
            show-quick-jumper
            :total="ipagination.total"
            :show-total="
              (total, range) =>
                `Total ${total} items　Page ${ipagination.current} / ${Math.ceil(total / ipagination.pageSize)}`
            "
            show-less-items
            @change="handlePageChange"
            @showSizeChange="handleSizeChange"
          />
        </div>
      </a-spin>
      <template slot="footer">
        <a-space class="operators" :size="20">
          <a-button type="success" @click="saveFileName">Save</a-button>
          <a-button type="warn" @click="cancelFileModale">Cancel</a-button>
        </a-space>
      </template>
    </a-modal>
  </div>
</template>

<script>
import { getAction, postActionWithTimeOut } from '../../../../api/manage'
import { FilePicker } from '@/utils/FilePicker'
import { readFile, zipFile } from '@/utils/file'
import { isSample, PHDParser, PHD_DATA_TYPE } from '@/utils/phdHelper'
import ModalMixin from '@/mixins/ModalMixin'
import { cloneDeep } from 'lodash'

const columns = [
  {
    title: 'SampleData',
    dataIndex: 'sampleFileName',
    width: '23%',
    ellipsis: true,
    scopedSlots: {
      customRender: 'sampleData',
    },
  },
  {
    title: 'GasBkData',
    dataIndex: 'gasFileName',
    width: '23%',
    ellipsis: true,
    scopedSlots: {
      customRender: 'gasBkData',
    },
  },
  {
    title: 'DetBkData',
    dataIndex: 'detFileName',
    width: '23%',
    ellipsis: true,
    scopedSlots: {
      customRender: 'detBkData',
    },
  },
  {
    title: 'QCData',
    dataIndex: 'qcFileName',
    width: '23%',
    ellipsis: true,
    scopedSlots: {
      customRender: 'qcData',
    },
  },
  {
    title: 'Status',
    align: 'center',
    scopedSlots: {
      customRender: 'status',
    },
  },
]
const columns_file = [
  {
    title: 'Name',
    dataIndex: 'name',
    width: '45%',
    align: 'left',
    ellipsis: true,
  },
  {
    title: 'UpdateDate',
    dataIndex: 'updateDate',
    align: 'left',
  },
  {
    title: 'Size',
    dataIndex: 'size',
    align: 'left',
  },
]

const canUseFilePicker = FilePicker.canUse()

export default {
  mixins: [ModalMixin],
  props: {
    value: {
      type: Boolean,
    },
  },
  data() {
    this.columns = columns
    return {
      visible_file: false,
      list_file: [],
      columns_file,
      loading_file: false,
      loading_list: false,
      isUploadingZip: false,
      list: [],
      ipagination: {
        current: 1,
        pageSize: 10,
        pageSizeOptions: ['10', '20', '30'],
        showTotal: (total, range) => {
          const { current, pageSize } = this.ipagination
          return `Total ${total} items　Page ${current} / ${Math.ceil(total / pageSize)}`
        },
        showQuickJumper: true,
        showSizeChanger: true,
        total: 0,
      },
      selectedRowKeys: [],
      selectedFiles: [],
      fileList: [],
      fileNum: 0,
      uploading: false,
      currRowData: {},
      currFileType: '_S_',
      selectedRowKeys_edit: [],
      selectionRows_edit: [],
      tableType: 'multiple',
      searchName: '',

      canUseFilePicker,
    }
  },
  created() {
    this.handleReset()
  },
  methods: {
    // 初始化为10*4的表格
    getInitialList() {
      return new Array(10).fill(0).map(() => ({
        sampleFileName: undefined,
        gasFileName: undefined,
        detFileName: undefined,
        qcFileName: undefined,
      }))
    },
    customRow(record, index) {
      const that = this
      return {
        on: {
          click: () => {
            if (that.selectedRowKeys.includes(record.id)) {
              const findIndex = that.selectedRowKeys.findIndex((k) => k == record.id)
              const idx = that.selectedFiles.findIndex((k) => k == record.name)
              that.selectedRowKeys.splice(findIndex, 1)
              that.selectedFiles.splice(idx, 1)
            } else {
              that.selectedRowKeys.push(record.id)
              that.selectedFiles.push(record.name)
            }
          },
        },
      }
    },

    handleFileChange(record, key, fileInfo) {
      record[key] = fileInfo
    },
    handleFileSelect(str, record) {
      this.currRowData = record
      this.currFileType = str
      this.selectedRowKeys = []
      this.selectedFiles = []
      this.visible_file = true
      this.tableType = str === '_S_' ? 'multiple' : 'single'
      this.getSpectrumFile({ pageNo: 1, pageSize: 10 })
    },

    // 用新的文件操作接口
    async useFilePicker(column, record, rowIndex) {
      // 如果没有选择sampleFile，则不允许选其他的
      if (column !== 'sampleFileName' && (!record.sampleFileName || record.fileType !== 'B')) {
        return
      }
      if (this.directoryHanlder) {
        this.chooseFile(column, record, rowIndex)
      } else {
        try {
          this.directoryHanlder = await FilePicker.chooseDirectory()
          this.chooseFile(column, record, rowIndex)
        } catch {}
      }
    },

    /**
     * 本地选择文件
     * @param column
     * @param record
     * @param rowIndex
     */
    async chooseFile(column, record, rowIndex) {
      try {
        const [fileHandle] = await FilePicker.chooseFile(false, [{ accept: { 'text/phd': ['.phd'] } }])
        try {
          const isFileInDirectory = await FilePicker.isFileInDirectory(this.directoryHanlder, fileHandle)
          if (!isFileInDirectory) {
            this.$message.warn('File and Directory Not in Same')
            this.directoryHanlder = undefined
            this.useFilePicker(column, record, rowIndex)
            return
          }

          const file = await fileHandle.getFile()
          const text = await readFile(file)
          const phdParser = new PHDParser(text)
          console.log('%c [ phdParser ]-313', 'font-size:13px; background:pink; color:#bf2c9f;', phdParser)
          const match = this.fileNameAndColumnMatch(column, phdParser.dataType)
          if (!match) {
            this.$message.warn('File Type Error')
            return
          }

          record.fileType = phdParser.fileType

          // 如果是sample
          if (column == 'sampleFileName') {
            // 看看之前有没有选中过该文件，非同一行，则只能选择文件名不同的
            const findIndex = this.list.findIndex(
              (item) => item.sampleFileName && item.sampleFileName.file && item.sampleFileName.file.name == file.name
            )
            if (-1 !== findIndex && findIndex !== rowIndex) {
              return
            }

            const { sampleFilePrefix, otherFilePrefixes, qualify, liveTime } = phdParser
            const fileName = `${sampleFilePrefix}S_${qualify}_${liveTime}.PHD`
            record.sampleFileName = {
              file: new File([file], fileName),
              fileName,
            }

            // 如果是Beta Gamma，则查找其他的文件
            if (phdParser.fileType == 'B') {
              const iter = await this.directoryHanlder.values()
              const fileList = []

              let result = await iter.next()
              while (!result.done) {
                const fileHandle = result.value
                const file = await fileHandle.getFile()
                fileList.push(file)
                result = await iter.next()
              }

              const nameKeys = ['detFileName', 'gasFileName']
              const fileTypes = ['D', 'G']

              otherFilePrefixes.forEach((otherFilePrefix, index) => {
                const fileType = fileTypes[index]
                // 在所有文件中查找 名字含有 从sample文件解析出的文件名 的文件
                const findFile = fileList.find((file) => {
                  return file.name.includes(`${otherFilePrefix}${fileType}_${qualify}`)
                })

                if (findFile) {
                  const regExp = new RegExp(
                    `(${otherFilePrefix}${fileType}_${qualify}_\\d{1,}\\.{0,}\\d{0,}).*?(\\.PHD)`
                  )
                  record[nameKeys[index]] = {
                    file: findFile,
                    fileName: findFile.name.replace(regExp, '$1$2'),
                  }
                } else {
                  record[nameKeys[index]] = {
                    file: undefined,
                    fileName: `${otherFilePrefix}${fileType}.PHD`,
                  }
                }
              })

              // 查找 QC 文件
              let qcFileInfo = {
                file: undefined,
                fileName: `${sampleFilePrefix}Q.PHD`,
              }
              const qcFileList = fileList.filter((file) => file.name.includes('_Q_'))
              for (const qcFile of qcFileList) {
                if (qcFile.name.slice(0, 23) <= sampleFilePrefix) {
                  qcFileInfo = {
                    file: qcFile,
                    fileName: qcFile.name,
                  }
                } else {
                  break
                }
              }
              record.qcFileName = qcFileInfo
            } else if (phdParser.fileType == 'C') {
              const iter = await this.directoryHanlder.values()
              const fileList = []

              let result = await iter.next()
              while (!result.done) {
                const fileHandle = result.value
                const file = await fileHandle.getFile()
                fileList.push(file)
                result = await iter.next()
              }

              const nameKeys = ['detFileName']
              const fileTypes = ['D']
              otherFilePrefixes.forEach((otherFilePrefix, index) => {
                const fileType = fileTypes[index]
                // 在所有文件中查找 名字含有 从sample文件解析出的文件名 的文件
                const findFile = fileList.find((file) => {
                  return file.name.includes(`${otherFilePrefix}${fileType}_${qualify}`)
                })

                if (findFile) {
                  const regExp = new RegExp(
                    `(${otherFilePrefix}${fileType}_${qualify}_\\d{1,}\\.{0,}\\d{0,}).*?(\\.PHD)`
                  )
                  record[nameKeys[index]] = {
                    file: findFile,
                    fileName: findFile.name.replace(regExp, '$1$2'),
                  }
                } else {
                  record[nameKeys[index]] = {
                    file: undefined,
                    fileName: `${otherFilePrefix}${fileType}.PHD`,
                  }
                }
              })
              // 查找 QC 文件
              let qcFileInfo = {
                file: undefined,
                fileName: `${sampleFilePrefix}Q.PHD`,
              }
              const qcFileList = fileList.filter((file) => file.name.includes('_Q_'))
              for (const qcFile of qcFileList) {
                if (qcFile.name.slice(0, 23) <= sampleFilePrefix) {
                  qcFileInfo = {
                    file: qcFile,
                    fileName: qcFile.name,
                  }
                } else {
                  break
                }
              }
              record.qcFileName = qcFileInfo
            } else {
              Object.assign(record, {
                gasFileName: undefined,
                detFileName: undefined,
                qcFileName: undefined,
              })
            }
          }
          // 非sample
          else {
            record[column] = {
              file,
              fileName: file.name,
            }
          }
        } catch (error) {
          console.log(error)
        }
      } catch {}
    },

    /**
     * 判断文件和列是否匹配
     * @param {*} column
     * @param {*} dataType
     */
    fileNameAndColumnMatch(column, dataType) {
      let currDataType = ''
      switch (column) {
        case 'sampleFileName':
          return isSample(dataType)
        case 'gasFileName':
          currDataType = PHD_DATA_TYPE.GASBKPHD
          break
        case 'detFileName':
          currDataType = PHD_DATA_TYPE.DETBKPHD
          break
        case 'qcFileName':
          currDataType = PHD_DATA_TYPE.QCPHD
          break
      }

      return currDataType == dataType
    },

    onSearchFileName() {
      this.getSpectrumFile({ pageNo: 1, pageSize: 10 })
    },
    getSpectrumFile(params) {
      this.loading_file = true
      let params_arg = { ...params, name: `${this.searchName ? this.searchName + ',' : ''}${this.currFileType}` }
      getAction('/spectrumFile/get', params_arg).then((res) => {
        this.loading_file = false
        if (res.success) {
          res.result.records.forEach((item, index) => {
            item.id = index
          })
          this.ipagination.total = res.result.total
          this.ipagination.current = res.result.current
          this.ipagination.pageSize = res.result.size
          this.list_file = res.result.records
        } else {
          this.$message.warning('This operation fails. Contact your system administrator')
        }
      })
    },
    handlePageChange(page, pageSize) {
      this.selectedRowKeys = []
      this.selectedFiles = []
      this.ipagination.current = page
      this.ipagination.pageSize = pageSize
      this.getSpectrumFile({
        pageNo: page,
        pageSize: pageSize,
      })
    },
    handleSizeChange(current, size) {
      this.ipagination.current = current
      this.ipagination.pageSize = size
      this.getSpectrumFile({
        pageNo: current,
        pageSize: size,
      })
    },
    onSelectChange(selectedRowKeys, selectedRows) {
      this.selectedRowKeys = selectedRowKeys
      this.selectedFiles = selectedRows.map((item) => {
        return item.name
      })
    },
    saveFileName() {
      this.visible_file = false
      if (this.tableType === 'multiple') {
        this.loading_list = true
        let params = {
          fileName: this.selectedFiles.join(','),
        }
        getAction('/spectrumAnalysis/getFilesBySampleFile', params).then((res) => {
          this.loading_list = false
          if (res.success) {
            let idx = res.result.length
            let staIdx = this.list.filter((item) => Object.keys(item).length > 4).length
            if (staIdx < 10) {
              this.list.splice(staIdx, idx, ...res.result)
            } else {
              this.list.push(...res.result)
            }
          } else {
            this.$message.warning('This operation fails. Contact your system administrator')
          }
        })
      } else {
        let currFileName = this.selectionRows_edit[0].name
        if (currFileName.includes(this.currFileType)) {
          this.currRowData.gasFileName = currFileName
        }
      }
    },
    cancelFileModale() {
      this.visible_file = false
      this.list_file = []
    },
    beforeUpload(file, fileList) {
      this.fileList = fileList
    },
    async handleUpload() {
      this.uploading = true
      this.fileNum += 1
      if (this.fileNum == this.fileList.length) {
        const file = await zipFile(this.fileList, 'test.zip')
        const res = await this.uploadZipFile(file)
        this.uploading = false
        this.fileNum = 0
        if (res.success) {
          this.$message.success(res.message)
        } else {
          this.$message.warning(res.message)
        }
      }
    },

    // 上传zip文件
    async uploadZipFile(file) {
      const formData = new FormData()
      formData.append('file', file)
      const res = await postActionWithTimeOut('/spectrumFile/upload', formData, 0)
      return res
    },

    handleReset() {
      this.list = this.getInitialList()
    },

    async handleLoad() {
      // 如果文件系统可用
      if (this.canUseFilePicker) {
        const propNames = ['sampleFileName', 'gasFileName', 'detFileName', 'qcFileName']
        const propStatus = ['sampleFileStatus', 'gasFileStatus', 'detFileStatus', 'qcFileStatus']
        const files = []
        const allFiles = []
        for (const item of this.list) {
          if (item.fileType) {
            let fileObj = {
              files: [],
              fileType: item.fileType,
            }
            propNames.forEach((propName, index) => {
              const value = item[propName]
              if (value && value.file) {
                fileObj[propStatus[index]] = true
                files.push(value.file)
                fileObj.files.push(value.fileName)
              } else {
                fileObj[propStatus[index]] = false
              }
            })
            allFiles.push(fileObj)
          }
        }
        console.log('filesfiles', files)
        if (!files.length) {
          this.$message.warn('File is Empty ')
          return
        }

        try {
          const zipedFiles = await zipFile(files, 'test.zip')
          console.log('zipedFileszipedFiles', zipedFiles)
          this.isUploadingZip = true

          const { success, message } = await this.uploadZipFile(zipedFiles)
          if (success) {
            let result = []
            allFiles.forEach((el) => {
              let obj = {}
              if (el.fileType == 'B') {
                obj.sampleSystemType = el.fileType
                el.files.forEach((item) => {
                  if (item.includes('_S_')) {
                    obj.sampleFileName = item
                  }
                  if (item.includes('_G_')) {
                    obj.gasFileName = item
                    obj.gasFileStatus = el.gasFileStatus
                  }
                  if (item.includes('_D_')) {
                    obj.detFileName = item
                    obj.detFileStatus = el.detFileStatus
                  }
                  if (item.includes('_Q_')) {
                    obj.qcFileName = item
                    obj.qcFileStatus = el.qcFileStatus
                  }
                })
              } else if (el.fileType == 'C') {
                obj.sampleSystemType = el.fileType
                obj.gasFileName = ''
                obj.qcFileName = ''
                el.files.forEach((item) => {
                  if (item.includes('_S_')) {
                    obj.sampleFileName = item
                  }
                  if (item.includes('_D_')) {
                    obj.detFileName = item
                    obj.detFileStatus = el.detFileStatus
                  }
                  if (item.includes('_Q_')) {
                    obj.qcFileName = item
                    obj.qcFileStatus = el.qcFileStatus
                  }
                })
              } else {
                el.files.forEach((item) => {
                  if (item.includes('_S_')) {
                    obj.sampleSystemType = el.fileType
                    obj.sampleFileName = item
                    obj.gasFileName = ''
                    obj.detFileName = ''
                    obj.qcFileName = ''
                  }
                })
              }
              result.push(obj)
            })
            this.$emit('loadFormFile', result)
            this.visible = false
            this.isUploadingZip = false
            // }
          } else {
            this.isUploadingZip = false
            this.$message.error(message)
          }
        } catch (error) {
          console.error(error)
          this.isUploadingZip = false
        }
      } else {
        this.visible = false
        this.$emit('loadFormFile', cloneDeep(this.list.filter((item) => item.sampleFileName)))
      }
    },

    handleCancel() {
      this.visible = false
    },
  },
}
</script>

<style lang="less" scoped>
.status {
  display: inline-block;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  margin-top: 8px;

  background-color: transparent;
}
.status_true {
  background-color: #00e170;
}
.status_false {
  background-color: red;
}
::v-deep {
  @tableBorderColor: #000;

  .ant-table-bordered .ant-table-thead > tr > th,
  .ant-table-bordered .ant-table-tbody > tr > td {
    border-right-color: @tableBorderColor;
  }
  .ant-table-thead > tr th {
    border-bottom: 1px solid @tableBorderColor;
  }

  .ant-table-bordered .ant-table-body > table {
    border-color: @tableBorderColor;
  }

  .ant-table-tbody tr td {
    padding-top: 0 !important;
    padding-bottom: 0 !important;
  }
  .ant-pagination {
    position: absolute;
    bottom: 0;
    width: 100%;
    text-align: center;
  }
  .ant-select {
    .ant-select-arrow-icon {
      transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
    }
    &-open {
      .ant-select-arrow-icon {
        transform: rotate(180deg);
      }
    }
  }
  .ant-modal-title {
    letter-spacing: 1px;
  }
}
.item-label {
  display: inline-block;
  font-size: 16px;
  font-family: ArialMT;
  color: #ade6ee;
  line-height: 32px;
  height: 32px;
  margin-right: 10px;
}
.operators {
  width: 100%;
  justify-content: center;
  .ant-btn {
    width: 92px;
  }
}
.file-name {
  height: 42px;
  line-height: 42px;
}
.file-name-color {
  color: red;
}
.file-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  user-select: none;
  height: 40px;
  line-height: 40px;
}
/deep/.ant-table-tbody .ant-table-row td {
  cursor: pointer;
}
.ant-input {
  width: 380px;
}
/deep/.ant-table-bordered.ant-table-fixed-header .ant-table-header > table {
  border: none;
}
</style>
