728x90
반응형

구현

- 기본 프로젝트 목록 Project List 구현 -

 

- Project Management System의 이용자가 참여중인 프로젝트와 사내 전체 프로젝트목록을 띄움
- 참여중인 프로젝트의 제목 클릭 시 해당 프로젝트의 대시보드 화면으로 이동(구현 예정)
- 사내 전체 프로젝트 목록은 검색이 가능함(검색조건: 프로젝트명, 팀명)
- 참여중인 프로젝트는 '참여중'을 띄우고, 그 외의 프로젝트는 '보기'버튼 활성화 및 완료된 프로젝트 표시
  (추후 권한에 따라 '보기'버튼 비활성화/활성화 예정)

 


 

Key Point
@click="함수명()" : 클릭하면 해당 함수 호출
@keyup.enter="함수명()" : 엔터를 누르면 해당 함수 호출 (검색창에 사용하면 유용)

 


 

Back 단
DAO / Mapper(SQL) / Service / Controller
  • DAO (Interface)
import java.util.List;

import org.springframework.stereotype.Repository;

import pms.vo.ProjectVO;

/**
 * 프로젝트 DAO
 * 
 * */
@Repository
public interface ProjectDAO {
	
	// 참여중인 프로젝트 정보
	public List<ProjectVO> projList(int userSn);
	
	// 모든 프로젝트 정보
	public List<ProjectVO> allProjList(ProjectVO project);
	
	// 모든 프로젝트 개수
	public int allProjCnt(ProjectVO project);
}

 

  • Mapper (SQL)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="pms.dao.ProjectDAO">

    <!-- 참여중인 프로젝트 -->
    <resultMap type="project" id="projList"/>
    <select id="projList" parameterType="int" resultMap="projList">
        SELECT 
            p.project_sn AS projectSn,
            p.TEAM_SN AS teamSn,
            p.PROJECT_NM AS projectNm,
            p.PROJECT_CTN AS projectCtn,
            to_char(p.PROJECT_BEG_DT, 'yyyy-mm-dd') AS projectBegDt,
            to_char(p.PROJECT_END_DT, 'yyyy-mm-dd') AS projectEndDt,
            p.PROJECT_COMPLETE_YN AS projectCompleteYn,
            (
                SELECT count(*) 
                FROM PROJECT p1, TEAM t1, "USER" u1
                WHERE 1=1
                AND p1.TEAM_SN = t1.TEAM_SN
                AND t1.TEAM_SN = u1.TEAM_SN
                AND p.PROJECT_SN = p1.PROJECT_SN 
            ) AS personCnt,
            (
                SELECT u2.USER_NM  
                FROM PROJECT p2, TEAM t2, "USER" u2, GRADE g
                WHERE 1=1
                AND p2.TEAM_SN = t2.TEAM_SN
                AND t2.TEAM_SN = u2.TEAM_SN
                AND u2.GRADE_SN = g.GRADE_SN
                AND p2.PROJECT_SN = p.PROJECT_SN
                AND g.GRADE_SN = 666
            ) AS pmNm
        FROM PROJECT p, "USER" u 
        WHERE 1=1
        AND p.TEAM_SN = u.TEAM_SN
        AND p.PROJECT_COMPLETE_YN = 'N'
        AND u.USER_SN = #{userSn}
    </select>

    <!-- 전체 프로젝트 -->
    <resultMap type="project" id="allProjList"/>
    <select id="allProjList" parameterType="project" resultMap="allProjList">
        SELECT 
            p.project_sn AS projectSn,
            p.TEAM_SN AS teamSn,
            p.PROJECT_NM AS projectNm,
            p.PROJECT_CTN AS projectCtn,
            to_char(p.PROJECT_BEG_DT, 'yyyy-mm-dd') AS projectBegDt,
            to_char(p.PROJECT_END_DT, 'yyyy-mm-dd') AS projectEndDt,
            p.PROJECT_COMPLETE_YN AS projectCompleteYn,
            (
                SELECT count(*) 
                FROM PROJECT p1, TEAM t1, "USER" u1
                WHERE 1=1
                AND p1.TEAM_SN = t1.TEAM_SN
                AND t1.TEAM_SN = u1.TEAM_SN
                AND p.PROJECT_SN = p1.PROJECT_SN 
            ) AS personCnt,
            (
                SELECT u2.USER_NM  
                FROM PROJECT p2, TEAM t2, "USER" u2, GRADE g
                WHERE 1=1
                AND p2.TEAM_SN = t2.TEAM_SN
                AND t2.TEAM_SN = u2.TEAM_SN
                AND u2.GRADE_SN = g.GRADE_SN
                AND p2.PROJECT_SN = p.PROJECT_SN
                AND g.GRADE_SN = 666
            ) AS pmNm
        FROM PROJECT p, TEAM t
        WHERE 1=1
        <if test="srhKeywordType != '' and srhKeywordType != null">
            <choose>
                <when test='srhKeywordType == "projectNm"'>
                    AND p.PROJECT_NM LIKE '%'||#{srhKeyword}||'%'
                </when>
                <when test='srhKeywordType == "teamNm"'>
                    AND t.TEAM_NM LIKE '%'||#{srhKeyword}||'%'
                </when>
            </choose>
        </if>
        AND p.TEAM_SN = t.TEAM_SN
    </select>

    <!-- 전체 프로젝트 개수 -->
    <select id="allProjCnt" parameterType="project" resultType="int">
        SELECT 
        COUNT(*) as totCount
        FROM PROJECT p, TEAM t
        WHERE 1=1
        <if test="srhKeywordType != '' and srhKeywordType != null">
            <choose>
                <when test='srhKeywordType == "projectNm"'>
                    AND p.PROJECT_NM LIKE '%'||#{srhKeyword}||'%'
                </when>
                <when test='srhKeywordType == "teamNm"'>
                    AND t.TEAM_NM LIKE '%'||#{srhKeyword}||'%'
                </when>
            </choose>
        </if>
        AND p.TEAM_SN = t.TEAM_SN
    </select>
</mapper>

서브쿼리 결과 변수인 personCnt, pmNm 등은 DB에 저장된 컬럼이 아니다.

객체에 담을 수 있게 VO에만 선언.


ERD 설계 는 아래 글 참고(작성시점 이후로 수정되었으나 글은 수정되지 않음. 전반적인 개요정도만 확인)

https://heisely93.tistory.com/entry/PMS-ERD-%EC%84%A4%EA%B3%84

 

[PMS] ERD 설계

1. 하나의 팀에 여러 명의 사용자 > 팀1 : 사용자多 1-1. 한 명의 사람이 한 팀만 가질 수 있어서 헷갈릴 수 있으나, 사용자 일련번호가 pk이므로 각각의 사용자별로 팀을 설정해 주면 됨 1-2.

heisely93.tistory.com


  • Service
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pms.dao.ProjectDAO;
import pms.vo.ProjectVO;

@Service
public class ProjectService {
	@Autowired(required = false)
	private ProjectDAO dao;
	
	// 참여중인 프로젝트 정보
	public Object projList(int userSn) {
		
		List<ProjectVO> list = dao.projList(userSn);
		Map<String, Object> result = new HashMap<String, Object>();
		
		result.put("list", list);
		
		return result;
	}
	
	// 모든 프로젝트 정보
	public Object allProjList(ProjectVO project) {
		
		List<ProjectVO> allList = dao.allProjList(project);
		int totCount = dao.allProjCnt(project);
		Map<String, Object> result = new HashMap<String, Object>();
		
		result.put("allList", allList);
		result.put("totCount", totCount);
		
		return result;
	}
}

 

  • Controller
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import pms.dao.ProjectDAO;
import pms.vo.ProjectVO;

@Service
public class ProjectService {
	@Autowired(required = false)
	private ProjectDAO dao;
	
	// 참여중인 프로젝트 정보
	public Object projList(int userSn) {
		
		List<ProjectVO> list = dao.projList(userSn);
		Map<String, Object> result = new HashMap<String, Object>();
		
		result.put("list", list);
		
		return result;
	}
	
	// 모든 프로젝트 정보
	public Object allProjList(ProjectVO project) {
		
		List<ProjectVO> allList = dao.allProjList(project);
		int totCount = dao.allProjCnt(project);
		Map<String, Object> result = new HashMap<String, Object>();
		
		result.put("allList", allList);
		result.put("totCount", totCount);
		
		return result;
	}
}

 


 

Front 단
instance / components / jsp
  • projectInfo.js (Vue Instance) - el 설정 및 components들의 초기화 함수 호출
/**
 * project info instance vue
 */

var app = window.app || {};
app.components = app.components || {};

// instance
$(document).ready(function(){
	app.components.projectInfo = new Vue({
		el : '.projectInfo',
		data : {
			
		},
//		components : { // 굳이 명시 안 해줘도 됨!
//			'project-list' : app.components.projList,
//			'all-project-list' : app.components.allProjList
//		},
		mounted() {
			this.init();
		},
		methods : {
			init() {
				this.$refs.projList.init();
				this.$refs.allProjList.init();
			},
			show() {
				$(this.$el).show();
			},
			hide() {
				$(this.$el).hide();
			}
		}
	})
});

 

  • project_info.jsp - 가장 바깥 껍데기
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>pmsPrj</title>
<%@include file="/WEB-INF/pmsPrj/jsp/main/template/common_lib.jsp" %>

<!-- 이 부분이 중요! -->
<script type="text/javascript" src="/pmsProject/pms/js/project/proj/components/allProjList.js"></script>
<script type="text/javascript" src="/pmsProject/pms/js/project/proj/components/projList.js"></script>
<script type="module" src="/pmsProject/pms/js/project/proj/projectInfo.js"></script><!-- vue instance -->
</head>
<body class="hold-transition sidebar-mini layout-fixed">
<!-- header와 footer는 지우고 업로드함 -->
<div class="wrapper">
<!-- Content Body -->
    <section class="content">
        <div class="container-fluid">
            <div class="row">
                <div class="col-12">
                    <div class="card projectInfo">
                        <div class="card-header">
                        	<h2>Project Info</h2>
                        </div>
                        <div class="card-body">

                            <!-- 참여중인 프로젝트 정보 -->
                            <%@include file="/WEB-INF/pmsPrj/jsp/proj/proj/components/proj_list.jsp" %>

                            <!-- 모든 프로젝트 리스트 // 페이징 필요 -->
                            <%@include file="/WEB-INF/pmsPrj/jsp/proj/proj/components/all_proj_list.jsp" %>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
<!-- /.Content Body -->
</div>
</body>
</html>

 

  • projList.js (Vue Components 1)
/**
 * projcet list components (참여중인 프로젝트)
 */

var app = window.app || {};
app.components = app.components || {};

$(document).ready(function(){
	
    app.components.projList = Vue.component('project-list', {
        props : [],
        data : function(){
        	return {
                list : [],
                userSn : ''
        	}
        },
        methods : {
            init() {
            	this.list = [];
           		this.userSn = '999';
            	this.getList();
            },
            getList(){
            	const self = this;

            	const formData = new FormData();

            	formData.append('userSn', self.userSn);
				
                // 서버통신
            	axios.post('/pmsProject/project/getProjList.do', formData).then(function(result){
            		self.list = result.data.list;
            	});
            },
            goDashboard(list) {
            	alert('대시보드 이동 준비중\n' + list.projectSn);
            },
            show() {
            	$(this.$el).show();
            },
            hide() {
            	$(this.$el).hide();
            }
        }
    });
});

 

  • proj_list.jsp - components명으로 감싸고(inline-template 및 refs 선언), div로 한 번 더 감싼 상태에서 작성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
<project-list inline-template ref='projList'>
    <div>
        <div class="card-header">
        	<h2 style="color:blue;">참여중인 프로젝트</h2>
        </div>
        <div class="card-body">
            <div v-for="list in list">
                <table class="table table-bordered table-hover">
                    <tr>
                    	<th colspan="2" @click="goDashboard(list)">{{list.projectNm}} (클릭 시 대시보드로 이동하게 수정예정)</th>
                    </tr>
                    <tr>
                    	<td colspan="2">{{list.projectCtn}}</td>
                    </tr>
                    <tr>
                    	<td>프로젝트 참여기간</td>
                    	<td>{{list.projectBegDt}} <span>~</span> {{list.projectEndDt}}</td>
                    </tr>
                    <tr>
                        <td>PM : {{list.pmNm}} </td>
                        <td>참여인원 : {{list.personCnt}}명</td>
                    </tr>
                </table>
            </div>
        </div>
    </div>
</project-list>

 

  • allProjList.js (Vue Components 2)
/**
 * all project list components (모든 프로젝트 리스트)
 */

var app = window.app || {};
app.components = app.components || {};

$(document).ready(function(){

    app.components.allProjList = Vue.component('all-project-list', {
        props : [],
        data : function(){
            return {
                allList : [],
                srhKeyword : '',
                srhKeywordType : 'projectNm',
                totCount : 0
            }
        },
        methods : {
            init() {
            	this.totCount = 0;
            	this.allList = [];
            	this.srhKeyword = '';
            	this.srhKeywordType = 'projectNm';
            	this.getAllProject();
            },
            getAllProject(){
            	const self = this;
            	const formData = new FormData();

            	formData.append('srhKeyword', self.srhKeyword);
            	formData.append('srhKeywordType', self.srhKeywordType);
				
                // 서버통신
            	axios.post('/pmsProject/project/getAllProj.do', formData).then(function(result){
            		self.allList = result.data.allList;
            		self.totCount = result.data.totCount;
            	});
            },
            show() {
            	$(this.$el).show();
            },
            hide() {
            	$(this.$el).hide();
            }
        }
    });
});

 

  • all_proj_list.jsp - components명으로 감싸고(inline-template 및 refs 선언), div로 한 번 더 감싼 상태에서 작성
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*"%>
<all-project-list inline-template ref='allProjList'>
    <div>
        <div class="card-header">
            <h2 style="color:blue;">전체 프로젝트<span>(전체 {{totCount}}건)</span></h2>
            
            <!-- 검색조건 -->
            <select v-model="srhKeywordType" id="srhKeywordType">
                <option value='projectNm'>프로젝트명</option>
                <option value='teamNm'>팀명</option>
            </select>
            <input type="text" v-model="srhKeyword" id="srhKeyword" @keyup.enter="getAllProject()">
            <button @click="getAllProject()">검색</button>
            <button @click="init()">초기화</button>
        </div>
        <div class="card-body">
            <div v-for="list in allList">
                <table class="table table-bordered table-hover">
                    <tr>
                    	<th colspan="3">{{list.projectNm}}</th>
                    </tr>
                    <tr>
                    	<td colspan="3">{{list.projectCtn}}</td>
                    </tr>
                    <tr>
                        <td>프로젝트 참여기간</td>
                        <td colspan="2">{{list.projectBegDt}} <span>~</span> {{list.projectEndDt}}</td>
                    </tr>
                    <tr>
                        <td>PM : {{list.pmNm}} </td>
                        <td>참여인원 : {{list.personCnt}}명</td>
                        <td>
                            <button v-if="list.projectCompleteYn == 'Y'" class="fr">완료된 프로젝트</button>
                            <button class="fr" @click="$parent.$refs.projList.goDashboard(list)">{{$parent.$refs.projList.list[0].projectSn == list.projectSn ? '참여중' : '보기'}}</button>
                        </td>
                    </tr>
                </table>
            </div>
        </div>
    </div>
</all-project-list>

 


 

실행화면
css 미적용. 단순 기능 확인

 

 

 


 

 

 

End.

heisely's 괴발개발 개발일지

728x90
반응형

'Programming > 구현' 카테고리의 다른 글

[구현] projectSn 세션처리  (0) 2022.04.19
[구현] 사용자 정보(feat. session)  (0) 2022.04.07
[구현] 로그인 화면 구현  (0) 2022.04.07
[구현] ERD 설계  (0) 2022.02.04
[구현] 분석단계 - 준비  (0) 2022.01.24

+ Recent posts