diff --git a/server/admin/src/client/i18n/en.ts b/server/admin/src/client/i18n/en.ts index c1cab1ab..edaa2bac 100644 --- a/server/admin/src/client/i18n/en.ts +++ b/server/admin/src/client/i18n/en.ts @@ -37,6 +37,9 @@ export const enTranslation = { 'Tailchat: The next-generation noIM Application in your own workspace', }, }, + file: { + fileTotalSize: 'File Total Size', + }, analytics: { activeGroupTop5: 'Active Group Top 5', activeUserTop5: 'Active User Top 5', diff --git a/server/admin/src/client/i18n/zh.ts b/server/admin/src/client/i18n/zh.ts index 8e07bd3e..15f73c68 100644 --- a/server/admin/src/client/i18n/zh.ts +++ b/server/admin/src/client/i18n/zh.ts @@ -128,6 +128,9 @@ export const zhTranslation = { tushan: 'Tailchat Admin后台 由 tushan 提供技术支持', }, }, + file: { + fileTotalSize: '文件总大小', + }, analytics: { activeGroupTop5: '前 5 名活跃群组', activeUserTop5: '前 5 名活跃用户', diff --git a/server/admin/src/client/resources/file.tsx b/server/admin/src/client/resources/file.tsx index b526da39..0a2541d6 100644 --- a/server/admin/src/client/resources/file.tsx +++ b/server/admin/src/client/resources/file.tsx @@ -1,19 +1,40 @@ +import filesize from 'filesize'; import React from 'react'; -import { createTextField, ListTable } from 'tushan'; +import { + createTextField, + ListTable, + useAsync, + useTranslation, + Typography, +} from 'tushan'; import { fileFields } from '../fields'; +import { request } from '../request'; export const FileList: React.FC = React.memo(() => { + const { t } = useTranslation(); + const { value: totalSize = 0 } = useAsync(async () => { + const { data } = await request.get('/file/filesizeSum'); + + return data.totalSize ?? 0; + }, []); + return ( - + <> + + {t('custom.file.fileTotalSize')}: {filesize(totalSize)} + + + ); }); FileList.displayName = 'FileList'; diff --git a/server/admin/src/server/router/file.ts b/server/admin/src/server/router/file.ts index 114a0748..d432036e 100644 --- a/server/admin/src/server/router/file.ts +++ b/server/admin/src/server/router/file.ts @@ -6,6 +6,7 @@ import { Router } from 'express'; import { callBrokerAction } from '../broker'; import { auth } from '../middleware/auth'; import Busboy from '@fastify/busboy'; +import fileModel from '../../../../models/file'; const router = Router(); @@ -57,4 +58,25 @@ router.put('/upload', auth(), async (req, res) => { req.pipe(busboy); }); +router.get('/filesizeSum', auth(), async (req, res) => { + const ret = await fileModel.aggregate([ + { + $group: { + _id: '$objectName' as any, + size: { $first: '$size' }, + }, + }, + { + $group: { + _id: null, + totalSize: { $sum: '$size' }, + }, + }, + ]); + + const totalSize = ret[0].totalSize; + + res.json({ totalSize }); +}); + export { router as fileRouter };