Commit 7285bfbd authored by Lee Soobeom's avatar Lee Soobeom
Browse files

files muliple uploads

parent 715ce2d9
...@@ -29,7 +29,6 @@ export const App = () => { ...@@ -29,7 +29,6 @@ export const App = () => {
<Route path="board" element={<Board />} /> <Route path="board" element={<Board />} />
<Route path="post/:postId" element={<IntoPost />} /> <Route path="post/:postId" element={<IntoPost />} />
<Route path="edit" element={<EditPost />} /> <Route path="edit" element={<EditPost />} />
{/* </Route> */}
<Route <Route
path="profile" path="profile"
element={ element={
...@@ -39,7 +38,7 @@ export const App = () => { ...@@ -39,7 +38,7 @@ export const App = () => {
} }
/> />
<Route path="admin" element={<Admin />} /> <Route path="admin" element={<Admin />} />
<Route path="rewrite" element={<ImgRewrite/>}/> <Route path="rewrite" element={<ImgRewrite />} />
</Route> </Route>
</Route> </Route>
</Routes> </Routes>
......
...@@ -2,7 +2,7 @@ import axios from "axios"; ...@@ -2,7 +2,7 @@ import axios from "axios";
import baseUrl from "./baseUrl"; import baseUrl from "./baseUrl";
import { PostType } from "../types"; import { PostType } from "../types";
export const createImgAndPost = async (formdata: FormData) => { export const createFileAndPost = async (formdata: FormData) => {
const { data } = await axios.post(`${baseUrl}/posts/`, formdata); const { data } = await axios.post(`${baseUrl}/posts/`, formdata);
return data; return data;
}; };
...@@ -10,31 +10,31 @@ export const createImgAndPost = async (formdata: FormData) => { ...@@ -10,31 +10,31 @@ export const createImgAndPost = async (formdata: FormData) => {
export const getData = async () => { export const getData = async () => {
const { data } = await axios.get(`${baseUrl}/posts/`); const { data } = await axios.get(`${baseUrl}/posts/`);
return data; return data;
}; }; //board
export const getFileByPostId = async (postId: string) => {
const { data } = await axios.get(`${baseUrl}/posts/files/${postId}`);
return data;
}; //
export const getImgData = async (name: string) => { export const getImgData = async (name: string) => {
const { data } = await axios.get(`/images/${name}`); const { data } = await axios.get(`/images/${name}`);
return data; return data;
}; };
export const addCounts = async (_id: string, counts: number) => { export const addCounts = async (postId: string, counts: number) => {
const { data } = await axios.post(`${baseUrl}/posts/${_id}`, { const { data } = await axios.post(`${baseUrl}/posts/${postId}`, {
counts: counts + 1, counts: counts + 1,
}); });
return data; return data;
}; };
export const getPostByPostId = async (_id: string) => { export const deletePost = async (postId: string) => {
const { data } = await axios.get(`${baseUrl}/posts/${_id}`); const { data } = await axios.delete(`${baseUrl}/posts/${postId}`);
return data;
};
export const deletePost = async (_id: string) => {
const { data } = await axios.delete(`${baseUrl}/posts/${_id}`);
return data; return data;
}; };
export const updating = async (post: PostType) => { export const updateImgAndPost = async (postId: string, formdata: FormData) => {
const { data } = await axios.put(`${baseUrl}/posts/${post._id}`, post); const { data } = await axios.put(`${baseUrl}/posts/${postId}`, formdata);
return data; return data;
}; };
...@@ -13,8 +13,8 @@ export default function BoardPage() { ...@@ -13,8 +13,8 @@ export default function BoardPage() {
useEffect(() => { useEffect(() => {
getDataList(); getDataList();
}, [posts]); }, []);
// posts
const getDataList = async () => { const getDataList = async () => {
const res = await postApi.getData(); const res = await postApi.getData();
setPosts(res); setPosts(res);
......
import React, { FormEvent, useState } from "react"; import React, { FormEvent, useState, useEffect } from "react";
import { useNavigate, useLocation } from "react-router-dom"; import { useNavigate, useLocation } from "react-router-dom";
import isLength from "validator/lib/isLength"; import isLength from "validator/lib/isLength";
import equals from "validator/lib/equals"; import equals from "validator/lib/equals";
...@@ -6,12 +6,16 @@ import { catchErrors } from "../helpers"; ...@@ -6,12 +6,16 @@ import { catchErrors } from "../helpers";
import { PostType } from "../types"; import { PostType } from "../types";
import { postApi } from "../apis"; import { postApi } from "../apis";
import { PostState } from "./intopost"; import { PostState } from "./intopost";
import { FileType } from "./intopost";
export function EditPost() { export function EditPost() {
const [city, setCity] = useState<string>("city"); const [city, setCity] = useState<string>("city");
const [theme, setTheme] = useState<string>("theme"); const [theme, setTheme] = useState<string>("theme");
const [title, setTitle] = useState<string>(""); const [title, setTitle] = useState<string>("");
const [text, setText] = useState<string>(""); const [text, setText] = useState<string>("");
const [file, setFile] = useState<FileList>();
const [imgSrc, setImgSrc] = useState<string[]>();
const [filesList, setFilesList] = useState<FileType[]>();
const navigate = useNavigate(); const navigate = useNavigate();
const location = useLocation() as PostState; const location = useLocation() as PostState;
...@@ -24,7 +28,7 @@ export function EditPost() { ...@@ -24,7 +28,7 @@ export function EditPost() {
city: post.city, city: post.city,
date: post.date, date: post.date,
user: post.user, user: post.user,
counts: 0, counts: post.counts,
_id: post._id, _id: post._id,
}); });
...@@ -33,22 +37,52 @@ export function EditPost() { ...@@ -33,22 +37,52 @@ export function EditPost() {
const [disabled, setDisabled] = useState(false); const [disabled, setDisabled] = useState(false);
const [success, setSuccess] = useState(false); const [success, setSuccess] = useState(false);
useEffect(() => {
getFilesList(post._id);
}, []);
const imgArr = new Array();
const getFilesList = async (postId: string) => {
const res = await postApi.getFileByPostId(postId); //_id는 req.params에 항상 같이 보낸다
setFilesList(res);
};
const updateImg2Db = async (filelist: FileList) => {
const formdata = new FormData();
formdata.append("title", user.title);
formdata.append("text", user.text);
formdata.append("theme", user.theme);
formdata.append("city", user.city);
if (filelist === undefined || filelist === null) {
const res = await postApi.updateImgAndPost(user._id, formdata);
} else {
for (var i = 0; i < filelist.length; i++) {
formdata.append("picture", filelist?.[i]);
}
const res = await postApi.updateImgAndPost(user._id, formdata);
}
};
async function reWriteSubmit(event: FormEvent) { async function reWriteSubmit(event: FormEvent) {
event.preventDefault(); event.preventDefault();
try { try {
if (confirm("게시물을 수정하시겠습니까?") == true) {
setError(""); setError("");
// console.log("user data", user);
console.log("user data", user);
if (postingFormMatch(user) === true) { if (postingFormMatch(user) === true) {
setLoading(true); setLoading(true);
const res = await postApi.updating(user); if (file) {
const res = updateImg2Db(file);
console.log("clear", res); // console.log(res);
}
navigate("/board", { replace: true }); navigate("/board", { replace: true });
setSuccess(true); setSuccess(true);
setError(""); setError("");
} }
} else {
return false;
}
} catch (error) { } catch (error) {
console.log("에러발생"); console.log("에러발생");
catchErrors(error, setError); catchErrors(error, setError);
...@@ -57,17 +91,46 @@ export function EditPost() { ...@@ -57,17 +91,46 @@ export function EditPost() {
} }
} }
const handleInputPic = async (event: React.ChangeEvent<HTMLInputElement>) => {
const maxImg = 10;
const { files } = event.target;
if (!(files === null)) {
setFile(files);
}
if (!(files?.length === undefined)) {
if (files?.length <= maxImg) {
for (var i = 0; i < files.length; i++) {
const reader = new FileReader();
reader.readAsDataURL(files?.[i]);
reader.onload = (e) => {
imgArr.push(e.target?.result);
setImgSrc(imgArr);
};
}
} else {
alert(`사진은 최대 ${maxImg}장까지 업로드 가능합니다!`);
}
}
};
function postingFormMatch(user: PostType) { function postingFormMatch(user: PostType) {
if (!isLength(user.title ?? "", { min: 1 })) { if (!isLength(user.title ?? "", { min: 1 })) {
setError("제목을 입력해 주세요."); setError("제목을 입력해 주세요.");
alert("제목을 입력해 주세요.");
return false; return false;
} else if (!isLength(user.text ?? "", { min: 1 })) { } else if (!isLength(user.text ?? "", { min: 1 })) {
alert("내용을 입력해 주세요.");
setError("내용을 입력해 주세요."); setError("내용을 입력해 주세요.");
return false; return false;
} else if (equals(city, "city")) { } else if (equals(user.city, "city")) {
alert("도시를 선택해 주세요.");
setError("도시를 선택해 주세요."); setError("도시를 선택해 주세요.");
return false; return false;
} else if (equals(theme, "theme")) { } else if (equals(user.theme, "theme")) {
alert("테마를 선택해 주세요.");
setError("테마를 선택해 주세요."); setError("테마를 선택해 주세요.");
return false; return false;
} else { } else {
...@@ -119,7 +182,7 @@ export function EditPost() { ...@@ -119,7 +182,7 @@ export function EditPost() {
id="files" id="files"
type="file" type="file"
multiple multiple
// onChange={handleInputPic} onChange={handleInputPic}
className="hidden" className="hidden"
/> />
<label htmlFor="files" className="text-xs mt-1.5 ml-1 "> <label htmlFor="files" className="text-xs mt-1.5 ml-1 ">
...@@ -132,14 +195,14 @@ export function EditPost() { ...@@ -132,14 +195,14 @@ export function EditPost() {
name="city" name="city"
className="border-2 border-sky-400 rounded-full w-20 text-xs" className="border-2 border-sky-400 rounded-full w-20 text-xs"
onChange={cityChange} onChange={cityChange}
defaultValue="질문종류" defaultValue={post.city}
> >
<option value="질문종류">도시</option> <option value="city">도시</option>
<option value="Seoul">서울</option> <option value="Seoul">서울</option>
<option value="Busan">부산</option> <option value="Busan">부산</option>
<option value="Incheon">인천</option> <option value="Incheon">인천</option>
<option value="Daegoo">대구</option> <option value="Daegu">대구</option>
<option value="Kwangjoo">광주</option> <option value="Gwangju">광주</option>
<option value="Daejeon">대전</option> <option value="Daejeon">대전</option>
<option value="Woolsan">울산</option> <option value="Woolsan">울산</option>
<option value="Sejong">세종</option> <option value="Sejong">세종</option>
...@@ -153,9 +216,9 @@ export function EditPost() { ...@@ -153,9 +216,9 @@ export function EditPost() {
name="theme" name="theme"
className="border-2 border-sky-400 rounded-full w-20 text-xs" className="border-2 border-sky-400 rounded-full w-20 text-xs"
onChange={themeChange} onChange={themeChange}
defaultValue="질문종류" defaultValue={post.theme}
> >
<option value="질문종류">테마</option> <option value="theme">테마</option>
<option value="cycling">사이클링</option> <option value="cycling">사이클링</option>
<option value="surfing">서핑</option> <option value="surfing">서핑</option>
<option value="activity">액티비티</option> <option value="activity">액티비티</option>
...@@ -174,9 +237,9 @@ export function EditPost() { ...@@ -174,9 +237,9 @@ export function EditPost() {
<div className="flex w-20"> <div className="flex w-20">
<button <button
type="submit" type="submit"
className="border-2 border-sky-400 rounded-full w-20 text-xs text-center transition ease-in-out delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-sky-300 duration-300" className="border-2 border-sky-400 rounded-full w-20 text-xs text-center transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-sky-300 duration-300"
> >
글쓰기 수정
</button> </button>
</div> </div>
</div> </div>
...@@ -190,9 +253,14 @@ export function EditPost() { ...@@ -190,9 +253,14 @@ export function EditPost() {
/> />
<div className="flex flex-col mt-1 mb-1"> <div className="flex flex-col mt-1 mb-1">
<div className="flex gap-x-2 h-48 overflow-x-scroll"> <div className="flex gap-x-2 h-48 overflow-x-scroll">
{/* {imgSrc?.map((img, i) => ( {filesList?.map((file, i) => (
<img key={i} src={img} width={200} height={200} /> <img
))} */} key={i}
src={"http://localhost:3000/images/" + file.newfilename}
width={200}
height={200}
/>
))}
</div> </div>
</div> </div>
<textarea <textarea
......
import React, { MouseEvent } from "react"; import React, { MouseEvent, useEffect, useState } from "react";
import { useLocation, useNavigate, Link, Outlet } from "react-router-dom"; import { useLocation, useNavigate, Link, Outlet } from "react-router-dom";
import { catchErrors } from "../helpers";
import { postApi } from "../apis"; import { postApi } from "../apis";
import { PostType } from "../types"; import { PostType } from "../types";
...@@ -7,17 +8,54 @@ export interface PostState { ...@@ -7,17 +8,54 @@ export interface PostState {
state: PostType; state: PostType;
} }
export interface FileType {
id: string;
post: string;
originalfilename: string;
newfilename: string;
picturepath: string;
}
export interface FilesList {
filesList: FileType[];
}
export function IntoPost() { export function IntoPost() {
const location = useLocation() as PostState; const location = useLocation() as PostState;
const post = location.state; const post = location.state;
const navigate = useNavigate(); const navigate = useNavigate();
const [filesList, setFilesList] = useState<FileType[]>();
// console.log(post); // console.log(post);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [addSuccess, setAddSuccess] = useState(false);
const [delSuccess, setDelSuccess] = useState(false);
useEffect(() => {
getFilesList(post._id);
console.log("newfilename", filesList?.[0].newfilename);
}, []);
const getFilesList = async (postId: string) => {
const res = await postApi.getFileByPostId(postId);
setFilesList(res);
};
const handleDeleteClick = async (event: MouseEvent<HTMLButtonElement>) => { const handleDeleteClick = async (event: MouseEvent<HTMLButtonElement>) => {
try {
if (confirm("삭제하시겠습니까?") == true) {
const postId = event.currentTarget.id; const postId = event.currentTarget.id;
const res = await postApi.deletePost(postId); const res = await postApi.deletePost(postId);
navigate("/board", { replace: true }); navigate("/board", { replace: true });
console.log("delete post", res); console.log("delete post", res);
} else {
return false;
}
} catch (error) {
console.log("에러발생");
catchErrors(error, setError);
}
}; };
return ( return (
...@@ -29,44 +67,59 @@ export function IntoPost() { ...@@ -29,44 +67,59 @@ export function IntoPost() {
<button <button
id={post._id} id={post._id}
onClick={handleDeleteClick} onClick={handleDeleteClick}
className="border-2 border-sky-300 rounded-full h-8 w-8 text-xs text-center transition ease-in-out delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-red-300 duration-300" className="border-2 border-sky-100 rounded-full h-8 w-8 text-xs text-center transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-red-300 duration-300"
> >
삭제 삭제
</button> </button>
</div> </div>
<div className="w-8"> <div className="w-8">
<Link to="/edit" state={post}> <Link to="/edit" state={post}>
<button className="border-2 border-sky-300 rounded-full h-8 w-8 text-xs transition ease-in-out delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-sky-300 duration-300"> <button className="border-2 border-sky-100 rounded-full h-8 w-8 text-xs transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-sky-300 duration-300">
수정 수정
</button> </button>
</Link> </Link>
</div> </div>
</div> </div>
<div className="flex flex-row h-8 gap-x-1 place-content-between"> <div className="flex flex-col h-16 md:h-8 md:flex-row">
<div className="flex basis-3/6 border-2 border-sky-300 rounded"> <div className="flex basis-1/2 place-content-between h-8">
제목: {post.title} <div className="flex basis-1/2 border-2 border-sky-200 rounded h-8">
</div> 작성자: {post.user.slice(0, 8)}
<div className="flex basis-2/6 border-2 border-sky-300 rounded">
작성자: {post.user}
</div> </div>
<div className="flex basis-2/6 border-2 border-sky-300 rounded"> <div className="flex basis-1/2 border-2 border-sky-200 rounded h-8">
작성일: {post.date} 작성일: {post.date.slice(0, 10)}
</div> </div>
</div> </div>
<div className="flex flex-row h-8 gap-x-1 place-content-start"> <div className="flex basis-1/2 place-content-between h-8">
<div className="flex basis-1/6 border-2 border-sky-300 rounded"> <div className="flex basis-1/3 border-2 border-sky-300 rounded">
도시: {post.city} 도시: {post.city}
</div> </div>
<div className="flex basis-1/6 border-2 border-sky-300 rounded"> <div className="flex basis-1/3 border-2 border-sky-300 rounded">
테마: {post.theme} 테마: {post.theme}
</div> </div>
<div className="flex basis-1/6 border-2 border-sky-300 rounded"> <div className="flex basis-1/3 border-2 border-sky-300 rounded">
조회수: {post.counts} 조회수: {post.counts}
</div> </div>
</div> </div>
</div> </div>
<div className="border-2 border-sky-300 rounded h-48">files</div> <div className="flex flex-row h-8 gap-x-1 ">
<div className="border-2 border-sky-300 rounded h-96">{post.text}</div> <div className="flex w-full border-2 border-sky-200 rounded">
제목: {post.title}
</div>
</div>
</div>
<div className="flex-row border-2 border-sky-400 rounded h-48 gap-x-2 ">
<div className="flex gap-x-2 h-48 overflow-x-scroll">
{filesList?.map((file, i) => (
<img
key={i}
src={"http://localhost:3000/images/" + file.newfilename}
width={200}
height={200}
/>
))}
</div>
</div>
<div className="border-2 border-sky-500 rounded h-96">{post.text}</div>
</div> </div>
</div> </div>
); );
......
...@@ -18,7 +18,7 @@ export default function Post({ handleClick, post }: Props) { ...@@ -18,7 +18,7 @@ export default function Post({ handleClick, post }: Props) {
</button> </button>
</Link> </Link>
</div> </div>
<div className="basis-3/12">{post.date}</div> <div className="basis-3/12">{post.date.slice(0, 10)}</div>
<div className="basis-2/12">{post.counts}</div> <div className="basis-2/12">{post.counts}</div>
</div> </div>
); );
......
...@@ -5,7 +5,6 @@ import equals from "validator/lib/equals"; ...@@ -5,7 +5,6 @@ import equals from "validator/lib/equals";
import { catchErrors } from "../helpers"; import { catchErrors } from "../helpers";
import { PostType } from "../types"; import { PostType } from "../types";
import { postApi } from "../apis"; import { postApi } from "../apis";
import { File } from "formidable";
export default function Posting() { export default function Posting() {
const [city, setCity] = useState<string>("city"); const [city, setCity] = useState<string>("city");
...@@ -41,35 +40,40 @@ export default function Posting() { ...@@ -41,35 +40,40 @@ export default function Posting() {
formdata.append("theme", user.theme); formdata.append("theme", user.theme);
formdata.append("city", user.city); formdata.append("city", user.city);
if (!(filelist === undefined || filelist === null)) { if (!(filelist === undefined || filelist === null)) {
if (filelist.length === 1) {
formdata.append("picture", filelist?.[0]);
const res = await postApi.createFileAndPost(formdata);
} else {
for (var i = 0; i < filelist.length; i++) { for (var i = 0; i < filelist.length; i++) {
formdata.append("picture", filelist?.[i]); formdata.append("picture", filelist?.[i]);
} }
// formdata: post, imgs const res = await postApi.createFileAndPost(formdata);
const res = await postApi.createImgAndPost(formdata); }
} }
// else {
// const res = await postApi.createImgAndPostTable(formdata);
// }
}; };
async function handlePostSubmit(event: FormEvent) { async function handlePostSubmit(event: FormEvent) {
event.preventDefault(); event.preventDefault();
try { try {
if (confirm("게시물을 작성하시겠습니까?") == true) {
setError(""); setError("");
console.log("user data", user); // console.log("user data", user);
if (postingFormMatch(user)) { if (!(imgSrc === undefined)) {
if (postingFormMatch(user, imgSrc)) {
setLoading(true); setLoading(true);
if (file) { if (file) {
const res = sendImg2Db(file); const res = sendImg2Db(file);
console.log(res); // console.log(res);
}
} }
// const res = await postApi.posting(user);
// console.log("서버연결됬나요", res);
navigate("/board", { replace: true }); navigate("/board", { replace: true });
setSuccess(true); setSuccess(true);
setError(""); setError("");
} }
} else {
return false;
}
} catch (error) { } catch (error) {
console.log("에러발생"); console.log("에러발생");
catchErrors(error, setError); catchErrors(error, setError);
...@@ -78,19 +82,27 @@ export default function Posting() { ...@@ -78,19 +82,27 @@ export default function Posting() {
} }
} }
function postingFormMatch(user: PostType) { function postingFormMatch(user: PostType, imgSrc: string[]) {
if (!isLength(user.title ?? "", { min: 1 })) { if (!isLength(user.title ?? "", { min: 1 })) {
alert("제목을 입력해 주세요.");
setError("제목을 입력해 주세요."); setError("제목을 입력해 주세요.");
return false; return false;
} else if (!isLength(user.text ?? "", { min: 1 })) { } else if (!isLength(user.text ?? "", { min: 1 })) {
alert("내용을 입력해 주세요.");
setError("내용을 입력해 주세요."); setError("내용을 입력해 주세요.");
return false; return false;
} else if (equals(city, "city")) { } else if (equals(city, "city")) {
alert("도시를 선택해 주세요.");
setError("도시를 선택해 주세요."); setError("도시를 선택해 주세요.");
return false; return false;
} else if (equals(theme, "theme")) { } else if (equals(theme, "theme")) {
alert("테마를 선택해 주세요.");
setError("테마를 선택해 주세요."); setError("테마를 선택해 주세요.");
return false; return false;
} else if (imgSrc === undefined || imgSrc === null) {
alert("사진을 첨부해 주세요.");
setError("사진을 첨부해 주세요.");
return false;
} else { } else {
return true; return true;
} }
...@@ -160,7 +172,7 @@ export default function Posting() { ...@@ -160,7 +172,7 @@ export default function Posting() {
className="flex flex-col w-96 items-center" className="flex flex-col w-96 items-center"
> >
<div className="flex flex-row h-8 gap-x-1"> <div className="flex flex-row h-8 gap-x-1">
<div className="flex border-2 border-sky-400 rounded-full w-20 place-content-center transition ease-in-out delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-gray-300 duration-300"> <div className="flex border-2 border-sky-400 rounded-full w-20 place-content-center transition delay-150 bg-white-400 hover:-translate-y-1 hover:scale-110 hover:bg-gray-300 duration-300">
<input <input
id="files" id="files"
type="file" type="file"
...@@ -184,8 +196,8 @@ export default function Posting() { ...@@ -184,8 +196,8 @@ export default function Posting() {
<option value="Seoul">서울</option> <option value="Seoul">서울</option>
<option value="Busan">부산</option> <option value="Busan">부산</option>
<option value="Incheon">인천</option> <option value="Incheon">인천</option>
<option value="Daegoo">대구</option> <option value="Daegu">대구</option>
<option value="Kwangjoo">광주</option> <option value="Gwangju">광주</option>
<option value="Daejeon">대전</option> <option value="Daejeon">대전</option>
<option value="Woolsan">울산</option> <option value="Woolsan">울산</option>
<option value="Sejong">세종</option> <option value="Sejong">세종</option>
......
...@@ -5,7 +5,7 @@ import { asyncWrap } from "../helpers"; ...@@ -5,7 +5,7 @@ import { asyncWrap } from "../helpers";
import { postDb, userDb } from "../db"; import { postDb, userDb } from "../db";
import { TypedRequest } from "../types"; import { TypedRequest } from "../types";
export const createImgAndPost = asyncWrap(async (reqExp, res, next) => { export const createFileAndPost = asyncWrap(async (reqExp, res, next) => {
const req = reqExp as TypedRequestAuth<{ userId: string }>; const req = reqExp as TypedRequestAuth<{ userId: string }>;
const { userId } = req.auth; const { userId } = req.auth;
...@@ -16,31 +16,47 @@ export const createImgAndPost = asyncWrap(async (reqExp, res, next) => { ...@@ -16,31 +16,47 @@ export const createImgAndPost = asyncWrap(async (reqExp, res, next) => {
multiples: true, multiples: true,
}); });
form.parse(req, (err, fields, files) => { 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)) { if (Array.isArray(files.picture)) {
for (var i = 0; i < files.picture.length; i++) { for (var i = 0; i < files.picture.length; i++) {
const originalfilename = files.picture?.[i].originalFilename; const originalfilename = files.picture?.[i].originalFilename;
const newfilename = files.picture?.[i].newFilename; const newfilename = files.picture?.[i].newFilename;
const filepath = files.picture?.[i].filepath; const filepath = files.picture?.[i].filepath;
const filesRes = postDb.createFilesRow( const filesRes = await postDb.createFilesRow(
originalfilename, originalfilename,
newfilename, newfilename,
filepath filepath
); );
fileIdArr.push(filesRes);
} }
} // create fileinfos row } else if (!Array.isArray(files.picture)) {
const originalfilename = files.picture.originalFilename;
const newfilename = files.picture.newFilename;
const filepath = files.picture.filepath;
if (!Array.isArray(fields.title)) { const filesRes = await postDb.createFilesRow(
const title = fields.title; originalfilename,
if (!Array.isArray(fields.text)) { newfilename,
const text = fields.text; filepath
if (!Array.isArray(fields.theme)) { );
const theme = fields.theme;
if (!Array.isArray(fields.city)) { fileIdArr.push(filesRes);
const city = fields.city; } // file or one or more
const postRes = postDb.createPostRow({ const postRes = await postDb.createPostRow({
title, title,
text, text,
theme, theme,
...@@ -48,7 +64,8 @@ export const createImgAndPost = asyncWrap(async (reqExp, res, next) => { ...@@ -48,7 +64,8 @@ export const createImgAndPost = asyncWrap(async (reqExp, res, next) => {
date: Date.now(), date: Date.now(),
counts: 0, counts: 0,
user: userId, user: userId,
}); // create posts file: fileIdArr,
});
} }
} }
} }
...@@ -58,18 +75,25 @@ export const createImgAndPost = asyncWrap(async (reqExp, res, next) => { ...@@ -58,18 +75,25 @@ export const createImgAndPost = asyncWrap(async (reqExp, res, next) => {
export const getAllPost = asyncWrap(async (req, res) => { export const getAllPost = asyncWrap(async (req, res) => {
const posts = await postDb.getPosts(); const posts = await postDb.getPosts();
console.log(posts); // console.log(posts);
return res.json(posts); return res.json(posts);
}); });
export const getFiles = asyncWrap(async (req, res) => {
const { postId } = req.params;
// console.log("나는 말하는 고구마.", postId);
const files = await postDb.getFilesByPostId(postId);
return res.json(files);
});
export const addCounts = asyncWrap(async (req, res) => { export const addCounts = asyncWrap(async (req, res) => {
// console.log(req.body);
const { postId } = req.params; const { postId } = req.params;
const { counts } = req.body as { const { counts } = req.body as {
counts: number; counts: number;
}; };
console.log(postId, counts); // console.log(postId, counts);
const updateCounts = await postDb.addOneCount(postId, counts); const updateCounts = await postDb.addOneCount(postId, counts);
...@@ -130,7 +154,7 @@ export const updatePost = asyncWrap(async (reqExp, res) => { ...@@ -130,7 +154,7 @@ export const updatePost = asyncWrap(async (reqExp, res) => {
postId postId
); );
console.log("게시글 수정 후", updatePost); // console.log("게시글 수정 후", updatePost);
return res.json(updatePost); return res.json(updatePost);
}); });
import { Types, ObjectId } from "mongoose";
import { Post, PostType } from "../models"; import { Post, PostType } from "../models";
import { FileInfo, IFileInfo } from "../models"; import { FileInfo, IFileInfo } from "../models";
...@@ -10,8 +11,8 @@ export const createPostRow = async (post: PostType) => { ...@@ -10,8 +11,8 @@ export const createPostRow = async (post: PostType) => {
user: post.user, user: post.user,
date: post.date, date: post.date,
counts: 0, counts: 0,
file: post.file,
}); });
console.log("check", newPostRow);
return newPostRow; return newPostRow;
}; };
...@@ -25,22 +26,18 @@ export const createFilesRow = async ( ...@@ -25,22 +26,18 @@ export const createFilesRow = async (
newfilename: newfilename, newfilename: newfilename,
picturepath: picturepath, picturepath: picturepath,
}); });
return newFileRow; // console.log("check", newFileRow);
return newFileRow._id;
}; };
export const findFile = async (postId: string) => { export const getPosts = async () => {
const fileInfo = await Post.findById({ postId }).populate("file"); const posts = await Post.find({}).sort({ date: -1 });
return fileInfo;
};
export const findFileByPostInfo = async (title: string, usreId: string) => {
const posts = await Post.find({ title: title, userId: usreId });
return posts; return posts;
}; };
export const getPosts = async () => { export const getFilesByPostId = async (postId: string) => {
const posts = await Post.find({}); const files = await Post.findOne({ _id: postId }).populate("file");
return posts; return files?.file;
}; };
export const addOneCount = async (_id: string, counts: number) => { export const addOneCount = async (_id: string, counts: number) => {
...@@ -49,8 +46,6 @@ export const addOneCount = async (_id: string, counts: number) => { ...@@ -49,8 +46,6 @@ export const addOneCount = async (_id: string, counts: number) => {
{ counts: counts }, { counts: counts },
{ new: true } { new: true }
); );
// console.log(newCounts);
return newCounts; return newCounts;
}; };
......
import { model, Schema } from "mongoose"; import { model, ObjectId, Schema } from "mongoose";
export interface IFileInfo { export interface IFileInfo {
originalfilename?: string; originalfilename?: string;
......
...@@ -8,7 +8,7 @@ export interface PostType { ...@@ -8,7 +8,7 @@ export interface PostType {
date: Date | number; date: Date | number;
counts?: number; counts?: number;
user: Types.ObjectId | string; user: Types.ObjectId | string;
file?: Types.ObjectId | string; file?: Array<Types.ObjectId>;
} }
const PostSchema = new Schema<PostType>({ const PostSchema = new Schema<PostType>({
...@@ -38,10 +38,12 @@ const PostSchema = new Schema<PostType>({ ...@@ -38,10 +38,12 @@ const PostSchema = new Schema<PostType>({
type: Number, type: Number,
default: 0, default: 0,
}, },
file: { file: [
{
type: Schema.Types.ObjectId, type: Schema.Types.ObjectId,
ref: "FileInfo", ref: "FileInfo",
}, },
],
}); });
export default model<PostType>("Post", PostSchema); export default model<PostType>("Post", PostSchema);
...@@ -3,14 +3,17 @@ import { postCtrl, authCtrl, fileInfoCtrl } from "../controllers"; ...@@ -3,14 +3,17 @@ import { postCtrl, authCtrl, fileInfoCtrl } from "../controllers";
const router = express.Router(); const router = express.Router();
router.route("/").post(authCtrl.requireLogin, postCtrl.createImgAndPost); router.route("/").post(authCtrl.requireLogin, postCtrl.createFileAndPost);
router.route("/").get(postCtrl.getAllPost); router.route("/").get(postCtrl.getAllPost);
router.route("/files/:postId").get(authCtrl.requireLogin, postCtrl.getFiles);
// router.param("postId", postCtrl.userByPostId);
router router
.route("/:postId") .route("/:postId")
.post(authCtrl.requireLogin, postCtrl.addCounts) .post(authCtrl.requireLogin, postCtrl.addCounts)
.get(authCtrl.requireLogin, postCtrl.getOnePost) .get(authCtrl.requireLogin, postCtrl.getOnePost)
.delete(authCtrl.requireLogin, postCtrl.deleteOnePost) // authenticate .delete(authCtrl.requireLogin, postCtrl.deleteOnePost) // +authenticate
.put(authCtrl.requireLogin, postCtrl.updatePost); .put(authCtrl.requireLogin, postCtrl.updatePost);
router.param("postId", postCtrl.userByPostId); router.param("postId", postCtrl.userByPostId);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment