mirror of
https://github.com/crystelf/crystelf-core.git
synced 2025-10-14 05:19:19 +00:00
Compare commits
No commits in common. "baf92f470ade749ed2a390655bbf429cb41f9999" and "d0eb167245ff4f59a06434a37f1e9936b8d293c1" have entirely different histories.
baf92f470a
...
d0eb167245
@ -46,15 +46,15 @@
|
|||||||
"@swc/core": "^1.10.7",
|
"@swc/core": "^1.10.7",
|
||||||
"@types/express": "^5.0.0",
|
"@types/express": "^5.0.0",
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/multer": "^2.0.0",
|
|
||||||
"@types/node": "^22.16.4",
|
"@types/node": "^22.16.4",
|
||||||
"@types/stream-throttle": "^0.1.4",
|
"@types/stream-throttle": "^0.1.4",
|
||||||
"@types/supertest": "^6.0.2",
|
"@types/supertest": "^6.0.2",
|
||||||
"@types/ws": "^8.18.1",
|
"@types/ws": "^8.18.1",
|
||||||
"eslint": "^9.18.0",
|
"eslint": "^9.18.0",
|
||||||
|
"eslint-config-prettier": "^10.0.1",
|
||||||
|
"eslint-plugin-prettier": "^5.2.2",
|
||||||
"globals": "^16.0.0",
|
"globals": "^16.0.0",
|
||||||
"jest": "^29.7.0",
|
"jest": "^29.7.0",
|
||||||
"multer": "^2.0.2",
|
|
||||||
"prettier": "^3.4.2",
|
"prettier": "^3.4.2",
|
||||||
"source-map-support": "^0.5.21",
|
"source-map-support": "^0.5.21",
|
||||||
"supertest": "^7.0.0",
|
"supertest": "^7.0.0",
|
||||||
|
80
pnpm-lock.yaml
generated
80
pnpm-lock.yaml
generated
@ -96,9 +96,6 @@ importers:
|
|||||||
'@types/jest':
|
'@types/jest':
|
||||||
specifier: ^29.5.14
|
specifier: ^29.5.14
|
||||||
version: 29.5.14
|
version: 29.5.14
|
||||||
'@types/multer':
|
|
||||||
specifier: ^2.0.0
|
|
||||||
version: 2.0.0
|
|
||||||
'@types/node':
|
'@types/node':
|
||||||
specifier: ^22.16.4
|
specifier: ^22.16.4
|
||||||
version: 22.16.5
|
version: 22.16.5
|
||||||
@ -114,15 +111,18 @@ importers:
|
|||||||
eslint:
|
eslint:
|
||||||
specifier: ^9.18.0
|
specifier: ^9.18.0
|
||||||
version: 9.31.0
|
version: 9.31.0
|
||||||
|
eslint-config-prettier:
|
||||||
|
specifier: ^10.0.1
|
||||||
|
version: 10.1.8(eslint@9.31.0)
|
||||||
|
eslint-plugin-prettier:
|
||||||
|
specifier: ^5.2.2
|
||||||
|
version: 5.5.3(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.31.0))(eslint@9.31.0)(prettier@3.6.2)
|
||||||
globals:
|
globals:
|
||||||
specifier: ^16.0.0
|
specifier: ^16.0.0
|
||||||
version: 16.3.0
|
version: 16.3.0
|
||||||
jest:
|
jest:
|
||||||
specifier: ^29.7.0
|
specifier: ^29.7.0
|
||||||
version: 29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@swc/core@1.13.1)(@types/node@22.16.5)(typescript@5.8.3))
|
version: 29.7.0(@types/node@22.16.5)(ts-node@10.9.2(@swc/core@1.13.1)(@types/node@22.16.5)(typescript@5.8.3))
|
||||||
multer:
|
|
||||||
specifier: ^2.0.2
|
|
||||||
version: 2.0.2
|
|
||||||
prettier:
|
prettier:
|
||||||
specifier: ^3.4.2
|
specifier: ^3.4.2
|
||||||
version: 3.6.2
|
version: 3.6.2
|
||||||
@ -931,6 +931,10 @@ packages:
|
|||||||
'@paralleldrive/cuid2@2.2.2':
|
'@paralleldrive/cuid2@2.2.2':
|
||||||
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==}
|
||||||
|
|
||||||
|
'@pkgr/core@0.2.9':
|
||||||
|
resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==}
|
||||||
|
engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0}
|
||||||
|
|
||||||
'@scarf/scarf@1.4.0':
|
'@scarf/scarf@1.4.0':
|
||||||
resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==}
|
resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==}
|
||||||
|
|
||||||
@ -1131,9 +1135,6 @@ packages:
|
|||||||
'@types/mime@1.3.5':
|
'@types/mime@1.3.5':
|
||||||
resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
|
resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==}
|
||||||
|
|
||||||
'@types/multer@2.0.0':
|
|
||||||
resolution: {integrity: sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==}
|
|
||||||
|
|
||||||
'@types/node@22.16.5':
|
'@types/node@22.16.5':
|
||||||
resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==}
|
resolution: {integrity: sha512-bJFoMATwIGaxxx8VJPeM8TonI8t579oRvgAuT8zFugJsJZgzqv0Fu8Mhp68iecjzG7cnN3mO2dJQ5uUM2EFrgQ==}
|
||||||
|
|
||||||
@ -1907,6 +1908,26 @@ packages:
|
|||||||
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
||||||
|
eslint-config-prettier@10.1.8:
|
||||||
|
resolution: {integrity: sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
eslint: '>=7.0.0'
|
||||||
|
|
||||||
|
eslint-plugin-prettier@5.5.3:
|
||||||
|
resolution: {integrity: sha512-NAdMYww51ehKfDyDhv59/eIItUVzU0Io9H2E8nHNGKEeeqlnci+1gCvrHib6EmZdf6GxF+LCV5K7UC65Ezvw7w==}
|
||||||
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/eslint': '>=8.0.0'
|
||||||
|
eslint: '>=8.0.0'
|
||||||
|
eslint-config-prettier: '>= 7.0.0 <10.0.0 || >=10.1.0'
|
||||||
|
prettier: '>=3.0.0'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/eslint':
|
||||||
|
optional: true
|
||||||
|
eslint-config-prettier:
|
||||||
|
optional: true
|
||||||
|
|
||||||
eslint-scope@5.1.1:
|
eslint-scope@5.1.1:
|
||||||
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
|
resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==}
|
||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
@ -2005,6 +2026,9 @@ packages:
|
|||||||
fast-deep-equal@3.1.3:
|
fast-deep-equal@3.1.3:
|
||||||
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
|
||||||
|
|
||||||
|
fast-diff@1.3.0:
|
||||||
|
resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==}
|
||||||
|
|
||||||
fast-fifo@1.3.2:
|
fast-fifo@1.3.2:
|
||||||
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
|
resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
|
||||||
|
|
||||||
@ -2975,6 +2999,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==}
|
||||||
engines: {node: '>= 0.8.0'}
|
engines: {node: '>= 0.8.0'}
|
||||||
|
|
||||||
|
prettier-linter-helpers@1.0.0:
|
||||||
|
resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==}
|
||||||
|
engines: {node: '>=6.0.0'}
|
||||||
|
|
||||||
prettier@3.6.2:
|
prettier@3.6.2:
|
||||||
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
resolution: {integrity: sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==}
|
||||||
engines: {node: '>=14'}
|
engines: {node: '>=14'}
|
||||||
@ -3349,6 +3377,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
|
resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==}
|
||||||
engines: {node: '>=0.10'}
|
engines: {node: '>=0.10'}
|
||||||
|
|
||||||
|
synckit@0.11.11:
|
||||||
|
resolution: {integrity: sha512-MeQTA1r0litLUf0Rp/iisCaL8761lKAZHaimlbGK4j0HysC4PLfqygQj9srcs0m2RdtDYnF8UuYyKpbjHYp7Jw==}
|
||||||
|
engines: {node: ^14.18.0 || >=16.0.0}
|
||||||
|
|
||||||
tapable@2.2.2:
|
tapable@2.2.2:
|
||||||
resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==}
|
resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
@ -4599,6 +4631,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.8.0
|
'@noble/hashes': 1.8.0
|
||||||
|
|
||||||
|
'@pkgr/core@0.2.9': {}
|
||||||
|
|
||||||
'@scarf/scarf@1.4.0': {}
|
'@scarf/scarf@1.4.0': {}
|
||||||
|
|
||||||
'@sec-ant/readable-stream@0.4.1': {}
|
'@sec-ant/readable-stream@0.4.1': {}
|
||||||
@ -4796,10 +4830,6 @@ snapshots:
|
|||||||
|
|
||||||
'@types/mime@1.3.5': {}
|
'@types/mime@1.3.5': {}
|
||||||
|
|
||||||
'@types/multer@2.0.0':
|
|
||||||
dependencies:
|
|
||||||
'@types/express': 5.0.3
|
|
||||||
|
|
||||||
'@types/node@22.16.5':
|
'@types/node@22.16.5':
|
||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.21.0
|
undici-types: 6.21.0
|
||||||
@ -5649,6 +5679,20 @@ snapshots:
|
|||||||
|
|
||||||
escape-string-regexp@4.0.0: {}
|
escape-string-regexp@4.0.0: {}
|
||||||
|
|
||||||
|
eslint-config-prettier@10.1.8(eslint@9.31.0):
|
||||||
|
dependencies:
|
||||||
|
eslint: 9.31.0
|
||||||
|
|
||||||
|
eslint-plugin-prettier@5.5.3(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.31.0))(eslint@9.31.0)(prettier@3.6.2):
|
||||||
|
dependencies:
|
||||||
|
eslint: 9.31.0
|
||||||
|
prettier: 3.6.2
|
||||||
|
prettier-linter-helpers: 1.0.0
|
||||||
|
synckit: 0.11.11
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/eslint': 9.6.1
|
||||||
|
eslint-config-prettier: 10.1.8(eslint@9.31.0)
|
||||||
|
|
||||||
eslint-scope@5.1.1:
|
eslint-scope@5.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
esrecurse: 4.3.0
|
esrecurse: 4.3.0
|
||||||
@ -5812,6 +5856,8 @@ snapshots:
|
|||||||
|
|
||||||
fast-deep-equal@3.1.3: {}
|
fast-deep-equal@3.1.3: {}
|
||||||
|
|
||||||
|
fast-diff@1.3.0: {}
|
||||||
|
|
||||||
fast-fifo@1.3.2: {}
|
fast-fifo@1.3.2: {}
|
||||||
|
|
||||||
fast-glob@3.3.3:
|
fast-glob@3.3.3:
|
||||||
@ -6901,6 +6947,10 @@ snapshots:
|
|||||||
|
|
||||||
prelude-ls@1.2.1: {}
|
prelude-ls@1.2.1: {}
|
||||||
|
|
||||||
|
prettier-linter-helpers@1.0.0:
|
||||||
|
dependencies:
|
||||||
|
fast-diff: 1.3.0
|
||||||
|
|
||||||
prettier@3.6.2: {}
|
prettier@3.6.2: {}
|
||||||
|
|
||||||
pretty-format@29.7.0:
|
pretty-format@29.7.0:
|
||||||
@ -7314,6 +7364,10 @@ snapshots:
|
|||||||
|
|
||||||
symbol-observable@4.0.0: {}
|
symbol-observable@4.0.0: {}
|
||||||
|
|
||||||
|
synckit@0.11.11:
|
||||||
|
dependencies:
|
||||||
|
'@pkgr/core': 0.2.9
|
||||||
|
|
||||||
tapable@2.2.2: {}
|
tapable@2.2.2: {}
|
||||||
|
|
||||||
tar-stream@3.1.7:
|
tar-stream@3.1.7:
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||||
import { AppConfigService } from '../../config/config.service';
|
import { AppConfigService } from '../../config/config.service';
|
||||||
import { FileInfo, FileUpload, FsList } from './openlist.types';
|
import { FileInfo, FsList } from './openlist.types';
|
||||||
import { OpenListUtils } from './openlist.utils';
|
import { OpenListUtils } from './openlist.utils';
|
||||||
import * as moment from 'moment';
|
import * as moment from 'moment';
|
||||||
|
|
||||||
@ -148,18 +148,13 @@ export class OpenListService {
|
|||||||
filePath: string,
|
filePath: string,
|
||||||
file: any,
|
file: any,
|
||||||
filePathOnserver: string,
|
filePathOnserver: string,
|
||||||
): Promise<FileUpload> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const token = await this.fetchToken(
|
const token = await this.fetchToken(
|
||||||
<string>this.configService.get('OPENLIST_API_BASE_USERNAME'),
|
<string>this.configService.get('OPENLIST_API_BASE_USERNAME'),
|
||||||
<string>this.configService.get('OPENLIST_API_BASE_PASSWORD'),
|
<string>this.configService.get('OPENLIST_API_BASE_PASSWORD'),
|
||||||
);
|
);
|
||||||
return await OpenListUtils.uploadFile(
|
await OpenListUtils.uploadFile(token, filePath, filePathOnserver, file);
|
||||||
token,
|
|
||||||
filePath,
|
|
||||||
filePathOnserver,
|
|
||||||
file,
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('上传文件失败:', error);
|
this.logger.error('上传文件失败:', error);
|
||||||
throw new Error('上传文件失败');
|
throw new Error('上传文件失败');
|
||||||
|
@ -162,13 +162,10 @@ export class OpenListUtils {
|
|||||||
file: fs.ReadStream,
|
file: fs.ReadStream,
|
||||||
): Promise<FileUpload> {
|
): Promise<FileUpload> {
|
||||||
const url = `${this.apiBaseUrl}/api/fs/put`;
|
const url = `${this.apiBaseUrl}/api/fs/put`;
|
||||||
const stats = fs.statSync(filePath);
|
|
||||||
const fileSize = stats.size;
|
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
Authorization: `${token}`,
|
Authorization: `${token}`,
|
||||||
'Content-Type': 'application/octet-stream',
|
'Content-Type': 'application/octet-stream',
|
||||||
'Content-Length': fileSize,
|
'Content-Length': file.bytesRead,
|
||||||
'File-Path': encodeURIComponent(filePathOnServer),
|
'File-Path': encodeURIComponent(filePathOnServer),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -177,17 +174,14 @@ export class OpenListUtils {
|
|||||||
headers,
|
headers,
|
||||||
params: {
|
params: {
|
||||||
path: filePath,
|
path: filePath,
|
||||||
'As-Task': 'true',
|
'As-Task': 'true', //作为任务
|
||||||
},
|
},
|
||||||
maxBodyLength: Infinity,
|
|
||||||
maxContentLength: Infinity,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.logger.log(`文件上传成功: ${filePathOnServer}`);
|
this.logger.log(`文件上传成功: ${filePathOnServer}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('上传文件失败..', error);
|
this.logger.error('上传文件失败..', error);
|
||||||
throw new Error(`上传文件失败: ${error.message || error}`);
|
throw new Error('上传文件失败..');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,18 +10,8 @@ import {
|
|||||||
Logger,
|
Logger,
|
||||||
Inject,
|
Inject,
|
||||||
Ip,
|
Ip,
|
||||||
UseInterceptors,
|
|
||||||
UploadedFile,
|
|
||||||
UseGuards,
|
|
||||||
} from '@nestjs/common';
|
} from '@nestjs/common';
|
||||||
import {
|
import { ApiTags, ApiOperation, ApiBody, ApiQuery } from '@nestjs/swagger';
|
||||||
ApiTags,
|
|
||||||
ApiOperation,
|
|
||||||
ApiBody,
|
|
||||||
ApiQuery,
|
|
||||||
ApiConsumes,
|
|
||||||
ApiHeader,
|
|
||||||
} from '@nestjs/swagger';
|
|
||||||
import { MemeService } from './meme.service';
|
import { MemeService } from './meme.service';
|
||||||
import { Response } from 'express';
|
import { Response } from 'express';
|
||||||
import * as fs from 'fs';
|
import * as fs from 'fs';
|
||||||
@ -29,12 +19,6 @@ import { Throttle } from 'stream-throttle';
|
|||||||
import { ToolsService } from '../../core/tools/tools.service';
|
import { ToolsService } from '../../core/tools/tools.service';
|
||||||
import { RedisService } from '../../core/redis/redis.service';
|
import { RedisService } from '../../core/redis/redis.service';
|
||||||
import imageType from 'image-type';
|
import imageType from 'image-type';
|
||||||
import { FileInterceptor } from '@nestjs/platform-express';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { OpenListService } from '../../core/openlist/openlist.service';
|
|
||||||
import { PathService } from '../../core/path/path.service';
|
|
||||||
import { TokenAuthGuard } from '../../core/tools/token-auth.guard';
|
|
||||||
import { AppConfigService } from '../../config/config.service';
|
|
||||||
|
|
||||||
class MemeRequestDto {
|
class MemeRequestDto {
|
||||||
character?: string;
|
character?: string;
|
||||||
@ -54,12 +38,6 @@ export class MemeController {
|
|||||||
private readonly toolsService: ToolsService,
|
private readonly toolsService: ToolsService,
|
||||||
@Inject(RedisService)
|
@Inject(RedisService)
|
||||||
private readonly redisService: RedisService,
|
private readonly redisService: RedisService,
|
||||||
@Inject(OpenListService)
|
|
||||||
private readonly openListService: OpenListService,
|
|
||||||
@Inject(PathService)
|
|
||||||
private readonly pathService: PathService,
|
|
||||||
@Inject(AppConfigService)
|
|
||||||
private readonly configService: AppConfigService,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Post('get')
|
@Post('get')
|
||||||
@ -180,102 +158,4 @@ export class MemeController {
|
|||||||
throw new HttpException('服务器错误', HttpStatus.INTERNAL_SERVER_ERROR);
|
throw new HttpException('服务器错误', HttpStatus.INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 上传文件
|
|
||||||
* @param file
|
|
||||||
* @param character
|
|
||||||
* @param status
|
|
||||||
* @param res
|
|
||||||
*/
|
|
||||||
@Post('upload')
|
|
||||||
@ApiOperation({ summary: '上传表情包并同步' })
|
|
||||||
@ApiConsumes('multipart/form-data')
|
|
||||||
@UseInterceptors(FileInterceptor('file'))
|
|
||||||
@ApiHeader({ name: 'x-token', description: '身份验证token', required: true })
|
|
||||||
@UseGuards(TokenAuthGuard)
|
|
||||||
@ApiBody({
|
|
||||||
description: '上传表情包文件',
|
|
||||||
schema: {
|
|
||||||
type: 'object',
|
|
||||||
properties: {
|
|
||||||
file: { type: 'string', format: 'binary' },
|
|
||||||
character: { type: 'string', description: '角色名称' },
|
|
||||||
status: { type: 'string', description: '状态' },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
public async uploadMeme(
|
|
||||||
@UploadedFile() file: Express.Multer.File,
|
|
||||||
@Body('character') character: string,
|
|
||||||
@Body('status') status: string,
|
|
||||||
) {
|
|
||||||
if (!file) {
|
|
||||||
throw new HttpException('未检测到上传文件', HttpStatus.BAD_REQUEST);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
const fsp = fs.promises;
|
|
||||||
const safeCharacter = character?.trim() || 'unknown';
|
|
||||||
const safeStatus = status?.trim() || 'default';
|
|
||||||
|
|
||||||
const memeBasePath = this.pathService.get('meme');
|
|
||||||
const localDir = path.join(memeBasePath, safeCharacter, safeStatus);
|
|
||||||
await fsp.mkdir(localDir, { recursive: true });
|
|
||||||
|
|
||||||
const buffer = file.buffer || (await fsp.readFile(file.path));
|
|
||||||
const imgType = await imageType(buffer);
|
|
||||||
if (!imgType || !['jpg', 'png', 'gif', 'webp'].includes(imgType.ext)) {
|
|
||||||
throw new HttpException(
|
|
||||||
'不支持的图片格式',
|
|
||||||
HttpStatus.UNSUPPORTED_MEDIA_TYPE,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const remoteMemePath = this.configService.get('OPENLIST_API_MEME_PATH');
|
|
||||||
const remoteDir = `${remoteMemePath}/${safeCharacter}/${safeStatus}/`;
|
|
||||||
let fileList: string[] = [];
|
|
||||||
|
|
||||||
try {
|
|
||||||
const listResult = await this.openListService.listFiles(remoteDir);
|
|
||||||
if (
|
|
||||||
listResult?.code === 200 &&
|
|
||||||
Array.isArray(listResult.data?.content)
|
|
||||||
) {
|
|
||||||
fileList = listResult.data.content.map((f) => f.name);
|
|
||||||
} else {
|
|
||||||
this.logger.warn(`目录为空或返回结构异常:${remoteDir}`);
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
this.logger.warn(`获取远程目录失败(${remoteDir}),将自动创建`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const usedNumbers = fileList
|
|
||||||
.map((name) => {
|
|
||||||
const match = name.match(/^(\d+)\./);
|
|
||||||
return match ? parseInt(match[1], 10) : null;
|
|
||||||
})
|
|
||||||
.filter((n) => n !== null) as number[];
|
|
||||||
|
|
||||||
const nextNumber =
|
|
||||||
usedNumbers.length > 0 ? Math.max(...usedNumbers) + 1 : 1;
|
|
||||||
const remoteFilename = `${nextNumber}.${imgType.ext}`;
|
|
||||||
const remoteFilePath = `${remoteDir}${remoteFilename}`;
|
|
||||||
const localFilePath = path.join(localDir, remoteFilename);
|
|
||||||
await fsp.writeFile(localFilePath, buffer);
|
|
||||||
const fileStream = fs.createReadStream(localFilePath);
|
|
||||||
await this.openListService.uploadFile(
|
|
||||||
localFilePath,
|
|
||||||
fileStream,
|
|
||||||
remoteFilePath,
|
|
||||||
);
|
|
||||||
this.logger.log(`表情包上传成功: ${remoteFilePath}`);
|
|
||||||
return '表情上传成功..';
|
|
||||||
} catch (error) {
|
|
||||||
this.logger.error('表情包上传失败:', error);
|
|
||||||
throw new HttpException(
|
|
||||||
`上传失败: ${error.message || error}`,
|
|
||||||
HttpStatus.INTERNAL_SERVER_ERROR,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@ import { FilesModule } from '../../core/files/files.module';
|
|||||||
RedisModule,
|
RedisModule,
|
||||||
AppConfigModule,
|
AppConfigModule,
|
||||||
FilesModule,
|
FilesModule,
|
||||||
PathModule,
|
|
||||||
],
|
],
|
||||||
providers: [MemeService],
|
providers: [MemeService],
|
||||||
controllers: [MemeController],
|
controllers: [MemeController],
|
||||||
|
Loading…
x
Reference in New Issue
Block a user