From 359de28158dcb5b7aea6b2db9024aa6da7383477 Mon Sep 17 00:00:00 2001 From: Bob Du Date: Mon, 26 May 2025 21:55:01 +0800 Subject: [PATCH] refactor: split room routes file Signed-off-by: Bob Du --- service/package.json | 4 +- service/pnpm-lock.yaml | 33 +++--- service/src/index.ts | 170 +------------------------------ service/src/routes/room.ts | 172 ++++++++++++++++++++++++++++++++ src/store/modules/chat/index.ts | 2 + 5 files changed, 196 insertions(+), 185 deletions(-) create mode 100644 service/src/routes/room.ts diff --git a/service/package.json b/service/package.json index 1741252a..18696340 100644 --- a/service/package.json +++ b/service/package.json @@ -36,8 +36,8 @@ "file-type": "^19.0.0", "https-proxy-agent": "^7.0.6", "jsonwebtoken": "^9.0.0", - "mongodb": "^6.6.2", - "multer": "1.4.5-lts.1", + "mongodb": "^6.16.0", + "multer": "^2.0.0", "node-fetch": "^3.3.0", "nodemailer": "^6.9.13", "openai": "^4.96.0", diff --git a/service/pnpm-lock.yaml b/service/pnpm-lock.yaml index 857294c7..e4bf97f4 100644 --- a/service/pnpm-lock.yaml +++ b/service/pnpm-lock.yaml @@ -30,11 +30,11 @@ dependencies: specifier: ^9.0.0 version: 9.0.0 mongodb: - specifier: ^6.6.2 - version: 6.6.2 + specifier: ^6.16.0 + version: 6.16.0 multer: - specifier: 1.4.5-lts.1 - version: 1.4.5-lts.1 + specifier: ^2.0.0 + version: 2.0.0 node-fetch: specifier: ^3.3.0 version: 3.3.0 @@ -519,9 +519,8 @@ packages: wrap-ansi-cjs: /wrap-ansi@7.0.0 dev: true - /@mongodb-js/saslprep@1.1.6: - resolution: {integrity: sha512-jqTTXQ46H8cAxmXBu8wm1HTSIMBMrIcoVrsjdQkKdMBj3il/fSCgWyya4P2I1xjPBl69mw+nRphrPlcIqBd20Q==} - requiresBuild: true + /@mongodb-js/saslprep@1.2.2: + resolution: {integrity: sha512-EB0O3SCSNRUFk66iRCpI+cXzIjdswfCs7F6nOC3RAGJ7xr5YhaicvsRwJ9eyzYvYRlCSDUO/c7g4yNulxKC1WA==} dependencies: sparse-bitfield: 3.0.3 dev: false @@ -1107,8 +1106,8 @@ packages: fill-range: 7.0.1 dev: true - /bson@6.7.0: - resolution: {integrity: sha512-w2IquM5mYzYZv6rs3uN2DZTOBe2a0zXLj53TGDqwF4l6Sz/XsISrisXOJihArF9+BZ6Cq/GjVht7Sjfmri7ytQ==} + /bson@6.10.3: + resolution: {integrity: sha512-MTxGsqgYTwfshYWTRdmZRC+M7FnG1b4y7RO7p2k3X24Wq0yv1m77Wsj0BzlPzd/IowgESfsruQCUToa7vbOpPQ==} engines: {node: '>=16.20.1'} dev: false @@ -2778,12 +2777,12 @@ packages: whatwg-url: 13.0.0 dev: false - /mongodb@6.6.2: - resolution: {integrity: sha512-ZF9Ugo2JCG/GfR7DEb4ypfyJJyiKbg5qBYKRintebj8+DNS33CyGMkWbrS9lara+u+h+yEOGSRiLhFO/g1s1aw==} + /mongodb@6.16.0: + resolution: {integrity: sha512-D1PNcdT0y4Grhou5Zi/qgipZOYeWrhLEpk33n3nm6LGtz61jvO88WlrWCK/bigMjpnOdAUKKQwsGIl0NtWMyYw==} engines: {node: '>=16.20.1'} peerDependencies: '@aws-sdk/credential-providers': ^3.188.0 - '@mongodb-js/zstd': ^1.1.0 + '@mongodb-js/zstd': ^1.1.0 || ^2.0.0 gcp-metadata: ^5.2.0 kerberos: ^2.0.1 mongodb-client-encryption: '>=6.0.0 <7' @@ -2805,8 +2804,8 @@ packages: socks: optional: true dependencies: - '@mongodb-js/saslprep': 1.1.6 - bson: 6.7.0 + '@mongodb-js/saslprep': 1.2.2 + bson: 6.10.3 mongodb-connection-string-url: 3.0.1 dev: false @@ -2817,9 +2816,9 @@ packages: /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - /multer@1.4.5-lts.1: - resolution: {integrity: sha512-ywPWvcDMeH+z9gQq5qYHCCy+ethsk4goepZ45GLD63fOu0YcNecQxi64nDs3qluZB+murG3/D4dJ7+dGctcCQQ==} - engines: {node: '>= 6.0.0'} + /multer@2.0.0: + resolution: {integrity: sha512-bS8rPZurbAuHGAnApbM9d4h1wSoYqrOqkE+6a64KLMK9yWU7gJXBDDVklKQ3TPi9DRb85cRs6yXaC0+cjxRtRg==} + engines: {node: '>= 10.16.0'} dependencies: append-field: 1.0.0 busboy: 1.6.0 diff --git a/service/src/index.ts b/service/src/index.ts index 747e2abe..72bebc72 100644 --- a/service/src/index.ts +++ b/service/src/index.ts @@ -12,26 +12,17 @@ import { clearApiKeyCache, clearConfigCache, getApiKeys, getCacheApiKeys, getCac import type { AnnounceConfig, AuditConfig, Config, GiftCard, KeyConfig, MailConfig, SiteConfig, UserConfig, UserInfo } from './storage/model' import { AdvancedConfig, Status, UserRole } from './storage/model' import { - createChatRoom, createUser, - deleteChatRoom, disableUser2FA, - existsChatRoom, getAmtByCardNo, - getChatRooms, - getChatRoomsCount, getUser, getUserById, getUserStatisticsByDay, getUsers, - renameChatRoom, updateApiKeyStatus, updateConfig, updateGiftCard, updateGiftCards, - updateRoomChatModel, - updateRoomPrompt, - updateRoomUsingContext, updateUser, updateUser2FA, updateUserAdvancedConfig, @@ -52,6 +43,7 @@ import { isAdmin, rootAuth } from './middleware/rootAuth' import { router as chatRouter } from './routes/chat' import { router as promptRouter } from './routes/prompt' +import { router as roomRouter } from './routes/room' import { router as uploadRouter } from './routes/upload' dotenv.config() @@ -79,163 +71,6 @@ app.all('/', (_, res, next) => { next() }) -router.get('/chatrooms', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const rooms = await getChatRooms(userId) - const result = [] - rooms.forEach((r) => { - result.push({ - uuid: r.roomId, - title: r.title, - isEdit: false, - prompt: r.prompt, - usingContext: r.usingContext === undefined ? true : r.usingContext, - chatModel: r.chatModel, - }) - }) - res.send({ status: 'Success', message: null, data: result }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Load error', data: [] }) - } -}) - -function formatTimestamp(timestamp: number) { - const date = new Date(timestamp) - const year = date.getFullYear() - const month = String(date.getMonth() + 1).padStart(2, '0') - const day = String(date.getDate()).padStart(2, '0') - const hours = String(date.getHours()).padStart(2, '0') - const minutes = String(date.getMinutes()).padStart(2, '0') - const seconds = String(date.getSeconds()).padStart(2, '0') - - return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` -} - -router.get('/chatrooms-count', auth, async (req, res) => { - try { - const userId = req.query.userId as string - const page = +req.query.page - const size = +req.query.size - const rooms = await getChatRoomsCount(userId, page, size) - const result = [] - rooms.data.forEach((r) => { - result.push({ - uuid: r.roomId, - title: r.title, - userId: r.userId, - name: r.username, - lastTime: formatTimestamp(r.dateTime), - chatCount: r.chatCount, - }) - }) - res.send({ status: 'Success', message: null, data: { data: result, total: rooms.total } }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Load error', data: [] }) - } -}) - -router.post('/room-create', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const { title, roomId, chatModel } = req.body as { title: string; roomId: number; chatModel: string } - const room = await createChatRoom(userId, title, roomId, chatModel) - res.send({ status: 'Success', message: null, data: room }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Create error', data: null }) - } -}) - -router.post('/room-rename', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const { title, roomId } = req.body as { title: string; roomId: number } - const success = await renameChatRoom(userId, title, roomId) - if (success) - res.send({ status: 'Success', message: null, data: null }) - else - res.send({ status: 'Fail', message: 'Saved Failed', data: null }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Rename error', data: null }) - } -}) - -router.post('/room-prompt', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const { prompt, roomId } = req.body as { prompt: string; roomId: number } - const success = await updateRoomPrompt(userId, roomId, prompt) - if (success) - res.send({ status: 'Success', message: 'Saved successfully', data: null }) - else - res.send({ status: 'Fail', message: 'Saved Failed', data: null }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Rename error', data: null }) - } -}) - -router.post('/room-chatmodel', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const { chatModel, roomId } = req.body as { chatModel: string; roomId: number } - const success = await updateRoomChatModel(userId, roomId, chatModel) - if (success) - res.send({ status: 'Success', message: 'Saved successfully', data: null }) - else - res.send({ status: 'Fail', message: 'Saved Failed', data: null }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Rename error', data: null }) - } -}) - -router.post('/room-context', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const { using, roomId } = req.body as { using: boolean; roomId: number } - const success = await updateRoomUsingContext(userId, roomId, using) - if (success) - res.send({ status: 'Success', message: 'Saved successfully', data: null }) - else - res.send({ status: 'Fail', message: 'Saved Failed', data: null }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Rename error', data: null }) - } -}) - -router.post('/room-delete', auth, async (req, res) => { - try { - const userId = req.headers.userId as string - const { roomId } = req.body as { roomId: number } - if (!roomId || !await existsChatRoom(userId, roomId)) { - res.send({ status: 'Fail', message: 'Unknown room', data: null }) - return - } - const success = await deleteChatRoom(userId, roomId) - if (success) - res.send({ status: 'Success', message: null, data: null }) - else - res.send({ status: 'Fail', message: 'Saved Failed', data: null }) - } - catch (error) { - console.error(error) - res.send({ status: 'Fail', message: 'Delete error', data: null }) - } -}) - router.post('/user-register', authLimiter, async (req, res) => { try { const { username, password } = req.body as { username: string; password: string } @@ -1053,6 +888,9 @@ app.use('/api', chatRouter) app.use('', promptRouter) app.use('/api', promptRouter) +app.use('', roomRouter) +app.use('/api', roomRouter) + app.use('', uploadRouter) app.use('/api', uploadRouter) diff --git a/service/src/routes/room.ts b/service/src/routes/room.ts new file mode 100644 index 00000000..e2e9e4b4 --- /dev/null +++ b/service/src/routes/room.ts @@ -0,0 +1,172 @@ +import Router from 'express' +import { auth } from '../middleware/auth' +import { + createChatRoom, + deleteChatRoom, + existsChatRoom, + getChatRooms, + getChatRoomsCount, + renameChatRoom, + updateRoomChatModel, + updateRoomPrompt, + updateRoomUsingContext, +} from '../storage/mongo' + +export const router = Router() + +router.get('/chatrooms', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const rooms = await getChatRooms(userId) + const result = [] + rooms.forEach((r) => { + result.push({ + uuid: r.roomId, + title: r.title, + isEdit: false, + prompt: r.prompt, + usingContext: r.usingContext === undefined ? true : r.usingContext, + chatModel: r.chatModel, + }) + }) + res.send({ status: 'Success', message: null, data: result }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Load error', data: [] }) + } +}) + +function formatTimestamp(timestamp: number) { + const date = new Date(timestamp) + const year = date.getFullYear() + const month = String(date.getMonth() + 1).padStart(2, '0') + const day = String(date.getDate()).padStart(2, '0') + const hours = String(date.getHours()).padStart(2, '0') + const minutes = String(date.getMinutes()).padStart(2, '0') + const seconds = String(date.getSeconds()).padStart(2, '0') + + return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}` +} + +router.get('/chatrooms-count', auth, async (req, res) => { + try { + const userId = req.query.userId as string + const page = +req.query.page + const size = +req.query.size + const rooms = await getChatRoomsCount(userId, page, size) + const result = [] + rooms.data.forEach((r) => { + result.push({ + uuid: r.roomId, + title: r.title, + userId: r.userId, + name: r.username, + lastTime: formatTimestamp(r.dateTime), + chatCount: r.chatCount, + }) + }) + res.send({ status: 'Success', message: null, data: { data: result, total: rooms.total } }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Load error', data: [] }) + } +}) + +router.post('/room-create', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const { title, roomId, chatModel } = req.body as { title: string; roomId: number; chatModel: string } + const room = await createChatRoom(userId, title, roomId, chatModel) + res.send({ status: 'Success', message: null, data: room }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Create error', data: null }) + } +}) + +router.post('/room-rename', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const { title, roomId } = req.body as { title: string; roomId: number } + const success = await renameChatRoom(userId, title, roomId) + if (success) + res.send({ status: 'Success', message: null, data: null }) + else + res.send({ status: 'Fail', message: 'Saved Failed', data: null }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Rename error', data: null }) + } +}) + +router.post('/room-prompt', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const { prompt, roomId } = req.body as { prompt: string; roomId: number } + const success = await updateRoomPrompt(userId, roomId, prompt) + if (success) + res.send({ status: 'Success', message: 'Saved successfully', data: null }) + else + res.send({ status: 'Fail', message: 'Saved Failed', data: null }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Rename error', data: null }) + } +}) + +router.post('/room-chatmodel', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const { chatModel, roomId } = req.body as { chatModel: string; roomId: number } + const success = await updateRoomChatModel(userId, roomId, chatModel) + if (success) + res.send({ status: 'Success', message: 'Saved successfully', data: null }) + else + res.send({ status: 'Fail', message: 'Saved Failed', data: null }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Rename error', data: null }) + } +}) + +router.post('/room-context', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const { using, roomId } = req.body as { using: boolean; roomId: number } + const success = await updateRoomUsingContext(userId, roomId, using) + if (success) + res.send({ status: 'Success', message: 'Saved successfully', data: null }) + else + res.send({ status: 'Fail', message: 'Saved Failed', data: null }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Rename error', data: null }) + } +}) + +router.post('/room-delete', auth, async (req, res) => { + try { + const userId = req.headers.userId as string + const { roomId } = req.body as { roomId: number } + if (!roomId || !await existsChatRoom(userId, roomId)) { + res.send({ status: 'Fail', message: 'Unknown room', data: null }) + return + } + const success = await deleteChatRoom(userId, roomId) + if (success) + res.send({ status: 'Success', message: null, data: null }) + else + res.send({ status: 'Fail', message: 'Saved Failed', data: null }) + } + catch (error) { + console.error(error) + res.send({ status: 'Fail', message: 'Delete error', data: null }) + } +}) diff --git a/src/store/modules/chat/index.ts b/src/store/modules/chat/index.ts index 5a53e694..56748970 100644 --- a/src/store/modules/chat/index.ts +++ b/src/store/modules/chat/index.ts @@ -107,6 +107,8 @@ export const useChatStore = defineStore('chat-store', { }, async setChatModel(chatModel: string, roomId: number) { + const index = this.history.findIndex(item => item.uuid === this.active) + this.history[index].chatModel = chatModel await fetchUpdateChatRoomChatModel(chatModel, roomId) const userStore = useUserStore() userStore.userInfo.config.chatModel = chatModel