@kne/fastify-file-manager 3.0.3 → 3.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/libs/services/folder.js +52 -9
- package/package.json +1 -1
package/libs/services/folder.js
CHANGED
|
@@ -47,6 +47,44 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
47
47
|
return node ? (typeof node.get === 'function' ? node.get({ plain: true }) : node) : null;
|
|
48
48
|
};
|
|
49
49
|
|
|
50
|
+
/** 重名时在扩展名前加 [_时间戳],如 avatar.png → avatar[_1712345678901].png */
|
|
51
|
+
const withTimestampSuffix = name => {
|
|
52
|
+
const str = String(name || 'file');
|
|
53
|
+
const lastDot = str.lastIndexOf('.');
|
|
54
|
+
const hasExt = lastDot > 0 && lastDot < str.length - 1;
|
|
55
|
+
const base = hasExt ? str.slice(0, lastDot) : str;
|
|
56
|
+
const ext = hasExt ? str.slice(lastDot) : '';
|
|
57
|
+
return `${base}[_${Date.now()}]${ext}`;
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const allocateUniqueSiblingName = async ({ type, parentId, name, language, tenantId, existingNames }) => {
|
|
61
|
+
const taken = async candidate => {
|
|
62
|
+
if (existingNames && existingNames.has(String(candidate))) {
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
const existing = await findChildByName({
|
|
66
|
+
type,
|
|
67
|
+
parentId: parentId || null,
|
|
68
|
+
name: candidate,
|
|
69
|
+
language,
|
|
70
|
+
tenantId
|
|
71
|
+
});
|
|
72
|
+
return !!existing;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
let candidate = String(name || 'file');
|
|
76
|
+
if (!(await taken(candidate))) {
|
|
77
|
+
return candidate;
|
|
78
|
+
}
|
|
79
|
+
for (let i = 0; i < 5; i++) {
|
|
80
|
+
candidate = withTimestampSuffix(name);
|
|
81
|
+
if (!(await taken(candidate))) {
|
|
82
|
+
return candidate;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return withTimestampSuffix(`${name}_${Math.random().toString(36).slice(2, 8)}`);
|
|
86
|
+
};
|
|
87
|
+
|
|
50
88
|
const assertUniqueSiblingName = async ({ type, parentId, name, language, tenantId, excludeId }) => {
|
|
51
89
|
const existing = await findChildByName({ type, parentId: parentId || null, name, language, tenantId });
|
|
52
90
|
if (existing && String(existing.id) !== String(excludeId || '')) {
|
|
@@ -155,7 +193,7 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
155
193
|
}
|
|
156
194
|
|
|
157
195
|
const targetParentId = parentId || null;
|
|
158
|
-
await
|
|
196
|
+
const uniqueName = await allocateUniqueSiblingName({
|
|
159
197
|
type,
|
|
160
198
|
parentId: targetParentId,
|
|
161
199
|
name: file.filename,
|
|
@@ -164,7 +202,7 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
164
202
|
});
|
|
165
203
|
|
|
166
204
|
const record = await services.fileRecord.uploadToFileSystem({
|
|
167
|
-
file,
|
|
205
|
+
file: Object.assign({}, file, { filename: uniqueName }),
|
|
168
206
|
namespace: namespace || fastifyOptions.namespace
|
|
169
207
|
});
|
|
170
208
|
|
|
@@ -496,7 +534,7 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
496
534
|
return null;
|
|
497
535
|
}
|
|
498
536
|
|
|
499
|
-
await
|
|
537
|
+
const uniqueName = await allocateUniqueSiblingName({
|
|
500
538
|
type,
|
|
501
539
|
parentId: targetParentId,
|
|
502
540
|
name: record.filename,
|
|
@@ -506,7 +544,7 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
506
544
|
|
|
507
545
|
const tag = await groupServices.save({
|
|
508
546
|
type,
|
|
509
|
-
name:
|
|
547
|
+
name: uniqueName,
|
|
510
548
|
parentId: targetParentId,
|
|
511
549
|
language,
|
|
512
550
|
tenantId,
|
|
@@ -570,12 +608,17 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
570
608
|
if (existingFileIds.has(linkedFileId) || existingFileIds.has(String(record.id)) || existingFileIds.has(String(fileId))) {
|
|
571
609
|
continue;
|
|
572
610
|
}
|
|
573
|
-
|
|
574
|
-
throw new Error(`同一文件夹下已存在同名文件或文件夹:${record.filename}`);
|
|
575
|
-
}
|
|
576
|
-
const tag = await groupServices.save({
|
|
611
|
+
const uniqueName = await allocateUniqueSiblingName({
|
|
577
612
|
type,
|
|
613
|
+
parentId: targetParentId,
|
|
578
614
|
name: record.filename,
|
|
615
|
+
language,
|
|
616
|
+
tenantId,
|
|
617
|
+
existingNames
|
|
618
|
+
});
|
|
619
|
+
const tag = await groupServices.save({
|
|
620
|
+
type,
|
|
621
|
+
name: uniqueName,
|
|
579
622
|
parentId: targetParentId,
|
|
580
623
|
language,
|
|
581
624
|
tenantId,
|
|
@@ -588,7 +631,7 @@ module.exports = fp(async (fastify, fastifyOptions) => {
|
|
|
588
631
|
}
|
|
589
632
|
});
|
|
590
633
|
existingFileIds.add(linkedFileId);
|
|
591
|
-
existingNames.add(String(
|
|
634
|
+
existingNames.add(String(uniqueName));
|
|
592
635
|
results.push(typeof tag.get === 'function' ? tag.get({ plain: true }) : tag);
|
|
593
636
|
}
|
|
594
637
|
return results;
|