[토이 투표] 22.07.06 일지

재호·2022년 7월 6일
0

투표글 등록

부트스트랩 데이트피커를 통해 마감일자를 선택할 수 있도록 했고 선택하지 않으면 24시간으로 설정된다. 항목추가 버튼을 누르면 투표 항목을 입력할 수 있는 input 폼이 나타난다. 등록 버튼으로 글에 대한 데이터와 투표 항목 데이터가 모두 저장되도록 했다.

--------------------------board controller---------------------------------
	@GetMapping("/register")
	public String boardRegister(HttpSession session, Model model) {
		log.info("게시글 등록 폼 요청");
		if(loginStat(session)) {
			String email = (String)session.getAttribute("userId");
			model.addAttribute("email", email);
			return "/board/register";
		}else {
			return "redirect:/";
		}
	}
	
	@PostMapping("/register")
	public String boardRegister(BoardDTO boardDTO, HttpServletRequest request) {
		log.info("등록 요청", boardDTO);
		String tempTime = request.getParameter("closetime");
		if(tempTime != null) {
			String str = tempTime + " 00:00:00";
			boardDTO.setClosetime(str);
		}
		
		String[] items = request.getParameterValues("item");
		
		List<VoteItemDTO> list = new ArrayList<>();
		for(String item : items) {
			VoteItemDTO dto = VoteItemDTO.builder().item(item).build();
			list.add(dto);
		}
		
		boardService.registerBoard(boardDTO, list);
		return "redirect:/board/list";
	}
    
--------------------------board service---------------------------------
	@Override // 투표글 등록
	public Long registerBoard(BoardDTO boardDTO, List<VoteItemDTO> itemDTO) {
		//파일 업로드 처리
		//전송 받은 파일을 가져오기
		for(VoteItemDTO item : itemDTO) {
			//image 파라미터의 값을 가져오기
			MultipartFile uploadFile = item.getImage();
			//잔성된 파일이 있다면
			if(uploadFile != null) {
				//원본 파일의 파일 이름 찾아오기
				String originalName = uploadFile.getOriginalFilename();
				String fileName = originalName.substring(originalName.lastIndexOf("\\") + 1);
				
				//파일을 업로드할 디렉토리 경로를 생성
				String realUploadPath = makeFolder();
				
				//업로드 할 파일의 경로를 생성
				String uuid = UUID.randomUUID().toString();
				String saveName = uploadPath + File.separator + realUploadPath 
									+ "/" + uuid + fileName;
				Path savePath = Paths.get(saveName);
				try {
					//파일 업로드
					uploadFile.transferTo(savePath);
					//이미지 경로를 DTO에 설정
					item.setImageurl(realUploadPath + "/" + uuid + fileName);
				} catch (Exception e) {
					log.info(e.getLocalizedMessage());
				}
			}
		}
		
		//마감 시간을 설정하지 않았다면 24시간을 기본값으로 설정
		if(boardDTO.getClosetime() == null) {
			ZonedDateTime nowUTC = ZonedDateTime.now(ZoneId.of("UTC"));
			LocalDateTime currentDateTime = nowUTC.withZoneSameInstant(
											ZoneId.of("Asia/Seoul")).toLocalDateTime();
			LocalDateTime closetime = currentDateTime.plusHours(24);
			String cltime = closetime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
			boardDTO.setClosetime(cltime);
		}

		// Board 정보 DB에 저장
		Long mno = memberRepository.findByEmail(boardDTO.getMember_email()).get(0).getMno();
		boardDTO.setMember_id(mno);
		Board board = dtoToEntity(boardDTO);
		boardRepository.save(board);

		// 투표 항목들 리스트로 변환 후 한번에 DB에 저장
		List<VoteItem> list = new ArrayList<>();
		for(VoteItemDTO dto : itemDTO) {
			VoteItem item = VoteItem.builder().item(dto.getItem())
												.imageurl(dto.getImageurl())
												.board(board).count(0).build();
			list.add(item);
		}
		itemRepository.saveAll(list);

		return board.getBno();
	}

파일 업로드 기능까지 구현해놓긴 했지만 우선순위를 후순위로 두었다.

투표 글 상세보기

폼 형식은 등록 형식과 똑같다. 투표 항목 옆에 득표수가 같이 출력되도록 했고 현재 로그인 중인 유저가 투표를 해당 글에 투표를 한 기록이 있다면 어떤 항목에 투표했는지 표시되도록 했다. 작성자 닉네임 옆에 팔로우 버튼을 통해 팔로우 등록을 할 수 있다. 또한 투표가 1회라도 진행되었다면 수정버튼이 보이지 않도록했고 삭제버튼이 나오도록 했다. 투표의 마감 여부에 따라 투표 버튼이 나타난다.

--------------------------board controller---------------------------------
	@GetMapping("/vote")
	public void vote(BoardDTO dto, Model model) {
		log.info("투표글 상세 조회");
		VoteItemDTO itemDTO = VoteItemDTO.builder().board_num(dto.getBno()).build();
		Long votedItem = itemService.votedItem(itemDTO, dto.getMember_email());
		model.addAttribute("votedItem", votedItem!=null ? votedItem : 0);
		BoardDTO result = boardService.getBoard(dto);
		model.addAttribute("result", result);
		model.addAttribute("closetime", result.getClosetime());
	}

--------------------------board service---------------------------------
	@Override //글 정보 가져오기
	public BoardDTO getBoard(BoardDTO dto) {
		Long bno = dto.getBno();
		Optional<Board> optional = boardRepository.findByIdWithJoin(bno);
		
		if(optional.isPresent()) {
			return entityToDto(optional.get(), 2);
		}
		return null;
	}

게시글 수정


투표가 진행되지 않아 수정이 가능하다면 게시글의 단순한 내용 부터 투표 항목의 삭제나 수정 및 삭제까지 모두 가능하도록 했다. 마감시간도 수정이 가능하다.

--------------------------board controller---------------------------------
	@GetMapping("/modify")
	public void modify(BoardDTO boardDTO, HttpServletRequest request, Model model) {
		log.info("수정 폼 요청");
		List<Long> inoList = new ArrayList<>();
		String[] inos = request.getParameterValues("ino");
		String[] items = request.getParameterValues("item");
		List<VoteItemDTO> list = new ArrayList<>();
		for(int i=0; i<inos.length; i++) {
			VoteItemDTO itemDTO = VoteItemDTO.builder().ino(Long.parseLong(inos[i]))
														.board_num(boardDTO.getBno())
														.item(items[i]).build();
			list.add(itemDTO);
			inoList.add(Long.parseLong(inos[i]));
		}
		int canMod = itemService.canModify(inoList);
		model.addAttribute("canMod", canMod);
		model.addAttribute("boardDTO", boardDTO);
		model.addAttribute("list", list);
	}
	
	@Transactional
	@PostMapping("/modify")
	public String modifyPro(BoardDTO boardDTO, HttpServletRequest request, RedirectAttributes reAttr) {
		String[] inos = request.getParameterValues("ino");
		String[] items = request.getParameterValues("item");
		
		List<VoteItemDTO> itemList = new ArrayList<>();
		for(int i=0; i<items.length; i++) {
			try {
				VoteItemDTO itemDTO = VoteItemDTO.builder().ino(Long.parseLong(inos[i]))
														.item(items[i])
														.board_num(boardDTO.getBno()).build();
				itemList.add(itemDTO);
			} catch (ArrayIndexOutOfBoundsException e) {
				log.info("new item add");
				VoteItemDTO itemDTO = VoteItemDTO.builder()
										.item(items[i])
										.board_num(boardDTO.getBno()).build();
				itemList.add(itemDTO);
			}
		}
		itemService.itemUpdate(itemList);
		boardService.updateBoard(boardDTO);
		
		reAttr.addAttribute("result", "수정성공");
		reAttr.addAttribute("bno", boardDTO.getBno());
		
		return "redirect:/board/result";
	}
	
	@Transactional
	@PostMapping("/delete")
	public String deletePro(BoardDTO boardDTO, RedirectAttributes reAttr) {
		Long res = boardService.deleteBoard(boardDTO);
		if(res != null) {
			reAttr.addAttribute("result", "삭제성공");
		}else {
			reAttr.addAttribute("result", "삭제실패");
			reAttr.addAttribute("bno", boardDTO.getBno());
		}
		return "redirect:/board/result";
	}
	
	@ResponseBody
	@PostMapping("/deleteitem")
	public void deleteItem(@RequestBody VoteItemDTO itemDTO) {
		itemService.deleteItem(itemDTO);
	}

--------------------------board service---------------------------------
	@Override //글 수정
	public Long updateBoard(BoardDTO dto) {
		Board findBoard = boardRepository.findById(dto.getBno()).get();
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		LocalDateTime closetime = LocalDateTime.parse(dto.getClosetime(), formatter);
		findBoard.changeBoard(dto.getTitle(), dto.getDescription(), closetime);
		return dto.getBno();
	}
	
	@Override //글 삭제
	public Long deleteBoard(BoardDTO dto) {
		boardRepository.deleteById(dto.getBno());
		return dto.getBno();
	}

--------------------------item service---------------------------------
	@Override // 수정 가능 여부 체크
	public int canModify(List<Long> itemIdList) {
		boolean canModifyItem = false;
		// 투표 진행 여부 체크
		for(Long id : itemIdList) {
			VoteItem voteItem = itemRepository.findById(id).get();
			long count = detailRepository.countByVoteitem(voteItem);
			// 투표에 참여한 사람이 1명이라도 있는 경우 수정 불가
			if(count > 0) {
				canModifyItem = false;
				break;
			// 아직 투표가 진행되지 않은 경우 수정 가능
			}else canModifyItem = true;
		}
		
		//수정가능
		if(canModifyItem) return 1;
		
		//수정불가
		return 0;
	}
	
	@Override // 투표 항목 수정 처리
	public void itemUpdate(List<VoteItemDTO> itemDTO) {
		for(VoteItemDTO dto : itemDTO) {
			VoteItem item = new VoteItem();
			if(dto.getIno() != null) {
				item = itemRepository.findById(dto.getIno()).get();
			}else {
				dto.setCount(0);
				item = dtoToEntity(dto);
			}
			itemRepository.save(item);
		}
	}
    
    @Override // 투표 항목 삭제
	public void deleteItem(VoteItemDTO itemDTO) {
		itemRepository.deleteById(itemDTO.getIno());
	}

투표 항목을 삭제할 때에는 Ajax 통신을 통해 진행했고 나머지 수정이나 추가 부분은 수정 버튼을 통해 한번에 이루어지도록 했다.

기타

투표 마감 체크를 위해 일정 시간 마다 체크를 해야하지만 토이프로젝트이기에 가볍게 하기 위해 메인 페이지 요청이 들어올 때 마다 글들의 마감 여부를 체크하도록 했다.
또한 메인 페이지에 로그인한 유저의 팔로잉의 게시글들이 보여지도록 하기 위해 구축중이다.

--------------------------main controller---------------------------------
	@Transactional
	@RequestMapping("/")
	public String home(HttpSession session, Model model) {
		log.info("mainpage 요청");
		//투표 마감여부 체크
		boardService.checkClose();
		//인기글 가져오기
		List<BoardDTO> list = boardService.mostPopluar();
		//팔로우 정보 가져오기
		String sessionLogin = (String)session.getAttribute("userLogin");
		if(sessionLogin != null) {
			List<FollowDTO> followList = memberService.getFollow((String)session.getAttribute("userId"));
			model.addAttribute("followList", followList);
			
			List<BoardDTO> boardList = new ArrayList<>();
			for(FollowDTO follow : followList) {
				BoardDTO findBoard = boardService.getFollowerLatest(follow.getMno());
				boardList.add(findBoard);
			}
			model.addAttribute("boadList", boardList);
		}
		model.addAttribute("list", list);
		return "index";
	}
    
--------------------------member service---------------------------------
	@Override //팔로우 처리
	public String followMember(FollowDTO followDTO) {
		Member member = memberRepository.findByEmail(followDTO.getMyEmail()).get(0);
		
		Optional<Follow> opt = followRepository.findByMemberAndYou(member, followDTO.getYou());
		if(opt.isPresent()) {
			return "팔로우중";
		}
		
		Follow follow = Follow.builder().you(followDTO.getYou())
										.member(member).build();
		followRepository.save(follow);
		return "팔로우성공";
	}
	
	@Override //팔로우 가져오기
	public List<FollowDTO> getFollow(String email) {
		Member member = memberRepository.findByEmail(email).get(0);
		List<Follow> list = followRepository.findByMember(member);
		
		List<FollowDTO> result = new ArrayList<>();
		for(Follow follow : list) {
			FollowDTO dto = FollowDTO.builder().fno(follow.getFno())
												.you(follow.getYou())
												.mno(member.getMno())
												.build();
			result.add(dto);
		}
		return result;
	}
    
--------------------------board service---------------------------------
	@Override //팔로워 최근 게시글
	public BoardDTO getFollowerLatest(Long mno) {
		Member member = Member.builder().mno(mno).build();
		Sort sort = Sort.by("bno").descending();
		Pageable pageable = PageRequest.of(0, 1, sort);
		Page<Board> page = boardRepository.findByFollow(member, pageable);
		
		return entityToDto(page.getContent().get(0), 0);
	}

--------------------------board repository---------------------------------
	//팔로워 가장 최근 게시물 조회
	@EntityGraph(attributePaths = {"member"})
	@Query("select b from Board b where b.member=:member")
	Page<Board> findByFollow(@Param("member") Member member, Pageable pageable);

내일은 팔로우 기능을 완성할 계획이다.

Git

https://github.com/JINJAEHO/vote

profile
Java, Spring, SpringMVC, JPA, MyBatis

0개의 댓글