Преглед изворни кода

알람 및 알람수신자 추가. 시스템알람관리 기능 추가

gagamel пре 5 година
родитељ
комит
b8ad7ae612

+ 297 - 237
style24.admin/src/main/java/com/style24/admin/biz/dao/TsaSystemDao.java

@@ -1,237 +1,297 @@
-package com.style24.admin.biz.dao;
-
-import java.util.Collection;
-
-import com.style24.core.support.annotation.ShopDs;
-import com.style24.persistence.domain.CommonCode;
-import com.style24.persistence.domain.Menu;
-import com.style24.persistence.domain.MenuAccessHst;
-import com.style24.persistence.domain.MenuRole;
-import com.style24.persistence.domain.SampleFile;
-import com.style24.persistence.domain.User;
-import com.style24.persistence.domain.UserHst;
-import com.style24.persistence.domain.UserMenu;
-
-/**
- * 시스템 Dao
- *
- * @author gagamel
- * @since 2020. 10. 7
- */
-@ShopDs
-public interface TsaSystemDao {
-
-	/**
-	 * 사용자 목록
-	 * @param user - 사용자 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	Collection<User> getUserList(User user);
-
-	/**
-	 * 사용자 정보 조회
-	 * @param userNo - 사용자번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	User getUser(Integer userNo);
-
-	/**
-	 * 사용자 삭제
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void deleteUser(User user);
-
-	/**
-	 * 사용자ID 건수 조회
-	 * @param userId - 사용자ID
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	int getUserIdCount(String userId);
-
-	/**
-	 * 사용자 정보 저장 처리
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void saveUser(User user);
-
-	/**
-	 * 임시비밀번호 조회
-	 * @param length - 비밀번호 자릿수
-	 * @return
-	 * @since 2020. 10. 7
-	 */
-	String getTemporaryPassword(int length);
-
-	/**
-	 * 사용자 비밀번호 수정
-	 * @param user - 사용자 정보
-	 * @since 2020. 10. 7
-	 */
-	void updateUserPassword(User user);
-
-	/**
-	 * 사용자 메뉴 목록
-	 * @param userNo - 사용자번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	Collection<UserMenu> getUserMenuList(Integer userNo);
-
-	/**
-	 * 사용자정보변경이력 생성
-	 * @param userHst - 사용자이력 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void createUserInfoChangeHistory(UserHst userHst);
-
-	/**
-	 * 메뉴 목록
-	 * @param menu - 메뉴정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	Collection<Menu> getMenuList(Menu menu);
-
-	/**
-	 * 메뉴 등록/수정
-	 * @param menu - 메뉴 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void saveMenu(Menu menu);
-
-	/**
-	 * 메뉴권한 삭제
-	 * @param menuId - 메뉴ID
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void deleteMenuRole(String menuId);
-
-	/**
-	 * 메뉴권한 생성
-	 * @param menuRole - 메뉴권한 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void createMenuRole(MenuRole menuRole);
-
-	/**
-	 * 전체 사용자 메뉴 삭제
-	 * @param menuRole - 메뉴권한 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void deleteAllUserMenu(MenuRole menuRole);
-
-	/**
-	 * 전체 사용자 메뉴 생성
-	 * @param menuRole - 메뉴권한 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void createAllUserMenu(MenuRole menuRole);
-
-	/**
-	 * 사용자 전체 메뉴 삭제
-	 * @param userNo - 사용자번호
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void deleteUserAllMenu(Integer userNo);
-
-	/**
-	 * 사용자 전체 메뉴 생성
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void createUserAllMenu(User user);
-
-	/**
-	 * 사용자 메뉴 삭제
-	 * @param userMenu - 사용자 메뉴 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void deleteAdminUserMenu(UserMenu userMenu);
-
-	/**
-	 * 사용자 메뉴 생성
-	 * @param userMenu - 사용자 메뉴 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void createUserMenu(UserMenu userMenu);
-
-	/**
-	 * 공통코드 목록
-	 * @param commoncode - 공통코드 정보
-	 * @return 공통코드 목록
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	Collection<CommonCode> getCommonCodeList(CommonCode commoncode);
-
-	/**
-	 * 메뉴접속이력 생성
-	 * @param menuAccessHst - 메뉴접속 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void createMenuAccessHistory(MenuAccessHst menuAccessHst);
-
-	/**
-	 * 공통코드 등록/수정
-	 * @param commoncode - 공통코드 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void saveCommonCode(CommonCode commoncode);
-
-	/**
-	 * 공통코드 삭제
-	 * @param commoncode - 공통코드 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	void deleteCommonCode(CommonCode commoncode);
-
-	/**
-	 * 샘플파일 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	Collection<SampleFile> getSampleFileList();
-
-	/**
-	 * 샘플파일 등록
-	 * @param sampleFile - 샘플파일 정보
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	void createSampleFile(SampleFile sampleFile);
-
-	/**
-	 * 샘플파일 수정
-	 * @param sampleFile - 샘플파일 정보
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	void updateSampleFile(SampleFile sampleFile);
-
-}
+package com.style24.admin.biz.dao;
+
+import java.util.Collection;
+
+import com.style24.core.support.annotation.ShopDs;
+import com.style24.persistence.domain.Alarm;
+import com.style24.persistence.domain.AlarmReceiver;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.MenuAccessHst;
+import com.style24.persistence.domain.MenuRole;
+import com.style24.persistence.domain.SampleFile;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.UserHst;
+import com.style24.persistence.domain.UserMenu;
+
+/**
+ * 시스템 Dao
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@ShopDs
+public interface TsaSystemDao {
+
+	/**
+	 * 사용자 목록
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<User> getUserList(User user);
+
+	/**
+	 * 사용자 정보 조회
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	User getUser(Integer userNo);
+
+	/**
+	 * 사용자 삭제
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteUser(User user);
+
+	/**
+	 * 사용자ID 건수 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	int getUserIdCount(String userId);
+
+	/**
+	 * 사용자 정보 저장 처리
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void saveUser(User user);
+
+	/**
+	 * 임시비밀번호 조회
+	 * @param length - 비밀번호 자릿수
+	 * @return
+	 * @since 2020. 10. 7
+	 */
+	String getTemporaryPassword(int length);
+
+	/**
+	 * 사용자 비밀번호 수정
+	 * @param user - 사용자 정보
+	 * @since 2020. 10. 7
+	 */
+	void updateUserPassword(User user);
+
+	/**
+	 * 사용자 메뉴 목록
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<UserMenu> getUserMenuList(Integer userNo);
+
+	/**
+	 * 사용자정보변경이력 생성
+	 * @param userHst - 사용자이력 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createUserInfoChangeHistory(UserHst userHst);
+
+	/**
+	 * 메뉴 목록
+	 * @param menu - 메뉴정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<Menu> getMenuList(Menu menu);
+
+	/**
+	 * 메뉴 등록/수정
+	 * @param menu - 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void saveMenu(Menu menu);
+
+	/**
+	 * 메뉴권한 삭제
+	 * @param menuId - 메뉴ID
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteMenuRole(String menuId);
+
+	/**
+	 * 메뉴권한 생성
+	 * @param menuRole - 메뉴권한 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createMenuRole(MenuRole menuRole);
+
+	/**
+	 * 전체 사용자 메뉴 삭제
+	 * @param menuRole - 메뉴권한 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteAllUserMenu(MenuRole menuRole);
+
+	/**
+	 * 전체 사용자 메뉴 생성
+	 * @param menuRole - 메뉴권한 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createAllUserMenu(MenuRole menuRole);
+
+	/**
+	 * 사용자 전체 메뉴 삭제
+	 * @param userNo - 사용자번호
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteUserAllMenu(Integer userNo);
+
+	/**
+	 * 사용자 전체 메뉴 생성
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createUserAllMenu(User user);
+
+	/**
+	 * 사용자 메뉴 삭제
+	 * @param userMenu - 사용자 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteAdminUserMenu(UserMenu userMenu);
+
+	/**
+	 * 사용자 메뉴 생성
+	 * @param userMenu - 사용자 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createUserMenu(UserMenu userMenu);
+
+	/**
+	 * 공통코드 목록
+	 * @param commoncode - 공통코드 정보
+	 * @return 공통코드 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	Collection<CommonCode> getCommonCodeList(CommonCode commoncode);
+
+	/**
+	 * 메뉴접속이력 생성
+	 * @param menuAccessHst - 메뉴접속 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void createMenuAccessHistory(MenuAccessHst menuAccessHst);
+
+	/**
+	 * 공통코드 등록/수정
+	 * @param commoncode - 공통코드 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void saveCommonCode(CommonCode commoncode);
+
+	/**
+	 * 공통코드 삭제
+	 * @param commoncode - 공통코드 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	void deleteCommonCode(CommonCode commoncode);
+
+	/**
+	 * 샘플파일 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	Collection<SampleFile> getSampleFileList();
+
+	/**
+	 * 샘플파일 등록
+	 * @param sampleFile - 샘플파일 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	void createSampleFile(SampleFile sampleFile);
+
+	/**
+	 * 샘플파일 수정
+	 * @param sampleFile - 샘플파일 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	void updateSampleFile(SampleFile sampleFile);
+
+	/**
+	 * 알람 목록
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	Collection<Alarm> getAlarmList(Alarm alarm);
+
+	/**
+	 * 알람 저장
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void createAlarm(Alarm alarm);
+
+	/**
+	 * 알람 수정
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void updateAlarm(Alarm alarm);
+
+	/**
+	 * 알람 삭제
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void deleteAlarm(Alarm alarm);
+
+	/**
+	 * 알람수신자 목록
+	 * @param alarmId - 알람ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	Collection<AlarmReceiver> getAlarmReceiverList(String alarmId);
+
+	/**
+	 * 알람수신자 저장
+	 * @param alarmReceiver - 알람수신자 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void saveAlarmReceiver(AlarmReceiver alarmReceiver);
+
+	/**
+	 * 알람수신자 삭제
+	 * @param alarmReceiver - 알람수신자 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	void deleteAlarmReceiver(AlarmReceiver alarmReceiver);
+
+}

+ 495 - 417
style24.admin/src/main/java/com/style24/admin/biz/service/TsaSystemService.java

@@ -1,417 +1,495 @@
-package com.style24.admin.biz.service;
-
-import java.util.Collection;
-
-import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
-
-import com.style24.admin.biz.dao.TsaSystemDao;
-import com.style24.admin.support.security.session.TsaSession;
-import com.style24.core.support.message.TscMessageByLocale;
-import com.style24.persistence.domain.CommonCode;
-import com.style24.persistence.domain.Menu;
-import com.style24.persistence.domain.MenuRole;
-import com.style24.persistence.domain.SampleFile;
-import com.style24.persistence.domain.User;
-import com.style24.persistence.domain.UserHst;
-import com.style24.persistence.domain.UserMenu;
-
-import lombok.extern.slf4j.Slf4j;
-
-/**
- * 시스템 Service
- *
- * @author gagamel
- * @since 2020. 10. 7
- */
-@Service
-@Slf4j
-public class TsaSystemService {
-
-	@Autowired
-	private TscMessageByLocale message;
-
-	@Autowired
-	private TsaSystemDao systemDao;
-
-	/**
-	 * 사용자 목록
-	 * @param user - 사용자 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public Collection<User> getUserList(User user) {
-		return systemDao.getUserList(user);
-	}
-
-	/**
-	 * 사용자 목록 삭제 처리
-	 * @param userList - 사용자 목록
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void deleteUserList(Collection<User> userList) {
-		for (User user : userList) {
-			user.setUpdNo(TsaSession.getInfo().getUserNo());
-			systemDao.deleteUser(user);
-			this.deleteUserAccount(user); // 계정말소
-		}
-	}
-
-	/**
-	 * 사용자 정보 조회
-	 * @param userNo - 사용자번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public User getUser(Integer userNo) {
-		return systemDao.getUser(userNo);
-	}
-
-	/**
-	 * 사용자ID 건수 조회
-	 * @param userId - 사용자ID
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public int getUserIdCount(String userId) {
-		return systemDao.getUserIdCount(userId);
-	}
-
-	/**
-	 * 사용자 정보 저장 처리
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void saveUser(User user) {
-		user.setRegNo(TsaSession.getInfo().getUserNo());
-		user.setUpdNo(TsaSession.getInfo().getUserNo());
-
-		// 사용자 저장 처리
-		systemDao.saveUser(user);
-
-		// 등록된 사용자번호 값 가져오기
-		Integer userNo = user.getUserNo();
-		log.info("userNo: {}", userNo);
-		user.setUserNo(userNo);
-
-		if (user.getMode().equals("N")) {
-			this.createUserAccount(user); // 계정생성
-		} else if (user.getMode().equals("U")) {
-			if (user.getUseYn().equals("N")) {
-				this.deleteUserAccount(user); // 계정말소
-			} else {
-				this.restoreUserAccount(user); // 계정복원
-			}
-		}
-
-		// 권한이 변경되었으면
-		if (user.getRoleChangeYn().equals("Y")) {
-			// 사용자 전체메뉴 삭제
-			systemDao.deleteUserAllMenu(user.getUserNo());
-
-			// 사용자 전체메뉴 생성
-			systemDao.createUserAllMenu(user);
-
-			if (user.getMode().equals("U")) {
-				this.createUserRoleChange(user); // 권한변경
-			}
-		}
-	}
-
-	/**
-	 * 사용자정보변경이력 생성 - 계정생성
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 8
-	 */
-	private void createUserAccount(User user) {
-		UserHst userHst = new UserHst();
-		userHst.setUserNo(user.getUserNo());
-		userHst.setChgGb("G049_10"); // 계정생성
-		userHst.setRegNo(TsaSession.getInfo().getUserNo());
-		systemDao.createUserInfoChangeHistory(userHst);
-	}
-
-	/**
-	 * 사용자정보변경이력 생성 - 계정말소
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 8
-	 */
-	private void deleteUserAccount(User user) {
-		UserHst userHst = new UserHst();
-		userHst.setUserNo(user.getUserNo());
-		userHst.setChgGb("G049_11"); // 계정말소
-		userHst.setRegNo(TsaSession.getInfo().getUserNo());
-		systemDao.createUserInfoChangeHistory(userHst);
-	}
-
-	/**
-	 * 사용자정보변경이력 생성 - 계정복원
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 8
-	 */
-	private void restoreUserAccount(User user) {
-		UserHst userHst = new UserHst();
-		userHst.setUserNo(user.getUserNo());
-		userHst.setChgGb("G049_12"); // 계정복원
-		userHst.setRegNo(TsaSession.getInfo().getUserNo());
-		systemDao.createUserInfoChangeHistory(userHst);
-	}
-
-	/**
-	 * 사용자정보변경이력 생성 - 권한변경
-	 * @param user - 사용자 정보
-	 * @author gagamel
-	 * @since 2020. 10. 8
-	 */
-	private void createUserRoleChange(User user) {
-		UserHst userHst = new UserHst();
-		userHst.setUserNo(user.getUserNo());
-		userHst.setChgGb("G049_20"); // 권한변경
-		userHst.setOrgRoleCd(TsaSession.getInfo().getRoleCd());
-		userHst.setRoleCd(user.getRoleCd());
-		userHst.setRegNo(TsaSession.getInfo().getUserNo());
-		systemDao.createUserInfoChangeHistory(userHst);
-	}
-
-	/**
-	 * 임시비밀번호 조회
-	 * @param length - 비밀번호 자릿수
-	 * @return 임시비밀번호
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public String getTemporaryPassword(int length) {
-		return systemDao.getTemporaryPassword(length);
-	}
-
-	/**
-	 * 사용자 비밀번호 수정
-	 * @param user - 사용자 정보
-	 * @since 2020. 10. 7
-	 */
-	public void updateUserPassword(User user) {
-		systemDao.updateUserPassword(user);
-
-		// 사용자정보변경이력 생성 - 비밀번호변경
-		UserHst userHst = new UserHst();
-		userHst.setUserNo(user.getUserNo());
-		userHst.setChgGb("G049_30"); // 비밀번호변경
-		userHst.setRegNo(TsaSession.getInfo().getUserNo());
-		systemDao.createUserInfoChangeHistory(userHst);
-	}
-
-	/**
-	 * 사용자 메뉴 목록
-	 * @param userNo - 사용자번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public Collection<UserMenu> getUserMenuList(Integer userNo) {
-		return systemDao.getUserMenuList(userNo);
-	}
-
-	/**
-	 * 사용자 메뉴 목록 저장 처리
-	 * @param userMenuList - 사용자 메뉴 목록
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void saveUserMenuList(Collection<UserMenu> userMenuList) {
-		if (userMenuList == null || userMenuList.isEmpty())
-			throw new IllegalStateException(message.getMessage("FAIL_1001"));
-
-		int cnt = 0;
-
-		for (UserMenu adminMenu : userMenuList) {
-			if (cnt++ == 0) {
-				// 사용자 전체메뉴 삭제
-				systemDao.deleteUserAllMenu(adminMenu.getUserNo());
-			}
-
-			adminMenu.setRegNo(TsaSession.getInfo().getUserNo());
-			adminMenu.setUpdNo(TsaSession.getInfo().getUserNo());
-
-			// 사용자 메뉴 생성
-			systemDao.createUserMenu(adminMenu);
-		}
-	}
-
-	/**
-	 * 메뉴 목록
-	 * @param pmenuId - 상위메뉴ID
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public Collection<Menu> getMenuList(String pmenuId) {
-		Menu menu = new Menu();
-		menu.setPmenuId(pmenuId);
-		return systemDao.getMenuList(menu);
-	}
-
-	/**
-	 * 메뉴 목록 저장 처리
-	 * @param menuList - 메뉴 목록
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void saveMenuList(Collection<Menu> menuList) {
-		if (menuList == null || menuList.isEmpty())
-			throw new IllegalStateException(message.getMessage("FAIL_1001"));
-
-		for (Menu menu : menuList) {
-			menu.setRegNo(TsaSession.getInfo().getUserNo());
-			menu.setUpdNo(TsaSession.getInfo().getUserNo());
-			systemDao.saveMenu(menu);
-		}
-	}
-
-	/**
-	 * 메뉴 등록/수정 및 메뉴권한 생성
-	 * @param menu - 메뉴 정보
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-//	@CacheEvict(value = "menu", allEntries = true)
-	public void saveMenu(Menu menu) {
-		menu.setRegNo(TsaSession.getInfo().getUserNo());
-		menu.setUpdNo(TsaSession.getInfo().getUserNo());
-
-		// 메뉴 등록/수정
-		systemDao.saveMenu(menu);
-
-		if (StringUtils.isNotBlank(menu.getRoleCds())) {
-			// 메뉴권한 삭제
-			systemDao.deleteMenuRole(menu.getMenuId());
-
-			String[] roleCds = menu.getRoleCds().split(",");
-
-			for (String roleCd : roleCds) {
-				MenuRole menuRole = new MenuRole();
-				menuRole.setRoleCd(roleCd);
-				menuRole.setMenuId(menu.getMenuId());
-				menuRole.setRegNo(TsaSession.getInfo().getUserNo());
-				menuRole.setUpdNo(TsaSession.getInfo().getUserNo());
-
-				// 메뉴권한 생성
-				systemDao.createMenuRole(menuRole);
-
-				// 전체 어드민사용자 메뉴 생성
-				systemDao.deleteAllUserMenu(menuRole);
-
-				// 전체 어드민사용자 메뉴 생성
-				systemDao.createAllUserMenu(menuRole);
-			}
-		}
-	}
-
-	/**
-	 * 공통코드 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public Collection<CommonCode> getCommonCodeList() {
-		return this.getCommonCodeList(new CommonCode());
-	}
-
-	/**
-	 * 공통코드 목록
-	 * @param commoncode - 공통코드 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	public Collection<CommonCode> getCommonCodeList(CommonCode commoncode) {
-		return systemDao.getCommonCodeList(commoncode);
-	}
-
-	/**
-	 * 공통코드 목록 저장 처리
-	 * @param dataList - 공통코드 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void saveCommonCodeList(Collection<CommonCode> dataList) {
-		if (dataList == null || dataList.isEmpty())
-			throw new IllegalStateException(message.getMessage("FAIL_1001"));
-
-		for (CommonCode commoncode : dataList) {
-			commoncode.setRegNo(TsaSession.getInfo().getUserNo());
-			commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
-			commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
-			systemDao.saveCommonCode(commoncode);
-		}
-	}
-
-	/**
-	 * 공통코드 저장 처리
-	 * @param commoncode - 공통코드 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void saveCommonCode(CommonCode commoncode) {
-		commoncode.setRegNo(TsaSession.getInfo().getUserNo());
-		commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
-		commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
-		systemDao.saveCommonCode(commoncode);
-	}
-
-	/**
-	 * 공통코드 삭제처리
-	 * @param commoncode - 공통코드 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@Transactional("shopTxnManager")
-	public void deleteCommonCode(CommonCode commoncode) {
-		systemDao.deleteCommonCode(commoncode);
-	}
-
-	/**
-	 * 샘플파일 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	public Collection<SampleFile> getSampleFileList() {
-		return systemDao.getSampleFileList();
-	}
-
-	/**
-	 * 샘플파일 등록/수정
-	 * @param sampleFile - 샘플파일 정보
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	@Transactional("shopTxnManager")
-	public void saveSampleFile(SampleFile sampleFile) {
-		if (sampleFile.getMode().equals("N")) {
-			systemDao.createSampleFile(sampleFile);
-		} else {
-			systemDao.updateSampleFile(sampleFile);
-		}
-	}
-
-}
+package com.style24.admin.biz.service;
+
+import java.util.Collection;
+
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import com.style24.admin.biz.dao.TsaSystemDao;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Alarm;
+import com.style24.persistence.domain.AlarmReceiver;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.MenuRole;
+import com.style24.persistence.domain.SampleFile;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.UserHst;
+import com.style24.persistence.domain.UserMenu;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * 시스템 Service
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@Service
+@Slf4j
+public class TsaSystemService {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private TsaSystemDao systemDao;
+
+	/**
+	 * 사용자 목록
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<User> getUserList(User user) {
+		return systemDao.getUserList(user);
+	}
+
+	/**
+	 * 사용자 목록 삭제 처리
+	 * @param userList - 사용자 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteUserList(Collection<User> userList) {
+		for (User user : userList) {
+			user.setUpdNo(TsaSession.getInfo().getUserNo());
+			systemDao.deleteUser(user);
+			this.deleteUserAccount(user); // 계정말소
+		}
+	}
+
+	/**
+	 * 사용자 정보 조회
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public User getUser(Integer userNo) {
+		return systemDao.getUser(userNo);
+	}
+
+	/**
+	 * 사용자ID 건수 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public int getUserIdCount(String userId) {
+		return systemDao.getUserIdCount(userId);
+	}
+
+	/**
+	 * 사용자 정보 저장 처리
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveUser(User user) {
+		user.setRegNo(TsaSession.getInfo().getUserNo());
+		user.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 사용자 저장 처리
+		systemDao.saveUser(user);
+
+		// 등록된 사용자번호 값 가져오기
+		Integer userNo = user.getUserNo();
+		log.info("userNo: {}", userNo);
+		user.setUserNo(userNo);
+
+		if (user.getMode().equals("N")) {
+			this.createUserAccount(user); // 계정생성
+		} else if (user.getMode().equals("U")) {
+			if (user.getUseYn().equals("N")) {
+				this.deleteUserAccount(user); // 계정말소
+			} else {
+				this.restoreUserAccount(user); // 계정복원
+			}
+		}
+
+		// 권한이 변경되었으면
+		if (user.getRoleChangeYn().equals("Y")) {
+			// 사용자 전체메뉴 삭제
+			systemDao.deleteUserAllMenu(user.getUserNo());
+
+			// 사용자 전체메뉴 생성
+			systemDao.createUserAllMenu(user);
+
+			if (user.getMode().equals("U")) {
+				this.createUserRoleChange(user); // 권한변경
+			}
+		}
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 계정생성
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void createUserAccount(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_10"); // 계정생성
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 계정말소
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void deleteUserAccount(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_11"); // 계정말소
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 계정복원
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void restoreUserAccount(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_12"); // 계정복원
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자정보변경이력 생성 - 권한변경
+	 * @param user - 사용자 정보
+	 * @author gagamel
+	 * @since 2020. 10. 8
+	 */
+	private void createUserRoleChange(User user) {
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_20"); // 권한변경
+		userHst.setOrgRoleCd(TsaSession.getInfo().getRoleCd());
+		userHst.setRoleCd(user.getRoleCd());
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 임시비밀번호 조회
+	 * @param length - 비밀번호 자릿수
+	 * @return 임시비밀번호
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public String getTemporaryPassword(int length) {
+		return systemDao.getTemporaryPassword(length);
+	}
+
+	/**
+	 * 사용자 비밀번호 수정
+	 * @param user - 사용자 정보
+	 * @since 2020. 10. 7
+	 */
+	public void updateUserPassword(User user) {
+		systemDao.updateUserPassword(user);
+
+		// 사용자정보변경이력 생성 - 비밀번호변경
+		UserHst userHst = new UserHst();
+		userHst.setUserNo(user.getUserNo());
+		userHst.setChgGb("G049_30"); // 비밀번호변경
+		userHst.setRegNo(TsaSession.getInfo().getUserNo());
+		systemDao.createUserInfoChangeHistory(userHst);
+	}
+
+	/**
+	 * 사용자 메뉴 목록
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<UserMenu> getUserMenuList(Integer userNo) {
+		return systemDao.getUserMenuList(userNo);
+	}
+
+	/**
+	 * 사용자 메뉴 목록 저장 처리
+	 * @param userMenuList - 사용자 메뉴 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveUserMenuList(Collection<UserMenu> userMenuList) {
+		if (userMenuList == null || userMenuList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		int cnt = 0;
+
+		for (UserMenu adminMenu : userMenuList) {
+			if (cnt++ == 0) {
+				// 사용자 전체메뉴 삭제
+				systemDao.deleteUserAllMenu(adminMenu.getUserNo());
+			}
+
+			adminMenu.setRegNo(TsaSession.getInfo().getUserNo());
+			adminMenu.setUpdNo(TsaSession.getInfo().getUserNo());
+
+			// 사용자 메뉴 생성
+			systemDao.createUserMenu(adminMenu);
+		}
+	}
+
+	/**
+	 * 메뉴 목록
+	 * @param pmenuId - 상위메뉴ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<Menu> getMenuList(String pmenuId) {
+		Menu menu = new Menu();
+		menu.setPmenuId(pmenuId);
+		return systemDao.getMenuList(menu);
+	}
+
+	/**
+	 * 메뉴 목록 저장 처리
+	 * @param menuList - 메뉴 목록
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveMenuList(Collection<Menu> menuList) {
+		if (menuList == null || menuList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		for (Menu menu : menuList) {
+			menu.setRegNo(TsaSession.getInfo().getUserNo());
+			menu.setUpdNo(TsaSession.getInfo().getUserNo());
+			systemDao.saveMenu(menu);
+		}
+	}
+
+	/**
+	 * 메뉴 등록/수정 및 메뉴권한 생성
+	 * @param menu - 메뉴 정보
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+//	@CacheEvict(value = "menu", allEntries = true)
+	public void saveMenu(Menu menu) {
+		menu.setRegNo(TsaSession.getInfo().getUserNo());
+		menu.setUpdNo(TsaSession.getInfo().getUserNo());
+
+		// 메뉴 등록/수정
+		systemDao.saveMenu(menu);
+
+		if (StringUtils.isNotBlank(menu.getRoleCds())) {
+			// 메뉴권한 삭제
+			systemDao.deleteMenuRole(menu.getMenuId());
+
+			String[] roleCds = menu.getRoleCds().split(",");
+
+			for (String roleCd : roleCds) {
+				MenuRole menuRole = new MenuRole();
+				menuRole.setRoleCd(roleCd);
+				menuRole.setMenuId(menu.getMenuId());
+				menuRole.setRegNo(TsaSession.getInfo().getUserNo());
+				menuRole.setUpdNo(TsaSession.getInfo().getUserNo());
+
+				// 메뉴권한 생성
+				systemDao.createMenuRole(menuRole);
+
+				// 전체 어드민사용자 메뉴 생성
+				systemDao.deleteAllUserMenu(menuRole);
+
+				// 전체 어드민사용자 메뉴 생성
+				systemDao.createAllUserMenu(menuRole);
+			}
+		}
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList() {
+		return this.getCommonCodeList(new CommonCode());
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	public Collection<CommonCode> getCommonCodeList(CommonCode commoncode) {
+		return systemDao.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록 저장 처리
+	 * @param dataList - 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveCommonCodeList(Collection<CommonCode> dataList) {
+		if (dataList == null || dataList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		for (CommonCode commoncode : dataList) {
+			commoncode.setRegNo(TsaSession.getInfo().getUserNo());
+			commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
+			commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
+			systemDao.saveCommonCode(commoncode);
+		}
+	}
+
+	/**
+	 * 공통코드 저장 처리
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void saveCommonCode(CommonCode commoncode) {
+		commoncode.setRegNo(TsaSession.getInfo().getUserNo());
+		commoncode.setUpdNo(TsaSession.getInfo().getUserNo());
+		commoncode.setCdNm(commoncode.getCdNm().replace("&gt;", ">"));
+		systemDao.saveCommonCode(commoncode);
+	}
+
+	/**
+	 * 공통코드 삭제처리
+	 * @param commoncode - 공통코드 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteCommonCode(CommonCode commoncode) {
+		systemDao.deleteCommonCode(commoncode);
+	}
+
+	/**
+	 * 샘플파일 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	public Collection<SampleFile> getSampleFileList() {
+		return systemDao.getSampleFileList();
+	}
+
+	/**
+	 * 샘플파일 등록/수정
+	 * @param sampleFile - 샘플파일 정보
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@Transactional("shopTxnManager")
+	public void saveSampleFile(SampleFile sampleFile) {
+		if (sampleFile.getMode().equals("N")) {
+			systemDao.createSampleFile(sampleFile);
+		} else {
+			systemDao.updateSampleFile(sampleFile);
+		}
+	}
+
+	/**
+	 * 알람 목록
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	public Collection<Alarm> getAlarmList(Alarm alarm) {
+		return systemDao.getAlarmList(alarm);
+	}
+
+	/**
+	 * 알람 저장
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAlarm(Alarm alarm) {
+		if (alarm.getMode().equals("N")) {
+			systemDao.createAlarm(alarm);
+		} else {
+			systemDao.updateAlarm(alarm);
+		}
+	}
+
+	/**
+	 * 알람 삭제
+	 * @param alarm - 알람 정보
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteAlarm(Alarm alarm) {
+		systemDao.deleteAlarm(alarm);
+	}
+
+	/**
+	 * 알람수신자 목록
+	 * @param alarmId - 알람ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	public Collection<AlarmReceiver> getAlarmReceiverList(String alarmId) {
+		return systemDao.getAlarmReceiverList(alarmId);
+	}
+
+	/**
+	 * 알람수신자 목록 저장
+	 * @param alarmReceiverList - 알람수신자 목록
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void saveAlarmReceiverList(Collection<AlarmReceiver> alarmReceiverList) {
+		for (AlarmReceiver alarmReceiver : alarmReceiverList) {
+			alarmReceiver.setRegNo(TsaSession.getInfo().getUserNo());
+			alarmReceiver.setUpdNo(TsaSession.getInfo().getUserNo());
+			systemDao.saveAlarmReceiver(alarmReceiver);
+		}
+	}
+
+	/**
+	 * 알람수신자 목록 삭제
+	 * @param alarmReceiverList - 알람수신자 목록
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@Transactional("shopTxnManager")
+	public void deleteAlarmReceiverList(Collection<AlarmReceiver> alarmReceiverList) {
+		for (AlarmReceiver alarmReceiver : alarmReceiverList) {
+			systemDao.deleteAlarmReceiver(alarmReceiver);
+		}
+	}
+
+}

+ 523 - 422
style24.admin/src/main/java/com/style24/admin/biz/web/TsaSystemController.java

@@ -1,422 +1,523 @@
-package com.style24.admin.biz.web;
-
-import java.util.Collection;
-
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.beans.factory.annotation.Value;
-import org.springframework.core.env.Environment;
-import org.springframework.stereotype.Controller;
-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.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RequestParam;
-import org.springframework.web.bind.annotation.ResponseBody;
-import org.springframework.web.servlet.ModelAndView;
-
-import com.style24.admin.biz.service.TsaRendererService;
-import com.style24.admin.biz.service.TsaSystemService;
-import com.style24.admin.support.controller.TsaBaseController;
-import com.style24.admin.support.security.session.TsaSession;
-import com.style24.core.support.message.TscMessageByLocale;
-import com.style24.persistence.domain.CommonCode;
-import com.style24.persistence.domain.Menu;
-import com.style24.persistence.domain.SampleFile;
-import com.style24.persistence.domain.User;
-import com.style24.persistence.domain.UserMenu;
-
-import lombok.extern.slf4j.Slf4j;
-
-import com.gagaframework.web.core.security.GagaPasswordEncoder;
-import com.gagaframework.web.rest.server.GagaResponse;
-
-/**
- * 운영관리 Controller
- *
- * @author gagamel
- * @since 2020. 10. 7
- */
-@Controller
-@RequestMapping("/system")
-@Slf4j
-public class TsaSystemController extends TsaBaseController {
-
-	@Autowired
-	private TscMessageByLocale message;
-
-	@Autowired
-	private Environment env;
-
-	@Autowired
-	private TsaSystemService systemService;
-
-	@Autowired
-	private TsaRendererService rendererService;
-
-	@Autowired
-	private GagaPasswordEncoder passwordEncoder;
-
-	@Value("${upload.default.target.path}")
-	private String uploadTargetPath;
-
-	/**
-	 * 사용자관리 화면
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/user/form")
-	public ModelAndView userForm() {
-		ModelAndView mav = new ModelAndView();
-
-		// 공급업체 콤보박스 목록
-		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
-
-		// 권한 콤보박스 목록
-		mav.addObject("roleList", rendererService.getCommonCodeList("G001"));
-
-		mav.setViewName("system/UserForm");
-
-		return mav;
-	}
-
-	/**
-	 * 사용자 목록
-	 * @param user - 사용자 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/user/list")
-	@ResponseBody
-	public Collection<User> getUserList(@RequestBody User user) {
-		return systemService.getUserList(user);
-	}
-
-	/**
-	 * 사용자 목록 삭제 처리
-	 * @param userList - 사용자 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/user/list/delete")
-	@ResponseBody
-	public GagaResponse deleteUserList(@RequestBody Collection<User> userList) {
-		if (userList == null || userList.isEmpty())
-			throw new IllegalStateException(message.getMessage("FAIL_1001"));
-
-		systemService.deleteUserList(userList);
-
-		return super.ok(message.getMessage("SUCC_0003"));
-	}
-
-	/**
-	 * 사용자 정보 조회
-	 * @param mode   - 모드(N:신규, U:상세/수정, C:복사)
-	 * @param userNo - 사용자번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/user/info/form")
-	public ModelAndView getUser(@RequestParam(value = "mode") String mode,
-		@RequestParam(value = "userNo", required = false) Integer userNo) {
-		ModelAndView mav = new ModelAndView();
-
-		// 권한 콤보박스 목록
-		if (!TsaSession.getInfo().getRoleCd().equals("0000")) {
-			mav.addObject("roleList", rendererService.getCommonCodeList("G001", "Y", new String[] {"0000"}));
-		} else {
-			mav.addObject("roleList", rendererService.getAvailCommonCodeList("G001"));
-		}
-
-		// 공급업체 콤보박스 목록
-		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
-
-		// 외부몰벤더 콤보박스 목록
-		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
-
-		if (mode.equals("U")) {
-			// 어드민사용자정보
-			mav.addObject("userInfo", systemService.getUser(userNo));
-		} else {
-			mav.addObject("userInfo", new User());
-		}
-
-		mav.addObject("mode", mode);
-
-		mav.setViewName("system/UserDetailForm");
-
-		return mav;
-	}
-
-	/**
-	 * 사용자ID 조회
-	 * @param userId - 사용자ID
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/user/id/{userId}")
-	@ResponseBody
-	public int getUserIdCount(@PathVariable("userId") String userId) {
-		return systemService.getUserIdCount(userId);
-	}
-
-	/**
-	 * 사용자 저장 처리
-	 * @param user - 사용자 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/user/save")
-	@ResponseBody
-	public GagaResponse saveUser(@RequestBody User user) {
-		if (user.getMode().equals("N")) { // 신규등록
-			user.setPasswd(passwordEncoder.encode(user.getPasswd()));
-		}
-
-		systemService.saveUser(user);
-
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-	/**
-	 * 사용자 비밀번호 변경
-	 * @param user - 사용자 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/user/password/change")
-	@ResponseBody
-	public GagaResponse changePassword(@RequestBody User user) {
-		user.setPasswd(passwordEncoder.encode(user.getPasswd()));
-		user.setUpdNo(TsaSession.getInfo().getUserNo());
-		log.info("user: {}", user);
-
-		// 어드민사용자 비밀번호 수정
-		systemService.updateUserPassword(user);
-
-		return super.ok(message.getMessage("SUCC_0009"));
-	}
-
-	/**
-	 * 사용자 메뉴 관리 화면
-	 * @param userNo - 사용자번호
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/user/menu/{userNo}")
-	public ModelAndView getAdminUserMenu(@PathVariable("userNo") Integer userNo) {
-		ModelAndView mav = new ModelAndView();
-
-		// 사용자 메뉴 목록
-		mav.addObject("userMenuList", systemService.getUserMenuList(userNo));
-
-		mav.setViewName("system/UserMenuForm");
-
-		return mav;
-	}
-
-	/**
-	 * 사용자 메뉴 목록 저장 처리
-	 * @param menuList - 사용자 메뉴 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/user/menu/list/save")
-	@ResponseBody
-	public GagaResponse saveUserMenuList(@RequestBody Collection<UserMenu> menuList) {
-		systemService.saveUserMenuList(menuList);
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-	/**
-	 * 비밀번호 변경 팝업
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 30
-	 */
-	@GetMapping("/password/change/form")
-	public ModelAndView passwordChangeForm() {
-		ModelAndView mav = new ModelAndView();
-
-		mav.setViewName("system/PasswordChangeForm");
-
-		return mav;
-	}
-
-	/**
-	 * 메뉴관리 화면
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/menu/form")
-	public ModelAndView menuListForm() {
-		ModelAndView mav = new ModelAndView();
-
-		// 최상위메뉴 콤보박스 목록
-		mav.addObject("topMenuList", rendererService.getTopMenuList(""));
-
-		// 전체메뉴 콤보박스 목록
-		mav.addObject("allMenuList", rendererService.getAllMenuList());
-
-		// 권한 콤보박스 목록
-		mav.addObject("roleList", rendererService.getCommonCodeList("G001"));
-
-		mav.setViewName("system/MenuForm");
-
-		return mav;
-	}
-
-	/**
-	 * 메뉴 목록
-	 * @param pmenuId - 상위메뉴ID
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/menu/list")
-	@ResponseBody
-	public Collection<Menu> getMenuList(@RequestParam(value = "pmenuId", required = false) String pmenuId) {
-		return systemService.getMenuList(pmenuId);
-	}
-
-	/**
-	 * 메뉴 사용안함 처리
-	 * @param menuList - 메뉴 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/menu/list/save")
-	@ResponseBody
-	public GagaResponse saveMenuList(@RequestBody Collection<Menu> menuList) {
-		systemService.saveMenuList(menuList);
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-	/**
-	 * 메뉴 등록/수정 처리
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/menu/save")
-	@ResponseBody
-	public GagaResponse saveMenu(@RequestBody Menu menu) {
-		systemService.saveMenu(menu);
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-	/**
-	 * 공통코드관리 화면
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/commoncode/form")
-	public ModelAndView commoncodeListForm() {
-		ModelAndView mav = new ModelAndView();
-
-//		// 코드구분 콤보박스 목록
-//		mav.addObject("cdGbList", rendererService.getCommonCodeList("ROOT"));
-
-		mav.setViewName("system/CommoncodeForm");
-
-		return mav;
-	}
-
-	/**
-	 * 공통코드 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@GetMapping("/commoncode/list")
-	@ResponseBody
-	public Collection<CommonCode> getCommonCodeList(@RequestParam(value = "cdGb", required = false) String cdGb) {
-		CommonCode commoncode = new CommonCode();
-		commoncode.setCdGb(cdGb);
-		return systemService.getCommonCodeList(commoncode);
-	}
-
-	/**
-	 * 공통코드 목록 저장 처리
-	 * @param commonCodeList - 공통코드 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/commoncode/list/save")
-	@ResponseBody
-	public GagaResponse saveCommonCodeList(@RequestBody Collection<CommonCode> commonCodeList) {
-		systemService.saveCommonCodeList(commonCodeList);
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-	/**
-	 * 공통코드 저장 처리
-	 * @param commonCode - 공통코드 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 10. 7
-	 */
-	@PostMapping("/commoncode/save")
-	@ResponseBody
-	public GagaResponse saveCommonCode(@RequestBody CommonCode commonCode) {
-		systemService.saveCommonCode(commonCode);
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-	/**
-	 * 샘플양식관리 화면
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	@GetMapping("/sample/file/form")
-	public ModelAndView sampleFileForm() {
-		ModelAndView mav = new ModelAndView();
-
-		mav.setViewName("system/SampleFileForm");
-
-		return mav;
-	}
-
-	/**
-	 * 샘플파일 목록
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	@GetMapping("/sample/file/list")
-	@ResponseBody
-	public Collection<SampleFile> getSampleFileList() {
-		return systemService.getSampleFileList();
-	}
-
-	/**
-	 * 샘플파일 등록/수정 처리
-	 * @param sampleFile - 샘플파일 정보
-	 * @return
-	 * @author gagamel
-	 * @since 2020. 11. 3
-	 */
-	@PostMapping("/sample/file/save")
-	@ResponseBody
-	public GagaResponse saveSampleFile(@RequestBody SampleFile sampleFile) {
-		sampleFile.setRegNo(TsaSession.getInfo().getUserNo());
-		sampleFile.setUpdNo(TsaSession.getInfo().getUserNo());
-		systemService.saveSampleFile(sampleFile);
-		return super.ok(message.getMessage("SUCC_0001"));
-	}
-
-}
+package com.style24.admin.biz.web;
+
+import java.util.Collection;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.env.Environment;
+import org.springframework.stereotype.Controller;
+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.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.ResponseBody;
+import org.springframework.web.servlet.ModelAndView;
+
+import com.style24.admin.biz.service.TsaRendererService;
+import com.style24.admin.biz.service.TsaSystemService;
+import com.style24.admin.support.controller.TsaBaseController;
+import com.style24.admin.support.security.session.TsaSession;
+import com.style24.core.support.message.TscMessageByLocale;
+import com.style24.persistence.domain.Alarm;
+import com.style24.persistence.domain.AlarmReceiver;
+import com.style24.persistence.domain.CommonCode;
+import com.style24.persistence.domain.Menu;
+import com.style24.persistence.domain.SampleFile;
+import com.style24.persistence.domain.User;
+import com.style24.persistence.domain.UserMenu;
+
+import lombok.extern.slf4j.Slf4j;
+
+import com.gagaframework.web.core.security.GagaPasswordEncoder;
+import com.gagaframework.web.rest.server.GagaResponse;
+
+/**
+ * 운영관리 Controller
+ *
+ * @author gagamel
+ * @since 2020. 10. 7
+ */
+@Controller
+@RequestMapping("/system")
+@Slf4j
+public class TsaSystemController extends TsaBaseController {
+
+	@Autowired
+	private TscMessageByLocale message;
+
+	@Autowired
+	private Environment env;
+
+	@Autowired
+	private TsaSystemService systemService;
+
+	@Autowired
+	private TsaRendererService rendererService;
+
+	@Autowired
+	private GagaPasswordEncoder passwordEncoder;
+
+	@Value("${upload.default.target.path}")
+	private String uploadTargetPath;
+
+	/**
+	 * 사용자관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/form")
+	public ModelAndView userForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 공급업체 콤보박스 목록
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 권한 콤보박스 목록
+		mav.addObject("roleList", rendererService.getCommonCodeList("G001"));
+
+		mav.setViewName("system/UserForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사용자 목록
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/list")
+	@ResponseBody
+	public Collection<User> getUserList(@RequestBody User user) {
+		return systemService.getUserList(user);
+	}
+
+	/**
+	 * 사용자 목록 삭제 처리
+	 * @param userList - 사용자 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/list/delete")
+	@ResponseBody
+	public GagaResponse deleteUserList(@RequestBody Collection<User> userList) {
+		if (userList == null || userList.isEmpty())
+			throw new IllegalStateException(message.getMessage("FAIL_1001"));
+
+		systemService.deleteUserList(userList);
+
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 사용자 정보 조회
+	 * @param mode   - 모드(N:신규, U:상세/수정, C:복사)
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/info/form")
+	public ModelAndView getUser(@RequestParam(value = "mode") String mode,
+		@RequestParam(value = "userNo", required = false) Integer userNo) {
+		ModelAndView mav = new ModelAndView();
+
+		// 권한 콤보박스 목록
+		if (!TsaSession.getInfo().getRoleCd().equals("0000")) {
+			mav.addObject("roleList", rendererService.getCommonCodeList("G001", "Y", new String[] {"0000"}));
+		} else {
+			mav.addObject("roleList", rendererService.getAvailCommonCodeList("G001"));
+		}
+
+		// 공급업체 콤보박스 목록
+		mav.addObject("supplyCompList", rendererService.getSupplyCompanyList(TsaSession.getInfo().getSupplyCompCd()));
+
+		// 외부몰벤더 콤보박스 목록
+		mav.addObject("vendorList", rendererService.getCommonCodeList("G003", "Y", TsaSession.getInfo().getSupplyCompCd()));
+
+		if (mode.equals("U")) {
+			// 어드민사용자정보
+			mav.addObject("userInfo", systemService.getUser(userNo));
+		} else {
+			mav.addObject("userInfo", new User());
+		}
+
+		mav.addObject("mode", mode);
+
+		mav.setViewName("system/UserDetailForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사용자ID 조회
+	 * @param userId - 사용자ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/id/{userId}")
+	@ResponseBody
+	public int getUserIdCount(@PathVariable("userId") String userId) {
+		return systemService.getUserIdCount(userId);
+	}
+
+	/**
+	 * 사용자 저장 처리
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/save")
+	@ResponseBody
+	public GagaResponse saveUser(@RequestBody User user) {
+		if (user.getMode().equals("N")) { // 신규등록
+			user.setPasswd(passwordEncoder.encode(user.getPasswd()));
+		}
+
+		systemService.saveUser(user);
+
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 사용자 비밀번호 변경
+	 * @param user - 사용자 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/password/change")
+	@ResponseBody
+	public GagaResponse changePassword(@RequestBody User user) {
+		user.setPasswd(passwordEncoder.encode(user.getPasswd()));
+		user.setUpdNo(TsaSession.getInfo().getUserNo());
+		log.info("user: {}", user);
+
+		// 어드민사용자 비밀번호 수정
+		systemService.updateUserPassword(user);
+
+		return super.ok(message.getMessage("SUCC_0009"));
+	}
+
+	/**
+	 * 사용자 메뉴 관리 화면
+	 * @param userNo - 사용자번호
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/user/menu/{userNo}")
+	public ModelAndView getAdminUserMenu(@PathVariable("userNo") Integer userNo) {
+		ModelAndView mav = new ModelAndView();
+
+		// 사용자 메뉴 목록
+		mav.addObject("userMenuList", systemService.getUserMenuList(userNo));
+
+		mav.setViewName("system/UserMenuForm");
+
+		return mav;
+	}
+
+	/**
+	 * 사용자 메뉴 목록 저장 처리
+	 * @param menuList - 사용자 메뉴 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/user/menu/list/save")
+	@ResponseBody
+	public GagaResponse saveUserMenuList(@RequestBody Collection<UserMenu> menuList) {
+		systemService.saveUserMenuList(menuList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 비밀번호 변경 팝업
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 30
+	 */
+	@GetMapping("/password/change/form")
+	public ModelAndView passwordChangeForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("system/PasswordChangeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 메뉴관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/menu/form")
+	public ModelAndView menuListForm() {
+		ModelAndView mav = new ModelAndView();
+
+		// 최상위메뉴 콤보박스 목록
+		mav.addObject("topMenuList", rendererService.getTopMenuList(""));
+
+		// 전체메뉴 콤보박스 목록
+		mav.addObject("allMenuList", rendererService.getAllMenuList());
+
+		// 권한 콤보박스 목록
+		mav.addObject("roleList", rendererService.getCommonCodeList("G001"));
+
+		mav.setViewName("system/MenuForm");
+
+		return mav;
+	}
+
+	/**
+	 * 메뉴 목록
+	 * @param pmenuId - 상위메뉴ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/menu/list")
+	@ResponseBody
+	public Collection<Menu> getMenuList(@RequestParam(value = "pmenuId", required = false) String pmenuId) {
+		return systemService.getMenuList(pmenuId);
+	}
+
+	/**
+	 * 메뉴 사용안함 처리
+	 * @param menuList - 메뉴 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/menu/list/save")
+	@ResponseBody
+	public GagaResponse saveMenuList(@RequestBody Collection<Menu> menuList) {
+		systemService.saveMenuList(menuList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 메뉴 등록/수정 처리
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/menu/save")
+	@ResponseBody
+	public GagaResponse saveMenu(@RequestBody Menu menu) {
+		systemService.saveMenu(menu);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 공통코드관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/commoncode/form")
+	public ModelAndView commoncodeListForm() {
+		ModelAndView mav = new ModelAndView();
+
+//		// 코드구분 콤보박스 목록
+//		mav.addObject("cdGbList", rendererService.getCommonCodeList("ROOT"));
+
+		mav.setViewName("system/CommoncodeForm");
+
+		return mav;
+	}
+
+	/**
+	 * 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@GetMapping("/commoncode/list")
+	@ResponseBody
+	public Collection<CommonCode> getCommonCodeList(@RequestParam(value = "cdGb", required = false) String cdGb) {
+		CommonCode commoncode = new CommonCode();
+		commoncode.setCdGb(cdGb);
+		return systemService.getCommonCodeList(commoncode);
+	}
+
+	/**
+	 * 공통코드 목록 저장 처리
+	 * @param commonCodeList - 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/commoncode/list/save")
+	@ResponseBody
+	public GagaResponse saveCommonCodeList(@RequestBody Collection<CommonCode> commonCodeList) {
+		systemService.saveCommonCodeList(commonCodeList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 공통코드 저장 처리
+	 * @param commonCode - 공통코드 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 10. 7
+	 */
+	@PostMapping("/commoncode/save")
+	@ResponseBody
+	public GagaResponse saveCommonCode(@RequestBody CommonCode commonCode) {
+		systemService.saveCommonCode(commonCode);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 샘플양식관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/sample/file/form")
+	public ModelAndView sampleFileForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("system/SampleFileForm");
+
+		return mav;
+	}
+
+	/**
+	 * 샘플파일 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@GetMapping("/sample/file/list")
+	@ResponseBody
+	public Collection<SampleFile> getSampleFileList() {
+		return systemService.getSampleFileList();
+	}
+
+	/**
+	 * 샘플파일 등록/수정 처리
+	 * @param sampleFile - 샘플파일 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 3
+	 */
+	@PostMapping("/sample/file/save")
+	@ResponseBody
+	public GagaResponse saveSampleFile(@RequestBody SampleFile sampleFile) {
+		sampleFile.setRegNo(TsaSession.getInfo().getUserNo());
+		sampleFile.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.saveSampleFile(sampleFile);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 시스템알람관리 화면
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/alarm/form")
+	public ModelAndView systemAlarmForm() {
+		ModelAndView mav = new ModelAndView();
+
+		mav.setViewName("system/SystemAlarmForm");
+
+		return mav;
+	}
+
+	/**
+	 * 시스템알람 목록
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/list")
+	@ResponseBody
+	public Collection<Alarm> getAlarmList(@RequestBody Alarm alarm) {
+		return systemService.getAlarmList(alarm);
+	}
+
+	/**
+	 * 알람 저장
+	 * @param alarm - 시스템알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/save")
+	@ResponseBody
+	public GagaResponse saveAlarm(@RequestBody Alarm alarm) {
+		alarm.setRegNo(TsaSession.getInfo().getUserNo());
+		alarm.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.saveAlarm(alarm);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 알람 삭제
+	 * @param alarm - 알람 정보
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/delete")
+	@ResponseBody
+	public GagaResponse deleteAlarm(@RequestBody Alarm alarm) {
+		alarm.setUpdNo(TsaSession.getInfo().getUserNo());
+		systemService.deleteAlarm(alarm);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+	/**
+	 * 알람수신자 목록
+	 * @param alarmId - 알람ID
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@GetMapping("/alarm/receiver/list/{alarmId}")
+	@ResponseBody
+	public Collection<AlarmReceiver> getAlarmReceiverList(@PathVariable String alarmId) {
+		return systemService.getAlarmReceiverList(alarmId);
+	}
+
+	/**
+	 * 알람수신자 목록 저장
+	 * @param alarmReceiverList - 알람수신자 목록
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/receiver/list/save")
+	@ResponseBody
+	public GagaResponse saveAlarmReceiverList(@RequestBody Collection<AlarmReceiver> alarmReceiverList) {
+		systemService.saveAlarmReceiverList(alarmReceiverList);
+		return super.ok(message.getMessage("SUCC_0001"));
+	}
+
+	/**
+	 * 알람수신자 삭제
+	 * @return
+	 * @author gagamel
+	 * @since 2020. 11. 13
+	 */
+	@PostMapping("/alarm/receiver/delete")
+	@ResponseBody
+	public GagaResponse deleteAlarmReceiverList(@RequestBody Collection<AlarmReceiver> alarmReceiverList) {
+		systemService.deleteAlarmReceiverList(alarmReceiverList);
+		return super.ok(message.getMessage("SUCC_0003"));
+	}
+
+}

+ 749 - 622
style24.admin/src/main/java/com/style24/persistence/mybatis/shop/TsaSystem.xml

@@ -1,623 +1,750 @@
-<?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="com.style24.admin.biz.dao.TsaSystemDao">
-
-	<!-- 사용자 목록 -->
-	<select id="getUserList" parameterType="User" resultType="User">
-		/* TsaSystem.getUserList */
-		SELECT A.USER_NO                                                     /*사용자번호*/
-		     , A.USER_ID                                                     /*사용자ID*/
-		     , A.USER_NM                                                     /*사용자명*/
-		     , A.ROLE_CD                                                     /*권한코드*/
-		     , A.ROLE_REF_VAL                                                /*권한관련값*/
-		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) IN ('A','B','E') THEN
-		                A.ROLE_REF_VAL
-		            END                                    AS SUPPLY_COMP_CD /*공급업체코드*/
-		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) IN ('A','B','E') THEN
-		                (SELECT SUPPLY_COMP_NM
-		                 FROM   TB_SUPPLY_COMPANY
-		                 WHERE  SUPPLY_COMP_CD = A.ROLE_REF_VAL
-		                )
-		       END                                         AS SUPPLY_COMP_NM /*공급업체명*/
-		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) = 'C' THEN
-		                A.ROLE_REF_VAL
-		       END                                         AS VENDOR_ID      /*벤더ID*/
-		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) = 'C' THEN
-		                FN_GET_CODE_NM('G003',A.ROLE_REF_VAL)
-		       END                                         AS VENDOR_NM      /*벤더명*/
-		     , A.EMAIL                                                       /*이메일*/
-		     , A.CELL_PHNNO                                                  /*휴대전화번호*/
-		     , A.PNT_ASSIGN_AMT                                              /*포인트부여가능금액*/
-		     , A.IP_ADDR                                                     /*IP주소*/
-		     , A.IP_CHK_YN                                                   /*IP체크여부*/
-		     , DATE_FORMAT(A.LOGIN_LDT,'%Y%m%d%H%i%S')     AS LOGIN_LDT      /*최종로그인일시*/
-		     , DATE_FORMAT(A.PASSWD_CHG_DT,'%Y%m%d%H%i%S') AS PASSWD_CHG_DT  /*비밀번호변경일시*/
-		     , A.USE_YN                                                      /*사용여부*/
-		FROM   TB_USER A
-		WHERE  1 = 1
-		<choose>
-		    <when test="searchGb == 'userId'">
-		AND    LOWER(A.USER_ID) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
-		    </when>
-		    <when test="searchGb == 'userNm'">
-		AND    LOWER(A.USER_NM) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
-		    </when>
-		</choose>
-		<if test="useYn != null and useYn != ''">
-		AND    A.USE_YN  = #{useYn}
-		</if>
-		<if test="supplyCompCd != null and supplyCompCd != ''">
-		AND    A.ROLE_REF_VAL = #{supplyCompCd}
-		</if>
-		<if test="roleCd != null and roleCd != ''">
-		AND    A.ROLE_CD  = #{roleCd}
-		</if>
-		ORDER  BY A.USER_NM
-	</select>
-
-	<!-- 사용자 조회 -->
-	<select id="getUser" parameterType="Integer" resultType="User">
-		/* TsaSystem.getUser */
-		SELECT USER_NO                                                         /*사용자번호*/
-		     , USER_ID                                                         /*사용자ID*/
-		     , USER_NM                                                         /*사용자명*/
-		     , ROLE_CD                                                         /*권한코드*/
-		     , (SELECT CD_NM
-		        FROM   TB_COMMON_CODE
-		        WHERE  CD_GB = 'G001'
-		        AND    CD = A.ROLE_CD
-		       )                                              AS ROLE_NM       /*권한명*/
-		     , ROLE_REF_VAL                                                    /*권한관련값*/
-		     , EMAIL                                                           /*이메일*/
-		     , CELL_PHNNO                                                      /*휴대전화번호*/
-		     , PNT_ASSIGN_AMT                                                  /*포인트부여가능금액*/
-		     , IP_ADDR                                                         /*IP주소*/
-		     , IP_CHK_YN                                                       /*IP체크여부*/
-		     , DATE_FORMAT(LOGIN_LDT,'%Y-%m-%d %H:%i:%S')     AS LOGIN_LDT     /*최종로그인일시*/
-		     , DATE_FORMAT(PASSWD_CHG_DT,'%Y-%m-%d %H:%i:%S') AS PASSWD_CHG_DT /*비밀번호변경일시*/
-		     , USE_YN                                                          /*사용여부*/
-		FROM   TB_USER A
-		WHERE  USER_NO = #{userNo}
-	</select>
-
-	<!-- 사용자 삭제 -->
-	<update id="deleteUser" parameterType="User">
-		/* TsaSystem.deleteUser */
-		UPDATE TB_USER
-		SET    USE_YN = 'N'
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-		WHERE  USER_NO = #{userNo}
-	</update>
-
-	<!-- 사용자ID 건수 -->
-	<select id="getUserIdCount" parameterType="String" resultType="int">
-		/* TsaSystem.getUserIdCount */
-		SELECT COUNT(*) AS CNT
-		FROM   TB_USER
-		WHERE  USER_ID = #{userId}
-	</select>
-
-	<!-- 사용자 등록/수정 -->
-	<insert id="saveUser" parameterType="User" keyProperty="userNo">
-		/* TsaSystem.saveUser */
-		INSERT INTO TB_USER (
-		       USER_NO
-		     , USER_ID
-		     , USER_NM
-		     , PASSWD
-		     , ROLE_CD
-		     , ROLE_REF_VAL
-		     , EMAIL
-		     , CELL_PHNNO
-		     , PNT_ASSIGN_AMT
-		     , IP_ADDR
-		     , IP_CHK_YN
-		     , USE_YN
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		VALUES (
-		       #{userNo}
-		     , #{userId}
-		     , #{userNm}
-		     , #{passwd}
-		     , #{roleCd}
-		     , #{roleRefVal}
-		     , #{email}
-		     , #{cellPhnno}
-		     , IFNULL(#{pntAssignAmt},0)
-		     , #{ipAddr}
-		     , #{ipChkYn}
-		     , #{useYn}
-		     , #{regNo}
-		     , NOW()
-		     , #{updNo}
-		     , NOW()
-		)
-		ON DUPLICATE KEY UPDATE
-		       USER_NM = #{userNm}
-		     , ROLE_CD = #{roleCd}
-		     , ROLE_REF_VAL = #{roleRefVal}
-		     , EMAIL = #{email}
-		     , CELL_PHNNO = #{cellPhnno}
-		     , PNT_ASSIGN_AMT = IFNULL(#{pntAssignAmt},0)
-		     , IP_ADDR = #{ipAddr}
-		     , IP_CHK_YN = #{ipChkYn}
-		     , USE_YN = #{useYn}
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-	</insert>
-
-	<!-- 임시비밀번호 조회 -->
-	<select id="getTemporaryPassword" parameterType="int" resultType="String">
-		/* TsaSystem.getTemporaryPassword */
-		SELECT CONVERT(TRUNCATE(A.VAL * CAST(CONCAT(1,LPAD(0,(#{length} - 1),'0')) AS UNSIGNED),0),CHAR) AS PASSWD FROM DUAL
-	</select>
-
-	<!-- 사용자 비밀번호 수정 -->
-	<update id="updateUserPassword" parameterType="User">
-		/* TsaSystem.updateUserPassword */
-		UPDATE TB_USER
-		SET    PASSWD = #{passwd}
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-		WHERE  USER_NO = #{userNo}
-	</update>
-
-	<!-- 사용자 메뉴 목록 -->
-	<select id="getUserMenuList" parameterType="Integer" resultType="UserMenu">
-		/* TsaSystem.getUserMenuList */
-		WITH RECURSIVE CONNECTBY AS (
-		    SELECT 1                                    AS LVL
-		         , PMENU_ID
-		         , MENU_ID
-		         , MENU_NM
-		         , MENU_GB
-		         , CONCAT(MENU_ID,LPAD(DISP_ORD,4,'0')) AS ORDBY
-		    FROM   TB_MENU
-		    WHERE  PMENU_ID = 'ROOT'
-		    AND    USE_YN = 'Y'
-		    
-		    UNION ALL
-		    
-		    SELECT A.LVL + 1                              AS LVL
-		         , B.PMENU_ID
-		         , B.MENU_ID
-		         , B.MENU_NM
-		         , B.MENU_GB
-		         , CONCAT(A.ORDBY,LPAD(B.DISP_ORD,4,'0')) AS ORDBY
-		    FROM   CONNECTBY A
-		    INNER JOIN TB_MENU B ON A.MENU_ID = B.PMENU_ID
-		)
-		SELECT #{userNo}                       AS USER_NO  /*사용자번호*/
-		     , A.PMENU_ID                                  /*상위메뉴ID*/
-		     , A.MENU_ID                                   /*메뉴ID*/
-		     , A.MENU_NM                                   /*메뉴명*/
-		     , A.MENU_GB                                   /*메뉴구분*/
-		     , CASE WHEN B.USER_NO IS NULL OR B.USE_ROLE = 'NNNN' THEN
-		                'N'
-		            ELSE
-		                'Y'
-		       END                             AS USE_YN   /*사용여부*/
-		     , A.LVL                           AS MENU_LVL /*메뉴레벨*/
-		     , IFNULL(B.USE_ROLE,'NNNN')       AS USE_ROLE /*사용권한*/
-		FROM   CONNECTBY A
-		LEFT OUTER JOIN TB_USER_MENU B ON A.MENU_ID = B.MENU_ID
-		                              AND B.USER_NO = #{userNo}
-		ORDER  BY A.ORDBY
-	</select>
-	
-	<!-- 사용자정보변경이력 생성 -->
-	<insert id="createUserInfoChangeHistory" parameterType="UserHst">
-		/* TsaSystem.createUserInfoChangeHistory */
-		INSERT INTO TB_USER_HST (
-		       CHG_HST_SQ
-		     , USER_NO
-		     , CHG_GB
-		     , CHG_CONTENT
-		     , REG_NO
-		     , REG_DT
-		)
-		VALUES (
-		       NULL
-		     , #{userNo}
-		     , #{chgGb}
-		     , CASE WHEN #{chgGb} = 'G049_20' THEN
-		                CONCAT(FN_GET_CODE_NM('G001',#{orgRoleCd}),' -> ',FN_GET_CODE_NM('G001',#{roleCd}))
-		            ELSE
-		                NULL
-		       END
-		     , #{regNo}
-		     , NOW()
-		)
-	</insert>
-
-	<!-- 메뉴 목록 -->
-	<select id="getMenuList" parameterType="Menu" resultType="Menu">
-		/* TsaSystem.getMenuList */
-		WITH RECURSIVE CONNECTBY1 AS (
-		    SELECT 1                                    AS MENU_LVL  /*메뉴레벨*/
-		         , MENU_ID                                           /*메뉴ID*/
-		         , MENU_NM                                           /*메뉴명*/
-		         , MENU_GB                                           /*메뉴구분*/
-		         , MENU_DESC                                         /*메뉴상세명*/
-		         , MENU_URL                                          /*메뉴URL*/
-		         , PMENU_ID                                          /*상위메뉴ID*/
-		         , DISP_ORD                                          /*표시순서*/
-		         , USE_YN                                            /*사용여부*/
-		         , MENU_ID                              AS TREE_PATH /*AG-GRID트리패스(ag-Grid미사용시 필요 없음)*/
-		         , CONCAT(MENU_ID,LPAD(DISP_ORD,4,'0')) AS ORDBY
-		    FROM   TB_MENU A
-		    WHERE  1 = 1
-		    <choose>
-		        <when test="pmenuId != null and pmenuId != ''">
-		    AND    PMENU_ID = #{pmenuId}
-		        </when>
-		        <otherwise>
-		    AND    PMENU_ID = 'ROOT'
-		        </otherwise>
-		    </choose>
-		    
-		    UNION ALL
-		    
-		    SELECT A.MENU_LVL + 1                         AS MENU_LVL  /*메뉴레벨*/
-		         , B.MENU_ID                                           /*메뉴ID*/
-		         , B.MENU_NM                                           /*메뉴명*/
-		         , B.MENU_GB                                           /*메뉴구분*/
-		         , B.MENU_DESC                                         /*메뉴상세명*/
-		         , B.MENU_URL                                          /*메뉴URL*/
-		         , B.PMENU_ID                                          /*상위메뉴ID*/
-		         , B.DISP_ORD                                          /*표시순서*/
-		         , B.USE_YN                                            /*사용여부*/
-		         , CONCAT(A.TREE_PATH,'/',B.MENU_ID)      AS TREE_PATH /*AG-GRID트리패스(ag-Grid미사용시 필요 없음) */
-		         , CONCAT(A.ORDBY,LPAD(B.DISP_ORD,4,'0')) AS ORDBY
-		    FROM   CONNECTBY1 A
-		    INNER JOIN TB_MENU B ON A.MENU_ID = B.PMENU_ID
-		), TAB_MENU_ROLE AS (
-		    SELECT A.MENU_ID
-		         , GROUP_CONCAT(B.ROLE_CD ORDER BY B.ROLE_CD SEPARATOR ',')                        AS ROLE_CDS /*다중메뉴권한코드*/
-		         , GROUP_CONCAT(FN_GET_CODE_NM('G001',B.ROLE_CD) ORDER BY B.ROLE_CD SEPARATOR ',') AS ROLE_NMS /*다중메뉴권한명*/
-		    FROM   TB_MENU A
-		    INNER JOIN TB_MENU_ROLE B ON A.MENU_ID = B.MENU_ID
-		    GROUP  BY A.MENU_ID
-		)
-		SELECT MENU_LVL
-		     , MENU_ID
-		     , MENU_NM
-		     , MENU_GB
-		     , MENU_DESC
-		     , MENU_URL
-		     , PMENU_ID
-		     , DISP_ORD
-		     , USE_YN
-		     , TREE_PATH
-		     , (SELECT ROLE_CDS
-		        FROM   TAB_MENU_ROLE
-		        WHERE  MENU_ID = A.MENU_ID) AS ROLE_CDS  /*다중메뉴권한코드*/
-		     , (SELECT ROLE_NMS
-		        FROM   TAB_MENU_ROLE
-		        WHERE  MENU_ID = A.MENU_ID) AS ROLE_NMS  /*다중메뉴권한명*/
-		FROM   CONNECTBY1 A
-		ORDER  BY ORDBY
-	</select>
-
-	<!-- 메뉴 등록/수정 -->
-	<insert id="saveMenu" parameterType="Menu">
-		/* TsaSystem.saveMenu */
-		INSERT INTO TB_MENU (
-		       MENU_ID
-		     , MENU_NM
-		     , MENU_GB
-		     , MENU_DESC
-		     , MENU_URL
-		     , DISP_ORD
-		     , USE_YN
-		     , PMENU_ID
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		VALUES (
-		       #{menuId}
-		     , #{menuNm}
-		     , #{menuGb}
-		     , #{menuDesc}
-		     , #{menuUrl}
-		     , #{dispOrd}
-		     , #{useYn}
-		     , IFNULL(NULLIF(#{pmenuId},''),'ROOT')
-		     , #{regNo}
-		     , NOW()
-		     , #{updNo}
-		     , NOW()
-		)
-		ON DUPLICATE KEY UPDATE
-		       MENU_NM = #{menuNm}
-		     , MENU_GB = #{menuGb}
-		     , MENU_DESC = #{menuDesc}
-		     , MENU_URL = #{menuUrl}
-		     , DISP_ORD = #{dispOrd}
-		     , USE_YN = #{useYn}
-		     , PMENU_ID = IFNULL(NULLIF(#{pmenuId},''),'ROOT')
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-	</insert>
-
-	<!-- 메뉴권한 삭제 -->
-	<delete id="deleteMenuRole" parameterType="String">
-		/* TsaSystem.deleteMenuRole */
-		DELETE FROM TB_MENU_ROLE
-		WHERE  MENU_ID = #{menuId}
-	</delete>
-
-	<!-- 메뉴권한 생성 -->
-	<insert id="createMenuRole" parameterType="MenuRole">
-		/* TsaSystem.createMenuRole */
-		INSERT INTO TB_MENU_ROLE (
-		       ROLE_CD
-		     , MENU_ID
-		     , USE_ROLE
-		     , REG_NO
-		     , REG_DT
-		)
-		VALUES (
-		       #{roleCd}
-		     , #{menuId}
-		     , IFNULL(NULLIF(#{useRole},''),'RCUD')
-		     , #{regNo}
-		     , NOW()
-		)
-	</insert>
-
-	<!-- 전체 사용자 메뉴 삭제 -->
-	<delete id="deleteAllUserMenu" parameterType="MenuRole">
-		/* TsaSystem.deleteAllUserMenu */
-		DELETE
-		FROM   TB_USER_MENU
-		WHERE  USER_NO IN (SELECT USER_NO
-		                   FROM   TB_USER
-		                   WHERE  ROLE_CD = #{roleCd}
-		                  )
-		AND    MENU_ID = #{menuId}
-	</delete>
-
-	<!-- 전체 사용자 메뉴 생성-->
-	<insert id="createAllUserMenu" parameterType="MenuRole">
-		/* TsaSystem.createAllUserMenu */
-		INSERT INTO TB_USER_MENU (
-		       USER_NO
-		     , MENU_ID
-		     , USE_ROLE
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		SELECT B.USER_NO
-		     , A.MENU_ID
-		     , A.USE_ROLE
-		     , #{regNo}
-		     , NOW()
-		     , #{updNo}
-		     , NOW()
-		FROM   TB_MENU_ROLE A
-		INNER JOIN TB_USER B ON A.ROLE_CD = B.ROLE_CD
-		WHERE  A.ROLE_CD = #{roleCd}
-		AND    A.MENU_ID = #{menuId}
-		AND    B.USE_YN = 'Y'
-		ON DUPLICATE KEY UPDATE
-		       USE_ROLE = A.USE_ROLE
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-	</insert>
-
-	<!-- 사용자 전체 메뉴 삭제 -->
-	<delete id="deleteUserAllMenu" parameterType="Integer">
-		/* TsaSystem.deleteUserAllMenu */
-		DELETE
-		FROM   TB_USER_MENU
-		WHERE  USER_NO = #{userNo}
-	</delete>
-
-	<!-- 사용자 전체 메뉴 생성 -->
-	<insert id="createUserAllMenu" parameterType="User">
-		/* TsaSystem.createUserAllMenu */
-		INSERT INTO TB_USER_MENU (
-		       USER_NO
-		     , MENU_ID
-		     , USE_ROLE
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		SELECT A.USER_NO
-		     , B.MENU_ID
-		     , B.USE_ROLE
-		     , #{regNo}     AS REG_NO
-		     , NOW()        AS REG_DT
-		     , #{updNo}     AS UPD_NO
-		     , NOW()        AS UPD_DT
-		FROM   TB_USER A
-		INNER JOIN TB_MENU_ROLE B ON A.ROLE_CD = B.ROLE_CD
-		WHERE  A.USER_NO = #{userNo}
-		AND    A.ROLE_CD = #{roleCd}
-	</insert>
-
-	<!-- 사용자 메뉴 삭제 -->
-	<delete id="deleteUserMenu" parameterType="UserMenu">
-		/* TsaSystem.deleteUserMenu */
-		DELETE
-		FROM   TB_USER_MENU
-		WHERE  USER_NO = #{userNo}
-		AND    MENU_ID = #{menuId}
-	</delete>
-
-	<!-- 사용자 메뉴 Insert/Update -->
-	<insert id="createUserMenu" parameterType="UserMenu">
-		/* TsaSystem.createUserMenu */
-		INSERT INTO TB_USER_MENU (
-		       USER_NO
-		     , MENU_ID
-		     , USE_ROLE
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		VALUES (
-		       #{userNo}
-		     , #{menuId}
-		     , #{useRole}
-		     , #{regNo}
-		     , NOW()
-		     , #{updNo}
-		     , NOW()
-		)
-		ON DUPLICATE KEY UPDATE
-		       USE_ROLE = #{useRole}
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-	</insert>
-	
-	<!-- 메뉴접속이력 생성 -->
-	<insert id="createMenuAccessHistory" parameterType="MenuAccessHst">
-		/* TsaSystem.createMenuAccessHistory */
-		INSERT INTO TB_MENU_ACCESS_HST (
-		       MENU_ACCESS_SQ
-		     , USER_NO
-		     , MENU_ID
-		     , REQ_URL
-		     , PARAMS
-		     , REG_NO
-		     , REG_DT
-		)
-		VALUES (
-		       NULL
-		     , #{userNo}
-		     , #{menuId}
-		     , #{reqUrl}
-		     , #{params}
-		     , #{userNo}
-		     , NOW()
-		)
-	</insert>
-
-	<!-- 공통코드 목록 -->
-	<select id="getCommonCodeList" parameterType="CommonCode" resultType="CommonCode">
-		/* TsaSystem.getCommonCodeList */
-		SELECT CD_GB
-		     , CD
-		     , CD_NM
-		     , CD_DESC
-		     , DISP_ORD
-		     , USE_YN
-		     , DISP_ORD
-		FROM   TB_COMMON_CODE
-		WHERE  CD_GB = #{cdGb}
-		ORDER  BY DISP_ORD
-	</select>
-
-	<!-- 공통코드 등록/수정 -->
-	<insert id="saveCommonCode" parameterType="CommonCode">
-		/* TsaSystem.saveCommonCode */
-		INSERT INTO TB_COMMON_CODE (
-		       CD_GB
-		     , CD
-		     , CD_NM
-		     , CD_DESC
-		     , DISP_ORD
-		     , USE_YN
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		VALUES (
-		       #{cdGb}
-		     , #{cd}
-		     , #{cdNm}
-		     , #{cdDesc}
-		     , #{dispOrd}
-		     , #{useYn}
-		     , #{regNo}
-		     , NOW()
-		     , #{updNo}
-		     , NOW()
-		)
-		ON DUPLICATE KEY UPDATE
-		       CD_NM = #{cdNm}
-		     , CD_DESC = #{cdDesc}
-		     , DISP_ORD = #{dispOrd}
-		     , USE_YN = #{useYn}
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-	</insert>
-
-	<!-- 공통코드 삭제 -->
-	<delete id="deleteCommonCode" parameterType="CommonCode">
-		/* TsaSystem.deleteCode */
-		DELETE FROM TB_COMMON_CODE
-		WHERE  CD_GB = #{cdGb}
-		AND    CD = #{cd}
-	</delete>
-	
-	<!-- 샘플파일 목록 -->
-	<select id="getSampleFileList" resultType="SampleFile">
-		/* TsaSystem.getSampleFileList */
-		SELECT SAMPLE_FILE_ID
-		     , SAMPLE_FILE_NM
-		     , ORG_FILE_NM
-		     , SYS_FILE_NM
-		     , USE_YN
-		FROM   TB_SAMPLE_FILE
-		ORDER  BY SAMPLE_FILE_NM
-	</select>
-
-	<!-- 샘플파일 등록/수정 -->
-	<insert id="createSampleFile" parameterType="SampleFile">
-		/* TsaSystem.createSampleFile */
-		INSERT INTO TB_SAMPLE_FILE (
-		       SAMPLE_FILE_ID
-		     , SAMPLE_FILE_NM
-		     , ORG_FILE_NM
-		     , SYS_FILE_NM
-		     , USE_YN
-		     , REG_NO
-		     , REG_DT
-		     , UPD_NO
-		     , UPD_DT
-		)
-		VALUES (
-		       (SELECT CONCAT('SF',IFNULL(LPAD(CAST(SUBSTRING(MAX(SAMPLE_FILE_ID),3) AS UNSIGNED) + 1,3,'0'),'000'))
-		        FROM   TB_SAMPLE_FILE Z
-		       )
-		     , #{sampleFileNm}
-		     , #{orgFileNm}
-		     , #{sysFileNm}
-		     , #{useYn}
-		     , #{regNo}
-		     , NOW()
-		     , #{updNo}
-		     , NOW()
-		)
-	</insert>
-	
-	<!-- 샘플파일 등록/수정 -->
-	<update id="updateSampleFile" parameterType="SampleFile">
-		/* TsaSystem.updateSampleFile */
-		UPDATE TB_SAMPLE_FILE
-		SET    SAMPLE_FILE_NM = #{sampleFileNm}
-		     , ORG_FILE_NM = #{orgFileNm}
-		     , SYS_FILE_NM = #{sysFileNm}
-		     , USE_YN = #{useYn}
-		     , UPD_NO = #{updNo}
-		     , UPD_DT = NOW()
-		WHERE  SAMPLE_FILE_ID = #{sampleFileId}
-	</update>
-
+<?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="com.style24.admin.biz.dao.TsaSystemDao">
+
+	<!-- 사용자 목록 -->
+	<select id="getUserList" parameterType="User" resultType="User">
+		/* TsaSystem.getUserList */
+		SELECT A.USER_NO                                                     /*사용자번호*/
+		     , A.USER_ID                                                     /*사용자ID*/
+		     , A.USER_NM                                                     /*사용자명*/
+		     , A.ROLE_CD                                                     /*권한코드*/
+		     , A.ROLE_REF_VAL                                                /*권한관련값*/
+		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) IN ('A','B','E') THEN
+		                A.ROLE_REF_VAL
+		            END                                    AS SUPPLY_COMP_CD /*공급업체코드*/
+		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) IN ('A','B','E') THEN
+		                (SELECT SUPPLY_COMP_NM
+		                 FROM   TB_SUPPLY_COMPANY
+		                 WHERE  SUPPLY_COMP_CD = A.ROLE_REF_VAL
+		                )
+		       END                                         AS SUPPLY_COMP_NM /*공급업체명*/
+		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) = 'C' THEN
+		                A.ROLE_REF_VAL
+		       END                                         AS VENDOR_ID      /*벤더ID*/
+		     , CASE WHEN SUBSTRING(A.ROLE_CD,1,1) = 'C' THEN
+		                FN_GET_CODE_NM('G003',A.ROLE_REF_VAL)
+		       END                                         AS VENDOR_NM      /*벤더명*/
+		     , A.EMAIL                                                       /*이메일*/
+		     , A.CELL_PHNNO                                                  /*휴대전화번호*/
+		     , A.PNT_ASSIGN_AMT                                              /*포인트부여가능금액*/
+		     , A.IP_ADDR                                                     /*IP주소*/
+		     , A.IP_CHK_YN                                                   /*IP체크여부*/
+		     , DATE_FORMAT(A.LOGIN_LDT,'%Y%m%d%H%i%S')     AS LOGIN_LDT      /*최종로그인일시*/
+		     , DATE_FORMAT(A.PASSWD_CHG_DT,'%Y%m%d%H%i%S') AS PASSWD_CHG_DT  /*비밀번호변경일시*/
+		     , A.USE_YN                                                      /*사용여부*/
+		FROM   TB_USER A
+		WHERE  1 = 1
+		<choose>
+		    <when test="searchGb == 'userId'">
+		AND    LOWER(A.USER_ID) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </when>
+		    <when test="searchGb == 'userNm'">
+		AND    LOWER(A.USER_NM) LIKE CONCAT('%',LOWER(#{searchTxt}),'%')
+		    </when>
+		</choose>
+		<if test="useYn != null and useYn != ''">
+		AND    A.USE_YN  = #{useYn}
+		</if>
+		<if test="supplyCompCd != null and supplyCompCd != ''">
+		AND    A.ROLE_REF_VAL = #{supplyCompCd}
+		</if>
+		<if test="roleCd != null and roleCd != ''">
+		AND    A.ROLE_CD  = #{roleCd}
+		</if>
+		ORDER  BY A.USER_NM
+	</select>
+
+	<!-- 사용자 조회 -->
+	<select id="getUser" parameterType="Integer" resultType="User">
+		/* TsaSystem.getUser */
+		SELECT USER_NO                                                         /*사용자번호*/
+		     , USER_ID                                                         /*사용자ID*/
+		     , USER_NM                                                         /*사용자명*/
+		     , ROLE_CD                                                         /*권한코드*/
+		     , (SELECT CD_NM
+		        FROM   TB_COMMON_CODE
+		        WHERE  CD_GB = 'G001'
+		        AND    CD = A.ROLE_CD
+		       )                                              AS ROLE_NM       /*권한명*/
+		     , ROLE_REF_VAL                                                    /*권한관련값*/
+		     , EMAIL                                                           /*이메일*/
+		     , CELL_PHNNO                                                      /*휴대전화번호*/
+		     , PNT_ASSIGN_AMT                                                  /*포인트부여가능금액*/
+		     , IP_ADDR                                                         /*IP주소*/
+		     , IP_CHK_YN                                                       /*IP체크여부*/
+		     , DATE_FORMAT(LOGIN_LDT,'%Y-%m-%d %H:%i:%S')     AS LOGIN_LDT     /*최종로그인일시*/
+		     , DATE_FORMAT(PASSWD_CHG_DT,'%Y-%m-%d %H:%i:%S') AS PASSWD_CHG_DT /*비밀번호변경일시*/
+		     , USE_YN                                                          /*사용여부*/
+		FROM   TB_USER A
+		WHERE  USER_NO = #{userNo}
+	</select>
+
+	<!-- 사용자 삭제 -->
+	<update id="deleteUser" parameterType="User">
+		/* TsaSystem.deleteUser */
+		UPDATE TB_USER
+		SET    USE_YN = 'N'
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  USER_NO = #{userNo}
+	</update>
+
+	<!-- 사용자ID 건수 -->
+	<select id="getUserIdCount" parameterType="String" resultType="int">
+		/* TsaSystem.getUserIdCount */
+		SELECT COUNT(*) AS CNT
+		FROM   TB_USER
+		WHERE  USER_ID = #{userId}
+	</select>
+
+	<!-- 사용자 등록/수정 -->
+	<insert id="saveUser" parameterType="User" keyProperty="userNo">
+		/* TsaSystem.saveUser */
+		INSERT INTO TB_USER (
+		       USER_NO
+		     , USER_ID
+		     , USER_NM
+		     , PASSWD
+		     , ROLE_CD
+		     , ROLE_REF_VAL
+		     , EMAIL
+		     , CELL_PHNNO
+		     , PNT_ASSIGN_AMT
+		     , IP_ADDR
+		     , IP_CHK_YN
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{userNo}
+		     , #{userId}
+		     , #{userNm}
+		     , #{passwd}
+		     , #{roleCd}
+		     , #{roleRefVal}
+		     , #{email}
+		     , #{cellPhnno}
+		     , IFNULL(#{pntAssignAmt},0)
+		     , #{ipAddr}
+		     , #{ipChkYn}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       USER_NM = #{userNm}
+		     , ROLE_CD = #{roleCd}
+		     , ROLE_REF_VAL = #{roleRefVal}
+		     , EMAIL = #{email}
+		     , CELL_PHNNO = #{cellPhnno}
+		     , PNT_ASSIGN_AMT = IFNULL(#{pntAssignAmt},0)
+		     , IP_ADDR = #{ipAddr}
+		     , IP_CHK_YN = #{ipChkYn}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+
+	<!-- 임시비밀번호 조회 -->
+	<select id="getTemporaryPassword" parameterType="int" resultType="String">
+		/* TsaSystem.getTemporaryPassword */
+		SELECT CONVERT(TRUNCATE(A.VAL * CAST(CONCAT(1,LPAD(0,(#{length} - 1),'0')) AS UNSIGNED),0),CHAR) AS PASSWD FROM DUAL
+	</select>
+
+	<!-- 사용자 비밀번호 수정 -->
+	<update id="updateUserPassword" parameterType="User">
+		/* TsaSystem.updateUserPassword */
+		UPDATE TB_USER
+		SET    PASSWD = #{passwd}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  USER_NO = #{userNo}
+	</update>
+
+	<!-- 사용자 메뉴 목록 -->
+	<select id="getUserMenuList" parameterType="Integer" resultType="UserMenu">
+		/* TsaSystem.getUserMenuList */
+		WITH RECURSIVE CONNECTBY AS (
+		    SELECT 1                                    AS LVL
+		         , PMENU_ID
+		         , MENU_ID
+		         , MENU_NM
+		         , MENU_GB
+		         , CONCAT(MENU_ID,LPAD(DISP_ORD,4,'0')) AS ORDBY
+		    FROM   TB_MENU
+		    WHERE  PMENU_ID = 'ROOT'
+		    AND    USE_YN = 'Y'
+		    
+		    UNION ALL
+		    
+		    SELECT A.LVL + 1                              AS LVL
+		         , B.PMENU_ID
+		         , B.MENU_ID
+		         , B.MENU_NM
+		         , B.MENU_GB
+		         , CONCAT(A.ORDBY,LPAD(B.DISP_ORD,4,'0')) AS ORDBY
+		    FROM   CONNECTBY A
+		    INNER JOIN TB_MENU B ON A.MENU_ID = B.PMENU_ID
+		)
+		SELECT #{userNo}                       AS USER_NO  /*사용자번호*/
+		     , A.PMENU_ID                                  /*상위메뉴ID*/
+		     , A.MENU_ID                                   /*메뉴ID*/
+		     , A.MENU_NM                                   /*메뉴명*/
+		     , A.MENU_GB                                   /*메뉴구분*/
+		     , CASE WHEN B.USER_NO IS NULL OR B.USE_ROLE = 'NNNN' THEN
+		                'N'
+		            ELSE
+		                'Y'
+		       END                             AS USE_YN   /*사용여부*/
+		     , A.LVL                           AS MENU_LVL /*메뉴레벨*/
+		     , IFNULL(B.USE_ROLE,'NNNN')       AS USE_ROLE /*사용권한*/
+		FROM   CONNECTBY A
+		LEFT OUTER JOIN TB_USER_MENU B ON A.MENU_ID = B.MENU_ID
+		                              AND B.USER_NO = #{userNo}
+		ORDER  BY A.ORDBY
+	</select>
+	
+	<!-- 사용자정보변경이력 생성 -->
+	<insert id="createUserInfoChangeHistory" parameterType="UserHst">
+		/* TsaSystem.createUserInfoChangeHistory */
+		INSERT INTO TB_USER_HST (
+		       CHG_HST_SQ
+		     , USER_NO
+		     , CHG_GB
+		     , CHG_CONTENT
+		     , REG_NO
+		     , REG_DT
+		)
+		VALUES (
+		       NULL
+		     , #{userNo}
+		     , #{chgGb}
+		     , CASE WHEN #{chgGb} = 'G049_20' THEN
+		                CONCAT(FN_GET_CODE_NM('G001',#{orgRoleCd}),' -> ',FN_GET_CODE_NM('G001',#{roleCd}))
+		            ELSE
+		                NULL
+		       END
+		     , #{regNo}
+		     , NOW()
+		)
+	</insert>
+
+	<!-- 메뉴 목록 -->
+	<select id="getMenuList" parameterType="Menu" resultType="Menu">
+		/* TsaSystem.getMenuList */
+		WITH RECURSIVE CONNECTBY1 AS (
+		    SELECT 1                                    AS MENU_LVL  /*메뉴레벨*/
+		         , MENU_ID                                           /*메뉴ID*/
+		         , MENU_NM                                           /*메뉴명*/
+		         , MENU_GB                                           /*메뉴구분*/
+		         , MENU_DESC                                         /*메뉴상세명*/
+		         , MENU_URL                                          /*메뉴URL*/
+		         , PMENU_ID                                          /*상위메뉴ID*/
+		         , DISP_ORD                                          /*표시순서*/
+		         , USE_YN                                            /*사용여부*/
+		         , MENU_ID                              AS TREE_PATH /*AG-GRID트리패스(ag-Grid미사용시 필요 없음)*/
+		         , CONCAT(MENU_ID,LPAD(DISP_ORD,4,'0')) AS ORDBY
+		    FROM   TB_MENU A
+		    WHERE  1 = 1
+		    <choose>
+		        <when test="pmenuId != null and pmenuId != ''">
+		    AND    PMENU_ID = #{pmenuId}
+		        </when>
+		        <otherwise>
+		    AND    PMENU_ID = 'ROOT'
+		        </otherwise>
+		    </choose>
+		    
+		    UNION ALL
+		    
+		    SELECT A.MENU_LVL + 1                         AS MENU_LVL  /*메뉴레벨*/
+		         , B.MENU_ID                                           /*메뉴ID*/
+		         , B.MENU_NM                                           /*메뉴명*/
+		         , B.MENU_GB                                           /*메뉴구분*/
+		         , B.MENU_DESC                                         /*메뉴상세명*/
+		         , B.MENU_URL                                          /*메뉴URL*/
+		         , B.PMENU_ID                                          /*상위메뉴ID*/
+		         , B.DISP_ORD                                          /*표시순서*/
+		         , B.USE_YN                                            /*사용여부*/
+		         , CONCAT(A.TREE_PATH,'/',B.MENU_ID)      AS TREE_PATH /*AG-GRID트리패스(ag-Grid미사용시 필요 없음) */
+		         , CONCAT(A.ORDBY,LPAD(B.DISP_ORD,4,'0')) AS ORDBY
+		    FROM   CONNECTBY1 A
+		    INNER JOIN TB_MENU B ON A.MENU_ID = B.PMENU_ID
+		), TAB_MENU_ROLE AS (
+		    SELECT A.MENU_ID
+		         , GROUP_CONCAT(B.ROLE_CD ORDER BY B.ROLE_CD SEPARATOR ',')                        AS ROLE_CDS /*다중메뉴권한코드*/
+		         , GROUP_CONCAT(FN_GET_CODE_NM('G001',B.ROLE_CD) ORDER BY B.ROLE_CD SEPARATOR ',') AS ROLE_NMS /*다중메뉴권한명*/
+		    FROM   TB_MENU A
+		    INNER JOIN TB_MENU_ROLE B ON A.MENU_ID = B.MENU_ID
+		    GROUP  BY A.MENU_ID
+		)
+		SELECT MENU_LVL
+		     , MENU_ID
+		     , MENU_NM
+		     , MENU_GB
+		     , MENU_DESC
+		     , MENU_URL
+		     , PMENU_ID
+		     , DISP_ORD
+		     , USE_YN
+		     , TREE_PATH
+		     , (SELECT ROLE_CDS
+		        FROM   TAB_MENU_ROLE
+		        WHERE  MENU_ID = A.MENU_ID) AS ROLE_CDS  /*다중메뉴권한코드*/
+		     , (SELECT ROLE_NMS
+		        FROM   TAB_MENU_ROLE
+		        WHERE  MENU_ID = A.MENU_ID) AS ROLE_NMS  /*다중메뉴권한명*/
+		FROM   CONNECTBY1 A
+		ORDER  BY ORDBY
+	</select>
+
+	<!-- 메뉴 등록/수정 -->
+	<insert id="saveMenu" parameterType="Menu">
+		/* TsaSystem.saveMenu */
+		INSERT INTO TB_MENU (
+		       MENU_ID
+		     , MENU_NM
+		     , MENU_GB
+		     , MENU_DESC
+		     , MENU_URL
+		     , DISP_ORD
+		     , USE_YN
+		     , PMENU_ID
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{menuId}
+		     , #{menuNm}
+		     , #{menuGb}
+		     , #{menuDesc}
+		     , #{menuUrl}
+		     , #{dispOrd}
+		     , #{useYn}
+		     , IFNULL(NULLIF(#{pmenuId},''),'ROOT')
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       MENU_NM = #{menuNm}
+		     , MENU_GB = #{menuGb}
+		     , MENU_DESC = #{menuDesc}
+		     , MENU_URL = #{menuUrl}
+		     , DISP_ORD = #{dispOrd}
+		     , USE_YN = #{useYn}
+		     , PMENU_ID = IFNULL(NULLIF(#{pmenuId},''),'ROOT')
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+
+	<!-- 메뉴권한 삭제 -->
+	<delete id="deleteMenuRole" parameterType="String">
+		/* TsaSystem.deleteMenuRole */
+		DELETE FROM TB_MENU_ROLE
+		WHERE  MENU_ID = #{menuId}
+	</delete>
+
+	<!-- 메뉴권한 생성 -->
+	<insert id="createMenuRole" parameterType="MenuRole">
+		/* TsaSystem.createMenuRole */
+		INSERT INTO TB_MENU_ROLE (
+		       ROLE_CD
+		     , MENU_ID
+		     , USE_ROLE
+		     , REG_NO
+		     , REG_DT
+		)
+		VALUES (
+		       #{roleCd}
+		     , #{menuId}
+		     , IFNULL(NULLIF(#{useRole},''),'RCUD')
+		     , #{regNo}
+		     , NOW()
+		)
+	</insert>
+
+	<!-- 전체 사용자 메뉴 삭제 -->
+	<delete id="deleteAllUserMenu" parameterType="MenuRole">
+		/* TsaSystem.deleteAllUserMenu */
+		DELETE
+		FROM   TB_USER_MENU
+		WHERE  USER_NO IN (SELECT USER_NO
+		                   FROM   TB_USER
+		                   WHERE  ROLE_CD = #{roleCd}
+		                  )
+		AND    MENU_ID = #{menuId}
+	</delete>
+
+	<!-- 전체 사용자 메뉴 생성-->
+	<insert id="createAllUserMenu" parameterType="MenuRole">
+		/* TsaSystem.createAllUserMenu */
+		INSERT INTO TB_USER_MENU (
+		       USER_NO
+		     , MENU_ID
+		     , USE_ROLE
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		SELECT B.USER_NO
+		     , A.MENU_ID
+		     , A.USE_ROLE
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		FROM   TB_MENU_ROLE A
+		INNER JOIN TB_USER B ON A.ROLE_CD = B.ROLE_CD
+		WHERE  A.ROLE_CD = #{roleCd}
+		AND    A.MENU_ID = #{menuId}
+		AND    B.USE_YN = 'Y'
+		ON DUPLICATE KEY UPDATE
+		       USE_ROLE = A.USE_ROLE
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+
+	<!-- 사용자 전체 메뉴 삭제 -->
+	<delete id="deleteUserAllMenu" parameterType="Integer">
+		/* TsaSystem.deleteUserAllMenu */
+		DELETE
+		FROM   TB_USER_MENU
+		WHERE  USER_NO = #{userNo}
+	</delete>
+
+	<!-- 사용자 전체 메뉴 생성 -->
+	<insert id="createUserAllMenu" parameterType="User">
+		/* TsaSystem.createUserAllMenu */
+		INSERT INTO TB_USER_MENU (
+		       USER_NO
+		     , MENU_ID
+		     , USE_ROLE
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		SELECT A.USER_NO
+		     , B.MENU_ID
+		     , B.USE_ROLE
+		     , #{regNo}     AS REG_NO
+		     , NOW()        AS REG_DT
+		     , #{updNo}     AS UPD_NO
+		     , NOW()        AS UPD_DT
+		FROM   TB_USER A
+		INNER JOIN TB_MENU_ROLE B ON A.ROLE_CD = B.ROLE_CD
+		WHERE  A.USER_NO = #{userNo}
+		AND    A.ROLE_CD = #{roleCd}
+	</insert>
+
+	<!-- 사용자 메뉴 삭제 -->
+	<delete id="deleteUserMenu" parameterType="UserMenu">
+		/* TsaSystem.deleteUserMenu */
+		DELETE
+		FROM   TB_USER_MENU
+		WHERE  USER_NO = #{userNo}
+		AND    MENU_ID = #{menuId}
+	</delete>
+
+	<!-- 사용자 메뉴 Insert/Update -->
+	<insert id="createUserMenu" parameterType="UserMenu">
+		/* TsaSystem.createUserMenu */
+		INSERT INTO TB_USER_MENU (
+		       USER_NO
+		     , MENU_ID
+		     , USE_ROLE
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{userNo}
+		     , #{menuId}
+		     , #{useRole}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       USE_ROLE = #{useRole}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+	
+	<!-- 메뉴접속이력 생성 -->
+	<insert id="createMenuAccessHistory" parameterType="MenuAccessHst">
+		/* TsaSystem.createMenuAccessHistory */
+		INSERT INTO TB_MENU_ACCESS_HST (
+		       MENU_ACCESS_SQ
+		     , USER_NO
+		     , MENU_ID
+		     , REQ_URL
+		     , PARAMS
+		     , REG_NO
+		     , REG_DT
+		)
+		VALUES (
+		       NULL
+		     , #{userNo}
+		     , #{menuId}
+		     , #{reqUrl}
+		     , #{params}
+		     , #{userNo}
+		     , NOW()
+		)
+	</insert>
+
+	<!-- 공통코드 목록 -->
+	<select id="getCommonCodeList" parameterType="CommonCode" resultType="CommonCode">
+		/* TsaSystem.getCommonCodeList */
+		SELECT CD_GB
+		     , CD
+		     , CD_NM
+		     , CD_DESC
+		     , DISP_ORD
+		     , USE_YN
+		     , DISP_ORD
+		FROM   TB_COMMON_CODE
+		WHERE  CD_GB = #{cdGb}
+		ORDER  BY DISP_ORD
+	</select>
+
+	<!-- 공통코드 등록/수정 -->
+	<insert id="saveCommonCode" parameterType="CommonCode">
+		/* TsaSystem.saveCommonCode */
+		INSERT INTO TB_COMMON_CODE (
+		       CD_GB
+		     , CD
+		     , CD_NM
+		     , CD_DESC
+		     , DISP_ORD
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{cdGb}
+		     , #{cd}
+		     , #{cdNm}
+		     , #{cdDesc}
+		     , #{dispOrd}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       CD_NM = #{cdNm}
+		     , CD_DESC = #{cdDesc}
+		     , DISP_ORD = #{dispOrd}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+
+	<!-- 공통코드 삭제 -->
+	<delete id="deleteCommonCode" parameterType="CommonCode">
+		/* TsaSystem.deleteCode */
+		DELETE FROM TB_COMMON_CODE
+		WHERE  CD_GB = #{cdGb}
+		AND    CD = #{cd}
+	</delete>
+	
+	<!-- 샘플파일 목록 -->
+	<select id="getSampleFileList" resultType="SampleFile">
+		/* TsaSystem.getSampleFileList */
+		SELECT SAMPLE_FILE_ID
+		     , SAMPLE_FILE_NM
+		     , ORG_FILE_NM
+		     , SYS_FILE_NM
+		     , USE_YN
+		FROM   TB_SAMPLE_FILE
+		ORDER  BY SAMPLE_FILE_NM
+	</select>
+
+	<!-- 샘플파일 등록/수정 -->
+	<insert id="createSampleFile" parameterType="SampleFile">
+		/* TsaSystem.createSampleFile */
+		INSERT INTO TB_SAMPLE_FILE (
+		       SAMPLE_FILE_ID
+		     , SAMPLE_FILE_NM
+		     , ORG_FILE_NM
+		     , SYS_FILE_NM
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       (SELECT CONCAT('SF',IFNULL(LPAD(CAST(SUBSTRING(MAX(SAMPLE_FILE_ID),3) AS UNSIGNED) + 1,3,'0'),'000'))
+		        FROM   TB_SAMPLE_FILE Z
+		       )
+		     , #{sampleFileNm}
+		     , #{orgFileNm}
+		     , #{sysFileNm}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+	</insert>
+	
+	<!-- 샘플파일 등록/수정 -->
+	<update id="updateSampleFile" parameterType="SampleFile">
+		/* TsaSystem.updateSampleFile */
+		UPDATE TB_SAMPLE_FILE
+		SET    SAMPLE_FILE_NM = #{sampleFileNm}
+		     , ORG_FILE_NM = #{orgFileNm}
+		     , SYS_FILE_NM = #{sysFileNm}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  SAMPLE_FILE_ID = #{sampleFileId}
+	</update>
+	
+	<!-- 알람 목록 -->
+	<select id="getAlarmList" parameterType="Alarm" resultType="Alarm">
+		/* TsaSystem.getAlarmList */
+		SELECT ALARM_ID
+		     , ALARM_TITLE
+		     , ALARM_MSG
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		FROM   TB_ALARM
+		WHERE  1 = 1
+		<if test="alarmId != null and alarmId != ''">
+		AND    ALARM_ID = #{alarmId}
+		</if>
+		<if test="alarmTitle != null and alarmTitle != ''">
+		AND    ALARM_TITLE LIKE CONCAT('%',#{alarmTitle},'%')
+		</if>
+		ORDER  BY ALARM_ID
+	</select>
+
+	<!-- 알람 저장 -->
+	<insert id="createAlarm" parameterType="Alarm">
+		/* TsaSystem.createAlarm */
+		INSERT INTO TB_ALARM (
+		       ALARM_ID
+		     , ALARM_TITLE
+		     , ALARM_MSG
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		        (SELECT CONCAT('A',IFNULL(LPAD(SUBSTRING(MAX(ALARM_ID),3) + 1,3,'0'),'000'))
+		         FROM   TB_ALARM Z
+		        )
+		      , #{alarmTitle}
+		      , #{alarmMsg}
+		      , #{useYn}
+		      , #{regNo}
+		      , NOW()
+		      , #{updNo}
+		      , NOW()
+		)
+	</insert>
+	
+	<!-- 알람 수정 -->
+	<update id="updateAlarm" parameterType="Alarm">
+		/* TsaSystem.updateAlarm */
+		UPDATE TB_ALARM
+		SET    ALARM_TITLE = #{alarmTitle}
+		     , ALARM_MSG = #{alarmMsg}
+		     , USE_YN = #{useYn}
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  ALARM_ID = #{alarmId}
+	</update>
+
+	<!-- 알람 삭제 -->
+	<delete id="deleteAlarm" parameterType="Alarm">
+		/* TsaSystem.deleteAlarm */
+		UPDATE TB_ALARM
+		SET    USE_YN = 'N'
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  ALARM_ID = #{alarmId}
+	</delete>
+
+	<!-- 알람수신자 목록 -->
+	<select id="getAlarmReceiverList" parameterType="String" resultType="Alarm">
+		/* TsaSystem.getAlarmReceiverList */
+		SELECT ALARM_ID
+		     , CELL_PHNNO
+		     , RECEIVER_NM
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		FROM   TB_ALARM_RECEIVER
+		WHERE  ALARM_ID = #{alarmId}
+	</select>
+
+	<!-- 알람수신자 저장 -->
+	<insert id="saveAlarmReceiver" parameterType="AlarmReceiver">
+		/* TsaSystem.saveAlarmReceiver */
+		INSERT INTO TB_ALARM_RECEIVER (
+		       ALARM_ID
+		     , CELL_PHNNO
+		     , RECEIVER_NM
+		     , USE_YN
+		     , REG_NO
+		     , REG_DT
+		     , UPD_NO
+		     , UPD_DT
+		)
+		VALUES (
+		       #{alarmId}
+		     , #{cellPhnno}
+		     , #{receiverNm}
+		     , #{useYn}
+		     , #{regNo}
+		     , NOW()
+		     , #{updNo}
+		     , NOW()
+		)
+		ON DUPLICATE KEY UPDATE
+		       RECEIVER_NM = #{receiverNm}
+		     , USE_YN = #{useYn}
+		     , UPD_ID = #{updNo}
+		     , UPD_DT = NOW()
+	</insert>
+
+	<!-- 시스템알람 수신자 삭제 -->
+	<delete id="deleteAlarmReceiver" parameterType="AlarmReceiver">
+		/* TsaSystem.deleteAlarmReceiver */
+		UPDATE TB_ALARM_RECEIVER
+		SET    USE_YN = 'N'
+		     , UPD_NO = #{updNo}
+		     , UPD_DT = NOW()
+		WHERE  ALARM_ID = #{alarmId}
+		AND    CELL_PHNNO = #{cellPhnno}
+	</delete>
+
 </mapper>

+ 185 - 233
style24.admin/src/main/webapp/WEB-INF/views/system/SystemAlarmForm.html

@@ -6,226 +6,206 @@
  * @source  : SystemAlarmForm.html
  * @desc    : 시스템알람관리 화면 Page
  *=============================================================
- * Wivismall
- * Copyright(C) 2019 TSIT, All rights reserved.
+ * STYLE24
+ * Copyright(C) 2020 TSIT, All rights reserved.
  *=============================================================
  * VER  DATE         AUTHOR      DESCRIPTION
  * ===  ===========  ==========  ==================================
- * 1.0  2020.05.19   yujung      최초 작성
+ * 1.0  2020.11.13   yujung      최초 작성
  *******************************************************************************
  -->
 	<div id="main">
+		<!-- 메인타이틀 영역 -->
 		<div class="main-title">
 		</div>
-
-		<div class="panelStyle2">
+		<!-- //메인타이틀 영역 -->
+		
+		<!-- 메뉴 설명 -->
+		<div class="infoBox menu-desc">
+		</div>
+		<!-- //메뉴 설명 -->
+		
+		<!-- 검색조건 영역 -->
+		<div class="panelStyle">
+			<!-- Search -->
 			<form id="searchForm" name="searchForm" action="#" th:action="@{'/system/alarm/list'}" onsubmit="$('#btnSearch').trigger('click'); return false;">
 				<table class="frmStyle" aria-describedby="검색조건">
 					<colgroup>
-						<col style="width:80px;"/>
-						<col style="width:500px;"/>
+						<col style="width:10%;"/>
 						<col/>
 					</colgroup>
 					<tbody>
 						<tr>
-							<th class="dashR">알람제목</th>
-							<td class="dashR">
-								<input type="text" name="alarmTitle" class="w300"/>
+							<th>알람제목</th>
+							<td>
+								<input type="text" class="w300" name="alarmTitle" maxlength="100"/>
 							</td>
 						</tr>
 					</tbody>
 				</table>
-				<div class="panelBtnB">
-					<input type="button" value="초기화" class="btn btn-gray btn-lg" id="btnReset" onclick="$('#searchForm')[0].reset();"/>
-					<input type="button" value="조회" class="btn btn-base btn-lg" id="btnSearch" onclick="fnSearch();"/>
-				</div>
+				
+				<ul class="panelBar">
+					<li class="center">
+						<button type="button" class="btn btn-base btn-lg" id="btnSearch">조회</button>
+						<button type="button" class="btn btn-gray btn-lg" onclick="$('#searchForm')[0].reset();">초기화</button>
+					</li>
+				</ul>
 			</form>
 		</div>
-		
-		<div class="panelStyle2">
-			<table class="frmStyle">
-				<colgroup>
-					<col style="width:60%;"/>
-					<col/>
-				</colgroup>
-				<tr>
-					<td style="border-top: none;">
-						<ul class="lrStyle">
-							<li class="padB10">
-								<h4 style="margin-top: -10px;">알람목록</h4>
-							</li>
-						</ul>
-						
-						<div class="panelContent" style="overflow: hidden;">
-							<div id="alarmGridList" style="width: 100%; height: 630px;" class="ag-theme-balham"></div>
-						</div>
-					</td>
-					<td style="border-top: none; vertical-align: top;">
-						<ul class="lrStyle">
-							<li class="padB10">
-								<button type="button" class="btn btn-info btn-lg" id="btnNew">신규</button>
-								<button type="button" class="btn btn-success btn-lg" id="btnSave">저장</button>
-							</li>
-						</ul>
+		<!-- //검색조건 영역 -->
+
+		<div class="panelStyle">
+			<!-- 다중 TABLE 배치 -->
+			<ul class="division">
+				<li style="width: 60%">
+					<div class="panelBar">
+						<h4>알람목록</h4>
+					</div>
+					<div id="gridList1" style="width: 100%; height: 570px" class="ag-theme-balham"></div>
+				</li>
+				<li style="width: 40%">
+					<!-- 버튼 배치 영역 -->
+					<ul class="panelBar">
+						<li>
+							<button type="button" class="btn btn-info btn-lg" id="btnNew">신규</button>
+							<button type="button" class="btn btn-success btn-lg" id="btnSave">알람 저장</button>
+						</li>
+					</ul>
+					<!-- //버튼 배치 영역 -->
+					
+					<form id="detailForm" name="detailForm" action="#" th:action="@{'/system/alarm/save'}">
+						<input type="hidden" name="mode" value="N"/>
 						
-						<form id="detailForm" name="detailForm" action="#" th:action="@{'/system/basic/answer/save'}">
-							<table >
-								<colgroup>
-									<col style="width:10%;"/>
-									<col style="width:20%;"/>
-									<col style="width:10%;"/>
-									<col style="width:20%;"/>
-									<col style="width:10%;"/>
-									<col style="width:20%;"/>
-									<col/>
-								</colgroup>
-								<tr>
-									<th>알람ID<i class="star"></i></th>
-									<td>
-										<input type="text" name="alarmId" readonly="readonly" placeholder="자동생성"/><!-- required="required" data-valid-name="알람ID" -->
-									</td>
-									
-									<th>사용여부</th>
-									<td>
-										<input type="hidden" name="useYn" value="Y"/>
-										<label><input type="checkbox" name="chkUseYn" checked="checked"/>사용</label>
-									</td>
-								</tr>
-								<tr>
-									<th>알람제목<i class="star"></i></th>
-									<td colspan="3">
-										<input type="text" name="alarmTitle" required="required" data-valid-name="알람제목"/>
-									</td>
-								</tr>
-								<tr>
-									<th>알람메세지<i class="star"></i><br/>(<span name="count"> 0 </span> / 80 byte)</th>
-									<td colspan="9">
-										<input type="text" name="alarmMsg" required="required" data-valid-name="알람메시지"/>
-									</td>
-								</tr>
-								<tr>
-									<td colspan="4" style="padding-left: 0px;padding-right: 0px;">
-										<div class="aL">
-											<h4>알람 수신자</h4>
-											<button type="button" class="btn btn-warning btn-sm" id="btnAddRow">행추가</button>
-											<button type="button" class="btn btn-danger btn-sm" id="btnDeleteRow">행삭제</button>
-											<button type="button" class="btn btn-success btn-lg" id="btnReciverSave" style="margin-left:335px;">저장</button>
-										</div>
-										
-										<input type="hidden" id="reciverAlarmId"/>
-										<div id="receiverGridList" style="width: 100%; height: 455px;" class="ag-theme-balham"></div>
-									</td>
-								</tr>
-							</table>
-						</form>
-					</td>
-				</tr>
-			</table>
+						<table class="frmStyle" aria-describedby="등록/수정폼">
+							<colgroup>
+								<col style="width:20%;"/>
+								<col style="width:30%;"/>
+								<col style="width:20%;"/>
+								<col/>
+							</colgroup>
+							<tr>
+								<th>알람ID<i class="required" title="필수" aria-hidden="true"></i></th>
+								<td>
+									<input type="text" name="alarmId" placeholder="자동생성" readonly="readonly"/>
+								</td>
+								<th>사용여부</th>
+								<td>
+									<input type="hidden" name="useYn" value="Y"/>
+									<label class="chkBox"><input type="checkbox" name="chkUseYn" checked="checked"/>사용</label>
+								</td>
+							</tr>
+							<tr>
+								<th>알람제목<i class="required" title="필수" aria-hidden="true"></i></th>
+								<td colspan="3">
+									<input type="text" name="alarmTitle" required="required" data-valid-name="알람제목"/>
+								</td>
+							</tr>
+							<tr>
+								<th>알람메세지<i class="required" title="필수" aria-hidden="true"></i><br/>(<span id="alarmMsgCnt">0</span> / 80 byte)</th>
+								<td colspan="3">
+									<input type="text" name="alarmMsg" required="required" data-valid-name="알람메시지"/>
+								</td>
+							</tr>
+						</table>
+					</form>
+					
+					<ul class="panelBar">
+						<li>
+							<h4>알람 수신자</h4>
+						</li>
+						<li class="right">
+							<button type="button" class="btn btn-warning btn-lg" id="btnAddRow">행추가</button>
+							<button type="button" class="btn btn-danger btn-lg" id="btnDeleteRow">행삭제</button>
+							<button type="button" class="btn btn-success btn-lg" id="btnSaveReceiver">알람수신자 저장</button>
+						</li>
+					</ul>
+					
+					<div id="gridList2" style="width: 100%; height: 385px" class="ag-theme-balham"></div>
+				</li>
+			</ul>
 		</div>
-		
 	</div>
 
 <script th:inline="javascript">
 /*<![CDATA[*/
-
-	var useYnList = { "Y":"Yes", "N":"No" };
+	let ynList = { "Y":"Yes", "N":"No" };
 	
-	var alarmColumnDefs = [
-// 		{headerName: "삭제",		field:'delete',			width:60,	cellClass: 'text-center'
-// 			, cellRenderer: function(params) {
-// 				return "<a href=\"javascript:void(0);\" class=\"btn btn-danger btn-sm\">삭제</a>";
-// 			}
-// 		},
-		{headerName: "알람ID",		field:'alarmId',		width:100,	cellClass: 'text-center'
-// 			, cellRenderer: function(params) { return '<a href=\"javascript:void(0);\">' + params.value + '</a>'; }
-		},
-		{headerName: "알람제목",	field:'alarmTitle',		width:250,	cellClass: 'text-left'
-			, cellRenderer: function(params) { return '<a href=\"javascript:void(0);\">' + params.value + '</a>'; }
-		},
-		{headerName: "알람메세지",	field:'alarmMsg',		width:455,	cellClass: 'text-left'},
-		{headerName: "사용여부",	field:'useYn',			width:80,	cellClass: 'text-center'},
-		
-		{headerName: "등록자",		field:'regId',			width:120,	cellClass: 'text-center', hide: true},
-		{headerName: "등록일시",	field:'regDt',			width:150,	cellClass: 'text-center', hide: true,
+	let columnDefs1 = [
+		{
+			headerName: "알람ID", field: "alarmId", width: 100, cellClass: 'text-center',
 			cellRenderer: function(params) {
-				return !gagajf.isNull(params.value) ? params.value.toDate("YYYY/MM/DD HH:mm:ss").format("YYYY-MM-DD HH:mm:ss") : '';
-			}	
+				return '<a href=\"javascript:void(0);\">' + params.value + '</a>';
+			}
 		},
-		{headerName: "수정자",		field:'updId',			width:120,	cellClass: 'text-center', hide: true},
-		{headerName: "수정일시",	field:'updDt',			width:150,	cellClass: 'text-center', hide: true,
-			cellRenderer: function(params) {
-				return !gagajf.isNull(params.value) ? params.value.toDate("YYYY/MM/DD HH:mm:ss").format("YYYY-MM-DD HH:mm:ss") : '';
-			}	
+		{headerName: "알람제목", field: "alarmTitle", width: 250},
+		{headerName: "알람메세지", field: "alarmMsg", width: 450},
+		{
+			headerName: "사용여부", field: "useYn", width: 80, cellClass: 'text-center',
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(ynList, params.value); }
 		}
 	];
 	
-	var receiverColumnDefs = [
+	let columnDefs2 = [
 		{width: 40, minWidth: 40, cellClass: 'text-center', headerCheckboxSelection: true, checkboxSelection: true, filter: false},
-		{headerName: "알람ID",		field:'alarmId',		width:100,	cellClass: 'text-center', editable:false},
-		{headerName: "수신자명",	field:'receiverNm',		width:100,	cellClass: 'text-center', cellEditorParams: { maxlength: 4, required: true }},
-		{headerName: "수신자번호",	field:'cellPhnno',		width:150,	cellClass: 'text-center', cellEditorParams: { maxlength: 11, required: true }},
-		{headerName: "사용여부",	field:'useYn',			width:80,	cellClass: 'text-center',
-			cellEditor: 'agRichSelectCellEditor',
-			cellEditorParams: { values: gagaAgGrid.extractValues(useYnList), maxlength: 20, required: true},
-			valueFormatter: function (params) { return gagaAgGrid.lookupValue(useYnList, params.value); },
-			valueParser: function (params) { return gagaAgGrid.lookupKey(useYnList, params.newValue); }	
+		{headerName: "CRUD", field: "crud", width: 75, hide: true},
+		{headerName: "알람ID", field: "alarmId", width: 100, cellClass: 'text-center', editable: false},
+		{
+			headerName: "수신자명", field: "receiverNm", width: 100, cellClass: 'text-center',
+			cellEditorParams: { maxlength: 4, required: true }
 		},
-		{headerName: "등록자",		field:'regId',			width:120,	cellClass: 'text-center', hide: true},
-		{headerName: "등록일시",	field:'regDt',			width:150,	cellClass: 'text-center', hide: true,
-			cellRenderer: function(params) {
-				return !gagajf.isNull(params.value) ? params.value.toDate("YYYY/MM/DD HH:mm:ss").format("YYYY-MM-DD HH:mm:ss") : '';
-			}	
+		{
+			headerName: "수신자번호", field: "cellPhnno", width: 150, cellClass: 'text-center',
+			cellEditorParams: { maxlength: 11, required: true }
 		},
-		{headerName: "수정자",		field:'updId',			width:120,	cellClass: 'text-center', hide: true},
-		{headerName: "수정일시",	field:'updDt',			width:150,	cellClass: 'text-center', hide: true,
-			cellRenderer: function(params) {
-				return !gagajf.isNull(params.value) ? params.value.toDate("YYYY/MM/DD HH:mm:ss").format("YYYY-MM-DD HH:mm:ss") : '';
-			}	
+		{
+			headerName: "사용여부", field: 'useYn', width: 80, cellClass: 'text-center',
+			cellEditor: 'agRichSelectCellEditor',
+			cellEditorParams: { values: gagaAgGrid.extractValues(ynList), maxlength: 20, required: true},
+			valueFormatter: function (params) { return gagaAgGrid.lookupValue(ynList, params.value); },
+			valueParser: function (params) { return gagaAgGrid.lookupKey(ynList, params.newValue); }
 		}
 	]
 	
+	// Get GridOptions
+	let gridOptions1 = gagaAgGrid.getGridOptions(columnDefs1);
+	let gridOptions2 = gagaAgGrid.getGridOptions(columnDefs2);
 	
-	var alarmGridOptions = gagaAgGrid.getGridOptions(alarmColumnDefs);
-	var receiverGridOptions = gagaAgGrid.getGridOptions(receiverColumnDefs);
-	receiverGridOptions.rowSelection = 'multiple';
-	receiverGridOptions.defaultColDef.editable = true;
-	receiverGridOptions.stopEditingWhenGridLosesFocus = true;
+	// 수정 가능
+	gridOptions2.defaultColDef.editable = true;
+	
+	// 중복 선택 가능
+	gridOptions2.rowSelection = 'multiple';
+	
+	gridOptions2.stopEditingWhenGridLosesFocus = true;
 	
 	// 셀 클릭 이벤트
-	alarmGridOptions.onCellClicked = function(event) {
-		if (event.colDef.field == 'alarmTitle') {
-			fnReceiverSearch(event.data.alarmId);
-			fnBindData(event.data);
-		}
-		
+	gridOptions1.onCellClicked = function(event) {
 		if (event.colDef.field == 'alarmId') {
-// 			fnReceiverSearch(event.data.alarmId);
-		}
-		
-		if (event.colDef.field == 'delete') {
-// 			fnDeleteAlarm(event.data.alarmId);
+			$('#detailForm input[name=mode]').val('U');
+			$('#detailForm input[name=alarmId]').val(event.data.alarmId);
+			$('#detailForm input[name=alarmTitle]').val(event.data.alarmTitle);
+			$('#detailForm input[name=alarmMsg]').val(event.data.alarmMsg);
+			
+			$("#detailForm input[name=useYn]").val(event.data.useYn);
+			if (event.data.useYn == 'Y') {
+				$("#detailForm input:checkbox[name=chkUseYn]").prop('checked', true);
+			} else {
+				$("#detailForm input:checkbox[name=chkUseYn]").prop('checked', false);
+			}
+			
+			// 수신자 목록
+			fnSearchReceiverList();
 		}
 	}
 	
-	// 바인딩
-	var fnBindData = function(data) {
-		$('#detailForm input[name=alarmId]').val(data.alarmId);
-		$('#detailForm input[name=alarmTitle]').val(data.alarmTitle);
-		$('#detailForm input[name=alarmMsg]').val(data.alarmMsg);
-		
-		if (data.useYn == 'Y') {
-			$("#detailForm input:checkbox[name=chkUseYn]").prop('checked', true);
-			$("#detailForm input:checkbox[name=chkUseYn]").parent().addClass('checked');
-		} else {
-			$("#detailForm input:checkbox[name=chkUseYn]").prop('checked', false);
-			$("#detailForm input:checkbox[name=chkUseYn]").parent().removeClass('checked');
-		}
-		
-	}
-	// 검색
-	var fnSearch = function() {
-		var formId = '#searchForm';
-		gagaAgGrid.fetch($(formId).prop('action'), alarmGridOptions, formId);
+	$('#btnSearch').on('click', function() {
+		gagaAgGrid.fetch($('#searchForm').prop('action'), gridOptions1, '#searchForm');
+	});
+	
+	// 수신자 목록 조회
+	var fnSearchReceiverList = function() {
+		let actionUrl = '/system/alarm/receiver/list/' + $('#detailForm input[name=alarmId]').val();
+		gagaAgGrid.fetch(actionUrl, gridOptions2);
 	}
 	
 	// 신규
@@ -233,69 +213,41 @@
 		$('#detailForm')[0].reset();
 		$('#detailForm input[name=alarmId]').val('');
 		$('#detailForm input[name=alarmTitle]').focus();
-		receiverGridOptions.api.setRowData('');
+		gridOptions2.api.setRowData('');
 	});
 	
-	// 저장/수정
+	// 알람 저장
 	$("#btnSave").on("click", function() {
-		var formId = '#detailForm';
-
-		if (!gagajf.validation(formId))
+		if (!gagajf.validation('#detailForm'))
 			return;
 	
-		var msg = '수정하시겠습니까?';
-		if (gagajf.isNull($('#detailForm input[name=alarmId]').val())) msg = '등록하시겠습니까?'; 
-		
-		mcxDialog.confirm(msg, {
+		mcxDialog.confirm('저장하시겠습니까?', {
 			cancelBtnText: "취소",
 			sureBtnText: "확인",
 			sureBtnClick: function() {
-				$(formId + ' input[name=useYn]').val($(formId + ' input:checkbox[name=chkUseYn]').is(":checked") ? 'Y' : 'N');	// 사용여부
-				gagajf.ajaxFormSubmit('/system/alarm/save', formId, fnSearch);
+				$('#detailForm input[name=useYn]').val($('#detailForm input:checkbox[name=chkUseYn]').is(":checked") ? 'Y' : 'N'); // 사용여부
+				gagajf.ajaxFormSubmit('/system/alarm/save', '#detailForm', function() {
+					$('#btnSearch').trigger('click');
+				});
 			}
 		});
 	});
 	
-	// 삭제
-	var fnDeleteAlarm = function(alarmId) {
-		mcxDialog.confirm('삭제하시곘습니까?', {
-			cancelBtnText: "취소",
-			sureBtnText: "확인",
-			sureBtnClick: function() {
-				var data = {alarmId : alarmId};
-				var jsonData = JSON.stringify(data);
-				gagajf.ajaxJsonSubmit('/system/alarm/delete', jsonData, fnSearch);
-			}
-		});
-	}
-	
-	// 수신자 관련 함수
-	// 수신자 조회
-	var fnReceiverSearch = function(alarmId) {
-		$('#reciverAlarmId').val(alarmId);
-		
-		var data = {alarmId : alarmId};
-		var jsonData = JSON.stringify(data);
-
-		gagajf.ajaxJsonSubmit('/system/alarm/reciver/list', jsonData, function(result) {
-			receiverGridOptions.api.setRowData(result);
-		});
-	}
-	
 	// 행추가
 	$('#btnAddRow').on('click', function() {
-		var alarmId = $('#reciverAlarmId').val();
+		var alarmId = $('#detailForm input[name=alarmId]').val();
 		if (gagajf.isNull(alarmId)) {
-			mcxDialog.alert('알람ID를 선택해 주세요.');
+			mcxDialog.alert('알람목록에서 알람ID를 선택해 주세요.');
 			return;
 		}
+		
 		var data = { alarmId: alarmId, receiverNm: null, cellPhnno: null, useYn: "Y" };
-		gagaAgGrid.addRowData(receiverGridOptions, data, 'alarmId');
+		gagaAgGrid.addRowData(gridOptions2, data, 'alarmId');
 	});
 	
 	// 행삭제
 	$('#btnDeleteRow').on('click', function() {
-		var removedData = gagaAgGrid.removeRowData(receiverGridOptions);
+		var removedData = gagaAgGrid.removeRowData(gridOptions2);
 		
 		if (removedData.length == 0) {
 			mcxDialog.alert('선택된 행이 없습니다.');
@@ -307,24 +259,29 @@
 			sureBtnText: "확인",
 			sureBtnClick: function() {
 				var jsonData = JSON.stringify(removedData);
-				gagajf.ajaxJsonSubmit('/system/alarm/reciver/delete', jsonData, function() {
-					fnReceiverSearch($('#reciverAlarmId').val());
+				gagajf.ajaxJsonSubmit('/system/alarm/receiver/delete', jsonData, function() {
+					fnSearchReceiverList();
 				});
 			}
 		});
 	});
 	
-	// 바이트
+	// 알람메시지 Byte 계산
 	$("#detailForm input[name=alarmMsg]").bind('focus focusout input keyup keydown paste change', function () {
-		cfnGetTextLength($(this), 80, $('#detailForm span[name=count]'));
+		cfnGetTextLength($(this), 80, $('#alarmMsgCnt'));
 	});
 	
-	// 저장
-	$('#btnReciverSave').on('click', function() {
-		var changedData = gagaAgGrid.getChangedData(receiverGridOptions);
+	// 알람수신자 저장
+	$('#btnSaveReceiver').on('click', function() {
+		var changedData = gagaAgGrid.getChangedData(gridOptions2);
+		
+		if (changedData.length == 0) {
+			mcxDialog.alert('변경된 데이터가 없습니다.');
+			return;
+		}
 		
 		// Validation
-		if (!gagaAgGrid.validation(receiverGridOptions, changedData))
+		if (!gagaAgGrid.validation(gridOptions2, changedData))
 			return;
 		
 		var Msg = '';
@@ -332,7 +289,7 @@
 			item.cellPhnno.replaceAll("-", "");
 			
 			var regexp = /^[0-9]*$/
-			if( !regexp.test(item.cellPhnno) ) {
+			if (!regexp.test(item.cellPhnno)) {
 				Msg = '휴대전화번호는 숫자를 입력해주세요.';
 				return;
 			}
@@ -353,22 +310,17 @@
 			sureBtnText: "확인",
 			sureBtnClick: function() {
 				var jsonData = JSON.stringify(changedData);
-				gagajf.ajaxJsonSubmit('/system/alarm/reciver/save', jsonData, function() {
-					fnReceiverSearch($('#reciverAlarmId').val());
+				gagajf.ajaxJsonSubmit('/system/alarm/receiver/save', jsonData, function() {
+					fnSearchReceiverList();
 				});
 			}
 		});
 	});
 	
 	$(document).ready(function() {
-		gagaAgGrid.createGrid('alarmGridList', alarmGridOptions);
-		gagaAgGrid.createGrid('receiverGridList', receiverGridOptions);
-		
-		// Grid 높이 자동 조정
-		uifnFitGrid(50);
-		fnSearch();
+		gagaAgGrid.createGrid('gridList1', gridOptions1);
+		gagaAgGrid.createGrid('gridList2', gridOptions2);
 	});
-
 /*]]>*/
 </script>
 

+ 25 - 0
style24.core/src/main/java/com/style24/persistence/domain/Alarm.java

@@ -0,0 +1,25 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 알람 Domain
+ * 
+ * @author gagamel
+ * @since 2020. 11. 13
+ */
+@SuppressWarnings("serial")
+@Data
+public class Alarm extends TscBaseDomain {
+
+	private String alarmId;		// 알람ID
+	private String alarmTitle;	// 알람제목
+	private String alarmMsg;	// 알람메시지
+	private String useYn;		// 사용여부
+
+	private String fuserid;		// 사용자계정
+	private String fcallback;	// 발신자전화번호(회신번호)
+
+}

+ 21 - 0
style24.core/src/main/java/com/style24/persistence/domain/AlarmReceiver.java

@@ -0,0 +1,21 @@
+package com.style24.persistence.domain;
+
+import com.style24.persistence.TscBaseDomain;
+
+import lombok.Data;
+
+/**
+ * 알람수신자 Domain
+ * 
+ * @author gagamel
+ * @since 2020. 11. 13
+ */
+@SuppressWarnings("serial")
+@Data
+public class AlarmReceiver extends TscBaseDomain {
+
+	private String alarmId;		// 알람ID
+	private String cellPhnno;	// 휴대전화번호
+	private String receiverNm;	// 수신자명
+
+}