From 5dbf7c2049866220250b4acbec2ce6c024efea98 Mon Sep 17 00:00:00 2001 From: parkmineum Date: Thu, 15 Aug 2024 01:35:40 +0900 Subject: [PATCH 1/2] =?UTF-8?q?feat=20:=20=EC=A4=91=EA=B0=84=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EB=B3=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domains/admin/admin.controller.js | 12 +++++++++++- domains/admin/admin.dao.js | 21 ++++++++++++++++++++- domains/admin/admin.service.js | 15 ++++++++++++++- domains/admin/admin.sql.js | 25 ++++++++++++++++++++++++- 4 files changed, 69 insertions(+), 4 deletions(-) diff --git a/domains/admin/admin.controller.js b/domains/admin/admin.controller.js index 6a97732..b8051af 100644 --- a/domains/admin/admin.controller.js +++ b/domains/admin/admin.controller.js @@ -13,6 +13,7 @@ import { userProfileService, userInviteService, deleteUserService, + userSubmitService } from "./admin.service.js"; export const createRoomsController = async (req, res, next) => { @@ -112,4 +113,13 @@ export const deleteUserController = async (req, res, next) => { } catch (error) { next(error); } -}; \ No newline at end of file +}; + +export const userSubmitController = async (req, res, next) => { + try { + const result = await userSubmitService(req.params["room-id"], req.params["state"]); + res.status(200).json(response(status.SUCCESS, result)); + } catch (error) { + next(error); + } +} \ No newline at end of file diff --git a/domains/admin/admin.dao.js b/domains/admin/admin.dao.js index 2b9c24d..df3ed18 100644 --- a/domains/admin/admin.dao.js +++ b/domains/admin/admin.dao.js @@ -24,6 +24,8 @@ import { penaltySQL, penaltyStateSQL, addUserSubmitSQL, + userSubmitSQL, + getSubmitStateSQL, } from "./admin.sql.js"; import schedule from 'node-schedule'; @@ -252,6 +254,7 @@ export const userListDao = async (nickname, roomId) => { const [result] = await conn.query(userListSQLQuery, params); conn.release(); return result.map(user => user.user_id); + // return result; } catch (error) { console.log("User 검색 에러:", error); throw new BaseError(status.INTERNAL_SERVER_ERROR); @@ -323,4 +326,20 @@ export const penaltyDao = async () => { throw new Error("쿼리 실행에 실패하였습니다."); } }); -}; \ No newline at end of file +}; + +export const userSubmitDao = async (roomId, state) => { + try{ + const conn = await pool.getConnection(); + const [submitPost] = await conn.query(userSubmitSQL,[roomId]); + if(submitPost.length === 0) return {massage : "공지가 없습니다."}; + + await conn.query(getSubmitStateSQL, [state, roomId]); + + conn.release(); + return ; + }catch(error){ + console.log("확인 요청 조회 에러"); + throw new BaseError(status.INTERNAL_SERVER_ERROR); + } +} \ No newline at end of file diff --git a/domains/admin/admin.service.js b/domains/admin/admin.service.js index 77c296d..c8c0721 100644 --- a/domains/admin/admin.service.js +++ b/domains/admin/admin.service.js @@ -10,6 +10,7 @@ import { userProfileDao, userInviteDao, deleteUserDao, + userSubmitDao, } from "./admin.dao.js"; import { createShortUUID } from "./uuid.js"; import { createRoomsDTO, updateRoomsDTO, createPostDTO, updatePostDTO } from "./admin.dto.js"; @@ -101,7 +102,7 @@ export const userListService = async (nickname, roomId) => { throw new Error("조회할 공지방의 ID가 필요합니다."); } const result = await userListDao(nickname, roomId); - + if (!result.length) return []; return result.map(user => ({ userId : user.user_id, @@ -147,3 +148,15 @@ export const deleteUserService = async (body) => { throw error; } }; + +export const userSubmitService = async (roomId, state) => { + try{ + if(!roomId) throw new Error("요청 내역 조회를 위한 roomId가 필요합니다."); + if(!state) throw new Error("요청 내역 조회를 위한 state가 필요합니다."); + + const result = await userSubmitDao(roomId, state); + return result; + }catch(error){ + throw error; + } +} diff --git a/domains/admin/admin.sql.js b/domains/admin/admin.sql.js index 08c9f1a..9e2eef7 100644 --- a/domains/admin/admin.sql.js +++ b/domains/admin/admin.sql.js @@ -150,4 +150,27 @@ export const addUserSubmitSQL = ` WHERE s2.user_id = ur.user_id AND s2.post_id = p.id ) AND NOW() > DATE_ADD(p.end_date, INTERVAL 1 SECOND); -`; \ No newline at end of file +`; + +// 확인 요청 내역 조회 + +export const userSubmitSQL = ` + SELECT + p.title, p.start_date, p.end_date, p.content, r.room_image + , COUNT(s.id) AS pending_count + FROM post p + JOIN submit s ON p.id = s.post_id AND s.submit_state = 'PENDING' + JOIN room r ON p.room_id = r.id + WHERE p.room_id = ? + GROUP BY p.id; +`; + +export const getSubmitStateSQL = ` + SELECT u.profile_image, u.nickname, s.URL + FROM post p + JOIN submit s ON p.id = s.post_id AND s.submit_state = ? + JOIN user u ON s.user_id = u.id + LEFT JOIN \`submit-image\` si ON s.id = si.id + WHERE p.room_id = ?; +`; + From dafd7eb16cc9f4ff77882b8cd18903a16abea762 Mon Sep 17 00:00:00 2001 From: parkmineum Date: Thu, 15 Aug 2024 01:35:40 +0900 Subject: [PATCH 2/2] =?UTF-8?q?feat=20:=20=EC=A4=91=EA=B0=84=20=EC=9E=91?= =?UTF-8?q?=EC=97=85=EB=B3=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domains/admin/admin.controller.js | 20 +++++++++++++++----- domains/admin/admin.dao.js | 28 ++++++++++++++++++++++++++-- domains/admin/admin.dto.js | 7 +++++++ domains/admin/admin.service.js | 17 +++++++++++++++-- domains/admin/admin.sql.js | 28 +++++++++++++++++++++++++++- routes/admin.route.js | 8 +++++--- swagger/admin.swagger.yaml | 30 +++++++++++++++--------------- 7 files changed, 110 insertions(+), 28 deletions(-) diff --git a/domains/admin/admin.controller.js b/domains/admin/admin.controller.js index 6a97732..e8782e1 100644 --- a/domains/admin/admin.controller.js +++ b/domains/admin/admin.controller.js @@ -13,6 +13,7 @@ import { userProfileService, userInviteService, deleteUserService, + userSubmitService, } from "./admin.service.js"; export const createRoomsController = async (req, res, next) => { @@ -71,7 +72,7 @@ export const deletePostController = async (req, res, next) => { export const unreadUserListController = async(req, res, next) => { try { - const result = await unreadUserListService(req.params["post-id"]); + const result = await unreadUserListService(req.params.postId); res.status(200).json(response(status.SUCCESS, result)); } catch (error) { next(error); @@ -80,7 +81,7 @@ export const unreadUserListController = async(req, res, next) => { export const userListController = async (req,res,next) => { try{ - const result = await userListService(req.query.nickname, req.query["room-id"]); + const result = await userListService(req.query.nickname, req.query.roomId); res.status(200).json(response(status.SUCCESS, result)); }catch (error){ next(error); @@ -89,7 +90,7 @@ export const userListController = async (req,res,next) => { export const userProfileController = async (req, res, next) => { try { - const result = await userProfileService(req.query["room-id"], req.query["user-id"]); + const result = await userProfileService(req.query.roomId, req.query.userId); res.status(200).json(response(status.SUCCESS, result)); } catch (error) { next(error); @@ -98,7 +99,7 @@ export const userProfileController = async (req, res, next) => { export const userInviteController = async (req, res, next) => { try { - const result = await userInviteService(req.params["room-id"]); + const result = await userInviteService(req.params.roomId); res.status(200).json(response(status.SUCCESS, result)); } catch (error) { next(error); @@ -112,4 +113,13 @@ export const deleteUserController = async (req, res, next) => { } catch (error) { next(error); } -}; \ No newline at end of file +}; + +export const userSubmitController = async (req, res, next) => { + try { + const result = await userSubmitService(req.params.roomId); + res.status(200).json(response(status.SUCCESS, result)); + } catch (error) { + next(error); + } +} \ No newline at end of file diff --git a/domains/admin/admin.dao.js b/domains/admin/admin.dao.js index 943b124..f78dced 100644 --- a/domains/admin/admin.dao.js +++ b/domains/admin/admin.dao.js @@ -25,6 +25,9 @@ import { penaltySQL, penaltyStateSQL, addUserSubmitSQL, + getPostCountSQL, + userSubmitSQL, + getSubmitStateSQL, } from "./admin.sql.js"; import schedule from "node-schedule"; @@ -248,7 +251,8 @@ export const userListDao = async (nickname, roomId) => { const [result] = await conn.query(userListSQLQuery, params); conn.release(); - return result.map((user) => user.user_id); + return result; + } catch (error) { console.log("User 검색 에러:", error); throw new BaseError(status.INTERNAL_SERVER_ERROR); @@ -258,7 +262,7 @@ export const userListDao = async (nickname, roomId) => { export const userProfileDao = async (roomId, userId) => { try { const conn = await pool.getConnection(); - const [result] = await conn.query(userProfileSQL, [roomId, userId]); + const [result] = await conn.query(userProfileSQL, [userId, roomId]); conn.release(); return result[0]; } catch (error) { @@ -320,3 +324,23 @@ export const penaltyDao = async () => { } }); }; + +export const userSubmitDao = async (roomId) => { + try{ + const conn = await pool.getConnection(); + + const [rows] = await conn.query(getPostCountSQL); + const countPost = rows[0]?.count || 0; + if(countPost.length === 0) return {massage : "공지가 없습니다."}; + + const [userSubmissions] = await conn.query(userSubmitSQL, roomId); + const [submitStates] = await conn.query(getSubmitStateSQL, roomId); + console.log(submitStates); + conn.release(); + return { userSubmissions, submitStates } ; + }catch(error){ + console.log("확인 요청 조회 에러"); + throw new BaseError(status.INTERNAL_SERVER_ERROR); + } +} + diff --git a/domains/admin/admin.dto.js b/domains/admin/admin.dto.js index cdc501b..c92365b 100644 --- a/domains/admin/admin.dto.js +++ b/domains/admin/admin.dto.js @@ -21,3 +21,10 @@ export const updatePostDTO = (updatePostData) => { ...updatePostData, }; }; + +export const userSubmitDTO = (userSubmissions, submitStates) => { + const pendingStates = submitStates.filter(state => state.submit_state === 'PENDING'); + const completeStates = submitStates.filter(state => state.submit_state === 'COMPLETE'); + + return { userSubmissions, pendingStates, completeStates }; +} \ No newline at end of file diff --git a/domains/admin/admin.service.js b/domains/admin/admin.service.js index 77c296d..200fc9e 100644 --- a/domains/admin/admin.service.js +++ b/domains/admin/admin.service.js @@ -10,9 +10,10 @@ import { userProfileDao, userInviteDao, deleteUserDao, + userSubmitDao, } from "./admin.dao.js"; import { createShortUUID } from "./uuid.js"; -import { createRoomsDTO, updateRoomsDTO, createPostDTO, updatePostDTO } from "./admin.dto.js"; +import { createRoomsDTO, updateRoomsDTO, createPostDTO, updatePostDTO, userSubmitDTO } from "./admin.dto.js"; export const createRoomsService = async (body, userId) => { try { @@ -101,7 +102,7 @@ export const userListService = async (nickname, roomId) => { throw new Error("조회할 공지방의 ID가 필요합니다."); } const result = await userListDao(nickname, roomId); - + if (!result.length) return []; return result.map(user => ({ userId : user.user_id, @@ -147,3 +148,15 @@ export const deleteUserService = async (body) => { throw error; } }; + +export const userSubmitService = async (roomId) => { + try{ + if(!roomId) throw new Error("요청 내역 조회를 위한 roomId가 필요합니다."); + + const { userSubmissions, submitStates } = await userSubmitDao(roomId); + const result = userSubmitDTO( userSubmissions, submitStates); + return result; + }catch(error){ + throw error; + } +}; diff --git a/domains/admin/admin.sql.js b/domains/admin/admin.sql.js index f894846..fc7e250 100644 --- a/domains/admin/admin.sql.js +++ b/domains/admin/admin.sql.js @@ -45,7 +45,7 @@ export const updatePostSQL = ` WHERE id = ?; `; export const deletePostImgSQL = ` - UPDATE \`post-image\` SET state = 'DELETED' WHERE post_id = ? AND URL = ?; + UPDATE \`post-image\` SET state = 'DELETED' WHERE post_id = ? AND URL = ?; `; // 공지글 삭제 @@ -150,3 +150,29 @@ export const addUserSubmitSQL = ` ) AND NOW() > DATE_ADD(p.end_date, INTERVAL 1 SECOND); `; + +// 확인 요청 내역 조회 +export const getPostCountSQL = ` + SELECT COUNT(*) AS count FROM post; +`; + +export const userSubmitSQL = ` + SELECT + p.title, p.start_date, p.end_date, p.content, r.room_image + , COUNT(s.id) AS pending_count + FROM post p + JOIN submit s ON p.id = s.post_id AND s.submit_state = 'PENDING' + JOIN room r ON p.room_id = r.id + WHERE p.room_id = ? + GROUP BY p.id; +`; + +export const getSubmitStateSQL = ` + SELECT u.profile_image, u.nickname, si.URL, s.submit_state + FROM post p + JOIN submit s ON p.id = s.post_id + JOIN user u ON s.user_id = u.id + LEFT JOIN \`submit-image\` si ON s.id = si.id + WHERE p.room_id = ? AND s.submit_state IN ('PENDING', 'COMPLETE'); +`; + diff --git a/routes/admin.route.js b/routes/admin.route.js index 813a868..3cf832b 100644 --- a/routes/admin.route.js +++ b/routes/admin.route.js @@ -13,18 +13,20 @@ import { userProfileController, userInviteController, deleteUserController, + userSubmitController } from "../domains/admin/admin.controller.js"; export const adminRouter = express.Router(); adminRouter.post("/rooms", tokenAuth, expressAsyncHandler(createRoomsController)); -adminRouter.patch("/rooms/:room_id", tokenAuth, expressAsyncHandler(updateRoomsController)); +adminRouter.patch("/rooms/:roomId", tokenAuth, expressAsyncHandler(updateRoomsController)); adminRouter.patch("/rooms", tokenAuth, expressAsyncHandler(deleteRoomsController)); adminRouter.post("/post", tokenAuth, expressAsyncHandler(createPostController)); -adminRouter.patch("/post/:post_id", tokenAuth, expressAsyncHandler(updatePostController)); +adminRouter.patch("/post/:postId", tokenAuth, expressAsyncHandler(updatePostController)); adminRouter.patch("/post", tokenAuth, expressAsyncHandler(deletePostController)); adminRouter.get("/post/:postId/unread", tokenAuth, expressAsyncHandler(unreadUserListController)); adminRouter.get("/users", tokenAuth, expressAsyncHandler(userListController)); adminRouter.get("/profile", tokenAuth, expressAsyncHandler(userProfileController)); adminRouter.get("/invitation/:roomId", tokenAuth, expressAsyncHandler(userInviteController)); -adminRouter.delete("/user-ban", tokenAuth, expressAsyncHandler(deleteUserController)); \ No newline at end of file +adminRouter.delete("/user-ban", tokenAuth, expressAsyncHandler(deleteUserController)); +adminRouter.get("/submit/:roomId", tokenAuth, expressAsyncHandler(userSubmitController)); \ No newline at end of file diff --git a/swagger/admin.swagger.yaml b/swagger/admin.swagger.yaml index e8423b9..51e2fcc 100644 --- a/swagger/admin.swagger.yaml +++ b/swagger/admin.swagger.yaml @@ -52,7 +52,7 @@ paths: result: type: object properties: - postId : + roomId : type : number description : 생성된 공지방ID roomImage: @@ -118,7 +118,7 @@ paths: type : number description : 삭제된 공지방의 Id - /admin/rooms/{room_id}: + /admin/rooms/{roomId}: patch: tags: - admin @@ -131,12 +131,12 @@ paths: - bearerAuth: [] parameters: - in: path - name: room_id + name: roomId required: true schema: type: integer example: 1 - description: room_Id + description: roomId requestBody: required: true content: @@ -216,7 +216,7 @@ paths: schema: type: object properties: - room_id: + roomId: type: integer description: 공지방 id type: @@ -338,7 +338,7 @@ paths: type : number description : 삭제된 공지글의 Id - /admin/post/{post_id}: + /admin/post/{postId}: patch: tags: - admin @@ -351,12 +351,12 @@ paths: - bearerAuth: [] parameters: - in: path - name: post_id + name: postId required: true schema: type: integer example: 1 - description: post_Id + description: postId requestBody: required: true content: @@ -434,7 +434,7 @@ paths: type : string description: 퀴즈/미션 질문 - /admin/post/{post-id}/unread: + /admin/post/{postId}/unread: get: tags: - admin @@ -446,7 +446,7 @@ paths: security: - bearerAuth: [] parameters: - - name: post-id + - name: postId in: path schema: type: integer @@ -498,7 +498,7 @@ paths: type: string example : 제이 - in: query - name: room-id + name: roomId required: true description: 사용자가 속한 room의 ID schema: @@ -547,14 +547,14 @@ paths: - bearerAuth: [] parameters: - in: query - name: room-id + name: roomId required: true description: 공지방 ID schema: type: integer example : 6 - in: query - name: user-id + name: userId required: true description: 유저 ID schema: @@ -590,7 +590,7 @@ paths: type : integer description : 패널티 개수 - /admin/invitation/{room-id} : + /admin/invitation/{roomId} : get: tags: - admin @@ -602,7 +602,7 @@ paths: security: - bearerAuth: [] parameters: - - name: room-id + - name: roomId in: path schema: type: integer