feat(c1): MinIO 存储模块
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f3c775cea9
commit
465057cce0
@ -29,3 +29,10 @@ REDIS_PORT="6379"
|
||||
REDIS_DB="0"
|
||||
REDIS_PASSWORD=""
|
||||
REDIS_KEY_PREFIX="sysmgr:"
|
||||
|
||||
# MinIO(对象存储,供 elder 模块上传评估结论副本)
|
||||
MINIO_ENDPOINT="localhost"
|
||||
MINIO_PORT=9000
|
||||
MINIO_ACCESS_KEY="minioadmin"
|
||||
MINIO_SECRET_KEY="minioadmin"
|
||||
MINIO_BUCKET="carelink"
|
||||
|
||||
@ -43,6 +43,7 @@
|
||||
"class-validator": "^0.15.1",
|
||||
"helmet": "^8.3.0",
|
||||
"ioredis": "^6.0.0",
|
||||
"minio": "^8.0.7",
|
||||
"nestjs-pino": "^5.3.1",
|
||||
"pino": "^10.4.0",
|
||||
"pino-pretty": "^13.2.0",
|
||||
|
||||
214
pnpm-lock.yaml
generated
214
pnpm-lock.yaml
generated
@ -205,6 +205,9 @@ importers:
|
||||
ioredis:
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0(supports-color@7.2.0)
|
||||
minio:
|
||||
specifier: ^8.0.7
|
||||
version: 8.0.7
|
||||
nestjs-pino:
|
||||
specifier: ^5.3.1
|
||||
version: 5.3.1(@nestjs/common@12.1.2(class-transformer@0.5.1)(class-validator@0.15.1)(reflect-metadata@0.2.2)(rxjs@7.8.2)(supports-color@7.2.0))(@nestjs/core@12.1.2)(pino-http@11.0.0)(pino@10.4.0)(rxjs@7.8.2)
|
||||
@ -790,6 +793,9 @@ packages:
|
||||
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
|
||||
engines: {node: ^14.21.3 || >=16}
|
||||
|
||||
'@nodable/entities@3.1.0':
|
||||
resolution: {integrity: sha512-LsS/DjHr+uDM647Gru/cA8+J3a3HfhttwCKLyuoyN7yXTFCxKBtSgMQBvrW9yNPa2/zDRUNuGPaH5QUFoa4arQ==}
|
||||
|
||||
'@oxc-project/types@0.153.0':
|
||||
resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==}
|
||||
|
||||
@ -1224,6 +1230,9 @@ packages:
|
||||
resolution: {integrity: sha512-9k3v7xcHwgdO/DruxGIg4HtjvlAZlcnsX/mzqUb1t3NkYnl9kK2UJ+Gq0io+vQf7iT//BD/HB/NBkUR1LWxoeA==}
|
||||
engines: {node: '>=14'}
|
||||
|
||||
anynum@1.0.1:
|
||||
resolution: {integrity: sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==}
|
||||
|
||||
append-field@1.0.0:
|
||||
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
|
||||
|
||||
@ -1243,6 +1252,9 @@ packages:
|
||||
ast-v8-to-istanbul@1.0.7:
|
||||
resolution: {integrity: sha512-kFL68AG6ajd8fg248zwM9GQrUWEp79gsmjum34OEXjs4yHuUMZfYKwOLW9GMmB4oNvVrj+EAGxsP7ye2UR9UlA==}
|
||||
|
||||
async@3.2.6:
|
||||
resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==}
|
||||
|
||||
asynckit@0.4.0:
|
||||
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
|
||||
|
||||
@ -1258,6 +1270,9 @@ packages:
|
||||
resolution: {integrity: sha512-GlF5wPWnSa/X5LKM1o0wz0suXIINz1iHRLvTS+sLyi7XPbe5ycmYI3DlZqVGZZtDgl4DmasFg7gOB3JYbphV5g==}
|
||||
hasBin: true
|
||||
|
||||
block-stream2@2.1.0:
|
||||
resolution: {integrity: sha512-suhjmLI57Ewpmq00qaygS8UgEq2ly2PCItenIyhMqVjo4t4pGzqMvfgJuX8iWTeSDdfSSqS6j38fL4ToNL7Pfg==}
|
||||
|
||||
body-parser@2.3.0:
|
||||
resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==}
|
||||
engines: {node: '>=18'}
|
||||
@ -1266,6 +1281,13 @@ packages:
|
||||
resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==}
|
||||
engines: {node: 20 || >=22}
|
||||
|
||||
browser-or-node@2.1.1:
|
||||
resolution: {integrity: sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==}
|
||||
|
||||
buffer-crc32@1.0.0:
|
||||
resolution: {integrity: sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
|
||||
@ -1428,6 +1450,10 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decode-uri-component@0.2.2:
|
||||
resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==}
|
||||
engines: {node: '>=0.10'}
|
||||
|
||||
deepmerge-ts@7.1.5:
|
||||
resolution: {integrity: sha512-HOJkrhaYsweh+W+e74Yn7YStZOilkoPb6fycpwNLKzSPtruFs48nYis0zy5yJz1+ktUhHxoRDJ27RQAWLIJVJw==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
@ -1538,6 +1564,9 @@ packages:
|
||||
resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
|
||||
eventemitter3@5.0.4:
|
||||
resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==}
|
||||
|
||||
expect-type@1.4.0:
|
||||
resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@ -1574,6 +1603,13 @@ packages:
|
||||
fast-wrap-ansi@0.2.2:
|
||||
resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==}
|
||||
|
||||
fast-xml-builder@1.3.1:
|
||||
resolution: {integrity: sha512-pIM/1n3ntFXKYrUZwW7QCK0gAW7XY+wzj1YMIV3tLDvPj/V+zTGJK5e3/4WJfwj0qWw2ElNXiTixda/R+3YSug==}
|
||||
|
||||
fast-xml-parser@5.11.2:
|
||||
resolution: {integrity: sha512-R9iDuNrQYeQut46cn2r2wHKn4HYzVDvDm5J1wW+koZewykv0yuO2HChTYeZtrULyHIDM9cj9TUXloCsueCQUog==}
|
||||
hasBin: true
|
||||
|
||||
fdir@6.5.0:
|
||||
resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
@ -1587,6 +1623,10 @@ packages:
|
||||
resolution: {integrity: sha512-sEB0oStmeLGtpmSAD88RDNuLsvhv4iC3u0lE25CUvfCULvj49xoQ3l3K525Vn+ZzsZ6DOLajQCV6RmhwwhqiJg==}
|
||||
engines: {node: '>=22'}
|
||||
|
||||
filter-obj@1.1.0:
|
||||
resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
finalhandler@2.1.1:
|
||||
resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==}
|
||||
engines: {node: '>= 18.0.0'}
|
||||
@ -1690,6 +1730,10 @@ packages:
|
||||
resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==}
|
||||
engines: {node: '>= 0.10'}
|
||||
|
||||
ipaddr.js@2.5.0:
|
||||
resolution: {integrity: sha512-aq+t5NAc+cS6rZQQVWC2x98CPqGtKKTMDd4Gaodv0wShnItdKg/51djkGJ1hqH+Oy0ivDftCbSLCQob8zso01w==}
|
||||
engines: {node: '>= 10'}
|
||||
|
||||
is-fullwidth-code-point@3.0.0:
|
||||
resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1705,6 +1749,9 @@ packages:
|
||||
resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
is-unsafe@2.0.2:
|
||||
resolution: {integrity: sha512-HgbIHPBH0KHHCcjLfGsCvhtPTVxjaAZlXjwdz7/GQC40SjSe4sfQsar8J5VFo8JOSbarkpV0OLG95bbaNd9aAQ==}
|
||||
|
||||
istanbul-lib-coverage@3.2.2:
|
||||
resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==}
|
||||
engines: {node: '>=8'}
|
||||
@ -1859,6 +1906,9 @@ packages:
|
||||
lodash.once@4.1.1:
|
||||
resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==}
|
||||
|
||||
lodash@4.18.1:
|
||||
resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==}
|
||||
|
||||
log-symbols@7.0.1:
|
||||
resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==}
|
||||
engines: {node: '>=18'}
|
||||
@ -1932,6 +1982,10 @@ packages:
|
||||
minimist@1.2.8:
|
||||
resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
|
||||
|
||||
minio@8.0.7:
|
||||
resolution: {integrity: sha512-E737MgufW8CeQAsTAtnEMrxZ9scMSf29kkhZoXzDTKj/Jszzo2SfeZUH9wbDQH2Rsq6TCtl/yQL0+XdVKZansQ==}
|
||||
engines: {node: ^16 || ^18 || >=20}
|
||||
|
||||
ms@2.1.3:
|
||||
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
|
||||
|
||||
@ -2029,6 +2083,10 @@ packages:
|
||||
resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
path-expression-matcher@1.6.2:
|
||||
resolution: {integrity: sha512-enSlaiat05iasnzmgNxRj8reFdj3puY2QpNgP1aPIaVfT6nn9ICuPoFlKHk8EN22HcwewshO+mN2DGbkCEOtqQ==}
|
||||
engines: {node: '>=14.0.0'}
|
||||
|
||||
path-to-regexp@8.4.2:
|
||||
resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==}
|
||||
|
||||
@ -2108,6 +2166,10 @@ packages:
|
||||
resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==}
|
||||
engines: {node: '>=0.6'}
|
||||
|
||||
query-string@7.1.3:
|
||||
resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
quick-format-unescaped@4.0.4:
|
||||
resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==}
|
||||
|
||||
@ -2122,6 +2184,10 @@ packages:
|
||||
rc9@2.1.2:
|
||||
resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
|
||||
|
||||
readable-stream@3.6.2:
|
||||
resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
|
||||
engines: {node: '>= 6'}
|
||||
|
||||
readdirp@4.1.2:
|
||||
resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==}
|
||||
engines: {node: '>= 14.18.0'}
|
||||
@ -2170,6 +2236,10 @@ packages:
|
||||
safer-buffer@2.1.2:
|
||||
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
|
||||
|
||||
sax@1.6.1:
|
||||
resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==}
|
||||
engines: {node: '>=11.0.0'}
|
||||
|
||||
secure-json-parse@4.1.0:
|
||||
resolution: {integrity: sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==}
|
||||
|
||||
@ -2237,6 +2307,10 @@ packages:
|
||||
resolution: {integrity: sha512-d8EqvL+k/SOXCreS/SUzg2ciyHqBBLcN/yuRjFsbvVhHTE2pgei7oAhmPM7kWFbkX6OSMQfUq4KbkF3au9lhYQ==}
|
||||
engines: {node: '>= 12'}
|
||||
|
||||
split-on-first@1.1.0:
|
||||
resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==}
|
||||
engines: {node: '>=6'}
|
||||
|
||||
split2@4.2.0:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
@ -2258,10 +2332,20 @@ packages:
|
||||
resolution: {integrity: sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
stream-chain@2.2.5:
|
||||
resolution: {integrity: sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA==}
|
||||
|
||||
stream-json@1.9.1:
|
||||
resolution: {integrity: sha512-uWkjJ+2Nt/LO9Z/JyKZbMusL8Dkh97uUBTv3AJQ74y07lVahLY4eEFsPsE97pxYBwr8nnjMAIch5eqI0gPShyw==}
|
||||
|
||||
streamsearch@1.1.0:
|
||||
resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
|
||||
strict-uri-encode@2.0.0:
|
||||
resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
string-width@4.2.3:
|
||||
resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
|
||||
engines: {node: '>=8'}
|
||||
@ -2270,6 +2354,9 @@ packages:
|
||||
resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
string_decoder@1.3.0:
|
||||
resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
|
||||
engines: {node: '>=8'}
|
||||
@ -2286,6 +2373,9 @@ packages:
|
||||
resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==}
|
||||
engines: {node: '>=14.16'}
|
||||
|
||||
strnum@2.5.1:
|
||||
resolution: {integrity: sha512-UM4nTLWzQiDBseVxUGxN0wJzIk0UU89Qi7pKXz9qISo+lhviJikTuikBsK/oFRlpvYHvSdz0TVoLyQ+sEpYwxA==}
|
||||
|
||||
strtok3@10.3.5:
|
||||
resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==}
|
||||
engines: {node: '>=18'}
|
||||
@ -2309,6 +2399,9 @@ packages:
|
||||
resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
through2@4.0.2:
|
||||
resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==}
|
||||
|
||||
tinybench@2.9.0:
|
||||
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
|
||||
|
||||
@ -2386,6 +2479,9 @@ packages:
|
||||
resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
||||
util-deprecate@1.0.2:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
validator@13.15.35:
|
||||
resolution: {integrity: sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==}
|
||||
engines: {node: '>= 0.10'}
|
||||
@ -2494,6 +2590,18 @@ packages:
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
xml-naming@0.3.0:
|
||||
resolution: {integrity: sha512-ghig2TBE/H11aOVgmahA3MhimvkBr6JIYknH/Dhdk10nXwdbIqBJsbfMxpvFPG8bAw77gN29aQWvKpmVoPlvPQ==}
|
||||
engines: {node: '>=16.0.0'}
|
||||
|
||||
xml2js@0.6.2:
|
||||
resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
xmlbuilder@11.0.1:
|
||||
resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==}
|
||||
engines: {node: '>=4.0'}
|
||||
|
||||
yaml@2.9.1:
|
||||
resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==}
|
||||
engines: {node: '>= 14.6'}
|
||||
@ -2895,6 +3003,8 @@ snapshots:
|
||||
|
||||
'@noble/hashes@1.8.0': {}
|
||||
|
||||
'@nodable/entities@3.1.0': {}
|
||||
|
||||
'@oxc-project/types@0.153.0': {}
|
||||
|
||||
'@oxlint-tsgolint/darwin-arm64@7.0.2003':
|
||||
@ -3233,6 +3343,8 @@ snapshots:
|
||||
|
||||
ansis@4.4.0: {}
|
||||
|
||||
anynum@1.0.1: {}
|
||||
|
||||
append-field@1.0.0: {}
|
||||
|
||||
argparse@2.0.1: {}
|
||||
@ -3249,6 +3361,8 @@ snapshots:
|
||||
estree-walker: 3.0.3
|
||||
js-tokens: 10.0.0
|
||||
|
||||
async@3.2.6: {}
|
||||
|
||||
asynckit@0.4.0: {}
|
||||
|
||||
atomic-sleep@1.0.0: {}
|
||||
@ -3257,6 +3371,10 @@ snapshots:
|
||||
|
||||
bcryptjs@3.0.3: {}
|
||||
|
||||
block-stream2@2.1.0:
|
||||
dependencies:
|
||||
readable-stream: 3.6.2
|
||||
|
||||
body-parser@2.3.0(supports-color@7.2.0):
|
||||
dependencies:
|
||||
bytes: 3.1.2
|
||||
@ -3275,6 +3393,10 @@ snapshots:
|
||||
dependencies:
|
||||
balanced-match: 4.0.4
|
||||
|
||||
browser-or-node@2.1.1: {}
|
||||
|
||||
buffer-crc32@1.0.0: {}
|
||||
|
||||
buffer-equal-constant-time@1.0.1: {}
|
||||
|
||||
buffer-from@1.1.2: {}
|
||||
@ -3411,6 +3533,8 @@ snapshots:
|
||||
optionalDependencies:
|
||||
supports-color: 7.2.0
|
||||
|
||||
decode-uri-component@0.2.2: {}
|
||||
|
||||
deepmerge-ts@7.1.5: {}
|
||||
|
||||
defu@6.1.7: {}
|
||||
@ -3521,6 +3645,8 @@ snapshots:
|
||||
|
||||
etag@1.8.1: {}
|
||||
|
||||
eventemitter3@5.0.4: {}
|
||||
|
||||
expect-type@1.4.0: {}
|
||||
|
||||
express@5.2.1(supports-color@7.2.0):
|
||||
@ -3580,6 +3706,20 @@ snapshots:
|
||||
dependencies:
|
||||
fast-string-width: 3.0.2
|
||||
|
||||
fast-xml-builder@1.3.1:
|
||||
dependencies:
|
||||
path-expression-matcher: 1.6.2
|
||||
xml-naming: 0.3.0
|
||||
|
||||
fast-xml-parser@5.11.2:
|
||||
dependencies:
|
||||
'@nodable/entities': 3.1.0
|
||||
fast-xml-builder: 1.3.1
|
||||
is-unsafe: 2.0.2
|
||||
path-expression-matcher: 1.6.2
|
||||
strnum: 2.5.1
|
||||
xml-naming: 0.3.0
|
||||
|
||||
fdir@6.5.0(picomatch@4.0.7):
|
||||
optionalDependencies:
|
||||
picomatch: 4.0.7
|
||||
@ -3593,6 +3733,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
filter-obj@1.1.0: {}
|
||||
|
||||
finalhandler@2.1.1(supports-color@7.2.0):
|
||||
dependencies:
|
||||
debug: 4.4.3(supports-color@7.2.0)
|
||||
@ -3709,6 +3851,8 @@ snapshots:
|
||||
|
||||
ipaddr.js@1.9.1: {}
|
||||
|
||||
ipaddr.js@2.5.0: {}
|
||||
|
||||
is-fullwidth-code-point@3.0.0: {}
|
||||
|
||||
is-interactive@2.0.0: {}
|
||||
@ -3717,6 +3861,8 @@ snapshots:
|
||||
|
||||
is-unicode-supported@2.1.0: {}
|
||||
|
||||
is-unsafe@2.0.2: {}
|
||||
|
||||
istanbul-lib-coverage@3.2.2: {}
|
||||
|
||||
istanbul-lib-report@3.0.1:
|
||||
@ -3839,6 +3985,8 @@ snapshots:
|
||||
|
||||
lodash.once@4.1.1: {}
|
||||
|
||||
lodash@4.18.1: {}
|
||||
|
||||
log-symbols@7.0.1:
|
||||
dependencies:
|
||||
is-unicode-supported: 2.1.0
|
||||
@ -3896,6 +4044,22 @@ snapshots:
|
||||
|
||||
minimist@1.2.8: {}
|
||||
|
||||
minio@8.0.7:
|
||||
dependencies:
|
||||
async: 3.2.6
|
||||
block-stream2: 2.1.0
|
||||
browser-or-node: 2.1.1
|
||||
buffer-crc32: 1.0.0
|
||||
eventemitter3: 5.0.4
|
||||
fast-xml-parser: 5.11.2
|
||||
ipaddr.js: 2.5.0
|
||||
lodash: 4.18.1
|
||||
mime-types: 2.1.35
|
||||
query-string: 7.1.3
|
||||
stream-json: 1.9.1
|
||||
through2: 4.0.2
|
||||
xml2js: 0.6.2
|
||||
|
||||
ms@2.1.3: {}
|
||||
|
||||
multer@2.4.0:
|
||||
@ -4002,6 +4166,8 @@ snapshots:
|
||||
|
||||
parseurl@1.3.3: {}
|
||||
|
||||
path-expression-matcher@1.6.2: {}
|
||||
|
||||
path-to-regexp@8.4.2: {}
|
||||
|
||||
pathe@2.0.3: {}
|
||||
@ -4104,6 +4270,13 @@ snapshots:
|
||||
es-define-property: 1.0.1
|
||||
side-channel: 1.1.1
|
||||
|
||||
query-string@7.1.3:
|
||||
dependencies:
|
||||
decode-uri-component: 0.2.2
|
||||
filter-obj: 1.1.0
|
||||
split-on-first: 1.1.0
|
||||
strict-uri-encode: 2.0.0
|
||||
|
||||
quick-format-unescaped@4.0.4: {}
|
||||
|
||||
range-parser@1.3.0: {}
|
||||
@ -4120,6 +4293,12 @@ snapshots:
|
||||
defu: 6.1.7
|
||||
destr: 2.0.5
|
||||
|
||||
readable-stream@3.6.2:
|
||||
dependencies:
|
||||
inherits: 2.0.4
|
||||
string_decoder: 1.3.0
|
||||
util-deprecate: 1.0.2
|
||||
|
||||
readdirp@4.1.2: {}
|
||||
|
||||
readdirp@5.1.1: {}
|
||||
@ -4178,6 +4357,8 @@ snapshots:
|
||||
|
||||
safer-buffer@2.1.2: {}
|
||||
|
||||
sax@1.6.1: {}
|
||||
|
||||
secure-json-parse@4.1.0: {}
|
||||
|
||||
semver@7.8.5: {}
|
||||
@ -4264,6 +4445,8 @@ snapshots:
|
||||
|
||||
source-map@0.8.0: {}
|
||||
|
||||
split-on-first@1.1.0: {}
|
||||
|
||||
split2@4.2.0: {}
|
||||
|
||||
stackback@0.0.2: {}
|
||||
@ -4276,8 +4459,16 @@ snapshots:
|
||||
|
||||
stdin-discarder@0.3.2: {}
|
||||
|
||||
stream-chain@2.2.5: {}
|
||||
|
||||
stream-json@1.9.1:
|
||||
dependencies:
|
||||
stream-chain: 2.2.5
|
||||
|
||||
streamsearch@1.1.0: {}
|
||||
|
||||
strict-uri-encode@2.0.0: {}
|
||||
|
||||
string-width@4.2.3:
|
||||
dependencies:
|
||||
emoji-regex: 8.0.0
|
||||
@ -4289,6 +4480,10 @@ snapshots:
|
||||
get-east-asian-width: 1.7.0
|
||||
strip-ansi: 7.2.0
|
||||
|
||||
string_decoder@1.3.0:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
|
||||
strip-ansi@6.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 5.0.1
|
||||
@ -4301,6 +4496,10 @@ snapshots:
|
||||
|
||||
strip-json-comments@5.0.3: {}
|
||||
|
||||
strnum@2.5.1:
|
||||
dependencies:
|
||||
anynum: 1.0.1
|
||||
|
||||
strtok3@10.3.5:
|
||||
dependencies:
|
||||
'@tokenizer/token': 0.3.0
|
||||
@ -4339,6 +4538,10 @@ snapshots:
|
||||
dependencies:
|
||||
real-require: 1.0.0
|
||||
|
||||
through2@4.0.2:
|
||||
dependencies:
|
||||
readable-stream: 3.6.2
|
||||
|
||||
tinybench@2.9.0: {}
|
||||
|
||||
tinyexec@1.3.1: {}
|
||||
@ -4401,6 +4604,8 @@ snapshots:
|
||||
|
||||
unpipe@1.0.0: {}
|
||||
|
||||
util-deprecate@1.0.2: {}
|
||||
|
||||
validator@13.15.35: {}
|
||||
|
||||
vary@1.1.2: {}
|
||||
@ -4466,6 +4671,15 @@ snapshots:
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
xml-naming@0.3.0: {}
|
||||
|
||||
xml2js@0.6.2:
|
||||
dependencies:
|
||||
sax: 1.6.1
|
||||
xmlbuilder: 11.0.1
|
||||
|
||||
xmlbuilder@11.0.1: {}
|
||||
|
||||
yaml@2.9.1:
|
||||
optional: true
|
||||
|
||||
|
||||
@ -28,6 +28,7 @@ import { NoticesModule } from './notices/notices.module.js';
|
||||
import { AgencyModule } from './agency/agency.module.js';
|
||||
import { StaffModule } from './staff/staff.module.js';
|
||||
import { CatalogModule } from './catalog/catalog.module.js';
|
||||
import { StorageModule } from './storage/storage.module.js';
|
||||
import { AppController } from './app.controller.js';
|
||||
import { AppService } from './app.service.js';
|
||||
|
||||
@ -53,6 +54,7 @@ import { AppService } from './app.service.js';
|
||||
AgencyModule,
|
||||
StaffModule,
|
||||
CatalogModule,
|
||||
StorageModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [
|
||||
|
||||
8
src/storage/storage.module.ts
Normal file
8
src/storage/storage.module.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { StorageService } from './storage.service.js';
|
||||
|
||||
@Module({
|
||||
providers: [StorageService],
|
||||
exports: [StorageService],
|
||||
})
|
||||
export class StorageModule {}
|
||||
20
src/storage/storage.service.spec.ts
Normal file
20
src/storage/storage.service.spec.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { describe, it, expect, vi } from 'vitest';
|
||||
import { StorageService } from './storage.service.js';
|
||||
|
||||
describe('StorageService', () => {
|
||||
it('upload 写桶并返回 key', async () => {
|
||||
const putObject = vi.fn().mockResolvedValue({ etag: 'x' });
|
||||
const svc = new StorageService();
|
||||
(svc as any).client = { putObject };
|
||||
(svc as any).bucket = 'carelink';
|
||||
const key = await svc.upload(Buffer.from('x'), 'elder/evidence/a.jpg');
|
||||
expect(putObject).toHaveBeenCalledWith('carelink', 'elder/evidence/a.jpg', expect.any(Buffer), expect.any(Number));
|
||||
expect(key).toBe('elder/evidence/a.jpg');
|
||||
});
|
||||
|
||||
it('buildKey 带租户前缀', () => {
|
||||
const svc = new StorageService();
|
||||
const key = svc.buildKey('T001', 'a.jpg');
|
||||
expect(key).toMatch(/^elder\/T001\/\d+-a\.jpg$/);
|
||||
});
|
||||
});
|
||||
30
src/storage/storage.service.ts
Normal file
30
src/storage/storage.service.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { Client } from 'minio';
|
||||
|
||||
@Injectable()
|
||||
export class StorageService {
|
||||
private readonly client: Client;
|
||||
private readonly bucket: string;
|
||||
|
||||
constructor() {
|
||||
// new Client() 只是构造客户端对象、不建立连接;putObject 时才连。
|
||||
// 测试里直接替换 (svc as any).client / .bucket 为 mock。
|
||||
this.client = new Client({
|
||||
endPoint: process.env.MINIO_ENDPOINT ?? 'localhost',
|
||||
port: Number(process.env.MINIO_PORT ?? 9000),
|
||||
useSSL: false,
|
||||
accessKey: process.env.MINIO_ACCESS_KEY ?? 'minioadmin',
|
||||
secretKey: process.env.MINIO_SECRET_KEY ?? 'minioadmin',
|
||||
});
|
||||
this.bucket = process.env.MINIO_BUCKET ?? 'carelink';
|
||||
}
|
||||
|
||||
buildKey(tenantCode: string, filename: string): string {
|
||||
return `elder/${tenantCode}/${Date.now()}-${filename}`;
|
||||
}
|
||||
|
||||
async upload(buffer: Buffer, key: string): Promise<string> {
|
||||
await this.client.putObject(this.bucket, key, buffer, buffer.length);
|
||||
return key;
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user