<template>
  <div class="app-container">
    <!-- 统计卡片 -->
    <el-row :gutter="16" class="stat-row" v-if="activeTab === 'all'">
      <el-col :span="6">
        <div class="stat-card">
          <div class="stat-num">{{ stats.totalFiles }}</div>
          <div class="stat-label">文件总数</div>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="stat-card public">
          <div class="stat-num">{{ stats.publicFiles }}</div>
          <div class="stat-label">公开文件</div>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="stat-card private">
          <div class="stat-num">{{ stats.privateFiles }}</div>
          <div class="stat-label">私有文件</div>
        </div>
      </el-col>
      <el-col :span="6">
        <div class="stat-card">
          <div class="stat-num">{{ stats.myFiles }}</div>
          <div class="stat-label">我上传的</div>
        </div>
      </el-col>
    </el-row>

    <!-- Tab 切换 -->
    <el-tabs v-model="activeTab" @tab-click="handleTabClick">
      <el-tab-pane label="我的文件" name="my"></el-tab-pane>
      <el-tab-pane label="共享文件" name="share"></el-tab-pane>
      <el-tab-pane label="与我相关" name="related"></el-tab-pane>
    </el-tabs>

    <!-- 左右分栏布局 -->
    <div class="file-layout" ref="layoutContainer">
      <!-- 左侧：文件列表 -->
      <div class="file-left" :style="{ width: activeTab === 'share' ? leftPanelWidth : '100%' }">
        <!-- 搜索栏 -->
        <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="80px">
          <el-form-item label="文件名称" prop="fileName">
            <el-input
              v-model="queryParams.fileName"
              placeholder="请输入文件名称"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="订单编号" prop="orderNo">
            <el-input
              v-model="queryParams.orderNo"
              placeholder="请输入订单编号"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="所属部门" prop="dept">
            <el-input
              v-model="queryParams.dept"
              placeholder="请输入部门"
              clearable
              style="width: 200px"
              @keyup.enter.native="handleQuery"
            />
          </el-form-item>
          <el-form-item label="文件类型" prop="fileType">
            <el-select
              v-model="queryParams.fileType"
              placeholder="请选择文件类型"
              clearable
              style="width: 200px"
            >
              <el-option
                v-for="item in dict.type.sys_file_type"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </el-form-item>
          <el-form-item label="可见范围" prop="scopeType" v-if="activeTab !== 'share' && activeTab !== 'related'">
            <el-select
              v-model="queryParams.scopeType"
              placeholder="请选择可见范围"
              clearable
              style="width: 200px"
            >
              <el-option label="公开" :value="1" />
              <el-option label="私有" :value="2" />
            </el-select>
          </el-form-item>
          <el-form-item label="上传时间">
            <el-date-picker
              v-model="dateRange"
              style="width: 240px"
              value-format="yyyy-MM-dd HH:mm:ss"
              type="daterange"
              range-separator="-"
              start-placeholder="开始日期"
              end-placeholder="结束日期"
              :default-time="['00:00:00', '23:59:59']"
            ></el-date-picker>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>

        <!-- 操作按钮 -->
        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5" v-if="activeTab === 'my' || activeTab === 'all'">
            <el-button
              type="primary"
              plain
              icon="el-icon-plus"
              size="mini"
              @click="handleAdd"
            >上传文件</el-button>
          </el-col>
          <el-col :span="1.5" v-if="activeTab === 'my' || activeTab === 'all'">
            <el-button
              type="danger"
              plain
              icon="el-icon-delete"
              size="mini"
              :disabled="multiple"
              @click="handleDelete"
            >删除</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button
              type="warning"
              plain
              icon="el-icon-download"
              size="mini"
              @click="handleExport"
            >导出</el-button>
          </el-col>
          <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
        </el-row>

        <!-- 文件列表表格 -->
        <KLPTable v-loading="loading" :data="fileList" @selection-change="handleSelectionChange" :highlight-current-row="activeTab === 'share'" @row-click="handleRowClick">
          <el-table-column type="selection" width="55" align="center" v-if="activeTab === 'my' || activeTab === 'all'" />
          <el-table-column label="文件名称" align="center" prop="fileName" :show-overflow-tooltip="true">
            <template slot-scope="scope">
              <el-link type="primary" @click="handlePreview(scope.row)">{{ scope.row.fileName }}</el-link>
            </template>
          </el-table-column>
          <el-table-column label="文件类型" align="center" prop="fileType" v-if="activeTab !== 'share'">
            <template slot-scope="scope">
              <dict-tag :options="dict.type.sys_file_type" :value="scope.row.fileType"/>
            </template>
          </el-table-column>
          <el-table-column label="文件大小" align="center" prop="fileSize" v-if="activeTab !== 'share'">
            <template slot-scope="scope">
              {{ formatFileSize(scope.row.fileSize) }}
            </template>
          </el-table-column>
          <el-table-column label="订单编号" align="center" prop="orderNo" :show-overflow-tooltip="true" v-if="activeTab !== 'share'" />
          <el-table-column label="所属部门" align="center" prop="dept" :show-overflow-tooltip="true" v-if="activeTab !== 'share'" />
          <el-table-column label="可见范围" align="center" prop="scopeType" v-if="activeTab !== 'share'">
            <template slot-scope="scope">
              <el-tag :type="scope.row.scopeType === 1 ? 'success' : 'warning'" size="small">
                {{ scope.row.scopeType === 1 ? '公开' : '私有' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="上传人" align="center" prop="createBy" />
          <el-table-column label="上传时间" align="center" prop="createTime" width="160">
            <template slot-scope="scope">
              <span>{{ parseTime(scope.row.createTime) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="浏览次数" align="center" width="90" v-if="activeTab === 'share'">
            <template slot-scope="scope">
              <span>{{ scope.row.viewCount != null ? scope.row.viewCount : 0 }}</span>
            </template>
          </el-table-column>
          <el-table-column label="备注" align="center" prop="remark" :show-overflow-tooltip="true" v-if="activeTab !== 'share'" />
          <el-table-column label="操作" align="center" width="220" class-name="small-padding fixed-width" v-if="activeTab !== 'share'">
            <template slot-scope="scope">
              <el-button
                size="mini"
                type="text"
                icon="el-icon-view"
                @click="handlePreview(scope.row)"
              >预览</el-button>
              <el-button
                v-if="canEdit(scope.row)"
                size="mini"
                type="text"
                icon="el-icon-edit"
                @click="handleUpdate(scope.row)"
              >编辑</el-button>
              <el-button
                v-if="canEdit(scope.row)"
                size="mini"
                type="text"
                icon="el-icon-delete"
                @click="handleDelete(scope.row)"
              >删除</el-button>
            </template>
          </el-table-column>
        </KLPTable>

        <pagination
          v-show="total>0"
          :total="total"
          :page.sync="queryParams.pageNum"
          :limit.sync="queryParams.pageSize"
          @pagination="getList"
        />
      </div>

      <!-- 拖拽分隔条（仅共享文件 tab） -->
      <div class="resize-handle" v-if="activeTab === 'share'" @mousedown="startResize" :class="{ dragging: isDragging }"></div>

      <!-- 右侧：文件预览（仅共享文件 tab） -->
      <div class="file-right" v-if="activeTab === 'share'">
        <div class="preview-panel">
          <div v-if="!selectedFile" class="preview-empty">
            <el-empty description="请选择左侧文件进行预览" />
          </div>
          <template v-else>
            <div class="preview-header">
              <span class="preview-filename" :title="selectedFile.fileName">{{ selectedFile.fileName }}</span>
              <div>
                <el-button size="mini" type="primary" icon="el-icon-download" @click="downloadFile(selectedFile)">下载</el-button>
                <el-button v-if="canEdit(selectedFile)" size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(selectedFile)">编辑</el-button>
                <el-button v-if="canEdit(selectedFile)" size="mini" type="text" icon="el-icon-delete" @click="handleDelete(selectedFile)">删除</el-button>
              </div>
            </div>
            <div class="preview-meta">
              <span>{{ formatFileSize(selectedFile.fileSize) }}</span>
              <dict-tag :options="dict.type.sys_file_type" :value="selectedFile.fileType" />
              <span>{{ selectedFile.createBy }}</span>
              <span>{{ parseTime(selectedFile.createTime) }}</span>
            </div>
            <div class="preview-comment">
              <div class="comment-bar" @click="commentExpanded = !commentExpanded">
                <span><i class="el-icon-chat-dot-round"></i> 评论 ({{ comments.length }})</span>
                <span class="comment-toggle">{{ commentExpanded ? '收起' : '展开' }} <i :class="commentExpanded ? 'el-icon-arrow-up' : 'el-icon-arrow-down'"></i></span>
              </div>
              <div v-show="commentExpanded" class="comment-body">
                <div v-if="commentLoading" class="comment-hint"><i class="el-icon-loading"></i> 加载中...</div>
                <div v-else-if="comments.length === 0" class="comment-hint comment-empty">暂无评论</div>
                <div v-else class="comment-list">
                  <div v-for="item in comments" :key="item.commentId" class="comment-item">
                    <div class="comment-meta">
                      <span class="comment-dept">{{ item.dept }}</span>
                      <span class="comment-user">{{ item.createBy }}</span>
                      <span class="comment-time">{{ parseTime(item.createTime) }}</span>
                    </div>
                    <div class="comment-text">{{ item.content }}</div>
                  </div>
                </div>
                <div class="comment-input-area">
                  <el-input
                    v-model="commentInput"
                    type="textarea"
                    :rows="2"
                    placeholder="输入评论..."
                    resize="none"
                  />
                  <el-button type="primary" size="mini" @click="handleAddComment" :disabled="!commentInput.trim()" style="margin-top: 6px;">发送</el-button>
                </div>
              </div>
            </div>
            <div class="preview-content">
              <ImagePreview v-if="fileTypeCategory === 'image'" :src="selectedFile.filePath" />
              <PdfPreview v-else-if="fileTypeCategory === 'pdf'" :src="selectedFile.filePath" />
              <DocxPreview v-else-if="fileTypeCategory === 'docx'" :src="selectedFile.filePath" />
              <XlsxPreview v-else-if="fileTypeCategory === 'xlsx'" :src="selectedFile.filePath" />
              <XlsPreview v-else-if="fileTypeCategory === 'xls'" :src="selectedFile.filePath" />
              <div v-else class="preview-not-supported">
                <el-empty description="暂不支持预览此文件类型" />
              </div>
            </div>
          </template>
        </div>
      </div>
    </div>

    <!-- 上传/编辑对话框 -->
    <el-dialog :title="dialogTitle" :visible.sync="open" width="650px" append-to-body @close="handleDialogClose">
      <el-form ref="form" :model="form" :rules="rules" label-width="100px">
        <el-form-item label="文件名称" prop="fileName">
          <el-input v-model="form.fileName" placeholder="请输入文件名称" :disabled="isEdit" />
        </el-form-item>
        <el-form-item label="上传文件" v-if="!isEdit">
          <el-upload
            ref="upload"
            :action="uploadUrl"
            :headers="uploadHeaders"
            :file-list="uploadFileList"
            :before-upload="handleBeforeUpload"
            :on-success="handleUploadSuccess"
            :on-error="handleUploadError"
            :auto-upload="false"
            :limit="1"
            class="upload-demo"
            drag
          >
            <i class="el-icon-upload"></i>
            <div class="el-upload__text">将文件拖到此处，或<em>点击选取</em></div>
          </el-upload>
        </el-form-item>
        <el-form-item label="订单编号" prop="orderNo">
          <el-input v-model="form.orderNo" placeholder="请输入订单编号" />
        </el-form-item>
        <el-form-item label="所属部门" prop="dept">
          <el-input v-model="form.dept" placeholder="请输入所属部门" />
        </el-form-item>
        <el-form-item label="文件类型" prop="fileType">
          <el-select v-model="form.fileType" placeholder="请选择文件类型" style="width: 100%">
            <el-option
              v-for="item in dict.type.sys_file_type"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="可见范围" prop="scopeType">
          <el-radio-group v-model="form.scopeType" @change="handleScopeChange">
            <el-radio :label="1">公开（所有人可见）</el-radio>
            <el-radio :label="2">私有（指定用户可见）</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="可见用户" v-if="form.scopeType === 2">
          <user-select
            v-model="form.visibleUsers"
            :multiple="true"
            placeholder="请选择可见用户"
          />
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" type="textarea" placeholder="请输入备注" :rows="3" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submitForm">确 定</el-button>
        <el-button @click="cancel">取 消</el-button>
      </div>
    </el-dialog>

    <!-- 文件预览对话框（仅非共享文件 tab 使用） -->
    <el-dialog :title="previewTitle" :visible.sync="previewVisible" width="80%" append-to-body>
      <div v-if="previewFile" class="file-preview-container">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="文件名称">{{ previewFile.fileName }}</el-descriptions-item>
          <el-descriptions-item label="文件类型">
            <dict-tag :options="dict.type.sys_file_type" :value="previewFile.fileType"/>
          </el-descriptions-item>
          <el-descriptions-item label="文件大小">{{ formatFileSize(previewFile.fileSize) }}</el-descriptions-item>
          <el-descriptions-item label="文件后缀">{{ previewFile.suffix }}</el-descriptions-item>
          <el-descriptions-item label="订单编号">{{ previewFile.orderNo || '-' }}</el-descriptions-item>
          <el-descriptions-item label="所属部门">{{ previewFile.dept || '-' }}</el-descriptions-item>
          <el-descriptions-item label="可见范围">
            <el-tag :type="previewFile.scopeType === 1 ? 'success' : 'warning'" size="small">
              {{ previewFile.scopeType === 1 ? '公开' : '私有' }}
            </el-tag>
          </el-descriptions-item>
          <el-descriptions-item label="上传人">{{ previewFile.createBy }}</el-descriptions-item>
          <el-descriptions-item label="上传时间">{{ parseTime(previewFile.createTime) }}</el-descriptions-item>
          <el-descriptions-item label="备注" :span="2">{{ previewFile.remark || '-' }}</el-descriptions-item>
        </el-descriptions>
        <div v-if="previewFile.filePath" style="margin-top: 16px;">
          <el-button type="primary" size="small" @click="downloadFile(previewFile)">下载文件</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import { listFile, getFile, addFile, updateFile, delFile, exportFile, listVisibleUser, addVisibleUser, delVisibleUser, listVisibleUserByFileId, listRelatedToMe, incrementView } from '@/api/system/file'
import { listFileComment, addFileComment } from '@/api/system/fileComment'
import { getToken } from '@/utils/auth'
import UserSelect from '@/components/KLPService/UserSelect/index'
import ImagePreview from '@/components/FilePreview/preview/image/index.vue'
import PdfPreview from '@/components/FilePreview/preview/pdf/index.vue'
import DocxPreview from '@/components/FilePreview/preview/docx/index.vue'
import XlsxPreview from '@/components/FilePreview/preview/xlsx/index.vue'
import XlsPreview from '@/components/FilePreview/preview/xls/index.vue'

export default {
  name: 'SysFile',
  dicts: ['sys_file_type'],
  components: {
    UserSelect,
    ImagePreview,
    PdfPreview,
    DocxPreview,
    XlsxPreview,
    XlsPreview
  },
  data() {
    return {
      // 当前激活tab
      activeTab: 'my',
      // 遮罩层
      loading: false,
      // 选中数组
      ids: [],
      // 非单个禁用
      single: true,
      // 非多个禁用
      multiple: true,
      // 显示搜索条件
      showSearch: true,
      // 总条数
      total: 0,
      // 文件列表
      fileList: [],
      // 弹出层标题
      dialogTitle: '',
      // 是否显示弹出层
      open: false,
      // 是否编辑
      isEdit: false,
      // 日期范围
      dateRange: [],
      // 查询参数
      queryParams: {
        pageNum: 1,
        pageSize: 20,
        fileName: undefined,
        orderNo: undefined,
        dept: undefined,
        fileType: undefined,
        scopeType: undefined
      },
      // 表单
      form: {
        fileId: undefined,
        fileName: undefined,
        filePath: undefined,
        fileSize: undefined,
        suffix: undefined,
        orderNo: undefined,
        dept: undefined,
        fileType: undefined,
        scopeType: 1,
        visibleUsers: [],
        remark: undefined
      },
      // 可见用户原始数据（编辑时回显）
      originalVisibleUsers: [],
      // 表单校验
      rules: {
        fileName: [
          { required: true, message: '文件名称不能为空', trigger: 'blur' }
        ],
        fileType: [
          { required: true, message: '请选择文件类型', trigger: 'change' }
        ]
      },
      // 统计
      stats: {
        totalFiles: 0,
        publicFiles: 0,
        privateFiles: 0,
        myFiles: 0
      },
      // 上传相关
      uploadUrl: process.env.VUE_APP_BASE_API + '/system/oss/upload',
      uploadHeaders: {
        Authorization: 'Bearer ' + getToken()
      },
      uploadFileList: [],
      // 预览对话框（非共享文件 tab）
      previewVisible: false,
      previewTitle: '',
      previewFile: null,
      // 选中的文件（共享文件 tab 右侧预览）
      selectedFile: null,
      // 评论
      comments: [],
      commentExpanded: false,
      commentInput: '',
      commentLoading: false,
      // 拖拽调节宽度（共享文件 tab）
      leftPanelWidth: '40%',
      isDragging: false,
      startX: 0,
      startLeftWidth: 60
    }
  },
  computed: {
    /** 根据文件后缀分类，决定右侧用哪个预览组件 */
    fileTypeCategory() {
      if (!this.selectedFile) return null
      const raw = this.selectedFile.suffix || this.selectedFile.fileName || ''
      const ext = (raw.includes('.') ? raw.split('.').pop() : raw).toLowerCase()
      if (['png', 'jpg', 'jpeg', 'bmp', 'webp'].includes(ext)) return 'image'
      if (ext === 'pdf') return 'pdf'
      if (ext === 'docx') return 'docx'
      if (ext === 'xlsx') return 'xlsx'
      if (ext === 'xls') return 'xls'
      return 'other'
    }
  },
  created() {
    this.getList()
  },
  watch: {
    selectedFile(val) {
      if (val) {
        this.loadComments()
      } else {
        this.comments = []
        this.commentExpanded = false
      }
    }
  },
  methods: {
    /** 切换tab */
    handleTabClick(tab) {
      this.resetQuery()
    },
    /** 查询文件列表 */
    getList() {
      this.loading = true
      const params = this.addDateRange(this.queryParams, this.dateRange)
      // 根据tab设置额外参数
      if (this.activeTab === 'my') {
        params.createBy = this.$store.getters.name
      } else if (this.activeTab === 'share') {
        params.scopeType = 1
      }

      // 根据tab选择不同的API
      let request
      if (this.activeTab === 'related') {
        request = listRelatedToMe(params)
      } else {
        request = listFile(params)
      }

      request.then(response => {
        this.fileList = response.rows
        this.total = response.total
        this.loading = false
        // 加载统计数据
        if (this.activeTab === 'all') {
          this.loadStats()
        }
      }).catch(() => {
        this.loading = false
      })
    },
    /** 加载统计数据 */
    loadStats() {
      // 获取所有公开文件数量
      listFile({ pageNum: 1, pageSize: 1, scopeType: 1 }).then(r => { this.stats.publicFiles = r.total })
      // 获取所有私有文件数量
      listFile({ pageNum: 1, pageSize: 1, scopeType: 2 }).then(r => { this.stats.privateFiles = r.total })
      // 我上传的
      listFile({ pageNum: 1, pageSize: 1, createBy: this.$store.getters.name }).then(r => { this.stats.myFiles = r.total })
      // 总计
      listFile({ pageNum: 1, pageSize: 1 }).then(r => { this.stats.totalFiles = r.total })
    },
    /** 格式化文件大小 */
    formatFileSize(size) {
      if (!size) return '0 B'
      if (size < 1024) return size + ' B'
      if (size < 1024 * 1024) return (size / 1024).toFixed(2) + ' KB'
      return (size / 1024 / 1024).toFixed(2) + ' MB'
    },
    /** 是否可编辑 */
    canEdit(row) {
      if (this.activeTab === 'related') return false
      if (this.activeTab === 'share') return false
      // 我的文件tab 或 所有文件tab中属于当前用户的
      return row.createBy === this.$store.getters.name
    },
    /** 取消按钮 */
    cancel() {
      this.open = false
      this.reset()
    },
    /** 对话框关闭回调 */
    handleDialogClose() {
      this.reset()
    },
    /** 表单重置 */
    reset() {
      this.form = {
        fileId: undefined,
        fileName: undefined,
        filePath: undefined,
        fileSize: undefined,
        suffix: undefined,
        orderNo: undefined,
        dept: undefined,
        fileType: undefined,
        scopeType: 1,
        visibleUsers: [],
        remark: undefined
      }
      this.uploadFileList = []
      this.originalVisibleUsers = []
      this.isEdit = false
      this.resetForm('form')
    },
    /** 可见范围切换 */
    handleScopeChange(val) {
      if (val === 1) {
        this.form.visibleUsers = []
      }
    },
    /** 搜索按钮 */
    handleQuery() {
      this.queryParams.pageNum = 1
      this.getList()
    },
    /** 重置按钮 */
    resetQuery() {
      this.dateRange = []
      this.selectedFile = null
      this.resetForm('queryForm')
      this.queryParams = {
        pageNum: 1,
        pageSize: 20,
        fileName: undefined,
        orderNo: undefined,
        dept: undefined,
        fileType: undefined,
        scopeType: undefined
      }
      this.handleQuery()
    },
    /** 多选框 */
    handleSelectionChange(selection) {
      this.ids = selection.map(item => item.fileId)
      this.single = selection.length !== 1
      this.multiple = !selection.length
    },
    /** 新增/上传 */
    handleAdd() {
      this.reset()
      this.isEdit = false
      this.open = true
      this.dialogTitle = '上传文件'
    },
    /** 修改 */
    handleUpdate(row) {
      this.reset()
      this.isEdit = true
      const fileId = row.fileId || this.ids[0]
      getFile(fileId).then(response => {
        const data = response.data
        this.form = {
          fileId: data.fileId,
          fileName: data.fileName,
          filePath: data.filePath,
          fileSize: data.fileSize,
          suffix: data.suffix,
          orderNo: data.orderNo,
          dept: data.dept,
          fileType: data.fileType,
          scopeType: data.scopeType,
          visibleUsers: [],
          remark: data.remark
        }
        // 如果是私有文件，加载可见用户
        if (data.scopeType === 2) {
          listVisibleUserByFileId(fileId).then(res => {
            const rows = res.rows || []
            this.form.visibleUsers = rows.map(r => r.userId)
            this.originalVisibleUsers = [...this.form.visibleUsers]
          })
        }
        this.open = true
        this.dialogTitle = '编辑文件'
      })
    },
    /** 上传前校验 */
    handleBeforeUpload(file) {
      // 自动设置文件名
      if (!this.form.fileName) {
        this.form.fileName = file.name
      }
      const ext = file.name.substring(file.name.lastIndexOf('.') + 1).toLowerCase()
      this.form.suffix = ext
      this.form.fileSize = file.size
    },
    /** 上传成功 */
    handleUploadSuccess(response, file, fileList) {
      if (response.code === 200) {
        this.form.filePath = response.data.url
        this.form.fileName = this.form.fileName || response.data.fileName
        this.$modal.msgSuccess('文件上传成功')
        // 自动提交表单
        this.doSubmit()
      } else {
        this.$modal.msgError(response.msg || '上传失败')
      }
    },
    /** 上传失败 */
    handleUploadError(err, file, fileList) {
      this.$modal.msgError('文件上传失败')
    },
    /** 提交表单 */
    submitForm() {
      this.$refs['form'].validate(valid => {
        if (valid) {
          if (this.isEdit) {
            // 编辑模式直接提交
            this.doSubmit()
          } else {
            // 新增模式，先上传文件
            if (this.$refs.upload && this.$refs.upload.uploadFiles.length > 0) {
              this.$refs.upload.submit()
            } else {
              this.$modal.msgWarning('请选择要上传的文件')
            }
          }
        }
      })
    },
    /** 执行提交 */
    doSubmit() {
      const data = { ...this.form }
      const visibleUsers = data.visibleUsers
      delete data.visibleUsers

      if (data.fileId) {
        // 编辑模式
        updateFile(data).then(response => {
          this.saveVisibleUsers(data.fileId, visibleUsers)
          this.$modal.msgSuccess('修改成功')
          this.open = false
          this.getList()
        }).catch(() => {})
      } else {
        // 新增模式
        addFile(data).then(response => {
          const newFileId = response.data
          if (newFileId && visibleUsers && visibleUsers.length > 0) {
            this.saveVisibleUsers(newFileId, visibleUsers)
          }
          this.$modal.msgSuccess('新增成功')
          this.open = false
          this.getList()
        }).catch(() => {})
      }
    },
    /** 保存可见用户 */
    saveVisibleUsers(fileId, visibleUsers) {
      if (!visibleUsers || visibleUsers.length === 0) {
        // 删除所有可见用户
        if (this.originalVisibleUsers.length > 0) {
          delVisibleUser(this.originalVisibleUsers.join(','))
        }
        return
      }
      // 新增的
      const toAdd = visibleUsers.filter(u => !this.originalVisibleUsers.includes(u))
      // 删除的
      const toDel = this.originalVisibleUsers.filter(u => !visibleUsers.includes(u))

      // 删除
      if (toDel.length > 0) {
        // 需要先查出visibleId
        listVisibleUserByFileId(fileId).then(res => {
          const rows = res.rows || []
          const delIds = rows.filter(r => toDel.includes(r.userId)).map(r => r.visibleId)
          if (delIds.length > 0) {
            delVisibleUser(delIds.join(','))
          }
        })
      }
      // 新增
      toAdd.forEach(userId => {
        addVisibleUser({ fileId, userId })
      })
    },
    /** 删除 */
    handleDelete(row) {
      const fileIds = row.fileId || this.ids.join(',')
      this.$modal.confirm('是否确认删除所选文件？').then(() => {
        return delFile(fileIds)
      }).then(() => {
        this.getList()
        this.$modal.msgSuccess('删除成功')
      }).catch(() => {})
    },
    /** 导出 */
    handleExport() {
      this.download('system/file/export', {
        ...this.queryParams
      }, `file_${new Date().getTime()}.xlsx`)
    },
    /** 预览 */
    handlePreview(row) {
      if (this.activeTab === 'share') {
        this.selectedFile = row
        incrementView(row.fileId)
      } else {
        this.previewFile = row
        this.previewTitle = '文件详情 - ' + row.fileName
        this.previewVisible = true
      }
    },
    /** 点击行选中预览（共享文件 tab） */
    handleRowClick(row) {
      if (this.activeTab === 'share') {
        this.selectedFile = row
      }
    },
    /** 下载文件 */
    downloadFile(row) {
      if (row.filePath) {
        window.open(row.filePath, '_blank')
      }
    },
    /** 加载评论列表 */
    loadComments() {
      this.commentLoading = true
      listFileComment(this.selectedFile.fileId).then(res => {
        this.comments = res.data || []
        this.commentLoading = false
      }).catch(() => {
        this.commentLoading = false
      })
    },
    /** 发送评论 */
    handleAddComment() {
      const content = this.commentInput.trim()
      if (!content) return
      addFileComment({ fileId: this.selectedFile.fileId, content }).then(() => {
        this.commentInput = ''
        this.loadComments()
      })
    },
    /** 开始拖拽 */
    startResize(e) {
      this.isDragging = true
      this.startX = e.clientX
      this.startLeftWidth = parseFloat(this.leftPanelWidth)
      document.addEventListener('mousemove', this.doResize)
      document.addEventListener('mouseup', this.stopResize)
      document.body.style.cursor = 'col-resize'
      document.body.style.userSelect = 'none'
    },
    /** 拖拽中 */
    doResize(e) {
      if (!this.isDragging) return
      const container = this.$refs.layoutContainer
      const rect = container.getBoundingClientRect()
      const deltaX = e.clientX - this.startX
      let percent = this.startLeftWidth + (deltaX / rect.width) * 100
      percent = Math.max(30, Math.min(80, percent))
      this.leftPanelWidth = percent + '%'
    },
    /** 结束拖拽 */
    stopResize() {
      if (!this.isDragging) return
      this.isDragging = false
      document.removeEventListener('mousemove', this.doResize)
      document.removeEventListener('mouseup', this.stopResize)
      document.body.style.cursor = ''
      document.body.style.userSelect = ''
    }
  }
}
</script>

<style scoped>
.stat-row {
  margin-bottom: 16px;
}

.stat-card {
  background: #fff;
  border-radius: 8px;
  padding: 20px;
  text-align: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
  border-left: 4px solid #409eff;
}

.stat-card.public {
  border-left-color: #67c23a;
}

.stat-card.private {
  border-left-color: #e6a23c;
}

.stat-num {
  font-size: 32px;
  font-weight: 700;
  color: #303133;
  line-height: 1.2;
}

.stat-label {
  font-size: 14px;
  color: #909399;
  margin-top: 8px;
}

.file-preview-container {
  padding: 8px;
}

.upload-demo {
  width: 100%;
}

/* 左右分栏布局 */
.file-layout {
  display: flex;
  align-items: flex-start;
  gap: 0;
}

.file-left {
  flex-shrink: 0;
}

.file-right {
  flex: 1;
  min-width: 300px;
}

/* 拖拽分隔条 */
.resize-handle {
  width: 6px;
  cursor: col-resize;
  flex-shrink: 0;
  align-self: stretch;
  background: transparent;
  position: relative;
  transition: background-color 0.2s;
  margin: 0 2px;
  border-radius: 3px;
}

.resize-handle:hover,
.resize-handle.dragging {
  background: #409eff;
}

.resize-handle::after {
  content: '';
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 2px;
  height: 30px;
  background: #dcdfe6;
  border-radius: 1px;
  transition: background-color 0.2s;
}

.resize-handle:hover::after,
.resize-handle.dragging::after {
  background: #fff;
}

.preview-panel {
  background: #fff;
  border: 1px solid #ebeef5;
  border-radius: 4px;
  height: calc(100vh - 280px);
  min-height: 450px;
  display: flex;
  flex-direction: column;
  position: sticky;
  top: 16px;
}

.preview-empty {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preview-header {
  padding: 12px 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.preview-filename {
  font-size: 14px;
  font-weight: 500;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-right: 12px;
}

.preview-meta {
  padding: 8px 16px;
  border-bottom: 1px solid #ebeef5;
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  font-size: 12px;
  color: #909399;
}

.preview-comment {
  border-bottom: 1px solid #ebeef5;
}

.comment-bar {
  padding: 8px 16px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  cursor: pointer;
  font-size: 13px;
  color: #606266;
  user-select: none;
}

.comment-bar:hover {
  background: #f5f7fa;
}

.comment-toggle {
  color: #909399;
  font-size: 12px;
}

.comment-body {
  max-height: 260px;
  overflow-y: auto;
}

.comment-hint {
  padding: 16px;
  text-align: center;
  color: #909399;
  font-size: 13px;
}

.comment-list {
  padding: 4px 0;
}

.comment-item {
  padding: 8px 16px;
  border-bottom: 1px solid #f2f2f2;
}

.comment-item:last-child {
  border-bottom: none;
}

.comment-meta {
  display: flex;
  gap: 8px;
  align-items: center;
  font-size: 12px;
  margin-bottom: 4px;
}

.comment-dept {
  color: #409eff;
  font-weight: 500;
}

.comment-user {
  color: #606266;
}

.comment-time {
  color: #c0c4cc;
}

.comment-text {
  font-size: 13px;
  color: #303133;
  line-height: 1.5;
  word-break: break-all;
}

.comment-input-area {
  padding: 8px 16px;
  border-top: 1px solid #f2f2f2;
}

.preview-content {
  flex: 1;
  overflow: auto;
  display: flex;
}

.preview-content > div {
  width: 100%;
}

.preview-not-supported {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 400px;
}
</style>

<!-- 表格选中行高亮（非 scoped，穿透 el-table） -->
<style>
.file-left .el-table .current-row > td {
  background-color: #ecf5ff !important;
}
</style>
