12 KiB
12 KiB
G3File 预览区域布局修改计划
一、需求分析
根据用户需求,需要对 g3-file-container 进行以下修改:
-
布局调整:改为左右两栏布局
- 左侧区域:保持现有完整结构(header + main + footer)
- 右侧区域:新增预览区域(toolbar 10% + 预览内容区 90%)
-
预览区域 Toolbar:
- 文件总数(仅统计已上传文件)
- 当前预览文件名
- 顺序导航按钮(上一个/下一个)
-
预览规则:
- 只有
status === 'uploaded'的文件才可预览 - 预览总数只计算已上传文件
- 只有
-
预览功能:暂时不实现实际预览功能,只显示测试内容
二、布局结构
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 修改要点
- 渲染方法 (
render):修改 HTML 结构为左右布局 - 状态管理:
currentPreviewIndex: 当前预览文件索引
- 预览操作方法:
getPreviewableFiles(): 获取已上传文件列表previewFile(file): 预览指定文件previewNext(): 预览下一个文件previewPrev(): 预览上一个文件updatePreviewArea(): 更新预览区域 UI
- 事件绑定:绑定预览区域按钮事件
3.3 CSS 修改要点
- 整体容器:改为横向 flex 布局
- 左侧区域:保持原有结构,设置宽度比例(如 50%)
- 右侧区域:
- 设置宽度比例(如 50%)
- 纵向 flex 布局
- toolbar 占 10% 高度
- 预览内容区占 90% 高度
- 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()
五、注意事项
- 预览计数:只统计
status === 'uploaded'的文件 - 预览权限:只有已上传文件才能预览
- 边界处理:
- 没有可预览文件时,工具栏按钮禁用
- 处于第一个文件时,上一个按钮禁用
- 处于最后一个文件时,下一个按钮禁用
- 预览内容:暂时显示测试内容(文件名、大小、日期等信息)
六、测试验证
- 上传文件后,预览区域显示可预览文件数量
- 点击已上传文件,预览区域显示文件信息
- 上下按钮正确切换预览文件
- 删除文件后,预览区域正确更新
- 未上传文件点击不触发预览