Skip to content

Commit 1e60668

Browse files
authored
Merge pull request #10 from CrazyMrYan/feat/full/1.2.0
feat: #9 Paging Example and Return Parameter Adjustment
2 parents 5d43b97 + 358526f commit 1e60668

3 files changed

Lines changed: 98 additions & 56 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ nodejs 实现文件上传功能
1616
| 公开失效时间 ||||
1717
| 高级搜索功能 ||||
1818

19+
[![YouTube](https://img.youtube.com/vi/5w1dCYBrf2k/0.jpg)](https://youtu.be/5w1dCYBrf2k)
20+
1921
### 使用方法
2022

2123
```shell

public/index.html

Lines changed: 85 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@
4343
.filter-buttons {
4444
margin-bottom: 20px;
4545
}
46+
47+
.pagination {
48+
margin-top: 20px;
49+
display: flex;
50+
justify-content: center;
51+
}
4652
</style>
4753
</head>
4854

@@ -54,29 +60,34 @@
5460
type="application/javascript"></script>
5561
<script>
5662
const { createApp, ref, onMounted } = Vue;
57-
const { ElTabs, ElTabPane, ElUpload, ElButton, ElMessage, ElSelect, ElOption, ElImage, ElLoading } = ElementPlus;
63+
const { ElTabs, ElTabPane, ElUpload, ElButton, ElMessage, ElSelect, ElOption, ElImage, ElLoading, ElPagination } = ElementPlus;
5864
const PUBLIC_NETWORK_DOMAIN = 'http://localhost:3000';
65+
5966
createApp({
6067
components: {
61-
ElTabs, ElTabPane, ElUpload, ElButton, ElMessage, ElSelect, ElOption, ElImage, ElLoading
68+
ElTabs, ElTabPane, ElUpload, ElButton, ElMessage, ElSelect, ElOption, ElImage, ElLoading, ElPagination
6269
},
6370
setup() {
6471
const uploadStatus = ref('');
6572
const fileList = ref([]);
6673
const fileType = ref('all');
6774
const loading = ref(false);
6875
const images = ref([]);
69-
const activeTab = ref('1')
76+
const activeTab = ref('1');
77+
const imageTotal = ref(0);
78+
const pageSize = ref(10);
79+
const currentPage = ref(1);
7080

71-
const fetchImages = async () => {
81+
const fetchImages = async (page = 1, size = 10) => {
7282
loading.value = true;
7383
try {
74-
const response = await fetch(`${PUBLIC_NETWORK_DOMAIN}/files?type=${fileType.value}`);
75-
const data = await response.json();
76-
images.value = data.map(file => ({
84+
const response = await fetch(`${PUBLIC_NETWORK_DOMAIN}/files?type=${fileType.value}&limit=${size}&offset=${(page - 1) * size}`);
85+
const { total, items } = await response.json();
86+
images.value = items.map(file => ({
7787
...file,
7888
preview: `${file.thumb_location ?? file.filelocation}`
7989
}));
90+
imageTotal.value = total;
8091
} catch (error) {
8192
ElMessage.error('获取图片列表失败');
8293
} finally {
@@ -96,7 +107,7 @@
96107
const data = await response.json();
97108
file.status = 'success';
98109
ElMessage.success(`${file.name} 上传成功`);
99-
fetchImages();
110+
fetchImages(currentPage.value, pageSize.value);
100111
} catch (error) {
101112
file.status = 'error';
102113
ElMessage.error(`${file.name} 上传失败`);
@@ -134,16 +145,26 @@
134145
}
135146
}
136147

137-
fetchImages();
148+
fetchImages(currentPage.value, pageSize.value);
138149
};
139150

140151
const handleFilterChange = (value) => {
141152
fileType.value = value;
142-
fetchImages();
153+
fetchImages(currentPage.value, pageSize.value);
154+
};
155+
156+
const handleSizeChange = (size) => {
157+
pageSize.value = size;
158+
fetchImages(currentPage.value, size);
159+
};
160+
161+
const handleCurrentChange = (page) => {
162+
currentPage.value = page;
163+
fetchImages(page, pageSize.value);
143164
};
144165

145166
onMounted(() => {
146-
fetchImages();
167+
fetchImages(currentPage.value, pageSize.value);
147168
});
148169

149170
return {
@@ -158,47 +179,63 @@
158179
loading,
159180
handleFilterChange,
160181
activeTab,
182+
pageSize,
183+
currentPage,
184+
imageTotal,
185+
handleSizeChange,
186+
handleCurrentChange
161187
};
162188
},
163189
template: `
164-
<el-tabs v-model="activeTab" >
165-
<el-tab-pane label="上传文件" name="1">
166-
<div
167-
class="upload-area"
168-
@dragover="handleDragover"
169-
@dragleave="handleDragleave"
170-
@drop="handleDrop">
171-
<p>拖拽文件到此处或点击上传</p>
172-
<el-upload
173-
:multiple="true"
174-
:file-list="fileList"
175-
:http-request="handleUpload"
176-
drag>
177-
<el-button>选择文件</el-button>
178-
</el-upload>
179-
</div>
180-
</el-tab-pane>
181-
<el-tab-pane label="图床" name="2">
182-
<div class="filter-buttons">
183-
<el-select v-model="fileType" @change="handleFilterChange" placeholder="选择类型">
184-
<el-option label="全部" value="all"></el-option>
185-
<el-option label="图片" value="image"></el-option>
186-
<el-option label="视频" value="video"></el-option>
187-
<el-option label="文件" value="file"></el-option>
188-
</el-select>
189-
</div>
190-
<div class="waterfall">
191-
<div class="waterfall-item" v-for="(image, index) in images" :key="index">
192-
<a target="_blank" :href="image.filelocation">
193-
<el-image :src="image.preview" :alt="image.filename" fit="cover" />
194-
</a>
195-
</div>
196-
</div>
197-
</el-tab-pane>
198-
</el-tabs>
199-
`
190+
<el-tabs v-model="activeTab">
191+
<el-tab-pane label="上传文件" name="1">
192+
<div
193+
class="upload-area"
194+
@dragover="handleDragover"
195+
@dragleave="handleDragleave"
196+
@drop="handleDrop">
197+
<p>拖拽文件到此处或点击上传</p>
198+
<el-upload
199+
:multiple="true"
200+
:file-list="fileList"
201+
:http-request="handleUpload"
202+
drag>
203+
<el-button>选择文件</el-button>
204+
</el-upload>
205+
</div>
206+
</el-tab-pane>
207+
<el-tab-pane label="图床" name="2">
208+
<div class="filter-buttons">
209+
<el-select v-model="fileType" @change="handleFilterChange" placeholder="选择类型">
210+
<el-option label="全部" value="all"></el-option>
211+
<el-option label="图片" value="image"></el-option>
212+
<el-option label="视频" value="video"></el-option>
213+
<el-option label="文件" value="file"></el-option>
214+
</el-select>
215+
</div>
216+
<div class="waterfall">
217+
<p class="waterfall-item" v-for="(image, index) in images" :key="index">
218+
<a target="_blank" :href="image.filelocation">
219+
<el-image :src="image.preview" :alt="image.filename" fit="cover" />
220+
</a>
221+
</p>
222+
</div>
223+
<div class="pagination">
224+
<el-pagination
225+
background
226+
layout="total, sizes, prev, pager, next, jumper"
227+
:total="imageTotal"
228+
:page-size="pageSize"
229+
:current-page="currentPage"
230+
@size-change="handleSizeChange"
231+
@current-change="handleCurrentChange">
232+
</el-pagination>
233+
</div>
234+
</el-tab-pane>
235+
</el-tabs>
236+
`
200237
}).mount('#app');
201238
</script>
202239
</body>
203240

204-
</html>
241+
</html>

routers/files.js

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ const tinify = require("tinify");
77
const { Op } = require("sequelize");
88
const { v4: uuidv4 } = require("uuid");
99
const { detectFileType } = require("../utils/detectFileType");
10-
const File = require("../models/files");
10+
const Files = require("../models/files");
1111
const JSZip = require("jszip");
1212
const {
1313
imageMimeTypes,
@@ -86,7 +86,7 @@ router.post("/files", async (ctx) => {
8686
const fileUrl = `${process.env.PUBLIC_NETWORK_DOMAIN}/files/${fileId}/preview`;
8787
const thumbUrl = shouldGenerateThumb ? `${fileUrl}?type=thumb` : null;
8888

89-
await File.create({
89+
await Files.create({
9090
id: fileId,
9191
filename: path.basename(realFilePath),
9292
filesize: (await fsp.stat(realFilePath)).size,
@@ -164,7 +164,7 @@ router.get("/files", async (ctx) => {
164164
};
165165
}
166166

167-
const files = await File.findAll({
167+
const { rows, count } = await Files.findAndCountAll({
168168
where: {
169169
is_delete: false,
170170
is_public: true,
@@ -187,7 +187,10 @@ router.get("/files", async (ctx) => {
187187
],
188188
});
189189

190-
ctx.body = files;
190+
ctx.body = {
191+
items: rows,
192+
total: count,
193+
};
191194
} catch (error) {
192195
ctx.status = 500;
193196
ctx.body = { message: "Error retrieving files", error: error.message };
@@ -200,7 +203,7 @@ router.get("/files/:id", async (ctx) => {
200203
const { id } = ctx.params;
201204

202205
try {
203-
const file = await File.findOne({
206+
const file = await Files.findOne({
204207
where: {
205208
id,
206209
is_delete: false,
@@ -251,7 +254,7 @@ router.get("/files/:id/preview", async (ctx) => {
251254
const { type } = ctx.query; // 获取查询参数 'type',可以是 'thumb' 或 'original'
252255

253256
try {
254-
const file = await File.findOne({
257+
const file = await Files.findOne({
255258
where: {
256259
id,
257260
is_delete: false,
@@ -314,7 +317,7 @@ router.get("/files/:id/export", async (ctx) => {
314317
const { id } = ctx.params;
315318

316319
try {
317-
const file = await File.findOne({
320+
const file = await Files.findOne({
318321
where: {
319322
id: id,
320323
is_delete: false,
@@ -372,7 +375,7 @@ router.get("/files/export", async (ctx) => {
372375
}
373376

374377
try {
375-
const files = await File.findAll({
378+
const files = await Files.findAll({
376379
where: {
377380
id: { [Op.in]: fileIds },
378381
is_delete: false,

0 commit comments

Comments
 (0)