Compare commits

...

181 Commits

Author SHA1 Message Date
aae556a180 연차 로직 변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-07-14 13:57:07 +09:00
7643723f25 로그 path 추가
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-15 15:18:11 +09:00
5516f71bfc f
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-14 13:24:33 +09:00
f1b3f1d953 ee
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-14 10:52:39 +09:00
18cf7d1a62 날씨 메인 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-11 10:18:55 +09:00
a2d57166fc 주석 제거
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-10 23:02:30 +09:00
0d6448bfbf 사원 등록 오류 수정 2025-04-10 23:00:10 +09:00
ac8d637dc2 s
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-10 16:03:38 +09:00
eea2d74c70 d
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-10 16:01:47 +09:00
0850d6d356 사원 등록에서 로그인 세션으로 등록/반려가 아닌 DB의 권한을 가져와서 처리하는 방향으로 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-10 15:22:11 +09:00
163fdb34cb 메인페이지 유저승인 api 변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-10 13:42:05 +09:00
7eaa24e4fc 휴가로직 변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-08 16:16:43 +09:00
71fa90d378 투표쿼리 변경 _메인일때만 2025-04-08 16:03:02 +09:00
0018734679 Merge branch 'khj' into main
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-08 10:52:04 +09:00
8697504d46 용어집 쿼리변경 2025-04-08 10:51:44 +09:00
yoon
aa37231f9b .
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-07 16:48:25 +09:00
yoon
c3cd6b3f5d selectbox 정렬 2025-04-07 16:47:49 +09:00
674ced8c16 사원 등록 쿼리 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-07 11:11:49 +09:00
8c3d5d1310 프로젝트 유저 색상 이름 추가
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-07 09:45:04 +09:00
29d29edaba 메인 페이지 휴가자 조회 쿼리 수정 2025-04-04 23:46:06 +09:00
yoon
8f272ce123 selectbox 2025-04-04 19:22:27 +09:00
yoon
ee1933008f 퇴근 2025-04-04 19:22:18 +09:00
yoon
b6bd7fac4d 승인여부 2025-04-04 15:45:07 +09:00
157eefdb9d 유저인포
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-04 14:19:28 +09:00
abb8a4916a 유저인포 수정 2025-04-04 14:07:44 +09:00
c9a2906e2d Merge branch 'main' of
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
http://192.168.0.251:3000/localnet/localhost-back.git into main
2025-04-04 13:29:07 +09:00
b55d150bc0 사원등록프로세스 추가, 주간 날씨 데이터 전화 프로세스 추가 2025-04-04 13:21:23 +09:00
0a127c35b4 마이페이지
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-04 10:13:56 +09:00
e4956f12b0 Merge branch 'khj' into main
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-04-01 16:18:32 +09:00
eb17f1a14e 투표 용어집 수정 2025-04-01 16:18:08 +09:00
dcb996f50b 메인 게시판 로직 수정 2025-04-01 16:13:04 +09:00
dd31e08c4f 날씨 2025-04-01 14:46:09 +09:00
yoon
a0cac0b987 usercolor 추가
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-31 19:10:05 +09:00
yoon
c73bd6459c NOT_AUTHORIZED 추가 (비인가 계정) 2025-03-31 17:41:06 +09:00
yoon
733a67fffc 따옴표 삭제 2025-03-31 16:35:29 +09:00
66fbd4fdad Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-31 13:14:41 +09:00
92e147a7df 메인 페이지 작업 2025-03-31 13:14:37 +09:00
yoon
a25b751d5e 퇴근위치
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-31 13:03:04 +09:00
yoon
436a4fc49b 출퇴근 로직변경 2025-03-31 12:48:22 +09:00
e45273a9b3 조건변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-28 15:42:18 +09:00
3b0d3b5f44 대체공휴일(~~~~)->대체공휴일
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-28 13:41:42 +09:00
c4e523843e Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-03-28 13:10:19 +09:00
7b2cab5b95 사용자 좋아요 싫어요 상태 내려주는 로직 추가. 2025-03-28 13:10:14 +09:00
fe3081e859 검색어 페이징 수정 2025-03-28 11:09:41 +09:00
fe7afd1d7f 1 2025-03-27 20:01:09 +09:00
yoon
1e7b380777 출근 퇴근 각각 색상 및 프젝이름 2025-03-27 18:53:19 +09:00
yoon
3ef2d8be18 출퇴근 드래그앤드랍 시 업데이트 x
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-27 18:18:50 +09:00
c1351808df 정렬 변경 2025-03-27 14:04:42 +09:00
8351e7a0d7 Merge branch 'khj' into main 2025-03-27 13:10:14 +09:00
373a8c6a5e 투표 쿼리수정 필터링 추가 2025-03-27 13:09:50 +09:00
6f968effdc 게시판
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-27 11:09:47 +09:00
92119be6fa 게시판 삭제 수정 2025-03-27 10:55:57 +09:00
01f936a407 휴가 삭제 수정 2025-03-27 09:56:17 +09:00
yoon
4fdc97fde5 Merge branch 'main' into yoon
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-25 17:46:36 +09:00
yoon
ec7e53b0b6 정렬 2025-03-25 17:46:14 +09:00
yoon
674aaba0ff 프로젝트 참여인원 포함 조회 2025-03-25 17:46:04 +09:00
b0f77138cd 게시판 검색 수정 2025-03-25 15:38:43 +09:00
4241859180 댓글삭제 로직 수정 2025-03-25 14:59:27 +09:00
e099a65006 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-03-25 14:55:32 +09:00
dba1edb701 투표수정 2025-03-25 14:55:26 +09:00
9c1c8621a0 본문에 댓글의 좋아요 싫어요가 반영 안되도록 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-25 11:58:47 +09:00
4ceb2ea128 주석 오타 2025-03-24 23:30:02 +09:00
5991a59e48 용어집 에디터 이미지 파일 매핑 및 삭제 로직 추가
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-24 15:44:28 +09:00
58f7679775 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-03-24 13:57:48 +09:00
dc7ab68fc6 게시판 에디터 이미지 삭제 시 파일 삭제 및 데이터 제거 추가 2025-03-24 13:57:43 +09:00
yoon
54bd9869c1 프로젝트 로직 변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-24 09:46:17 +09:00
38d4c401c3 게시글 정보가 없는 파일 삭제 스케쥴러 생성2 2025-03-24 09:40:22 +09:00
f93676081f Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-03-24 09:25:34 +09:00
f8ebcbd1be 게시글 정보가 없는 파일 삭제 스케쥴러 생성 2025-03-24 09:25:13 +09:00
eb1c4a6961 투표쿼리수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-21 15:08:03 +09:00
59df70ee4c 댓글 삭제시 수정됨 삭제 2025-03-21 13:20:18 +09:00
8568ad84fc 익명 닉네임 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-21 10:53:26 +09:00
fde1520377 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-03-20 16:17:18 +09:00
302efa298c 에디터 첨부 이미지 게시글 번호 업데이트 로직 추가 2025-03-20 16:16:52 +09:00
5f2c4f3bd2 게시판 익명 닉네임 추가 2025-03-20 13:02:50 +09:00
f37a281f6c 공휴일 사용자 지정 추가 2025-03-20 10:14:04 +09:00
yoon
1643a5fc7c Merge branch 'main' into yoon 2025-03-20 10:08:40 +09:00
yoon
ed7623c448 프로젝트 수정 2025-03-20 10:08:18 +09:00
42bb0dd244 휴가 저장로직 수정 2025-03-19 17:45:46 +09:00
ea50617980 ErrorCode 변경 2025-03-18 20:34:27 +09:00
b16008c0d1 handler Error 수정 2025-03-18 20:10:45 +09:00
e411a0a567 게시판 통합검색(작성자,내용,제목) 추가 2025-03-18 15:59:07 +09:00
4d208ae802 댓글/ 대댓글 조회 쿼리 > 수정일 기준에서 작성일 기준 순서로 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-18 10:58:53 +09:00
4f14ef5d53 Merge branch 'khj' into main 2025-03-18 10:27:07 +09:00
49024275a4 투표 쿼리수정 2025-03-18 10:26:42 +09:00
yoon
352dc770ee 콘솔에러 안찍히게 2025-03-18 10:24:13 +09:00
09d656ee5b 수정시 멀티파일 업로드 쿼리 원복
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-17 22:04:53 +09:00
b1028b61c7 공지글 수정 권한 변경(관리자 > 작성자) 2025-03-17 21:49:17 +09:00
ea35ea3082 댓글 최신순 2025-03-17 15:52:21 +09:00
b3e3cc7277 게시판 수정 2025-03-17 15:26:22 +09:00
11550daf6f 대댓글 프로필 이미지 조회 쿼리 추가
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-17 13:57:53 +09:00
6affb7dade Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-17 13:06:58 +09:00
31cad333d1 게시글 수정 페이지 접근 시 비밀번호 확인 2025-03-17 13:06:48 +09:00
ada6654edd 휴가쿼리문 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-17 12:32:16 +09:00
e9f4cb2fc5 Admin 권한 2025-03-17 12:06:33 +09:00
yoon
778ffb5edf 필요없는 import 삭제 2025-03-17 12:04:38 +09:00
yoon
2a730cdf0b Merge branch 'main' into yoon 2025-03-17 12:02:50 +09:00
yoon
606c3c586c 개인참여기간 추가 2025-03-17 12:01:39 +09:00
e7d6db5e94 Merge branch 'khj' into main 2025-03-17 11:13:20 +09:00
920af2adfe Merge branch 'khj' into main 2025-03-17 10:55:14 +09:00
dfca1a9ee2 수정 2025-03-17 10:54:42 +09:00
yoon
558e732f62 Merge branch 'main' of
http://192.168.0.251:3000/localnet/localhost-back.git into main
2025-03-17 09:38:21 +09:00
87bf1c37de 관리자권한부여 2025-03-14 13:16:31 +09:00
yoon
1673ddccac get -> select 변경 2025-03-14 12:12:06 +09:00
yoon
214f4ec8a0 Merge branch 'main' into yoon
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-13 12:14:10 +09:00
yoon
d0f9cefa80 출퇴근 2025-03-13 12:13:31 +09:00
d34fdf1fda 응답용 프로세스 변경 2025-03-13 11:00:45 +09:00
c182f749b8 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-03-13 10:37:23 +09:00
c277eb1a27 응답 처리 변경 2025-03-13 10:37:16 +09:00
yoon
1c42e51664 주석 수정 2025-03-12 21:39:05 +09:00
cae7928017 휴가 쿼리문 수정 2025-03-11 16:14:09 +09:00
f52b5be47c Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-11 12:46:49 +09:00
a125ad3c25 게시글 및 댓글 이미지 조회 프로세스 추가 2025-03-11 12:45:20 +09:00
3d03663896 댓글 삭제 수정 2025-03-11 10:33:37 +09:00
799945e154 게시판 댓글갯수 수정
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-10 15:49:27 +09:00
yoon
0f2777916e Merge branch 'main' into yoon 2025-03-10 15:46:32 +09:00
yoon
e8ae11250e 출퇴근 2025-03-10 15:45:58 +09:00
yoon
eb7b65aed7 연도 불러오기 쿼리 변경 2025-03-10 15:45:50 +09:00
8f3f5901da 댓글 대댓글 조회쿼리 최신순으로 변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-10 11:18:05 +09:00
yoon
b29c2df5e3 사용자가 속한 프로젝트 조회 쿼리 변경 2025-03-10 10:26:39 +09:00
yoon
1326e0e33f Merge branch 'main' into yoon 2025-03-09 20:48:16 +09:00
yoon
fb4c2c2180 사용자가 속한 프로젝트 조회 2025-03-09 20:47:38 +09:00
2a9fc778fb 코드수정 2025-03-07 16:19:11 +09:00
269c80eb95 Merge branch 'khj' into main 2025-03-07 13:33:05 +09:00
yoon
7091e41a18 Merge branch 'main' into yoon 2025-03-07 11:14:06 +09:00
yoon
8419f76386 프로젝트 정렬 및 로그 조회 로직 수정 2025-03-07 11:13:21 +09:00
4490655eab 게시글 수정 관련
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-07 10:19:32 +09:00
b7435d82f4 Merge branch 'khj' into main 2025-03-06 15:27:10 +09:00
9777553500 용어집 수정 2025-03-06 15:26:35 +09:00
yoon
7caaa0dd81 회원가입 시 색상 체크 2025-03-06 13:14:28 +09:00
yoon
24aea013bc 주석 추가 2025-03-06 13:14:10 +09:00
yoon
963ff1f106 Merge branch 'main' into yoon 2025-03-06 09:29:12 +09:00
278605e5d9 게시판 수정 2025-03-04 17:43:26 +09:00
b906ed74a7 게시판 파일다운 추가 2025-03-04 17:00:28 +09:00
02e2b593f7 젠킨스 서비스 실행으로 변경
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-04 11:59:28 +09:00
89f23e7226 1233
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-04 11:56:23 +09:00
f145f6dbaa 123
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-03-04 11:20:07 +09:00
9e141789ae 연차계산 로직 수정
Some checks are pending
LocalNet_front/pipeline/head Build started...
LOCALNET-DEV/pipeline/head This commit looks good
2025-02-28 16:21:36 +09:00
yoon
0e4a9e6716 연도 최신순 정렬 2025-02-28 15:50:21 +09:00
df70d798d3 Merge branch 'main' of
http://192.168.0.251:3000/localnet/localhost-back.git into main
2025-02-28 13:06:48 +09:00
6fbc38e117 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-28 13:05:38 +09:00
55c911a121 휴가관리 수정 2025-02-28 13:05:26 +09:00
daca8ffd34 Merge branch 'khj' into main 2025-02-27 16:17:52 +09:00
772efb8d96 조회수정 2025-02-27 16:17:21 +09:00
6d46c07b29 Merge branch 'main' of
http://192.168.0.251:3000/localnet/localhost-back.git into main
2025-02-27 14:39:50 +09:00
741fc0260e Merge branch 'khj' into main 2025-02-27 13:28:53 +09:00
f119c4724a 투표수정 2025-02-27 13:28:32 +09:00
yoon
d6f205f332 Merge branch 'main' into yoon 2025-02-27 13:27:20 +09:00
yoon
ebab4bb51e 삭제 추가 2025-02-27 13:24:06 +09:00
c94c6bd8e3 Merge branch 'vacation' into main 2025-02-27 13:20:58 +09:00
5835b39da7 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-27 13:16:42 +09:00
1345a5ce0b Merge remote-tracking branch 'origin/jihee' into main 2025-02-27 13:16:25 +09:00
11f1503d1e 휴가수정 2025-02-27 13:07:25 +09:00
yoon
54bb4d4cc9 .
All checks were successful
LOCALNET-DEV/pipeline/head This commit looks good
2025-02-25 13:37:02 +09:00
yoon
ec5dd31c0d . 2025-02-25 13:36:04 +09:00
common
6198078447 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-25 13:21:36 +09:00
17552d0867 용어집 수정 BlobUtil 추ㅏㄱ 2025-02-25 13:20:13 +09:00
231b763f7c blob 공통으로 분리 2025-02-25 10:50:29 +09:00
yoon
41372391de 주석 변경 2025-02-25 09:50:58 +09:00
yoon
68281f0874 Merge branch 'main' into yoon 2025-02-25 09:50:29 +09:00
yoon
a7e3dfd23d Merge branch 'main' into yoon 2025-02-25 09:47:48 +09:00
yoon
2c5705088b . 2025-02-25 09:47:06 +09:00
3192db220d 게시판 수정 2025-02-24 16:10:05 +09:00
common
ca947c62bb Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 15:05:25 +09:00
fec0172d66 게시판 댓글 수정 2025-02-24 15:04:53 +09:00
common
6bf491dacd Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 13:36:12 +09:00
1563af1d6b Merge branch 'khj' into main 2025-02-24 13:35:28 +09:00
972c18d1cb 수정 2025-02-24 13:34:59 +09:00
common
e9b90b3f0d Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 13:24:53 +09:00
e9e6431d77 쿠키 partitioned: true 설정 2025-02-24 13:24:31 +09:00
common
73b633f49b Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 13:20:26 +09:00
51142afa61 게시판 쿼리문 수정 2025-02-24 13:09:20 +09:00
yoon
2f83264ce0 전화번호 중복체크, 회원가입 시 프로젝트 멤버 테이블에 자동 insert (미참여 형태로) 2025-02-24 12:01:50 +09:00
common
d1acb91745 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 11:10:18 +09:00
d09d313958 s 2025-02-24 11:09:51 +09:00
common
2dcbbcc407 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 11:07:52 +09:00
c721da3d6f . 2025-02-24 11:07:24 +09:00
common
6a41c77554 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 10:01:00 +09:00
common
a11f608063 Merge branch 'main' of http://192.168.0.251:3000/localnet/localhost-back.git into main 2025-02-24 09:54:43 +09:00
yoon
7e8090dead 비밀번호 중복체크 2025-02-22 18:08:43 +09:00
common
a74b6fc8ed 66 2025-02-22 00:31:43 +09:00
71 changed files with 4332 additions and 762 deletions

8
Jenkinsfile vendored
View File

@ -21,8 +21,7 @@ pipeline {
echo "Tomcat is not running, skipping shutdown..." echo "Tomcat is not running, skipping shutdown..."
) else ( ) else (
echo "Tomcat is running, shutting down..." echo "Tomcat is running, shutting down..."
cd C:\\localhost-tomcat\\apache-tomcat-10.1.36-windows-x64\\apache-tomcat-10.1.36\\bin net stop localtomcat
call shutdown.bat
ping -n 5 127.0.0.1 > nul ping -n 5 127.0.0.1 > nul
) )
@ -35,9 +34,8 @@ pipeline {
ping -n 5 127.0.0.1 > nul ping -n 5 127.0.0.1 > nul
echo "start" echo "start"
cd /d C:\\localhost-tomcat\\apache-tomcat-10.1.36-windows-x64\\apache-tomcat-10.1.36\\bin net start localtomcat
call startup.bat ping -n 8 127.0.0.1 > nul
ping -n 5 127.0.0.1 > nul
''' '''
} }
} }

19
WEB-INF/web.xml Normal file
View File

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
version="2.4">
<display-name>localhost</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
</web-app>

View File

@ -14,20 +14,23 @@
*************************************************************/ *************************************************************/
package io.company.localhost; package io.company.localhost;
import io.company.localhost.common.config.ComponentScanConfig; import java.util.Locale;
import io.company.localhost.common.context.ApplicationContextProvider; import java.util.TimeZone;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration; import org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration;
import org.springframework.scheduling.annotation.EnableScheduling;
import java.util.Locale; import io.company.localhost.common.config.ComponentScanConfig;
import java.util.TimeZone; import io.company.localhost.common.context.ApplicationContextProvider;
import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
@EnableScheduling
@SpringBootApplication(scanBasePackageClasses = { ApplicationContextProvider.class , ComponentScanConfig.class} , @SpringBootApplication(scanBasePackageClasses = { ApplicationContextProvider.class , ComponentScanConfig.class} ,
exclude = {DataSourceTransactionManagerAutoConfiguration.class, TransactionAutoConfiguration.class , JacksonAutoConfiguration.class}) exclude = {DataSourceTransactionManagerAutoConfiguration.class, TransactionAutoConfiguration.class , JacksonAutoConfiguration.class})
public class LocalhostApplication { public class LocalhostApplication {

View File

@ -61,6 +61,6 @@ public class ParameterAop {
if(obj instanceof ApiResponse) if(obj instanceof ApiResponse)
returnObj = ((ApiResponse)obj).getData(); returnObj = ((ApiResponse)obj).getData();
log.info("리턴값 : {}", returnObj); //log.info("리턴값 : {}", returnObj);
} }
} }

View File

@ -89,7 +89,7 @@ public class TransactionConfig {
// naming 설정 // naming 설정
txAttributes.setProperty("select*", readOnlyAttribute.toString()); txAttributes.setProperty("select*", readOnlyAttribute.toString());
txAttributes.setProperty("*NewTx*", newTxAttribute.toString()); txAttributes.setProperty("insert*", newTxAttribute.toString());
txAttributes.setProperty("*NestedTx*", nestedTxAttribute.toString()); txAttributes.setProperty("*NestedTx*", nestedTxAttribute.toString());
txAttributes.setProperty("*", writeTxAttribute.toString()); txAttributes.setProperty("*", writeTxAttribute.toString());

View File

@ -14,11 +14,12 @@
*************************************************************/ *************************************************************/
package io.company.localhost.common.dto; package io.company.localhost.common.dto;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import lombok.Getter;
@Getter @Getter
@AllArgsConstructor
public class ApiResponse<T> { public class ApiResponse<T> {
private int code; private int code;
private HttpStatus status; private HttpStatus status;
@ -47,6 +48,11 @@ public class ApiResponse<T> {
public static <T> ApiResponse<T> error(HttpStatus status, String message) { public static <T> ApiResponse<T> error(HttpStatus status, String message) {
return new ApiResponse<>(status, message, null); return new ApiResponse<>(status, message, null);
} }
public static <T> ApiResponse<T> error(int code,HttpStatus status, String message) {
return new ApiResponse<>(code,status, message, null);
}
public static <T> ApiResponse<T> okMessage(String message) { public static <T> ApiResponse<T> okMessage(String message) {
return new ApiResponse<>(HttpStatus.OK, message, null); return new ApiResponse<>(HttpStatus.OK, message, null);
} }

View File

@ -79,6 +79,23 @@ public class MapDto extends ListOrderedMap {
return null; return null;
} }
/**
* 주어진 키에 해당하는 값을 Long 타입으로 반환합니다.
* 값이 BigInteger인 경우 자동으로 long으로 변환합니다.
*
* @param key Map에서 값을 검색할
* @return 해당 키에 대한 (Long 타입), 값이 없으면 null
*/
public Long getLong(String key) {
Object value = get(key);
if (value instanceof BigInteger) {
return ((BigInteger) value).longValue();
} else if (value instanceof Long) {
return (Long) value;
}
return null;
}
public <T> List<T> getList(String key, Class<T> clazz) { public <T> List<T> getList(String key, Class<T> clazz) {
Object value = this.get(key); Object value = this.get(key);
if (value == null) { if (value == null) {
@ -97,6 +114,8 @@ public class MapDto extends ListOrderedMap {
result.add(clazz.cast(item)); result.add(clazz.cast(item));
} else if (clazz.equals(Long.class) && item instanceof Integer) { } else if (clazz.equals(Long.class) && item instanceof Integer) {
result.add(clazz.cast(Long.valueOf((Integer) item))); result.add(clazz.cast(Long.valueOf((Integer) item)));
} else if (clazz.equals(String.class) && item instanceof Integer) {
result.add(clazz.cast(String.valueOf((Integer) item)));
} else if (item instanceof Map && clazz.equals(MapDto.class)) { } else if (item instanceof Map && clazz.equals(MapDto.class)) {
result.add(clazz.cast(new MapDto((Map<String, Object>) item))); result.add(clazz.cast(new MapDto((Map<String, Object>) item)));
} else { } else {

View File

@ -26,10 +26,10 @@ public enum UserErrorCode implements ErrorCode {
NOT_AUTH_USER(HttpStatus.UNAUTHORIZED ,"로그인이 필요합니다."), NOT_AUTH_USER(HttpStatus.UNAUTHORIZED ,"로그인이 필요합니다."),
INACTIVE_USER(HttpStatus.FORBIDDEN,"권한이 필요합니다."), INACTIVE_USER(HttpStatus.FORBIDDEN,"권한이 필요합니다."),
USER_NOT_FOUND(HttpStatus.UNAUTHORIZED,"아이디 혹은 비밀번호가 틀렸습니다."), USER_NOT_FOUND(10001,HttpStatus.UNAUTHORIZED,"아이디 혹은 비밀번호가 틀렸습니다."),
NOT_AUTHORIZED(HttpStatus.UNAUTHORIZED,"비인가 계정입니다."), NOT_AUTHORIZED(10002,HttpStatus.UNAUTHORIZED,"비인가 계정입니다."),
EXIT_USER(HttpStatus.UNAUTHORIZED,"탈퇴한 계정입니다."), EXIT_USER(10003,HttpStatus.UNAUTHORIZED,"탈퇴한 계정입니다."),
BAD_CREDENTIAL(HttpStatus.UNAUTHORIZED, "아이디 혹은 비밀번호 문제") BAD_CREDENTIAL(10004,HttpStatus.UNAUTHORIZED, "아이디 혹은 비밀번호 문제")
; ;
private final long code; private final long code;
@ -43,8 +43,12 @@ public enum UserErrorCode implements ErrorCode {
} }
public ApiResponse<?> getApiResponse() { public ApiResponse<?> getApiResponse() {
if(this.code > 10000){
return ApiResponse.error((int) this.getCode(),this.getHttpStatus() , this.getMessage());
}else{
return ApiResponse.error(this.getHttpStatus() , this.getMessage()); return ApiResponse.error(this.getHttpStatus() , this.getMessage());
} }
}
public ApiResponse<?> getApiResponse(String message) { public ApiResponse<?> getApiResponse(String message) {
return ApiResponse.error(this.getHttpStatus() , message); return ApiResponse.error(this.getHttpStatus() , message);

View File

@ -32,16 +32,18 @@ public class MemberAuthFailureHandler implements AuthenticationFailureHandler {
@Override @Override
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException { public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
ObjectMapper mapper = new ObjectMapper(); ObjectMapper mapper = new ObjectMapper();
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); response.setStatus(HttpServletResponse.SC_OK);
response.setContentType(MediaType.APPLICATION_JSON_VALUE); response.setContentType(MediaType.APPLICATION_JSON_VALUE);
ApiResponse<?> res = UserErrorCode.BAD_CREDENTIAL.getApiResponse();
String message = exception.getMessage(); String message = exception.getMessage();
ApiResponse<?> res = UserErrorCode.BAD_CREDENTIAL.getApiResponse();
if (exception instanceof BadCredentialsException || message.startsWith("NOT_FOUND")) { if (exception instanceof BadCredentialsException || message.startsWith("NOT_FOUND")) {
res = UserErrorCode.USER_NOT_FOUND.getApiResponse(); res = UserErrorCode.USER_NOT_FOUND.getApiResponse();
} else if (message.startsWith("NOT_AUTH_USER")) {
res = UserErrorCode.NOT_AUTH_USER.getApiResponse();
} else if (message.startsWith("NOT_AUTHORIZED")) { } else if (message.startsWith("NOT_AUTHORIZED")) {
res = UserErrorCode.NOT_AUTHORIZED.getApiResponse(); res = UserErrorCode.NOT_AUTHORIZED.getApiResponse();
} else if (message.startsWith("EXIT")) { } else if (message.startsWith("EXIT")) {

View File

@ -30,11 +30,14 @@ public class MapBasedUrlRoleMapper implements UrlRoleMapper{
public Map<String, String> getUrlRoleMappings() { public Map<String, String> getUrlRoleMappings() {
urlRoleMappings.put("/api/user/**", PERMIT_ALL); urlRoleMappings.put("/api/user/**", PERMIT_ALL);
urlRoleMappings.put("/api/project/**", ROLE_MEMBER); urlRoleMappings.put("/api/project/**", ROLE_MEMBER);
urlRoleMappings.put("/api/vacation/**", PERMIT_ALL); urlRoleMappings.put("/api/vacation/**", ROLE_MEMBER);
urlRoleMappings.put("/api/board/**", PERMIT_ALL); urlRoleMappings.put("/api/board/**", ROLE_MEMBER);
urlRoleMappings.put("/api/vote/**", PERMIT_ALL); urlRoleMappings.put("/api/vote/**", ROLE_MEMBER);
urlRoleMappings.put("/api/worddict/**", PERMIT_ALL); urlRoleMappings.put("/api/worddict/**", ROLE_MEMBER);
urlRoleMappings.put("/api/quilleditor/**", PERMIT_ALL); urlRoleMappings.put("/api/quilleditor/**", ROLE_MEMBER);
urlRoleMappings.put("/api/commuters/**", ROLE_MEMBER);
urlRoleMappings.put("/api/weather/**", ROLE_MEMBER);
urlRoleMappings.put("/api/admin/**", PERMIT_ALL);
return new HashMap<>(urlRoleMappings); return new HashMap<>(urlRoleMappings);
} }
} }

View File

@ -0,0 +1,73 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.api
* @fileName : AdminController.java
* @author : 서지희
* @date : 25.03.14
* @description : 게시판
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.03.14 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.controller.api;
import java.util.List;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.company.localhost.common.annotation.Member;
import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.NetmemberService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequestMapping("/api/admin")
@RequiredArgsConstructor
@Slf4j
public class AdminController {
private final NetmemberService netmemberService;
/**
* 사원 리스트
* @return 사원 리스트
*/
@Member
@ParameterCheck
@GetMapping("/users")
public ApiResponse<List<MapDto>> selectallUserList() {
List<MapDto> response = netmemberService.selectallUserList();
return ApiResponse.ok(response);
}
/**
* 관리자 권한 수정
* @ReqMap map 요청 파라미터 (MEMBERROL, MEMBERSEQ)
* @return 결과 메시지
*/
@Member
@ParameterCheck
@PutMapping("/role")
public ApiResponse<String> updateUserRole(@ReqMap MapDto map) {
Long id = Long.valueOf(map.get("id").toString());
String role = map.get("role").toString();
String newRole = role.equalsIgnoreCase("ADMIN") ? "ROLE_ADMIN" : "ROLE_MEMBER";
netmemberService.updateUserRole(id, newRole);
return ApiResponse.ok("관리자 권한이 변경되었습니다.");
}
}

View File

@ -9,17 +9,36 @@
* =========================================================== * ===========================================================
* DATE AUTHOR NOTE * DATE AUTHOR NOTE
* ----------------------------------------------------------- * -----------------------------------------------------------
* 24.01.02 서지희 최초 생성 * 25.01.07 서지희 최초 생성
* *
*************************************************************/ *************************************************************/
package io.company.localhost.controller.api; package io.company.localhost.controller.api;
import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
@ -28,7 +47,6 @@ import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap; import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse; import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.common.exception.InvalidPasswordException;
import io.company.localhost.common.exception.NotFoundHandler; import io.company.localhost.common.exception.NotFoundHandler;
import io.company.localhost.service.commoncodService; import io.company.localhost.service.commoncodService;
import io.company.localhost.service.localbordService; import io.company.localhost.service.localbordService;
@ -46,6 +64,7 @@ public class BoardController {
private final commoncodService commoncodService; private final commoncodService commoncodService;
private final PasswordEncoder passwordEncoder; private final PasswordEncoder passwordEncoder;
/** /**
* 공지사항 목록 조회 * 공지사항 목록 조회
* @ReqMap map 요청 파라미터 (searchKeyword) * @ReqMap map 요청 파라미터 (searchKeyword)
@ -55,6 +74,19 @@ public class BoardController {
@ParameterCheck @ParameterCheck
@GetMapping("/notices") @GetMapping("/notices")
public ApiResponse<List<MapDto>> getNotices(@ReqMap MapDto map) { public ApiResponse<List<MapDto>> getNotices(@ReqMap MapDto map) {
// size를 안전하게 Integer로 변환하여 MapDto에 다시 넣기
Object sizeObj = map.get("size");
Integer size = null;
if (sizeObj instanceof String) {
size = Integer.parseInt((String) sizeObj);
}else {
size = null;
}
map.put("size", size);
return ApiResponse.ok(boardService.selectNotices(map)); return ApiResponse.ok(boardService.selectNotices(map));
} }
@ -81,7 +113,6 @@ public class BoardController {
@PostMapping @PostMapping
public ApiResponse<BigInteger> createBoard(@ReqMap MapDto map) { public ApiResponse<BigInteger> createBoard(@ReqMap MapDto map) {
if (map.containsKey("LOCBRDPWD") && !map.getString("LOCBRDPWD").trim().isEmpty()) { // 체크 if (map.containsKey("LOCBRDPWD") && !map.getString("LOCBRDPWD").trim().isEmpty()) { // 체크
String rawPassword = map.getString("LOCBRDPWD"); String rawPassword = map.getString("LOCBRDPWD");
String hashedPassword = passwordEncoder.encode(rawPassword); String hashedPassword = passwordEncoder.encode(rawPassword);
@ -102,11 +133,60 @@ public class BoardController {
public ApiResponse<MapDto> getBoardDetail(@PathVariable("boardId") Long boardId) { public ApiResponse<MapDto> getBoardDetail(@PathVariable("boardId") Long boardId) {
MapDto board = boardService.selectBoardDetail(boardId); MapDto board = boardService.selectBoardDetail(boardId);
if (board == null) { if (board == null) {
throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다."); //throw new NotFoundHandler("게시물 ID " + boardId + "을(를) 찾을 수 없습니다.");
String errMessage = "게시물 ID " + boardId + "을(를) 찾을 수 없습니다.";
return ApiResponse.error(HttpStatus.NOT_FOUND, errMessage);
} }
// 📌 첨부파일 목록 추가
List<MapDto> attachments = boardService.selectAttachments(boardId);
board.put("attachments", attachments != null ? attachments : new ArrayList<>());
return ApiResponse.ok(board); return ApiResponse.ok(board);
} }
/**
* 게시물 수정 조회(익명 게시글은 비밀번호 필수)
*
* @param boardId
* @param map
* @return
*/
@Member
@ParameterCheck
@PostMapping("/{boardId}")
public ApiResponse<MapDto> getBoardDetail2(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
map.put("boardId", boardId);
return boardService.selectBoardDetail2(map);
}
/**
* 파일 다운로드 API
* @param path 파일 경로
* @return 파일 데이터 (바이너리 응답)
*/
@GetMapping("/download")
public ResponseEntity<Resource> downloadFile(@RequestParam String path) {
try {
Path filePath = Paths.get(path).normalize();
Resource resource = new UrlResource(filePath.toUri());
if (!resource.exists() || !resource.isReadable()) {
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(null);
}
String contentType = Files.probeContentType(filePath);
String fileName = filePath.getFileName().toString();
return ResponseEntity.ok()
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"")
.header(HttpHeaders.CONTENT_TYPE, contentType != null ? contentType : "application/octet-stream")
.body(resource);
} catch (IOException e) {
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
}
}
/** /**
* 게시물 삭제 * 게시물 삭제
* @ReqMap map 수정 데이터 (LOCBRDSEQ) * @ReqMap map 수정 데이터 (LOCBRDSEQ)
@ -116,23 +196,25 @@ public class BoardController {
@ParameterCheck @ParameterCheck
@DeleteMapping("/{boardId}") @DeleteMapping("/{boardId}")
public ApiResponse<String> deleteBoard(@ReqMap MapDto map) { public ApiResponse<String> deleteBoard(@ReqMap MapDto map) {
boardService.deleteBoard(map); return boardService.deleteBoard(map);
return ApiResponse.ok("게시물이 삭제되었습니다.");
} }
/** /**
* 게시물 수정 * 게시물 수정
* @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON, LOCBRDSEQ) *
* @return 수정 결과 메시지 * @param map 수정 데이터 (LOCBRDTTL, LOCBRDCON, LOCBRDSEQ, delListInfo)
* @param files 첨부파일 정보
* @return
* @throws IOException
*/ */
@Member @Member
@ParameterCheck
@PutMapping("/{boardId}") @PutMapping("/{boardId}")
public ApiResponse<String> updateBoard(@ReqMap MapDto map) { public ApiResponse<String> updateBoard(@ReqMap MapDto map, @RequestPart(value = "files", required = false) List<MultipartFile> files) throws IOException {
boardService.updateBoard(map); return boardService.updateBoardWithFiles(map, files);
return ApiResponse.ok("게시물이 수정되었습니다.");
} }
/** /**
* 첨부파일 추가 * 첨부파일 추가
* @ReqMap map 요청 파라미터 (CMNFLEREG, CMNFLESIZ, CMNFLEEXT, CMNFLEORG, CMNFLENAM, CMNFLEPAT, CMNBRDSEQ) * @ReqMap map 요청 파라미터 (CMNFLEREG, CMNFLESIZ, CMNFLEEXT, CMNFLEORG, CMNFLENAM, CMNFLEPAT, CMNBRDSEQ)
@ -141,12 +223,19 @@ public class BoardController {
@Member @Member
@ParameterCheck @ParameterCheck
@PostMapping("/{CMNBRDSEQ}/attachments") @PostMapping("/{CMNBRDSEQ}/attachments")
public ApiResponse<String> uploadAttachment(@ReqMap MapDto map) { public ApiResponse<String> uploadAttachment(@ReqMap MapDto map, @RequestParam("file") MultipartFile file) {
try {
Long userId = AuthUtil.getUser().getId(); Long userId = AuthUtil.getUser().getId();
map.put("CMNFLEREG", userId); map.put("CMNFLEREG", userId);
boardService.insertAttachment(map);
boardService.insertAttachment(map, file);
return ApiResponse.ok("첨부파일이 저장되었습니다."); return ApiResponse.ok("첨부파일이 저장되었습니다.");
} catch (Exception e) {
return ApiResponse.ok("첨부파일 저장 실패: " + e.getMessage());
} }
}
/** /**
* 게시물, 댓글 좋아요/싫어요 추가 * 게시물, 댓글 좋아요/싫어요 추가
@ -165,7 +254,7 @@ public class BoardController {
/** /**
* 댓글 조회 * 댓글 조회
* @ReqMap map 수정 데이터 (LOCBRDSEQ) * @ReqMap map 수정 데이터 (LOCBRDSEQ, page)
* @return 댓글 * @return 댓글
*/ */
@Member @Member
@ -181,7 +270,7 @@ public class BoardController {
/** /**
* 대댓글 조회 * 대댓글 조회
* @ReqMap map 수정 데이터 (LOCBRDSEQ) * @ReqMap map 수정 데이터 (LOCCMTPNT)
* @return 대댓글 * @return 대댓글
*/ */
@Member @Member
@ -203,8 +292,6 @@ public class BoardController {
@ParameterCheck @ParameterCheck
@PostMapping("/{LOCBRDSEQ}/comment") @PostMapping("/{LOCBRDSEQ}/comment")
public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) { public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId();
map.put("MEMBERSEQ", userId);
if (map.containsKey("LOCCMTPWD") && !map.getString("LOCCMTPWD").trim().isEmpty()) { // 체크 if (map.containsKey("LOCCMTPWD") && !map.getString("LOCCMTPWD").trim().isEmpty()) { // 체크
String rawPassword = map.getString("LOCCMTPWD"); String rawPassword = map.getString("LOCCMTPWD");
@ -231,13 +318,17 @@ public class BoardController {
/** /**
* 댓글/대댓글 삭제 * 댓글/대댓글 삭제
* @ReqMap map 수정 데이터 (LOCCMTSEQ) * @param commentId 댓글 ID
* @return 삭제 결과 메시지 * @return 삭제 결과 메시지
*/ */
@Member @Member
@ParameterCheck @ParameterCheck
@DeleteMapping("/comment/{commentId}") @DeleteMapping("/comment/{commentId}")
public ApiResponse<String> deleteComment(@ReqMap MapDto map) { public ApiResponse<String> deleteComment(@PathVariable("commentId") Long commentId, @RequestParam(value = "LOCCMTPNT") Long parentId) {
MapDto map = new MapDto();
map.put("LOCCMTSEQ", commentId);
map.put("LOCCMTPNT", parentId);
boardService.deleteComment(map); boardService.deleteComment(map);
return ApiResponse.ok("댓글이 삭제되었습니다."); return ApiResponse.ok("댓글이 삭제되었습니다.");
} }
@ -266,11 +357,13 @@ public class BoardController {
String storedHashedPassword = boardService.selectBoardPassword(boardId); String storedHashedPassword = boardService.selectBoardPassword(boardId);
if (storedHashedPassword == null) { if (storedHashedPassword == null) {
throw new NotFoundHandler("해당 게시물이 존재하지 않습니다."); throw new NotFoundHandler("해당 게시물이 존재하지 않습니다.");
} }
boolean isMatch = passwordEncoder.matches(rawPassword, storedHashedPassword); boolean isMatch = passwordEncoder.matches(rawPassword, storedHashedPassword);
if (!isMatch) { if (!isMatch) {
throw new InvalidPasswordException("비밀번호가 일치하지 않습니다."); //throw new InvalidPasswordException("비밀번호가 일치하지 않습니다.");
return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다.");
} }
return ApiResponse.ok(true); return ApiResponse.ok(true);
@ -303,7 +396,8 @@ public class BoardController {
boolean isMatch = passwordEncoder.matches(rawPassword, storedHashedPassword); boolean isMatch = passwordEncoder.matches(rawPassword, storedHashedPassword);
if (!isMatch) { if (!isMatch) {
throw new InvalidPasswordException("비밀번호가 일치하지 않습니다."); //throw new InvalidPasswordException("비밀번호가 일치하지 않습니다.");
return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다.");
} }
return ApiResponse.ok(true); return ApiResponse.ok(true);
@ -314,7 +408,7 @@ public class BoardController {
* @return 카테고리 리스트 * @return 카테고리 리스트
*/ */
@GetMapping("/categories") @GetMapping("/categories")
public ApiResponse<List<MapDto>> getCategories() { public ApiResponse<List<MapDto>> SelectCategories() {
List<MapDto> categories = commoncodService.selectCategoryList(); List<MapDto> categories = commoncodService.selectCategoryList();
return ApiResponse.ok(categories); return ApiResponse.ok(categories);
} }

View File

@ -0,0 +1,116 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.api
* @fileName : CommuterController.java
* @author : 박지윤
* @date : 25.03.10
* @description : 출퇴근
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.03.10 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.controller.api;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.CommutersService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@RestController
@RequestMapping("/api/commuters")
@RequiredArgsConstructor
@Slf4j
public class CommutersController {
private final CommutersService commutersService;
/**
* 출퇴근 등록
*
* @param map
* @return
*/
@PostMapping("/insert")
public ApiResponse<Integer> insertCommuters(@ReqMap MapDto map) {
int commuters = commutersService.insertCommuters(map);
return ApiResponse.ok(commuters);
}
/**
* 퇴근 업데이트
*
* @param map
* @return
*
*/
@PatchMapping("/updateLve")
public ApiResponse<Boolean> updateLeaveTime(@ReqMap MapDto map) {
boolean isLeaveTime = commutersService.updateLeaveTime(map);
return ApiResponse.ok(isLeaveTime);
}
/**
* 현재 달의 모든 출근 정보 조회
*
* @param map
* @return
*/
@GetMapping("/month")
public ApiResponse<List<MapDto>> selectCommutersByMonth(int year, int month) {
return ApiResponse.ok(commutersService.selectCommutersByMonth(year, month));
}
/**
* 오늘 사용자의 출근 정보 조회
*
* @param map
* @return
*/
@GetMapping("/today/{memberSeq}")
public ApiResponse<List<MapDto>> selectTodayCommuterInfo(@PathVariable Integer memberSeq) {
return ApiResponse.ok(commutersService.selectTodayCommuterInfo(memberSeq));
}
/**
* 오늘 출근 모든 사용자 조회
*
* @param map
* @return
*/
@GetMapping("/todays")
public ApiResponse<List<MapDto>> selectTodayCommuter() {
return ApiResponse.ok(commutersService.selectTodayCommuter());
}
/**
* 출근 프로젝트 업데이트
*
* @param map
* @return
*
*/
/*
* @PatchMapping("/update") public ApiResponse<Boolean>
* updateCommuterProject(@ReqMap MapDto map) { boolean isCommuter =
* commutersService.updateCommuterProject(map); return
* ApiResponse.ok(isCommuter); }
*/
}

View File

@ -0,0 +1,86 @@
package io.company.localhost.controller.api;
import java.util.List;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import io.company.localhost.common.annotation.Admin;
import io.company.localhost.common.annotation.Member;
import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.MainService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/main")
public class MainController {
private final MainService mainService;
@Member
@ParameterCheck
@GetMapping("/category")
public ApiResponse<List<MapDto>> selectMainMenuCategory() {
return mainService.selectMainMenuCategory();
}
@Member
@ParameterCheck
@GetMapping("/eventList")
public ApiResponse<MapDto> selectEventList(@ReqMap MapDto map) {
return mainService.selectEventList(map);
}
@Member
@ParameterCheck
@PostMapping("/toggleEvent")
public ApiResponse<String> toggleEvent(@ReqMap MapDto map) {
return mainService.toggleEvent(map);
}
@Member
@ParameterCheck
@PostMapping("/inserEvent")
public ApiResponse<String> insertEvent(@ReqMap MapDto map) {
return mainService.insertEvent(map);
}
@Admin
@ParameterCheck
@GetMapping("/registerMemberList")
public ApiResponse<List<MapDto>> registerMemberList() {
return mainService.registerMemberList();
}
@Admin
@ParameterCheck
@PostMapping("/registerMember")
public ApiResponse<String> registerMember(@ReqMap MapDto map) {
long memberSeq = map.getInt("memberSeq");
return mainService.registerMember(memberSeq);
}
@Admin
@ParameterCheck
@PostMapping("/rejectMember")
public ApiResponse<String> rejectMember(@ReqMap MapDto map) {
long memberSeq = map.getInt("memberSeq");
return mainService.rejectMember(memberSeq);
}
@Member
@ParameterCheck
@PostMapping("/getUserLeaveRecord")
public ApiResponse<MapDto> getUserLeaveRecord(@ReqMap MapDto map) {
return mainService.getUserLeaveRecord(map);
}
}

View File

@ -22,18 +22,15 @@ import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import io.company.localhost.common.annotation.ParameterCheck; import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap; import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse; import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.NetprojctService; import io.company.localhost.service.NetprojctService;
import io.company.localhost.service.ProMemberService;
import io.company.localhost.service.commoncodService; import io.company.localhost.service.commoncodService;
import io.company.localhost.utils.AuthUtil;
import io.company.localhost.vo.MemberVo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -45,6 +42,7 @@ public class ProjectController {
private final commoncodService commoncodservice; private final commoncodService commoncodservice;
private final NetprojctService netprojctService; private final NetprojctService netprojctService;
private final ProMemberService promemberService;
/** /**
* 프로젝트 연도 조회 * 프로젝트 연도 조회
@ -62,9 +60,7 @@ public class ProjectController {
/** /**
* 프로젝트 목록 조회 * 프로젝트 목록 조회
* *
* @param projectName 프로젝트 이름 * @param map
* @param participantSeq 참여자 번호
* @param address 주소 정보 (주소, 상세주소, 우편번호
* @return * @return
* *
*/ */
@ -106,7 +102,7 @@ public class ProjectController {
/** /**
* 비밀번호 재설정 * 프로젝트 멤버 참여 업데이트
* *
* @param map * @param map
* @return * @return
@ -114,7 +110,7 @@ public class ProjectController {
*/ */
@PatchMapping("/updateYon") @PatchMapping("/updateYon")
public ApiResponse<Boolean> updateProjectMember(@ReqMap MapDto map) { public ApiResponse<Boolean> updateProjectMember(@ReqMap MapDto map) {
boolean isMember = netprojctService.updateProjectMember(map); boolean isMember = promemberService.updateProjectMember(map);
return ApiResponse.ok(isMember); return ApiResponse.ok(isMember);
} }
@ -128,7 +124,7 @@ public class ProjectController {
@GetMapping("/members/{projctSeq}") @GetMapping("/members/{projctSeq}")
public ApiResponse<List<MapDto>> selectProjectMembers(@PathVariable int projctSeq) { public ApiResponse<List<MapDto>> selectProjectMembers(@PathVariable int projctSeq) {
return ApiResponse.ok(netprojctService.getProjectMembers(projctSeq)); return ApiResponse.ok(promemberService.selectProjectMembers(projctSeq));
} }
/** /**
@ -144,4 +140,51 @@ public class ProjectController {
return ApiResponse.ok(netprojctService.selectProjectLog(projctSeq)); return ApiResponse.ok(netprojctService.selectProjectLog(projctSeq));
} }
/**
* 프로젝트 삭제
*
* @return
*
*/
@ParameterCheck
@PatchMapping("/delete")
public ApiResponse<Boolean> deleteProject(@ReqMap MapDto map) {
boolean isDelete = netprojctService.deleteProject(map);
return ApiResponse.ok(isDelete);
}
/**
* 사용자가 속한 프로젝트 조회
*
* @return
*
*/
@ParameterCheck
@GetMapping("{memberSeq}")
public ApiResponse<List<MapDto>> selectMemberProjects(@PathVariable int memberSeq) {
return ApiResponse.ok(promemberService.selectMemberProjects(memberSeq));
}
/**
* 프로젝트 모든 사용자 참여기간 조회
*
* @return
*
*/
@ParameterCheck
@GetMapping("/period/{projctSeq}")
public ApiResponse<List<MapDto>> selectUserProjectPeriod(@PathVariable int projctSeq) {
return ApiResponse.ok(netprojctService.selectUserProjectPeriod(projctSeq));
}
@ParameterCheck
@GetMapping("/people/{memberSeq}")
public ApiResponse<List<MapDto>> selectUserProjectPeriod2(@PathVariable int memberSeq) {
return ApiResponse.ok(netprojctService.selectUserProjectPeriod2(memberSeq));
}
} }

View File

@ -1,6 +1,19 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.api
* @fileName : VacationController.java
* @author : 서지희
* @date : 25.02.06
* @description : 게시판
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.06 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.controller.api; package io.company.localhost.controller.api;
import java.time.LocalDate; import java.util.ArrayList;
import java.time.temporal.ChronoUnit;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -9,6 +22,7 @@ import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import io.company.localhost.common.annotation.Member; import io.company.localhost.common.annotation.Member;
@ -41,11 +55,12 @@ public class VacationController {
@PostMapping @PostMapping
public ApiResponse<?> insertVacations(@RequestBody List<MapDto> list) { public ApiResponse<?> insertVacations(@RequestBody List<MapDto> list) {
Long user = AuthUtil.getUser().getId(); Long user = AuthUtil.getUser().getId();
List<MapDto> savedVacations = new ArrayList<>();
for (MapDto request : list) { for (MapDto request : list) {
String date = request.getString("date"); String date = request.getString("date");
String type = request.getString("type"); String type = request.getString("type");
Object receiverId = request.get("receiverId"); Object receiverId = request.get("receiverId");
request.put("employeeId", user);
if (date == null || type == null) { if (date == null || type == null) {
throw new IllegalArgumentException("요청 데이터에 누락된 값이 있습니다: " + request); throw new IllegalArgumentException("요청 데이터에 누락된 값이 있습니다: " + request);
@ -55,11 +70,21 @@ public class VacationController {
if (count == null || count < 1) { if (count == null || count < 1) {
count = 1; count = 1;
} }
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
localVacaService.insertVacation(request); MapDto vacationRequest = new MapDto();
vacationRequest.put("date", date);
vacationRequest.put("type", type);
vacationRequest.put("receiverId", receiverId);
vacationRequest.put("employeeId", user);
// 실제 저장
localVacaService.insertVacation(vacationRequest);
savedVacations.add(vacationRequest);
} }
} }
return ApiResponse.ok("모든 휴가가 성공적으로 저장되었습니다.");
return ApiResponse.ok(savedVacations);
} }
/** /**
@ -75,20 +100,23 @@ public class VacationController {
List<MapDto> addRequests = map.getList("add", MapDto.class); List<MapDto> addRequests = map.getList("add", MapDto.class);
List<Long> deleteIds = map.getList("delete", Long.class); List<Long> deleteIds = map.getList("delete", Long.class);
if (addRequests != null) { // 1 삭제 먼저 처리
if (deleteIds != null && !deleteIds.isEmpty()) {
localVacaService.deleteVacation(deleteIds);
}
// 2 추가 또는 업데이트 처리
if (addRequests != null && !addRequests.isEmpty()) {
for (MapDto addRequest : addRequests) { for (MapDto addRequest : addRequests) {
addRequest.put("employeeId", user); addRequest.put("employeeId", user);
localVacaService.insertVacation(addRequest); localVacaService.upsertVacation(addRequest);
}
}
if (deleteIds != null) {
for (Long deleteId : deleteIds) {
localVacaService.deleteVacation(deleteId);
} }
} }
return ApiResponse.ok("휴가 변경이 성공적으로 처리되었습니다."); return ApiResponse.ok("휴가 변경이 성공적으로 처리되었습니다.");
} }
/** /**
* 전체 사원의 휴가 조회 * 전체 사원의 휴가 조회
* @param year, month * @param year, month
@ -119,9 +147,9 @@ public class VacationController {
@Member @Member
@ParameterCheck @ParameterCheck
@GetMapping("/history") @GetMapping("/history")
public ApiResponse<Map<String, List<MapDto>>> selectUserVacationHistory() { public ApiResponse<Map<String, List<MapDto>>> selectUserVacationHistory(@RequestParam("year") int year) {
Long userId = AuthUtil.getUser().getId(); Long userId = AuthUtil.getUser().getId();
return ApiResponse.ok(localVacaService.selectUserVacationHistory(userId)); return ApiResponse.ok(localVacaService.selectUserVacationHistory(userId, year));
} }
/** /**

View File

@ -30,23 +30,20 @@ public class VoteBoardController {
/** /**
* 투표목록조회 * 투표목록조회
* @param page 페이지번호 , 내가한투표 :0 투표안한것 :1 , 전체:0,투표마감:1,투표중:2 * @param page 페이지번호 , myVote 내가한투표 :1 투표안한것 :0 , 전체:0, voteset 투표마감:1,투표중:2
* @return * @return
*/ */
@Member @Member
@ParameterCheck @ParameterCheck
@GetMapping("getVoteList") @GetMapping("getVoteList")
public ApiResponse<PageInfo<MapDto>> getVoteList(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) { public ApiResponse<PageInfo<MapDto>> selectVoteList(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) {
//userId
Long userId = AuthUtil.getUser().getId(); Long userId = AuthUtil.getUser().getId();
map.put("userId", userId); map.put("userId", userId);
PageInfo<MapDto> VoteList = localvoteservice.getVoteList(map); PageInfo<MapDto> VoteList = localvoteservice.selectVoteList(map);
return ApiResponse.ok(VoteList); return ApiResponse.ok(VoteList);
} }
/** /**
* 투표 등록 * 투표 등록
* @param title 제목 ,endDate 종료날짜 ,itemList 항목리스트(항목,링크) ,addvoteIs 항목추가여부, votemMltiIs 다중투표 허용여부 * @param title 제목 ,endDate 종료날짜 ,itemList 항목리스트(항목,링크) ,addvoteIs 항목추가여부, votemMltiIs 다중투표 허용여부
@ -55,14 +52,11 @@ public class VoteBoardController {
@Member @Member
@PostMapping("insertWord") @PostMapping("insertWord")
public ApiResponse<Long> insertWord(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) { public ApiResponse<Long> insertWord(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) {
//userId
Long userId = AuthUtil.getUser().getId(); Long userId = AuthUtil.getUser().getId();
map.put("userId", userId); map.put("userId", userId);
Long result = localvoteservice.insertVote(map); Long result = localvoteservice.insertVote(map);
return ApiResponse.ok(result); return ApiResponse.ok(result);
} }
/** /**
* 투표 선택 * 투표 선택
* @param title 제목 ,endDate 종료날짜 ,itemList 항목리스트(항목,링크) ,addvoteIs 항목추가여부, votemMltiIs 다중투표 허용여부 * @param title 제목 ,endDate 종료날짜 ,itemList 항목리스트(항목,링크) ,addvoteIs 항목추가여부, votemMltiIs 다중투표 허용여부
@ -71,12 +65,10 @@ public class VoteBoardController {
@Member @Member
@PostMapping("insertCheckedNums") @PostMapping("insertCheckedNums")
public ApiResponse<Long> insertCheckedNums(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) { public ApiResponse<Long> insertCheckedNums(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId(); Long userId = AuthUtil.getUser().getId();
map.put("userId", userId); map.put("userId", userId);
return ApiResponse.ok(localvoteservice.insertCheckedNums(map)); return ApiResponse.ok(localvoteservice.insertCheckedNums(map));
} }
/** /**
* 투표 종료 * 투표 종료
* @param endVoteId 투표번호 * @param endVoteId 투표번호
@ -85,11 +77,26 @@ public class VoteBoardController {
@Member @Member
@PatchMapping("updateEndData") @PatchMapping("updateEndData")
public ApiResponse<Long> updateEndData(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) { public ApiResponse<Long> updateEndData(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId();
map.put("userId", userId);
return ApiResponse.ok(localvoteservice.updateEndData(map)); return ApiResponse.ok(localvoteservice.updateEndData(map));
} }
/**
* 투표 삭제
* @param endVoteId 투표번호
* @return
*/
@Member
@PatchMapping("updateDeleteData")
public ApiResponse<Long> updateDeleteData(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) {
return ApiResponse.ok(localvoteservice.updateDeleteData(map));
}
/**
* 투표 랜덤뽑기
* @param randomList 랜덤리스트 ,voteid 투표 번호
* @return
*/
@Member
@PostMapping("randomList")
public ApiResponse<Long> randomList(@ReqMap MapDto map) {
return ApiResponse.ok(localvoteservice.updateRandomResult(map));
}
} }

View File

@ -31,6 +31,7 @@ import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.commoncodService; import io.company.localhost.service.commoncodService;
import io.company.localhost.service.worddictyService; import io.company.localhost.service.worddictyService;
import io.company.localhost.utils.AuthUtil;
import io.company.localhost.vo.MemberVo; import io.company.localhost.vo.MemberVo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -52,10 +53,10 @@ public class worddictController {
@Member @Member
@ParameterCheck @ParameterCheck
@GetMapping("getWordList") @GetMapping("getWordList")
public ApiResponse<MapDto> getWordList(@ReqMap MapDto map) { public ApiResponse<MapDto> selectWordList(@ReqMap MapDto map) {
int total = worddictyservice.getTotal(map); int total = worddictyservice.getTotal(map);
List<MapDto> wordList = worddictyservice.getWordList(map); List<MapDto> wordList = worddictyservice.selectWordList(map);
MapDto OutData = new MapDto(); MapDto OutData = new MapDto();
OutData.put("total", total); OutData.put("total", total);
@ -65,18 +66,30 @@ public class worddictController {
} }
/** /**
* 용어집 카테고리 목록 * 용어집 검색정렬 목록
* @param * @param
* @return * @return
*/ */
@Member @Member
@ParameterCheck @ParameterCheck
@GetMapping("getWordCategory") @GetMapping("getWordCategory")
public ApiResponse<List<MapDto>> getWordCategory() { public ApiResponse<List<MapDto>> selectWordCategory() {
List<MapDto> WordCategoryList = commoncodservice.selectWordCategory(); List<MapDto> WordCategoryList = commoncodservice.selectWordCategory();
return ApiResponse.ok(WordCategoryList); return ApiResponse.ok(WordCategoryList);
} }
/** /**
* 용어집 카테고리 목록
* @param
* @return
*/
@Member
@ParameterCheck
@GetMapping("getIndexCategory")
public ApiResponse<List<MapDto>> selectIndexCategory() {
List<MapDto> selectIndexCategory = worddictyservice.selectIndexCategory();
return ApiResponse.ok(selectIndexCategory);
}
/**
* 용어집 상세 조회 * 용어집 상세 조회
* @param WRDDICSEQ 용어 번호 * @param WRDDICSEQ 용어 번호
* @return * @return
@ -84,37 +97,19 @@ public class worddictController {
@Member @Member
@ParameterCheck @ParameterCheck
@GetMapping("getWordDetail") @GetMapping("getWordDetail")
public ApiResponse<MapDto> getWordDetail(@ReqMap MapDto map) { public ApiResponse<MapDto> selectWordDetail(@ReqMap MapDto map) {
return ApiResponse.ok( worddictyservice.getWordDetail(map)); return ApiResponse.ok( worddictyservice.selectWordDetail(map));
} }
/** /**
* 용어집 카테고리 등록 * 용어 등록 - 카테고리 등록
* @param CMNCODNAM 용어집 등록 카테고리 이름 * @param WRDDICCAT 카테고리 코드값 ,WRDDICTTL 용어,WRDDICCON 내용 ,WRDDICRIK 링크 ,CMNCODNAM 추가 등록 카테고리 이름
* @return
*/
@Member
@ParameterCheck
@PostMapping("insertCategory")
public ApiResponse<Long> insertCategory(@ReqMap MapDto map) {
Long result = commoncodservice.insertCategory(map);
if(result == -1) {
return ApiResponse.okMessage("이미 존재하는 카테고리명입니다.");
}
return ApiResponse.ok(result);
}
/**
* 용어 등록
* @param WRDDICCAT 카테고리 코드값 ,WRDDICTTL 용어,WRDDICCON 내용 ,WRDDICRIK 링크
* @return * @return
*/ */
@Member @Member
@PostMapping("insertWord") @PostMapping("insertWord")
public ApiResponse<Long> insertWord(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) { public ApiResponse<Long> insertWord(@ReqMap MapDto map) {
//userId Long userId = AuthUtil.getUser().getId();
//Long userId = AuthUtil.getUser().getId();
//임시
int userId = 38;
map.put("userId", userId); map.put("userId", userId);
Long result = worddictyservice.insertWord(map); Long result = worddictyservice.insertWord(map);
@ -128,12 +123,9 @@ public class worddictController {
@Member @Member
@ParameterCheck @ParameterCheck
@PatchMapping("updateWord") @PatchMapping("updateWord")
public ApiResponse<Long> updateWord(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) { public ApiResponse<Long> updateWord(@ReqMap MapDto map) {
//userId Long userId = AuthUtil.getUser().getId();
//Long userId = AuthUtil.getUser().getId();
//임시
int userId = 38;
map.put("userId", userId); map.put("userId", userId);
Long result = worddictyservice.updateWord(map); Long result = worddictyservice.updateWord(map);

View File

@ -18,10 +18,12 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
@ -29,8 +31,11 @@ import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.company.localhost.common.annotation.ParameterCheck; import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse; import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.localbordService;
import io.company.localhost.utils.AuthUtil;
import io.company.localhost.vo.UploadFile;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@ -43,6 +48,8 @@ public class ImageUploadController {
@Value("${filePath.boardfile}") @Value("${filePath.boardfile}")
private String boardFilePath; private String boardFilePath;
private final localbordService localbordService;
/** /**
* quilleditor 안에서 삽입된 이미지를 서버에 저장하는 메소드 * quilleditor 안에서 삽입된 이미지를 서버에 저장하는 메소드
* @form-data 서버에 저장된 이미지 경로와 이름 * @form-data 서버에 저장된 이미지 경로와 이름
@ -50,7 +57,8 @@ public class ImageUploadController {
*/ */
@ParameterCheck @ParameterCheck
@PostMapping("/upload") @PostMapping("/upload")
public ApiResponse<String> uploadImage(@RequestParam("file") MultipartFile file) throws IOException { @Transactional
public ApiResponse<MapDto> uploadImage(@RequestParam("file") MultipartFile file) throws IOException {
if (file.isEmpty()) { if (file.isEmpty()) {
return ApiResponse.error(HttpStatus.BAD_REQUEST, "File is empty"); return ApiResponse.error(HttpStatus.BAD_REQUEST, "File is empty");
@ -59,13 +67,47 @@ public class ImageUploadController {
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf(".")); String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
String fileName = UUID.randomUUID().toString() + fileExtension; String fileName = UUID.randomUUID().toString() + fileExtension;
Path filePath = Paths.get(boardFilePath, fileName); Path filePath = Paths.get(boardFilePath, fileName);
Long fileSize = file.getSize();
Files.createDirectories(filePath.getParent()); Files.createDirectories(filePath.getParent());
Files.write(filePath, file.getBytes()); Files.write(filePath, file.getBytes());
String fileUrl = "upload/img/board/" + fileName; String fileUrl = "upload/img/board/" + fileName;
long fileIndex = insertUploadEditorImageInfo(fileName, originalFileName, filePath.toString(), fileExtension, fileSize);
return ApiResponse.ok(fileUrl); MapDto map = new MapDto();
if(fileIndex != 0) map.put("fileIndex", fileIndex);
map.put("fileUrl", fileUrl);
return ApiResponse.ok(map);
}
/**
* 업로드 파일정보를 DB 적재
*
* @param fileName
* @param originalFileName
* @param filePath
* @param fileExtension
* @param fileSize
* @return success: DB 시퀀스 번호, fail: 0
*
*/
public long insertUploadEditorImageInfo(String fileName, String originalFileName, String filePath, String fileExtension, Long fileSize) {
Long userId = AuthUtil.getUser().getId();
MapDto map = new MapDto();
map.put("CMNFLENAM" , fileName );
map.put("CMNFLEORG" , originalFileName );
map.put("CMNFLEPAT" , filePath );
map.put("CMNFLEEXT" , fileExtension );
map.put("CMNFLESIZ" , fileSize );
map.put("CMNFLEREG" , userId );
int result = localbordService.insertUploadEditorImageInfo(map);
return result == 1 ? map.getLong("id") : 0;
} }
} }

View File

@ -17,10 +17,12 @@ package io.company.localhost.controller.common;
import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY; import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.security.authentication.RememberMeAuthenticationToken; import org.springframework.security.authentication.RememberMeAuthenticationToken;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.security.core.annotation.AuthenticationPrincipal;
@ -28,11 +30,14 @@ import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy; import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping; import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -43,6 +48,7 @@ import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap; import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse; import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.service.FileService;
import io.company.localhost.service.NetmemberService; import io.company.localhost.service.NetmemberService;
import io.company.localhost.service.commoncodService; import io.company.localhost.service.commoncodService;
import io.company.localhost.utils.AuthUtil; import io.company.localhost.utils.AuthUtil;
@ -67,20 +73,33 @@ public class UserController {
/** /**
* 사용 가능 색상 조회 * 사용 가능 색상 조회
* *
* @return ApiResponse<List<MapDto>> * @return
* *
*/ */
@ParameterCheck @ParameterCheck
@GetMapping("/color") @GetMapping("/color")
public ApiResponse<List<MapDto>> selectColorList(@RequestParam("type") String type) { public ApiResponse<List<MapDto>> selectColorList(String type) {
List<MapDto> ColorList = commoncodservice.selectColorList(type); List<MapDto> ColorList = commoncodservice.selectColorList(type);
return ApiResponse.ok(ColorList); return ApiResponse.ok(ColorList);
} }
/**
* 색상 중복 체크
*
* @return
*
*/
@ParameterCheck
@GetMapping("/checkColor")
public ApiResponse<Boolean> selectMemberColor(String memberCol) {
boolean isDuplicate = netmemberservice.selectMemberColor(memberCol);
return ApiResponse.ok(isDuplicate);
}
/** /**
* MBTI 목록 조회 * MBTI 목록 조회
* *
* @return ApiResponse<List<MapDto>> * @return
* *
*/ */
@ParameterCheck @ParameterCheck
@ -93,7 +112,7 @@ public class UserController {
/** /**
* 비밀번호 힌트 목록 조회 * 비밀번호 힌트 목록 조회
* *
* @return ApiResponse<List<MapDto>> * @return
* *
*/ */
@ParameterCheck @ParameterCheck
@ -108,7 +127,7 @@ public class UserController {
* *
* @param profile * @param profile
* @param map * @param map
* @return ApiResponse<Integer> * @return
*/ */
@PostMapping("/join") @PostMapping("/join")
public ApiResponse<Integer> register(@RequestParam("memberPrf") MultipartFile memberPrf, @ReqMap MapDto map) { public ApiResponse<Integer> register(@RequestParam("memberPrf") MultipartFile memberPrf, @ReqMap MapDto map) {
@ -120,19 +139,32 @@ public class UserController {
* 아이디 중복 체크 * 아이디 중복 체크
* *
* @param memberIds * @param memberIds
* @return ApiResponse<Boolean> * @return
* *
*/ */
@GetMapping("/checkId") @GetMapping("/checkId")
public ApiResponse<Boolean> selectCheckId(@RequestParam("memberIds") String memberIds) { public ApiResponse<Boolean> selectCheckId(String memberIds) {
boolean isDuplicate = netmemberservice.selectCheckId(memberIds); boolean isDuplicate = netmemberservice.selectCheckId(memberIds);
return ApiResponse.ok(!isDuplicate); return ApiResponse.ok(!isDuplicate);
} }
/**
* 전화번호 중복 체크
*
* @param memberTel
* @return
*
*/
@GetMapping("/checkPhone")
public ApiResponse<Boolean> selectCheckPhone(String memberTel) {
boolean isDuplicate = netmemberservice.selectCheckPhone(memberTel);
return ApiResponse.ok(!isDuplicate);
}
/** /**
* 로그인 여부 체크 * 로그인 여부 체크
* *
* @return ApiResponse<Boolean> * @return
*/ */
@GetMapping("/isLogin") @GetMapping("/isLogin")
public ApiResponse<Boolean> checkLogin() { public ApiResponse<Boolean> checkLogin() {
@ -144,7 +176,7 @@ public class UserController {
* 비밀번호 재설정 member 체크 * 비밀번호 재설정 member 체크
* *
* @param map * @param map
* @return ApiResponse<Boolean> * @return
* *
*/ */
@PostMapping("/pwReset") @PostMapping("/pwReset")
@ -157,7 +189,7 @@ public class UserController {
* 기존 비밀번호 체크 * 기존 비밀번호 체크
* *
* @param map * @param map
* @return ApiResponse<Boolean> * @return
*/ */
@PostMapping("/checkPassword") @PostMapping("/checkPassword")
public ApiResponse<Boolean> selectPassword(@ReqMap MapDto map) { public ApiResponse<Boolean> selectPassword(@ReqMap MapDto map) {
@ -169,31 +201,52 @@ public class UserController {
* 비밀번호 재설정 * 비밀번호 재설정
* *
* @param map * @param map
* @return ApiResponse<Boolean> * @return
* *
*/ */
@PatchMapping("/pwNew") @PatchMapping("/pwNew")
public ApiResponse<Boolean> updatePassword(@ReqMap MapDto map) { public ApiResponse<Boolean> updatePassword(@ReqMap MapDto map) {
System.out.println(map);
boolean isPwNew = netmemberservice.updatePassword(map); boolean isPwNew = netmemberservice.updatePassword(map);
return ApiResponse.ok(isPwNew); return ApiResponse.ok(isPwNew);
} }
// security 인증 체크 // // security 인증 체크
// @GetMapping("userInfo")
// public ApiResponse<MemberVo> getUserInfo(@AuthenticationPrincipal MemberVo memberVo) {
// SecurityContextHolderStrategy contextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
// log.info(">> contextHolderStrategy : {}", contextHolderStrategy);
// SecurityContext context = contextHolderStrategy.getContext();
// log.info(">> context : {}", context);
// Authentication authentication = context.getAuthentication();
// log.info(">> authentication : {}", authentication);
// log.info(">> memberVo : {}", memberVo);
//
// MemberVo user = AuthUtil.getUser();
// log.info(">> AuthUtil : {}", user);
//
// return ApiResponse.ok(memberVo);
// }
@GetMapping("userInfo") @GetMapping("userInfo")
public ApiResponse<MemberVo> getUserInfo(@AuthenticationPrincipal MemberVo memberVo) { public ApiResponse<MemberVo> getUserInfo2(@AuthenticationPrincipal MemberVo memberVo) {
SecurityContextHolderStrategy contextHolderStrategy = SecurityContextHolder.getContextHolderStrategy(); if(AuthUtil.getUser() != null) {
log.info(">> contextHolderStrategy : {}", contextHolderStrategy); Long memberId = AuthUtil.getUser().getId();
SecurityContext context = contextHolderStrategy.getContext();
log.info(">> context : {}", context);
Authentication authentication = context.getAuthentication();
log.info(">> authentication : {}", authentication);
log.info(">> memberVo : {}", memberVo);
MemberVo user = AuthUtil.getUser(); log.info("🧩 memberId from AuthUtil: {}", memberId);
log.info(">> AuthUtil : {}", user);
return ApiResponse.ok(memberVo); MemberVo user = netmemberservice.getUserInfoById(memberId);
log.info("📦 User from DB: {}", user);
return ApiResponse.ok(user);
} }
return null;
}
// @GetMapping("checkUserSession")
// public
// 유저 세션 체크 // 유저 세션 체크
@GetMapping(value = "check") @GetMapping(value = "check")
@ -210,6 +263,21 @@ public class UserController {
return ApiResponse.ok(sessionData); return ApiResponse.ok(sessionData);
} }
// 유저 세션 권한 체크
@PostMapping(value = "authCheck")
public ApiResponse<?> authCheck(@ReqMap MapDto map) {
String memberId = map.getString("memberId");
if(!StringUtils.hasText(memberId)) return ApiResponse.error(HttpStatus.BAD_REQUEST, "파라미터 오류");
String userRole = "";
MemberVo vo = AuthUtil.getUser();
if(vo != null && memberId.equals(vo.getLoginId())) {
userRole = vo.getRole();
}
return ApiResponse.ok(userRole);
}
// rememberMe 확인용 // rememberMe 확인용
@GetMapping(value = "rememberCheck") @GetMapping(value = "rememberCheck")
public ApiResponse<?> rememberCheck(HttpServletRequest request) { public ApiResponse<?> rememberCheck(HttpServletRequest request) {
@ -260,14 +328,11 @@ public class UserController {
/** /**
* 사원 목록 전체 조회 * 사원 목록 전체 조회
*
*
*
*/ */
@ParameterCheck @ParameterCheck
@GetMapping("/allUserList") @GetMapping("/allUserList")
public ApiResponse<MapDto> getallUserList() { public ApiResponse<MapDto> selectallUserList() {
List<MapDto> allUserList = netmemberservice.getallUserList(); List<MapDto> allUserList = netmemberservice.selectallUserList();
MemberVo user = AuthUtil.getUser(); MemberVo user = AuthUtil.getUser();
MapDto outData = new MapDto(); MapDto outData = new MapDto();
@ -276,6 +341,27 @@ public class UserController {
return ApiResponse.ok(outData); return ApiResponse.ok(outData);
} }
@PatchMapping("/updateInfo")
public ApiResponse<?> updateUserInfo(@ReqMap MapDto map,
@RequestPart(value = "profileFile", required = false) MultipartFile profileFile
) throws IOException {
Long userId = AuthUtil.getUser().getId();
map.put("memberId", userId);
netmemberservice.updateUserInfo(map, profileFile);
return ApiResponse.ok("수정 완료");
}
@PatchMapping("/updateColorYon")
public ApiResponse<Integer> updateColorYon(@ReqMap MapDto map) {
return ApiResponse.ok(commoncodservice.updateColorYon(map));
}
@PatchMapping("/updateColorChange")
public ApiResponse<Integer> updateColorChange(@ReqMap MapDto map) {
return ApiResponse.ok(commoncodservice.updateColorChange(map));
}
@Guest @Guest
@GetMapping("get1") @GetMapping("get1")
public ApiResponse<?> getAuthTest1() { public ApiResponse<?> getAuthTest1() {

View File

@ -0,0 +1,156 @@
package io.company.localhost.controller.common;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.vo.WeatherVo;
import lombok.RequiredArgsConstructor;
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/weather")
public class WeatherController {
@Value("${api.weather.key}")
private String weatherApiKey;
private final ObjectMapper objectMapper;
@GetMapping
public ApiResponse<MapDto> getWeather(@RequestParam("lat") double lat,@RequestParam("lon") double lon) throws Exception {
String url = String.format(
"https://api.openweathermap.org/data/2.5/forecast?lat=%f&lon=%f&appid=%s&units=metric&lang=kr",
lat, lon, weatherApiKey
);
RestTemplate restTemplate = new RestTemplate();
String response = restTemplate.getForObject(url, String.class);
List<WeatherVo> list = this.convertDailyForecast(response);
MapDto map = new MapDto();
map.put("weatherInfo", response);
map.put("dailyWeatherList", list);
return ApiResponse.ok(map);
}
/**
* 일별 데이터 전환
*
* @param jsonData
* @return
* @throws Exception
*/
private List<WeatherVo> convertDailyForecast(String jsonData) throws Exception {
JsonNode nodeData = objectMapper.readTree(jsonData);
JsonNode forecastList = nodeData.get("list");
// 현재 날짜 시간 계산
LocalDate today = LocalDate.now();
LocalDateTime nowTime = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 날짜별 데이터를 그룹화
Map<String, List<String>> dailyWeathers = new HashMap<>();
Map<String, List<String>> dailyDescriptions = new HashMap<>();
Map<String, List<String>> dailyIcons = new HashMap<>();
// 오늘 예보 가장 가까운 예보 저장 변수
JsonNode closestForecastToday = null;
long minDiff = Long.MAX_VALUE;
// forecastList를 순회하며 데이터를 그룹화하고, 오늘의 경우 가장 가까운 forecast 선택
for (JsonNode forecast : forecastList) {
String dtTxt = forecast.get("dt_txt").asText();
String date = dtTxt.split(" ")[0]; // 날짜 추출 (: "2025-04-04")
JsonNode weather = forecast.get("weather").get(0);
String mainWeather = weather.get("main").asText();
String description = weather.get("description").asText();
String icon = weather.get("icon").asText();
// 해당 날짜의 리스트에 추가 (map이 없으면 생성)
dailyWeathers.computeIfAbsent(date, k -> new ArrayList<>()).add(mainWeather);
dailyDescriptions.computeIfAbsent(date, k -> new ArrayList<>()).add(description);
dailyIcons.computeIfAbsent(date, k -> new ArrayList<>()).add(icon);
// 오늘 날짜의 forecast라면 현재 시간과의 차이 계산
if (date.equals(today.toString())) {
LocalDateTime forecastTime = LocalDateTime.parse(dtTxt, formatter);
long diff = Math.abs(Duration.between(forecastTime, nowTime).toMillis());
if (diff < minDiff) {
minDiff = diff;
closestForecastToday = forecast;
}
}
}
// 최종적으로 날짜의 대표 날씨 결정
List<WeatherVo> dailyWeatherList = new ArrayList<>();
for (String date : dailyWeathers.keySet()) {
String repMainWeather;
String repDescription;
String repIcon;
// 오늘인 경우, 가장 가까운 forecast의 아이콘과 설명 사용
if (date.equals(today.toString()) && closestForecastToday != null) {
JsonNode weather = closestForecastToday.get("weather").get(0);
repMainWeather = weather.get("main").asText();
repDescription = weather.get("description").asText();
repIcon = weather.get("icon").asText();
} else {
// 기타 날짜는 기존 방식대로 가장 빈번한 날씨 상태 선택
List<String> weathers = dailyWeathers.get(date);
List<String> descriptions = dailyDescriptions.get(date);
List<String> icons = dailyIcons.get(date);
Map<String, Integer> weatherCounts = new HashMap<>();
for (String w : weathers) {
weatherCounts.put(w, weatherCounts.getOrDefault(w, 0) + 1);
}
repMainWeather = "";
int maxCount = 0;
for (Map.Entry<String, Integer> entry : weatherCounts.entrySet()) {
if (entry.getValue() > maxCount) {
maxCount = entry.getValue();
repMainWeather = entry.getKey();
}
}
int repIndex = weathers.indexOf(repMainWeather);
repDescription = descriptions.get(repIndex);
repIcon = icons.get(repIndex);
}
dailyWeatherList.add(new WeatherVo(date, repMainWeather, repDescription, repIcon));
}
return dailyWeatherList;
}
}

View File

@ -0,0 +1,42 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : CommutersMapper.java
* @author : 박지윤
* @date : 24.03.10
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.03.10 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import io.company.localhost.common.dto.MapDto;
@Mapper
public interface CommutersMapper {
int insertCommuters(MapDto map);
int updateLeaveTime(MapDto map);
List<MapDto> selectCommutersByMonth(int year, int month);
List<MapDto> selectTodayCommuterInfo(Integer memberSeq);
List<MapDto> selectTodayCommuter();
// int updateCommuterProject(MapDto map);
int deleteCommuters(MapDto map);
MapDto selectUserLeaveWorkList(MapDto map);
}

View File

@ -0,0 +1,20 @@
package io.company.localhost.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import io.company.localhost.common.dto.MapDto;
@Mapper
public interface LocalevntMapper {
int insertEvent(MapDto map);
int selectCheckEvent(MapDto map);
List<MapDto> selectEventList(MapDto map);
int deleteEvent(MapDto map);
}

View File

@ -18,6 +18,7 @@ import java.util.List;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.vo.MemberVo; import io.company.localhost.vo.MemberVo;
@ -32,11 +33,30 @@ public interface NetmemberMapper {
int selectCheckId(String memberIds); int selectCheckId(String memberIds);
int selectCheckPhone(String memberTel);
int selectMemberColor(String memberCol);
int selectPwReset(MapDto map); int selectPwReset(MapDto map);
String selectPassword(String id); String selectPassword(String id);
int updatePassword(MapDto map); int updatePassword(MapDto map);
List<MapDto> getallUserList(); List<MapDto> selectallUserList();
void updateUserRole(Long id, String role);
List<MapDto> selectMemberBirthDay(MapDto map);
List<MapDto> selectRegisterMemberList();
void updateUserInfo(MapDto map);
MemberVo selectUserById(Long memberId);
int updateRegistMember(long memberSeq);
int updateRejectMember(long memberSeq);
} }

View File

@ -29,11 +29,12 @@ public interface NetprojctMapper {
int updateProject(MapDto map); int updateProject(MapDto map);
int insertProjectMember(Integer projctSeq);
int updateProjectMember(MapDto map);
List<MapDto> selectProjectMembers(int projctSeq);
List<MapDto> selectProjectLog(int projctSeq); List<MapDto> selectProjectLog(int projctSeq);
int deleteProject(MapDto map);
List<MapDto> selectUserProjectPeriod(int projectSeq);
List<MapDto> selectUserProjectPeriod2(int memberSeq);
} }

View File

@ -0,0 +1,40 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : PromemberMapper.java
* @author : 박지윤
* @date : 24.02.20
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.02.20 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import io.company.localhost.common.dto.MapDto;
@Mapper
public interface PromemberMapper {
int insertProjectMember(MapDto map);
int updateProjectMembers(MapDto map);
int insertNewMemberToProjects(Integer memberSeq);
int updateProjectMember(MapDto map);
List<MapDto> selectProjectMembers(int projctSeq);
List<MapDto> selectMemberProjects(int memberSeq);
int deletePromember(MapDto map);
}

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : VotDetailMapper.java
* @author : 공현지
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;
@ -11,6 +25,6 @@ public interface VotDetailMapper {
Long insertdetail(MapDto map); Long insertdetail(MapDto map);
List<MapDto> getVoteDetails(int locvotSeq); List<MapDto> selectVoteDetailsResult(MapDto map);
} }

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : VotMemberMapper.java
* @author : 공현지
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;
@ -11,10 +25,6 @@ public interface VotMemberMapper {
void insertmem(MapDto map); void insertmem(MapDto map);
List<MapDto> getVoteMember(Integer locvotSeq); List<MapDto> selectVoteMember(Integer locvotSeq);
} }

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : VotRecordMapper.java
* @author : 공현지
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
@ -7,8 +21,6 @@ import io.company.localhost.common.dto.MapDto;
@Mapper @Mapper
public interface VotRecordMapper { public interface VotRecordMapper {
int yesVotetotal(MapDto map);
Long insertCheckedNums(MapDto map); Long insertCheckedNums(MapDto map);
} }

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : VotchoiceMapper.java
* @author : 공현지
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;

View File

@ -44,4 +44,6 @@ public interface commoncodMapper {
Long selectcheckCategoryExists(MapDto map); Long selectcheckCategoryExists(MapDto map);
List<MapDto> selectVacationType(); List<MapDto> selectVacationType();
List<MapDto> selectCodeList(MapDto map);
} }

View File

@ -1,13 +1,25 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : localbordMapper.java
* @author : 서지희
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.01.07 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultType;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.vo.FileVo;
@Mapper @Mapper
public interface localbordMapper { public interface localbordMapper {
@ -33,7 +45,7 @@ public interface localbordMapper {
void deleteCommentsByBoardId(MapDto map); void deleteCommentsByBoardId(MapDto map);
// 게시물 수정 // 게시물 수정
void updateBoard(MapDto map); int updateBoard(MapDto map);
// 기존 반응 조회 // 기존 반응 조회
MapDto selectReaction(MapDto map); MapDto selectReaction(MapDto map);
@ -56,20 +68,14 @@ public interface localbordMapper {
// 댓글/대댓글 수정 // 댓글/대댓글 수정
void updateComment(MapDto map); void updateComment(MapDto map);
// 대댓글인지 확인
boolean selectIsReply(MapDto map);
// 댓글에 대댓글이 있는지 확인 // 댓글에 대댓글이 있는지 확인
boolean selectHasReplies(MapDto map); int selectReplyCount(Long parentId);
// 댓글 내용만 삭제 처리 (대댓글 유지) // 댓글 내용만 삭제 처리 (대댓글 유지)
void updateSoftDeleteComment(MapDto map); void updateSoftDeleteComment(Long commentId);
// 댓글 삭제 (대댓글 없음) // 댓글 삭제 (대댓글 없음)
void deleteComment(MapDto map); void deleteComment(Long commentId);
// 대댓글 삭제
void deleteReply(MapDto map);
// 댓글 비밀번호 조회 // 댓글 비밀번호 조회
String selectCommentPassword(int commentId); String selectCommentPassword(int commentId);
@ -98,6 +104,36 @@ public interface localbordMapper {
//댓글id 확인 //댓글id 확인
MapDto selectCommentById(int commentId); MapDto selectCommentById(int commentId);
void insertAttachments(MapDto map);
List<String> selectDelFileInfo(String[] array);
void deleteFileInfo(String[] array);
String selectUserProfileImg(String userId);
MapDto selectBoardDetail2(Long boardId);
int insertUploadEditorImageInfo(MapDto map);
int updateBoardIndexToFile(MapDto map);
List<FileVo> selectFilesInfo(MapDto map);
void deleteFiles(MapDto map);
void deleteGoodOrBadByBoardId(MapDto map);
List<FileVo> selectFilesBoardIndexIsNull();
int deleteTrashFileData(FileVo vo);
void deleteGoodOrBadByCommentId(MapDto map);
MapDto selectMyBoardReaction(MapDto boardDetail);
MapDto selectMyBoardReactions(MapDto param);
} }

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : localvacaMapper.java
* @author : 서지희
* @date : 25.02.06
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.06 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;
@ -12,17 +26,23 @@ import io.company.localhost.common.dto.MapDto;
public interface localvacaMapper { public interface localvacaMapper {
void insertVacation(MapDto map); void insertVacation(MapDto map);
void deleteVacation(Long vacationId); void deleteVacation(@Param("vacationIds") List<Long> vacationIds);
List<MapDto> selectVacations(@Param("year") int year, @Param("month") int month); List<MapDto> selectVacations(@Param("year") int year, @Param("month") int month);
List<MapDto> selectUsedVacations(@Param("userId") Long userId); List<MapDto> selectUsedVacations(@Param("userId") Long userId, @Param("year") int year);
List<MapDto> selectReceivedVacations(@Param("userId") Long userId); List<MapDto> selectReceivedVacations(@Param("userId") Long userId, @Param("year") int year);
List<MapDto> selectEmployeeRemainingVacation(); List<MapDto> selectEmployeeRemainingVacation();
List<MapDto> selectSentVacationCount(MapDto map); List<MapDto> selectSentVacationCount(MapDto map);
Long findVacationIdByDate(@Param("userId") Long employeeId, @Param("date") String date);
void updateVacation(MapDto vacation);
List<MapDto> selectMemberVacationsInMain(@Param("year") int year, @Param("month") int month);
} }

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.mapper
* @fileName : localvoteMapper.java
* @author : 공현지
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.mapper; package io.company.localhost.mapper;
import java.util.List; import java.util.List;
@ -13,9 +27,15 @@ public interface localvoteMapper {
Long insertVote(MapDto map); Long insertVote(MapDto map);
List<MapDto> getVoteList(MapDto map); List<MapDto> selectVoteList(MapDto map);
Long updateEndData(MapDto map); Long updateEndData(MapDto map);
Long updateRandomResult(MapDto selectedItem);
Long updateDeleteData(MapDto map);
List<MapDto> selectVoteListWithDetails(MapDto map);
} }

View File

@ -23,22 +23,24 @@ import io.company.localhost.common.dto.MapDto;
@Mapper @Mapper
public interface worddictyMapper { public interface worddictyMapper {
List<MapDto> getWordList(MapDto map); List<MapDto> selectWordList(MapDto map);
Long insertWord(MapDto map); Long insertWord(MapDto map);
Long updateWord(MapDto map); Long updateWord(MapDto map);
MapDto getWordDetail(MapDto map); MapDto selectWordDetail(MapDto map);
int getTotal(MapDto map); int getTotal(MapDto map);
Long updateword(MapDto map); Long updateword(MapDto map);
List<MapDto> selectIndexCategory();
int updateBoardIndexToFile(MapDto map);
List<String> selectDelFileInfo(String[] array);
void deleteFileInfo(String[] array);
} }

View File

@ -0,0 +1,123 @@
/************************************************************
*
* @packageName : io.company.localhost.CommutersService
* @fileName : CommutersService.java
* @author : 박지윤
* @date : 25.03.10
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.03.10 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.service;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;
import org.springframework.stereotype.Service;
import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.CommutersMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class CommutersService {
private final CommutersMapper commutersMapper;
/**
* 출퇴근 등록
*
* @param map
* @return
*/
public int insertCommuters(MapDto map) {
map.put("commutDay", LocalDateTime.now());
map.put("commutCme", LocalTime.now());
int result = commutersMapper.insertCommuters(map);
return result;
}
/**
* 퇴근 시간 업데이트
* @param map
* @return
*/
public boolean updateLeaveTime(MapDto map) {
if(map.get("commutLve") != null) {
map.put("commutLve", null);
map.put("commutOut", null);
map.put("projctLve", null);
} else {
map.put("commutLve", LocalTime.now());
}
return commutersMapper.updateLeaveTime(map) > 0;
}
/**
* 현재 달의 모든 출근 정보 조회
*
* @param year, month
* @return
*/
public List<MapDto> selectCommutersByMonth(int year, int month) {
return commutersMapper.selectCommutersByMonth(year, month);
}
/**
* 오늘 사용자 출근 정보 조회
*
* @param memberSeq
* @return
*/
public List<MapDto> selectTodayCommuterInfo(Integer memberSeq) {
return commutersMapper.selectTodayCommuterInfo(memberSeq);
}
/**
* 오늘 출근 모든 사용자 조회
*
* @param
* @return
*/
public List<MapDto> selectTodayCommuter() {
return commutersMapper.selectTodayCommuter();
}
/**
* 출근 프로젝트 업데이트
*
* @param map
* @return
*/
/*
* public boolean updateCommuterProject(MapDto map) { return
* commutersMapper.updateCommuterProject(map) > 0; }
*/
/**
* 사용자의 퇴근 기록 조회
*
* @return
*/
public ApiResponse<MapDto> selectUserLeaveWorkList(@ReqMap MapDto map) {
map.put("currentDate", LocalDateTime.now());
return ApiResponse.ok(commutersMapper.selectUserLeaveWorkList(map));
}
}

View File

@ -19,11 +19,15 @@ import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.UUID; import java.util.UUID;
import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.company.localhost.utils.FileUtil;
import io.company.localhost.vo.UploadFile;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Service @Service
@ -34,6 +38,11 @@ public class FileService {
@Value("${filePath.profile}") @Value("${filePath.profile}")
private String uploadPath; private String uploadPath;
@Value("${filePath.boardfile}")
private String boardFilePath;
private final FileUtil fileUtil;
/** /**
* 파일 업로드 * 파일 업로드
* *
@ -65,4 +74,79 @@ public class FileService {
throw new RuntimeException("파일 업로드 실패: " + e.getMessage()); throw new RuntimeException("파일 업로드 실패: " + e.getMessage());
} }
} }
/**
* 게시판 파일 업로드
*
* @param file
* @return
* @throws RuntimeException
*/
public String boardUploadFile(MultipartFile file) {
try {
System.out.println(file);
// 원본 파일명
String originalFilename = file.getOriginalFilename();
// 파일 확장자
String extension = FilenameUtils.getExtension(originalFilename);
// UUID를 사용하여 고유한 파일명 생성
String newFilename = UUID.randomUUID().toString() + "." + extension;
// 최종 저장 경로 생성 (기본경로 + 파일명)
Path targetPath = Paths.get(boardFilePath, newFilename);
// 저장될 디렉토리가 없는 경우 생성
Files.createDirectories(targetPath.getParent());
// 동일 파일명이 있을 경우 덮어쓰기
Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
// 저장된 파일의 상대 경로 반환
return targetPath.toString();
} catch (IOException e) {
throw new RuntimeException("파일 업로드 실패: " + e.getMessage());
}
}
/**
* 게시판 다중파일 업로드
*
* @param files
* @return
* @throws IOException
*/
public List<UploadFile> boardUploadFiles(List<MultipartFile> files) throws IOException {
return fileUtil.uploadFiles(boardFilePath, files);
}
/**
* 파일 삭제
*
* @param path 경로+파일명
* @return
*/
public boolean removeFile(String path) {
return fileUtil.removeFile(path);
}
/**
* 파일 삭제
*
* @param path
* @param fileName
* @return
*/
public boolean removeFile(String path, String fileName) {
return fileUtil.removeFile(path, fileName);
}
/**
* 게시글 파일 삭제
*
* @param fileName
* @return
*/
public boolean removeBoardFile(String fileName) {
return fileUtil.removeFile(boardFilePath, fileName);
}
} }

View File

@ -0,0 +1,53 @@
/************************************************************
*
* @packageName : io.company.localhost.service
* @fileName : LocalbordService.java
* @author : 박성용
* @date : 25.03.30
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.03.30 박성용 최초 생성
*
*************************************************************/
package io.company.localhost.service;
import java.util.List;
import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.LocalevntMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Service
@RequiredArgsConstructor
@Slf4j
public class LocalevntService {
private final LocalevntMapper localevntMapper;
public int insertEvent(MapDto map) {
return localevntMapper.insertEvent(map);
}
public int selectCheckEvent(MapDto map) {
return localevntMapper.selectCheckEvent(map);
}
public List<MapDto> selectEventList(MapDto map) {
return localevntMapper.selectEventList(map);
}
public int deleteEvent(MapDto map) {
return localevntMapper.deleteEvent(map);
}
}

View File

@ -0,0 +1,142 @@
/************************************************************
*
* @packageName : io.company.localhost.CommutersService
* @fileName : MainService.java
* @author : 박성용
* @date : 25.03.17
* @description : 메인페이지 비지니스 로직
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.03.17 박성용 최초 생성
*
*************************************************************/
package io.company.localhost.service;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.utils.AuthUtil;
import io.company.localhost.vo.MemberVo;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class MainService {
private final commoncodService commoncodService;
private final NetmemberService netmemberService;
private final localvacaService localvacaService;
private final LocalevntService localevntService;
private final CommutersService commutersService;
/**
* 메인페이지 카테고리 메뉴 조회
*
* @return
*/
public ApiResponse<List<MapDto>> selectMainMenuCategory() {
return ApiResponse.ok(commoncodService.selectCodeList("300", "200"));
}
/**
* 메인페이지 이벤트 리스트
*
* @param map (year, month)
* @return { 생일자, 휴가자, 생일파티, 회식, 티타임, 워크샵 } 일정
*/
public ApiResponse<MapDto> selectEventList(MapDto map) {
int year = Integer.valueOf(map.getString("year"));
int month = Integer.valueOf(map.getString("month"));
map.put("memberBirthdayList", netmemberService.selectMemberBirthDay(map)); //생일자 조회
map.put("memberVacationList", localvacaService.selectMemberVacationsInMain(year, month)); //휴가자 조회
map.put("eventList", localevntService.selectEventList(map));
return ApiResponse.ok(map);
}
/**
* 이벤트 생성/삭제
*
* @param map (code, date)
* @return
*/
public ApiResponse<String> toggleEvent(MapDto map) {
if(localevntService.selectCheckEvent(map) > 0) {
localevntService.deleteEvent(map);
return ApiResponse.okMessage("이벤트 삭제");
} else {
return ApiResponse.error(HttpStatus.CONFLICT, "해당 이벤트가 존재하지 않습니다");
}
}
public ApiResponse<String> insertEvent(MapDto map) {
if(localevntService.selectCheckEvent(map) > 0) {
return ApiResponse.error(HttpStatus.CONFLICT, "이미 동일한 이벤트가 존재합니다");
} else {
localevntService.insertEvent(map);
return ApiResponse.okMessage("이벤트 추가");
}
}
/**
* 사원 등록 대상자 목록 조회
*
* @return
*/
public ApiResponse<List<MapDto>> registerMemberList() {
return ApiResponse.ok(netmemberService.selectRegisterMemberList());
}
/**
* 사원 등록 승인
* @param memberSeq
*
* @return
*/
public ApiResponse<String> registerMember(long memberSeq) {
Long loginUserId = AuthUtil.getUser().getId();
MemberVo user = netmemberService.getUserInfoById(loginUserId);
if(user.getId() != loginUserId || !"ROLE_ADMIN".equals(user.getRole())) {
return ApiResponse.error(HttpStatus.FORBIDDEN, "사용 권한 없음");
}
int result = netmemberService.registerMember(memberSeq);
return result == 1 ? ApiResponse.ok("사원 등록 성공") : ApiResponse.ok("사원 등록 실패");
}
/**
* 사원 등록 거절
*
* @param memberSeq
* @return
*/
public ApiResponse<String> rejectMember(long memberSeq) {
Long loginUserId = AuthUtil.getUser().getId();
MemberVo user = netmemberService.getUserInfoById(loginUserId);
if(user.getId() != loginUserId || !"ROLE_ADMIN".equals(user.getRole())) {
return ApiResponse.error(HttpStatus.UNAUTHORIZED, "사용 권한 없음");
}
int result = netmemberService.rejectMember(memberSeq);
return result == 1 ? ApiResponse.ok("미승인 대상자 등록") : ApiResponse.ok("미승인 대상자 등록 실패");
}
public ApiResponse<MapDto> getUserLeaveRecord(MapDto map) {
return commutersService.selectUserLeaveWorkList(map);
}
}

View File

@ -14,6 +14,7 @@
*************************************************************/ *************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.io.IOException;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
@ -21,9 +22,12 @@ import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.NetmemberMapper; import io.company.localhost.mapper.NetmemberMapper;
import io.company.localhost.mapper.PromemberMapper;
import io.company.localhost.mapper.commoncodMapper; import io.company.localhost.mapper.commoncodMapper;
import io.company.localhost.vo.MemberVo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Service @Service
@ -31,6 +35,7 @@ import lombok.RequiredArgsConstructor;
public class NetmemberService { public class NetmemberService {
private final NetmemberMapper memberMapper; private final NetmemberMapper memberMapper;
private final commoncodMapper commoncodMapper; private final commoncodMapper commoncodMapper;
private final PromemberMapper promemberMapper;
private final DelegatingPasswordEncoder passwordEncoder; private final DelegatingPasswordEncoder passwordEncoder;
private final FileService fileService; private final FileService fileService;
@ -54,7 +59,7 @@ public class NetmemberService {
map.put("memberRol", "ROLE_MEMBER"); map.put("memberRol", "ROLE_MEMBER");
map.put("memberPos", 500107); map.put("memberPos", 500107);
map.put("memberTkn", "Null"); map.put("memberTkn", "Null");
map.put("memberPrm", "Y"); map.put("memberPrm", "N");
map.put("memberDel", "N"); map.put("memberDel", "N");
map.put("memberLea", "N"); map.put("memberLea", "N");
map.put("memberRdt", LocalDateTime.now()); map.put("memberRdt", LocalDateTime.now());
@ -73,6 +78,10 @@ public class NetmemberService {
commoncodMapper.updateColorYon(colorMap); commoncodMapper.updateColorYon(colorMap);
// 모든 프로젝트에 새로운 멤버 추가
Integer newMemberSeq = map.getInt("MEMBERSEQ");
promemberMapper.insertNewMemberToProjects(newMemberSeq);
return result; return result;
} }
@ -86,14 +95,45 @@ public class NetmemberService {
return memberMapper.selectCheckId(memberIds) > 0; return memberMapper.selectCheckId(memberIds) > 0;
} }
/**
* 전화번호 중복 체크
*
* @param memberTel
* @return
*/
public boolean selectCheckPhone(String memberTel) {
return memberMapper.selectCheckPhone(memberTel) > 0;
}
/**
* 색상 중복 체크
*
* @param memberCol
* @return
*/
public boolean selectMemberColor(String memberCol) {
return memberMapper.selectMemberColor(memberCol) > 0;
}
/** /**
* 사원 목록 전체 조회 * 사원 목록 전체 조회
* *
* @param * @param
* @return * @return
*/ */
public List<MapDto> getallUserList() { public List<MapDto> selectallUserList() {
return memberMapper.getallUserList(); return memberMapper.selectallUserList();
}
/**
* 사원 권한 업데이트
*
* @param
* @return
*/
public void updateUserRole(Long id, String newRole) {
memberMapper.updateUserRole(id, newRole);
} }
/** /**
@ -143,4 +183,50 @@ public class NetmemberService {
return memberMapper.updatePassword(map) > 0; return memberMapper.updatePassword(map) > 0;
} }
/**
* 멤버 생일 조회
*
* @param map (year, month)
* @return
*/
public List<MapDto> selectMemberBirthDay(MapDto map) {
return memberMapper.selectMemberBirthDay(map);
}
/**
* 등록 대기 멤버 조회
*
* @param map
* @return
*/
public List<MapDto> selectRegisterMemberList() {
return memberMapper.selectRegisterMemberList();
}
public void updateUserInfo(MapDto map, MultipartFile profileFile) throws IOException {
// 프로필 이미지 저장 처리
if (profileFile != null && !profileFile.isEmpty()) {
String savedFilePath = fileService.uploadFile(profileFile);
map.put("memberPrf", savedFilePath); // DB 컬럼에 맞게 추가
}
System.out.println(map);
// DB 업데이트
memberMapper.updateUserInfo(map);
}
public MemberVo getUserInfoById(Long memberId) {
return memberMapper.selectUserById(memberId);
}
public int registerMember(long memberSeq) {
return memberMapper.updateRegistMember(memberSeq);
}
public int rejectMember(long memberSeq) {
return memberMapper.updateRejectMember(memberSeq);
}
} }

View File

@ -14,14 +14,16 @@
*************************************************************/ *************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.math.BigInteger;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.util.List; import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.CommutersMapper;
import io.company.localhost.mapper.NetprojctMapper; import io.company.localhost.mapper.NetprojctMapper;
import io.company.localhost.mapper.PromemberMapper;
import io.company.localhost.mapper.commoncodMapper; import io.company.localhost.mapper.commoncodMapper;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@ -30,6 +32,8 @@ import lombok.RequiredArgsConstructor;
public class NetprojctService { public class NetprojctService {
private final commoncodMapper commoncodMapper; private final commoncodMapper commoncodMapper;
private final NetprojctMapper netprojctMapper; private final NetprojctMapper netprojctMapper;
private final PromemberMapper promemberMapper;
private final CommutersMapper commutersMapper;
/** /**
@ -52,22 +56,37 @@ public class NetprojctService {
public int insertProject(MapDto map) { public int insertProject(MapDto map) {
map.put("projctCdt", LocalDateTime.now()); map.put("projctCdt", LocalDateTime.now());
int result = netprojctMapper.insertProject(map); int result = netprojctMapper.insertProject(map);
Integer color = map.getInt("projctCol"); Integer color = map.getInt("projctCol");
// 컬러 업데이트
MapDto colorMap = new MapDto(); MapDto colorMap = new MapDto();
colorMap.put("color", color); colorMap.put("color", color);
colorMap.put("type", "YNP"); colorMap.put("type", "YNP");
commoncodMapper.updateColorYon(colorMap); commoncodMapper.updateColorYon(colorMap);
Integer projctSeq = map.getInt("PROJCTSEQ"); Integer projctSeq = map.getInt("PROJCTSEQ");
netprojctMapper.insertProjectMember(projctSeq); // 비활성화된 사용자 목록 받아오기
List<Integer> disabledMembers = (List<Integer>) map.get("disabledMembers");
// 프로젝트 멤버 추가 (비활성화된 사용자 정보 포함)
MapDto paramMap = new MapDto();
paramMap.put("projctSeq", projctSeq);
paramMap.put("disabledMembers", disabledMembers);
promemberMapper.insertProjectMember(paramMap);
return result; return result;
} }
/**
* 프로젝트 수정
*
* @param map
* @return
*/
/** /**
* 프로젝트 수정 * 프로젝트 수정
* *
@ -96,30 +115,20 @@ public class NetprojctService {
commoncodMapper.updateColorChange(OldColorMap); commoncodMapper.updateColorChange(OldColorMap);
} }
// 멤버 상태 업데이트
Integer projctSeq = map.getInt("projctSeq");
List<Integer> disabledMembers = (List<Integer>) map.get("disabledMembers");
if (disabledMembers != null) {
MapDto memberMap = new MapDto();
memberMap.put("projctSeq", projctSeq);
memberMap.put("disabledMembers", disabledMembers);
promemberMapper.updateProjectMembers(memberMap);
}
return result; return result;
} }
/**
* 프로젝트 참여, 미참여 member
*
* @param map
* @return
*/
public boolean updateProjectMember(MapDto map) {
return netprojctMapper.updateProjectMember(map) > 0;
}
/**
* 프로젝트 멤버리스트 조회
*
* @param
* @return
*/
public List<MapDto> getProjectMembers(int projctSeq) {
return netprojctMapper.selectProjectMembers(projctSeq);
}
/** /**
* 프로젝트 log 조회 * 프로젝트 log 조회
@ -131,5 +140,43 @@ public class NetprojctService {
return netprojctMapper.selectProjectLog(projctSeq); return netprojctMapper.selectProjectLog(projctSeq);
} }
/**
* 프로젝트 삭제
*
* @param
* @return
*/
public boolean deleteProject(MapDto map) {
promemberMapper.deletePromember(map);
commutersMapper.deleteCommuters(map);
boolean result = netprojctMapper.deleteProject(map) > 0;
Integer color = map.getInt("projctCol");
MapDto colorMap = new MapDto();
colorMap.put("color", color);
colorMap.put("type", "YNP");
commoncodMapper.updateColorChange(colorMap);
return result;
}
/**
* 프로젝트 모든 사용자 참여기간 조회
*
* @param
* @return
*/
public List<MapDto> selectUserProjectPeriod(int projctSeq) {
return netprojctMapper.selectUserProjectPeriod(projctSeq);
}
public List<MapDto> selectUserProjectPeriod2(int memberSeq) {
return netprojctMapper.selectUserProjectPeriod2(memberSeq);
}
} }

View File

@ -0,0 +1,63 @@
/************************************************************
*
* @packageName : io.company.localhost.PromemberService
* @fileName : PromemberService.java
* @author : 박지윤
* @date : 25.02.20
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.20 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.service;
import java.util.List;
import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.PromemberMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class ProMemberService {
private final PromemberMapper promemberMapper;
/**
* 프로젝트 참여, 미참여 member
*
* @param map
* @return
*/
public boolean updateProjectMember(MapDto map) {
return promemberMapper.updateProjectMember(map) > 0;
}
/**
* 프로젝트 멤버리스트 조회
*
* @param
* @return
*/
public List<MapDto> selectProjectMembers(int projctSeq) {
return promemberMapper.selectProjectMembers(projctSeq);
}
/**
* 사용자가 속한 프로젝트 조회
*
* @param
* @return
*/
public List<MapDto> selectMemberProjects(int memberSeq) {
return promemberMapper.selectMemberProjects(memberSeq);
}
}

View File

@ -22,6 +22,7 @@ import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.common.exception.NotFoundHandler; import io.company.localhost.common.exception.NotFoundHandler;
import io.company.localhost.mapper.commoncodMapper; import io.company.localhost.mapper.commoncodMapper;
import io.company.localhost.utils.StringUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Service @Service
@ -34,14 +35,6 @@ public class commoncodService {
return commoncodmapper.selectWordCategory(); return commoncodmapper.selectWordCategory();
} }
public Long insertCategory(MapDto map) {
Long count = commoncodmapper.selectcheckCategoryExists(map);
if(count > 0) {
return -1L;
}
return commoncodmapper.insertCategory(map);
}
public List<MapDto> selectColorList(String type) { public List<MapDto> selectColorList(String type) {
return commoncodmapper.selectColorList(type); return commoncodmapper.selectColorList(type);
} }
@ -68,4 +61,22 @@ public class commoncodService {
// 데이터가 비어있으면 리스트 반환 (null 방지) // 데이터가 비어있으면 리스트 반환 (null 방지)
return (codeList != null) ? codeList : new ArrayList<>(); return (codeList != null) ? codeList : new ArrayList<>();
} }
public List<MapDto> selectCodeList(String code1, String code2) {
if(!StringUtil.isNumeric(code1) || !StringUtil.isNumeric(code2)) throw new IllegalArgumentException("파라미터는 반드시 숫자 타입이여야 함");
MapDto map = new MapDto();
map.put("CMNCODLV1", code1);
map.put("CMNCODLV2", code2.substring(0, 1));
return commoncodmapper.selectCodeList(map);
}
public int updateColorYon(MapDto map) {
return commoncodmapper.updateColorYon(map);
}
public int updateColorChange(MapDto map) {
return commoncodmapper.updateColorChange(map);
}
} }

View File

@ -1,39 +1,69 @@
/************************************************************
*
* @packageName : io.company.localhost.service
* @fileName : localbordService.java
* @author : 서지희
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.01.07 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.io.ByteArrayInputStream; import java.io.IOException;
import java.math.BigInteger; import java.math.BigInteger;
import java.nio.charset.StandardCharsets; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.UUID; import java.util.UUID;
import org.springframework.http.HttpStatus;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.localbordMapper; import io.company.localhost.mapper.localbordMapper;
import io.company.localhost.utils.AuthUtil; import io.company.localhost.utils.AuthUtil;
import io.company.localhost.utils.BlobUtil;
import io.company.localhost.utils.PageUtil; import io.company.localhost.utils.PageUtil;
import io.company.localhost.vo.FileVo;
import io.company.localhost.vo.MemberVo;
import io.company.localhost.vo.UploadFile;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Service @Service
@RequiredArgsConstructor @RequiredArgsConstructor
@Slf4j
public class localbordService { public class localbordService {
private final localbordMapper boardMapper; private final localbordMapper boardMapper;
private final FileService fileService;
private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
private final PasswordEncoder passwordEncoder;
public List<MapDto> selectNotices(MapDto map) { public List<MapDto> selectNotices(MapDto map) {
map.put("searchKeyword", null);
List<MapDto> posts = boardMapper.selectNotices(map); List<MapDto> posts = boardMapper.selectNotices(map);
enrichPostsWithAdditionalData(posts); enrichPostsWithAdditionalData(posts);
return posts;
return posts; // 검색 없이 전체 공지사항 리스트 반환
} }
public PageInfo<MapDto> selectGeneralPosts(MapDto map) { public PageInfo<MapDto> selectGeneralPosts(MapDto map) {
System.out.println(map);
int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1; int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1;
int size = map.getString("size") != null ? Integer.parseInt(map.getString("size")) : 10; int size = map.getString("size") != null ? Integer.parseInt(map.getString("size")) : 10;
@ -42,18 +72,41 @@ public class localbordService {
map.put("orderBy", "date"); map.put("orderBy", "date");
} }
PageHelper.startPage(page, size); String keyword = map.getString("searchKeyword");
boolean hasKeyword = keyword != null && !keyword.trim().isEmpty();
if (hasKeyword) {
// 전체 데이터를 가져와서 필터링
map.put("searchKeyword", null);
List<MapDto> allPosts = boardMapper.selectGeneralPosts(map);
enrichPostsWithAdditionalData(allPosts);
// 검색어 기반 필터링
List<MapDto> filtered = filterPostsByKeyword(allPosts, keyword.trim());
// Java에서 수동 페이징
int fromIndex = (page - 1) * size;
int toIndex = Math.min(fromIndex + size, filtered.size());
List<MapDto> pagedList = fromIndex >= filtered.size() ? new ArrayList<>() : filtered.subList(fromIndex, toIndex);
PageInfo<MapDto> pageInfo = new PageInfo<>(pagedList);
pageInfo.setTotal(filtered.size());
return PageUtil.redefineNavigation(pageInfo);
}
// 키워드 없으면 MyBatis에서 DB 페이징 처리
PageHelper.startPage(page, size);
List<MapDto> result = boardMapper.selectGeneralPosts(map); List<MapDto> result = boardMapper.selectGeneralPosts(map);
enrichPostsWithAdditionalData(result); enrichPostsWithAdditionalData(result);
return PageUtil.redefineNavigation(new PageInfo<>(result));
return PageUtil.redefineNavigation(new PageInfo<>(result, size));
} }
public void updateIncrementViewCount(Long boardId) { public void updateIncrementViewCount(Long boardId) {
boardMapper.updateIncrementViewCount(boardId); boardMapper.updateIncrementViewCount(boardId);
} }
@SuppressWarnings("unchecked")
@Transactional
public BigInteger insertBoard(MapDto map) { public BigInteger insertBoard(MapDto map) {
// 익명게시판이면 회원 정보를 null로 설정 // 익명게시판이면 회원 정보를 null로 설정
if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) { if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) {
@ -63,17 +116,33 @@ public class localbordService {
map.put("MEMBERSEQ", userId); map.put("MEMBERSEQ", userId);
} }
boardMapper.insertBoard(map); boardMapper.insertBoard(map);
//에디터 첨부 이미지 게시글 번호 업데이트
if(map.get("editorUploadedImgList") != null) {
ArrayList<String> editorUploadedImgList = (ArrayList<String>) map.get("editorUploadedImgList");
map.put("editorImgList", editorUploadedImgList);
this.updateBoardIndexToFile(map);
}
// 에디터 수정 업로드 에디터 이미지 삭제
if(map.get("editorDeleteImgList") != null) {
ArrayList<String> editorDeleteImgList = (ArrayList<String>) map.getList("editorDeleteImgList", String.class);
String[] array = editorDeleteImgList.stream().toArray(String[]::new);
this.deleteFileAndData(array);
}
return (BigInteger) map.get("LOCBRDSEQ"); return (BigInteger) map.get("LOCBRDSEQ");
} }
public void insertAttachment(MapDto map) { public void insertAttachment(MapDto map, MultipartFile file) {
String boardSeqStr = (String) map.get("CMNBRDSEQ"); String boardSeqStr = (String) map.get("CMNBRDSEQ");
Long boardSeq = Long.parseLong(boardSeqStr); Long boardSeq = Long.parseLong(boardSeqStr);
map.put("CMNBRDSEQ", boardSeq); map.put("CMNBRDSEQ", boardSeq);
String newFilename = UUID.randomUUID().toString(); String newFilename = UUID.randomUUID().toString();
map.put("CMNFLENAM", newFilename); map.put("CMNFLENAM", newFilename);
String Path = fileService.boardUploadFile(file);
map.put("CMNFLEPAT", Path);
boardMapper.insertAttachment(map); boardMapper.insertAttachment(map);
} }
@ -99,13 +168,51 @@ public class localbordService {
return boardMapper.selectAttachments(boardId); return boardMapper.selectAttachments(boardId);
} }
public void deleteBoard(MapDto map) { @Transactional
boardMapper.deleteCommentsByBoardId(map); public ApiResponse<String> deleteBoard(MapDto map) {
boardMapper.deleteBoard(map); boardMapper.deleteCommentsByBoardId(map); // 댓글 대댓글
boardMapper.deleteGoodOrBadByBoardId(map); // 좋아요 싫어요 삭제
this.deleteBoardFiles(map); // 파일 삭제
boardMapper.deleteBoard(map); // 게시글 삭제
return ApiResponse.ok("게시물이 삭제되었습니다.");
} }
public void updateBoard(MapDto map) { /**
boardMapper.updateBoard(map); * 게시글 첨부파일 에디터 이미지 파일 삭제
*
* @param map
*/
private void deleteBoardFiles(MapDto map) {
List<FileVo> list = this.selectFilesInfo(map); // 삭제 파일 정보 조회
for(FileVo vo : list) {
String fileName = vo.getCMNFLEPAT();
//if(!fileName.contains(vo.getCMNFLEEXT())) fileName = fileName + vo.getCMNFLEEXT();
fileService.removeFile(fileName); // 파일 삭제
}
this.deleteFiles(map); // 파일 데이터 삭제
}
/**
* 게시글 파일정보 삭제
* @param map
*/
public void deleteFiles(MapDto map) {
boardMapper.deleteFiles(map);
}
/**
* 게시글 파일 정보 조회
*
* @param map
* @return
*/
public List<FileVo> selectFilesInfo(MapDto map) {
return boardMapper.selectFilesInfo(map);
}
public int updateBoard(MapDto map) {
return boardMapper.updateBoard(map);
} }
public void procReactToBoard(MapDto map) { public void procReactToBoard(MapDto map) {
@ -124,20 +231,29 @@ public class localbordService {
PageHelper.startPage(page, size); PageHelper.startPage(page, size);
List<MapDto> result = boardMapper.selectComments(map); List<MapDto> result = boardMapper.selectComments(map);
enrichCommentsWithAdditionalData(result); // 댓글 데이터 보강 enrichCommentsWithAdditionalData(map, result); // 댓글 데이터 보강
return PageUtil.redefineNavigation(new PageInfo<>(result, size)); return PageUtil.redefineNavigation(new PageInfo<>(result, size));
} }
public List<MapDto> selectReply(MapDto map) { public List<MapDto> selectReply(MapDto map) {
return boardMapper.selectReply(map); return boardMapper.selectReply(map);
} }
public void insertCommentOrReply(MapDto map) { public void insertCommentOrReply(MapDto map) {
// 익명게시판이면 회원 정보를 null로 설정
if ("300102".equals(String.valueOf(map.get("LOCBRDTYP")))) {
map.put("MEMBERSEQ", null);
}else {
Long userId = AuthUtil.getUser().getId();
map.put("MEMBERSEQ", userId);
}
if (map.get("LOCCMTPNT") == null) { if (map.get("LOCCMTPNT") == null) {
map.put("LOCCMTPNT", null); map.put("LOCCMTPNT", null);
} }
boardMapper.insertCommentOrReply(map); boardMapper.insertCommentOrReply(map);
} }
public void updateComment(MapDto map) { public void updateComment(MapDto map) {
@ -145,18 +261,30 @@ public class localbordService {
} }
public void deleteComment(MapDto map) { public void deleteComment(MapDto map) {
boolean isReply = boardMapper.selectIsReply(map); Long commentId = (Long) map.get("LOCCMTSEQ");
// 댓글이 대댓글이 있는지 확인
if (isReply) { boolean hasReplies = boardMapper.selectReplyCount(commentId) > 0;
boardMapper.deleteReply(map);
} else {
boolean hasReplies = boardMapper.selectHasReplies(map);
if (hasReplies) { if (hasReplies) {
boardMapper.updateSoftDeleteComment(map); // 대댓글이 있는 경우, '삭제된 댓글입니다.' 변경 (소프트 삭제)
boardMapper.updateSoftDeleteComment(commentId);
} else { } else {
boardMapper.deleteComment(map); // 대댓글이 없는 경우, 완전 삭제
boardMapper.deleteComment(commentId);
} }
checkAndDeleteParentComment(map);
boardMapper.deleteGoodOrBadByCommentId(map);
}
private void checkAndDeleteParentComment(MapDto map) {
Long parentId = (Long) map.get("LOCCMTPNT");
if (parentId == null) return; // 부모가 없으면 종료
// 부모 댓글의 남아있는 대댓글 개수 확인
int remainingReplies = boardMapper.selectReplyCount(parentId);
if (remainingReplies == 0) {
// 남은 대댓글이 없으면 부모 댓글도 삭제
boardMapper.deleteComment(parentId);
} }
} }
@ -189,41 +317,21 @@ public class localbordService {
return boardMapper.selectCountCommentReactions(boardId); return boardMapper.selectCountCommentReactions(boardId);
} }
private String procBlobToString(Object blob) { public static String procFirstImageUrl(String jsonContent) {
try { try {
if (blob instanceof String) {
return (String) blob; // 이미 문자열이면 그대로 반환
} else if (blob instanceof java.sql.Blob) {
java.sql.Blob sqlBlob = (java.sql.Blob) blob;
long blobLength = sqlBlob.length();
byte[] blobBytes = sqlBlob.getBytes(1, (int) blobLength);
return new String(blobBytes, StandardCharsets.UTF_8); // SQL BLOB 바이트 배열 문자열 변환
} else {
throw new UnsupportedOperationException("Unsupported blob type: " + blob.getClass()); // 지원되지 않는 타입이면 예외 발생
}
} catch (Exception e) {
throw new RuntimeException("Failed to convert Blob to String: " + e.getMessage(), e); // 변환 실패 예외 처리
}
}
private String procFirstImageUrl(String jsonContent) {
try {
// JSON 유효성 검사
if (!procIsValidJson(jsonContent)) {
throw new IllegalArgumentException("Invalid JSON content: " + jsonContent);
}
ObjectMapper objectMapper = new ObjectMapper(); ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonContent); JsonNode rootNode = objectMapper.readTree(jsonContent);
// JSON 배열 순회 // "ops" 배열 가져오기
for (JsonNode node : rootNode) { JsonNode opsNode = rootNode.get("ops");
if (opsNode != null && opsNode.isArray()) {
for (JsonNode node : opsNode) {
JsonNode insertNode = node.get("insert"); JsonNode insertNode = node.get("insert");
if (insertNode != null && insertNode.has("image")) { if (insertNode != null && insertNode.has("image")) {
return insertNode.get("image").asText(); // 번째 이미지 URL 반환 return insertNode.get("image").asText(); // 번째 이미지 URL 반환
} }
} }
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
throw new RuntimeException("Failed to extract first image URL: " + e.getMessage(), e); throw new RuntimeException("Failed to extract first image URL: " + e.getMessage(), e);
@ -231,65 +339,127 @@ public class localbordService {
return null; // 이미지가 없는 경우 return null; // 이미지가 없는 경우
} }
private boolean procIsValidJson(String json) { public String extractPlainText(String deltaJson) {
StringBuilder sb = new StringBuilder();
ObjectMapper mapper = new ObjectMapper();
try { try {
final ObjectMapper objectMapper = new ObjectMapper(); JsonNode root = mapper.readTree(deltaJson);
objectMapper.readTree(json); // JSON 파싱 시도 JsonNode ops = root.get("ops");
return true; // JSON이 유효하면 true 반환
} catch (Exception e) {
return false; // 유효하지 않은 경우 false 반환
}
}
private String procPlainTextFromJson(String jsonContent) { if (ops != null && ops.isArray()) {
StringBuilder plainTextBuilder = new StringBuilder(); for (JsonNode op : ops) {
try { JsonNode insertNode = op.get("insert");
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonContent);
// JSON 배열인지 확인 // insert가 문자열일 경우만 추출
if (!rootNode.isArray()) {
System.err.println("JSON content is not an array");
return "";
}
// JSON 노드 순회
for (JsonNode node : rootNode) {
JsonNode insertNode = node.get("insert");
// insert 노드가 텍스트인지 확인
if (insertNode != null && insertNode.isTextual()) { if (insertNode != null && insertNode.isTextual()) {
String text = insertNode.asText(); String text = insertNode.asText();
if (!"\n".equals(text.trim())) { // 줄바꿈 제외
sb.append(text).append(" ");
}
}
// insert가 객체면 image일 가능성 제외
}
}
// '\n' 제거하고 순수 텍스트만 추가
if (!text.trim().isEmpty() && !text.trim().equals("\n")) {
plainTextBuilder.append(text.trim());
}
}
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace(); // 실제 운영에서는 로깅 처리
throw new RuntimeException("Failed to extract plain text: " + e.getMessage(), e);
} }
return plainTextBuilder.toString();
return sb.toString().trim();
} }
/**
* 검색어로 순수 텍스트 기준 게시글 필터링
*/
private List<MapDto> filterPostsByKeyword(List<MapDto> posts, String keyword) {
if (keyword == null || keyword.trim().isEmpty()) return posts;
keyword = keyword.trim();
List<MapDto> filtered = new ArrayList<>();
for (MapDto post : posts) {
String title = post.getString("title");
String author = post.getString("author");
String contentJson = BlobUtil.procBlobToString(post.get("content")); // Blob 처리
String plainText = extractPlainText(contentJson);
// 포함 여부 판단 (title, author, content 순수 텍스트)
if ((title != null && title.contains(keyword)) ||
(author != null && author.contains(keyword)) ||
plainText.contains(keyword)) {
post.put("content", contentJson); // content는 원래대로 복원
filtered.add(post);
}
}
return filtered;
}
private void enrichBoardDetail(MapDto boardDetail) { private void enrichBoardDetail(MapDto boardDetail) {
if(boardDetail == null) return;
long userId = AuthUtil.getUser().getId();
long boardId = ((Number) boardDetail.get("id")).longValue(); long boardId = ((Number) boardDetail.get("id")).longValue();
boardDetail.put("userId", userId);
boardDetail.put("hasAttachment", selectIsAttachments(boardId)); boardDetail.put("hasAttachment", selectIsAttachments(boardId));
boardDetail.put("commentCount", selectCountComments(boardId)); boardDetail.put("commentCount", selectCountComments(boardId));
MapDto reactions = selectCountBoardReactions(boardId); MapDto reactions = selectCountBoardReactions(boardId);
long myReaction = this.selectMyBoardReaction(boardDetail);
boardDetail.put("likeCount", reactions.getOrDefault("likeCount", 0)); boardDetail.put("likeCount", reactions.getOrDefault("likeCount", 0));
boardDetail.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0)); boardDetail.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
boardDetail.put("myReaction", myReaction);
// Blob 데이터를 문자열로 변환 // Blob 데이터를 문자열로 변환
Object content = boardDetail.get("content"); Object content = boardDetail.get("content");
if (content != null) { if (content != null) {
String contentString = procBlobToString(content); // Blob을 문자열로 변환 String contentString = BlobUtil.procBlobToString(content); // Blob을 문자열로 변환
boardDetail.put("content", contentString); // JSON 변환 가능 boardDetail.put("content", contentString); // JSON 변환 가능
} }
} }
// 사용자 게시글 좋아요/싫어요 조회
private long selectMyBoardReaction(MapDto boardDetail) {
MapDto map = boardMapper.selectMyBoardReaction(boardDetail);
long result = 3;
if(map == null) {
result = 3;
} else if("T".equals(map.getString("LOCGOBGOD")) && "F".equals(map.getString("LOCGOBBAD"))) {
result = 1;
} else if("F".equals(map.getString("LOCGOBGOD")) && "T".equals(map.getString("LOCGOBBAD"))) {
result = 2;
} else {
result = 3;
}
return result;
}
// 사용자 댓글 좋아요/싫어요 조회
private long selectMyBoardReactions(MapDto param) {
MapDto map = boardMapper.selectMyBoardReactions(param);
long result = 3;
if(map == null) {
result = 3;
} else if("T".equals(map.getString("LOCGOBGOD")) && "F".equals(map.getString("LOCGOBBAD"))) {
result = 1;
} else if("F".equals(map.getString("LOCGOBGOD")) && "T".equals(map.getString("LOCGOBBAD"))) {
result = 2;
} else {
result = 3;
}
return result;
}
private void enrichPostsWithAdditionalData(List<MapDto> posts) { private void enrichPostsWithAdditionalData(List<MapDto> posts) {
for (MapDto post : posts) { for (MapDto post : posts) {
Object idObject = post.get("id"); Object idObject = post.get("id");
@ -302,32 +472,226 @@ public class localbordService {
post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0)); post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
Object content = post.get("content"); Object content = post.get("content");
String contentString = procBlobToString(content); String contentString = BlobUtil.procBlobToString(content);
post.put("content", contentString); post.put("content", contentString);
String firstImageUrl = procFirstImageUrl(contentString); String firstImageUrl = procFirstImageUrl(contentString);
post.put("firstImageUrl", firstImageUrl); post.put("firstImageUrl", firstImageUrl);
String plainContent = procPlainTextFromJson(contentString);
post.put("plainContent", plainContent);
} }
} }
} }
private void enrichCommentsWithAdditionalData(List<MapDto> comments) { private void enrichCommentsWithAdditionalData(MapDto map, List<MapDto> comments) {
for (MapDto comment : comments) { for (MapDto comment : comments) {
Object idObject = comment.get("LOCCMTSEQ"); Object idObject = comment.get("LOCCMTSEQ");
String userId = "";
// 프로필 이미지 추가
if(comment.containsKey("authorId")) {
userId = String.valueOf(comment.get("authorId"));
String profileImg = boardMapper.selectUserProfileImg(userId);
comment.put("profileImg", profileImg);
}
if (idObject instanceof Number) { if (idObject instanceof Number) {
long commentId = ((Number) idObject).longValue(); long commentId = ((Number) idObject).longValue();
long id = AuthUtil.getUser().getId(); //사용자 아이디
MapDto reactions = boardMapper.selectCountCommentReactions(commentId); MapDto reactions = boardMapper.selectCountCommentReactions(commentId);
comment.put("likeCount", reactions != null ? reactions.getOrDefault("likeCount", 0) : 0); comment.put("likeCount", reactions != null ? reactions.getOrDefault("likeCount", 0) : 0);
comment.put("dislikeCount", reactions != null ? reactions.getOrDefault("dislikeCount", 0) : 0); comment.put("dislikeCount", reactions != null ? reactions.getOrDefault("dislikeCount", 0) : 0);
map.put("userId", id);
map.put("boardId", map.get("LOCBRDSEQ"));
map.put("commentId", commentId);
comment.put("myReaction", this.selectMyBoardReactions(map));
Object content = comment.get("content"); Object content = comment.get("content");
comment.put("content", content); comment.put("content", content);
} }
} }
} }
/**
* 게시판 수정
*
* @param map
* @param files
* @throws IOException
*/
@Transactional
public ApiResponse<String> updateBoardWithFiles(MapDto map, List<MultipartFile> files) throws IOException {
int result = this.updateBoard(map); // 게시글 수정
Long userId = AuthUtil.getUser().getId();
String[] editorUploadedImgList = null;
// 수정 성공 첨부파일 수정 변경
if(result == 1) {
//에디터 첨부 이미지 게시글 번호 업데이트
if(map.get("editorUploadedImgList") != null) {
editorUploadedImgList = String.valueOf(map.get("editorUploadedImgList")).split(",");
map.put("editorImgList", editorUploadedImgList);
this.updateBoardIndexToFile(map);
}
// 추가 첨부파일 업로드
if(files != null && !files.isEmpty()) {
List<UploadFile> list = fileService.boardUploadFiles(files); // 파일 업로드
map.put("CMNFLEREG", userId);
map.put("list", list);
boardMapper.insertAttachments(map); // 파일 정보 DB 적재
}
// 제거 첨부파일 삭제
if(map.get("delFileIdx") != null) {
String[] array = String.valueOf(map.get("delFileIdx")).split(",");
this.deleteFileAndData(array);
}
// 에디터 수정 업로드 에디터 이미지 삭제
if(map.get("editorDeleteImgList") != null) {
String[] array = String.valueOf(map.get("editorDeleteImgList")).split(",");
this.deleteFileAndData(array);
}
} else {
return ApiResponse.error(HttpStatus.INTERNAL_SERVER_ERROR, "게시물이 수정에 실패하였습니다.");
}
return ApiResponse.ok("게시물이 수정되었습니다.");
}
/**
* 첨부파일 데이터 삭제
*
* @param array
*/
private void deleteFileInfo(String[] array) {
boardMapper.deleteFileInfo(array);
}
private int updateBoardIndexToFile(MapDto map) {
return boardMapper.updateBoardIndexToFile(map);
}
/**
* 파일 삭제 db 데이터 제거
*
* @param array
*/
private void deleteFileAndData(String[] array) {
List<String> delListInfo = this.selectDelFileInfo(array); // 삭제할 파일 정보 조회
for(String item : delListInfo) {
fileService.removeFile(item); // 파일 삭제
}
this.deleteFileInfo(array);
}
/**
* 삭제 첨부파일 정보 조회
*
* @param array
* @return
*/
private List<String> selectDelFileInfo(String[] array) {
return boardMapper.selectDelFileInfo(array);
}
/**
* 게시글 수정 조회
*
* @param map
* @return
*/
public ApiResponse<MapDto> selectBoardDetail2(MapDto map) {
String password = map.getString("password"); // 입력한 비밀번호
Long boardId = map.getLong("boardId"); // 조회한 게시글 번호
MemberVo member = AuthUtil.getUser(); // 로그인 정보 조회
MapDto resultMap = boardMapper.selectBoardDetail2(boardId); // 게시글 정보 조회
if(resultMap == null) return ApiResponse.error(HttpStatus.NOT_FOUND, "해당 게시글이 없습니다");
String boardType = resultMap.getString("type"); // 게시글 타입
// 익명 게시글
if("300102".equals(boardType)) {
String hashedPassword = resultMap.getString("password");
if(StringUtils.hasText(password)) {
boolean isMatch = passwordEncoder.matches(password, hashedPassword);
if(!isMatch) return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호가 일치하지 않습니다");
} else {
return ApiResponse.error(HttpStatus.UNAUTHORIZED, "비밀번호를 입력하세요");
}
// 자유 게시글 && 공지글
} else if("300101".equals(boardType) || "300103".equals(boardType)) {
Long writerId = Long.valueOf(resultMap.getInt("authorId"));
if(member.getId() != writerId) return ApiResponse.error(HttpStatus.UNAUTHORIZED, "권한이 없습니다");
// 공지글
// } else if("300103".equals(boardType)) {
// if(!"ROLE_ADMIN".equals(member.getRole())) return ApiResponse.error(HttpStatus.UNAUTHORIZED, "권한이 없습니다");
//
} else {
log.error("게시글 카테고리 정보 없음");
return ApiResponse.error(HttpStatus.NOT_FOUND, "해당 게시글이 없습니다");
}
this.enrichBoardDetail(resultMap); // 추가정보 세팅
List<MapDto> attachments = this.selectAttachments(boardId); // 📌 첨부파일 목록 추가
resultMap.put("attachments", attachments != null ? attachments : new ArrayList<>());
return ApiResponse.ok(resultMap);
}
/**
* 에디터 업로드 이미지 게시글 번호 업데이트
*
* @param map
* @return
*/
public int insertUploadEditorImageInfo(MapDto map) {
return boardMapper.insertUploadEditorImageInfo(map);
}
/**
* 게시글 정보가 없는 파일 조회
*
* @return
*/
public List<FileVo> selectFilesBoardIndexIsNull() {
return boardMapper.selectFilesBoardIndexIsNull();
}
/**
* 파일 data 제거
*
* @param vo
* @return
*/
public int deleteTrashFileData(FileVo vo) {
return boardMapper.deleteTrashFileData(vo);
}
/**
* Garbage File Collector
*/
@Scheduled(cron = "0 0 2 1 * *", zone = "Asia/Seoul")
public void deleteTrashFiles() {
List<FileVo> list = this.selectFilesBoardIndexIsNull();
for(FileVo file : list) {
String fileName = file.getCMNFLEPAT();
//if(!fileName.contains(file.getCMNFLEEXT())) fileName = fileName + file.getCMNFLEEXT();
boolean deleteResult = fileService.removeFile(fileName);
if(deleteResult) this.deleteTrashFileData(file);
}
}
} }

View File

@ -1,3 +1,17 @@
/************************************************************
*
* @packageName : io.company.localhost.service
* @fileName : localvacaService.java
* @author : 서지희
* @date : 25.02.06
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.06 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.net.URLDecoder; import java.net.URLDecoder;
@ -11,6 +25,7 @@ import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -20,6 +35,7 @@ import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.scheduling.annotation.Scheduled; import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.localvacaMapper; import io.company.localhost.mapper.localvacaMapper;
@ -34,47 +50,108 @@ public class localvacaService {
@Value("${api.public-holiday.key}") @Value("${api.public-holiday.key}")
private String serviceKey; private String serviceKey;
private static final List<MapDto> CUSTOM_HOLIDAYS = new ArrayList<>();
// 초기 사용자 지정 공휴일 추가
static {
MapDto customHoliday1 = new MapDto();
customHoliday1.put("monthDay", "05-01");
customHoliday1.put("name", "근로자의 날");
CUSTOM_HOLIDAYS.add(customHoliday1);
// MapDto customHoliday2 = new MapDto();
// customHoliday2.put("date", "2025-03-21");
// customHoliday2.put("name", "사용자 지정 예시");
//
// CUSTOM_HOLIDAYS.add(customHoliday2);
}
public void insertVacation(MapDto vacation) { public void insertVacation(MapDto vacation) {
// 필요한 경우 데이터 검증/전처리 매퍼 호출 // 필요한 경우 데이터 검증/전처리 매퍼 호출
localvacaMapper.insertVacation(vacation); localvacaMapper.insertVacation(vacation);
} }
public void deleteVacation(Long vacationId) { /**
localvacaMapper.deleteVacation(vacationId); * 여러 개의 휴가를 삭제
*/
@Transactional
public void deleteVacation(List<Long> vacationIds) {
if (vacationIds != null && !vacationIds.isEmpty()) {
localvacaMapper.deleteVacation(vacationIds);
}
}
/**
* 휴가 추가 또는 업데이트 (중복 검사 처리)
*/
@Transactional
public void upsertVacation(MapDto vacation) {
String date = vacation.getString("date");
Long employeeId = vacation.getLong("employeeId");
// 기존 데이터 확인
Long existingId = localvacaMapper.findVacationIdByDate(employeeId, date);
if (existingId != null) {
// 기존 휴가가 존재하면 업데이트
vacation.put("id", existingId);
localvacaMapper.updateVacation(vacation);
} else {
// 기존 휴가가 없으면 새롭게 추가
localvacaMapper.insertVacation(vacation);
}
} }
public List<MapDto> selectVacationList(int year, int month) { public List<MapDto> selectVacationList(int year, int month) {
return localvacaMapper.selectVacations(year, month); return localvacaMapper.selectVacations(year, month);
} }
/**
* 🔹 특정 연월에 대한 공휴일 데이터 조회
*/
public List<MapDto> selectHolidays(int year, int month) { public List<MapDto> selectHolidays(int year, int month) {
// ServiceKey를 디코딩해서 사용 // API에서 공휴일 가져오기
String decodedServiceKey = URLDecoder.decode(serviceKey, StandardCharsets.UTF_8); List<MapDto> apiHolidays = fetchHolidaysFromApi(year, month);
System.out.println("📌 디코딩된 ServiceKey: " + decodedServiceKey);
// URI를 직접 문자열로 구성하여 ServiceKey가 다시 인코딩되지 않도록 // 사용자 정의 공휴일 추가 (monthDay: 전체 연도 / date: 특정 연도)
List<MapDto> userDefinedHolidays = CUSTOM_HOLIDAYS.stream()
.filter(holiday ->
Optional.ofNullable(holiday.getString("date"))
.map(d -> d.startsWith(year + "-")) // 특정 연도의 공휴일
.orElse(false) // date가 있으면 연도 매칭 포함
|| Optional.ofNullable(holiday.getString("monthDay"))
.map(md -> md.startsWith(String.format("%02d-", month))) // 모든 연도에 적용되는 monthDay
.orElse(false)
)
.map(holiday -> {
MapDto newHoliday = new MapDto();
// 특정 연도 공휴일이면 그대로 사용, 모든 연도 공휴일이면 해당 연도 추가
newHoliday.put("date", holiday.containsKey("date") ? holiday.getString("date") : year + "-" + holiday.getString("monthDay"));
newHoliday.put("name", holiday.getString("name"));
return newHoliday;
})
.collect(Collectors.toList());
// API 공휴일과 사용자 정의 공휴일 합치기
List<MapDto> combinedHolidays = new ArrayList<>();
combinedHolidays.addAll(apiHolidays);
combinedHolidays.addAll(userDefinedHolidays);
return combinedHolidays;
}
private List<MapDto> fetchHolidaysFromApi(int year, int month) {
String decodedServiceKey = URLDecoder.decode(serviceKey, StandardCharsets.UTF_8);
String url = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo" String url = "http://apis.data.go.kr/B090041/openapi/service/SpcdeInfoService/getRestDeInfo"
+ "?solYear=" + year + "?solYear=" + year
+ "&solMonth=" + String.format("%02d", month) + "&solMonth=" + String.format("%02d", month)
+ "&ServiceKey=" + decodedServiceKey // 디코딩된 상태로 직접 추가 + "&ServiceKey=" + decodedServiceKey
+ "&_type=json"; + "&_type=json";
System.out.println("📌 API 요청 URL: " + url);
// API 요청 헤더 추가 (User-Agent 포함)
HttpHeaders headers = new HttpHeaders(); HttpHeaders headers = new HttpHeaders();
headers.set(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"); headers.set(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
HttpEntity<String> entity = new HttpEntity<>(headers); HttpEntity<String> entity = new HttpEntity<>(headers);
// `exchange` 메서드를 사용하여 요청
ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class); ResponseEntity<Map> response = restTemplate.exchange(url, HttpMethod.GET, entity, Map.class);
System.out.println("📌 API 응답 데이터: " + response.getBody());
return parseResponse(response.getBody()); return parseResponse(response.getBody());
} }
@ -151,16 +228,19 @@ public class localvacaService {
dto.put("date", locdateStr); // 변환 불가능한 경우 원본 저장 dto.put("date", locdateStr); // 변환 불가능한 경우 원본 저장
} }
dto.put("name", item.get("dateName")); String dateName = String.valueOf(item.get("dateName"));
if (dateName.contains("대체공휴일")) {
dto.put("name", "대체공휴일");
} else {
dto.put("name", dateName);
}
return dto; return dto;
} }
/**
* 연차 사용 내역 조회 (사용한 연차 & 받은 연차) public Map<String, List<MapDto>> selectUserVacationHistory(Long userId, int year) {
*/ List<MapDto> usedVacations = localvacaMapper.selectUsedVacations(userId,year);
public Map<String, List<MapDto>> selectUserVacationHistory(Long userId) { List<MapDto> receivedVacations = localvacaMapper.selectReceivedVacations(userId,year);
List<MapDto> usedVacations = localvacaMapper.selectUsedVacations(userId);
List<MapDto> receivedVacations = localvacaMapper.selectReceivedVacations(userId);
Map<String, List<MapDto>> history = new HashMap<>(); Map<String, List<MapDto>> history = new HashMap<>();
history.put("usedVacations", usedVacations); history.put("usedVacations", usedVacations);
@ -169,9 +249,6 @@ public class localvacaService {
return history; return history;
} }
/**
* 사원별 남은 연차 개수 조회
*/
public List<MapDto> selectEmployeeRemainingVacation() { public List<MapDto> selectEmployeeRemainingVacation() {
List<MapDto> employeeVacations = localvacaMapper.selectEmployeeRemainingVacation(); List<MapDto> employeeVacations = localvacaMapper.selectEmployeeRemainingVacation();
@ -215,23 +292,25 @@ public class localvacaService {
/** /**
* 연차 계산 로직 * 연차 계산 로직
*/ */
private int procCalculateTotalVacation(LocalDate hireDate) { public int procCalculateTotalVacation(LocalDate hireDate) {
LocalDate today = LocalDate.now(); LocalDate today = LocalDate.now();
int yearsWorked = hireDate.until(today).getYears(); int hireYear = hireDate.getYear();
int currentYear = today.getYear();
// 🔹 1년 미만: 연간 12개 지급 // 입사년도와 현재년도가 같으면 : (12 - 입사월)
if (yearsWorked < 1) { if (hireYear == currentYear) {
return 12; return 12 - hireDate.getMonthValue();
} }
// 🔹 1년 이상 기본 15개 // 기본 연차 15
int totalVacation = 15; int totalVacation = 15;
LocalDate nextIncreaseDate = hireDate.plusYears(2).withMonth(1).withDayOfMonth(1);
// 🔹 2년마다 1개 추가 // 입사년도 기준 3년차 1월부터, 2년마다 1개씩 증가
while (nextIncreaseDate.isBefore(today) || nextIncreaseDate.isEqual(today)) { LocalDate accrualDate = LocalDate.of(hireYear + 3, 1, 1);
totalVacation += 1;
nextIncreaseDate = nextIncreaseDate.plusYears(2); while (!accrualDate.isAfter(today)) {
totalVacation++;
accrualDate = accrualDate.plusYears(2);
} }
return totalVacation; return totalVacation;
@ -240,4 +319,8 @@ public class localvacaService {
public List<MapDto> selectSentVacationCount(MapDto map) { public List<MapDto> selectSentVacationCount(MapDto map) {
return localvacaMapper.selectSentVacationCount(map); return localvacaMapper.selectSentVacationCount(map);
} }
public List<MapDto> selectMemberVacationsInMain(int year, int month) {
return localvacaMapper.selectMemberVacationsInMain(year, month);
}
} }

View File

@ -1,10 +1,26 @@
/************************************************************
*
* @packageName : io.company.localhost.service
* @fileName : localvoteService.java
* @author : 공현지
* @date : 25.01.07
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.service; package io.company.localhost.service;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Random;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
@ -30,7 +46,6 @@ public class localvoteService {
public Long insertVote(MapDto map) { public Long insertVote(MapDto map) {
Long result = 0L; Long result = 0L;
int voteIdInt = 0 ; int voteIdInt = 0 ;
if(map.get("voteId") != null) { if(map.get("voteId") != null) {
voteIdInt = (int) map.get("voteId"); voteIdInt = (int) map.get("voteId");
@ -49,35 +64,31 @@ public class localvoteService {
return result; return result;
} }
public PageInfo<MapDto> getVoteList(MapDto map) { public PageInfo<MapDto> selectVoteList(MapDto map) {
//투표 목록조회 //투표 목록조회
int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1; int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1;
PageHelper.startPage(page, 10); PageHelper.startPage(page, 10);
PageInfo<MapDto> localvote = PageUtil.redefineNavigation(new PageInfo<>(localvotemapper.getVoteList(map),10)); PageInfo<MapDto> localvote = PageUtil.redefineNavigation(new PageInfo<>(localvotemapper.selectVoteList(map),10));
List<MapDto> resultList = new ArrayList<>();
List<MapDto> resultList = new ArrayList<>();
List<MapDto> voteList = localvote.getList(); List<MapDto> voteList = localvote.getList();
for (MapDto vote : voteList) { for (MapDto vote : voteList) {
MapDto voteMap = new MapDto(); MapDto voteMap = new MapDto();
voteMap.put("localVote", vote); voteMap.put("localVote", vote);
Integer locvotSeq = (Integer) vote.get("LOCVOTSEQ"); Integer locvotSeq = (Integer) vote.get("LOCVOTSEQ");
//투표 항목조회 map.put("locvotSeq", locvotSeq);
List<MapDto> voteDetails = votdetailmapper.getVoteDetails(locvotSeq); //투표 항목조회 + 결과 조회 + 투표여부
List<MapDto> voteDetails = votdetailmapper.selectVoteDetailsResult(map);
//투표 가능 멤버 조회 //투표 가능 멤버 조회
List<MapDto> voteMembers = votmembermapper.getVoteMember(locvotSeq); List<MapDto> voteMembers = votmembermapper.selectVoteMember(locvotSeq);
voteMap.put("voteDetails", voteDetails); voteMap.put("voteDetails", voteDetails);
voteMap.put("voteMembers", voteMembers); voteMap.put("voteMembers", voteMembers);
map.put("id",locvotSeq);
//투표 여부
int yesVotetotal = votrecordmapper.yesVotetotal(map);
voteMap.put("yesVotetotal", yesVotetotal);
resultList.add(voteMap); resultList.add(voteMap);
} }
localvote.setList(resultList); localvote.setList(resultList);
return localvote; return localvote;
} }
@ -94,5 +105,27 @@ public class localvoteService {
return localvotemapper.updateEndData(map); return localvotemapper.updateEndData(map);
} }
public Long updateRandomResult(MapDto map) {
Long result = 0L;
ObjectMapper objectMapper = new ObjectMapper();
Object randomListObj = map.get("randomList");
if (randomListObj instanceof List<?>) {
List<?> rawList = (List<?>) randomListObj;
if (!rawList.isEmpty()) {
//랜덤뽑기
Object selectedObj = rawList.get(new Random().nextInt(rawList.size()));
MapDto selectedItem = objectMapper.convertValue(selectedObj, MapDto.class);
selectedItem.put("voteid", map.get("voteid"));
//투표결과 저장
result = localvotemapper.updateRandomResult(selectedItem);
}
}
return result;
}
public Long updateDeleteData(MapDto map) {
return localvotemapper.updateDeleteData(map);
}
} }

View File

@ -20,8 +20,13 @@ import java.util.List;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.company.localhost.common.dto.MapDto; import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.commoncodMapper;
import io.company.localhost.mapper.worddictyMapper; import io.company.localhost.mapper.worddictyMapper;
import io.company.localhost.utils.BlobUtil;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
@Service @Service
@ -29,9 +34,18 @@ import lombok.RequiredArgsConstructor;
public class worddictyService { public class worddictyService {
private final worddictyMapper worddictymapper; private final worddictyMapper worddictymapper;
private final commoncodMapper commoncodmapper;
private final FileService fileService;
public List<MapDto> selectWordList(MapDto map) {
if( map.getString("pageNum") != null) {
String pageNumStr = map.getString("pageNum");
int pageNum = Integer.parseInt(pageNumStr);
map.put("pageNum", pageNum);
}
List<MapDto> wordList = worddictymapper.selectWordList(map);
String keyword = map.getString("searchKeyword");
public List<MapDto> getWordList(MapDto map) {
List<MapDto> wordList = worddictymapper.getWordList(map);
List<MapDto> processedList = new ArrayList<>(); List<MapDto> processedList = new ArrayList<>();
// 데이터 가공 // 데이터 가공
@ -55,34 +69,158 @@ public class worddictyService {
processedDto.putAll(dto); processedDto.putAll(dto);
processedList.add(processedDto); processedList.add(processedDto);
} }
return processedList; return filterPostsByKeyword(processedList,keyword);
}
/**
* 검색어로 순수 텍스트 기준 게시글 필터링
*/
private List<MapDto> filterPostsByKeyword(List<MapDto> posts, String keyword) {
keyword = keyword.trim();
List<MapDto> filtered = new ArrayList<>();
for (MapDto post : posts) {
String title = post.getString("WRDDICTTL");
Object content = post.get("WRDDICCON");
// BlobUtil.procBlobToString으로 content 변환
String contentString = BlobUtil.procBlobToString(content);
if(keyword != null || !keyword.trim().isEmpty()) {
String plainText = extractPlainText(contentString);
if ((title != null && title.contains(keyword)) ||plainText.contains(keyword)) {
post.put("WRDDICCON", contentString); // content는 원래대로 복원
filtered.add(post);
}
}
}
return filtered;
}
public String extractPlainText(String deltaJson) {
StringBuilder sb = new StringBuilder();
ObjectMapper mapper = new ObjectMapper();
try {
JsonNode root = mapper.readTree(deltaJson);
if (root != null && root.isArray()) {
for (JsonNode op : root) {
JsonNode insertNode = op.get("insert");
// insert가 문자열일 경우만 추출
if (insertNode != null && insertNode.isTextual()) {
String text = insertNode.asText();
if (!"\n".equals(text.trim())) { // 줄바꿈 제외
sb.append(text).append(" ");
}
}
// insert가 객체면 image일 가능성 제외
}
}
} catch (Exception e) {
e.printStackTrace(); // 실제 운영에서는 로깅 처리
}
return sb.toString().trim();
} }
public Long insertWord(MapDto map) { public Long insertWord(MapDto map) {
return worddictymapper.insertWord(map); Long result = 1L;
if (map.containsKey("CMNCODNAM") && map.get("CMNCODNAM") != null && map.get("CMNCODNAM") != "") {
commoncodmapper.insertCategory(map);
result = 2L;
}
worddictymapper.insertWord(map);
//에디터 첨부 이미지 게시글 번호 업데이트
if(map.get("editorUploadedImgList") != null) {
ArrayList<String> editorUploadedImgList = (ArrayList<String>) map.getList("editorUploadedImgList", String.class);
map.put("editorImgList", editorUploadedImgList);
this.updateBoardIndexToFile(map);
} }
// 에디터 수정 업로드 에디터 이미지 삭제
if(map.get("editorDeleteImgList") != null) {
ArrayList<String> editorDeleteImgList = (ArrayList<String>) map.getList("editorDeleteImgList", String.class);
String[] array = editorDeleteImgList.stream().toArray(String[]::new);
this.deleteFileAndData(array);
}
return result;
}
/**
* 실제 파일 삭제 db 데이터 제거
*
* @param array
*/
private void deleteFileAndData(String[] array) {
List<String> delListInfo = this.selectDelFileInfo(array); // 삭제할 파일 정보 조회
for(String item : delListInfo) {
fileService.removeFile(item); // 파일 삭제
}
this.deleteFileInfo(array);
}
/**
* 삭제 첨부파일 정보 조회
*
* @param array
* @return
*/
private List<String> selectDelFileInfo(String[] array) {
return worddictymapper.selectDelFileInfo(array);
}
/**
* 첨부파일 데이터 삭제
*
* @param array
*/
private void deleteFileInfo(String[] array) {
worddictymapper.deleteFileInfo(array);
}
private int updateBoardIndexToFile(MapDto map) {
return worddictymapper.updateBoardIndexToFile(map);
}
public Long updateWord(MapDto map) { public Long updateWord(MapDto map) {
return worddictymapper.updateWord(map);
Long result = worddictymapper.updateWord(map);
if(result == 1) {
map.put("id", map.get("WRDDICSEQ"));
//에디터 첨부 이미지 게시글 번호 업데이트
if(map.get("editorUploadedImgList") != null) {
ArrayList<String> editorUploadedImgList = (ArrayList<String>) map.getList("editorUploadedImgList", String.class);
map.put("editorImgList", editorUploadedImgList);
this.updateBoardIndexToFile(map);
} }
public MapDto getWordDetail(MapDto map) { // 에디터 수정 업로드 에디터 이미지 삭제
return worddictymapper.getWordDetail(map); if(map.get("editorDeleteImgList") != null) {
ArrayList<String> editorDeleteImgList = (ArrayList<String>) map.getList("editorDeleteImgList", String.class);
String[] array = editorDeleteImgList.stream().toArray(String[]::new);
this.deleteFileAndData(array);
}
} }
return result;
}
public MapDto selectWordDetail(MapDto map) {
return worddictymapper.selectWordDetail(map);
}
public int getTotal(MapDto map) { public int getTotal(MapDto map) {
return worddictymapper.getTotal(map); return worddictymapper.getTotal(map);
} }
public Long updateword(MapDto map) { public Long updateword(MapDto map) {
return worddictymapper.updateword(map); return worddictymapper.updateword(map);
} }
public List<MapDto> selectIndexCategory() {
return worddictymapper.selectIndexCategory();
}
} }

View File

@ -0,0 +1,42 @@
/************************************************************
*
* @packageName : io.company.localhost.utils
* @fileName : BlobUtil.java
* @author : 서지희
* @date : 25.02.25
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.02.25 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.utils;
import java.nio.charset.StandardCharsets;
import java.sql.Blob;
public class BlobUtil {
private BlobUtil() {
// 객체 생성 방지 (유틸리티 클래스는 인스턴스를 만들 필요가 없음)
}
public static String procBlobToString(Object blob) {
try {
if (blob instanceof String) {
return (String) blob; // 이미 문자열이면 그대로 반환
} else if (blob instanceof Blob) {
Blob sqlBlob = (Blob) blob;
long blobLength = sqlBlob.length();
byte[] blobBytes = sqlBlob.getBytes(1, (int) blobLength);
return new String(blobBytes, StandardCharsets.UTF_8); // SQL BLOB 바이트 배열 문자열 변환
} else {
throw new UnsupportedOperationException("Unsupported blob type: " + blob.getClass()); // 지원되지 않는 타입이면 예외 발생
}
} catch (Exception e) {
throw new RuntimeException("Failed to convert Blob to String: " + e.getMessage(), e); // 변환 실패 예외 처리
}
}
}

View File

@ -0,0 +1,147 @@
package io.company.localhost.utils;
import java.io.File;
import java.io.IOException;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import io.company.localhost.vo.UploadFile;
import lombok.extern.slf4j.Slf4j;
@Component
@Slf4j
public class FileUtil {
/**
* 파일 저장 경로/파일명
* @param savePath
* @param fileName
* @return
*/
public String getFullPath(String savePath, String fileName) {
return Paths.get(savePath, fileName).toString();
}
/**
* DB에 저장될 파일명
* @param originalFilename
* @return
*/
public String createSaveFileName(String originalFilename) {
String uuid = UUID.randomUUID().toString();
String extension = getFileExtension(originalFilename);
return uuid + "." + extension;
}
/**
* 파일 확장자
* @param originalFileName
* @return
*/
public String getFileExtension(String originalFileName) {
int pos = originalFileName.lastIndexOf(".");
return originalFileName.substring(pos + 1);
}
/**
* 파일 확장자 제외
* @param
* @return
*/
public String excludeFileExtension(String withExt) {
int pos = withExt.lastIndexOf(".");
return withExt.substring(0, pos);
}
/**
* 단일 파일 업로드
* @param savePath
* @param multipartFile
* @return
* @throws IOException
*/
public UploadFile uploadFile(String savePath, MultipartFile multipartFile) throws IOException{
File saveDirectory = new File(savePath);
if(!saveDirectory.exists()) saveDirectory.mkdirs();
if(multipartFile.isEmpty()) return null;
String originalFileName = multipartFile.getOriginalFilename(); //원본파일명
String saveFileName = createSaveFileName(originalFileName); //난수명
String ext = getFileExtension(originalFileName); //확장자
Long size = multipartFile.getSize(); //사이즈
String filePath = getFullPath(savePath, saveFileName);
multipartFile.transferTo(new File(filePath));
String orgFileName = this.excludeFileExtension(originalFileName);
String savFileName = this.excludeFileExtension(saveFileName);
return new UploadFile(orgFileName, savFileName, ext, size, filePath);
}
/**
* 다중 파일 업로드
* @param savePath
* @param multipartFiles
* @return
* @throws IOException
*/
public List<UploadFile> uploadFiles(String savePath, List<MultipartFile> multipartFiles) throws IOException{
List<UploadFile> uploadFiles = new ArrayList<>();
for(MultipartFile multipartFile : multipartFiles) {
if(!multipartFile.isEmpty()) {
uploadFiles.add(uploadFile(savePath, multipartFile));
}
}
return uploadFiles;
}
/**
* 업로드된 파일 삭제
* @param path
* @param originalProfile
* @return
*/
public Boolean removeFile(String path, String saveFileName) {
log.debug("========================================");
log.debug("FileUtil.removeFile()");
log.debug("path : {}", path);
log.debug("saveFileName : {}", saveFileName);
File file = new File(path, saveFileName);
System.gc();
boolean result = file.delete();
log.debug("result : {}", result);
log.debug("========================================");
return result;
}
public Boolean removeFile(String path) {
log.debug("========================================");
log.debug("FileUtil.removeFile()");
log.debug("path : {}", path);
File file = new File(path);
System.gc();
boolean result = file.delete();
log.debug("result : {}", result);
log.debug("========================================");
return result;
}
}

View File

@ -18,7 +18,15 @@ import org.springframework.util.StringUtils;
public class StringUtil extends StringUtils { public class StringUtil extends StringUtils {
//String Util 여기서 작성 /**
* 정수타입 확인
*
* @param str
* @return
*/
public static boolean isNumeric(String str) {
return str.matches("\\d+");
}
public StringUtil() {} public StringUtil() {}
} }

View File

@ -0,0 +1,18 @@
package io.company.localhost.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class FileVo {
private String CMNFLESEQ;
private String CMNBRDSEQ;
private String CMNFLENAM;
private String CMNFLEORG;
private String CMNFLEPAT;
private String CMNFLEEXT;
private String CMNFLESIZ;
private String CMNFLETYP;
}

View File

@ -47,6 +47,7 @@ public class MemberVo {
private String isLea; // 휴직여부 private String isLea; // 휴직여부
private int color; // 색상 private int color; // 색상
private int mbit; // MBTI private int mbit; // MBTI
private String usercolor; // usercolor
private Boolean remember; // 로그인 유지 private Boolean remember; // 로그인 유지
} }

View File

@ -0,0 +1,15 @@
package io.company.localhost.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class UploadFile {
private String originalFileName;
private String saveFileName;
private String extension;
private long fileSize;
private String filePath;
}

View File

@ -0,0 +1,33 @@
/************************************************************
*
* @packageName : io.company.localhost.vo
* @fileName : MemberVo.java
* @author : 조인제
* @date : 24.12.06
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 조인제 최초 생성
*
*************************************************************/
package io.company.localhost.vo;
import lombok.*;
import java.util.Date;
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class WeatherVo {
String date;
String mainWeather;
String description;
String icon;
}

View File

@ -0,0 +1,4 @@
ssl:
key-store: classpath:localhost.p12
key-store-password: pmgk1234
key-store-type: PKCS12

View File

@ -55,7 +55,8 @@ management:
api: api:
public-holiday: public-holiday:
key: "MugzCRZ7VmR/LJ3BZ1Ehmmg5yiI0GPFt4evLjNkNuwKoiWbKbe/M9U5pLjAxfSP13OOwHi943aMFM9yiI8OADA==" key: "MugzCRZ7VmR/LJ3BZ1Ehmmg5yiI0GPFt4evLjNkNuwKoiWbKbe/M9U5pLjAxfSP13OOwHi943aMFM9yiI8OADA=="
weather:
key: "3505b3500aacf34c4497bf449996ea09"
server: server:
shutdown: graceful shutdown: graceful
@ -81,10 +82,7 @@ server:
http-only: false http-only: false
secure: true secure: true
same-site: NONE same-site: NONE
ssl: partitioned: true
key-store: classpath:localhost.p12
key-store-password: pmgk1234
key-store-type: PKCS12
logging: logging:
level: level:
@ -97,6 +95,8 @@ logging:
connection: off connection: off
io.company: DEBUG io.company: DEBUG
io.company.localhost.mapper: off io.company.localhost.mapper: off
file:
path: logs
filePath: filePath:

View File

@ -0,0 +1,108 @@
<?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="io.company.localhost.mapper.CommutersMapper">
<!-- 출퇴근 등록 -->
<insert id="insertCommuters" useGeneratedKeys="true" keyProperty="COMMUTSEQ">
INSERT INTO commuters (
COMMUTSEQ,
MEMBERSEQ,
PROJCTSEQ,
COMMUTCMT,
COMMUTLVE,
COMMUTDAY,
COMMUTARR,
COMMUTOUT
) VALUES (
#{commutSeq},
#{memberSeq},
#{projctSeq},
#{commutCme},
#{commutLve},
#{commutDay},
#{commutArr},
#{commutOut}
)
</insert>
<!-- 퇴근 시간 업데이트 -->
<update id="updateLeaveTime">
UPDATE commuters
SET COMMUTLVE = #{commutLve},
PROJCTLVE = #{projctLve},
COMMUTOUT = #{commutOut}
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTDAY = CURDATE()
</update>
<!-- 현재 달의 모든 출근 정보 조회 -->
<select id="selectCommutersByMonth" parameterType="map" resultType="map">
SELECT
c.COMMUTSEQ,
c.MEMBERSEQ,
c.PROJCTSEQ,
c.PROJCTLVE,
c.COMMUTCMT,
c.COMMUTLVE,
c.COMMUTDAY,
c.COMMUTARR,
m.MEMBERNAM AS memberName,
m.MEMBERPRF AS profile,
p.PROJCTNAM,
p.PROJCTARR AS projectAddress,
cc.CMNCODNAM AS projctcolor,
p2.PROJCTNAM AS leaveProjectName,
p2.PROJCTARR AS leaveProjectAddress,
cl.CMNCODNAM AS leaveProjectColor
FROM
commuters c
JOIN
netmember m ON c.MEMBERSEQ = m.MEMBERSEQ
JOIN
netprojct p ON c.PROJCTSEQ = p.PROJCTSEQ
LEFT JOIN
commoncod cc ON p.PROJCTCOL = cc.CMNCODVAL AND cc.CMNCODYNP = '1'
LEFT JOIN
netprojct p2 ON c.PROJCTLVE = p2.PROJCTSEQ
LEFT JOIN
commoncod cl ON p2.PROJCTCOL = cl.CMNCODVAL AND cl.CMNCODYNP = '1'
WHERE
YEAR(c.COMMUTDAY) = #{year}
AND MONTH(c.COMMUTDAY) = #{month}
</select>
<!-- 사용자 오늘 출근 정보 조회 -->
<select id="selectTodayCommuterInfo" parameterType="Integer" resultType="map">
SELECT c.COMMUTCMT, c.COMMUTLVE
FROM commuters c
WHERE c.MEMBERSEQ = #{memberSeq}
AND c.COMMUTDAY = CURDATE()
</select>
<!-- 오늘 출근 모든 사용자 조회 -->
<select id="selectTodayCommuter">
SELECT c.COMMUTCMT, c.PROJCTLVE, c.COMMUTLVE, m.MEMBERSEQ, m.MEMBERPRF as profile, p.PROJCTNAM
FROM commuters c
JOIN netmember m ON c.MEMBERSEQ = m.MEMBERSEQ
JOIN netprojct p ON c.PROJCTSEQ = p.PROJCTSEQ
WHERE c.COMMUTDAY = CURDATE()
</select>
<!-- 출근 프로젝트 업데이트 -->
<!-- <update id="updateCommuterProject">
UPDATE commuters
SET PROJCTSEQ = #{projctSeq}
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTDAY = CURDATE()
</update> -->
<delete id="deleteCommuters" parameterType="int">
DELETE FROM commuters WHERE PROJCTSEQ = #{projctSeq}
</delete>
<select id="selectUserLeaveWorkList">
/* 금일 퇴근 조회 */
SELECT * FROM COMMUTERS WHERE MEMBERSEQ = #{memberSeq} AND COMMUTDAY = DATE_FORMAT(#{currentDate}, '%Y-%m-%d')
</select>
</mapper>

View File

@ -0,0 +1,57 @@
<?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="io.company.localhost.mapper.LocalevntMapper">
<!-- 이벤트 작성 -->
<insert id="insertEvent">
/* 이벤트 작성 */
INSERT INTO LOCALEVNT (
CMNCODVAL,
LOCEVTPLC,
LOCEVTTME,
LOCEVTRDT
) VALUES (
#{code},
<choose>
<when test="place != null">
#{place},
</when>
<otherwise>
null,
</otherwise>
</choose>
#{date},
NOW()
)
</insert>
<select id="selectCheckEvent">
/* 이벤트 확인 */
SELECT
COUNT(*)
FROM
LOCALEVNT
WHERE
CMNCODVAL = #{code} AND DATE(LOCEVTTME) = DATE(#{date})
</select>
<select id="selectEventList">
/* 이벤트 조회 */
SELECT
*
FROM
LOCALEVNT
WHERE
YEAR(LOCEVTTME) = #{year} AND MONTH(LOCEVTTME) = #{month}
</select>
<delete id="deleteEvent">
/* 이벤트 제거 */
DELETE FROM
LOCALEVNT
WHERE
CMNCODVAL = #{code} AND DATE(LOCEVTTME) = DATE(#{date})
</delete>
</mapper>

View File

@ -26,8 +26,13 @@
, MEMBERLEA AS isLea , MEMBERLEA AS isLea
, MEMBERCOL AS color , MEMBERCOL AS color
, MEMBERMBT AS mbit , MEMBERMBT AS mbit
, c.CMNCODNAM usercolor
FROM FROM
netmember netmember m
left join
commoncod c
on
M.MEMBERCOL = C.CMNCODVAL
WHERE WHERE
MEMBERIDS = #{id} MEMBERIDS = #{id}
</select> </select>
@ -88,13 +93,27 @@
) )
</insert> </insert>
<!-- 중복체크 --> <!-- id 중복체크 -->
<select id="selectCheckId" resultType="int"> <select id="selectCheckId" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM netmember FROM netmember
WHERE MEMBERIDS = #{memberIds} WHERE MEMBERIDS = #{memberIds}
</select> </select>
<!-- phone 중복체크 -->
<select id="selectCheckPhone" resultType="int">
SELECT COUNT(*)
FROM netmember
WHERE MEMBERTEL = #{memberTel}
</select>
<!-- 색상 중복체크 -->
<select id="selectMemberColor" resultType="int">
SELECT COUNT(*)
FROM netmember
WHERE MEMBERCOL = #{memberCol}
</select>
<!-- 비밀번호 재설정 member 체크 --> <!-- 비밀번호 재설정 member 체크 -->
<select id="selectPwReset" resultType="int"> <select id="selectPwReset" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
@ -120,7 +139,7 @@
</update> </update>
<!-- 전체 회원 목록 --> <!-- 전체 회원 목록 -->
<select id="getallUserList" resultType="Map"> <select id="selectallUserList" resultType="Map">
SELECT SELECT
m.* m.*
,c.CMNCODNAM usercolor ,c.CMNCODNAM usercolor
@ -138,5 +157,115 @@
m.MEMBERLEA ="N" m.MEMBERLEA ="N"
</select> </select>
<update id="updateUserRole">
UPDATE netmember SET MEMBERROL = #{role} WHERE MEMBERSEQ = #{id}
</update>
<select id="selectMemberBirthDay">
SELECT
A.MEMBERSEQ,
A.MEMBERNAM,
A.MEMBERCOL,
A.MEMBERPRF,
A.MEMBERBTH,
B.CMNCODNAM AS usercolor
FROM
NETMEMBER A
LEFT JOIN
COMMONCOD B ON B.CMNCODVAL = A.MEMBERCOL
WHERE
MONTH(MEMBERBTH) = #{month} AND MEMBERPRM = "Y";
</select>
<select id="selectRegisterMemberList">
/* 미등록 멤버 조회 */
SELECT
MEMBERSEQ,
MEMBERIDS,
MEMBERPRF,
MEMBERNAM,
MEMBERTEL,
MEMBERRDT,
MEMBERPRM,
MEMBERMBT,
MEMBERCDT,
B.CMNCODNAM AS MBTI
FROM
NETMEMBER
LEFT JOIN
COMMONCOD B ON B.CMNCODVAL = MEMBERMBT
WHERE
MEMBERPRM = 'N'
</select>
<update id="updateRegistMember">
/* 멤버 승인 */
UPDATE
NETMEMBER
SET
MEMBERPRM = 'Y'
WHERE
MEMBERSEQ = #{memberSeq}
</update>
<update id="updateRejectMember">
/* 멤버 등록 미승인 */
UPDATE
NETMEMBER
SET
MEMBERPRM = 'R'
WHERE
MEMBERSEQ = #{memberSeq}
</update>
<update id="updateUserInfo" parameterType="map">
UPDATE NETMEMBER
<set>
<if test="phone != null"> MEMBERTEL = #{phone}, </if>
<if test="color != null"> MEMBERCOL = #{color}, </if>
<if test="mbti != null"> MEMBERMBT = #{mbti}, </if>
<if test="birth != null"> MEMBERBTH = #{birth}, </if>
<if test="entryDate != null"> MEMBERCDT = #{entryDate}, </if>
<if test="address != null"> MEMBERARR = #{address}, </if>
<if test="detailAddress != null"> MEMBERDTL = #{detailAddress}, </if>
<if test="memberPrf != null"> MEMBERPRF = #{memberPrf}, </if>
</set>
WHERE MEMBERSEQ = #{memberId}
</update>
<select id="selectUserById" resultType="io.company.localhost.vo.MemberVo">
SELECT
MEMBERSEQ AS id
, MEMBERIDS AS loginId
, MEMBERROL AS role
, MEMBERTKN AS token
, MEMBERPRF AS profile
, MEMBERNAM AS name
, MEMBERPWD AS password
, MEMBERPWH AS passwordhint
, MEMBERPWR AS passwordRes
, MEMBERPOS AS position
, MEMBERARR AS address
, MEMBERDTL AS addressDetail
, MEMBERZIP AS zipcode
, MEMBERBTH AS birth
, MEMBERTEL AS phone
, MEMBERRDT AS regist
, MEMBERCDT AS isCdt
, MEMBERPRM AS isUsed
, MEMBERDEL AS isDel
, MEMBERLEA AS isLea
, MEMBERCOL AS color
, MEMBERMBT AS mbit
, c.CMNCODNAM usercolor
FROM
netmember m
left join
commoncod c
on
M.MEMBERCOL = C.CMNCODVAL
WHERE MEMBERSEQ = #{memberId}
</select>
</mapper> </mapper>

View File

@ -0,0 +1,180 @@
<?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="io.company.localhost.mapper.NetprojctMapper">
<!-- 프로젝트 목록 조회 -->
<select id="selectProject" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
SELECT DISTINCT
p.*,
c.CMNCODNAM AS projctcolor,
(SELECT COUNT(*)
FROM promember pm2
WHERE pm2.PROJCTSEQ = p.PROJCTSEQ
AND pm2.PROJCTYON = '1') AS participant_count
FROM netprojct p
LEFT JOIN commoncod c ON p.PROJCTCOL = c.CMNCODVAL AND c.CMNCODYNP = '1'
LEFT JOIN promember pm ON p.PROJCTSEQ = pm.PROJCTSEQ
WHERE 1=1
<if test="searchKeyword != null and searchKeyword != ''">
AND (
p.PROJCTNAM LIKE CONCAT('%', #{searchKeyword}, '%')
OR EXISTS (
SELECT 1
FROM promember pm2
JOIN netmember m ON pm2.MEMBERSEQ = m.MEMBERSEQ
WHERE pm2.PROJCTSEQ = p.PROJCTSEQ
AND pm2.PROJCTYON = '1'
AND m.membernam LIKE CONCAT('%', #{searchKeyword}, '%')
)
OR p.PROJCTARR LIKE CONCAT('%', #{searchKeyword}, '%')
OR p.PROJCTDTL LIKE CONCAT('%', #{searchKeyword}, '%')
OR p.PROJCTZIP LIKE CONCAT('%', #{searchKeyword}, '%')
)
</if>
<if test="category != null and category != ''">
AND SUBSTRING(p.PROJCTSTR, 1, 4) = #{category}
</if>
<if test="excludeEnded != null and excludeEnded == 'true'">
AND (p.PROJCTEND IS NULL OR p.PROJCTEND > CURDATE())
</if>
ORDER BY p.PROJCTSTR DESC
</select>
<!-- 프로젝트 등록 -->
<insert id="insertProject" useGeneratedKeys="true" keyProperty="PROJCTSEQ">
INSERT INTO netprojct (
PROJCTNAM,
PROJCTCOL,
PROJCTSTR,
PROJCTEND,
PROJCTDES,
PROJCTARR,
PROJCTDTL,
PROJCTZIP,
PROJCTCDT,
PROJCTCMB
) VALUES (
#{projctNam},
#{projctCol},
#{projctStr},
#{projctEnd},
#{projctDes},
#{projctArr},
#{projctDtl},
#{projctZip},
#{projctCdt},
#{projctCmb}
)
</insert>
<!-- 프로젝트 수정 -->
<update id="updateProject">
UPDATE netprojct
SET PROJCTNAM = #{projctNam},
PROJCTCOL = #{projctCol},
PROJCTARR = #{projctArr},
PROJCTDTL = #{projctDtl},
PROJCTZIP = #{projctZip},
PROJCTSTR = #{projctStr},
PROJCTEND = #{projctEnd},
PROJCTDES = #{projctDes},
PROJCTUDT = #{projctUdt},
PROJCTUMB = #{projctUmb}
WHERE PROJCTSEQ = #{projctSeq}
</update>
<!-- 프로젝트 등록·수정자 조회 -->
<select id="selectProjectLog" parameterType="int" resultType="map">
SELECT logDate, logMessage
FROM (
SELECT
DATE_FORMAT(p.PROJCTCDT, '%Y-%m-%d %H:%i') AS logDate,
CONCAT('[', m.MEMBERNAM, '] 프로젝트 등록') AS logMessage
FROM netprojct p
JOIN netmember m ON p.PROJCTCMB = m.MEMBERSEQ
WHERE p.PROJCTSEQ = #{projctSeq}
UNION ALL
SELECT
DATE_FORMAT(p.PROJCTUDT, '%Y-%m-%d %H:%i') AS logDate,
CONCAT('[', m.MEMBERNAM, '] 프로젝트 수정') AS logMessage
FROM netprojct p
JOIN netmember m ON p.PROJCTUMB = m.MEMBERSEQ
WHERE p.PROJCTSEQ = #{projctSeq}
AND p.PROJCTUDT IS NOT NULL
) AS logs
ORDER BY logDate DESC;
</select>
<!-- 프로젝트 삭제 -->
<delete id="deleteProject" parameterType="int">
DELETE FROM netprojct WHERE PROJCTSEQ = #{projctSeq}
</delete>
<!-- 프로젝트 모든 사용자 참여기간 조회 -->
<select id="selectUserProjectPeriod" resultType="io.company.localhost.common.dto.MapDto">
SELECT
m.MEMBERSEQ,
m.MEMBERNAM,
p.PROJCTSEQ,
p.PROJCTNAM,
p.PROJCTSTR AS projectStartDate,
p.PROJCTEND AS projectEndDate,
COALESCE((
SELECT MIN(c2.COMMUTDAY)
FROM commuters c2
WHERE c2.PROJCTSEQ = p.PROJCTSEQ
AND c2.MEMBERSEQ = m.MEMBERSEQ
), p.PROJCTSTR) AS userStartDate,
COALESCE((
SELECT MAX(c2.COMMUTDAY)
FROM commuters c2
WHERE c2.PROJCTSEQ = p.PROJCTSEQ
AND c2.MEMBERSEQ = m.MEMBERSEQ
), p.PROJCTEND) AS userEndDate
FROM
netprojct p
LEFT JOIN
commuters c ON p.PROJCTSEQ = c.PROJCTSEQ
LEFT JOIN
netmember m ON c.MEMBERSEQ = m.MEMBERSEQ
WHERE
p.PROJCTSEQ = #{projectSeq}
GROUP BY
m.MEMBERSEQ, m.MEMBERNAM, p.PROJCTSEQ, p.PROJCTNAM, p.PROJCTSTR, p.PROJCTEND
</select>
<select id="selectUserProjectPeriod2" resultType="io.company.localhost.common.dto.MapDto">
SELECT
pm.MEMBERSEQ,
p.PROJCTSEQ,
p.PROJCTNAM,
p.PROJCTSTR AS projectStartDate,
p.PROJCTEND AS projectEndDate,
(
SELECT MIN(c2.COMMUTDAY)
FROM commuters c2
WHERE c2.PROJCTSEQ = p.PROJCTSEQ
AND c2.MEMBERSEQ = pm.MEMBERSEQ
) AS userStartDate,
CASE
WHEN p.PROJCTEND IS NOT NULL THEN (
SELECT MAX(c2.COMMUTDAY)
FROM commuters c2
WHERE c2.PROJCTSEQ = p.PROJCTSEQ
AND c2.MEMBERSEQ = pm.MEMBERSEQ
)
ELSE NULL
END AS userEndDate
FROM promember pm
INNER JOIN netprojct p ON pm.PROJCTSEQ = p.PROJCTSEQ
WHERE pm.MEMBERSEQ = #{memberSeq}
AND pm.PROJCTYON = 1
</select>
</mapper>

View File

@ -0,0 +1,155 @@
<?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="io.company.localhost.mapper.PromemberMapper">
<!-- 프로젝트 등록 후 모든 사용자 참여 -->
<insert id="insertProjectMember">
INSERT INTO promember (PROJCTSEQ, MEMBERSEQ, PROJCTYON)
SELECT
#{projctSeq},
MEMBERSEQ,
<choose>
<when test="disabledMembers != null and disabledMembers.size() > 0">
CASE
WHEN MEMBERSEQ IN
<foreach item="member" collection="disabledMembers" open="(" separator="," close=")">
#{member}
</foreach>
THEN '0'
ELSE '1'
END
</when>
<otherwise>
'1'
</otherwise>
</choose>
FROM netmember;
</insert>
<update id="updateProjectMembers">
UPDATE promember
SET PROJCTYON =
<choose>
<when test="disabledMembers != null and disabledMembers.size() > 0">
CASE
WHEN MEMBERSEQ IN
<foreach item="member" collection="disabledMembers" open="(" separator="," close=")">
#{member}
</foreach>
THEN '0'
ELSE '1'
END
</when>
<otherwise>
'1'
</otherwise>
</choose>
WHERE PROJCTSEQ = #{projctSeq}
</update>
<!-- 새로 가입한 회원 모든 프로젝트 멤버에 미참여 상태로 추가 -->
<insert id="insertNewMemberToProjects">
INSERT INTO promember (PROJCTSEQ, MEMBERSEQ, PROJCTYON)
SELECT PROJCTSEQ, #{memberSeq},
CASE
WHEN PROJCTSEQ IN (1, 2) THEN '1'
ELSE '0'
END AS PROJCTYON
FROM netprojct;
</insert>
<!-- 프로젝트 참여 미참여 -->
<update id="updateProjectMember">
UPDATE promember
SET PROJCTYON = #{projctYon}
WHERE PROJCTSEQ = #{projctSeq}
AND MEMBERSEQ = #{memberSeq}
</update>
<!-- 프로젝트 멤버 조회 -->
<select id="selectProjectMembers" resultType="io.company.localhost.common.dto.MapDto">
SELECT pm.PROJCTSEQ,
pm.MEMBERSEQ,
pm.PROJCTYON,
nm.MEMBERNAM,
nm.MEMBERPRF,
nm.MEMBERCOL as usercolor,
cc.CMNCODNAM as usercolorName
FROM promember pm
JOIN netmember nm ON pm.MEMBERSEQ = nm.MEMBERSEQ
LEFT JOIN commoncod cc on nm.MEMBERCOL = cc.CMNCODVAL
WHERE pm.PROJCTSEQ = #{projctSeq}
</select>
<!-- 사용자가 속한 프로젝트 조회 -->
<select id="selectMemberProjects" resultType="io.company.localhost.common.dto.MapDto">
SELECT
p.PROJCTSEQ,
p.PROJCTNAM,
c.CMNCODNAM AS projctcolor,
MAX(cm.PROJCTLVE) AS last_worked_project,
MAX(cm.COMMUTLVE) AS last_check_out_time,
MAX(cm.COMMUTCMT) AS last_check_in_time
FROM promember pm
JOIN netprojct p ON pm.PROJCTSEQ = p.PROJCTSEQ
LEFT JOIN commoncod c ON p.PROJCTCOL = c.CMNCODVAL AND c.CMNCODYNP = '1'
LEFT JOIN commuters cm
ON pm.MEMBERSEQ = cm.MEMBERSEQ
AND (pm.PROJCTSEQ = cm.PROJCTSEQ OR pm.PROJCTSEQ = cm.PROJCTLVE)
WHERE pm.MEMBERSEQ = #{memberSeq}
AND pm.PROJCTYON = '1'
AND (p.PROJCTEND IS NULL OR p.PROJCTEND >= CURDATE())
GROUP BY p.PROJCTSEQ, p.PROJCTNAM, c.CMNCODNAM
ORDER BY
/* 오늘 퇴근이 있는 프로젝트를 최우선 */
CASE WHEN EXISTS (
SELECT 1 FROM commuters
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTDAY = CURDATE()
AND COMMUTLVE IS NOT NULL
AND PROJCTLVE = p.PROJCTSEQ
) THEN 0 ELSE 1 END,
/* 오늘 출근이 있는 프로젝트를 두 번째 우선순위 */
CASE WHEN EXISTS (
SELECT 1 FROM commuters
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTDAY = CURDATE()
AND PROJCTSEQ = p.PROJCTSEQ
) THEN 0 ELSE 1 END,
/* 마지막 퇴근 프로젝트를 세 번째 우선순위 - 여기서 정확히 프로젝트별 최신 날짜를 확인 */
CASE WHEN p.PROJCTSEQ IN (
SELECT PROJCTLVE
FROM commuters
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTLVE IS NOT NULL
AND COMMUTDAY = (
SELECT MAX(COMMUTDAY)
FROM commuters
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTLVE IS NOT NULL
)
) THEN 0 ELSE 1 END,
/* 마지막 출근 프로젝트를 네 번째 우선순위 */
CASE WHEN p.PROJCTSEQ IN (
SELECT PROJCTSEQ
FROM commuters
WHERE MEMBERSEQ = #{memberSeq}
AND COMMUTDAY = (
SELECT MAX(COMMUTDAY)
FROM commuters
WHERE MEMBERSEQ = #{memberSeq}
)
) THEN 0 ELSE 1 END,
/* 없으면 최신 날짜 기준 */
MAX(cm.COMMUTDAY) DESC,
MAX(cm.COMMUTLVE) DESC,
MAX(cm.COMMUTCMT) DESC,
p.PROJCTSTR DESC
</select>
<delete id="deletePromember" parameterType="int">
DELETE FROM promember WHERE PROJCTSEQ = #{projctSeq}
</delete>
</mapper>

View File

@ -16,13 +16,23 @@
) )
</foreach> </foreach>
</insert> </insert>
<select id="getVoteDetails" parameterType="int" > <select id="selectVoteDetailsResult" parameterType="map">
select SELECT
* d.*,
from COALESCE(COUNT(c.VOTDETSEQ), 0) AS VOTE_COUNT,
votdetail (SELECT COUNT(*)
where FROM votrecord
LOCVOTSEQ = #{LOCVOTSEQ} WHERE LOCVOTSEQ = d.LOCVOTSEQ
AND VOTRECMEM = #{userId}) AS yesvote
FROM
votdetail d
LEFT JOIN
votchoice c ON d.LOCVOTSEQ = c.LOCVOTSEQ AND d.VOTDETSEQ = c.VOTDETSEQ
WHERE
d.LOCVOTSEQ = #{locvotSeq}
GROUP BY
d.VOTDETSEQ, d.LOCVOTCON
ORDER BY
VOTDETSEQ ASC
</select> </select>
</mapper> </mapper>

View File

@ -11,10 +11,12 @@
(#{voteId}, #{user.id}) (#{voteId}, #{user.id})
</foreach> </foreach>
</insert> </insert>
<select id="getVoteMember" parameterType="int" > <select id="selectVoteMember" parameterType="int" >
SELECT SELECT
a.*, n.MEMBERSEQ,
n.*, n.MEMBERNAM,
n.MEMBERCOL,
n.MEMBERPRF,
c.CMNCODNAM AS usercolor, c.CMNCODNAM AS usercolor,
CASE CASE
WHEN v.LOCVOTSEQ IS NOT NULL THEN 1 WHEN v.LOCVOTSEQ IS NOT NULL THEN 1

View File

@ -1,15 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.company.localhost.mapper.VotRecordMapper"> <mapper namespace="io.company.localhost.mapper.VotRecordMapper">
<select id="yesVotetotal" parameterType="map">
select count(*) as yesvote
from
votrecord
where
LOCVOTSEQ = #{id}
and
VOTRECMEM = #{userId}
</select>
<insert id="insertCheckedNums" parameterType="map"> <insert id="insertCheckedNums" parameterType="map">
INSERT INTO votrecord INSERT INTO votrecord
( (

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.company.localhost.mapper.VotchoiceMapper"> <mapper namespace="io.company.localhost.mapper.VotchoiceMapper">
<insert id="insertChoice" parameterType="map"> <insert id="insertChoice" parameterType="map">
INSERT INTO votchoice INSERT INTO votchoice
( (
@ -16,5 +15,4 @@
) )
</foreach> </foreach>
</insert> </insert>
</mapper> </mapper>

View File

@ -30,6 +30,7 @@
CMNCODLV1 = 600; CMNCODLV1 = 600;
</insert> </insert>
<!-- 색상 조회 YON는 user, YNP는 프로젝트-->
<select id="selectColorList" resultType="Map"> <select id="selectColorList" resultType="Map">
SELECT SELECT
CMNCODVAL CMNCODVAL
@ -48,6 +49,7 @@
</if> </if>
</select> </select>
<!-- mbti 조회 -->
<select id="selectMbtiList" resultType="Map"> <select id="selectMbtiList" resultType="Map">
SELECT SELECT
CMNCODVAL CMNCODVAL
@ -60,6 +62,7 @@
CMNCODODR != 0 CMNCODODR != 0
</select> </select>
<!-- 비밀번호 힌트 조회 -->
<select id="selectPwhintList" resultType="Map"> <select id="selectPwhintList" resultType="Map">
SELECT SELECT
CMNCODVAL CMNCODVAL
@ -72,6 +75,7 @@
CMNCODODR != 0 CMNCODODR != 0
</select> </select>
<!-- 선택한 색상 사용 중으로 업데이트 -->
<update id="updateColorYon" parameterType="Map"> <update id="updateColorYon" parameterType="Map">
UPDATE commoncod UPDATE commoncod
SET SET
@ -84,6 +88,7 @@
WHERE CMNCODVAL = #{color}; WHERE CMNCODVAL = #{color};
</update> </update>
<!-- 수정 시 기존 컬러 사용안함으로 업데이트 -->
<update id="updateColorChange" parameterType="Map"> <update id="updateColorChange" parameterType="Map">
UPDATE commoncod UPDATE commoncod
SET SET
@ -101,17 +106,31 @@
WHERE CMNCODVAL BETWEEN 300101 AND 300103 WHERE CMNCODVAL BETWEEN 300101 AND 300103
</select> </select>
<!-- 연도 -->
<select id="selectYearCategories" resultType="Map"> <select id="selectYearCategories" resultType="Map">
SELECT SELECT
CMNCODVAL CMNCODVAL,
,CMNCODNAM CMNCODNAM
FROM FROM
commoncod commoncod
WHERE WHERE
CMNCODLV1 = 900 CMNCODLV1 = 900
AND AND
CMNCODODR != 0 CMNCODODR != 0
AND
(CMNCODNAM = 'All' OR CMNCODNAM IN (
SELECT DISTINCT
CAST(YEAR(STR_TO_DATE(PROJCTSTR, '%Y-%m-%d')) AS CHAR) AS project_year
FROM
netprojct
WHERE
PROJCTSTR IS NOT NULL
))
ORDER BY
CASE WHEN CMNCODODR = 1 THEN 0 ELSE 1 END ASC,
CMNCODODR DESC
</select> </select>
<select id="selectcheckCategoryExists" parameterType="Map" resultType="Long"> <select id="selectcheckCategoryExists" parameterType="Map" resultType="Long">
select select
count(*) checkCategory count(*) checkCategory
@ -127,4 +146,20 @@
FROM commoncod FROM commoncod
WHERE CMNCODVAL IN ('700101', '700102', '700103') WHERE CMNCODVAL IN ('700101', '700102', '700103')
</select> </select>
<select id="selectCodeList" parameterType="Map">
/* 코드 목록 조회 */
SELECT
CMNCODVAL,
CMNCODNAM,
CMNCODODR
FROM
COMMONCOD
WHERE
CMNCODLV1 = #{CMNCODLV1} AND CMNCODLV2 LIKE CONCAT(#{CMNCODLV2}, '%')
AND
CMNCODYON = 1
</select>
</mapper> </mapper>

View File

@ -14,10 +14,10 @@
FROM localbord b FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE LOCBRDTYP = '300103' WHERE LOCBRDTYP = '300103'
<if test="searchKeyword != null and searchKeyword != ''">
AND LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%')
</if>
ORDER BY LOCBRDUDT DESC ORDER BY LOCBRDUDT DESC
<if test="size != null">
LIMIT #{size}
</if>
</select> </select>
<!-- 자유/익명 게시판 조회 (작성자 이름 포함) --> <!-- 자유/익명 게시판 조회 (작성자 이름 포함) -->
@ -28,13 +28,11 @@
b.LOCBRDCON AS content, b.LOCBRDCON AS content,
b.LOCBRDUDT AS date, b.LOCBRDUDT AS date,
b.LOCBRDCNT AS cnt, b.LOCBRDCNT AS cnt,
b.LOCBRDNIC AS nickname,
m.MEMBERNAM AS author m.MEMBERNAM AS author
FROM localbord b FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE b.LOCBRDTYP IN ('300101', '300102') WHERE b.LOCBRDTYP IN ('300101', '300102')
<if test="searchKeyword != null and searchKeyword != ''">
AND b.LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%')
</if>
ORDER BY ORDER BY
<choose> <choose>
<when test="orderBy == 'date'"> b.LOCBRDUDT DESC </when> <when test="orderBy == 'date'"> b.LOCBRDUDT DESC </when>
@ -50,8 +48,8 @@
<!-- 게시물 작성 --> <!-- 게시물 작성 -->
<insert id="insertBoard" parameterType="map" useGeneratedKeys="true" keyProperty="LOCBRDSEQ"> <insert id="insertBoard" parameterType="map" useGeneratedKeys="true" keyProperty="LOCBRDSEQ">
INSERT INTO localbord (LOCBRDTTL, LOCBRDCON, LOCBRDCAT, MEMBERSEQ, LOCBRDCNT, LOCBRDRDT, LOCBRDUDT, LOCBRDPWD, LOCBRDTYP) INSERT INTO localbord (LOCBRDTTL, LOCBRDCON, LOCBRDCAT, MEMBERSEQ, LOCBRDCNT, LOCBRDRDT, LOCBRDUDT, LOCBRDPWD, LOCBRDTYP, LOCBRDNIC)
VALUES (#{LOCBRDTTL}, #{LOCBRDCON}, #{LOCBRDCAT}, #{MEMBERSEQ}, 0, NOW(), NOW(), #{LOCBRDPWD}, #{LOCBRDTYP}) VALUES (#{LOCBRDTTL}, #{LOCBRDCON}, #{LOCBRDCAT}, #{MEMBERSEQ}, 0, NOW(), NOW(), #{LOCBRDPWD}, #{LOCBRDTYP}, #{LOCBRDNIC})
</insert> </insert>
<!-- 첨부파일 저장 --> <!-- 첨부파일 저장 -->
@ -65,6 +63,57 @@
) )
</insert> </insert>
<!-- 멀티 첨부파일 저장 -->
<insert id="insertAttachments" parameterType="map">
INSERT INTO commonfil (
CMNBRDSEQ,
CMNFLENAM,
CMNFLEORG,
CMNFLEPAT,
CMNFLEEXT,
CMNFLESIZ,
CMNFLEREG,
CMNFLERDT
) VALUES
<foreach collection="list" item="item" index="index" open="(" separator="),(" close=")">
#{LOCBRDSEQ},
#{item.saveFileName},
#{item.originalFileName},
#{item.filePath},
#{item.extension},
#{item.fileSize},
#{CMNFLEREG},
NOW()
</foreach>
</insert>
<!-- 에디터 첨부 이미지 저장 -->
<insert id="insertUploadEditorImageInfo" parameterType="map">
<selectKey keyProperty="id" order="AFTER" resultType="long">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO commonfil (
CMNFLENAM,
CMNFLEORG,
CMNFLEPAT,
CMNFLEEXT,
CMNFLESIZ,
CMNFLEREG,
CMNFLERDT,
CMNFLETYP
) VALUES (
#{CMNFLENAM},
#{CMNFLEORG},
#{CMNFLEPAT},
#{CMNFLEEXT},
#{CMNFLESIZ},
#{CMNFLEREG},
NOW(),
2
)
</insert>
<!-- 게시물 상세정보 조회 --> <!-- 게시물 상세정보 조회 -->
<select id="selectBoardDetail" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectBoardDetail" resultType="io.company.localhost.common.dto.MapDto">
SELECT SELECT
@ -74,7 +123,29 @@
b.LOCBRDUDT AS date, b.LOCBRDUDT AS date,
b.LOCBRDTYP AS type, b.LOCBRDTYP AS type,
b.LOCBRDCNT AS cnt, b.LOCBRDCNT AS cnt,
m.MEMBERNAM AS author b.LOCBRDNIC AS nickname,
m.MEMBERNAM AS author,
m.MEMBERSEQ AS authorId,
m.MEMBERPRF AS profileImg
FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE b.LOCBRDSEQ = #{boardId}
</select>
<!-- 게시물 상세정보 조회2 -->
<select id="selectBoardDetail2" resultType="io.company.localhost.common.dto.MapDto">
SELECT
b.LOCBRDSEQ AS id,
b.LOCBRDTTL AS title,
b.LOCBRDCON AS content,
b.LOCBRDUDT AS date,
b.LOCBRDTYP AS type,
b.LOCBRDNIC AS nickname,
b.LOCBRDCNT AS cnt,
b.LOCBRDPWD AS password,
m.MEMBERNAM AS author,
m.MEMBERSEQ AS authorId,
m.MEMBERPRF AS profileImg
FROM localbord b FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE b.LOCBRDSEQ = #{boardId} WHERE b.LOCBRDSEQ = #{boardId}
@ -86,10 +157,36 @@
SELECT CMNFLESEQ AS id, CMNFLEORG AS originalName, CMNFLENAM AS fileName, CMNFLEPAT AS path, SELECT CMNFLESEQ AS id, CMNFLEORG AS originalName, CMNFLENAM AS fileName, CMNFLEPAT AS path,
CMNFLEEXT AS extension, CMNFLESIZ AS size, CMNFLERDT AS uploadDate CMNFLEEXT AS extension, CMNFLESIZ AS size, CMNFLERDT AS uploadDate
FROM commonfil FROM commonfil
WHERE CMNBRDSEQ = #{boardId} WHERE CMNBRDSEQ = #{boardId} and CMNFLETYP = 1
ORDER BY CMNFLERDT DESC ORDER BY CMNFLERDT DESC
</select> </select>
<!-- 게시글 삭제 파일 목록 조회 -->
<select id="selectFilesInfo" resultType="io.company.localhost.vo.FileVo">
SELECT
CMNFLESEQ,
CMNBRDSEQ,
CMNFLENAM,
CMNFLEORG,
CMNFLEPAT,
CMNFLEEXT,
CMNFLESIZ,
CMNFLETYP
FROM
COMMONFIL
WHERE
CMNBRDSEQ = #{LOCBRDSEQ}
AND CMNFLETYP IN (1, 2)
</select>
<!-- 파일 목록 조회 -->
<select id="deleteFiles">
DELETE FROM
COMMONFIL
WHERE
CMNBRDSEQ = #{LOCBRDSEQ}
</select>
<!-- 게시물 삭제 --> <!-- 게시물 삭제 -->
<delete id="deleteBoard"> <delete id="deleteBoard">
DELETE FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ} DELETE FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ}
@ -101,6 +198,18 @@
WHERE LOCBRDSEQ = #{LOCBRDSEQ} WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete> </delete>
<!-- 게시물 삭제 시 좋아요/싫어요 삭제 -->
<delete id="deleteGoodOrBadByBoardId">
DELETE FROM localgorb
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete>
<!-- 댓글 및 대댓글 삭제 시 좋아요/싫어요 삭제 -->
<delete id="deleteGoodOrBadByCommentId">
DELETE FROM localgorb
WHERE LOCCMTSEQ = #{LOCCMTSEQ}
</delete>
<!-- 게시물 수정 --> <!-- 게시물 수정 -->
<update id="updateBoard"> <update id="updateBoard">
UPDATE localbord UPDATE localbord
@ -112,18 +221,46 @@
<select id="selectReaction" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectReaction" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD SELECT LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD
FROM localgorb FROM localgorb
WHERE (LOCBRDSEQ = #{LOCBRDSEQ} OR (#{LOCBRDSEQ} IS NULL AND LOCBRDSEQ IS NULL)) WHERE
AND (LOCCMTSEQ = #{LOCCMTSEQ} OR (#{LOCCMTSEQ} IS NULL AND LOCCMTSEQ IS NULL)) <choose>
AND MEMBERSEQ = #{MEMBERSEQ} <when test="LOCCMTSEQ == null">
LOCBRDSEQ = #{LOCBRDSEQ} AND LOCCMTSEQ IS NULL
</when>
<otherwise>
LOCBRDSEQ = #{LOCBRDSEQ} AND LOCCMTSEQ = #{LOCCMTSEQ}
</otherwise>
</choose>
AND
MEMBERSEQ = #{MEMBERSEQ}
</select> </select>
<!-- 반응 업데이트 --> <!-- 반응 업데이트 -->
<update id="updateReaction"> <update id="updateReaction">
UPDATE localgorb UPDATE localgorb
SET LOCGOBGOD = #{LOCGOBGOD}, LOCGOBBAD = #{LOCGOBBAD} SET LOCGOBGOD = #{LOCGOBGOD}, LOCGOBBAD = #{LOCGOBBAD}
WHERE (LOCBRDSEQ = #{LOCBRDSEQ} OR (#{LOCBRDSEQ} IS NULL AND LOCBRDSEQ IS NULL)) WHERE
AND (LOCCMTSEQ = #{LOCCMTSEQ} OR (#{LOCCMTSEQ} IS NULL AND LOCCMTSEQ IS NULL)) <choose>
AND MEMBERSEQ = #{MEMBERSEQ} <when test="LOCCMTSEQ == null">
LOCBRDSEQ = #{LOCBRDSEQ} AND LOCCMTSEQ IS NULL
</when>
<otherwise>
LOCBRDSEQ = #{LOCBRDSEQ} AND LOCCMTSEQ = #{LOCCMTSEQ}
</otherwise>
</choose>
AND
MEMBERSEQ = #{MEMBERSEQ}
</update>
<update id="updateBoardIndexToFile">
UPDATE
COMMONFIL
SET
CMNBRDSEQ = #{LOCBRDSEQ}
WHERE
CMNFLESEQ IN
<foreach collection="editorImgList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</update> </update>
<!-- 새 반응 삽입 --> <!-- 새 반응 삽입 -->
@ -136,12 +273,14 @@
<select id="selectComments" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectComments" resultType="io.company.localhost.common.dto.MapDto">
SELECT SELECT
c.LOCCMTSEQ,c.LOCBRDSEQ,c.LOCCMTPNT,c.LOCCMTRPY, c.LOCCMTSEQ,c.LOCBRDSEQ,c.LOCCMTPNT,c.LOCCMTRPY,
c.LOCCMTUDT,c.LOCCMTPWD,c.LOCCMTRDT,c.LOCCMTPNT, c.LOCCMTUDT,c.LOCCMTPWD,c.LOCCMTRDT,
m.MEMBERNAM AS author m.MEMBERNAM AS author,
m.MEMBERSEQ AS authorId,
c.LOCCMTNIC
FROM localcomt c FROM localcomt c
LEFT JOIN netmember m ON c.MEMBERSEQ = m.MEMBERSEQ LEFT JOIN netmember m ON c.MEMBERSEQ = m.MEMBERSEQ
WHERE LOCBRDSEQ = #{LOCBRDSEQ} and LOCCMTPNT = 1 WHERE LOCBRDSEQ = #{LOCBRDSEQ} and LOCCMTPNT = 1
ORDER BY LOCCMTPNT ASC, LOCCMTUDT ASC ORDER BY LOCCMTRDT DESC
</select> </select>
<!-- 대댓글 조회 --> <!-- 대댓글 조회 -->
@ -149,17 +288,20 @@
SELECT SELECT
c.LOCCMTSEQ,c.LOCBRDSEQ,c.LOCCMTPNT,c.LOCCMTRPY, c.LOCCMTSEQ,c.LOCBRDSEQ,c.LOCCMTPNT,c.LOCCMTRPY,
c.LOCCMTUDT,c.LOCCMTPWD,c.LOCCMTRDT,c.LOCCMTPNT, c.LOCCMTUDT,c.LOCCMTPWD,c.LOCCMTRDT,c.LOCCMTPNT,
m.MEMBERNAM AS author m.MEMBERNAM AS author,
m.MEMBERSEQ AS authorId,
m.MEMBERPRF AS profileImg,
c.LOCCMTNIC
FROM localcomt c FROM localcomt c
LEFT JOIN netmember m ON c.MEMBERSEQ = m.MEMBERSEQ LEFT JOIN netmember m ON c.MEMBERSEQ = m.MEMBERSEQ
WHERE LOCCMTPNT = #{LOCCMTPNT} and LOCCMTPNT != 1 WHERE LOCCMTPNT = #{LOCCMTPNT} and LOCCMTPNT != 1
ORDER BY LOCCMTPNT ASC, LOCCMTUDT ASC ORDER BY LOCCMTRDT DESC
</select> </select>
<!-- 댓글/대댓글 작성 --> <!-- 댓글/대댓글 작성 -->
<insert id="insertCommentOrReply"> <insert id="insertCommentOrReply">
INSERT INTO localcomt (LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTUDT, LOCCMTPNT, MEMBERSEQ) INSERT INTO localcomt (LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTUDT, LOCCMTPNT, MEMBERSEQ,LOCCMTNIC)
VALUES (#{LOCBRDSEQ}, #{LOCCMTRPY}, #{LOCCMTPWD}, NOW(), NOW() , #{LOCCMTPNT}, #{MEMBERSEQ}) VALUES (#{LOCBRDSEQ}, #{LOCCMTRPY}, #{LOCCMTPWD}, NOW(), NOW() , #{LOCCMTPNT}, #{MEMBERSEQ},#{LOCCMTNIC})
</insert> </insert>
<!-- 댓글/대댓글 수정 --> <!-- 댓글/대댓글 수정 -->
@ -173,6 +315,7 @@
<update id="updateSoftDeleteComment"> <update id="updateSoftDeleteComment">
UPDATE localcomt UPDATE localcomt
SET LOCCMTRPY = '삭제된 댓글입니다' SET LOCCMTRPY = '삭제된 댓글입니다'
,LOCCMTUDT = NOW()
WHERE LOCCMTSEQ = #{LOCCMTSEQ} WHERE LOCCMTSEQ = #{LOCCMTSEQ}
AND EXISTS ( AND EXISTS (
SELECT 1 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ} SELECT 1 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ}
@ -188,22 +331,12 @@
) )
</delete> </delete>
<!-- 대댓글 삭제 --> <!-- 특정 댓글에 달린 대댓글 개수 조회 -->
<delete id="deleteReply"> <select id="selectReplyCount" resultType="int">
DELETE FROM localcomt SELECT COUNT(*)
WHERE LOCCMTSEQ = #{LOCCMTSEQ} FROM localcomt
WHERE LOCCMTPNT = #{LOCCMTSEQ}
AND LOCCMTPNT IS NOT NULL AND LOCCMTPNT IS NOT NULL
</delete>
<!-- 대댓글인지 확인 -->
<select id="selectIsReply" resultType="boolean">
SELECT COUNT(1) > 0 FROM localcomt
WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPNT IS NOT NULL
</select>
<!-- 댓글에 대댓글이 있는지 확인 -->
<select id="selectHasReplies" resultType="boolean">
SELECT COUNT(1) > 0 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ}
</select> </select>
<!-- 댓글 비밀번호 조회 --> <!-- 댓글 비밀번호 조회 -->
@ -231,14 +364,14 @@
<select id="selectCountComments" parameterType="long" resultType="int"> <select id="selectCountComments" parameterType="long" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM localcomt FROM localcomt
WHERE LOCBRDSEQ = #{boardId} WHERE LOCBRDSEQ = #{boardId} and LOCCMTPNT = 1
</select> </select>
<!-- 첨부파일 유무 --> <!-- 첨부파일 유무 -->
<select id="selectIsAttachments" resultType="int"> <select id="selectIsAttachments" resultType="int">
SELECT COUNT(*) SELECT COUNT(*)
FROM commonfil FROM commonfil
WHERE CMNBRDSEQ = #{boardId} WHERE CMNBRDSEQ = #{boardId} and CMNFLETYP = 1
</select> </select>
<!-- 게시물 좋아요/싫어요 개수 조회 --> <!-- 게시물 좋아요/싫어요 개수 조회 -->
@ -247,8 +380,33 @@
COALESCE(SUM(CASE WHEN LOCGOBGOD = 'T' THEN 1 ELSE 0 END), 0) AS likeCount, COALESCE(SUM(CASE WHEN LOCGOBGOD = 'T' THEN 1 ELSE 0 END), 0) AS likeCount,
COALESCE(SUM(CASE WHEN LOCGOBBAD = 'T' THEN 1 ELSE 0 END), 0) AS dislikeCount COALESCE(SUM(CASE WHEN LOCGOBBAD = 'T' THEN 1 ELSE 0 END), 0) AS dislikeCount
FROM localgorb FROM localgorb
WHERE LOCBRDSEQ = #{boardId}; WHERE LOCBRDSEQ = #{boardId} AND LOCCMTSEQ IS NULL;
</select>
<!-- 사용자 게시물 좋아요/싫어요 상태 조회 -->
<select id="selectMyBoardReaction">
SELECT
LOCGOBGOD,
LOCGOBBAD
FROM
localgorb
WHERE
LOCBRDSEQ = #{id}
AND LOCCMTSEQ IS NULL
AND MEMBERSEQ = #{userId};
</select>
<!-- 사용자 댓글 게시물 좋아요/싫어요 상태 조회 -->
<select id="selectMyBoardReactions">
SELECT
LOCGOBGOD,
LOCGOBBAD
FROM
localgorb
WHERE
LOCBRDSEQ = #{boardId}
AND LOCCMTSEQ = #{commentId}
AND MEMBERSEQ = #{userId};
</select> </select>
<!-- 댓글별 좋아요/싫어요 개수 조회 --> <!-- 댓글별 좋아요/싫어요 개수 조회 -->
@ -262,5 +420,64 @@
LIMIT 1 LIMIT 1
</select> </select>
<!-- 삭제 파일 정보 조회 -->
<select id="selectDelFileInfo" >
SELECT
CMNFLEPAT
FROM
commonfil
WHERE
CMNFLESEQ in
<foreach collection="array" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</select>
<!-- 파일 정보 삭제 -->
<delete id="deleteFileInfo" >
DELETE FROM
commonfil
WHERE
CMNFLESEQ in
<foreach collection="array" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</delete>
<!-- 프로파일 이미지 조회 -->
<select id="selectUserProfileImg">
SELECT
MEMBERPRF
FROM
NETMEMBER
WHERE
MEMBERSEQ = ${userId}
</select>
<!-- 게시글 정보가 없는 파일 조회-->
<select id="selectFilesBoardIndexIsNull" resultType="io.company.localhost.vo.FileVo">
SELECT
CMNFLESEQ,
CMNBRDSEQ,
CMNFLENAM,
CMNFLEORG,
CMNFLEPAT,
CMNFLEEXT,
CMNFLESIZ,
CMNFLETYP
FROM
COMMONFIL
WHERE
CMNBRDSEQ IS NULL
</select>
<!-- 파일 데이터 삭제 -->
<delete id="deleteTrashFileData">
DELETE FROM
COMMONFIL
WHERE
CMNFLESEQ = #{CMNFLESEQ}
</delete>
</mapper> </mapper>

View File

@ -8,22 +8,49 @@
VALUES (#{employeeId}, #{date}, #{type}, NOW(), #{receiverId}) VALUES (#{employeeId}, #{date}, #{type}, NOW(), #{receiverId})
</insert> </insert>
<!-- 휴가 데이터 삭제 --> <!-- 특정 날짜의 휴가 ID 조회 (존재 여부 확인) -->
<delete id="deleteVacation" parameterType="long"> <select id="findVacationIdByDate" resultType="Long">
SELECT LOCVACSEQ
FROM localvaca
WHERE MEMBERSEQ = #{userId} AND LOCVACUDT = #{date}
AND LOCVACRMM IS NULL
</select>
<!-- 휴가 수정 (기존 데이터가 존재하는 경우) -->
<update id="updateVacation">
UPDATE localvaca
SET LOCVACTYP = #{type}
WHERE LOCVACSEQ = #{id}
</update>
<!-- 여러 개의 휴가 삭제 -->
<delete id="deleteVacation">
DELETE FROM localvaca DELETE FROM localvaca
WHERE LOCVACSEQ = #{vacationId} WHERE LOCVACSEQ IN
<foreach item="id" collection="vacationIds" open="(" separator="," close=")">
#{id}
</foreach>
</delete> </delete>
<!-- 휴가 정보 조회 --> <!-- 휴가 정보 조회 -->
<select id="selectVacations" parameterType="map" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectVacations" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCVACSEQ, MEMBERSEQ, LOCVACUDT, LOCVACTYP, LOCVACRMM SELECT
FROM localvaca A.LOCVACSEQ, A.MEMBERSEQ, A.LOCVACUDT, A.LOCVACTYP, A.LOCVACRMM, B.MEMBERPRF, B.MEMBERNAM, C.CMNCODNAM AS usercolor
WHERE DATE_FORMAT(LOCVACUDT, '%Y-%m') = CONCAT(#{year}, '-', LPAD(#{month}, 2, '0')) FROM
localvaca A
LEFT JOIN
NETMEMBER B ON A.MEMBERSEQ = B.MEMBERSEQ
LEFT JOIN
COMMONCOD C ON C.CMNCODVAL = B.MEMBERCOL
WHERE
DATE_FORMAT(LOCVACUDT, '%Y-%m') = CONCAT(#{year}, '-', LPAD(#{month}, 2, '0'))
ORDER BY
A.LOCVACUDT ASC
</select> </select>
<!-- 사용자가 사용한 연차 목록 조회 --> <!-- 사용자가 사용한 연차 목록 조회 -->
<select id="selectUsedVacations" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectUsedVacations" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCVACUDT AS date, LOCVACTYP AS type, LOCVACRMM AS receiverId, SELECT LOCVACSEQ AS id, LOCVACUDT AS date, LOCVACTYP AS type, LOCVACRMM AS receiverId,
-- 반차(700101, 700102)는 0.5, 연차(700103)는 1로 계산 -- 반차(700101, 700102)는 0.5, 연차(700103)는 1로 계산
SUM(CASE SUM(CASE
WHEN LOCVACTYP IN ('700101', '700102') THEN 0.5 WHEN LOCVACTYP IN ('700101', '700102') THEN 0.5
@ -32,22 +59,32 @@
END) AS used_quota END) AS used_quota
FROM localvaca FROM localvaca
WHERE MEMBERSEQ = #{userId} WHERE MEMBERSEQ = #{userId}
AND DATE_FORMAT(LOCVACUDT, '%Y') = DATE_FORMAT(CURDATE(), '%Y') AND YEAR(LOCVACUDT) = #{year}
GROUP BY LOCVACUDT, LOCVACTYP, LOCVACRMM GROUP BY LOCVACUDT, LOCVACTYP, LOCVACRMM
ORDER BY LOCVACUDT DESC ORDER BY LOCVACUDT DESC
</select> </select>
<!-- 사용자가 받은 연차 목록 조회 --> <!-- 사용자가 받은 연차 목록 조회 -->
<select id="selectReceivedVacations" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectReceivedVacations" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCVACUDT AS date, LOCVACTYP AS type, MEMBERSEQ AS senderId SELECT
LOCVACUDT AS date,
LOCVACTYP AS type,
MEMBERSEQ AS senderId,
-- 반차(700101, 700102)는 0.5, 연차(700103)는 1로 계산하여 받은 연차 수량 저장
SUM(
CASE
WHEN LOCVACTYP IN ('700101', '700102') THEN 0.5
WHEN LOCVACTYP = '700103' THEN 1
ELSE 0
END
) AS received_quota
FROM localvaca FROM localvaca
WHERE LOCVACRMM = #{userId} WHERE LOCVACRMM = #{userId} -- 현재 로그인한 사용자가 받은 연차
AND DATE_FORMAT(LOCVACUDT, '%Y') = DATE_FORMAT(CURDATE(), '%Y') AND YEAR(LOCVACUDT) = #{year} -- 해당 연도의 데이터만 가져옴
GROUP BY LOCVACUDT, LOCVACTYP, MEMBERSEQ GROUP BY LOCVACUDT, LOCVACTYP, MEMBERSEQ -- 연차를 보낸 사람별로 그룹화
ORDER BY LOCVACUDT DESC ORDER BY LOCVACUDT DESC;
</select> </select>
<!-- 전체 직원 남은 연차 조회 --> <!-- 전체 직원 남은 연차 조회 -->
<select id="selectEmployeeRemainingVacation" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectEmployeeRemainingVacation" resultType="io.company.localhost.common.dto.MapDto">
<![CDATA[ <![CDATA[
@ -112,7 +149,33 @@
</select> </select>
<select id="selectSentVacationCount" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectSentVacationCount" resultType="io.company.localhost.common.dto.MapDto">
SELECT COUNT(*) as count FROM localvaca WHERE MEMBERSEQ = #{userId} AND LOCVACRMM = #{receiverId} SELECT COUNT(*) as count FROM localvaca WHERE MEMBERSEQ = #{userId} AND LOCVACRMM = #{receiverId} AND YEAR(LOCVACUDT) = YEAR(NOW())
</select>
<select id="selectMemberVacationsInMain">
/* 메인페이지 휴가자 조회 */
SELECT
A.LOCVACSEQ,
A.MEMBERSEQ,
A.LOCVACUDT,
A.LOCVACTYP,
A.LOCVACRMM,
B.MEMBERPRF,
B.MEMBERNAM,
C.CMNCODNAM as usercolor
FROM
localvaca A
LEFT JOIN
NETMEMBER B on A.MEMBERSEQ = B.MEMBERSEQ
LEFT JOIN
COMMONCOD C on C.CMNCODVAL = B.MEMBERCOL
WHERE
DATE_FORMAT(LOCVACUDT, '%Y-%m') = CONCAT(#{year}, '-', LPAD(${month}, 2, '0'))
AND LOCVACRMM is null
GROUP BY
A.LOCVACUDT, A.MEMBERSEQ
ORDER BY
A.LOCVACUDT ASC;
</select> </select>

View File

@ -1,7 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?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"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="io.company.localhost.mapper.localvoteMapper"> <mapper namespace="io.company.localhost.mapper.localvoteMapper">
<sql id="searchConditions">
<if test="voteset != null and voteset != ''">
<choose>
<when test='voteset == "1"'>
AND a.LOCVOTDDT IS NOT NULL
</when>
<when test='voteset == "2"'>
AND a.LOCVOTDDT IS NULL
AND a.LOCVOTDEL IS NULL
</when>
</choose>
</if>
</sql>
<insert id="insertVote" parameterType="map" useGeneratedKeys="true" keyProperty="voteId"> <insert id="insertVote" parameterType="map" useGeneratedKeys="true" keyProperty="voteId">
insert into localvote insert into localvote
( (
@ -22,25 +34,64 @@
,#{votemMltiIs} ,#{votemMltiIs}
) )
</insert> </insert>
<select id="getVoteList" parameterType="map"> <select id="selectVoteList" parameterType="map">
select SELECT * FROM (
a.* SELECT
,DATE_FORMAT(a.LOCVOTRDT, '%Y-%m-%d %H:%i') AS formatted_LOCVOTRDT a.*,
,DATE_FORMAT(a.LOCVOTEDT, '%Y-%m-%d %H:%i') AS formatted_LOCVOTEDT DATE_FORMAT(a.LOCVOTRDT, '%Y-%m-%d %H:%i') AS formatted_LOCVOTRDT,
,b.* DATE_FORMAT(a.LOCVOTEDT, '%Y-%m-%d %H:%i') AS formatted_LOCVOTEDT,
,c.CMNCODNAM usercolor b.MEMBERSEQ,
from b.MEMBERNAM,
b.MEMBERCOL,
b.MEMBERPRF,
c.CMNCODNAM AS usercolor,
(SELECT COUNT(*) FROM votmember vm WHERE vm.LOCVOTSEQ = a.LOCVOTSEQ) AS total_votable,
(SELECT COUNT(*) FROM votrecord v WHERE v.LOCVOTSEQ = a.LOCVOTSEQ) AS total_voted,
CASE
WHEN EXISTS (
SELECT 1
FROM votrecord v
WHERE v.LOCVOTSEQ = a.LOCVOTSEQ
AND v.VOTRECMEM = #{userId}
) THEN 'Y'
ELSE 'N'
END AS myvoted
FROM
localvote a localvote a
LEFT JOIN LEFT JOIN
netmember b netmember b ON a.LOCVOTREG = b.MEMBERSEQ
on LEFT JOIN
a.LOCVOTREG = b.MEMBERSEQ commoncod c ON b.MEMBERCOL = c.CMNCODVAL
left join WHERE
commoncod c 1=1
on <include refid="searchConditions"/>
b.MEMBERCOL = c.CMNCODVAL AND EXISTS (
order by SELECT 1 FROM votmember vm
a.LOCVOTRDT desc WHERE vm.LOCVOTSEQ = a.LOCVOTSEQ
AND vm.MEMBERSEQ = #{userId}
)
) AS subquery
WHERE 1=1
<if test="myVote != null and myVote != ''">
<choose>
<when test='myVote == "1"' >
AND myvoted = 'Y'
AND LOCVOTDEL IS NULL
</when>
<when test='myVote == "2"' >
AND myvoted = 'N'
AND LOCVOTDEL IS NULL
</when>
</choose>
</if>
<choose>
<when test='myVote == "2"'>
ORDER BY LOCVOTEDT ASC, formatted_LOCVOTRDT DESC
</when>
<otherwise>
ORDER BY formatted_LOCVOTRDT DESC
</otherwise>
</choose>
</select> </select>
<update id="updateEndData" parameterType="map"> <update id="updateEndData" parameterType="map">
UPDATE UPDATE
@ -49,4 +100,18 @@
LOCVOTDDT = now() LOCVOTDDT = now()
WHERE LOCVOTSEQ = #{endVoteId} WHERE LOCVOTSEQ = #{endVoteId}
</update> </update>
<update id="updateDeleteData" parameterType="map">
UPDATE
localvote
SET
LOCVOTDEL = now()
WHERE LOCVOTSEQ = #{deleteVoteId}
</update>
<update id="updateRandomResult" parameterType="map">
UPDATE
localvote
SET
LOCVOTRES = #{LOCVOTCON}
WHERE LOCVOTSEQ = #{voteid}
</update>
</mapper> </mapper>

View File

@ -1,124 +0,0 @@
<?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="io.company.localhost.mapper.NetprojctMapper">
<!-- 프로젝트 목록 조회 -->
<select id="selectProject" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
SELECT DISTINCT
p.*,
c.CMNCODNAM AS projctcolor
FROM netprojct p
LEFT JOIN commoncod c ON p.PROJCTCOL = c.CMNCODVAL
LEFT JOIN promember pm ON p.PROJCTSEQ = pm.PROJCTSEQ
WHERE c.CMNCODYON = '1'
<if test="searchKeyword != null and searchKeyword != ''">
AND (
p.PROJCTNAM LIKE CONCAT('%', #{searchKeyword}, '%')
OR EXISTS (
SELECT 1
FROM promember pm2
JOIN netmember m ON pm2.MEMBERSEQ = m.MEMBERSEQ
WHERE pm2.PROJCTSEQ = p.PROJCTSEQ
AND pm2.PROJCTYON = '1'
AND m.membernam LIKE CONCAT('%', #{searchKeyword}, '%')
)
OR p.PROJCTARR LIKE CONCAT('%', #{searchKeyword}, '%')
OR p.PROJCTDTL LIKE CONCAT('%', #{searchKeyword}, '%')
OR p.PROJCTZIP LIKE CONCAT('%', #{searchKeyword}, '%')
)
</if>
<if test="category != null and category != ''">
AND SUBSTRING(p.PROJCTSTR, 1, 4) = #{category}
</if>
ORDER BY p.PROJCTSEQ DESC
</select>
<!-- 프로젝트 등록 -->
<insert id="insertProject" useGeneratedKeys="true" keyProperty="PROJCTSEQ">
INSERT INTO netprojct (
PROJCTNAM,
PROJCTCOL,
PROJCTSTR,
PROJCTEND,
PROJCTDES,
PROJCTARR,
PROJCTDTL,
PROJCTZIP,
PROJCTCDT,
PROJCTCMB
) VALUES (
#{projctNam},
#{projctCol},
#{projctStr},
#{projctEnd},
#{projctDes},
#{projctArr},
#{projctDtl},
#{projctZip},
#{projctCdt},
#{projctCmb}
)
</insert>
<!-- 프로젝트 수정 -->
<update id="updateProject">
UPDATE netprojct
SET PROJCTNAM = #{projctNam},
PROJCTCOL = #{projctCol},
PROJCTARR = #{projctArr},
PROJCTDTL = #{projctDtl},
PROJCTZIP = #{projctZip},
PROJCTSTR = #{projctStr},
PROJCTEND = #{projctEnd},
PROJCTDES = #{projctDes},
PROJCTUDT = #{projctUdt},
PROJCTUMB = #{projctUmb}
WHERE PROJCTSEQ = #{projctSeq}
</update>
<!-- 프로젝트 등록 후 모든 사용자 자동 참여 -->
<insert id="insertProjectMember">
INSERT INTO promember (PROJCTSEQ, MEMBERSEQ, PROJCTYON)
SELECT #{projctSeq}, MEMBERSEQ, '1' FROM netmember;
</insert>
<!-- 프로젝트 참여 미참여 -->
<update id="updateProjectMember">
UPDATE promember
SET PROJCTYON = #{projctYon}
WHERE PROJCTSEQ = #{projctSeq}
AND MEMBERSEQ = #{memberSeq}
</update>
<!-- 프로젝트 멤버 조회 -->
<select id="selectProjectMembers" resultType="io.company.localhost.common.dto.MapDto">
SELECT pm.PROJCTSEQ,
pm.MEMBERSEQ,
pm.PROJCTYON,
nm.MEMBERNAM,
nm.MEMBERPRF,
nm.MEMBERCOL as usercolor
FROM promember pm
JOIN netmember nm ON pm.MEMBERSEQ = nm.MEMBERSEQ
WHERE pm.PROJCTSEQ = #{projctSeq}
</select>
<!-- 프로젝트 로그 조회 -->
<select id="selectProjectLog" parameterType="int" resultType="map">
SELECT
DATE_FORMAT(PROJCTCDT, '%Y-%m-%d %H:%i') as createDate,
PROJCTCMB as creator,
CASE
WHEN PROJCTUDT IS NOT NULL THEN DATE_FORMAT(PROJCTUDT, '%Y-%m-%d %H:%i')
ELSE NULL
END as updateDate,
PROJCTUMB as updater
FROM netprojct
WHERE PROJCTSEQ = #{projctSeq}
</select>
</mapper>

View File

@ -4,54 +4,56 @@
<sql id="searchConditions"> <sql id="searchConditions">
<!-- 검색어 조건 --> <!-- 검색어 조건 -->
<if test="searchKeyword != null and searchKeyword != ''"> <if test="searchKeyword != null and searchKeyword != ''">
and (w.WRDDICTTL like CONCAT('%', #{searchKeyword}, '%') and (
or w.WRDDICCON like CONCAT('%', #{searchKeyword}, '%')) w.WRDDICTTL LIKE CONCAT('%', #{searchKeyword}, '%')
OR w.WRDDICCON LIKE CONCAT('%', #{searchKeyword}, '%')
)
</if> </if>
<!-- 색인표 조건 --> <!-- 색인표 조건 -->
<if test="indexKeyword != null and indexKeyword != ''"> <if test="indexKeyword != null and indexKeyword != ''">
<choose> <choose>
<!-- 한글 ㄱ ~ ㅎ에 대한 검색 --> <!-- 한글 ㄱ ~ ㅎ에 대한 검색 (자음만 있는 경우도 포함) -->
<when test='indexKeyword == "ㄱ"'> <when test='indexKeyword == "ㄱ"'>
and w.WRDDICTTL BETWEEN '가' AND '깋' AND (w.WRDDICTTL BETWEEN '가' AND '깋' OR w.WRDDICTTL LIKE 'ㄱ%')
</when> </when>
<when test='indexKeyword == "ㄴ"'> <when test='indexKeyword == "ㄴ"'>
and w.WRDDICTTL BETWEEN '나' AND '닣' AND (w.WRDDICTTL BETWEEN '나' AND '닣' OR w.WRDDICTTL LIKE 'ㄴ%')
</when> </when>
<when test='indexKeyword == "ㄷ"'> <when test='indexKeyword == "ㄷ"'>
and w.WRDDICTTL BETWEEN '다' AND '딷' AND (w.WRDDICTTL BETWEEN '다' AND '딷' OR w.WRDDICTTL LIKE 'ㄷ%')
</when> </when>
<when test='indexKeyword == "ㄹ"'> <when test='indexKeyword == "ㄹ"'>
and w.WRDDICTTL BETWEEN '라' AND '릿' AND (w.WRDDICTTL BETWEEN '라' AND '릿' OR w.WRDDICTTL LIKE 'ㄹ%')
</when> </when>
<when test='indexKeyword == "ㅁ"'> <when test='indexKeyword == "ㅁ"'>
and w.WRDDICTTL BETWEEN '마' AND '맇' AND (w.WRDDICTTL BETWEEN '마' AND '밓' OR w.WRDDICTTL LIKE 'ㅁ%')
</when> </when>
<when test='indexKeyword == "ㅂ"'> <when test='indexKeyword == "ㅂ"'>
and w.WRDDICTTL BETWEEN '바' AND '빟' AND (w.WRDDICTTL BETWEEN '바' AND '빟' OR w.WRDDICTTL LIKE 'ㅂ%')
</when> </when>
<when test='indexKeyword == "ㅅ"'> <when test='indexKeyword == "ㅅ"'>
and w.WRDDICTTL BETWEEN '사' AND '싷' AND (w.WRDDICTTL BETWEEN '사' AND '싷' OR w.WRDDICTTL LIKE 'ㅅ%')
</when> </when>
<when test='indexKeyword == "ㅇ"'> <when test='indexKeyword == "ㅇ"'>
and w.WRDDICTTL BETWEEN '아' AND '잏' AND (w.WRDDICTTL BETWEEN '아' AND '잏' OR w.WRDDICTTL LIKE 'ㅇ%')
</when> </when>
<when test='indexKeyword == "ㅈ"'> <when test='indexKeyword == "ㅈ"'>
and w.WRDDICTTL BETWEEN '자' AND '짛' AND (w.WRDDICTTL BETWEEN '자' AND '짛' OR w.WRDDICTTL LIKE 'ㅈ%')
</when> </when>
<when test='indexKeyword == "ㅊ"'> <when test='indexKeyword == "ㅊ"'>
and w.WRDDICTTL BETWEEN '차' AND '칳' AND (w.WRDDICTTL BETWEEN '차' AND '칳' OR w.WRDDICTTL LIKE 'ㅊ%')
</when> </when>
<when test='indexKeyword == "ㅋ"'> <when test='indexKeyword == "ㅋ"'>
and w.WRDDICTTL BETWEEN '카' AND '킿' AND (w.WRDDICTTL BETWEEN '카' AND '킿' OR w.WRDDICTTL LIKE 'ㅋ%')
</when> </when>
<when test='indexKeyword == "ㅌ"'> <when test='indexKeyword == "ㅌ"'>
and w.WRDDICTTL BETWEEN '타' AND '틷' AND (w.WRDDICTTL BETWEEN '타' AND '틷' OR w.WRDDICTTL LIKE 'ㅌ%')
</when> </when>
<when test='indexKeyword == "ㅍ"'> <when test='indexKeyword == "ㅍ"'>
and w.WRDDICTTL BETWEEN '파' AND '핗' AND (w.WRDDICTTL BETWEEN '파' AND '핗' OR w.WRDDICTTL LIKE 'ㅍ%')
</when> </when>
<when test='indexKeyword == "ㅎ"'> <when test='indexKeyword == "ㅎ"'>
and w.WRDDICTTL BETWEEN '하' AND '힣' AND (w.WRDDICTTL BETWEEN '하' AND '힣' OR w.WRDDICTTL LIKE 'ㅎ%')
</when> </when>
<!-- 알파벳 a ~ z에 대한 검색 --> <!-- 알파벳 a ~ z에 대한 검색 -->
<when test='indexKeyword == "a"'> <when test='indexKeyword == "a"'>
@ -132,14 +134,17 @@
<when test='indexKeyword == "z"'> <when test='indexKeyword == "z"'>
and w.WRDDICTTL like "z%" and w.WRDDICTTL like "z%"
</when> </when>
<otherwise>
and w.WRDDICTTL like CONCAT('%', #{indexKeyword}, '%')
</otherwise>
</choose> </choose>
</if> </if>
<!-- 카테고리 조건 --> <!-- 카테고리 조건 -->
<if test="category != null and category != ''"> <if test="category != null and category != '' and category != 'all'">
and w.WRDDICCAT = #{category} and w.WRDDICCAT = #{category}
</if> </if>
</sql> </sql>
<select id="getWordList" parameterType="map" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectWordList" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
select select
w.WRDDICSEQ, w.WRDDICSEQ,
w.WRDDICCAT, w.WRDDICCAT,
@ -181,6 +186,9 @@
and w.WRDDICEDT IS NULL and w.WRDDICEDT IS NULL
<include refid="searchConditions"/> <include refid="searchConditions"/>
order by w.WRDDICRDT desc order by w.WRDDICRDT desc
<if test="pageNum != null and pageNum != ''">
limit #{pageNum}
</if>
</select> </select>
<select id="getTotal" parameterType="map" > <select id="getTotal" parameterType="map" >
select count(*) from worddicty w select count(*) from worddicty w
@ -188,6 +196,9 @@
<include refid="searchConditions"/> <include refid="searchConditions"/>
</select> </select>
<insert id="insertWord" parameterType="map"> <insert id="insertWord" parameterType="map">
<selectKey keyProperty="id" order="AFTER" resultType="long">
SELECT LAST_INSERT_ID()
</selectKey>
insert into worddicty insert into worddicty
( (
WRDDICCAT WRDDICCAT
@ -215,6 +226,47 @@
</if> </if>
) )
</insert> </insert>
<!-- 삭제 파일 정보 조회 -->
<select id="selectDelFileInfo" >
SELECT
CMNFLEPAT
FROM
commonfil
WHERE
CMNFLESEQ in
<foreach collection="array" item="item" separator="," open="(" close=")">
#{item}
</foreach>
AND CMNFLETYP = 3
</select>
<!-- 파일 정보 삭제 -->
<delete id="deleteFileInfo" >
DELETE FROM
commonfil
WHERE
CMNFLESEQ in
<foreach collection="array" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</delete>
<insert id="updateBoardIndexToFile">
/* 용어집 인덱스와 에디터 이미지 매핑 */
UPDATE
COMMONFIL
SET
CMNBRDSEQ = #{id},
CMNFLETYP = 3
WHERE
CMNFLESEQ IN
<foreach collection="editorImgList" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</insert>
<update id="updateWord" parameterType="map"> <update id="updateWord" parameterType="map">
update update
worddicty worddicty
@ -230,7 +282,7 @@
where where
WRDDICSEQ = #{WRDDICSEQ} WRDDICSEQ = #{WRDDICSEQ}
</update> </update>
<select id="getWordDetail" parameterType="map" resultType="io.company.localhost.common.dto.MapDto"> <select id="selectWordDetail" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
select * select *
from from
worddicty worddicty
@ -247,4 +299,111 @@
#{id} #{id}
</foreach> </foreach>
</update> </update>
<select id="selectIndexCategory">
SELECT
CHARACTER_,
COUNT(*) AS COUNT
FROM (
SELECT 'ㄱ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '가' AND '깋' OR WRDDICTTL LIKE 'ㄱ%'
UNION ALL
SELECT 'ㄴ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '나' AND '닣' OR WRDDICTTL LIKE 'ㄴ%'
UNION ALL
SELECT 'ㄷ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '다' AND '딷' OR WRDDICTTL LIKE 'ㄷ%'
UNION ALL
SELECT 'ㄹ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '라' AND '릿' OR WRDDICTTL LIKE 'ㄹ%'
UNION ALL
SELECT 'ㅁ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '마' AND '밓' OR WRDDICTTL LIKE 'ㅁ%'
UNION ALL
SELECT 'ㅂ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '바' AND '빟' OR WRDDICTTL LIKE 'ㅂ%'
UNION ALL
SELECT 'ㅅ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '사' AND '싷' OR WRDDICTTL LIKE 'ㅅ%'
UNION ALL
SELECT 'ㅇ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '아' AND '잏' OR WRDDICTTL LIKE 'ㅇ%'
UNION ALL
SELECT 'ㅈ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '자' AND '짛' OR WRDDICTTL LIKE 'ㅈ%'
UNION ALL
SELECT 'ㅊ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '차' AND '칳' OR WRDDICTTL LIKE 'ㅊ%'
UNION ALL
SELECT 'ㅋ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '카' AND '킿' OR WRDDICTTL LIKE 'ㅋ%'
UNION ALL
SELECT 'ㅌ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '타' AND '틷' OR WRDDICTTL LIKE 'ㅌ%'
UNION ALL
SELECT 'ㅍ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '파' AND '핗' OR WRDDICTTL LIKE 'ㅍ%'
UNION ALL
SELECT 'ㅎ' AS CHARACTER_, WRDDICTTL FROM worddicty
WHERE WRDDICTTL BETWEEN '하' AND '힣' OR WRDDICTTL LIKE 'ㅎ%'
UNION ALL
SELECT 'a' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'a%'
UNION ALL
SELECT 'b' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'b%'
UNION ALL
SELECT 'c' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'c%'
UNION ALL
SELECT 'd' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'd%'
UNION ALL
SELECT 'e' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'e%'
UNION ALL
SELECT 'f' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'f%'
UNION ALL
SELECT 'g' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'g%'
UNION ALL
SELECT 'h' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'h%'
UNION ALL
SELECT 'i' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'i%'
UNION ALL
SELECT 'j' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'j%'
UNION ALL
SELECT 'k' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'k%'
UNION ALL
SELECT 'l' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'l%'
UNION ALL
SELECT 'm' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'm%'
UNION ALL
SELECT 'n' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'n%'
UNION ALL
SELECT 'o' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'o%'
UNION ALL
SELECT 'p' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'p%'
UNION ALL
SELECT 'q' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'q%'
UNION ALL
SELECT 'r' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'r%'
UNION ALL
SELECT 's' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 's%'
UNION ALL
SELECT 't' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 't%'
UNION ALL
SELECT 'u' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'u%'
UNION ALL
SELECT 'v' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'v%'
UNION ALL
SELECT 'w' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'w%'
UNION ALL
SELECT 'x' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'x%'
UNION ALL
SELECT 'y' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'y%'
UNION ALL
SELECT 'z' AS CHARACTER_, WRDDICTTL FROM worddicty WHERE WRDDICTTL LIKE 'z%'
) AS combined
GROUP BY CHARACTER_
ORDER BY
CASE
WHEN CHARACTER_ BETWEEN 'ㄱ' AND 'ㅎ' THEN 1
ELSE 2
END,
CHARACTER_
</select>
</mapper> </mapper>