jungtaeyeon / workcongw Goto Github PK
View Code? Open in Web Editor NEWWorkCon 그룹웨어 프로젝트
WorkCon 그룹웨어 프로젝트
일정관리 기능에서 일정 조회시 권한 별로 셀렉 결과가 달라야 하는데
기존에는 이런 권한별 셀렉을 생각하지 못했다
예상했던 정상적인 결과가 어떤 것이었는지 설명해주세요
개발1팀 부장 -> 개발부 일정, 개발부에 속한 모든 하위팀 일정
개발2팀 김사원 -> 개발부 일정, 개발2팀 일정
이런식으로 부서장이면 부서의 모든 일정을 확인할 수 있어야 하고,
일반 직원 이라면 자신이 속한 부서의 일정과 자신이 속한 팀의 일정만 확인 가능해야 한다
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.addPathPatterns("/common/login")
registry.addInterceptor(new LoginInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/common/login", "/common/loginForm", "/resources/**", "/attend/insertStartWorkQR", "/m/home");
}
특정 url로 접근 시 로그인하면 home으로 넘어가야함.
데이터 베이스를 설계하면서, varchar2로 string 타입을 설계했다.
하지만 멘토님은 고정형으로 처리할 수 있는 부분은 고정형으로 처리하는게 좋다고 하셨다. (피드백을 받음)
그래서 사전에 기저에 깔고 가는 타입들은 char를 사용하여 고정시켰다.
개발을 하는데, char형을 정확하게 주지 않고, 넉넉하게 char(2) -> char(10)이런식으로 줬는데, 실질적으로 1~2 더 넉넉하게 줌
근데 이 부분이 스페이스가 패딩되어 에러가 발생했다. 즉 마이바티스에서 받아올 때 view 단에서 관리자 페이지를 분기하는데, 이 부분이 적용되어 아무리 해도 비교가 안 됐다.
처음엔 xml ->vo->service->controller->view 순서로 진행했는데, 아무리 봐도 이상이 없었다.
토드에서 확인해보니, 스페이스만큼 패딩되어 에러가 발생했다. 또한 c02 를 char(3)으로 줬더니 char(10) 이상 잡으라는 오류가 발생했다.
하지만 고정형 타입을 char(1)로 주게 되었는데, y/n이 -> char(1)로 했을 때 읽지 못하는 오류를 발견했다.
개발을 계속 하는데, 길이에 대한 오류가 발생했고, 이에 대해 찾아보니, 실제 데이터의 길이에 따라 1~3의 오버헤드가 발생 된다고 한다.
그리고 오라클 서버 저장 이미지 측면에선 char와 varchar2가 동일하다.
추가적으로 char의 경우 스페이스가 패딩되는 만큼 추가적인 Scan 오버헤드를 유발하므로 성능에서도 손해다.
컨트롤러
@PostMapping("/login")
public String login(String empId, String empPwd,HttpServletRequest request)throws SQLException
{
logger.info(empId);
logger.info(empPwd);
String url = "redirect:./home";
HttpSession session = request.getSession();
logger.info((String)session.getId());
try{
empService.login(empId,empPwd,session);
users.put(empId,session); // users에서 관리하는 이유는 로그인 유저 정보를 조회하기 위해서
}catch(NotFoundIDException|InvalidPasswordException e){
url = "/common/loginForm";
logger.info("여기서 지금 에러가 발생합니다."); // 이 부분은 postHandle에서 txt 파일로 에러관리 시 사용된다.
session.setAttribute("errorType", e); //로그찍을 떄 사용
session.setAttribute("empId", empId);
}
return url;
}
서비스
public EmpVO login(String empId, String empPwd, HttpSession session)throws SQLException, NotFoundIDException,InvalidPasswordException {
EmpVO emp = empDAO.selectEmpById(empId);
if(emp == null)
{
throw new NotFoundIDException(); // 아이디 자체가 없다는 뜻
}
if(!empPwd.equals(emp.getEmp_Pwd())) // 조회된 emp.getEmp_Pwd()값과 empPwd가 같지 않다면,
{
throw new InvalidPasswordException(); // 비밀번호가 다르다는 에러를 던져라
}
session.setAttribute("loginUser", emp);
return emp;
}
분명히 session.setAttribute를 했는데 세션값이 담기지 않는다...ㅠㅠ
Application Session Storage에 담긴다.
기존 add_book_manage 테이블에서 주소록을 공유 한 이후 새로운 주소록을 추가하고
재 공유시 기존의 공유한 데이터의 구분을 판단하는 구분컬럼(share_add_book_manage_yn)을 두었다.
공유를 진행했을시에 1(공유됨) 상태를 두고 공유된 주소록들을 관리중에 문제가 생김.
예를 들어 1그룹에 해당하는 홍길동을 A가 B와C 에게 공유 이후 B가 공유받은 주소록을 삭제 후 재공유를 요청하게되면
B에겐 이전에 공유했던 데이터를 못보내는 문제가 발생.
상태값을 0,1로만 두지 말고 3,4자리를 두어 여러 상태값을 체크할수있도록 컬럼 수정
각 자리의 숫자들에게 의미를 부여 ex)그룹존재여부, 몇번째그룹멤버인지, crud상태값
각 부여한 숫자들로 여러 상태를 구분 지을수 있어서 좋고 기존 이슈뿐만 아니라 다른 상태값을 필요로한 코드에도 적용할 수 있을거같다.
기존 메뉴 ERD 설계
Header 부분을 비동기적으로 처리 했음
사이드바를 고정하려 했지만, @woohyungkang 님이 서브 메뉴를 Ajax로 처리하고 데이터베이스를 설계하는 부분에 대한 건의가 있었음
만약 Ajax를 사용하여 처리한다면, 깊이가 깊어질 수 있지만 권한 관리에 대한 부분도 처리할 수 있는 장점이 있었고, 테이블을 같이 설계했음
화면정의서
MENU 테이블 : Home 화면에서 나타나는 헤더 부분. 이 부분도 비동기적으로 처리하기 때문에 MCODE(PK)를 복합키로 구성한 SUB_MENU테이블을 설계
하위 메뉴를 나타날 떈, 셀프조인
을 사용하여 값을 Select 할 예정
아직 VO 설계는 하지 않았기 때문에 VO 설계 관련 부분은 추후 Commit 예정
기존에는 우리 프로젝트의 조직도는 부서에도 직원이 들어가고, 팀에도 들어가있었다
그래서 권한별 등록은 생각하지 않고 DEPT_ID를 가져와서 해당 속한 부서 또는 팀 일정을 등록할 . 수있었는데,
팀에만 직원이 들어 있고 부서는 팀을 품고있는 구조로 변경하였다
그래서 일정을 등록하는 기능에도, 부서장만 부서의 일정 등록이 가능하고, 부서장은 해당 부서의 하위팀 일정은 모두 등록할 . 수있도록
변경해야 하는 문제가 생겼다
개발1팀 부장 김기백 : 개발부, 개발부 모든 하위팀 일정 등록
개발2팀 차장 오상식 : 개발2팀 일정 등록
쉽게 말해 부서장이면 해당부서에 속해있다면 어떤 팀이던 등록이 가능해야하고, 팀원은 해당 팀의 일정등록만 가능해야한다
마이페이지 이미지 처리 구현 시 액박이 떨어지는 문제
@PostMapping("/profile")
public String updateProfile(@RequestParam("profileImage") MultipartFile profileImage, @SessionAttribute("loginUser")EmpVO empVO, RedirectAttributes attr, HttpSession session) throws IOException, IllegalStateException
{
logger.info("config : "+ config);
logger.info("profileImage :" + profileImage);
logger.info("profile Controller 들어오니?");
logger.info(config.getUploadPath());
String webPath = config.getUploadPath();
logger.info("updateProfile : " );
int result = homeService.updateProfile(profileImage, webPath,empVO);
logger.info("result :" + result);
String url = "common/mypage/modifyform";
String message = null;
if(result > 0)
{
message = "프로필 이미지가 변경되었습니다.";
}
else{
message = "프로필 변경 실패";
}
attr.addFlashAttribute("message",message);
return url;
}
public int updateProfile(MultipartFile profileImage, String webPath, EmpVO empVO)throws IOException, IllegalStateException {
logger.info("profile Service updateProfile 들어오니?");
String temp = empVO.getEmp_Picture(); // 이전 이미지 저장
logger.info(temp);
String rename = null;
if(profileImage.getSize() > 0) // 업로드된 이미지가 있을 경우
{
rename = fileRename(profileImage.getOriginalFilename(), empVO);
logger.info(rename);
logger.info("if : profileImage 사진이 있을 때");
//바뀐 이름 저장
empVO.setEmp_Picture(webPath+rename);
}
else{ // 없는 경우
empVO.setEmp_Picture(null); //세션이미지를 null로 변경해서 삭제한다.
logger.info(" else : profileImage 사진이 없을 때");
}
int result = homeDAO.updateProfile(empVO);
if(result > 0) // 성공했을 경우
{
if(rename != null) // 새 이미지가 업로드 된 경우
{
if(empVO.getEmp_Picture()!= null && webPath != null)
{
profileImage.transferTo(new File(rename));
}
}////////////end of if/////////////
}//////////////////////////end of if /////////////////////////////
else{ // 실패한 경우
empVO.setEmp_Picture(temp); // 이전 이미지로 다시 세팅
}/////////////////////////end of else /////////////////////////////
return result;
}
public static String fileRename(String originFileName, EmpVO empVO) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
String date = sdf.format(new java.util.Date(System.currentTimeMillis()));
int ranNum = (int) (Math.random() * 100000); // 5자리 랜덤 숫자 생성
String str = "_" + String.format("%05d", ranNum);
String ext = originFileName.substring(originFileName.lastIndexOf("."));
return empVO.getEmp_Id()+empVO.getEmp_Name()+date + str + ext;
}
<update id="updateProfile">
UPDATE EMP SET EMP_PICTURE = #{emp_Picture} WHERE EMP_ID = #{emp_Id}
</update>
Not allowed to load local resource: file:///C:/Users/Ohjihwan/Desktop/ProjectTest/%EB%A7%88%EC%9D%B4%ED%8E%98%EC%9D%B4%EC%A7%80/WorkConGW/src/main/webapp/pds/empPicturee001%EC%98%A4%EC%A7%80%ED%99%982024-01-25-16-01-20_66386.jpg
이미지 변경을 누르면 사원에 맞는 이미지가 노출되고 디비에 저장된 값도 변경
어떤 버그인지 간결하게 설명해주세요
조직도(treeView)를 jsp페이지로 바로 호출했을 때는 정상적으로 동작하지만
ajax로 조직도(treeView) 페이지 내 데이터를 모달창으로 넣어서 호출했을 때, jQuery 및 스크립트를 정상적으로 읽어오지 못하는 현상.
조직도 모달창 종료 후 재클릭 시, 모달창 미노출
아래와 같이 작성해주세요
예상했던 정상적인 결과가 어떤 것이었는지 설명해주세요
메뉴바에 "조직도" 클릭 시, 노출되는 모달창에서도
jsp페이지를 바로 호출했을 때 처럼 jQuery 및 스크립트를 정상적으로 읽어와야 한다.
조직도 모달창 종류 후 메뉴바 "조직도" 재클릭 시, 모달창이 정상적으로 열려야 한다.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.