/** 
 * AdminController.java
 * @author 임새미 
 * @since 2016. 10. 27.
 *
 *  	 수정일                     수정자                                       수정내용
 *  -------------	--------	---------------------------
 *  2016. 10. 27. 	    임새미				       최초생성
 * 
 */
package kcg.faics.admin.web;

import java.net.URLEncoder;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import kcg.faics.admin.vo.LogSearchVO;
import kcg.faics.cmmn.excel.ExcelExporter;
import kcg.faics.cmmn.service.CodeService;
import kcg.faics.cmmn.service.LogService;
import kcg.faics.cmmn.vo.CodeVO;
import kcg.faics.member.UserType;
import kcg.faics.member.service.MemberAuthService;
import kcg.faics.member.service.MemberService;
import kcg.faics.member.vo.MemberSearchVO;
import kcg.faics.member.vo.MemberVO;
import kcg.faics.sec.LoginUserVO;
import kcg.faics.sec.UserUtil;
import kcg.faics.sec.service.impl.SecurityMapper;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.session.SessionInformation;
import org.springframework.security.core.session.SessionRegistry;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import egovframework.rte.fdl.property.EgovPropertyService;
import egovframework.rte.fdl.security.userdetails.EgovUserDetails;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationInfo;

/** 
 * AdminController.java
 * @author 임새미 
 * @since 2016. 10. 27.
 *
 *  	 수정일                     수정자                                       수정내용
 *  -------------	--------	---------------------------
 *  2016. 10. 27. 	    임새미				       최초생성
 * 
 */
@Controller
@RequestMapping("/admin")
public class AdminController {
	
	@Resource(name = "propertiesService")
	private EgovPropertyService propertiesService;
	
	@Resource(name = "codeService")
	CodeService codeService;
	
	@Resource(name = "memberService")
	MemberService memberService;
	
	@Resource(name = "memberAuthService")
	MemberAuthService memberAuthService;
	
	@Resource(name = "logService")
	LogService logService;
	
	
	/**
	 * 외사경찰 등록화면을 반환한다.
	 * 
	 * @param memberVO modelAttribute 객체
	 * @param model 모델 객체
	 * @return 외사경찰 등록화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "/faMemberAdd.do", method=RequestMethod.GET)
	public String faMemberAddView(@ModelAttribute("memberVO") final MemberVO memberVO, Model model) throws Exception {
		/* 외사경찰 */
		memberVO.setUsertype(UserType.FA);
		
		model.addAttribute("memberVO", new MemberVO());
		model.addAttribute("place1List", codeService.getPlace1List(false));
		model.addAttribute("positionList", codeService.getPositionList());
		model.addAttribute("dutiesList", codeService.getDutiesList());
		model.addAttribute("jobTypeList", codeService.getJobTypeList());
		model.addAttribute("scholarshipList", codeService.getScholarshipList());
		
		/* create or modify 플래그 */
		model.addAttribute("registerFlag", "create");
		
		return "admin/faMemberAdd.tiles";
	}
	
	/**
	 * 외사경찰을 등록한다.
	 * 
	 * @param multiRequest multpart타입의 요청 객체
	 * @param memberVO 외사경찰 정보 객체
	 * @param bindingResult 바인딩 객체
	 * @param model 모델 객체
	 * @param status 세선 상태 객체
	 * @return 게시물  화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = "/faMemberAdd.do", method=RequestMethod.POST)
	public String faMemberAdd(final MultipartHttpServletRequest multiRequest, @ModelAttribute("memberVO") final MemberVO memberVO, 
			final BindingResult bindingResult, final Model model, final SessionStatus status) throws Exception {
		/* 외사경찰 */
		memberVO.setUsertype(UserType.FA);
		
		HashMap<String, Object> result = new HashMap<String, Object>();
		try {
			/* 유효성 검사 */
			MemberVO vo = memberService.select(memberVO);
			if (vo != null || bindingResult.hasErrors()) {
				
				if (vo != null) {
					bindingResult.rejectValue("userid", "member.msg.duplicate");
				}
				
				model.addAttribute("memberVO", memberVO);
				model.addAttribute("place1List", codeService.getPlace1List(false));
				model.addAttribute("positionList", codeService.getPositionList());
				model.addAttribute("dutiesList", codeService.getDutiesList());
				model.addAttribute("jobTypeList", codeService.getJobTypeList());
				model.addAttribute("scholarshipList", codeService.getScholarshipList());
				
				/* create or modify 플래그 */
				model.addAttribute("registerFlag", "create");
				
				return "admin/faMemberAdd.tiles";
			}
			
			result = memberService.insert(memberVO, multiRequest.getFileMap());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		if ((Integer) result.get("result") != 1) {
			return "redirect:/admin/faMemberAdd.do";
		}
		
		String newUserId = (String) result.get("userid");
		newUserId = URLEncoder.encode(newUserId, "UTF-8");
		return "redirect:/admin/faMemberInfo.do?userid=" + newUserId;
	}
	
	/**
	 * 외사경찰 정보를 반환한다.
	 * 
	 * @param memberVO 외사경찰 정보 객체
	 * @param model 모델 객체
	 * @return 외사경찰 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/faMemberInfo.do")
	public String faMemberInfo(final MemberVO memberVO, final Model model) throws Exception {
		try {
			/* 외사경찰 */
			memberVO.setUsertype(UserType.FA);
			model.addAttribute("memberVO", memberService.select(memberVO));
			model.addAttribute("isAdmin", UserUtil.isAdmin());
			model.addAttribute("isSysAdmin", UserUtil.isSysAdmin());
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/faMemberInfo.tiles";
	}
	
	
	
	/**
	 * 외사경찰 목록을 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 외사경찰 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/faMemberList.do")
	public String faMemberList(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		try {
			/* 페이징 처리 정보 */
			searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			searchVO.setPageSize(propertiesService.getInt("pageSize"));
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
			paginationInfo.setPageSize(searchVO.getPageSize());

			searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			int totSearchCnt = memberService.selectListCnt(searchVO);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			
			/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
			int totCnt = memberService.selectTotalCnt(searchVO);
			model.addAttribute("totalCnt", totCnt);
			
			model.addAttribute("resultList", memberService.selectList(searchVO));
			model.addAttribute("place1List", codeService.getPlace1List(false));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/faMemberList.tiles";
		
	}
	
	/**
	 * 외사경찰 목록을 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 외사경찰 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/faMemberCmmnList.do")
	public String faMemberCmmnList(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		try {
			if (searchVO.getPlace1() == null || searchVO.getPlace1().length() == 0) {
				searchVO.setPlace1("PS00");
			}
			/* 페이징 처리 정보 */
			searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			searchVO.setPageSize(propertiesService.getInt("pageSize"));
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
			paginationInfo.setPageSize(searchVO.getPageSize());
			
			searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			int totSearchCnt = memberService.selectListCnt(searchVO);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			
			/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
			int totCnt = memberService.selectTotalCnt(searchVO);
			model.addAttribute("totalCnt", totCnt);
			
			model.addAttribute("resultList", memberService.selectList(searchVO));
			model.addAttribute("place1List", codeService.getPlace1List(false));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/faMemberCmmnList.tiles";
	}
	
	/**
	 * 외사 경찰의 현황을 엑셀로 출력한다.
	 * 
	 * @param searchVO
	 *            검색조건 VO
	 * @param model
	 *            Model객체
	 * @return 외사장비현황
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping("/faMemberListExcel.do")
	public String faMemberListExcel(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		
		String title = "외사경찰현황";
		
		List<MemberVO> memberList = memberService.getFaListAll(searchVO);
		
		LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
		header.put("place1N2Str", "소속");
		header.put("positionStr", "계급");
		header.put("name", "성명");
		header.put("userid", "아이디");
		header.put("inoutStr", "근무형태");
		header.put("jobtypeStr", "직별");
		header.put("usegrade", "등급");
		
		model.addAttribute("excel", new ExcelExporter<MemberVO>(header, memberList, title));
		model.addAttribute("filename", title);
		
		return "excelView";
	}
	
	/**
	 * 외사경찰 정보수정 화면을 반환한다.
	 * 
	 * "/faMemberUpdateView.do"   = 관리자-외사경찰현황
	 * "/cmmnMemberUpdateView.do" = 외사경찰-일반현황
	 * 
	 * @param memberVO 외사경찰 정보
	 * @param model 모델 객체
	 * @param request 리퀘스트 객체
	 * @return 외사경찰 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping(value = {"/faMemberUpdateView.do", "/cmmnMemberUpdateView.do"}, method = RequestMethod.POST)
	public String faMemberUpdateView(@ModelAttribute("memberVO") final MemberVO memberVO, final Model model,
			final HttpServletRequest request) throws Exception {
		/* 외사경찰 */
		memberVO.setUsertype(UserType.FA);
		
		model.addAttribute("memberVO", memberService.select(memberVO));
		model.addAttribute("place1List", codeService.getPlace1List(false));
		model.addAttribute("positionList", codeService.getPositionList());
		model.addAttribute("dutiesList", codeService.getDutiesList());
		model.addAttribute("jobTypeList", codeService.getJobTypeList());
		model.addAttribute("scholarshipList", codeService.getScholarshipList());
		
		/* create or modify 플래그 */
		model.addAttribute("registerFlag", "modify");
		
		/* 요청한 url에 따라 돌아갈 목록 타입을 설정한다. */
		String requestUrl = request.getRequestURL().toString();
		if (requestUrl.indexOf("/faMemberUpdateView.do") > 0) {
			model.addAttribute("listType", "fa");
		} else {
			model.addAttribute("listType", "cmmn");
		}
		
		return "admin/faMemberAdd.tiles";
	}
	
	/**
	 * 외사경찰 정보를 수정한다.
	 * 
	 * @param multiRequest
	 *            multpart타입의 요청 객체
	 * @param memberVO
	 *            외사경찰 정보 객체
	 * @param bindingResult
	 *            바인딩 객체
	 * @param model
	 *            모델 객체
	 * @param status
	 *            세선 상태 객체
	 * @return 게시물 화면
	 * @throws Exception
	 *             기본 예외 처리
	 */
	@RequestMapping(value = {"/faMemberUpdate.do", "/cmmnMemberUpdate.do"}, method = RequestMethod.POST)
	public String faMemberUpdate(final MultipartHttpServletRequest multiRequest, @ModelAttribute("memberVO") final MemberVO memberVO,
			final BindingResult bindingResult, final Model model, final SessionStatus status) throws Exception {
		
		HashMap<String, Object> result = new HashMap<String, Object>();
		
		try {
			/* 유효성 검사 */
			if (bindingResult.hasErrors()) {
				model.addAttribute("memberVO", memberVO);
				model.addAttribute("place1List", codeService.getPlace1List(false));
				model.addAttribute("positionList", codeService.getPositionList());
				model.addAttribute("dutiesList", codeService.getDutiesList());
				model.addAttribute("jobTypeList", codeService.getJobTypeList());
				model.addAttribute("scholarshipList", codeService.getScholarshipList());
				return "admin/faMemberAdd.tiles";
			}
			
			String [] deleteFiles = null;
			result = memberService.updateFaMember(memberVO, multiRequest.getFileMap(), deleteFiles);
			
			if ((Integer) result.get("result") != 1) {
				return "redirect:/admin/faMemberAdd.do";
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		}


		/* 요청한 url에 따라 돌아갈 목록url을 반환한다. */
		String requestUrl = multiRequest.getRequestURL().toString();
		if (requestUrl.indexOf("/faMemberUpdate.do") > 0) {
			return "redirect:/admin/faMemberList.do";
		} else {
			return "redirect:/admin/faMemberCmmnList.do";
		}
	}
	
	
	
	
	/**
	 * 외사경찰 권한설정 화면을 반환한다.
	 * 
	 * @param searchVO searchVO 객체
	 * @param model 모델 객체
	 * @return 외사경찰 권한설정 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/memberAuth.do")
	public String memberAuth(final MemberSearchVO searchVO, final Model model) throws Exception {
		
		LoginUserVO user = UserUtil.getMemberInfo();
		if (StringUtils.isBlank(searchVO.getPlace1())) {
			searchVO.setPlace1(user.getPlace1());
		}
		
		/* 페이징 처리 정보 */
		searchVO.setPageUnit(20);
		searchVO.setPageSize(propertiesService.getInt("pageSize"));
		
		/* 페이징 처리 */
		PaginationInfo paginationInfo = new PaginationInfo();
		paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
		paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
		paginationInfo.setPageSize(searchVO.getPageSize());

		searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
		searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
		searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
		
		int totSearchCnt = memberAuthService.getMemberListByPlace1Cnt(searchVO);
		paginationInfo.setTotalRecordCount(totSearchCnt);
		model.addAttribute("paginationInfo", paginationInfo);
		
		HashMap<String, Object> result = memberAuthService.getMemberListByPlace1(searchVO);
		model.addAttribute("head", result.get("head"));
		model.addAttribute("section", result.get("section"));
		model.addAttribute("resultList", result.get("resultList"));
		model.addAttribute("loginUserVO", user);
		
		String targetPlace1 = searchVO.getPlace1();
		if (StringUtils.isBlank(targetPlace1)) {
			targetPlace1 = user.getPlace1();
		}
		model.addAttribute("targetPlace1", targetPlace1);
		
		
		
		List<CodeVO> placeList = codeService.getPlace1List(true);
		model.addAttribute("placeList", placeList);
		
		return "admin/faMemberAuth.tiles";
	}
	
	/**
	 * 외사경찰의 권한을 설정한다.
	 * 
	 * @param memberVO userid, usegrade 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/memberAuth.json")
	public HashMap<String, Object> memberAuth(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberAuthService.updateMemberAuth(memberVO);
		results.put("result", result);
		return results;
	}
	
	/**
	 * 외사경찰의 견문권한을 설정한다.
	 * 
	 * @param memberVO userid, usegrade 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/memberRpt.json")
	public HashMap<String, Object> memberRpt(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberAuthService.updateMemberRpt(memberVO);
		results.put("result", result);
		return results;
	}
	
	/**
	 * 외사경찰 부서 계장 권한을 설정한다.
	 * 
	 * @param memberVO userid 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/updateSection.json")
	public HashMap<String, Object> updateSection(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberAuthService.updateSection(memberVO);
		results.put("result", result);
		return results;
	}
	
	/**
	 * 외사경찰 부서 과장 권한을 설정한다.
	 * 
	 * @param memberVO userid 정보
	 * @return 결과 : 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping(value = "/updateHead.json")
	public HashMap<String, Object> updateHead(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> results = new HashMap<String, Object>();
		int result = memberAuthService.updateHead(memberVO);
		results.put("result", result);
		return results;
	}
	
	
	
	/**
	 * 일반경찰 목록을 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 외사경찰 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/cmmnMemberList.do")
	public String memberList(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		try {
			/* 일반 경찰 */
			searchVO.setUsertype(UserType.CM);
			
			/* 페이징 처리 정보 */
			searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			searchVO.setPageSize(propertiesService.getInt("pageSize"));
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
			paginationInfo.setPageSize(searchVO.getPageSize());

			searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			int totSearchCnt = memberService.selectListCnt(searchVO);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			
			/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
			int totCnt = memberService.selectTotalCnt(searchVO);
			model.addAttribute("totalCnt", totCnt);
			List<MemberVO> resultList = memberService.selectList(searchVO);
			model.addAttribute("resultList", resultList);
			model.addAttribute("place1List", codeService.getPlace1List(false));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/cmmnMemberList.tiles";
	}
	
	/**
	 * 외사 경찰의 현황을 엑셀로 출력한다.
	 * 
	 * @param model Model객체
	 * @return 엑셀
	 */
	@RequestMapping("/cmmnMemberListExcel.do")
	public String memberListExcel(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
		
		/* 일반 경찰 */
		searchVO.setUsertype(UserType.CM);
		
		String title = "일반경찰현황";
		
		searchVO.setUsertype("");
		List<MemberVO> memberList = memberService.selectListAll(searchVO);
		
		LinkedHashMap<String, String> header = new LinkedHashMap<String, String>();
		header.put("place3Str", "소속");
		header.put("positionStr", "계급");
		header.put("useridStr", "아이디");
		header.put("name", "성명");
		
		model.addAttribute("excel", new ExcelExporter<MemberVO>(header, memberList, title));
		model.addAttribute("filename", title);
		
		return "excelView";
	}
	
	
	
	/**
	 * 사용자 로그 통계를 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 사용자 로그 통계 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/userLogStatistics.do")
	public String userLogStatistics(@ModelAttribute("logSearchVO") final LogSearchVO searchVO, final Model model) throws Exception {
		try {
			/* 페이징 처리 정보 */
			searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
			searchVO.setPageSize(propertiesService.getInt("pageSize"));
			
			if (StringUtils.isEmpty(searchVO.getSdate()) && StringUtils.isEmpty(searchVO.getEdate())) {
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
				Calendar day = Calendar.getInstance();
				day.add(Calendar.MONTH, -1);
				searchVO.setSdate(sdf.format(day.getTime()));
				
				searchVO.setEdate(sdf.format(new Date()));				
			}
			
			/* 페이징 처리 */
			PaginationInfo paginationInfo = new PaginationInfo();
			paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
			paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
			paginationInfo.setPageSize(searchVO.getPageSize());

			searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
			searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
			searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
			
			int totSearchCnt = logService.selectListCnt(searchVO);
			paginationInfo.setTotalRecordCount(totSearchCnt);
			model.addAttribute("paginationInfo", paginationInfo);
			
			/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
			int totCnt = logService.selectTotalCnt(searchVO);
			model.addAttribute("totalCnt", totCnt);
			
			model.addAttribute("resultList", logService.getUserLogList(searchVO));
			model.addAttribute("place1List", codeService.getPlace1List(false));
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return "admin/logStatistics.tiles";
	}
	
	/**
	 * 접속설정 화면 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 접속설정 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/memberManage.do")
	public String memberManage(@ModelAttribute("memberSearchVO") final MemberSearchVO searchVO, final Model model) throws Exception {
			try {
				/* 페이징 처리 정보 */
				searchVO.setPageUnit(propertiesService.getInt("pageUnit"));
				searchVO.setPageSize(propertiesService.getInt("pageSize"));
				
				/* 페이징 처리 */
				PaginationInfo paginationInfo = new PaginationInfo();
				paginationInfo.setCurrentPageNo(searchVO.getPageIndex());
				paginationInfo.setRecordCountPerPage(searchVO.getPageUnit());
				paginationInfo.setPageSize(searchVO.getPageSize());

				searchVO.setFirstIndex(paginationInfo.getFirstRecordIndex());
				searchVO.setLastIndex(paginationInfo.getLastRecordIndex());
				searchVO.setRecordCountPerPage(paginationInfo.getRecordCountPerPage());
				
				int totSearchCnt = memberService.selectListCnt(searchVO);
				paginationInfo.setTotalRecordCount(totSearchCnt);
				model.addAttribute("paginationInfo", paginationInfo);
				
				/* 게시판 상단 페이지 및 게시물 정보 표현을 위한 데이터 */
				int totCnt = memberService.selectTotalCnt(searchVO);
				model.addAttribute("totalCnt", totCnt);
				
				List<MemberVO> memberList = memberService.selectList(searchVO);
				model.addAttribute("resultList", memberList);
				model.addAttribute("place1List", codeService.getPlace1List(false));
			} catch (Exception e) {
				e.printStackTrace();
			}
			
			return "admin/memberManage.tiles";
		}
	
	
	/**
	 * 접속설정 화면 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 접속설정 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/initPw.json")
	public HashMap<String, Object> initPw(final MemberVO memberVO, final String[] targetId) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		try {
			resultMap = memberService.initPassword(memberVO, targetId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}
	
	
	@Autowired
	private SessionRegistry sessionRegistry;
	@Resource(name="securityMapper")
	private SecurityMapper securityMapper;
	@Resource(name="userService")
	private UserDetailsService securityService;
	@Resource(name="loginSuccessHandler")
	private AuthenticationSuccessHandler successHandler;
	/**
	 * 사용자 접속을 해지한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 접속설정 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/loginUser.do")
	public void loginUser(final HttpServletRequest request, final HttpServletResponse response, final String userid) throws Exception {
		Authentication authentication = null;
		if (userid != null) {
			authentication = login(userid);
		} else {
			authentication = UserUtil.getCurrentAuthentication();
		}
		successHandler.onAuthenticationSuccess(request, response, authentication);
	}
	
	/**
	 * 사용자 접속을 해지한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 접속설정 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/releaseConnection.json")
	public HashMap<String, Object> releaseConnection(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("result", logout(memberVO.getUserid()));
		return resultMap;
	}
	
	/**
	 * 접속 제한을 해지한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 접속설정 정보 화면
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/releaseRestriction.json")
	public HashMap<String, Object> releaseRestriction(final MemberVO memberVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		resultMap.put("result", 0);
		
		try {
			resultMap = memberService.initChkcnt(memberVO);
			logout(memberVO.getUserid());
		} catch (Exception e) {
			e.printStackTrace();
		}

		return resultMap;
	}
	
	/**
	 * 해당 아이디를 세션에서 로그아웃 시킨다.
	 * 
	 * @param userid 로그아웃 대상 아이디
	 * @return 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	private final int logout(final String userid) {
		int result = 0;
		EgovUserDetails target = null;
		List<Object> principals = sessionRegistry.getAllPrincipals();
		for (Object principal: principals) {
			if (principal instanceof EgovUserDetails) {
				EgovUserDetails details = (EgovUserDetails) principal;
				LoginUserVO vo = (LoginUserVO) details.getEgovUserVO();
				if (userid.equals(vo.getUserid())) {
					for (final SessionInformation session : sessionRegistry.getAllSessions(principal, false)) {
			            session.expireNow();
			            vo.setLoginchk("N");
			            result = securityMapper.updateLoginInfo(vo);
					}
					break;
				}
			}
		}
		return result;
	}
	
	/**
	 * 해당 아이디로 로그인한다.
	 * 
	 * @param userid 로그인 대상 아이디
	 * @return Authentication 인증정보객체
	 * @throws Exception 기본 예외 처리
	 */
	private final Authentication login(final String userid) {
		Authentication auth = null; 
		try {
			UserDetails user = securityService.loadUserByUsername(userid);
			auth = new UsernamePasswordAuthenticationToken(user, null, user.getAuthorities());
			SecurityContextHolder.getContext().setAuthentication(auth);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return auth;
	}
	
	
	
	/**
	 * 코드관리 페이지를 반환한다.
	 * 
	 * @param searchVO 검색, 페이지 정보 객체
	 * @param model 모델 객체
	 * @return 코드관리 페이지
	 * @throws Exception 기본 예외 처리
	 */
	@RequestMapping("/codeManage.do")
	public String codeManage(final CodeVO codeVO, final Model model) throws Exception {
		
		if (codeVO.getCode1() != null) {
			model.addAttribute("code", codeService.getCodeValue("C000", codeVO.getCode1()));
		}
		model.addAttribute("code1List", codeService.getCodeValues("C000", null));
		
		return "admin/codeManage.tiles";
	}
	
	/**
	 * 세부코드 리스트를 반환한다.
	 * 
	 * @param code1 대분류코드
	 * @param model 모델 객체
	 * @return 세부코드 리스트
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/getCode2List.json")
	public HashMap<String, Object> getCode2List(final String code1) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		try {
			resultMap.put("code2List", codeService.getCodeValues(code1, null));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}
	
	/**
	 * 코드를 추가한다.
	 * 
	 * @param codeVO CodeVO 객체
	 * @return 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/insertCode.json")
	public HashMap<String, Object> insertCode(final CodeVO codeVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		try {
			resultMap.put("result", codeService.insertCode(codeVO));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}
	
	/**
	 * 코드를 수정한다.
	 * 
	 * @param codeVO CodeVO 객체
	 * @return 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/updateCode.json")
	public HashMap<String, Object> updateCode(final CodeVO codeVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		try {
			resultMap.put("result", codeService.updateCode(codeVO));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}
	
	/**
	 * 코드를 삭제한다.
	 * 
	 * @param codeVO CodeVO 객체
	 * @return 성공 - 1, 실패 - 0
	 * @throws Exception 기본 예외 처리
	 */
	@ResponseBody
	@RequestMapping("/deleteCode.json")
	public HashMap<String, Object> deleteCode(final CodeVO codeVO) throws Exception {
		HashMap<String, Object> resultMap = new HashMap<String, Object>();
		try {
			resultMap.put("result", codeService.deleteCode(codeVO));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return resultMap;
	}
}
