0110 개발일지

Yesol Lee·2022년 1월 11일
0

개발일지 - 2022

목록 보기
6/187

오늘 한 일

  1. controller에서 json 파싱해서 RoleVO 생성
  2. 관련자 출력할 때 VOList 쓰는 경우와 json 쓰는 경우 분기처리
  3. 인물 선택 -> Register -> '수정' 클릭 시 출장 정보, 출장 비용, 출장 관련자 테이블 한꺼번에 업데이트 확인
  4. svn 업데이트 후 로컬 svn 프로젝트에 기존 파일들 추가해서 실행 테스트
  5. btPreview.jsp, selectBtPrevList.do로 출장정보 5개 미리보기

출장 관련자 테이블 업데이트 기능 구현

지난주부터 일주일은 고민한 것 같은 출장 관련자 업데이트 기능을 드디어 구현했다. 관건은 별도 창을 띄워서 인물 검색, 추가 및 삭제 후 그 정보를 부모 페이지에 전달한 후 부모 페이지에서 출장 정보 업데이트 시 한꺼번에 업데이트하는 방법을 찾는 것이었다. 고려해야 했던 사항들은 다음과 같다.

  1. 출장 정보 페이지에서 기존 출장 관련자 정보가 있으면 불러와서 화면에 보여주기
  2. 인물 검색 페이지 열었을 때 기존 출장 관련자 정보 보여주기
  3. 인물 검색 페이지에서 인물 정보 조회, 검색
  4. 인물 검색 페이지에서 새로운 관련자 추가, 기존 관련자 삭제 기능
  5. 인물 검색 페이지의 '추가' 버튼 클릭 시 업데이트 된 관련자 정보 부모 페이지에 전달
  6. 부모 페이지 html에 업데이트 된 관련자 이름 보여주기
  7. 출장 정보 페이지에서 '수정' 버튼 클릭 시 출장/출장비용/출장 관련자 일괄 업데이트

1. 기존 출장 관련자 정보 화면에 보여주기

출장 정보 페이지에 기존 출장 관련자 정보를 보여주는 것은 지금까지 하던 방식대로 db에서 관련자 리스트 조회한 결과를 model.Attribute()에 넣어서 전달했다. 그런데 추후 해당 정보를 DB 저장 없이 추가, 수정, 삭제해야 하는 것을 고려하면 인물 검색 페이지에서 같은 방식으로 (VO 리스트) 값을 받아 처리하긴 어려워보였다. 그래서 인물 검색 페이지를 열 때 관련자 조회 결과를 json으로 바꿔서 전달해주었다.

문제는 인물 검색 페이지를 여는 일이 한 번 이상 일어날 수 있다는 것이었다. 최대 출장자, 결재자, 수신자 3개 타입의 관련자를 추가할 수 있고 한 타입을 여러 번 수정할 수 있어야 했다. 인물 검색 페이지를 처음 열 때는 DB에 있는 정보를 전해주면 되지만, 그 다음부터는 인물 검색 페이지에서 수정한 정보를 다시 전달해줄 수 있어야 했다. 이 부분이 어려워서 많이 고민했는데, 꼼수같지만 boolean 변수인 hasJson을 하나 만들어서 인물검색 페이지를 여는 javascript 함수가 최초 호출되었을 때만 값이 한 번 바뀌도록 했다. hasJson==True 인 경우 출장 관련자가 한 번 이상 수정되어 json이 만들어졌다는 의미이므로 DB 리스트 말고 json을 전달하도록 했다.

/* 직원 검색 dialog 띄우기 */
var hasJson = false;
var openWin;

function openUserSearch(BT_ID, userType) {
  console.log("hasJson = " + hasJson);
  openWin = window.open("<c:url value='/selectUserList.do?BT_ID="+BT_ID+"&USER_TYPE="+userType+"&hasJson="+hasJson+"'/>", "", "width=800, height=800, left=100, top=100");
  hasJson = true;
  console.log("hasJson = " + hasJson);
}

2. 수정한 정보 json으로 만들어 부모 html 요소 value로 전달

인물 검색 페이지에서 수정된 관련자 정보를 json으로 만들었는데, 이걸 다시 기존 페이지로 전달하는 방법도 여러 가지 고민이 많았다. form 등을 사용해 정보를 보낼 수도 있었겠지만 그럼 기존 페이지가 다시 로드될 것을 생각하면 자원 낭비라는 생각이 들었다. 또 팝업창을 띄웠다가 끄면 원래 창이 로드 없이 그대로 있는 것이 사용자 입장에서 더 익숙하다는 판단도 있었다.
출장 정보 생성 시 서버로 값을 전달할 때 btVO를 사용하기 때문에, json String도 쉽게 전달하기 위해 btVO에 json을 저장하기 위한 String 변수를 하나 추가했다. 인물 검색 페이지를 끄면 json을 String으로 바꿔 부모 html form 안의 input:hidden의 value에 넣어준다.

3. controller에서 json파싱하여 DB 업데이트

출장 정보 페이지에서 업데이트 시 btVO의 get()으로 json 문자열을 가져왔다. 어디서 바뀌는지 이유는 알 수 없지만 모든 쌍따옴표가 &quot;로 바뀌어있어서 문자열을 바꿔주는 코드가 따로 필요했다. 원래 json 배열의 json object와 roleVO의 변수명을 맞춰서 바로 변환되게 하고 싶었지만 잘 안되서 그냥 jsonObject의 개별값 중 필요한 것만 가져와 roleVO안에 넣어주었다.
경비 테이블 CRUD와 마찬가지로 1)기존값을 수정하는 경우, 2)기존 값을 삭제하는 경우, 3)새로운 값을 생성하는 경우 3가지 경우의 수가 있어서 bt_role_iduser_id값을 이용해 분기처리 해주었다. bt_role_id의 경우 db에서 auto-increment로 생성된 int값인데 이 값이 null인 roleVO에 대해 분기처리를 하려고 했더니 int는 primitive 타입 데이터라 null이 들어갈 수 없다는 것을 알게 되었다. int형 변수에 값을 할당하지 않으면 0으로 취급된다. id는 1부터 생성되므로 id가 없는 경우 0을 넣어주어서 처리했다.

// javascript list로  roleVO 만들기
String jsonStr = btVO.getSELECTED_USERS();

if (jsonStr.indexOf("&quot;") != -1) {
	jsonStr = jsonStr.replaceAll("&quot;", "\\\""); //vervangt &quot; door "
}
		
if(!jsonStr.isEmpty()) {
	JSONArray jsonArr = new JSONArray(jsonStr);
	
	List<Object> list = jsonArr.toList();
	
	for (int i=0; i<jsonArr.length(); i++) {
    	JSONObject json = jsonArr.getJSONObject(i);
		
        BtRoleVO role = new BtRoleVO();
		
		role.setBT_ID(json.getString("BT_ID"));
		role.setUSER_ID(json.getString("USER_ID"));
		role.setUSER_TYPE(json.getInt("USER_TYPE"));
		
		if(json.getInt("BT_ROLE_ID")!=0) { // 기존 값
			role.setBT_ROLE_ID(json.getInt("BT_ROLE_ID"));
            
			if(role.getUSER_ID().isEmpty()) { 
				btService.deleteBtRole(role); // role 삭제
			} else {
				btService.updateBtRole(role); //role 수정
			}
		} else {
			btService.insertBtRole(role); // role 생성
		}
	}

svn 로컬 프로젝트 파일 추가


svn 업데이트한 로컬 프로젝트에 지금까지 만든 파일들을 넣어주었다. 전자정부프레임워크 tiles 라이브러리를 사용한 구조에 내 파일을 넣으니 body에 잘 들어가는 것이 신기했다.

메인페이지에 미리보기 테이블 추가

메인페이지는 내가 만든 출장 정보 게시판을 비롯해 다른 분들의 게시판으로 이동할 수 있는 통로 역할을 한다. 예시에 게시판 미리보기로 최신 5개 게시물의 간략한 정보를 보여주는 부분이 있어 나도 만들어 보았다.

btPreview.jsp 만들기

mainPage에 <jsp includ> 방식으로 넣을거라서 btPreview.jsp 파일을 새로 만들어주었다. 기존에 출장 목록 페이지가 있기 때문에 만드는데 오래 걸리지 않았다. 그런데 서버에서 resultList를 받아 뿌려주는 곳에 항상 게시물이 없다고 떴다. 사실 당연한건데 mainpage로 이동할 때 화면에 보여줄 정보를 db에서 가져와 model.Attribute 등을 이용해 전달해주어야 하는데 그 부분을 만들지 않은 것이다.

loginController의 mainPage.do에 내가 필요한 정보 추가하기

원래 기존 출장 목록 조회하던 쿼리를 썼는데 egovMap이 아닌 출장 VO로 정보를 받기 위해 미리보기용 새로운 쿼리 및 mapper 메소드를 추가했다. controller의 mainPage로 이동하는 메소드 안에서 정보를 전달해준 후 preview 페이지에서 받아주니 정보가 잘 떴다.

<!-- SQL.xml -->
<select id="selectPrevBtList" resultType="btVO">

  SELECT
  BT_ID,
  TRIP_START_DATE,
  TRIP_END_DATE,

  (SELECT GROUP_CONCAT(EMP.EMP_Name SEPARATOR ', ')
  FROM BUSINESSTRIP_ROLES AS BTR
  JOIN EMPLOYEE AS EMP ON EMP.EMP_NO = BTR.USER_ID
  WHERE BTR.BT_ID = BT.BT_ID
  AND BTR.USER_TYPE = 0) AS TRAVELER_NAME

  FROM BUSINESSTRIP AS BT
  ORDER BY CREATED_AT DESC
  LIMIT 5
</select>
// loginController.java
@RequestMapping(value = "/MainPage.do")
public String Mainpage(@ModelAttribute("searchVO") NoticeBoardVO searchVO, ModelMap model) throws Exception {

	List<?> NoticeboardList = noticeboardService.selectPreview(searchVO );		
	model.addAttribute("resultList", NoticeboardList);
		
    // 추가한 부분
	List<BtVO> btList = btService.selectPrevBtList();
	model.addAttribute("btList", btList);
		
	return "/noticeboard/MainPage";
}
<!-- BtPreview.jsp -->
<tbody>
  <c:if test="${empty btList}">
    <td class="no_content" colspan="6">게시글이 없습니다</td>
  </c:if>

  <c:forEach var="bt" items="${btList}" varStatus="status">
    <tr>   
      <td>
        <a href="javascript:fn_egov_select('<c:out value="${bt.BT_ID}"/>')"><c:out value="${bt.TRAVELER_NAME}"/></a>
      </td>
      <fmt:formatDate var="startDate" value="${bt.TRIP_START_DATE}" pattern="yyyy-MM-dd"/>
      <fmt:formatDate var="endDate" value="${bt.TRIP_END_DATE}" pattern="yyyy-MM-dd"/>
      <td><c:out value="${startDate} ~ ${endDate}"/></td>
    </tr>
  </c:forEach>


</tbody>
profile
문서화를 좋아하는 개발자

0개의 댓글