<template>
  <div class="app-container">
    <el-card class="topCard">
      <div class="topDiv">
        <!-- 面包屑导航 -->
        <el-breadcrumb separator="/" style="margin-bottom: 10px;">
          <el-breadcrumb-item v-for="(seg, idx) in currentPathArr" :key="idx" @click.native="jumpToPath(idx)"
            style="cursor:pointer;">
            {{ seg || '根目录' }}
          </el-breadcrumb-item>
        </el-breadcrumb>
        <div style="display: flex;">
          <!-- 左侧文件浏览区 -->
          <div style="width: 650px;border-right: 1px solid #eee; padding-right: 20px;">
            <el-table :data="fileList" style="width: 100%; margin-top: 0;" height="800" size="mini" highlight-current-row
              @row-click="handleRowClick">
              <el-table-column prop="name" label="名称" min-width="120">
                <template slot-scope="scope">
                  <i v-if="scope.row.type === 'directory'" class="el-icon-folder-opened"
                    style="color:#f7ba2a;margin-right:5px;"></i>
                  <i v-else class="el-icon-document" style="color:#409EFF;margin-right:5px;"></i>
                  <span>{{ scope.row.name }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="type" label="类型" width="80" align="center">
                <template slot-scope="scope">
                  <span v-if="scope.row.type === 'directory'">文件夹</span>
                  <span v-else>文件</span>
                </template>
              </el-table-column>
              <el-table-column prop="size" label="大小" width="80">
                <template slot-scope="scope">
                  <span v-if="scope.row.type === 'file'">{{ scope.row.size | fileSize }}</span>
                </template>
              </el-table-column>
              <el-table-column prop="modified" label="修改时间" width="140">
                <template slot-scope="scope">
                  {{ scope.row.modified | dateTime }}
                </template>
              </el-table-column>
            </el-table>
          </div>
          <!-- 右侧预览区 -->
          <div style="flex:1; padding-left: 30px;">
            <FilePreview :fileInfo="fileInfo" :loading="loading" @download="handleDownload" />
          </div>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script>
import FilePreview from './FilePreview.vue'
import axios from 'axios'

export default {
  name: 'CameraImgFileBrowser',
  components: { FilePreview },
  data() {
    return {
      fileList: [], // 当前目录下的文件和文件夹
      currentPath: '', // 当前路径
      fileInfo: null, // 当前选中文件信息
      downloadUrl: '', // 下载链接
      baseUrl: window.g.webAPIURL + '/api/file/',
      loading: false, // 文件加载状态
    }
  },
  computed: {
    currentPathArr() {
      // 用于面包屑导航
      if (!this.currentPath) return ['']
      return ['', ...this.currentPath.split('/').filter(Boolean)]
    }
  },
  created() {
    this.loadDirectory('')
  },
  methods: {
    // 加载目录内容
    loadDirectory(path) {
      this.fileInfo = null
      this.downloadUrl = ''
      this.currentPath = path
      axios.post(this.baseUrl + 'browse', { RelativePath: path })
        .then(res => {
          if (res.data && res.data.type === 'directory') {
            this.fileList = res.data.items
          } else if (res.data && res.data.type === 'file') {
            this.fileList = []
            this.handleFileClick(res.data)
          } else if (res.data && res.data.success === false) {
            this.fileInfo = { errorMsg: res.data.message }
            this.$message.error(res.data.message)
          }
        })
        .catch(err => {
          console.log(err, res)
          this.fileInfo = { errorMsg: err.message }
          this.$message.error('请求失败: ' + err.message)
        })
    },
    // 行点击事件
    handleRowClick(row) {
      if (row.type === 'directory') {
        this.handleFolderClick(row)
      } else {
        this.handleFileClick(row)
      }
    },
    // 文件夹点击
    handleFolderClick(folder) {
      let nextPath = this.currentPath ? this.currentPath + '/' + folder.name : folder.name
      this.loadDirectory(nextPath)
    },
    // 文件点击，预览
    handleFileClick(file) {
      let filePath = file.path || (this.currentPath ? this.currentPath + '/' + file.name : file.name)
      this.loading = true // 开始加载
      axios.post(this.baseUrl + 'browse', { RelativePath: filePath })
        .then(res => {
          if (res.data && res.data.type === 'file') {
            this.fileInfo = res.data
            this.downloadUrl = `${this.baseUrl}?RelativePath=${encodeURIComponent(filePath)}`
          } else if (res.data && res.data.success === false) {
            this.fileInfo = { errorMsg: res.data.message }
            this.$message.error(res.data.message)
          }
          this.loading = false // 加载完成
        })
        .catch(err => {
          this.fileInfo = { errorMsg: err.message }
          this.$message.error('请求失败: ' + err.message)
          this.loading = false // 加载失败
        })
    },
    // 面包屑跳转
    jumpToPath(idx) {
      let arr = this.currentPathArr.slice(1, idx + 1)
      let path = arr.join('/')
      this.loadDirectory(path)
    },
    handleDownload(file) {
      if (!file) return
      const fileName = file.name || 'download'
      const contentType = file.contentType || 'application/octet-stream'
      axios.post(this.baseUrl + 'download', { RelativePath: file.path }, {
        responseType: 'blob'
      }).then(res => {
        const blob = new Blob([res.data], { type: contentType })
        const link = document.createElement('a')
        link.href = window.URL.createObjectURL(blob)
        link.download = fileName
        link.style.display = 'none'
        document.body.appendChild(link)
        link.click()
        document.body.removeChild(link)
        window.URL.revokeObjectURL(link.href)
      }).catch(() => {
        this.$message.error('下载失败')
      })
    },
  },
  filters: {
    fileSize(val) {
      if (!val) return ''
      if (val < 1024) return val + ' B'
      if (val < 1024 * 1024) return (val / 1024).toFixed(1) + ' KB'
      return (val / 1024 / 1024).toFixed(1) + ' MB'
    },
    dateTime(val) {
      if (!val) return ''
      let d = new Date(val)
      return d.getFullYear() + '-' + (d.getMonth() + 1).toString().padStart(2, '0') + '-' + d.getDate().toString().padStart(2, '0') + ' ' + d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0')
    }
  }
}
</script>

<style scoped>
.topCard {
  margin: 5px;
}

.topDiv {
  margin-bottom: 10px;
}
</style>
