This commit is contained in:
nevermoregb 2025-02-07 16:08:42 +09:00
commit f8da4b8b0b
38 changed files with 2192 additions and 514 deletions

View File

@ -131,3 +131,4 @@ tasks.javadoc {
tasks.named('test') {
useJUnitPlatform()
}

View File

@ -15,10 +15,14 @@
package io.company.localhost.common.config;
import io.company.localhost.common.resolver.RequestToMapArgumentResolver;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.support.StandardServletMultipartResolver;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@ -35,6 +39,12 @@ public class WebMvcConfig implements WebMvcConfigurer {
public static final String WILD_CARD = "/**";
@Value("${filePath.boardfile}")
private String boardFilePath;
@Value("${filePath.profile}")
private String uploadPath;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 여기서 인터셉터를 추가할 있음
@ -47,6 +57,13 @@ public class WebMvcConfig implements WebMvcConfigurer {
registry
.addResourceHandler("/index.html")
.addResourceLocations("classpath:/static/index.html", "/index.html");
//게시판 에디터 이미지 업로드 경로
registry.addResourceHandler("/upload/img/board/**")
.addResourceLocations("file:" + boardFilePath);
//프로필 이미지 업로드 경로
registry.addResourceHandler("/upload/img/profile/**")
.addResourceLocations("file:" + uploadPath);
}
// Controller의 파라미터를 처리할 Resolver 등록
@ -82,4 +99,11 @@ public class WebMvcConfig implements WebMvcConfigurer {
return localeResolver;
}
@Bean
public MultipartResolver multipartResolver() {
return new StandardServletMultipartResolver();
}
}

View File

@ -23,13 +23,18 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum CommonErrorCode implements ErrorCode {
INVALID_PARAMETER(HttpStatus.BAD_REQUEST.value(),HttpStatus.BAD_REQUEST,"잘못된 매개변수가 포함되었습니다."),
RESOURCE_NOT_FOUND(HttpStatus.NOT_FOUND.value(),HttpStatus.NOT_FOUND,"리소스가 존재하지 않습니다"),
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(),HttpStatus.INTERNAL_SERVER_ERROR,"내부 서버 오류"),
INVALID_PARAMETER(HttpStatus.BAD_REQUEST,"잘못된 매개변수가 포함되었습니다."),
RESOURCE_NOT_FOUND(HttpStatus.NOT_FOUND,"리소스가 존재하지 않습니다"),
INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR,"내부 서버 오류"),
;
private final long code;
private final HttpStatus httpStatus;
private final String message;
CommonErrorCode(HttpStatus httpStatus, String message) {
this.code = httpStatus.value();
this.httpStatus = httpStatus;
this.message = message;
}
}

View File

@ -24,13 +24,23 @@ import lombok.RequiredArgsConstructor;
@RequiredArgsConstructor
public enum UserErrorCode implements ErrorCode {
NOT_AUTH_USER(HttpStatus.UNAUTHORIZED.value(),HttpStatus.UNAUTHORIZED ,"로그인이 필요합니다."),
INACTIVE_USER(HttpStatus.FORBIDDEN.value(),HttpStatus.FORBIDDEN,"권한이 필요합니다.");
NOT_AUTH_USER(HttpStatus.UNAUTHORIZED ,"로그인이 필요합니다."),
INACTIVE_USER(HttpStatus.FORBIDDEN,"권한이 필요합니다."),
USER_NOT_FOUND(HttpStatus.UNAUTHORIZED,"아이디 혹은 비밀번호가 틀렸습니다."),
NOT_AUTHORIZED(HttpStatus.UNAUTHORIZED,"비인가 계정입니다."),
EXIT_USER(HttpStatus.UNAUTHORIZED,"탈퇴한 계정입니다."),
BAD_CREDENTIAL(HttpStatus.UNAUTHORIZED, "아이디 혹은 비밀번호 문제")
;
private final long code;
private final HttpStatus httpStatus;
private final String message;
UserErrorCode(HttpStatus httpStatus, String message) {
this.code = httpStatus.value();
this.httpStatus = httpStatus;
this.message = message;
}
public ApiResponse<?> getApiResponse() {
return ApiResponse.error(this.getHttpStatus() , this.getMessage());

View File

@ -21,10 +21,12 @@ import io.company.localhost.common.security.handler.MemberAuthSuccessHandler;
import io.company.localhost.common.security.handler.RestAccessDeniedHandler;
import io.company.localhost.common.security.handler.RestAuthenticationEntryPointHandler;
import io.company.localhost.common.security.service.CustomRememberMeServices;
import io.company.localhost.common.security.service.TokenService;
import io.company.localhost.common.security.service.MemberPrincipalDetailService;
import io.company.localhost.common.security.session.AuthenticationSessionControlStrategy;
import io.company.localhost.common.security.session.CustomSessionRegistryImpl;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
@ -50,6 +52,7 @@ public class SecurityConfig {
// 의존성 주입
private final AuthenticationProvider memberAuthenticatorProvider;
private final MemberPrincipalDetailService userDetailsService;
private final MemberAuthSuccessHandler successHandler;
private final MemberAuthFailureHandler failureHandler;
private final AuthorizationManager<RequestAuthorizationContext> authorizationManager;
@ -63,6 +66,9 @@ public class SecurityConfig {
final String SECURITY_BASE_URL = "/api/user";
final String LOGIN_URL = SECURITY_BASE_URL + "/login";
final String LOGIN_KEY = "loginSecretKey";
// 보안 필터 체인 설정
@Bean
public SecurityFilterChain restSecurityFilterChain(HttpSecurity http, WebCorsFilter webCorsFilter) throws Exception {
@ -71,12 +77,11 @@ public class SecurityConfig {
.authenticationProvider(memberAuthenticatorProvider)
.build();
MemberAuthSuccessHandler successHandler = new MemberAuthSuccessHandler(rememberMeServices());
http
.securityMatcher("/api/**") // '/api/**' 경로에 대해서만 보안 적용
.authorizeHttpRequests(auth ->
auth.requestMatchers("/api/board/general").permitAll() // 특정 엔드포인트 허용
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/board/**").hasRole("MEMBER")
.requestMatchers("/api/**").permitAll() // 특정 엔드포인트 허용
.anyRequest().authenticated() // 나머지 요청은 인증 필요
//auth.anyRequest().access(authorizationManager) // 모든 요청에 대해 권한 관리
)
@ -116,9 +121,15 @@ public class SecurityConfig {
@Bean
public RememberMeServices rememberMeServices(){
return new CustomRememberMeServices(REMEMBER_KEY , userDetailsService);
return new CustomRememberMeServices(tokenService(), userDetailsService);
}
@Bean
public TokenService tokenService() {
return new TokenService(REMEMBER_KEY, LOGIN_KEY);
}
// 세션 관리
protected ConcurrentSessionControlAuthenticationStrategy sessionControlStrategy() {
AuthenticationSessionControlStrategy sessionControlStrategy = new AuthenticationSessionControlStrategy(sessionRegistry());

View File

@ -15,6 +15,8 @@
package io.company.localhost.common.security.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.exception.code.UserErrorCode;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.http.MediaType;
@ -35,10 +37,17 @@ public class MemberAuthFailureHandler implements AuthenticationFailureHandler {
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
if (exception instanceof BadCredentialsException) {
mapper.writeValue(response.getWriter(),"아이디 혹은 비밀번호 문제");
ApiResponse<?> res = UserErrorCode.BAD_CREDENTIAL.getApiResponse();
String message = exception.getMessage();
if (exception instanceof BadCredentialsException || message.startsWith("NOT_FOUND")) {
res = UserErrorCode.USER_NOT_FOUND.getApiResponse();
} else if (message.startsWith("NOT_AUTHORIZED")) {
res = UserErrorCode.NOT_AUTHORIZED.getApiResponse();
} else if (message.startsWith("EXIT")) {
res = UserErrorCode.EXIT_USER.getApiResponse();
}
mapper.writeValue(response.getWriter(), "인증 실패");
response.getWriter().write(mapper.writeValueAsString(res));
}
}

View File

@ -15,45 +15,66 @@
package io.company.localhost.common.security.handler;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.company.localhost.common.dto.ApiResponse;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.common.security.service.TokenService;
import io.company.localhost.service.NetmemberService;
import io.company.localhost.vo.MemberVo;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.WebAttributes;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@Component("successHandler")
public class MemberAuthSuccessHandler implements AuthenticationSuccessHandler{
public class MemberAuthSuccessHandler implements AuthenticationSuccessHandler {
private final RememberMeServices rememberMeServices;
private final TokenService tokenService;
private final NetmemberService netmemberService;
public MemberAuthSuccessHandler(RememberMeServices rememberMeServices) {
this.rememberMeServices = rememberMeServices;
public MemberAuthSuccessHandler(@Lazy TokenService tokenService, NetmemberService netmemberService) {
this.tokenService = tokenService;
this.netmemberService = netmemberService;
}
@Override
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, Authentication authentication) throws IOException {
public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response,
Authentication authentication) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Boolean rememberMe = (Boolean) request.getAttribute("remember");
if (rememberMe != null && rememberMe) {
rememberMeServices.loginSuccess(request, response, authentication);
// 로그인 성공한 사용자 가져오기
Object principal = authentication.getPrincipal();
if (!(principal instanceof MemberVo member)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return;
}
MemberVo member = (MemberVo) authentication.getPrincipal();
// 로그인 토큰 생성
String username = member.getLoginId();
String loginToken = tokenService.generateToken(username, "login");
// DB에 저장
MapDto map = new MapDto();
map.put("id", username);
map.put("token", loginToken);
netmemberService.updateMemberToken(map);
response.setStatus(HttpStatus.OK.value());
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
mapper.writeValue(response.getWriter(), member);
response.getWriter().write(mapper.writeValueAsString(ApiResponse.ok("Success")));
clearAuthenticationAttributes(request);
}

View File

@ -10,11 +10,12 @@
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 조인제 최초 생성
*
* 24.02.03 박지윤 토큰 로직 변경
*************************************************************/
package io.company.localhost.common.security.service;
import io.company.localhost.common.security.details.MemberPrincipalDetails;
import io.company.localhost.service.NetmemberService;
import io.company.localhost.vo.MemberVo;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
@ -27,8 +28,6 @@ import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.RememberMeServices;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
@ -39,11 +38,12 @@ public class CustomRememberMeServices implements RememberMeServices {
private static final long TOKEN_VALIDITY_SECONDS = 60 * 60 * 24 * 365; // 1 year
private static final String DELIMITER = ":";
private final String secretKey;
private final TokenService tokenService;
private final UserDetailsService userDetailsService;
public CustomRememberMeServices(String secretKey, UserDetailsService userDetailsService) {
this.secretKey = secretKey;
public CustomRememberMeServices(TokenService tokenService, UserDetailsService userDetailsService) {
this.tokenService = tokenService;
this.userDetailsService = userDetailsService;
}
@ -55,33 +55,22 @@ public class CustomRememberMeServices implements RememberMeServices {
return null;
}
String[] tokenParts = decodeAndSplitCookie(rememberMeCookie.getValue());
if (tokenParts == null || tokenParts.length != 3) {
String token = rememberMeCookie.getValue();
if (!tokenService.validateToken(token, "rememberme")) {
return null;
}
String[] tokenParts = decodeAndSplitCookie(token);
String username = tokenParts[0];
long expiryTime;
try {
expiryTime = Long.parseLong(tokenParts[1]);
} catch (NumberFormatException e) {
return null;
}
String signature = tokenParts[2];
if (!isTokenValid(username, expiryTime, signature)) {
return null;
}
if (System.currentTimeMillis() > expiryTime) {
return null;
}
UserDetails userDetails = userDetailsService.loadUserByUsername(username);
if (userDetails != null) {
MemberPrincipalDetails memberDetails = (MemberPrincipalDetails) userDetails;
MemberVo memberVo = memberDetails.member();
RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(secretKey, memberVo, userDetails.getAuthorities());
String rememberMeSecretKey = tokenService.getRememberMeSecretKey();
RememberMeAuthenticationToken auth = new RememberMeAuthenticationToken(rememberMeSecretKey, memberVo, userDetails.getAuthorities());
auth.setAuthenticated(true);
SecurityContextHolder.getContext().setAuthentication(auth);
return auth;
@ -92,16 +81,19 @@ public class CustomRememberMeServices implements RememberMeServices {
@Override
public void loginSuccess(HttpServletRequest request, HttpServletResponse response, Authentication successfulAuthentication) {
Boolean rememberMe = (Boolean) request.getAttribute("remember");
if(!rememberMe){
return;
}
Object principal = successfulAuthentication.getPrincipal();
if (!(principal instanceof MemberVo member)) {
return;
}
String username = member.getLoginId();
long expiryTime = System.currentTimeMillis() + (TOKEN_VALIDITY_SECONDS * 1000);
String signature = generateSignature(username, expiryTime);
String tokenValue = encodeToken(username, expiryTime, signature);
String tokenValue = tokenService.generateToken(username, "rememberme");
SecurityContextHolder.getContext().setAuthentication(successfulAuthentication);
@ -143,24 +135,4 @@ public class CustomRememberMeServices implements RememberMeServices {
}
}
private String encodeToken(String username, long expiryTime, String signature) {
String tokenValue = username + DELIMITER + expiryTime + DELIMITER + signature;
return Base64.getEncoder().encodeToString(tokenValue.getBytes(StandardCharsets.UTF_8));
}
private boolean isTokenValid(String username, long expiryTime, String signature) {
String expectedSignature = generateSignature(username, expiryTime);
return expectedSignature.equals(signature);
}
private String generateSignature(String username, long expiryTime) {
try {
String data = username + DELIMITER + expiryTime;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secretKey.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
throw new IllegalStateException("Failed to generate signature", e);
}
}
}

View File

@ -21,28 +21,28 @@ import org.springframework.stereotype.Service;
import io.company.localhost.common.security.details.MemberPrincipalDetails;
import io.company.localhost.vo.MemberVo;
import io.company.localhost.mapper.MemberMapper;
import io.company.localhost.mapper.NetmemberMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class MemberPrincipalDetailService implements UserDetailsService {
private final MemberMapper memberMapper;
private final NetmemberMapper memberMapper;
@Override
public UserDetails loadUserByUsername(String id) throws UsernameNotFoundException {
MemberVo member = memberMapper.findByLoginId(id);
// 없을경우 에러 발생
//FailHandler 에서 처리
if(member == null)
throw new UsernameNotFoundException(id + "을 찾을 수 없습니다.");
throw new UsernameNotFoundException("NOT_FOUND");
if(!"Y".equals(member.getIsUsed()))
throw new UsernameNotFoundException("사용할 수 없는 계정입니다.");
throw new UsernameNotFoundException("NOT_AUTHORIZED");
if(!"N".equals(member.getIsDel()))
throw new UsernameNotFoundException("삭제된 계정입니다.");
throw new UsernameNotFoundException("EXIT");
// MemberPrincipalDetails Member 객체를 넘겨줌
return new MemberPrincipalDetails(member);

View File

@ -0,0 +1,121 @@
/************************************************************
*
* @packageName : io.company.localhost.common.security.service
* @fileName : TokenService.java
* @author : 박지윤
* @date : 24.01.24
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.01.24 박지윤 최초 생성
*************************************************************/
package io.company.localhost.common.security.service;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.springframework.stereotype.Service;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class TokenService {
private static final long REMBER_TOKEN_VALIDITY_SECONDS = 60 * 60 * 24 * 365; // 1년
private static final long LOGIN_TOKEN_VALIDITY_SECONDS = 60 * 60 * 24 * 365; // 하루
private static final String DELIMITER = ":";
private final String rememberMeSecretKey;
private final String loginSecretKey;
public TokenService(String rememberMeSecretKey, String loginSecretKey) {
this.rememberMeSecretKey = rememberMeSecretKey;
this.loginSecretKey = loginSecretKey;
}
public String generateToken(String username, String tokenType) {
long expiryTime;
// 토큰타입에 따라 만료기간 다르게 설정
if ("rememberme".equals(tokenType)) {
expiryTime = System.currentTimeMillis() + (REMBER_TOKEN_VALIDITY_SECONDS * 1000);
} else if ("login".equals(tokenType)) {
expiryTime = System.currentTimeMillis() + (LOGIN_TOKEN_VALIDITY_SECONDS * 1000);
} else {
throw new IllegalArgumentException("Invalid token type");
}
String signature = generateSignature(username, expiryTime, tokenType);
return encodeToken(username, expiryTime, signature);
}
public boolean validateToken(String token, String tokenType) {
try {
String[] tokenParts = decodeAndSplitToken(token);
if (tokenParts == null || tokenParts.length != 3) {
return false;
}
String username = tokenParts[0];
long expiryTime;
try {
expiryTime = Long.parseLong(tokenParts[1]);
} catch (NumberFormatException e) {
return false;
}
String signature = tokenParts[2];
if (!isTokenValid(username, expiryTime, signature, tokenType)) {
return false;
}
return System.currentTimeMillis() <= expiryTime;
} catch (Exception e) {
return false;
}
}
private String generateSignature(String username, long expiryTime, String tokenType) {
try {
// tokenType에 따라 login 또는 remember secretKey 사용
String secretKeyToUse = "rememberme".equals(tokenType) ? rememberMeSecretKey : loginSecretKey;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(secretKeyToUse.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
String data = username + DELIMITER + expiryTime;
return Base64.getEncoder().encodeToString(mac.doFinal(data.getBytes(StandardCharsets.UTF_8)));
} catch (Exception e) {
throw new IllegalStateException("Failed to generate signature", e);
}
}
private String encodeToken(String username, long expiryTime, String signature) {
String tokenValue = username + DELIMITER + expiryTime + DELIMITER + signature;
return Base64.getEncoder().encodeToString(tokenValue.getBytes(StandardCharsets.UTF_8));
}
private String[] decodeAndSplitToken(String token) {
try {
String decodedValue = new String(Base64.getDecoder().decode(token), StandardCharsets.UTF_8);
return decodedValue.split(DELIMITER);
} catch (Exception e) {
return null;
}
}
private boolean isTokenValid(String username, long expiryTime, String signature, String tokenType) {
String expectedSignature = generateSignature(username, expiryTime, tokenType);
return expectedSignature.equals(signature);
}
public String getRememberMeSecretKey() {
return rememberMeSecretKey;
}
}

View File

@ -1,25 +1,35 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.api
* @fileName : BoardController.java
* @author : 서지희
* @date : 25.01.07
* @description : 게시판
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.01.02 서지희 최초 생성
*
*************************************************************/
package io.company.localhost.controller.api;
import java.nio.charset.StandardCharsets;
import java.sql.Blob;
import java.math.BigInteger;
import java.util.List;
import java.util.Map;
import org.springframework.http.ResponseEntity;
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.RequestBody;
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.*;
import com.github.pagehelper.PageInfo;
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.LocalBordService;
import io.company.localhost.service.commoncodService;
import io.company.localhost.service.localbordService;
import io.company.localhost.utils.AuthUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -28,108 +38,209 @@ import lombok.extern.slf4j.Slf4j;
@RequiredArgsConstructor
@Slf4j
public class BoardController {
private final LocalBordService boardService;
//공지사항
private final localbordService boardService;
private final commoncodService commoncodService;
/**
* 공지사항 목록 조회
* @ReqMap map 요청 파라미터 (searchKeyword)
* @return 전체 공지사항 목록
*/
@Member
@ParameterCheck
@GetMapping("/notices")
public ApiResponse<List<Map<String, Object>>> getNotices() {
return ApiResponse.ok(boardService.getNotices());
public ApiResponse<List<MapDto>> getNotices(@ReqMap MapDto map) {
return ApiResponse.ok(boardService.getNotices(map));
}
//비밀,자유게시판
/**
* 자유/익명 게시판 목록 조회
* @ReqMap map 요청 파라미터 (page, searchKeyword, orderBy, size)
* @return 페이징된 자유/익명 게시판 목록
*/
@Member
@ParameterCheck
@GetMapping("/general")
public ApiResponse<List<Map<String, Object>>> getGeneralPosts() {
List<Map<String, Object>> posts = boardService.getGeneralPosts();
for (Map<String, Object> post : posts) {
Object content = post.get("content");
if (content instanceof Blob) {
Blob blob = (Blob) content;
try {
post.put("content", new String(blob.getBytes(1, (int) blob.length()), StandardCharsets.UTF_8));
} catch (Exception e) {
post.put("content", ""); // 변환 실패 기본 설정
public ApiResponse<PageInfo<MapDto>> getGeneralPosts(@ReqMap MapDto map) {
return ApiResponse.ok(boardService.getGeneralPosts(map));
}
}
}
System.out.println(posts);
return ApiResponse.ok(posts);
}
//게시물 작성
/**
* 게시물 작성
* @ReqMap map 요청 파라미터 (LOCBRDTTL, LOCBRDCON, MEMBERSEQ, LOCBRDTYP,
* LOCBRDPWD(익명일 때만), LOCBRDCAT(지식커뮤니티만))
* @return 작성된 게시물의 ID
*/
@Member
@ParameterCheck
@PostMapping
public ApiResponse<String> createBoard(@ReqMap MapDto map) {
boardService.createBoard(map);
return ApiResponse.ok("게시물이 작성되었습니다.");
public ApiResponse<BigInteger> createBoard(@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId();
map.put("MEMBERSEQ", userId);
return ApiResponse.ok(boardService.createBoard(map));
}
// 첨부파일 추가
@PostMapping("/{boardId}/attachments")
public ApiResponse<String> uploadAttachment(@PathVariable Long boardId, @ReqMap MapDto map) {
map.put("LOCBRDSEQ", boardId);
log.info("Uploading attachment for board ID: {}", boardId);
boardService.addAttachment(map);
return ApiResponse.ok("첨부파일이 저장되었습니다.");
/**
* 게시물 상세보기
* @param boardId 게시물 ID
* @return 게시물 상세정보
*/
@Member
@ParameterCheck
@GetMapping("/{boardId}")
public ApiResponse<MapDto> getBoardDetail(@PathVariable("boardId") Long boardId) {
return ApiResponse.ok(boardService.getBoardDetail(boardId));
}
// 게시물 삭제
/**
* 게시물 삭제
* @param boardId 게시물 ID
* @return 삭제 결과 메시지
*/
@Member
@ParameterCheck
@DeleteMapping("/{boardId}")
public ApiResponse<String> deleteBoard(@PathVariable Long boardId, @ReqMap MapDto map) {
public ApiResponse<String> deleteBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
map.put("LOCBRDSEQ", boardId);
log.info("Deleting board with ID: {}", boardId);
boardService.deleteBoard(map);
return ApiResponse.ok("게시물이 삭제되었습니다.");
}
//게시물 수정
@PutMapping
public ApiResponse<String> updateBoard(@ReqMap MapDto map) {
/**
* 게시물 수정
* @param boardId 게시물 ID
* @ReqMap map 수정 데이터 (LOCBRDTTL, LOCBRDCON)
* @return 수정 결과 메시지
*/
@Member
@ParameterCheck
@PutMapping("/{boardId}")
public ApiResponse<String> updateBoard(@PathVariable("boardId") Long boardId, @ReqMap MapDto map) {
map.put("LOCBRDSEQ", boardId);
boardService.updateBoard(map);
return ApiResponse.ok("게시물이 수정되었습니다.");
}
//게시물과 댓글에 좋아요/싫어요 추가
@PostMapping("/{boardId}/reaction")
public ApiResponse<String> reactToBoard(@PathVariable Long boardId, @ReqMap MapDto map) {
map.put("LOCBRDSEQ", boardId);
boardService.reactToBoard(map);
return ApiResponse.ok("반응이 추가되었습니다.");
/**
* 첨부파일 추가
* @ReqMap map 요청 파라미터 (CMNFLEREG, CMNFLESIZ, CMNFLEEXT, CMNFLEORG, CMNFLENAM, CMNFLEPAT, CMNBRDSEQ)
* @return 첨부파일 저장 결과 메시지
*/
@Member
@ParameterCheck
@PostMapping("/{CMNBRDSEQ}/attachments")
public ApiResponse<String> uploadAttachment(@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId();
map.put("CMNFLEREG", userId);
boardService.addAttachment(map);
return ApiResponse.ok("첨부파일이 저장되었습니다.");
}
//댓글/대댓글 조회
/**
* 게시물, 댓글 좋아요/싫어요 추가
* @ReqMap map 데이터 (LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD, LOCBRDSEQ)
* @return 반응 추가 결과 메시지
*/
@Member
@ParameterCheck
@PostMapping("/{LOCBRDSEQ}/{LOCCMTSEQ}/reaction")
public ApiResponse<String> reactToBoard(@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId();
map.put("MEMBERSEQ", userId);
boardService.reactToBoard(map);
return ApiResponse.ok("반응이 성공적으로 처리되었습니다.");
}
/**
* 댓글/대댓글 조회
* @param boardId 게시물 ID
* @return 댓글과 대댓글의 계층 구조 데이터
*/
@Member
@ParameterCheck
@GetMapping("/{boardId}/comments")
public ApiResponse<List<Map<String, Object>>> getComments(@PathVariable int boardId) {
public ApiResponse<List<MapDto>> getComments(@PathVariable("boardId") int boardId) {
return ApiResponse.ok(boardService.getComments(boardId));
}
//댓글/대댓글 작성
@PostMapping("/{boardId}/comment")
public ApiResponse<String> addCommentOrReply(@PathVariable int boardId, @ReqMap MapDto map) {
map.put("LOCBRDSEQ", boardId);
/**
* 댓글/대댓글 작성
* @param boardId 게시물 ID
* @ReqMap map 댓글 데이터 (LOCBRDSEQ, LOCCMTRPY, LOCCMTPNT, LOCCMTPWD, MEMBERSEQ )
* @return 작성 결과 메시지
*/
@Member
@ParameterCheck
@PostMapping("/{LOCBRDSEQ}/comment")
public ApiResponse<String> addCommentOrReply(@ReqMap MapDto map) {
Long userId = AuthUtil.getUser().getId();
map.put("MEMBERSEQ", userId);
boardService.addCommentOrReply(map);
return ApiResponse.ok("댓글 또는 대댓글이 작성되었습니다.");
}
//댓글/대댓글 수정
/**
* 댓글/대댓글 수정
* @param commentId 댓글 ID
* @ReqMap map 수정 데이터 (LOCCMTSEQ, LOCCMTRPY)
* @return 수정 결과 메시지
*/
@Member
@ParameterCheck
@PutMapping("/comment/{commentId}")
public ApiResponse<String> updateComment(@PathVariable int commentId, @ReqMap MapDto map) {
map.put("LOCCMTSEQ", commentId);
public ApiResponse<String> updateComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
boardService.updateComment(map);
return ApiResponse.ok("댓글이 수정되었습니다.");
}
//댓글/대댓글 삭제
/**
* 댓글/대댓글 삭제
* @param commentId 댓글 ID
* @ReqMap map 삭제 데이터
* @return 삭제 결과 메시지
*/
@Member
@ParameterCheck
@DeleteMapping("/comment/{commentId}")
public ApiResponse<String> deleteComment(@PathVariable int commentId, @ReqMap MapDto map) {
map.put("LOCCMTSEQ", commentId);
public ApiResponse<String> deleteComment(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
boardService.deleteComment(map);
return ApiResponse.ok("댓글이 삭제되었습니다.");
}
//비밀번호 확인 (게시물)
/**
* 댓글 비밀번호 확인
* @param commentId 댓글 ID
* @ReqMap map 비밀번호 데이터
* @return 비밀번호 확인 결과
*/
@Member
@ParameterCheck
@PostMapping("/comment/{commentId}/password")
public ApiResponse<Boolean> checkCommentPassword(@PathVariable int commentId, @ReqMap MapDto map) {
map.put("LOCCMTSEQ", commentId);
return ApiResponse.ok(boardService.checkCommentPassword(map));
public ApiResponse<Boolean> checkCommentPassword(@PathVariable("commentId") int commentId, @ReqMap MapDto map) {
return ApiResponse.ok(boardService.getCommentPassword(commentId).equals(map.getString("LOCCMTPWD")));
}
//비밀번호 확인 (댓글)
/**
* 게시물 비밀번호 확인
* @param boardId 게시물 ID
* @ReqMap map 비밀번호 데이터
* @return 비밀번호 확인 결과
*/
@Member
@ParameterCheck
@PostMapping("/{boardId}/password")
public ApiResponse<Boolean> checkBoardPassword(@PathVariable int boardId, @ReqMap MapDto map) {
map.put("LOCBRDSEQ", boardId);
return ApiResponse.ok(boardService.checkBoardPassword(map));
public ApiResponse<Boolean> checkBoardPassword(@PathVariable("boardId") int boardId, @ReqMap MapDto map) {
return ApiResponse.ok(boardService.getBoardPassword(boardId).equals(map.getString("LOCBRDPWD")));
}
// 비밀게시판 여부 확인
@GetMapping("/{boardId}/isSecret")
public ApiResponse<Boolean> isSecretBoard(@PathVariable Long boardId) {
log.info("Checking if board ID {} is secret", boardId);
return ApiResponse.ok(boardService.isSecretBoard(boardId));
/**
* 카테고리 목록 조회
* @return 카테고리 리스트
*/
@GetMapping("/categories")
public ApiResponse<List<MapDto>> getCategories() {
List<MapDto> categories = commoncodService.getCategoryList();
return ApiResponse.ok(categories);
}
}

View File

@ -0,0 +1,57 @@
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.RequestBody;
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.localvacaService; // 서비스 클래스 경로 수정
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/vacation")
public class VacationController {
private final localvacaService localVacaService;
@PostMapping
public ApiResponse<String> saveVacations(@RequestBody List<MapDto> map) {
for (MapDto request : map) {
// 요청 데이터의 필수 검증
Integer employeeId = (Integer) request.get("employeeId");
String date = request.getString("date");
String type = request.getString("type");
if (employeeId == null || date == null || type == null) {
throw new IllegalArgumentException("요청 데이터에 누락된 값이 있습니다: " + request);
}
// 데이터 저장
localVacaService.insertVacation(request);
}
// 성공적으로 저장된 경우 응답 반환
return ApiResponse.ok("모든 휴가가 성공적으로 저장되었습니다.");
}
/**
* 휴가 정보를 조회하여 프론트엔드로 전달
*/
@GetMapping("/list")
public ApiResponse<List<MapDto>> getVacationList(@ReqMap MapDto map) {
// 서비스 호출을 통해 데이터 조회
List<MapDto> vacationList = localVacaService.getVacationList(map);
return ApiResponse.ok(vacationList);
}
}

View File

@ -1,6 +1,6 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.common
* @packageName : io.company.localhost.controller.api
* @fileName : worddictController.java
* @author : 공현지
* @date : 25.01.07
@ -12,7 +12,7 @@
* 24.12.06 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.controller.common;
package io.company.localhost.controller.api;
import java.util.List;
@ -23,8 +23,6 @@ import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.github.pagehelper.PageInfo;
import io.company.localhost.common.annotation.Member;
import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap;
@ -54,10 +52,18 @@ public class worddictController {
@Member
@ParameterCheck
@GetMapping("getWordList")
public ApiResponse<PageInfo<MapDto>> getWordList(@ReqMap MapDto map) {
PageInfo<MapDto> WordList = worddictyservice.getWordList(map);
return ApiResponse.ok(WordList);
public ApiResponse<MapDto> getWordList(@ReqMap MapDto map) {
int total = worddictyservice.getTotal(map);
List<MapDto> wordList = worddictyservice.getWordList(map);
MapDto OutData = new MapDto();
OutData.put("total", total);
OutData.put("data", wordList);
return ApiResponse.ok(OutData);
}
/**
* 용어집 카테고리 목록
* @param
@ -71,6 +77,17 @@ public class worddictController {
return ApiResponse.ok(WordCategoryList);
}
/**
* 용어집 상세 조회
* @param WRDDICSEQ 용어 번호
* @return
*/
@Member
@ParameterCheck
@GetMapping("getWordDetail")
public ApiResponse<MapDto> getWordDetail(@ReqMap MapDto map) {
return ApiResponse.ok( worddictyservice.getWordDetail(map));
}
/**
* 용어집 카테고리 등록
* @param CMNCODNAM 용어집 등록 카테고리 이름
* @return
@ -84,11 +101,10 @@ public class worddictController {
}
/**
* 용어 등록
* @param WRDDICCAT 카테고리,WRDDICTTL 용어,WRDDICCON 내용 ,WRDDICRIK 링크
* @param WRDDICCAT 카테고리 코드값 ,WRDDICTTL 용어,WRDDICCON 내용 ,WRDDICRIK 링크
* @return
*/
@Member
@ParameterCheck
@PostMapping("insertWord")
public ApiResponse<Long> insertWord(@AuthenticationPrincipal MemberVo memberVo,@ReqMap MapDto map) {
@ -116,6 +132,4 @@ public class worddictController {
return ApiResponse.ok(result);
}
}

View File

@ -0,0 +1,71 @@
/************************************************************
*
* @packageName : io.company.localhost.controller.common
* @fileName : ImageUploadController.java
* @author : 공현지
* @date : 25.01.16
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 25.01.16 공현지 최초 생성
*
*************************************************************/
package io.company.localhost.controller.common;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.PostMapping;
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.multipart.MultipartFile;
import io.company.localhost.common.annotation.ParameterCheck;
import io.company.localhost.common.annotation.ReqMap;
import io.company.localhost.common.dto.ApiResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
@RequestMapping("/api/quilleditor")
@RequiredArgsConstructor
public class ImageUploadController {
@Value("${filePath.boardfile}")
private String boardFilePath;
/**
* quilleditor 안에서 삽입된 이미지를 서버에 저장하는 메소드
* @form-data 서버에 저장된 이미지 경로와 이름
* @return
*/
@ParameterCheck
@PostMapping("/upload")
public ApiResponse<String> uploadImage(@ReqMap MultipartFile file) throws IOException {
if (file.isEmpty()) {
return ApiResponse.error(HttpStatus.BAD_REQUEST, "File is empty");
}
String originalFileName = file.getOriginalFilename();
String fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
String fileName = UUID.randomUUID().toString() + fileExtension;
Path filePath = Paths.get(boardFilePath, fileName);
Files.createDirectories(filePath.getParent());
Files.write(filePath, file.getBytes());
String fileUrl = "upload/img/board/" + fileName;
return ApiResponse.ok(fileUrl);
}
}

View File

@ -10,6 +10,7 @@
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.12.06 조인제 최초 생성
* 24.01.17 박지윤 Register 합침
*
*************************************************************/
package io.company.localhost.controller.common;
@ -17,7 +18,12 @@ package io.company.localhost.controller.common;
import io.company.localhost.common.annotation.Admin;
import io.company.localhost.common.annotation.Guest;
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 io.company.localhost.service.commoncodService;
import io.company.localhost.utils.AuthUtil;
import io.company.localhost.utils.SessionListener;
import io.company.localhost.vo.MemberVo;
@ -35,10 +41,15 @@ import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextHolderStrategy;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PostMapping;
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.multipart.MultipartFile;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.springframework.security.web.authentication.rememberme.AbstractRememberMeServices.SPRING_SECURITY_REMEMBER_ME_COOKIE_KEY;
@ -49,8 +60,113 @@ import static org.springframework.security.web.authentication.rememberme.Abstrac
@RequiredArgsConstructor
public class UserController {
private final commoncodService commoncodservice;
private final NetmemberService netmemberservice;
//security 인증 체크
/**
* 사용 가능 색상 조회
*
* @return ApiResponse<List<MapDto>>
*
*/
@ParameterCheck
@GetMapping("/color")
public ApiResponse<List<MapDto>> getColorList() {
List<MapDto> ColorList = commoncodservice.getColorList();
return ApiResponse.ok(ColorList);
}
/**
* MBTI 목록 조회
*
* @return ApiResponse<List<MapDto>>
*
*/
@ParameterCheck
@GetMapping("/mbti")
public ApiResponse<List<MapDto>> getMbtiList() {
List<MapDto> MbtiList = commoncodservice.getMbtiList();
return ApiResponse.ok(MbtiList);
}
/**
* 비밀번호 힌트 목록 조회
*
* @return ApiResponse<List<MapDto>>
*
*/
@ParameterCheck
@GetMapping("/pwhint")
public ApiResponse<List<MapDto>> getPwhintList() {
List<MapDto> PwhintList = commoncodservice.getPwhintList();
return ApiResponse.ok(PwhintList);
}
/**
* 회원가입
*
* @param profile
* @param map
* @return ApiResponse<Integer>
* @throws RuntimeException 파일 업로드 실패
*/
@PostMapping("/join")
public ApiResponse<Integer> register(@RequestParam("memberPrf") MultipartFile memberPrf, @ReqMap MapDto map) {
int member = netmemberservice.register(memberPrf, map);
return ApiResponse.ok(member);
}
/**
* 아이디 중복 체크
*
* @param memberIds
* @return ApiResponse<Boolean>
*
*/
@GetMapping("/checkId")
public ApiResponse<Boolean> selectCheckId(@RequestParam String memberIds) {
boolean isDuplicate = netmemberservice.selectCheckId(memberIds);
return ApiResponse.ok(!isDuplicate);
}
/**
* 로그인 여부 체크
*
* @return ApiResponse<Boolean>
*/
@GetMapping("/isLogin")
public ApiResponse<Boolean> checkLogin() {
boolean isLoggedIn = AuthUtil.isLoggedIn();
return ApiResponse.ok(isLoggedIn);
}
/**
* 비밀번호 재설정 member 체크
*
* @param map
* @return ApiResponse<Boolean>
*
*/
@PostMapping("/pwReset")
public ApiResponse<Boolean> selectPwReset(@ReqMap MapDto map) {
boolean isPwReset = netmemberservice.selectPwReset(map);
return ApiResponse.ok(isPwReset);
}
/**
* 비밀번호 재설정
*
* @param map
* @return ApiResponse<Boolean>
*
*/
@PatchMapping("/pwNew")
public ApiResponse<Boolean> updatePassword(@ReqMap MapDto map) {
boolean isPwNew = netmemberservice.updatePassword(map);
return ApiResponse.ok(isPwNew);
}
// security 인증 체크
@GetMapping("userInfo")
public ApiResponse<MemberVo> getUserInfo(@AuthenticationPrincipal MemberVo memberVo) {
SecurityContextHolderStrategy contextHolderStrategy = SecurityContextHolder.getContextHolderStrategy();
@ -67,9 +183,9 @@ public class UserController {
return ApiResponse.ok(memberVo);
}
//유저 세션 체크
// 유저 세션 체크
@GetMapping(value = "check")
public ApiResponse<?> check(){
public ApiResponse<?> check() {
Map<String, HttpSession> sessions = SessionListener.getSessions();
Map<String, Object> sessionData = new HashMap<>();
@ -106,10 +222,7 @@ public class UserController {
return ApiResponse.ok(remember);
}
//로그아웃
// 로그아웃
@Guest
@GetMapping("/logout")
public ApiResponse<String> logout(HttpServletRequest request, HttpServletResponse response) {
@ -133,6 +246,23 @@ public class UserController {
return ApiResponse.ok(returnMessage);
}
/**
* 사원 목록 전체 조회
*
*
*
*/
@ParameterCheck
@GetMapping("/allUserList")
public ApiResponse<MapDto> getallUserList() {
List<MapDto> allUserList = netmemberservice.getallUserList();
MemberVo user = AuthUtil.getUser();
MapDto outData = new MapDto();
outData.put("allUserList", allUserList);
outData.put("user", user);
return ApiResponse.ok(outData);
}
@Guest
@GetMapping("get1")

View File

@ -1,55 +0,0 @@
package io.company.localhost.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import io.company.localhost.common.dto.MapDto;
@Mapper
public interface LocalBordMapper {
// 공지사항 조회
List<Map<String, Object>> getNotices();
// 자유/비밀 게시판 조회
List<Map<String, Object>> getGeneralPosts();
// 게시물 작성
void createBoard(MapDto map);
// 첨부파일 저장
void addAttachment(MapDto map);
// 게시물 삭제
void deleteBoard(MapDto map);
// 게시물 수정
void updateBoard(MapDto map);
// 게시물 좋아요/싫어요 추가
void reactToBoard(MapDto map);
// 댓글 조회
List<Map<String, Object>> getComments(int boardSeq);
// 댓글/대댓글 작성
void addCommentOrReply(MapDto map);
// 댓글/대댓글 수정
void updateComment(MapDto map);
// 댓글/대댓글 삭제
void deleteComment(MapDto map);
// 게시물 비밀번호 확인
boolean checkBoardPassword(MapDto map);
// 댓글 비밀번호 확인
boolean checkCommentPassword(MapDto map);
// 비밀 게시판 여부 확인
boolean isSecretBoard(Long boardId);
}

View File

@ -14,12 +14,30 @@
*************************************************************/
package io.company.localhost.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.vo.MemberVo;
@Mapper
public interface MemberMapper {
public interface NetmemberMapper {
MemberVo findByLoginId(String id);
int updateMemberToken(MapDto map);
int insertMember(MapDto map);
int selectCheckId(String memberIds);
int selectPwReset(MapDto map);
String selectPassword(String id);
int updatePassword(MapDto map);
List<MapDto> getallUserList();
}

View File

@ -27,4 +27,13 @@ public interface commoncodMapper {
Long insertCategory(MapDto map);
List<MapDto> getColorList();
List<MapDto> getMbtiList();
List<MapDto> getPwhintList();
int updateColorYon(String color);
List<MapDto> getCategories();
}

View File

@ -0,0 +1,98 @@
package io.company.localhost.mapper;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import io.company.localhost.common.dto.MapDto;
@Mapper
public interface localbordMapper {
// 공지사항 조회
List<MapDto> getNotices(MapDto map);
// 자유/비밀 게시판 조회
List<MapDto> getGeneralPosts(MapDto map);
// 조회수 증가
void incrementViewCount(Long boardId);
// 게시물 작성
void createBoard(MapDto map);
// 첨부파일 저장
void addAttachment(MapDto map);
// 게시물 삭제
void deleteBoard(MapDto map);
// 게시물 삭제시 댓글/대댓글 삭제
void deleteCommentsByBoardId(MapDto map);
// 게시물 수정
void updateBoard(MapDto map);
// 기존 반응 조회
MapDto findReaction(MapDto map);
// 반응 삽입
void insertReaction(MapDto map);
// 기존 반응 업데이트
void updateReaction(MapDto map);
// 댓글 조회
List<MapDto> getComments(int boardSeq);
// 댓글/대댓글 작성
void addCommentOrReply(MapDto map);
// 댓글/대댓글 수정
void updateComment(MapDto map);
// 대댓글인지 확인
boolean isReply(MapDto map);
// 댓글에 대댓글이 있는지 확인
boolean hasReplies(MapDto map);
// 댓글 내용만 삭제 처리 (대댓글 유지)
void softDeleteComment(MapDto map);
// 댓글 삭제 (대댓글 없음)
void deleteComment(MapDto map);
// 대댓글 삭제
void deleteReply(MapDto map);
// 게시물 비밀번호 조회
String selectCommentPassword(int commentId);
// 댓글 비밀번호 조회
String selectBoardPassword(int boardId);
// 게시물 상세보기
MapDto selectBoardDetail(Long boardId);
// 댓글 갯수
int countComments(Long boardId);
// 첨부파일 유무
int countAttachments(Long boardId);
// 게시물 좋아요/싫어요 개수
MapDto getBoardReactions(Long boardId);
// 댓글 좋아요/싫어요 개수
List<MapDto> getCommentReactions(Long boardId);
// 첨부파일 가져오기
List<MapDto> selectAttachments(Long boardId);
//댓글id 확인
MapDto getCommentById(int commentId);
}

View File

@ -0,0 +1,19 @@
package io.company.localhost.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import io.company.localhost.common.dto.MapDto;
@Mapper
public interface localvacaMapper {
void insertVacation(MapDto map);
List<MapDto> findVacations(MapDto map);
}

View File

@ -29,6 +29,10 @@ public interface worddictyMapper {
Long updateWord(MapDto map);
MapDto getWordDetail(MapDto map);
int getTotal(MapDto map);

View File

@ -0,0 +1,68 @@
/************************************************************
*
* @packageName : io.company.localhost.FileService
* @fileName : FileService.java
* @author : 박지윤
* @date : 25.01.17
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.01.17 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.service;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.UUID;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class FileService {
@Value("${filePath.profile}")
private String uploadPath;
/**
* 파일 업로드
*
* @param file
* @return
* @throws RuntimeException
*/
public String uploadFile(MultipartFile file) {
try {
// 원본 파일명
String originalFilename = file.getOriginalFilename();
// 파일 확장자
String extension = FilenameUtils.getExtension(originalFilename);
// UUID를 사용하여 고유한 파일명 생성
String newFilename = UUID.randomUUID().toString() + "." + extension;
// 최종 저장 경로 생성 (기본경로 + 파일명)
Path targetPath = Paths.get(uploadPath, newFilename);
// 저장될 디렉토리가 없는 경우 생성
Files.createDirectories(targetPath.getParent());
// 동일 파일명이 있을 경우 덮어쓰기
Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING);
// 저장된 파일의 상대 경로 반환
return newFilename;
} catch (IOException e) {
throw new RuntimeException("파일 업로드 실패: " + e.getMessage());
}
}
}

View File

@ -1,76 +0,0 @@
package io.company.localhost.service;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.LocalBordMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class LocalBordService {
private final LocalBordMapper boardMapper;
public List<Map<String, Object>> getNotices() {
return boardMapper.getNotices();
}
public List<Map<String, Object>> getGeneralPosts() {
return boardMapper.getGeneralPosts();
}
public void createBoard(MapDto map) {
boardMapper.createBoard(map);
}
public void addAttachment(MapDto map) {
boardMapper.addAttachment(map);
}
public void deleteBoard(MapDto map) {
boardMapper.deleteBoard(map);
}
public void updateBoard(MapDto map) {
boardMapper.updateBoard(map);
}
public void reactToBoard(MapDto map) {
boardMapper.reactToBoard(map);
}
public List<Map<String, Object>> getComments(int boardSeq) {
return boardMapper.getComments(boardSeq);
}
public void addCommentOrReply(MapDto map) {
boardMapper.addCommentOrReply(map);
}
public void updateComment(MapDto map) {
boardMapper.updateComment(map);
}
public void deleteComment(MapDto map) {
boardMapper.deleteComment(map);
}
public boolean checkBoardPassword(MapDto map) {
return boardMapper.checkBoardPassword(map);
}
public boolean checkCommentPassword(MapDto map) {
return boardMapper.checkCommentPassword(map);
}
public boolean isSecretBoard(Long boardId) {
return boardMapper.isSecretBoard(boardId);
}
}

View File

@ -0,0 +1,140 @@
/************************************************************
*
* @packageName : io.company.localhost.RegisterService
* @fileName : RegisterService.java
* @author : 박지윤
* @date : 25.01.17
* @description :
*
* ===========================================================
* DATE AUTHOR NOTE
* -----------------------------------------------------------
* 24.01.17 박지윤 최초 생성
*
*************************************************************/
package io.company.localhost.service;
import java.time.LocalDateTime;
import java.util.List;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.NetmemberMapper;
import io.company.localhost.mapper.commoncodMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class NetmemberService {
private final NetmemberMapper memberMapper;
private final commoncodMapper commoncodMapper;
private final DelegatingPasswordEncoder passwordEncoder;
private final FileService fileService;
/**
* 회원 가입
*
* @param profile
* @param map
* @return
*/
public int register(MultipartFile memberPrf, MapDto map) {
// 프로필 이미지 저장, 저장된 경로 가져옴
String profilePath = fileService.uploadFile(memberPrf);
map.put("memberPrf", profilePath);
// 비밀번호 암호화 저장
String encodedPassword = passwordEncoder.encode(map.getString("memberPwd"));
map.put("memberPwd", encodedPassword);
// 회원 기본 정보 설정
map.put("memberRol", "ROLE_MEMBER");
map.put("memberPos", 500107);
map.put("memberTkn", "Null");
map.put("memberPrm", "Y");
map.put("memberDel", "N");
map.put("memberLea", "N");
map.put("memberRdt", LocalDateTime.now());
map.put("memberCdt", LocalDateTime.now());
// 회원 정보 저장
int result = memberMapper.insertMember(map);
// 선택한 색상 코드 사용 처리
String color = map.getString("memberCol");
commoncodMapper.updateColorYon(color);
return result;
}
/**
* 아이디 중복 체크
*
* @param memberIds
* @return
*/
public boolean selectCheckId(String memberIds) {
return memberMapper.selectCheckId(memberIds) > 0;
}
/**
* 사원 목록 전체 조회
*
* @param
* @return
*/
public List<MapDto> getallUserList() {
return memberMapper.getallUserList();
}
/**
* 로그인 토큰
*
* @param id, token
* @return
*/
public void updateMemberToken(MapDto map) {
memberMapper.updateMemberToken(map);
}
/**
* 비밀번호 재설정 member 체크
*
* @param map
* @return
*/
public boolean selectPwReset(MapDto map) {
return memberMapper.selectPwReset(map) > 0;
}
/**
* 기존 비밀번호 체크
*
* @param map
* @return
*/
public boolean selectPassword(MapDto map) {
String currentPassword = memberMapper.selectPassword(map.getString("id"));
String newPassword = map.getString("password");
// 기존 비밀번호, 비밀번호 같은지 확인
return !passwordEncoder.matches(newPassword, currentPassword);
}
/**
* 비밀번호 재설정
*
* @param map
* @return
*/
public boolean updatePassword(MapDto map) {
String encodedPassword = passwordEncoder.encode(map.getString("password"));
map.put("password", encodedPassword);
System.out.println("암호화된 비밀번호: " + encodedPassword);
return memberMapper.updatePassword(map) > 0;
}
}

View File

@ -36,4 +36,18 @@ public class commoncodService {
return commoncodmapper.insertCategory(map);
}
public List<MapDto> getColorList() {
return commoncodmapper.getColorList();
}
public List<MapDto> getMbtiList() {
return commoncodmapper.getMbtiList();
}
public List<MapDto> getPwhintList() {
return commoncodmapper.getPwhintList();
}
public List<MapDto> getCategoryList() {
return commoncodmapper.getCategories();
}
}

View File

@ -0,0 +1,304 @@
package io.company.localhost.service;
import java.io.ByteArrayInputStream;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.localbordMapper;
import io.company.localhost.utils.PageUtil;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class localbordService {
private final localbordMapper boardMapper;
private static final long MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB
public List<MapDto> getNotices(MapDto map) {
List<MapDto> posts = boardMapper.getNotices(map);
enrichPostsWithAdditionalData(posts);
return posts;
}
public PageInfo<MapDto> getGeneralPosts(MapDto map) {
System.out.println(map);
int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1;
int size = map.getString("size") != null ? Integer.parseInt(map.getString("size")) : 10;
String orderBy = map.getString("orderBy");
if (orderBy == null || (!orderBy.equals("date") && !orderBy.equals("views"))) {
map.put("orderBy", "date");
}
PageHelper.startPage(page, size);
List<MapDto> result = boardMapper.getGeneralPosts(map);
enrichPostsWithAdditionalData(result);
return PageUtil.redefineNavigation(new PageInfo<>(result, size));
}
public void incrementViewCount(Long boardId) {
boardMapper.incrementViewCount(boardId);
}
public BigInteger createBoard(MapDto map) {
boardMapper.createBoard(map);
return (BigInteger) map.get("LOCBRDSEQ");
}
public void addAttachment(MapDto map) {
String boardSeqStr = (String) map.get("CMNBRDSEQ");
Long boardSeq = Long.parseLong(boardSeqStr);
map.put("CMNBRDSEQ", boardSeq);
String newFilename = UUID.randomUUID().toString();
map.put("CMNFLENAM", newFilename);
boardMapper.addAttachment(map);
}
public void validateAttachmentsSize(List<MapDto> attachments) {
long totalSize = attachments.stream()
.mapToLong(attachment -> (Long) attachment.get("size"))
.sum();
if (totalSize > MAX_FILE_SIZE) {
throw new IllegalArgumentException("첨부파일의 총 용량이 5MB를 초과합니다.");
}
}
public MapDto getBoardDetail(Long boardId) {
incrementViewCount(boardId);
MapDto boardDetail = boardMapper.selectBoardDetail(boardId);
if (boardDetail != null) {
enrichBoardDetail(boardDetail);
}
return boardDetail;
}
public List<MapDto> getAttachments(Long boardId) {
return boardMapper.selectAttachments(boardId);
}
public void deleteBoard(MapDto map) {
boardMapper.deleteCommentsByBoardId(map);
boardMapper.deleteBoard(map);
}
public void updateBoard(MapDto map) {
boardMapper.updateBoard(map);
}
public void reactToBoard(MapDto map) {
MapDto existingReaction = boardMapper.findReaction(map);
if (existingReaction != null) {
boardMapper.updateReaction(map);
} else {
boardMapper.insertReaction(map);
}
}
public List<MapDto> getComments(int boardSeq) {
return boardMapper.getComments(boardSeq);
}
public void addCommentOrReply(MapDto map) {
if (map.get("LOCCMTPNT") == null) {
map.put("LOCCMTPNT", null);
}
boardMapper.addCommentOrReply(map);
}
public void updateComment(MapDto map) {
boardMapper.updateComment(map);
}
public void deleteComment(MapDto map) {
boolean isReply = boardMapper.isReply(map);
if (isReply) {
boardMapper.deleteReply(map);
} else {
boolean hasReplies = boardMapper.hasReplies(map);
if (hasReplies) {
boardMapper.softDeleteComment(map);
} else {
boardMapper.deleteComment(map);
}
}
}
public String getCommentPassword(int commentId) {
return boardMapper.selectCommentPassword(commentId);
}
public String getBoardPassword(int boardId) {
return boardMapper.selectBoardPassword(boardId);
}
public MapDto getCommentById(int commentId) {
return boardMapper.getCommentById(commentId);
}
public int getCommentCount(Long boardId) {
return boardMapper.countComments(boardId);
}
public boolean hasAttachments(Long boardId) {
int count = boardMapper.countAttachments(boardId);
return count > 0;
}
public MapDto getBoardReactions(Long boardId) {
return boardMapper.getBoardReactions(boardId);
}
public List<MapDto> getCommentReactions(Long boardId) {
return boardMapper.getCommentReactions(boardId);
}
private void enrichBoardDetail(MapDto boardDetail) {
long boardId = ((Number) boardDetail.get("id")).longValue();
boardDetail.put("hasAttachment", hasAttachments(boardId));
boardDetail.put("commentCount", getCommentCount(boardId));
MapDto reactions = getBoardReactions(boardId);
boardDetail.put("likeCount", reactions.getOrDefault("likeCount", 0));
boardDetail.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
// Blob 데이터를 문자열로 변환
Object content = boardDetail.get("content");
if (content != null) {
String contentString = convertBlobToString(content); // Blob을 문자열로 변환
boardDetail.put("content", contentString); // JSON 변환 가능
}
}
private String convertBlobToString(Object blob) {
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);
} else if (blob instanceof ByteArrayInputStream) {
ByteArrayInputStream inputStream = (ByteArrayInputStream) blob;
byte[] bytes = inputStream.readAllBytes();
return new String(bytes, StandardCharsets.UTF_8);
} else {
System.err.println("Unsupported blob type: " + blob.getClass());
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to convert Blob to String: " + e.getMessage(), e);
}
return null;
}
private String extractFirstImageUrl(String jsonContent) {
try {
// JSON 유효성 검사
if (!isValidJson(jsonContent)) {
throw new IllegalArgumentException("Invalid JSON content: " + jsonContent);
}
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonContent);
// JSON 배열 순회
for (JsonNode node : rootNode) {
JsonNode insertNode = node.get("insert");
if (insertNode != null && insertNode.has("image")) {
return insertNode.get("image").asText(); // 번째 이미지 URL 반환
}
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to extract first image URL: " + e.getMessage(), e);
}
return null; // 이미지가 없는 경우
}
private boolean isValidJson(String json) {
try {
final ObjectMapper objectMapper = new ObjectMapper();
objectMapper.readTree(json); // JSON 파싱 시도
return true; // JSON이 유효하면 true 반환
} catch (Exception e) {
return false; // 유효하지 않은 경우 false 반환
}
}
private String extractPlainTextFromJson(String jsonContent) {
StringBuilder plainTextBuilder = new StringBuilder();
try {
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonContent);
// JSON 배열인지 확인
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()) {
String text = insertNode.asText();
// '\n' 제거하고 순수 텍스트만 추가
if (!text.trim().isEmpty() && !text.trim().equals("\n")) {
plainTextBuilder.append(text.trim());
}
}
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException("Failed to extract plain text: " + e.getMessage(), e);
}
return plainTextBuilder.toString();
}
private void enrichPostsWithAdditionalData(List<MapDto> posts) {
for (MapDto post : posts) {
Object idObject = post.get("id");
if (idObject instanceof Number) {
long postId = ((Number) idObject).longValue();
post.put("commentCount", getCommentCount(postId));
post.put("hasAttachment", hasAttachments(postId));
MapDto reactions = getBoardReactions(postId);
post.put("likeCount", reactions.getOrDefault("likeCount", 0));
post.put("dislikeCount", reactions.getOrDefault("dislikeCount", 0));
Object content = post.get("content");
String contentString = convertBlobToString(content);
post.put("content", contentString);
String firstImageUrl = extractFirstImageUrl(contentString);
post.put("firstImageUrl", firstImageUrl);
String plainContent = extractPlainTextFromJson(contentString);
post.put("plainContent", plainContent);
}
}
}
}

View File

@ -0,0 +1,25 @@
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.localvacaMapper;
import lombok.RequiredArgsConstructor;
@Service
@RequiredArgsConstructor
public class localvacaService {
private final localvacaMapper localvacaMapper;
public void insertVacation(MapDto map) {
localvacaMapper.insertVacation(map);
}
public List<MapDto> getVacationList(MapDto map) {
return localvacaMapper.findVacations(map);
}
}

View File

@ -15,14 +15,13 @@
package io.company.localhost.service;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import io.company.localhost.common.dto.MapDto;
import io.company.localhost.mapper.worddictyMapper;
import io.company.localhost.utils.PageUtil;
import lombok.RequiredArgsConstructor;
@Service
@ -31,11 +30,35 @@ public class worddictyService {
private final worddictyMapper worddictymapper;
public PageInfo<MapDto> getWordList(MapDto map) {
int page = map.getString("page") != null ? Integer.parseInt(map.getString("page")) : 1;
PageHelper.startPage(page, 10);
return PageUtil.redefineNavigation(new PageInfo<>(worddictymapper.getWordList(map),10));
public List<MapDto> getWordList(MapDto map) {
List<MapDto> wordList = worddictymapper.getWordList(map);
List<MapDto> processedList = new ArrayList<>();
// 데이터 가공
for (MapDto dto : wordList) {
MapDto author = new MapDto();
author.put("profileImage", dto.remove("REGPRF"));
author.put("name", dto.remove("REGNAME"));
author.put("color", dto.remove("REGCOLOR"));
author.put("createdAt", dto.remove("REGRDT"));
MapDto lastEditor = new MapDto();
lastEditor.put("profileImage", dto.remove("UPDPRF"));
lastEditor.put("name", dto.remove("UPDNAME"));
lastEditor.put("color", dto.remove("UPDCOLOR"));
lastEditor.put("updatedAt", dto.remove("UPDUDT"));
dto.put("author", author);
dto.put("lastEditor", lastEditor);
MapDto processedDto = new MapDto();
processedDto.putAll(dto);
processedList.add(processedDto);
}
return processedList;
}
public Long insertWord(MapDto map) {
return worddictymapper.insertWord(map);
@ -45,6 +68,14 @@ public class worddictyService {
return worddictymapper.updateWord(map);
}
public MapDto getWordDetail(MapDto map) {
return worddictymapper.getWordDetail(map);
}
public int getTotal(MapDto map) {
return worddictymapper.getTotal(map);
}

View File

@ -58,6 +58,18 @@ public class PageUtil {
list.setNavigateLastPage(nav2[nav2.length -1]);
}
// 페이지 그룹 크기 (: 10개씩)
int groupSize = list.getNavigatePages();
int totalPages = list.getPages();
// 현재 페이지 그룹 계산
int currentGroup = (int) Math.ceil((double) currentPage / groupSize);
int totalGroups = (int) Math.ceil((double) totalPages / groupSize);
// 이전/다음 그룹 존재 여부 설정
list.setHasPreviousPage(currentGroup > 1); // 이전 그룹 존재
list.setHasNextPage(currentGroup < totalGroups); // 다음 그룹 존재
return list;
}
}

View File

@ -25,16 +25,28 @@ import java.util.Date;
@AllArgsConstructor
@ToString
public class MemberVo {
private Long id;
private String loginId;
private String role;
private String name;
private String password;
private String email;
private String isUsed;
private String isDel;
private Date isrtDate;
private Date updtDate;
private Boolean remember;
private String loginId; // 사용자 아이디
private String role; // 권한
private String token; // 토큰
private String profile; // 프로필사진
private String name; // 이름
private String password; // 비밀번호
private String passwordhint; // 비밀번호힌트
private String passwordRes; // 비밀번호힌트답변
private int position; // 직급
private String address; // 주소
private String addressDetail; // 상세주소
private String zipcode; // 우편번호
private Date birth; // 생년월일
private String phone; // 전화번호
private Date regist; // 가입요청일
private Date isCdt; // 입사일
private String isUsed; // 허가여부
private String isDel; // 퇴사여부
private String isLea; // 휴직여부
private int color; // 색상
private int mbit; // MBTI
private Boolean remember; // 로그인 유지
}

View File

@ -4,11 +4,6 @@ project:
time-zone: Asia/Seoul
spring:
datasource:
url: jdbc:mariadb://192.168.0.251:3306/localnet
username: root
password: host1234
driver-class-name: org.mariadb.jdbc.Driver
devtools:
livereload:
enabled: true
@ -23,6 +18,10 @@ spring:
web:
resources:
add-mappings: false
servlet:
multipart:
max-file-size: 5MB
max-request-size: 5MB
mybatis:
mapper-locations: classpath:mapper/**/*.xml
@ -89,3 +88,10 @@ logging:
connection: off
io.company: DEBUG
io.company.localhost.mapper: off
filePath:
boardfile: C:\\localhost-back\\upload\\img\\board\\
profile: C:\\localhost-back\\upload\\img\\profile\\

View File

@ -1,110 +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.LocalBordMapper">
<!-- 공지사항 조회 -->
<select id="getNotices" resultType="java.util.Map">
SELECT
b.LOCBRDSEQ,
b.LOCBRDTTL,
b.LOCBRDCON,
b.LOCBRDRDT,
b.LOCBRDTYP,
a.FILE_PATH,
a.FILE_NAME,
a.FILE_TYPE
FROM localbord b
LEFT JOIN attachments a ON b.LOCBRDSEQ = a.LOCBRDSEQ
WHERE b.LOCBRDTYP = 'N'
ORDER BY b.LOCBRDRDT DESC
</select>
<!-- 자유/비밀 게시판 조회 -->
<select id="getGeneralPosts" resultType="map">
SELECT
LOCBRDSEQ AS id,
LOCBRDTTL AS title,
LOCBRDCON AS content,
LOCBRDRDT AS date
FROM localbord
WHERE LOCBRDTYP IN ('F', 'S')
ORDER BY LOCBRDRDT DESC
</select>
<!-- 게시물 작성 -->
<insert id="createBoard">
INSERT INTO localbord (LOCBRDTTL, LOCBRDCON, LOCBRDCAT, MEMBERSEQ, LOCBRDCNT, LOCBRDRDT, LOCBRDUDT, LOCBRDPWD, LOCBRDTYP)
VALUES (#{LOCBRDTTL}, #{LOCBRDCON}, #{LOCBRDCAT}, #{MEMBERSEQ}, 0, NOW(), NOW(), #{LOCBRDPWD}, #{LOCBRDTYP})
</insert>
<!-- 첨부파일 저장 -->
<insert id="addAttachment">
INSERT INTO commonfil (CMNBRDSEQ, CMNFLEPAT, CMNFLENAM, CMNFLEORG, CMNFLEEXT, CMNFLESIZ, CMNFLEREG, CMNFLERDT)
VALUES (#{CMNBRDSEQ}, #{CMNFLEPAT}, #{CMNFLENAM}, #{CMNFLEORG}, #{CMNFLEEXT}, #{CMNFLESIZ}, #{CMNFLEREG}, NOW())
</insert>
<!-- 게시물 삭제 -->
<delete id="deleteBoard">
DELETE FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete>
<!-- 게시물 수정 -->
<update id="updateBoard">
UPDATE localbord
SET LOCBRDTTL = #{LOCBRDTTL}, LOCBRDCON = #{LOCBRDCON}, LOCBRDUDT = NOW()
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</update>
<!-- 게시물 좋아요/싫어요 추가 -->
<insert id="reactToBoard">
INSERT INTO localgorb (LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD )
VALUES (#{LOCBRDSEQ}, #{LOCCMTSEQ}, #{MEMBERSEQ}, #{LOCGOBGOD}, #{LOCGOBBAD})
ON DUPLICATE KEY UPDATE LOCGOBGOD = #{LOCGOBGOD}, LOCGOBBAD = #{LOCGOBBAD}
</insert>
<!-- 댓글/대댓글 조회 -->
<select id="getComments" resultType="java.util.Map">
SELECT LOCCMTSEQ, LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTPNT
FROM loccomt
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
ORDER BY LOCCMTPNT ASC, LOCCMTRDT ASC
</select>
<!-- 댓글/대댓글 작성 -->
<insert id="addCommentOrReply">
INSERT INTO loccomt (LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTPNT)
VALUES (#{LOCBRDSEQ}, #{LOCCMTRPY}, #{LOCCMTPWD}, NOW(), #{LOCCMTPNT})
</insert>
<!-- 댓글/대댓글 수정 -->
<update id="updateComment">
UPDATE loccomt
SET LOCCMTRPY = #{LOCCMTRPY}, LOCCMTUDT = NOW()
WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPWD = #{LOCCMTPWD}
</update>
<!-- 댓글/대댓글 삭제 -->
<delete id="deleteComment">
DELETE FROM loccomt
WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPWD = #{LOCCMTPWD}
</delete>
<!-- 비밀번호 확인 (게시물) -->
<select id="checkBoardPassword" resultType="boolean">
SELECT COUNT(*) > 0 FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ} AND LOCBRDPWD = #{LOCBRDPWD}
</select>
<!-- 비밀번호 확인 (댓글) -->
<select id="checkCommentPassword" resultType="boolean">
SELECT COUNT(*) > 0 FROM loccomt WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPWD = #{LOCCMTPWD}
</select>
<!-- 비밀 게시판 여부 확인 -->
<select id="isSecretBoard" resultType="boolean">
SELECT CASE WHEN LOCBRDTYP = 'S' THEN TRUE ELSE FALSE END
FROM localbord
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</select>
</mapper>

View File

@ -29,4 +29,55 @@
WHERE
CMNCODLV1 = 600;
</insert>
<select id="getColorList" resultType="Map">
SELECT
CMNCODVAL
,CMNCODNAM
FROM
commoncod
WHERE
CMNCODLV1 = 100
AND
CMNCODODR != 0
AND
CMNCODYON = 0
</select>
<select id="getMbtiList" resultType="Map">
SELECT
CMNCODVAL
,CMNCODNAM
FROM
commoncod
WHERE
CMNCODLV1 = 200
AND
CMNCODODR != 0
</select>
<select id="getPwhintList" resultType="Map">
SELECT
CMNCODVAL
,CMNCODNAM
FROM
commoncod
WHERE
CMNCODLV1 = 800
AND
CMNCODODR != 0
</select>
<update id="updateColorYon" parameterType="String">
UPDATE commoncod
SET CMNCODYON = 1
WHERE CMNCODVAL = #{color};
</update>
<select id="getCategories" resultType="Map">
SELECT CMNCODVAL, CMNCODNAM FROM commoncod
WHERE CMNCODVAL BETWEEN 300101 AND 300103
</select>
</mapper>

View File

@ -0,0 +1,249 @@
<?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.localbordMapper">
<!-- 공지사항 조회 -->
<select id="getNotices" 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.LOCBRDCNT AS cnt,
m.MEMBERNAM AS author
FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE LOCBRDTYP = '300103'
<if test="searchKeyword != null and searchKeyword != ''">
AND LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%')
</if>
ORDER BY LOCBRDUDT DESC
</select>
<!-- 자유/익명 게시판 조회 (작성자 이름 포함) -->
<select id="getGeneralPosts" 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.LOCBRDCNT AS cnt,
m.MEMBERNAM AS author
FROM localbord b
LEFT JOIN netmember m ON b.MEMBERSEQ = m.MEMBERSEQ
WHERE b.LOCBRDTYP IN ('300101', '300102')
<if test="searchKeyword != null and searchKeyword != ''">
AND b.LOCBRDTTL LIKE CONCAT('%', #{searchKeyword}, '%')
</if>
ORDER BY
<choose>
<when test="orderBy == 'date'"> b.LOCBRDUDT DESC </when>
<when test="orderBy == 'views'"> b.LOCBRDCNT DESC </when>
</choose>
</select>
<!-- 조회수 증가 -->
<update id="incrementViewCount">
UPDATE localbord SET LOCBRDCNT = LOCBRDCNT + 1 WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</update>
<!-- 게시물 작성 -->
<insert id="createBoard" parameterType="map" useGeneratedKeys="true" keyProperty="LOCBRDSEQ">
INSERT INTO localbord (LOCBRDTTL, LOCBRDCON, LOCBRDCAT, MEMBERSEQ, LOCBRDCNT, LOCBRDRDT, LOCBRDUDT, LOCBRDPWD, LOCBRDTYP)
VALUES (#{LOCBRDTTL}, #{LOCBRDCON}, #{LOCBRDCAT}, #{MEMBERSEQ}, 0, NOW(), NOW(), #{LOCBRDPWD}, #{LOCBRDTYP})
</insert>
<!-- 첨부파일 저장 -->
<insert id="addAttachment" parameterType="map">
INSERT INTO commonfil (
CMNBRDSEQ,CMNFLENAM,CMNFLEORG,CMNFLEPAT,
CMNFLEEXT,CMNFLESIZ,CMNFLEREG,CMNFLERDT
) VALUES (
#{CMNBRDSEQ},#{CMNFLENAM},#{CMNFLEORG},#{CMNFLEPAT},
#{CMNFLEEXT},#{CMNFLESIZ},#{CMNFLEREG},NOW()
)
</insert>
<!-- 게시물 상세정보 조회 -->
<select id="selectBoardDetail" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCBRDSEQ AS id, LOCBRDTTL AS title, LOCBRDCON AS content, LOCBRDUDT AS date, LOCBRDTYP AS type, LOCBRDCNT AS cnt
FROM localbord
WHERE LOCBRDSEQ = #{boardId}
</select>
<!-- 첨부파일 목록 조회 -->
<select id="selectAttachments" resultType="io.company.localhost.common.dto.MapDto">
SELECT CMNFLESEQ AS id, CMNFLEORG AS originalName, CMNFLENAM AS fileName, CMNFLEPAT AS path,
CMNFLEEXT AS extension, CMNFLESIZ AS size, CMNFLERDT AS uploadDate
FROM commonfil
WHERE CMNBRDSEQ = #{boardId}
ORDER BY CMNFLERDT DESC
</select>
<!-- 게시물 삭제 -->
<delete id="deleteBoard">
DELETE FROM localbord WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete>
<!-- 게시물 삭제 시 댓글/대댓글 삭제 -->
<delete id="deleteCommentsByBoardId">
DELETE FROM localcomt
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</delete>
<!-- 게시물 수정 -->
<update id="updateBoard">
UPDATE localbord
SET LOCBRDTTL = #{LOCBRDTTL}, LOCBRDCON = #{LOCBRDCON}, LOCBRDUDT = NOW()
WHERE LOCBRDSEQ = #{LOCBRDSEQ}
</update>
<!-- 기존 반응 조회 -->
<select id="findReaction" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD
FROM localgorb
WHERE (LOCBRDSEQ = #{LOCBRDSEQ} OR (#{LOCBRDSEQ} IS NULL AND LOCBRDSEQ IS NULL))
AND (LOCCMTSEQ = #{LOCCMTSEQ} OR (#{LOCCMTSEQ} IS NULL AND LOCCMTSEQ IS NULL))
AND MEMBERSEQ = #{MEMBERSEQ}
</select>
<!-- 반응 업데이트 -->
<update id="updateReaction">
UPDATE localgorb
SET LOCGOBGOD = #{LOCGOBGOD}, LOCGOBBAD = #{LOCGOBBAD}
WHERE (LOCBRDSEQ = #{LOCBRDSEQ} OR (#{LOCBRDSEQ} IS NULL AND LOCBRDSEQ IS NULL))
AND (LOCCMTSEQ = #{LOCCMTSEQ} OR (#{LOCCMTSEQ} IS NULL AND LOCCMTSEQ IS NULL))
AND MEMBERSEQ = #{MEMBERSEQ}
</update>
<!-- 새 반응 삽입 -->
<insert id="insertReaction">
INSERT INTO localgorb (LOCBRDSEQ, LOCCMTSEQ, MEMBERSEQ, LOCGOBGOD, LOCGOBBAD)
VALUES (#{LOCBRDSEQ}, #{LOCCMTSEQ}, #{MEMBERSEQ}, #{LOCGOBGOD}, #{LOCGOBBAD})
</insert>
<!-- 댓글/대댓글 조회 -->
<select id="getComments" resultType="io.company.localhost.common.dto.MapDto">
SELECT
LOCCMTSEQ,LOCBRDSEQ,LOCCMTPNT,LOCCMTRPY,
LOCCMTUDT,LOCCMTPWD,LOCCMTRDT,LOCCMTPNT
FROM localcomt
WHERE LOCBRDSEQ = #{boardId}
ORDER BY LOCCMTPNT ASC, LOCCMTUDT ASC
</select>
<!-- 댓글/대댓글 작성 -->
<insert id="addCommentOrReply">
INSERT INTO localcomt (LOCBRDSEQ, LOCCMTRPY, LOCCMTPWD, LOCCMTRDT, LOCCMTUDT, LOCCMTPNT, MEMBERSEQ)
VALUES (#{LOCBRDSEQ}, #{LOCCMTRPY}, #{LOCCMTPWD}, NOW(), NOW() , #{LOCCMTPNT}, #{MEMBERSEQ})
</insert>
<!-- 댓글/대댓글 수정 -->
<update id="updateComment">
UPDATE localcomt
SET LOCCMTRPY = #{LOCCMTRPY}, LOCCMTUDT = NOW()
WHERE LOCCMTSEQ = #{LOCCMTSEQ}
</update>
<!-- 댓글 삭제 -->
<update id="softDeleteComment">
UPDATE localcomt
SET LOCCMTRPY = '삭제된 댓글입니다'
WHERE LOCCMTSEQ = #{LOCCMTSEQ}
AND EXISTS (
SELECT 1 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ}
)
</update>
<!-- 댓글 삭제 (대댓글 없을 경우) -->
<delete id="deleteComment">
DELETE FROM localcomt
WHERE LOCCMTSEQ = #{LOCCMTSEQ}
AND NOT EXISTS (
SELECT 1 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ}
)
</delete>
<!-- 대댓글 삭제 -->
<delete id="deleteReply">
DELETE FROM localcomt
WHERE LOCCMTSEQ = #{LOCCMTSEQ}
AND LOCCMTPNT IS NOT NULL
</delete>
<!-- 대댓글인지 확인 -->
<select id="isReply" resultType="boolean">
SELECT COUNT(1) > 0 FROM localcomt
WHERE LOCCMTSEQ = #{LOCCMTSEQ} AND LOCCMTPNT IS NOT NULL
</select>
<!-- 댓글에 대댓글이 있는지 확인 -->
<select id="hasReplies" resultType="boolean">
SELECT COUNT(1) > 0 FROM localcomt WHERE LOCCMTPNT = #{LOCCMTSEQ}
</select>
<!-- 댓글 비밀번호 조회 -->
<select id="selectCommentPassword" resultType="String">
SELECT LOCCMTPWD
FROM localcomt
WHERE LOCCMTSEQ = #{commentId}
</select>
<!-- 게시물 비밀번호 조회 -->
<select id="selectBoardPassword" resultType="String">
SELECT LOCBRDPWD
FROM localbord
WHERE LOCBRDSEQ = #{boardId}
</select>
<!-- 비밀 게시판 여부 확인 -->
<select id="isSecretBoard" resultType="boolean">
SELECT CASE WHEN LOCBRDTYP = 'S' THEN TRUE ELSE FALSE END
FROM localbord
WHERE LOCBRDSEQ = #{boardId}
</select>
<!-- 댓글 id확인 -->
<select id="getCommentById" resultType="io.company.localhost.common.dto.MapDto">
SELECT LOCCMTSEQ AS id, LOCCMTPNT AS point
FROM localcomt
WHERE LOCCMTSEQ = #{commentId}
</select>
<!-- 댓글 개수 조회 -->
<select id="countComments" parameterType="long" resultType="int">
SELECT COUNT(*)
FROM localcomt
WHERE LOCBRDSEQ = #{boardId}
</select>
<!-- 첨부파일 유무 -->
<select id="countAttachments" resultType="int">
SELECT COUNT(*)
FROM commonfil
WHERE CMNBRDSEQ = #{boardId}
</select>
<!-- 게시물 좋아요/싫어요 개수 조회 -->
<select id="getBoardReactions" resultType="io.company.localhost.common.dto.MapDto">
SELECT
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
FROM localgorb
WHERE LOCBRDSEQ = #{boardId};
</select>
<!-- 댓글별 좋아요/싫어요 개수 조회 -->
<select id="getCommentReactions" resultType="io.company.localhost.common.dto.MapDto">
SELECT
LOCCMTSEQ,
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
FROM localgorb
WHERE LOCBRDSEQ = #{boardId}
GROUP BY LOCCMTSEQ
</select>
</mapper>

View File

@ -0,0 +1,20 @@
<?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.localvacaMapper">
<!-- 휴가 저장 -->
<insert id="insertVacation" parameterType="io.company.localhost.common.dto.MapDto">
INSERT INTO localvaca (MEMBERSEQ, LOCVACUDT, LOCVACTYP, LOCVACRDT)
VALUES (#{employeeId}, #{date}, #{type}, NOW())
</insert>
<!-- 휴가 정보 조회 -->
<select id="findVacations" parameterType="io.company.localhost.common.dto.MapDto">
SELECT
MEMBERSEQ,
LOCVACUDT,
LOCVACTYP
FROM
localvaca
</select>
</mapper>

View File

@ -1,24 +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.MemberMapper">
<select id="findByLoginId" parameterType="String" resultType="io.company.localhost.vo.MemberVo">
SELECT
MEMBER_ID AS id
, MEMBER_LOGIN_ID AS loginId
, MEMBER_ROLE AS role
, MEMBER_NAME AS name
, MEMBER_PASSWORD AS password
, MEMBER_EMAIL AS email
, IS_USED AS isUsed
, IS_DEL AS isDel
, ISRT_DATE AS isrtDate
, UPDT_DATE AS updtDate
, #{remember} as remember
FROM
MEMBER_TB
WHERE
MEMBER_LOGIN_ID = #{id}
</select>
</mapper>

View File

@ -0,0 +1,142 @@
<?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.NetmemberMapper">
<select id="findByLoginId" parameterType="String" 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
FROM
netmember
WHERE
MEMBERIDS = #{id}
</select>
<update id="updateMemberToken">
UPDATE netmember
SET MEMBERTKN = #{token}
WHERE MEMBERIDS = #{id}
</update>
<!-- 회원가입 -->
<insert id="insertMember" useGeneratedKeys="true" keyProperty="MEMBERSEQ">
INSERT INTO netmember (
MEMBERIDS,
MEMBERROL,
MEMBERTKN,
MEMBERPRF,
MEMBERNAM,
MEMBERPWD,
MEMBERPWH,
MEMBERPWR,
MEMBERPOS,
MEMBERARR,
MEMBERDTL,
MEMBERZIP,
MEMBERBTH,
MEMBERTEL,
MEMBERRDT,
MEMBERCDT,
MEMBERPRM,
MEMBERDEL,
MEMBERLEA,
MEMBERCOL,
MEMBERMBT
) VALUES (
#{memberIds},
#{memberRol},
#{memberTkn},
#{memberPrf},
#{memberNam},
#{memberPwd},
#{memberPwh},
#{memberPwr},
#{memberPos},
#{memberArr},
#{memberDtl},
#{memberZip},
#{memberBth},
#{memberTel},
#{memberRdt},
#{memberCdt},
#{memberPrm},
#{memberDel},
#{memberLea},
#{memberCol},
#{memberMbt}
)
</insert>
<!-- 중복체크 -->
<select id="selectCheckId" resultType="int">
SELECT COUNT(*)
FROM netmember
WHERE MEMBERIDS = #{memberIds}
</select>
<!-- 비밀번호 재설정 member 체크 -->
<select id="selectPwReset" resultType="int">
SELECT COUNT(*)
FROM netmember
WHERE MEMBERIDS = #{id}
AND MEMBERBTH = #{birth}
AND MEMBERPWH = #{pwhint}
AND MEMBERPWR = #{pwhintRes}
</select>
<!-- 비밀번호 재설정 기존 비밀번호 체크 -->
<select id="selectPassword">
SELECT MEMBERPWD
FROM netmember
WHERE MEMBERIDS = #{id}
</select>
<!-- 비밀번호 재설정 -->
<update id="updatePassword">
UPDATE netmember
SET MEMBERPWD = #{password}
WHERE MEMBERIDS = #{id}
</update>
<!-- 전체 회원 목록 -->
<select id="getallUserList" resultType="Map">
SELECT
m.*
,c.CMNCODNAM usercolor
FROM
netmember m
left join
commoncod c
on
M.MEMBERCOL = C.CMNCODVAL
WHERE
m.MEMBERDEL = "N"
AND
m.MEMBERPRM = "Y"
AND
m.MEMBERLEA ="N"
</select>
</mapper>

View File

@ -1,19 +1,7 @@
<?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.worddictyMapper">
<select id="getWordList" parameterType="map" resultType="Map">
select
w.*
,DATE_FORMAT(w.WRDDICRDT,'%y.%m.%d %H:%i') AS formatWRDDICRDT
,c.CMNCODNAM category
from
worddicty w
left join
commoncod c
on
w.WRDDICCAT = c.CMNCODVAL
where
1=1
<sql id="searchConditions">
<!-- 검색어 조건 -->
<if test="searchKeyword != null and searchKeyword != ''">
and (w.WRDDICTTL like CONCAT('%', #{searchKeyword}, '%')
@ -21,14 +9,183 @@
</if>
<!-- 색인표 조건 -->
<if test="indexKeyword != null and indexKeyword != ''">
and w.WRDDICTTL like CONCAT(#{indexKeyword}, '%')
<choose>
<!-- 한글 ㄱ ~ ㅎ에 대한 검색 -->
<when test='indexKeyword == "ㄱ"'>
and w.WRDDICTTL BETWEEN '가' AND '깋'
</when>
<when test='indexKeyword == "ㄴ"'>
and w.WRDDICTTL BETWEEN '나' AND '닣'
</when>
<when test='indexKeyword == "ㄷ"'>
and w.WRDDICTTL BETWEEN '다' AND '딷'
</when>
<when test='indexKeyword == "ㄹ"'>
and w.WRDDICTTL BETWEEN '라' AND '릿'
</when>
<when test='indexKeyword == "ㅁ"'>
and w.WRDDICTTL BETWEEN '마' AND '맇'
</when>
<when test='indexKeyword == "ㅂ"'>
and w.WRDDICTTL BETWEEN '바' AND '빟'
</when>
<when test='indexKeyword == "ㅅ"'>
and w.WRDDICTTL BETWEEN '사' AND '싷'
</when>
<when test='indexKeyword == "ㅇ"'>
and w.WRDDICTTL BETWEEN '아' AND '잏'
</when>
<when test='indexKeyword == "ㅈ"'>
and w.WRDDICTTL BETWEEN '자' AND '짛'
</when>
<when test='indexKeyword == "ㅊ"'>
and w.WRDDICTTL BETWEEN '차' AND '칳'
</when>
<when test='indexKeyword == "ㅋ"'>
and w.WRDDICTTL BETWEEN '카' AND '킿'
</when>
<when test='indexKeyword == "ㅌ"'>
and w.WRDDICTTL BETWEEN '타' AND '틷'
</when>
<when test='indexKeyword == "ㅍ"'>
and w.WRDDICTTL BETWEEN '파' AND '핗'
</when>
<when test='indexKeyword == "ㅎ"'>
and w.WRDDICTTL BETWEEN '하' AND '힣'
</when>
<!-- 알파벳 a ~ z에 대한 검색 -->
<when test='indexKeyword == "a"'>
and w.WRDDICTTL like "a%"
</when>
<when test='indexKeyword == "b"'>
and w.WRDDICTTL like "b%"
</when>
<when test='indexKeyword == "c"'>
and w.WRDDICTTL like "c%"
</when>
<when test='indexKeyword == "d"'>
and w.WRDDICTTL like "d%"
</when>
<when test='indexKeyword == "e"'>
and w.WRDDICTTL like "e%"
</when>
<when test='indexKeyword == "f"'>
and w.WRDDICTTL like "f%"
</when>
<when test='indexKeyword == "g"'>
and w.WRDDICTTL like "g%"
</when>
<when test='indexKeyword == "h"'>
and w.WRDDICTTL like "h%"
</when>
<when test='indexKeyword == "i"'>
and w.WRDDICTTL like "i%"
</when>
<when test='indexKeyword == "j"'>
and w.WRDDICTTL like "j%"
</when>
<when test='indexKeyword == "k"'>
and w.WRDDICTTL like "k%"
</when>
<when test='indexKeyword == "l"'>
and w.WRDDICTTL like "l%"
</when>
<when test='indexKeyword == "m"'>
and w.WRDDICTTL like "m%"
</when>
<when test='indexKeyword == "n"'>
and w.WRDDICTTL like "n%"
</when>
<when test='indexKeyword == "o"'>
and w.WRDDICTTL like "o%"
</when>
<when test='indexKeyword == "p"'>
and w.WRDDICTTL like "p%"
</when>
<when test='indexKeyword == "q"'>
and w.WRDDICTTL like "q%"
</when>
<when test='indexKeyword == "r"'>
and w.WRDDICTTL like "r%"
</when>
<when test='indexKeyword == "s"'>
and w.WRDDICTTL like "s%"
</when>
<when test='indexKeyword == "t"'>
and w.WRDDICTTL like "t%"
</when>
<when test='indexKeyword == "u"'>
and w.WRDDICTTL like "u%"
</when>
<when test='indexKeyword == "v"'>
and w.WRDDICTTL like "v%"
</when>
<when test='indexKeyword == "w"'>
and w.WRDDICTTL like "w%"
</when>
<when test='indexKeyword == "x"'>
and w.WRDDICTTL like "x%"
</when>
<when test='indexKeyword == "y"'>
and w.WRDDICTTL like "y%"
</when>
<when test='indexKeyword == "z"'>
and w.WRDDICTTL like "z%"
</when>
</choose>
</if>
<!-- 카테고리 조건 -->
<if test="category != null and category != ''">
and w.WRDDICCAT = #{category}
</if>
</sql>
<select id="getWordList" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
select
w.WRDDICSEQ,
w.WRDDICCAT,
w.WRDDICTTL,
w.WRDDICCON,
c.CMNCODNAM category,
m1.MEMBERPRF REGPRF,
m1.MEMBERNAM REGNAME,
cr.CMNCODNAM REGCOLOR,
w.WRDDICRDT REGRDT,
m2.MEMBERPRF UPDPRF,
m2.MEMBERNAM UPDNAME,
cu.CMNCODNAM UPDCOLOR,
w.WRDDICUDT UPDUDT
from
worddicty w
left join
commoncod c
on
w.WRDDICCAT = c.CMNCODVAL
left join
netmember m1
on
w.WRDDICREG = m1.MEMBERSEQ
left join
commoncod cr
on
m1.MEMBERCOL = cr.CMNCODVAL -- 등록자 색상
left join
netmember m2
on
w.WRDDICUPD = m2.MEMBERSEQ
left join
commoncod cu
on
m2.MEMBERCOL = cu.CMNCODVAL -- 수정자 색상
where
1=1
<include refid="searchConditions"/>
order by w.WRDDICRDT desc
</select>
<select id="getTotal" parameterType="map" >
select count(*) from worddicty w
where 1=1
<include refid="searchConditions"/>
</select>
<insert id="insertWord" parameterType="map">
insert into worddicty
(
@ -72,4 +229,11 @@
where
WRDDICSEQ = #{WRDDICSEQ}
</update>
<select id="getWordDetail" parameterType="map" resultType="io.company.localhost.common.dto.MapDto">
select *
from
worddicty
where
WRDDICSEQ = #{WRDDICSEQ}
</select>
</mapper>