import { NextFunction, Request, Response } from "express"; import formidable, { Fields, Files } from "formidable"; import { TypedRequestAuth } from "./auth.controller"; import { asyncWrap } from "../helpers"; import { postDb, userDb } from "../db"; import { TypedRequest } from "../types"; import { Types } from "mongoose"; export const userByPostId = async ( reqExp: Request, res: Response, next: NextFunction, postId: string ) => { const req = reqExp as TypedRequest; req.user = await userDb.findUserByPostId(postId); next(); }; export const SubTract = (oldSet: Set, newSet: Set) => { const keep = new Array(); //유지 const drop = new Array(); //삭제 const add = new Array(); //추가 oldSet.forEach((oldname) => { drop.push(oldname); newSet.forEach((newname) => { add.push(newname); if (oldname === newname) { keep.push(oldname); } }); }); const addSet = new Set(add); const newAdd = [...addSet]; // console.log("before delete drop ", drop); // console.log("before delete add ", add); for (var i = 0; i < drop.length; i++) { for (var j = 0; j < keep.length; j++) { if (drop[i] === keep[j]) { drop.splice(i, 1); } } } for (var i = 0; i < newAdd.length; i++) { for (var j = 0; j < keep.length; j++) { if (newAdd[i] === keep[j]) { newAdd.splice(i, 1); } } } // console.log("spliced add", add); const dropSet = new Set(drop); const newDrop = [...dropSet]; const reAddSet = new Set(newAdd); const reNewAdd = [...reAddSet]; const res = { keep: keep, drop: newDrop, add: reNewAdd, }; return res; }; //Create export const createFileAndPost = asyncWrap(async (reqExp, res, next) => { const req = reqExp as TypedRequestAuth<{ userId: string }>; const { userId } = req.auth; const form = formidable({ uploadDir: "uploads", keepExtensions: true, multiples: true, }); const fileIdArr = new Array(); form.parse(req, async (err, fields, files) => { if (!Array.isArray(fields.title)) { const title = fields.title; if (!Array.isArray(fields.text)) { const text = fields.text; if (!Array.isArray(fields.theme)) { const theme = fields.theme; if (!Array.isArray(fields.city)) { const city = fields.city; if (Array.isArray(files.picture)) { for (var i = 0; i < files.picture.length; i++) { const originalfilename = files.picture?.[i].originalFilename; const newfilename = files.picture?.[i].newFilename; const filepath = files.picture?.[i].filepath; const filesRes = await postDb.createFilesRow( originalfilename, newfilename, filepath ); fileIdArr.push(filesRes); } } else if (!Array.isArray(files.picture)) { const originalfilename = files.picture.originalFilename; const newfilename = files.picture.newFilename; const filepath = files.picture.filepath; const filesRes = await postDb.createFilesRow( originalfilename, newfilename, filepath ); fileIdArr.push(filesRes); } // file or one or more const postRes = await postDb.createPostRow({ title, text, theme, city, date: Date.now(), counts: 0, user: userId, file: fileIdArr, }); return res.json(postRes); } } } } }); }); //Read export const getAllPost = asyncWrap(async (req, res) => { const posts = await postDb.getPosts(); return res.json(posts); }); export const getFiles = asyncWrap(async (req, res) => { const { postId } = req.params; const files = await postDb.getFilesByPostId(postId); return res.json(files); }); //Update export const addCounts = asyncWrap(async (req, res) => { const { postId } = req.params; const { counts } = req.body as { counts: number; }; const updateCounts = await postDb.addOneCount(postId, counts); return res.json(updateCounts); }); export const updateOnePost = asyncWrap(async (reqExp, res) => { const req = reqExp as TypedRequestAuth<{ userId: string }>; const { userId } = req.auth; const { postId } = req.params; const oldSet = new Set(); const newSet = new Set(); const fileIdArr = new Array(); const form = formidable({ uploadDir: "uploads", keepExtensions: true, multiples: true, }); form.parse(req, async (err, fields, files) => { if (!Array.isArray(fields.title)) { const title = fields.title; if (!Array.isArray(fields.text)) { const text = fields.text; if (!Array.isArray(fields.theme)) { const theme = fields.theme; if (!Array.isArray(fields.city)) { const city = fields.city; console.log("check files", files); if (files.picture === undefined || files.picture === null) { const postRes1 = await postDb.updatePostRow( { title, text, theme, city, date: Date.now(), }, postId ); console.log("no files update", postRes1); return res.json(postRes1); } else { if (Array.isArray(files.picture)) { const oldFilesId = await postDb.getFilesByPostId(postId); if (!(oldFilesId === undefined)) { for (var i = 0; i < oldFilesId?.length; i++) { const name = await postDb.getOriginalFileName( oldFilesId[i] ); if (!(name === undefined)) { oldSet.add(name); } } } console.log("OldSet", oldSet); if (Array.isArray(files.picture)) { for (var i = 0; i < files.picture.length; i++) { const newFileName = files.picture?.[i].originalFilename; if (!(newFileName === undefined || newFileName === null)) { newSet.add(newFileName); } } } console.log("NewSet", newSet); //유지, 삭제, 추가 구분하기 const trdPart = SubTract(oldSet, newSet); console.log("keep", trdPart.keep); console.log("drop", trdPart.drop); console.log("add", trdPart.add); // 삭제 for (var i = 0; i < trdPart.drop.length; i++) { const dropRes = await postDb.deleteFileByName( trdPart.drop[i] ); console.log("delete counts", dropRes); } //유지 for (var i = 0; i < trdPart.keep.length; i++) { const keepRes = await postDb.findByName(trdPart.keep[i]); fileIdArr.push(keepRes[0]._id); // console.log("keep Id", keepRes[0]._id); } //추가 for (var i = 0; i < files.picture.length; i++) { const originalfilename = files.picture?.[i].originalFilename; const newfilename = files.picture?.[i].newFilename; const filepath = files.picture?.[i].filepath; for (var j = 0; j < trdPart.add.length; j++) { const check = trdPart.add[j]; if (originalfilename === check) { const addRes = await postDb.createFilesRow( originalfilename, newfilename, filepath ); fileIdArr.push(addRes._id); } } } console.log("all fileId", fileIdArr); //post정보 + file정보 update const postRes2 = await postDb.updatePostRow( { title, text, theme, city, date: Date.now(), file: fileIdArr, }, postId ); console.log("plural files update", postRes2); return res.json(postRes2); } else { const oldFilesId = await postDb.getFilesByPostId(postId); if (!(oldFilesId === undefined)) { const name = await postDb.getOriginalFileName(oldFilesId[0]); if (!(name === undefined)) { oldSet.add(name); } } console.log("OldSet", oldSet); const newFileName = files.picture.originalFilename; if (!(newFileName === undefined || newFileName === null)) { newSet.add(newFileName); } console.log("NewSet", newSet); //유지, 삭제, 추가 구분하기 const trdPart = SubTract(oldSet, newSet); console.log("add part", trdPart.add); //삭제 for (var i = 0; i < trdPart.drop.length; i++) { const dropRes = await postDb.deleteFileByName( trdPart.drop[i] ); console.log("delete counts", dropRes); } //추가 const originalfilename = files.picture.originalFilename; const newfilename = files.picture.newFilename; const filepath = files.picture.filepath; if (originalfilename === trdPart.add[0]) { const addRes = await postDb.createFilesRow( originalfilename, newfilename, filepath ); fileIdArr.push(addRes._id); } console.log("all fileId", fileIdArr); //post정보 + file정보 update const postRes3 = await postDb.updatePostRow( { title, text, theme, city, date: Date.now(), file: fileIdArr, }, postId ); console.log("singular file update", postRes3); return res.json(postRes3); } } } } } } }); }); // Delete export const deleteOnePost = asyncWrap(async (req, res) => { const { postId } = req.params; const deleteCount = await postDb.deletePost(postId); return res.json(deleteCount); });