개발하는 삶

'다이어트 관리 웹' 팀프로젝트 [3차] - 스프링으로 게시판 페이지 만들기 본문

프로젝트&회고/프로젝트

'다이어트 관리 웹' 팀프로젝트 [3차] - 스프링으로 게시판 페이지 만들기

삶_ 2022. 10. 28. 06:51

 

전 게시물 : 1차 프로젝트 일지 ▼

https://xmclsdhfkrrhks.tistory.com/99?category=578648

 

전 게시물 : 2차 프로젝트 일지 ▼

https://xmclsdhfkrrhks.tistory.com/103?category=578648

 

 

 

팀 프로젝트

  • 프로젝트명 : 0칼로리
  • 기술 스택 : Spring, Java, JSP, Ajax, Javascript, 카카오맵API연동, 날씨공공데이터연동, 외부라이브러리( jQuery, Chart.js), DBMS(Oracle), CSS3, HTML5
  • 개발 환경 : Eclipse, JDK 11.0.15, Apache Tomcat 9.0, Maven
  • 개발 기간 : 2022.10.02 ~ 2022.10.26 (1주~3주)
  • 제작 인원 : 6명 (팀장)
  • 맡은 역할 : 로그인, 회원가입, 아이디/비밀번호찾기, 고객센터 게시판 CRUD/답글, 검색, 페이징, 좋아요/싫어요, 댓글/답글 등
  • 목표 : 다이어트 관리 웹 애플리케이션 개발
    • 수업시간에 배운 스프링 오라클DB 지식을 활용해 게시판 CRUD 기능을 활용하는 프로젝트이다
    • 각자 맡은 역할
      • 나 : 로그인, 회원가입 기능 (클릭시 페이지 이동, 유효성검사까지), 고객센터 게시판 (CRUD 기능)
      • 팀원A : 캘린더 기능 (달력에 날짜마다 할일 일정 CRUD(수정/삭제/추가) 기능 넣기), 마이페이지
      • 팀원B : 캘린더 기능 (웹페이지 전반 css, 달력 CRUD 기능), 마이페이지 css
      • 팀원C : 마이페이지 - 회원정보 변경 (프로필 사진 변경 기능 빼고)
      • 팀원D : 커뮤니티 게시판 - 게시판 CRUD
      • 팀원E : 캘린더 내 회원 검색 구현

 

 

 

깃헙 주소 (코드 보기)

 

 

 

배운 점

  • ajax 기능 활용
    • 회원 가입시 필수 항목
      • 2차 프로젝트 때, 회원 가입에 적는 본인정보는 개인의 사생활과 보안에 연관이 있기 때문에 미입력 사항도 포함되어야한다는 피드백을 받았다. 따라서 필수값만 컨트롤러에 넘겨, 유효성 검사가 체크되면 @Responsebody 로 ajax의 success 부분에 "통과" 문자열 값을 보내 메인페이지로 이동할 수 있게했다.
      • 비밀번호에 spring security 기능을 이용해 암호화를 걸었다. 안에 내장된 클래스를 통해 암호화를 걸어 DB에 저장하고, 후에 로그인 시 사용자가 입력한 비밀번호와 암호화된 비밀번호를 비교해 boolean 값을 출력해준다. 이 또한 @Responsebody 로 값이 잘 전달되었는지 확인했다.
      • 대부분은 3차 프로젝트로 넘어오며 form-submit 보다는 ajax로 값을 넘겨주었다. 게시물을 작성하거나 회원가입을 할 때 첨부파일 기능이 들어가 있어 formdata들을 담아도 ajax로 넘겨주었다.
    • 서버와 클라이언트를 통한 값 검사
      • 회원가입시 클라이언트 단에서(자바스크립트) 유효성 검사를 마치고, 거르지 못한 값이 없도록 서버 단에서도(자바) 유효성 검사를 해주었다.
      • 유효성 검사 하는 방법이 사람마다 다르지만 숫자와 영문자가 포함되게 할 때 한줄에 유효성 검사를 다 할 수 있게 코드를 작성했는데 가끔 테스트 시 인식하지 못하는 경우가 있었다. 그래서 코드가 좀 길어지더라도 숫자, 영문자 따로 검사할 수있게 했는데 더 정확하게 할 수 있어서 결과적으로 좋았다.

 

	@ResponseBody
	@PostMapping(path="/joinComplet", produces="application/text;charset=utf-8")
	public String postJoinComplet(
			HttpServletRequest request,
		// 값 불러오기 (생략)
        ...
		// 필수값 유효성 검사
		String msg = m_service.testMember(m_dto); 
		if (msg.equals("통과")) {
			// 유효성 검사 일치할 때 회원정보 추가
			m_dto.setPw(pwd);
			m_service.addMember(m_dto);
			System.out.println("회원가입 성공");
		} else {
			// 유효성 검사가 일치하지 않을 때
			System.out.println("회원가입 실패");
		}
		// 결과 값 전달
		return msg;
	}

 

 

  • 협업의 중요성
    • 깃헙 활용하기
      • gitignore를 잘 작성하는 게 중요하다. 각자 작업하는 폴더명도 다르고 특히 settings 파일을 건드리면 파일이 제대로 실행되지 않는 일이 있었다. 프로젝트의 path 명이 'all' 이었는데 처음에 세팅 파일을 만들때 Web Project Settings 를 controller (수정하지 않으면 디폴트값)으로 저장하는 바람에 모든 팀원이 일일이 파일을 클론할 때마다 수정해야 했기 때문이다. 프로젝트의 properties 에서 수정해도 깃에서 클론할 땐 반영이 안되서 해결법을 찾다가 settings 파일 속 org.eclipse.wst.common.component 에 property 명이 context-root 인 value를 all로 수정했다. 다만 이건 프로젝트 폴더를 all로 했을때에만 잘 실행되서 다른 방법을 찾았다. target 폴더는 잘 쓰지 않지만 커밋할때마다 자동으로 올라가 있어서 보니 각자 파일작업을 하면 작업한 폴더 경로가 올라가있었다. 그리고 그 안에 artifactId 가 all로 되어있는지 체크했다. 이 부분이 pom.xml의 프로젝트명 artifactId 과 일치해야해서 처음부터 프로젝트를 만들 때 패스명을 잘 생성해야겠다고 다짐했다.
      • 또 gitignore가 프로젝트 파일 밖에 있어야하는데, 팀원의 프로젝트 파일 속에 gitignore을 만들어놔서 잘못 커밋되는 경우가 있었다. 그래서 블로그 등에 참고된 gitignore에 들어가는 사항들을 위처럼 직접 체험해보며 필요성을 깨달았다.
      • 커밋 할 때 스태시를 활용하자. 스태시는 커밋할 파일들을 임시로 백업해주는 기능이다. 커밋한 내용을 push할 때 pull 할 내용이 있으면 알 수 없는 오류가 뜰 때가 있다. 그래서 스태시로 백업해두고 패치한 뒤 pull 할 내용이 있으면 받아주고, 스태시 적용해서 커밋할 목록을 불러온다. 또 팀원을 깃허브 주소에 초대했다고 해서, 유효기간 동안 메일 확인을 안하고 지나면 기록 권한이 사라지기 때문에 이런 기본적인 기능도 잘 알아두어야겠다고 생각했다. 또 깃헙이 서툴러 브랜치 경험을 많이 못한 점이 아쉬웠다.
    • 팀장으로서의 역할
      • 2차 프로젝트보다는 전체적인 회의보다는 개개인에게 신경을 쓰기위해 노력했다. 전보다 기능이 복잡해지면서 잘 못따라오는 팀원이 있었기 때문이다. 이 부분이 우려되서 좀 더 내 개인 작업을 빨리 끝내려고 노력했다. 팀마다 필수로 넣어야 하는 기능이 페이징, 댓글/답글, 검색 등이 있는데 게시판을 만들면서 접할 아주 기본적인 기능들이라 마감 일주일 전에 구현해놓았다. 2차 프로젝트 때 팀원 개개인의 성향을 파악해보니 스스로 질문을 안하고 혼자 오랜시간을 보내는 팀원도 있었기에 더 적극적으로 불편한 점이 없는지 말을 걸었다. 그리고 팀원에게 잘 설명할 수 있을 정도가 되도록 미리 구현한 내용을 복습했다.
      • 팀원에게 도움을 받는 일도 종종 있었다. DB 테이블을 만드는데 게시판 번호에 필요한 시퀀스 기능을 활용하려는데 시퀀스를 보통 어떻게 생성하는지 블로그를 봐도 잘 이해하지 못한 상태였다. 그 때 미리 시퀀스를 만들어 본 팀원분이 자신의 짠 쿼리문으로 '시퀀스는 연속적인 값을 생성해주고, 테이블을 시퀀스라는 고유값으로 불러오기 편하다' 고 설명해주신 적이 있는데 크게 도움이 되었다.
    • 오류 테스트의 중요성
      • 오류가 있을 경우에 깃에 커밋을 하지 않는 게 중요한데, 같이 공유하는 파일이기 때문이다. 하지만 미처 발견해지 못했던 오류를 뒤늦게 알게되는 경우가 있다. 팀원이 깃을 만지는 동안 다른 팀원이 기다리며 내가 만든 페이지를 테스트 한 적이 있었다. 그 때 게시물 상세보기의 좋아요 기능이 연속적으로 누르면 중복이 발생해서 마이너스값이나 회원당 1개만 허용하는 좋아요 수를 훌쩍 넘는 수를 DB에 저장하게 되어 테이블을 초기화 한 적이 있다. 그래서 ajax로 컨트롤러에 값을 넘길 때 제대로 검사를 안했다는 사실을 깨닫고 다시 값에 제한을 두었다.
      • 중간에 비밀번호 암호화하는 코드를 빠뜨려서 원하는 값으로 db에 저장이 안된경우도 있었다. 초반에 로그인, 회원가입을 구현하고 고객센터 게시판을 완성한 뒤에 아이디/비밀번호 찾기 기능을 만들었었다. 그런데 오랜만에 회원 정보 관련 컨트롤러를 사용하면서 중간에 바뀐 비밀번호를 암호화해서 저장하지 못한 실수를 발견하지 못했다. 하지만 팀원이 테스트 해준 덕에 바로 바꿀 수 있었다.
  • 효율적인 DB 테이블 작성
    • 테이블 내 우선순위를 정하기
      • 게시물 원글/답글, 댓글/답글을 만드려면 그 내의 원글번호와 우선순위를 적어놓아야 한다. 기본적으로 게시물 원글, 답글순서1, 답글순서2.. 이런식으로 테이블을 보기 좋게 불러와야 하기 때문이다. 일단 원글번호 컬럼을 가진 값으로 테이블을 나열하고, 각 게시물 고유번호를 오름차순으로 하여 가장 먼저 생성된 게시물으로 우선순위를 매기는 것이다. 부가적으로 답글인지 댓글인지 타입을 정해놓는 컬럼도 있으면 좋은 게, 원글이 삭제되면 답글들을 자동으로 삭제하도록 쿼리를 짜는 데 도움이 되었다.
    • DTO를 새롭게 생성하기
      • 페이징 기능을 만들 때 조회수순/좋아요순/최신순으로, 검색기능이 있으면 검색옵션/기간/검색내용으로, 원글/답글 별로 정렬해서 불러와야하는데 그 안에 페이지수/페이지넘김가능여부/게시물목록수 를 체크해야 하다보니 테이블을 합치는 게 복잡하다는 생각이 들었다. 자주 활용할 기능이니 생성자 안에 특정 값을 넣으면 알아서 페이지 속 필수 값들을 세팅해주는 페이징 알고리즘을 짜보았다.
      • 우선 전체 게시물 갯수와 현재 페이지 숫자만 알면 다른 값을 자동으로 구할 수 있어서 전체 게시물 갯수는 count(*) 값을 이용해 불러오고, 게시물 목록이 보이는 현재페이지는 디폴트값으로 1을 두고, 페이지 버튼을 눌렀을 때 달리하게 했다.
      • 아무래도 테이블을 새로 생성하면 controller 부터 dao 문까지 싹다 수정해야하기 때문에 시간이 오래걸려서 혹시나 부수적인 컬럼을 추가해야할 경우 등에 dto를 만들어 db로부터 필요한 내용들만 필드값으로 넣어 활용할 수 있게 하는 것도 괜찮은 방법이라고 생각했다.
public class e_SvPagingViewDTO {
	// 현재 페이지
	private int page_NowBno;
	// 현재 페이지의 시작 번호
	private int page_StartBno;
	// 현재 페이지의 끝 번호
	private int page_EndBno;
	// 페이징에 필요한 필드값 (생략)
    ...
    
	// 전체 게시물 갯수, 현재 페이지로 전체 값 자동 설정
	public e_SvPagingViewDTO(int board_AllCount, int page_NowBno) {
		// 총 게시물 수
		setBoard_AllCount(board_AllCount);
		// 전체 페이지 수
		if (board_AllCount % this.board_NowBnoSize > 0) {
			setPage_AllCount(board_AllCount / this.board_NowBnoSize + 1);
		} else {
			setPage_AllCount(board_AllCount / this.board_NowBnoSize);
		}
		// 현재 페이지 번호
		setPage_NowBno(page_NowBno);
		// 1~5, 6~10. 현재 번호의 맨 뒤 숫자 파악.
		String bno_all = String.valueOf(page_NowBno);
		int bno_end = Integer.parseInt(String.valueOf(bno_all.charAt(bno_all.length()-1)));
		// 페이지 맨 뒤 숫자로 앞뒤 번호 저장하기
        ....// 생략

 

어려웠던 점

  • 팀원에게 지시를 내리는 역할
    • 프로젝트에 적극적으로 임하는 자세
      • 학부생 때 조별과제 경험이 많았고 대부분 팀장을 맡았었지만 팀원과의 트러블이 생길 때 한번에 해결하는 게 쉽지는 않았다. 나는 학원을 취업을 목표로 다니고 있기 때문에 성실히 프로젝트와 수업에 임할 생각이었고 대부분은 나와 같은 마음으로 임할 거라고 생각했다. 따라서 2차 프로젝트 때 회의에 빠지고 팀과제도 적극적으로 참여하지 않는 팀원의 사정을 최종 프로젝트부터는 봐주기 어려웠다. 두 달 전부터 팀의 목표를 누누히 얘기했고, 충분한 시간이 있었기 때문이었다.
      • 팀원 대부분의 불만 사항은 같은 페이지를 만들 때 서로 충돌이 없도록 각자의 역할에 성실히 임하는 약속을 지키지 않는 부분에서 나왔다. 내 역할이 팀장이었으나 나 역시 작업해야하는 분량이 있고 매번 2차 프로젝트 때 처럼 시간을 쏟아 선생님 역할을 할 순 없었다. 아르바이트에 가거나 정말 시간이 없는 팀원은 양해를 해주었다. 하지만 수업 시간에 매번 자고있거나 게임을 하고 핑계를 대며 작업을 해오지 않는 팀원에겐 더 제한적으로 기간을 두고 지시를 내릴 수 밖에 없었다. 2차 프로젝트 때 한번 팀원이 그런식으로 프로젝트를 제대로 마무리 하지 않은 채 파일을 전달해서 다른 팀원이 밤을 새서 작업을 대신 마무리 한 기억이 있었기 때문이다.
      • 선생님처럼 처음부터 끝까지 알려주는 역할이 아닌 4~7일 정도의 마감 기한을 두고 가능한 분량의 작업을 시킨 뒤 동기를 이끌어내도록 유도했다. 그리고 중간에 혼자 시도했으나 해결이 안되는 문제는 질문을 하도록 하고 그에 대한 답변을 해주었다. 3차 프로젝트가 끝났을 때, 이 방법을 잘 실천했던 팀원은 2차 프로젝트 때 게시판 CRUD 기능을 아예 못 만들었었는데, 이제는 게시판 기능에 파일 첨부기능 까지 추가로 열심히 작업하는 모습을 보며 나 또한 뿌듯함을 느꼈다.
    • 스프링 기초 셋팅 파일 만들기
      • 팀 프로젝트엔 팀원이 공유하는 기초적인 세팅 파일이 필요했다. 2차 프로젝트가 끝나고 3차 스프링 프로젝트를 만들기 위해 진행되는 수업 진도가 마무리 되면 마감까지 2주 남짓 남았기에 기간이 촉박하다고 느꼈다. 그래서 팀원들이 작업에 들어가기 쉽게 미리 스프링 프로젝트 셋팅 파일을 만들자는 계획을 세웠고 인프런의 <김영한 스프링 강의>를 들으며 스프링을 예습했다.
      • 먼저 스프링 프로젝트와 서블릿을 이용한 다이내믹 프로젝트와의 차이를 이해해야 했다. 예를들어 jstl 이나 그 외 라이브러리 기능을 불러올 때, lib 폴더에 추가했던 것을 pom.xml 에 문장을 적으면 기능이 자동으로 다운로드 됬다는 점이다. 주로 https://mvnrepository.com/ 사이트에 검색해 찾았다. 그리고 스프링 레거시 프로젝트를 만들면 views 폴더의 jsp 파일을 인식해 컨트롤러에서 간단히 매핑할 수 있다는 점이다. 또 component-scan 을 통한 전체적인 파일 경로 설정 등이 web.xml에 기본적으로 우선 실행 설정된 servlet-context.xml 에 적어놓는 다는 점이다. 그리고 하나의 component-scan 으로 팀원의 폴더를 다 읽을 수 있게 패키지명을 'com.zerocalorie.페이지명.controller' 등으로 통일했다.
      • 주로 유튜브 뉴렉처 강의와 블로그 등에 있는 게시판 만들기를 따라해보면서 감을 익혔고, 인프런 강의를 통해 게시판을 만드는 데 유용한 스프링 애너테이션 등의 이론을 배웠다. 주로 controller ▶ service ▶ dao ▶ mybatis **mapper.xml문들 을 통해 DB와 연결하곤 했는데, controller 은 jsp 뷰단과 연결되어 전체적인 맵핑을 해주고 service와 연결한다. service는 필요할 때 dao를 호출할 수 있으며 db를 사용하지 않지만 controller 내에서 자주 불러와 활용될 장문의 코드 등을 적을 때 사용했다. dao는 db와 직접적으로 연결되는 용도로 사용했다.
      • 이렇게 셋팅파일을 미리 만드니 잘 모르는 팀원에게 설명해주기 편했고, 또 주석도 많이 달아놨었는데 팀원이 자신의 작업 폴더를 만들때 구조를 이해하기 편하다고 했다.
  • 남의 코드 해석해보기
    • ajax로 컨트롤러에 값을 넘긴 뒤 @Responsebody 로 다시 결과값을 자바스크립트에 보낼 때 나는 주로 문자열을 넘겨서 유효성 검사 체크용으로 사용하곤 했는데, 다른 팀원은 List나 map 형태로 값을 넘기는 것을 보았다. 같은 기능을 써도 다른 구현 작업에 쓸 수 있다는 점이 매력적이었고 개인 프로젝트에 꼭 활용해보고 싶다.
    • 주석은 많이 활용할 수록 좋다. 어떤 팀원은 코드에 주석이 없었는데 본인이 스스로 이해하지 못한 상태에서 교재를 보고 그대로 친 경우도 있었기에 같이 해석하는 데 오래걸렸던 코드도 있었다. 나도 아이디/비밀번호 찾기에서 사용한 메일링 기능(ex. 메일로 비밀번호 인증코드 전송)을 구글링하며 내 것으로 만드려고 노력했던 적이 있는데, 일단 같은 메일링 기능을 여러 방법으로 구현한 블로그를 몇개 띄워놓고 공통된 점을 찾으려고 했다. 우선 구글에서 메일링 서비스를 이용할 개인 코드를 받아 자바메일 스프링빈 안에 넣어주고, 보낼 내 구글 이메일 계정을 적는다. 그리고 SimpleMailMessage 기능을 이용해 메일을 받는곳, 내용, 제목을 담았다. 그리고 최종으로 자바메일 스프링 빈이 메일을 보내주는 역할을 한다. 아쉬웠던 점은 메일을 전달하는 속도가 빠르지 않다는 점이다. 이 점을 나중에 또 공부하고싶다.
  • 회의
    • 일주일에 1~2번 회의하기
      • 2차 때보다 팀원의 성향을 더 잘 알기도하고 스프링 프로젝트에 넣어야 하는 기능이 많다보니 개인마다 공부해야 할 시간이 필요해 회의시간을 길게 잡지 않았다. 하지만 꼭 주마다 구현해야하는 각자의 목표를 점검했다. 잘 진행이 안되는 팀원은 회의시간 외에도 직접 찾아가 구현 방법을 알려주거나 어느 정도까지 진도가 나갔는지 점검해 같은 페이지를 공유하는 팀원에게도 서로의 근황을 짧게 공지하는 역할을 수행했다.
      • 팀장으로서 가장 중요시 생각한 건 책임감이다. 나 또한 같은 팀원으로서 같은 목표를 위해 매 수업마다 해야하는 역할 수행도 중요하나 그 외에 서로의 의견이 충돌됬을 때 어떻게 맞춰가냐도 중요한 문제라고 생각했다. 따라서 회의에 잘 참여하지 않거나 소통이 어려운 팀원도 같은 팀이라는 걸 인식하고 책임감을 심어줄 수 있도록 적당한 관심을 두고 작업 진도를 파악하는 것이 중요했다.
    • 팀원의 의견과 조언에 귀기울이기
      • 팀장이 되면서, 팀을 이끌어가는게 부담이 될때가 많았다. 특히 4명에서 6명으로 늘어나고, 3차 프로젝트 때부터 부쩍 어려워진 수업 진도에 힘들어하는 팀원이 많아지면서 웹페이지를 완성할 수 있을지 걱정이 많았다. 팀장이기 때문에 더 책임감을 가져야 되긴 하지만 나 또한 팀원 중 한명이기 때문에 이런 고민도 같이 공유하는 게 맞다고 생각했다. 특히 성실하지 못한 팀원을 어떻게 대해야할지 고민이 많았는데 다행히 팀원이 자기 일처럼 '같이 도와주겠다', '기간을 정해두고 확실히 작업했는지 확인이 필요하다' 며 진심으로 조언해주었고 그 중에 수업 내용이 어려운 팀원에게 조언해주는 고마운 팀원도 있었다. 덕분에 팀 프로젝트 발표 준비를 하며 시간적 여유를 얻고 마음의 부담을 줄일 수 있었다. 

 

 

 

 

구현 화면

로그인

  • 로그인 할 수 있는 페이지
  • 로그인/로그아웃
  • 회원가입이나 아이디/비밀번호 찾기 페이지로 이동 가능

 

  • 아이디/비밀번호 찾기 - 아이디 찾기
    • 이메일 입력 ▶ 해당 이메일의 회원 확인 ▶ 이메일 주소에 해당 회원 아이디 전송

 

  • 아이디/비밀번호 찾기 - 비밀번호 찾기
    • 아이디, 이메일 입력 ▶ 이메일에 인증코드 네자리 전송 ▶ 인증코드 인증 성공 ▶ 비밀번호 변경

 

 

 

회원가입

  • 회원 가입 할 수 있는 페이지 - 필수값, 필수아닌값
    • 필수값 - 아이디, 비밀번호, 닉네임, 이메일, 전화번호, 본인의 키
    • 필수아닌 값 - 이름, 생년월일, 성별, 프로필사진(기본 프로필)
  • 유효성 검사 (통과 안될시 빨간줄의 에러, 회원가입 버튼 클릭 시 에러 메시지. 서버/클라이언트 동시 검사)

 

 

고객센터 게시판

  • 페이징, 검색, 조회수, 좋아요, 파일 첨부(5개 제한) 구현
  • 자주하는 질문(관리자용 글쓰기), 공개 건의함(관리자/회원용 글쓰기)
  • 자주하는 질문 - 게시물 목록 (관리자용 글쓰기)

 

  • 자주하는 질문 - 상세보기
    • 좋아요 (회원당 1번만 가능)
    • 조회수 (회원, 비회원당 하루에 1번만 가능. 자신의 게시물이 아닐경우)
    • 첨부파일 (다운로드 가능)
    • 글수정, 글삭제 (관리자일 경우 가능)

 

  • 자주하는 질문 - 글쓰기
    • 글쓰기 유형 선택 (회원정보관리 or 사이트이용가이드)
    • 제목, 내용, 파일첨부 (최대 5개까지 첨부 가능. 첨부된 파일 삭제/재업로드 가능)

 

  • 공개 건의함 - 게시물 목록
    • 게시물 원글, 답글, 댓글수
    • 최신순/좋아요순/조회수순 나열 (클릭하면 새로고침 후 나열됨)
    • 내가 쓴 글 보기 (내가 쓴 글 보기 페이지로 이동)
    • 글쓰기 (로그인 한 경우 가능)
    • 검색 (전체기간/1일/1주일/1개월, 제목+내용/제목/글작성자, 검색내용입력)

 

  • 공개 건의함 - 상세보기
    • 좋아요/싫어요 (회원당 각각 1개씩 가능)
    • 첨부파일 5개 제한 (다운로드 가능)
    • 댓글/댓글의 답글 (작성자 표시)
    • 답글쓰기, 게시물 수정/삭제 (수정 양식은 '자주하는 질문 - 글 수정' 양식과 같음)

  • 공개 건의함 - 내가 작성한 글
    • 내가 작성한 글을 관리 할 수 있음 (전체선택/선택 삭제)
    • 검색, 페이징 구현

 

 

 

 

erd

  • 회원정보 : 회원의 기본적인 정보가 담김. 회원 번호를 이용해 테이블을 구분.
  • 고객센터 게시판
    • 대표 게시물 : 게시물의 기본적인 정보가 담김. 게시물 번호, 회원번호(글쓴이)로 테이블을 구분.
    • 조회수 : 게시물의 조회수를 체크함. 회원이나 비회원당 1씩 증가. 게시물 번호, 회원번호로 구분.
    • 좋아요, 싫어요 : 게시물의 좋아요, 싫어요를 체크함. 회원당 1씩 증가. (자신의 게시물이 아닐 경우) 게시물 번호, 회원번호로 구분.
    • 댓글 : 게시물의 댓글과 댓글의 답글이 담김. 댓글의 답글은 답글 대상의 닉네임이 담김. 게시물번호, 회원번호로 구분. 댓글 번호로 고유의 번호를 체크하고, 원글 번호로 댓글의 원글 주소를 체크한다.
    • 첨부파일 : 파일의 정보가 담김. 게시물 번호로 구분. 총 5개의 파일 첨부 가능(첨부수 제한)