386 lines
12 KiB
Markdown
386 lines
12 KiB
Markdown
# 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 样式
|
||
|
||
```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 结构:
|
||
|
||
```javascript
|
||
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:添加预览相关状态和方法
|
||
|
||
```javascript
|
||
// 构造函数中添加
|
||
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:绑定预览事件
|
||
|
||
```javascript
|
||
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. 未上传文件点击不触发预览 |