Files
workspace/code/file-preview/.trae/documents/g3-file-preview-plan.md
T
2026-04-28 17:29:53 +08:00

12 KiB
Raw Blame History

G3File 预览区域布局修改计划

一、需求分析

根据用户需求,需要对 g3-file-container 进行以下修改:

  1. 布局调整:改为左右两栏布局

    • 左侧区域:保持现有完整结构(header + main + footer)
    • 右侧区域:新增预览区域(toolbar 10% + 预览内容区 90%)
  2. 预览区域 Toolbar:

    • 文件总数(仅统计已上传文件)
    • 当前预览文件名
    • 顺序导航按钮(上一个/下一个)
  3. 预览规则:

    • 只有 status === 'uploaded' 的文件才可预览
    • 预览总数只计算已上传文件
  4. 预览功能:暂时不实现实际预览功能,只显示测试内容

二、布局结构

2.1 原布局

┌─────────────────────────────────────┐
│              Header                 │
├─────────────────────────────────────┤
│              Main                   │
│           (文件列表)                 │
├─────────────────────────────────────┤
│              Footer                 │
└─────────────────────────────────────┘

2.2 新布局

┌─────────────────────────────────────────────────────────────────┐
│  左侧区域                                    │  右侧预览区域     │
│  ┌─────────────────────────────────────┐    │  ┌───────────┐  │
│  │              Header                 │    │  │ Toolbar   │  │
│  ├─────────────────────────────────────┤    │  │(10%高度)  │  │
│  │              Main                   │    ├───────────────┤  │
│  │           (文件列表)                 │    │             │  │
│  ├─────────────────────────────────────┤    │  预览内容区  │  │
│  │              Footer                 │    │  (90%高度)   │  │
│  └─────────────────────────────────────┘    │             │  │
│                                            └─────────────┘  │
└───────────────────────────────────────────────────────────────┘

2.3 Toolbar 内容

┌─────────────────────────────────────────────────────────┐
│ [上一个]  第 1/5 个文件  当前: filename.pdf  [下一个]   │
└─────────────────────────────────────────────────────────┘

三、修改方案

3.1 修改文件

文件 修改内容
g3-file/index.css 添加左右布局和预览区域样式
g3-file/index.js 修改布局结构、添加预览区域逻辑

3.2 JS 修改要点

  1. 渲染方法 (render):修改 HTML 结构为左右布局
  2. 状态管理:
    • currentPreviewIndex: 当前预览文件索引
  3. 预览操作方法:
    • getPreviewableFiles(): 获取已上传文件列表
    • previewFile(file): 预览指定文件
    • previewNext(): 预览下一个文件
    • previewPrev(): 预览上一个文件
    • updatePreviewArea(): 更新预览区域 UI
  4. 事件绑定:绑定预览区域按钮事件

3.3 CSS 修改要点

  1. 整体容器:改为横向 flex 布局
  2. 左侧区域:保持原有结构,设置宽度比例(如 50%)
  3. 右侧区域:
    • 设置宽度比例(如 50%)
    • 纵向 flex 布局
    • toolbar 占 10% 高度
    • 预览内容区占 90% 高度
  4. Toolbar 样式:按钮、进度显示等

四、实施步骤

步骤 1:修改 CSS 样式

/* 整体布局 - 横向排列 */
.g3-file-container {
  height: 100%;
  display: flex;
  background: #ffffff;
  overflow: hidden;
}

/* 左侧区域 */
.g3-file-left-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  border-right: 1px solid #eef0f2;
}

/* 右侧预览区域 */
.g3-file-right-panel {
  flex: 1;
  display: flex;
  flex-direction: column;
  background: #fafbfc;
}

/* 预览 Toolbar */
.g3-preview-toolbar {
  height: 10%;
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0 16px;
  background: #fff;
  border-bottom: 1px solid #eef0f2;
}

/* 预览内容区域 */
.g3-preview-content {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
  overflow: auto;
}

/* 预览空状态 */
.g3-preview-empty {
  text-align: center;
  color: #999;
  font-size: 14px;
}

/* 预览文件信息 */
.g3-preview-file-info {
  text-align: center;
}

/* 预览按钮 */
.g3-preview-btn {
  padding: 6px 12px;
  border: 1px solid #d9d9d9;
  background: #fff;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.g3-preview-btn:hover:not(:disabled) {
  border-color: #165dff;
  color: #165dff;
}

.g3-preview-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

/* 预览状态文字 */
.g3-preview-status {
  font-size: 13px;
  color: #666;
}

步骤 2:修改 JS 渲染方法

修改 render() 方法的 HTML 结构:

render: function () {
  const html = `
    <div class="g3-file-container">
      <!-- 左侧区域 -->
      <div class="g3-file-left-panel">
        <div class="header">...</div>
        <div class="main" style="display: none;">main</div>
        <div class="empty-tip">...</div>
        <div class="footer">...</div>
      </div>
      
      <!-- 右侧预览区域 -->
      <div class="g3-file-right-panel">
        <div class="g3-preview-toolbar">
          <button class="g3-preview-btn preview-prev" disabled>上一个</button>
          <div class="g3-preview-status">
            <span class="preview-counter">第 0/0 个文件</span>
            <span class="preview-filename" style="margin-left: 12px;"></span>
          </div>
          <button class="g3-preview-btn preview-next" disabled>下一个</button>
        </div>
        <div class="g3-preview-content">
          <div class="g3-preview-empty">请选择一个已上传的文件进行预览</div>
        </div>
      </div>
      
      <input type="file" class="file-input" style="display: none;" multiple />
      <div class="g3-global-menu"></div>
    </div>
  `;
  
  this.$container.html(html);
  
  // 缓存 DOM 元素
  this.$leftPanel = this.$container.find(".g3-file-left-panel");
  this.$rightPanel = this.$container.find(".g3-file-right-panel");
  this.$fileList = this.$leftPanel.find(".main");
  this.$emptyTip = this.$leftPanel.find(".empty-tip");
  this.$checkAll = this.$leftPanel.find(".check-all-checkbox");
  this.$btnDownload = this.$leftPanel.find(".download-all");
  this.$btnDelete = this.$leftPanel.find(".delete-all");
  this.$btnUpload = this.$leftPanel.find(".upload");
  this.$btnSelect = this.$leftPanel.find(".select");
  this.$fileInput = this.$container.find(".file-input");
  this.$pendingCount = this.$leftPanel.find(".pending-number");
  
  // 预览区域元素
  this.$previewToolbar = this.$container.find(".g3-preview-toolbar");
  this.$previewContent = this.$container.find(".g3-preview-content");
  this.$btnPreviewPrev = this.$container.find(".preview-prev");
  this.$btnPreviewNext = this.$container.find(".preview-next");
  this.$previewCounter = this.$container.find(".preview-counter");
  this.$previewFilename = this.$container.find(".preview-filename");
  
  return this;
}

步骤 3:添加预览相关状态和方法

// 构造函数中添加
this.currentPreviewIndex = -1;

// 获取可预览文件(已上传文件)
getPreviewableFiles: function () {
  return this.files.filter(file => file.status === 'uploaded');
},

// 预览指定文件
previewFile: function (file) {
  const previewableFiles = this.getPreviewableFiles();
  const index = previewableFiles.findIndex(f => f._id === file._id);
  
  if (index !== -1) {
    this.currentPreviewIndex = index;
    this.updatePreviewArea();
  }
},

// 预览下一个
previewNext: function () {
  const previewableFiles = this.getPreviewableFiles();
  if (previewableFiles.length === 0) return;
  
  if (this.currentPreviewIndex < previewableFiles.length - 1) {
    this.currentPreviewIndex++;
    this.updatePreviewArea();
  }
},

// 预览上一个
previewPrev: function () {
  if (this.currentPreviewIndex > 0) {
    this.currentPreviewIndex--;
    this.updatePreviewArea();
  }
},

// 更新预览区域
updatePreviewArea: function () {
  const previewableFiles = this.getPreviewableFiles();
  const total = previewableFiles.length;
  
  // 更新计数器
  if (this.currentPreviewIndex >= 0 && this.currentPreviewIndex < total) {
    this.$previewCounter.text(`第 ${this.currentPreviewIndex + 1}/${total} 个文件`);
    this.$previewFilename.text(`当前: ${previewableFiles[this.currentPreviewIndex].name}`);
  } else {
    this.$previewCounter.text(`第 0/${total} 个文件`);
    this.$previewFilename.text('');
  }
  
  // 更新按钮状态
  this.$btnPreviewPrev.prop('disabled', this.currentPreviewIndex <= 0);
  this.$btnPreviewNext.prop('disabled', 
    this.currentPreviewIndex >= total - 1 || total === 0);
  
  // 更新预览内容
  if (this.currentPreviewIndex >= 0 && this.currentPreviewIndex < total) {
    const file = previewableFiles[this.currentPreviewIndex];
    this.$previewContent.html(`
      <div class="g3-preview-file-info">
        <h3>${file.name}</h3>
        <p>大小: ${this.formatFileSize(file.size)}</p>
        <p>上传时间: ${this.formatDate(file.uploadDate)}</p>
        <p>状态: 已上传</p>
        <p>URL: ${file.url || '-'}</p>
      </div>
    `);
  } else {
    this.$previewContent.html('<div class="g3-preview-empty">请选择一个已上传的文件进行预览</div>');
  }
}

步骤 4:绑定预览事件

bindEvents: function () {
  var self = this;
  
  // ... 原有事件绑定 ...
  
  // 预览下一个按钮
  this.$btnPreviewNext.off("click").on("click", function () {
    self.previewNext();
  });
  
  // 预览上一个按钮
  this.$btnPreviewPrev.off("click").on("click", function () {
    self.previewPrev();
  });
  
  // 点击文件项预览(只对已上传文件生效)
  this.$fileList
    .off("click", ".g3-file-item")
    .on("click", ".g3-file-item", function (e) {
      if ($(e.target).closest(".g3-file-action, .g3-file-checkbox, .g3-file-delete-btn").length) {
        return;
      }
      
      var id = $(this).data("id");
      var file = self.files.find(f => f._id === id);
      
      if (!file) return;
      
      // 只有已上传文件才能预览
      if (file.status === 'uploaded') {
        self.previewFile(file);
      }
      
      if (typeof self.options.onPreview === "function") {
        self.options.onPreview([file]);
      }
    });
}

步骤 5:更新文件操作后的预览状态

在 internalDelete()、updateFileStatus() 等方法中调用 updatePreviewArea()

五、注意事项

  1. 预览计数:只统计 status === 'uploaded' 的文件
  2. 预览权限:只有已上传文件才能预览
  3. 边界处理:
    • 没有可预览文件时,工具栏按钮禁用
    • 处于第一个文件时,上一个按钮禁用
    • 处于最后一个文件时,下一个按钮禁用
  4. 预览内容:暂时显示测试内容(文件名、大小、日期等信息)

六、测试验证

  1. 上传文件后,预览区域显示可预览文件数量
  2. 点击已上传文件,预览区域显示文件信息
  3. 上下按钮正确切换预览文件
  4. 删除文件后,预览区域正确更新
  5. 未上传文件点击不触发预览