This commit is contained in:
JSYOO 2021-09-16 17:04:16 +09:00
commit 2aa9031f59
20 changed files with 1053 additions and 97 deletions

View File

@ -27,6 +27,7 @@ public class ArticleVO extends PagingVO {
private String useYn; /* 사용여부 */ private String useYn; /* 사용여부 */
private String questionType; /* 질문유형 */ private String questionType; /* 질문유형 */
private String questionTypeName; /* 질문유형명 */ private String questionTypeName; /* 질문유형명 */
private String secretYn; /* 비밀글여부 */
private int viewCnt; /* 조회수 */ private int viewCnt; /* 조회수 */
private String bdAttachFileId; /* 첨부파일아이디 */ private String bdAttachFileId; /* 첨부파일아이디 */
@ -38,12 +39,16 @@ public class ArticleVO extends PagingVO {
private String modId; /* 등록자아이디 */ private String modId; /* 등록자아이디 */
private String modDd; /* 등록일자 */ private String modDd; /* 등록일자 */
private int rno; /* 글번호 */ private int rno; /* 글번호 */
private String loginedMbInfoId; /* 로그인 사용자 ID */
private String loginedName; /* 로그인 사용자명 */
private String myQnaYn; /* 내가한 질문인지 여부 */
// 검색관련 // 검색관련
private String searchType; /* 검색대상구분 */ private String searchType; /* 검색대상구분 */
private String searchKeyword; /* 검색어 */ private String searchKeyword; /* 검색어 */
private String searchQuestionType; /* 검색FAQ유형 */ private String searchQuestionType; /* 검색FAQ유형 */
private String searchMbInfoId; /* 로그인한 사용자ID */
// 첨부파일 // 첨부파일
private List<AttachFileVO> attachFiles = null; /* 첨부파일목록 */ private List<AttachFileVO> attachFiles = null; /* 첨부파일목록 */
@ -247,4 +252,44 @@ public class ArticleVO extends PagingVO {
this.searchQuestionType = searchQuestionType; this.searchQuestionType = searchQuestionType;
} }
public String getSearchMbInfoId() {
return searchMbInfoId;
}
public void setSearchMbInfoId(String searchMbInfoId) {
this.searchMbInfoId = searchMbInfoId;
}
public String getSecretYn() {
return secretYn;
}
public void setSecretYn(String secretYn) {
this.secretYn = secretYn;
}
public String getLoginedMbInfoId() {
return loginedMbInfoId;
}
public void setLoginedMbInfoId(String mbInfoId) {
this.loginedMbInfoId = mbInfoId;
}
public String getMyQnaYn() {
return myQnaYn;
}
public void setMyQnaYn(String myQnaYn) {
this.myQnaYn = myQnaYn;
}
public String getLoginedName() {
return loginedName;
}
public void setLoginedName(String loginedName) {
this.loginedName = loginedName;
}
} }

View File

@ -0,0 +1,23 @@
package nlib.bbs.service;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import nlib.user.service.NlibLoginVO;
public interface AttachFileService
{
/**
* 첨부파일 목록을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception;
}

View File

@ -0,0 +1,52 @@
package nlib.bbs.service.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.stereotype.Repository;
import egovframework.com.cmm.service.impl.EgovComAbstractDAO;
import egovframework.rte.psl.dataaccess.mapper.Mapper;
import nlib.cmm.service.NotificationVO;
import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.AttachFileVO;
import nlib.cmm.service.NlibProperty;
import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil;
/**
* <pre>
* @Class Name : AttachFileDAO.java
*
* @Description : 게시판 첨부파일 관리 DAO
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 16.
* @version 1.0
*
*/
@Mapper("attachFileDAO")
public interface AttachFileDAO {
/**
* 첨부파일 목록을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception;
}

View File

@ -0,0 +1,33 @@
package nlib.bbs.service.impl;
import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import nlib.bbs.service.AttachFileService;
import nlib.bbs.service.AttachFileVO;
@Service("attachFileService")
public class AttachFileServiceImpl implements AttachFileService
{
static Logger log = LoggerFactory.getLogger(AttachFileServiceImpl.class);
@Resource(name="attachFileDAO")
AttachFileDAO attachFileDAO;
/**
* 첨부파일 목록을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception {
return attachFileDAO.listAttachFiles(attachFileId);
}
}

View File

@ -69,14 +69,4 @@ public interface BoardDAO {
*/ */
public ArticleVO selectArticle(ArticleVO notiVO) throws Exception; public ArticleVO selectArticle(ArticleVO notiVO) throws Exception;
/**
* 첨부파일 목록을 조회한다.
*
* @param
* @return
* @throws Exception
*/
public List<AttachFileVO> listAttachFiles(String attachFileId) throws Exception;
} }

View File

@ -2,10 +2,13 @@ package nlib.bbs.service.impl;
import java.util.List; import java.util.List;
import javax.annotation.Resource;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import nlib.bbs.service.ArticleVO; import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.AttachFileService;
import nlib.bbs.service.AttachFileVO; import nlib.bbs.service.AttachFileVO;
import nlib.bbs.service.BoardService; import nlib.bbs.service.BoardService;
import nlib.util.StringUtil; import nlib.util.StringUtil;
@ -14,6 +17,9 @@ public abstract class BoardServiceImpl implements BoardService
{ {
static Logger log = LoggerFactory.getLogger(BoardServiceImpl.class); static Logger log = LoggerFactory.getLogger(BoardServiceImpl.class);
@Resource(name="attachFileService")
AttachFileService attachFileService;
public abstract BoardDAO getBoardDAO(); public abstract BoardDAO getBoardDAO();
/* /*
@ -60,7 +66,7 @@ public abstract class BoardServiceImpl implements BoardService
// 첨부파일 조회 // 첨부파일 조회
if(StringUtil.isNotEmpty(retVO.getBdAttachFileId())) { if(StringUtil.isNotEmpty(retVO.getBdAttachFileId())) {
String attachFileId = retVO.getBdAttachFileId(); String attachFileId = retVO.getBdAttachFileId();
List<AttachFileVO> listFile = getBoardDAO().listAttachFiles(attachFileId); List<AttachFileVO> listFile = attachFileService.listAttachFiles(attachFileId);
retVO.setAttachFiles(listFile); retVO.setAttachFiles(listFile);
} }
// 조회수 증가 // 조회수 증가

View File

@ -1,6 +1,7 @@
package nlib.bbs.web; package nlib.bbs.web;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -10,34 +11,25 @@ import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap; import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.web.servlet.support.RequestContextUtils;
import nlib.bbs.service.ArticleVO; import nlib.bbs.service.ArticleVO;
import nlib.bbs.service.BoardService; import nlib.bbs.service.BoardService;
import nlib.bbs.service.BoardServiceApi;
import nlib.cmm.NlibCommonController; import nlib.cmm.NlibCommonController;
import nlib.cmm.crypto.AriaCrypto;
import nlib.cmm.crypto.NlibPasswordEncoder;
import nlib.cmm.service.CodeService; import nlib.cmm.service.CodeService;
import nlib.cmm.service.NlibProperty; import nlib.cmm.service.NlibProperty;
import nlib.restful.service.DataApiReqVO;
import nlib.restful.service.DataApiResVO;
import nlib.user.service.NlibLoginVO; import nlib.user.service.NlibLoginVO;
import nlib.util.StringUtil; import nlib.util.StringUtil;
@Controller @Controller
public class QnaController extends NlibCommonController public class QnaController extends NlibCommonController {
{
private static final Logger log = LoggerFactory.getLogger(QnaController.class); private static final Logger log = LoggerFactory.getLogger(QnaController.class);
static final int DEFUALT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10); static final int DEFUALT_PAGE_SIZE = NlibProperty.getInt("list.paging.page.size", 10);
@ -45,6 +37,10 @@ public class QnaController extends NlibCommonController
@Resource(name = "qnaService") @Resource(name = "qnaService")
private BoardService qnaService; private BoardService qnaService;
@Resource(name="codeService")
private CodeService codeService;
/** /**
* 목록 화면을 표시한다. * 목록 화면을 표시한다.
* *
@ -76,12 +72,29 @@ public class QnaController extends NlibCommonController
Authentication authentication, Authentication authentication,
@RequestBody ArticleVO searchArticleVO) throws Exception { @RequestBody ArticleVO searchArticleVO) throws Exception {
String message = null;
boolean needToQeury = true;
if(searchArticleVO.getPageIndex() < 1) searchArticleVO.setPageIndex(1); if(searchArticleVO.getPageIndex() < 1) searchArticleVO.setPageIndex(1);
if(searchArticleVO.getPageSize() < 1) searchArticleVO.setPageSize(DEFUALT_PAGE_SIZE); if(searchArticleVO.getPageSize() < 1) searchArticleVO.setPageSize(DEFUALT_PAGE_SIZE);
if(StringUtil.equalsIgnoreCase(searchArticleVO.getSearchQuestionType(), "USER")) {
String mbInfoId = getMbInfoId(req);
searchArticleVO.setSearchMbInfoId(mbInfoId);
if(StringUtil.isEmpty(mbInfoId)) needToQeury = false;
} else {
searchArticleVO.setSearchMbInfoId(null);
}
List<ArticleVO> list = qnaService.listArticles(searchArticleVO); List<ArticleVO> list = null;
int totRecordCount = 0;
int totRecordCount = qnaService.countArticles(searchArticleVO); if(needToQeury) {
list = qnaService.listArticles(searchArticleVO);
totRecordCount = qnaService.countArticles(searchArticleVO);
} else {
list = new ArrayList<ArticleVO>();
message = "로그인이 필요합니다.";
}
//------------------------------- //-------------------------------
// JSON변환 응답 처리 // JSON변환 응답 처리
@ -93,11 +106,12 @@ public class QnaController extends NlibCommonController
HashMap<String, Object> retMap = new HashMap<String, Object>(); HashMap<String, Object> retMap = new HashMap<String, Object>();
retMap.put("data", list); retMap.put("data", list);
retMap.put("itemsCount", totRecordCount); retMap.put("itemsCount", totRecordCount);
retMap.put("message", message);
return makeResponseEntityJson(retMap); return makeResponseEntityJson(retMap);
} }
/** /**
* 알림 상세 내용 조회한다. * 알림 상세 내용 조회한다.
* *
@ -115,4 +129,23 @@ public class QnaController extends NlibCommonController
return "nlib/bbs/selectQnaArticle"; return "nlib/bbs/selectQnaArticle";
} }
/**
* 묻고답하기 글작성화면을 표출한다.
*
* @param req
* @return
*/
@RequestMapping("/bbs/insertQnaForm.do")
public String insertQnAForm(HttpServletRequest req, ArticleVO searchArticleVO, ModelMap model) throws Exception {
NlibLoginVO nlibLoginVO = getNlibLoginVO(req);
searchArticleVO.setLoginedMbInfoId(nlibLoginVO.getMbInfoId());
searchArticleVO.setLoginedName(nlibLoginVO.getName());
model.addAttribute("searchArticle", searchArticleVO);
return "nlib/bbs/insertQnaForm";
}
} }

View File

@ -166,7 +166,7 @@ public class StringUtil extends StringUtils {
log.error("[ERROR] getHostName(..) : " + e.toString()); log.error("[ERROR] getHostName(..) : " + e.toString());
return ""; return "";
} }
if("|localhost|nlib.nculture.org|nlib-dev.nculture.org|".contains(hostName)) hostName = "nlib";
return (hostName.split("\\."))[0]; return (hostName.split("\\."))[0];
} }

View File

@ -88,28 +88,6 @@
]]> ]]>
</select> </select>
<select id="listAttachFiles" parameterType="String" resultType="AttachFileVO">
SELECT
A.FILE_MASK
, A.FILE_ID
, A.FILE_SEQ
, A.FILE_NAME
, A.FILE_SIZE
, A.FILE_TYPE_CD
, A.DOWNLOAD_COUNT
, A.DOWNLOAD_EXPIRE_DATE
, A.DOWNLOAD_LIMIT_COUNT
, DATE_FORMAT(A.REG_DATE, '%Y-%m-%d') AS REG_DD
, A.DELETE_YN
, A.STREAMING_URL
, A.CONTENT
, A.ATCH_TYPE_CD
FROM J_ATTACHFILE A
WHERE A.FILE_ID = #{attachFileId}
ORDER BY A.FILE_SEQ
</select>
<update id="updateRead" parameterType="ArticleVO"> <update id="updateRead" parameterType="ArticleVO">
<![CDATA[ <![CDATA[
UPDATE BD_NLIB_ANCMNT UPDATE BD_NLIB_ANCMNT

View File

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?><!--Converted at: Wed May 11 15:49:38 KST 2016-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="nlib.bbs.service.impl.AttachFileDAO">
<select id="listAttachFiles" parameterType="String" resultType="AttachFileVO">
SELECT
A.FILE_MASK
, A.FILE_ID
, A.FILE_SEQ
, A.FILE_NAME
, A.FILE_SIZE
, A.FILE_TYPE_CD
, A.DOWNLOAD_COUNT
, A.DOWNLOAD_EXPIRE_DATE
, A.DOWNLOAD_LIMIT_COUNT
, DATE_FORMAT(A.REG_DATE, '%Y-%m-%d') AS REG_DD
, A.DELETE_YN
, A.STREAMING_URL
, A.CONTENT
, A.ATCH_TYPE_CD
FROM J_ATTACHFILE A
WHERE A.FILE_ID = #{attachFileId}
ORDER BY A.FILE_SEQ
</select>
</mapper>

View File

@ -102,28 +102,6 @@
]]> ]]>
</select> </select>
<select id="listAttachFiles" parameterType="String" resultType="AttachFileVO">
SELECT
A.FILE_MASK
, A.FILE_ID
, A.FILE_SEQ
, A.FILE_NAME
, A.FILE_SIZE
, A.FILE_TYPE_CD
, A.DOWNLOAD_COUNT
, A.DOWNLOAD_EXPIRE_DATE
, A.DOWNLOAD_LIMIT_COUNT
, DATE_FORMAT(A.REG_DATE, '%Y-%m-%d') AS REG_DD
, A.DELETE_YN
, A.STREAMING_URL
, A.CONTENT
, A.ATCH_TYPE_CD
FROM J_ATTACHFILE A
WHERE A.FILE_ID = #{attachFileId}
ORDER BY A.FILE_SEQ
</select>
<update id="updateRead" parameterType="ArticleVO"> <update id="updateRead" parameterType="ArticleVO">
<![CDATA[ <![CDATA[
UPDATE BD_QNA UPDATE BD_QNA

View File

@ -0,0 +1,128 @@
<?xml version="1.0" encoding="UTF-8"?><!--Converted at: Wed May 11 15:49:38 KST 2016-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="nlib.bbs.service.impl.QnaDAO">
<sql id="search_condition">
<![CDATA[
FROM BD_QNA S
WHERE S.USE_YN = 'Y'
AND S.BD_TYPE = 'QNA'
]]>
<if test='searchType != null and searchType.equals("T")'>
<if test="searchKeyword != null and !searchKeyword.equals('')">
AND S.TITLE LIKE CONCAT('%', #{escapeSearchKeyword}, '%')
</if>
</if>
<if test='searchType != null and searchType.equals("C")'>
<if test="searchKeyword != null and !searchKeyword.equals('')">
AND CONCAT(S.CONTENT, S.ANSWER) LIKE CONCAT('%', #{escapeSearchKeyword}, '%')
</if>
</if>
<if test='searchMbInfoId != null and !searchMbInfoId.equals("")'>
AND S.REG_ID = #{searchMbInfoId}
</if>
</sql>
<select id="listArticles" parameterType="ArticleVO" resultType="ArticleVO">
SELECT
A.QNA_ID AS ARTICLE_ID
, A.MNG_ORG_CD
, B.DEPT_NM AS MNG_ORG_NM
, A.QUESTION_TYPE
, A.TITLE
, A.ANSWER_YN
, A.USE_YN
, IFNULL(A.SECRET_YN, 'N') AS SECRET_YN
, A.VIEW_CNT
, CASE WHEN A.BD_ATTACH_FILE_ID IS NULL OR A.BD_ATTACH_FILE_ID = '' THEN 'N' ELSE 'Y' END AS ATTACH_YN
, DATE_FORMAT(A.REG_DD, '%Y-%m-%d') AS REG_DD
, A2.RNO
, C.USER_NM AS REG_NM
, CASE
WHEN #{loginedMbInfoId} IS NULL OR #{loginedMbInfoId} = '' THEN 'N'
WHEN A.REG_ID = #{loginedMbInfoId} THEN 'Y'
ELSE 'N'
END AS MY_QNA_YN
FROM BD_QNA A
INNER JOIN (
SELECT QNA_ID, RNO
FROM (
SELECT S.QNA_ID
, ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY S.REG_DD, S.TITLE) AS RNO
, ROW_NUMBER() OVER(PARTITION BY 1 ORDER BY S.REG_DD DESC, S.TITLE DESC) AS ONO
<include refid="search_condition" />
) S2
WHERE ONO BETWEEN (#{pageStartRowNum} + 1) AND (#{pageStartRowNum} + #{pageSize})
) AS A2
USING(QNA_ID)
JOIN SM_DEPT B
ON B.ORG_CD = A.MNG_ORG_CD
LEFT OUTER JOIN (
SELECT USER_ID
, USER_NM
FROM SM_USER
UNION ALL
SELECT MB_INFO_ID AS USER_ID
, NAME AS USER_NM
FROM MB_INFO ) C
ON A.REG_ID = C.USER_ID
ORDER BY RNO DESC
</select>
<select id="countArticles" parameterType="ArticleVO" resultType="Integer">
SELECT COUNT(1)
<include refid="search_condition" />
</select>
<select id="selectArticle" parameterType="ArticleVO" resultType="ArticleVO">
<![CDATA[
SELECT
A.QNA_ID AS ARTICLE_ID
, A.MNG_ORG_CD
, B.DEPT_NM AS MNG_ORG_NM
, A.QUESTION_TYPE
, A.TITLE
, A.CONTENT
, A.ANSWER_YN
, A.ANSWER
, A.USE_YN
, IFNULL(A.SECRET_YN, 'N') AS SECRET_YN
, A.VIEW_CNT
, A.BD_ATTACH_FILE_ID
, CASE WHEN A.BD_ATTACH_FILE_ID IS NULL OR A.BD_ATTACH_FILE_ID = '' THEN 'N' ELSE 'Y' END AS ATTACH_YN
, DATE_FORMAT(A.REG_DD, '%Y-%m-%d') AS REG_DD
, C.USER_NM AS REG_NM
, CASE
WHEN #{loginedMbInfoId} IS NULL OR #{loginedMbInfoId} = '' THEN 'N'
WHEN A.REG_ID = #{loginedMbInfoId} THEN 'Y'
ELSE 'N'
END AS MY_QNA_YN
FROM BD_QNA A
LEFT OUTER JOIN SM_DEPT B
ON B.ORG_CD = A.MNG_ORG_CD
LEFT OUTER JOIN (
SELECT USER_ID
, USER_NM
FROM SM_USER
UNION ALL
SELECT MB_INFO_ID AS USER_ID
, NAME AS USER_NM
FROM MB_INFO ) C
ON A.REG_ID = C.USER_ID
WHERE A.QNA_ID = #{articleId}
ORDER BY A.REG_DD DESC
]]>
</select>
<update id="updateRead" parameterType="ArticleVO">
<![CDATA[
UPDATE BD_QNA
SET VIEW_CNT = VIEW_CNT + 1
WHERE QNA_ID = #{articleId}
]]>
</update>
</mapper>

View File

@ -0,0 +1,211 @@
<%
/**
* <pre>
* @Class Name : insertQnAForm.jsp
*
* @Description : 묻고답하기 등록화면을 표출한다.
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 7. 13. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 7. 13.
* @version 1.0
*
*/
%>
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" %>
<c:set var="pageTitle">묻고답하기 - 등록</c:set>
<!DOCTYPE html>
<html>
<head>
<title>${pageTitle}</title>
<!-- File Upload : 시작 -->
<link rel="stylesheet" href="${pageContext.request.contextPath}/js/fileupload/dropzone.css" />
<link rel="stylesheet" href="${pageContext.request.contextPath}/js/fileupload/style.css" />
<script src="${pageContext.request.contextPath}/js/fileupload/dropzone.js"></script>
<!-- File Upload : 종료 -->
<script type="text/javaScript">
var myDropzone = null; <% // 파일드롭다운 객체 %>
var fileList = new Array(); <% // 업로드된 파일 정보 %>
var IN_PROC = false; <% // 현재 상태가 업로드처리중에 있는지 여부 %>
$(document).ready(function() {
// 파일업로드 객체 생성
myDropzone = new Dropzone("form#myDropzone", { url: "${pageContext.request.contextPath}/fileupload/uploadFilesAjax.do?subPathKey=fileupload.bbs.qna.subpath"});
// 각 파일별 업로드 성공시 호출됨 (1th called)
myDropzone.on("success", function(file, responseText) {
var jobj = JSON.parse(responseText);
console.log("file upload success : responseText = " + responseText);
console.log("fileUpDone count : " + fileList.length);
var idx = fileList.length;
fileList[idx] = {
"orignlFileNm" : jobj[0].orignlFileNm,
"streFileNm" : jobj[0].streFileNm,
"fileMg" : jobj[0].fileMg,
};
console.log("success : " + file.name + " -> " + "data > " + jobj[0].streFileNm);
//alert("file : status " + file.status);
});
// 각 파일별 업로드 처리 완료 시 호출됨 (2th called)
myDropzone.on("complete", function(file) {
console.log("개별 파일 처리 완료 > file = " + JSON.stringify(file));
});
// 모든 업로드 처리 완료 시 호출됨
myDropzone.on("queuecomplete", function() {
var targetCnt = this.getAcceptedFiles().length;
var uploadCnt = fileList.length;
if(uploadCnt > 0) {
$("#fileList").val(JSON.stringify(JSON.stringify(fileList)));
}
if(IN_PROC) {
if(targetCnt > 0 && targetCnt != uploadCnt) {
alert("총 " + targetCnt + "건의 첨부파일 중 " + uploadCnt + "건이 정상적으로 업로드 되었습니다. 게시물 등록을 계속 진행합니다.");
}
fn_insertSubmit();
}
});
});
// 목록으로 이동
function fn_list() {
$('#articleForm').removeAttr('onsubmit');
$("#articleForm").attr("action", "${pageContext.request.contextPath}/board/listQnAs.do");
$("#articleForm").submit();
}
// 등록 처리
function fn_insert() {
if(!validEmail($("#email").val())) {
alert("이메일 형식에 맞지 않습니다. 다시 확인하여 주시기 바랍니다.");
$("#email").focus();
return false;
}
$("#articleForm").attr("action", "${pageContext.request.contextPath}/board/insertQnA.do");
if(!confirm("저장하시겠습니까?")) return false;
IN_PROC = true;
// 파일 업로드 처리
if(myDropzone.getAcceptedFiles().length > 0) {
myDropzone.processQueue();
return false;
}
return true;
}
//등록 처리
function fn_insertSubmit() {
$('#articleForm').removeAttr('onsubmit');
$("#articleForm").attr("action", "${pageContext.request.contextPath}/board/insertQnA.do");
$("#articleForm").submit();
}
</script>
</head>
<body>
<h1>${pageTitle }</h1>
메시지 : <span style="color:red;">${message }</span>
<br />
<form name="articleForm" id="articleForm"
action="${pageContext.request.contextPath}/board/insertQnA.do"
method="post"
onsubmit="return fn_insert();">
<!-- HIDDEN 영역 : 시작 -->
<input type="text" name="pageIndex" id="pageIndex" title="페이지번호" value="${searchArticle.pageIndex}" readonly />
<input type="text" name="pageSize" id="pageSize" title="목록에 보여줄 글개수" value="${searchArticle.pageSize}" readonly />
<input type="text" name="searchType" id="searchType" title="검색구분" value="${searchArticle.searchType}" readonly />
<input type="text" name="searchKeyword" id="searchKeyword" title="검색어" value="${searchArticle.searchKeyword}" readonly />
<input type="text" name="articleId" id="articleId" title="선택글번호" value="${searchArticle.articleId}" readonly />
<!-- HIDDEN 영역 : 종료 -->
&nbsp;<br/>
&nbsp;<br/>
<table class="table_content" style="width:100% !important;">
<tr>
<th>제목</th>
<td><input type="text" name="title" id="title" title="제목" value="${title}" size="100" maxlength="200" required /></td>
</tr>
<tr>
<th>작성자</th>
<td>
<input type="text" name="regId" id="regId" title="작성자" value="${searchArticle.loginedMbInfoId}" size="100" maxlength="200" readonly />
<input type="text" name="regName" id="regName" title="작성자" value="${searchArticle.loginedName}" size="100" maxlength="200" readonly />
</td>
</tr>
<tr>
<th>비밀번호</th>
<td><input type="text" name="articlePassword" id="articlePassword" title="비밀번호" value="${articlePassword}" size="100" maxlength="200" required /><br/>
* 비밀번호 : SHA-256 암호화 처리 후, DB에 저장되며, 웹 화면에 표출될 때는 Aria로 AuthKey를 Salt값으로 하여 재암호화처리하고 BASE64로 다시한번 인코딩하여 표출함
</td>
</tr>
<tr>
<th>이메일</th>
<td><input type="email" name="email" id="email" title="이메일" value="${email}" size="100" maxlength="200" required /></td>
</tr>
<tr>
<th>질문내용</th>
<td><textarea name="contentQeust" id="contentQeust" cols="80" rows="10" required >${contentQeust}</textarea></td>
</tr>
</table>
<br/>
<input type="button" name="btnCancel" id="btnCancel" title="취소버튼" class="float" value="취소"
onclick="fn_list()" />
<input type="submit" name="btnSave" id="btnSave" title="저장버튼" class="float" value="저장" />
</form>
&nbsp;<br/>
&nbsp;<br/>
&nbsp;<br/>
<div id="dropzone">
<form id="myDropzone" name="myDropzone"
action="${pageContext.request.contextPath}/fileupload/uploadFile.do"
class="dropzone needsclick" >
<div class="dz-message needsclick">
<button type="button" class="dz-button">Drop files here or click to select files.</button><br />
<span class="note needsclick">이곳에 파일을 끌어다 놓거나, 클릭하여 올릴 파일을 선택하세요.</span>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,303 @@
<%
/**
* <pre>
* @Class Name : listQnas.jsp
*
* @Description : 묻고답하기 목록 화면을 표출한다.
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 16.
* @version 1.0
*
*/
%>
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" %>
<c:set var="pageTitle">묻고답하기(DB)</c:set>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>${pageTitle}</title>
<!-- GRID -->
<link type="text/css" rel="stylesheet" href="/nlib/js/jsgrid/nlib-jsgrid.css" />
<link type="text/css" rel="stylesheet" href="/nlib/js/jsgrid/nlib-jsgrid-theme.css" />
<script src="/nlib/js/jsgrid/nlib-jsgrid.js"></script>
<script type="text/javaScript" language="javascript">
$( document ).ready(function() {
//=======================================================
// 그리드 생성 환경설정
//=======================================================
$("#jsGrid").jsGrid({
pageSize : $("#pageSize").val(),
scrollOffset:0,
controller: {
loadData: function (filter) { // 그리드에 데이터를 가져올 때 실팽되는 함수
var data = $.Deferred();
//======================================
// 요청 정보 구성 : 시작 (각 요청에 맞게 조정)
//======================================
var reqUrl = "${pageContext.request.contextPath}/bbs/listQnasAjax.do";
var pageIndex = ( filter && filter.pageIndex ? filter.pageIndex : $("#pageIndex").val());
var pageSize = ( filter && filter.pageSize ? filter.pageSize : $("#pageSize").val());
var searchType = $("#searchType").val();
var searchKeyword = $("#searchKeyword").val();
var searchQuestionType = $("#searchQuestionType").val();
$("#pageIndex").val(pageIndex);
var inputData = {
"pageIndex" : pageIndex
, "pageSize" : pageSize
, "searchType" : searchType
, "searchKeyword" : searchKeyword
, "searchQuestionType" : searchQuestionType
};
//--------------------------------------
// 요청 처리
//--------------------------------------
$.ajax({
type: "post",
contentType: "application/json; charset=utf-8",
url: reqUrl,
dataType: "json",
data: JSON.stringify(inputData),
}).done(function(response){
<%
// 그리드 데이터 예시 :
// (1) 페이징 클라이언트에서 수행하는 경우(pageloading = false) : [{ "articleNo": 1, "articleType": "01" }, { "articleNo": 2, "articleType": "02" }]
// (2) 페이징 서버에서 수행하는 경우(pageloading = true) : {data: [{...}], itemsCount: 255}
%>
var jsonObj = JSON.parse(response);
//$("#itemsCount").val(jsonOjb.itemsCount);
console.log("itemsCount=" + jsonObj.itemsCount);
console.log("message=" + jsonObj.message);
$("#message").text(jsonObj.message);
if(jsonObj.itemsCount == undefined) {
$("#itemsCount").text("0");
$("#searchItemsCount").text("0");
}
else {
$("#itemsCount").text(jsonObj.itemsCount);
$("#searchItemsCount").text(jsonObj.itemsCount);
}
if($("#searchKeyword").val() != "") {
$("#searchKeywordPrt").text($("#searchKeyword").val());
$("#listResult").hide();
$("#searchResult").show();
}
else {
$("#listResult").show();
$("#searchResult").hide();
}
data.resolve(jsonObj);
});
return data.promise();
} // loadData
},
rowClick: function(args) { // 행 클릭 시, 실행되는 이벤트 함수
// 클릭된 행의 자료 객체
var getData = args.item;
// 추출할 컬럼의 데이터 가져오기
var articleId = getData["articleId"];
var selectedRow = $("#jsGrid").find('table tr.jsgrid-selected-row');
// 상세 내용 보기
fn_viewDetail(articleId, selectedRow);
},
//======================================
// 그리드 컬럼 정의 (각 요청에 맞게 조정)
//======================================
fields: [
{ title:"ID", name: "articleId" , type: "text", width: 200, align: "left" },
{ title:"번호", name: "rno" , type: "text", width: 200, align: "center" },
{ title:"비밀글", name: "secretYn" , type: "text", width: 200, align: "center" },
{ title:"제목", name: "title" , type: "text", width: 200, align: "left" },
{ title:"등록자", name: "regNm" , type: "text", width: 100, align: "center"},
{ title:"등록일", name: "regDd" , type: "text", width: 100, align: "center"},
{ title:"첨부", name: "attachYn" , type: "text", width: 100, align: "center"},
{ title:"내글여부", name: "myQnaYn", type: "text", width: 100, align: "center"}
]
});
// 검색 버튼 클릭
$("#btnSearch").on("click", function(e) {
fn_searchArticle($("#pageSize").val(), 1);
});
//초기 자료 조회
fn_searchArticle();
}); // document ready
// 선택한 글 상세 보기로 이동
function fn_viewDetail(articleId, selectedRow) {
var $selectedRow = $(selectedRow);
// 비밀글인 경우, 본인에 한하여 조회 가능
if($("#jsGrid").jsGrid("rowByItem", $selectedRow).data("JSGridItem")["secretYn"] == "Y" &&
$("#jsGrid").jsGrid("rowByItem", $selectedRow).data("JSGridItem")["myQnaYn"] == "N") {
alert("비공개 게시물은 작성자만 확인할 수 있습니다.");
return;
}
$("#articleId").val(articleId);
$("#articleForm").submit();
}
// 그리드 데이터 조회 호출
function fn_searchArticle(pageSize, pageIndex) {
$("#jsGrid").jsGrid("search"
, {'pageSize' : (pageSize ? pageSize : fn_getIntValue("pageSize", ${searchArticle.pageSize}) ),
'pageIndex' : (pageIndex ? pageIndex : fn_getIntValue("pageIndex", ${searchArticle.pageIndex}))
}
);
}
//파일 다운로드
function fn_downloadFile(fileId, fileSeq, fileName) {
if(fileId == null || fileId.trim().length < 1) {
alert("파일정보를 확인해 주시기 바랍니다.[1]");
return;
}
if(fileSeq < 1) {
alert("파일정보를 확인해 주시기 바랍니다.[2]");
return;
}
if(fileName == null || fileName.trim().length < 1) {
alert("파일정보를 확인해 주시기 바랍니다.[3]");
return;
}
$("#fileId").val(fileId);
$("#fileSeq").val(fileSeq);
$("#fileName").val(fileName);
$("#downloadFileForm").submit();
}
function fn_changeQuestionType(searchQuestionType) {
$("#searchQuestionType").val(searchQuestionType);
fn_searchArticle($("#pageSize").val(), 1);
}
//게시글 작성으로 이동
function fn_newArticle() {
$("#articleNo").val("");
$("#articleForm").attr("action", "${pageContext.request.contextPath}/bbs/insertQnaForm.do");
$("#articleForm").submit();
}
</script>
</head>
<body>
<h1>${pageTitle }</h1>
메시지 : <span name="message" id="message" style="color:red;">${message}</span>
<div name="listResult" id="listResult">
총 <span name="itemsCount" id="itemsCount"></span>건<br>
</div>
<div style="display:none;" name="searchResult" id="searchResult">
'<span name="searchKeywordPrt" id="searchKeywordPrt"></span>' 에 대한 검색결과는 총 <span name="searchItemsCount" id="searchItemsCount"></span>건 입니다.<br>
</div>
&nbsp;<br/>
<!-- 질문자선택 -->
<table>
<tr>
<td><a href="javascript:void(0);" onclick="fn_changeQuestionType('')">전체</a></td>
<td><a href="javascript:void(0);" onclick="fn_changeQuestionType('USER')">내 질문</a></td>
</tr>
</table>
<br>
<form name="articleForm" id="articleForm" method="post" action="${pageContext.request.contextPath}/bbs/selectQnaArticle.do">
<button type="button" name="btnNewTop" id="btnNewTop" class="float" title="글쓰기버튼"
onclick="fn_newArticle()">글쓰기</button>
<!-- 검색조건 -->
<input type="text" name="pageSize" id="pageSize" value="${searchArticle.pageSize }" />
<input type="text" name="pageIndex" id="pageIndex" title="페이지번호" value="${searchArticle.pageIndex }" size="5" maxlength="5" />
<select name="searchType" id="searchType">
<option value="T" <c:if test='${searchArticle.searchType == "T" }'>selected</c:if> >제목</option>
<option value="C" <c:if test='${searchArticle.searchType == "C" }'>selected</c:if> >내용</option>
</select>
<input type="text" name="searchKeyword" id="searchKeyword" title="검색어" value="${searchArticle.searchKeyword }" maxlength="20" />
<input type="text" name="articleId" id="articleId" title="게시글번호" value="" readonly />
<input type="button" name="btnSearch" id="btnSearch" title="검색" value="검색" />
<br/>
<div id="jsGrid" name="jsGrid" style="height: 100%"></div>
<input type="text" name="searchQuestionType" id="searchQuestionType" value="" title="유형코드" readonly />
<input type="text" name="articleNo" id="articleNo" value="" title="선택글번호" readonly />
<button type="button" name="btnNew" id="btnNew" class="float" title="글쓰기버튼"
onclick="fn_newArticle()">글쓰기</button>
</form>
<!-- 첨부파일 다운로드용 폼 -->
<form name="downloadFileForm" id="downloadFileForm"
action="${pageContext.request.contextPath}/fileupload/downloadAttachFile.do"
method="post">
<input type="text" name="subPathKey" id="subPathKey" value="fileupload.bbs.ancmnt.subpath" readonly />
<input type="text" name="fileId" id="fileId" value="" readonly />
<input type="text" name="fileSeq" id="fileSeq" value="" readonly />
<input type="text" name="fileName" id="fileName" value="" readonly />
</form>
</body>
</html>

View File

@ -0,0 +1,170 @@
<%
/**
* <pre>
* @Class Name : selectQnaArticle.jsp
*
* @Description : 묻고답하기 상세내용을 조회한다.
*
*
* @프로젝트명: 지방문화원 통합자료관리시스템 구축사업 (2021)
*
* </pre>
*
* @ ------------ -------- ---------------------------
* @ 수정일 수정자 수정내용
* @ ------------ -------- ---------------------------
* @ 2021. 9. 16. KNKIM 최초 생성
*
*
* @author 이씨플라자 * DIGITALSHIP KNKIM
* @since 2021. 9. 16.
* @version 1.0
*
*/
%>
<%@ page language="java" contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="ui" uri="http://egovframework.gov/ctl/ui" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="validator" uri="http://www.springmodules.org/tags/commons-validator" %>
<c:set var="pageTitle">묻고답하기 - 상세조회</c:set>
<!DOCTYPE html>
<html lang="ko">
<head>
<title>${pageTitle}</title>
<script type="text/javaScript" language="javascript">
// 목록으로 이동
function fn_list() {
$("#articleForm").submit();
}
// 파일 다운로드
function fn_downloadFile(fileId, fileSeq, fileName) {
if(fileId == null || fileId.trim().length < 1) {
alert("파일정보를 확인해 주시기 바랍니다.[1]");
return;
}
if(fileSeq < 1) {
alert("파일정보를 확인해 주시기 바랍니다.[2]");
return;
}
if(fileName == null || fileName.trim().length < 1) {
alert("파일정보를 확인해 주시기 바랍니다.[3]");
return;
}
$("#fileId").val(fileId);
$("#fileSeq").val(fileSeq);
$("#fileName").val(fileName);
$("#downloadFileForm").submit();
}
</script>
</head>
<body>
<h1>${pageTitle }</h1>
메시지 : <span style="color:red;">${message }</span>
<br />
<form name="articleForm" id="articleForm"
action="${pageContext.request.contextPath}/bbs/listQnas.do"
method="post">
<!-- HIDDEN 영역 : 시작 -->
<input type="text" name="pageIndex" id="pageIndex" title="페이지번호" value="${searchArticle.pageIndex}" readonly />
<input type="text" name="pageSize" id="pageSize" title="목록에 보여줄 글개수" value="${searchArticle.pageSize}" readonly />
<input type="text" name="searchType" id="searchType" title="검색구분" value="${searchArticle.searchType}" readonly />
<input type="text" name="searchKeyword" id="searchKeyword" title="검색어" value="${searchArticle.searchKeyword}" readonly />
<input type="text" name="articleId" id="articleId" title="선택글번호" value="${searchArticle.articleId}" readonly />
<!-- HIDDEN 영역 : 종료 -->
<table class="table_content" style="width:100% !important; margin-top: 20px;">
<tr>
<th>작성일</th>
<td>${article.regDd }</td>
<th>답변여부</th>
<td>
<c:if test='${article.answerYn == "Y"}'>답변완료</c:if>
<c:if test='${article.answerYn != "Y"}'>답변대기중</c:if>
</td>
</tr>
<tr>
<th>비밀글여부</th>
<td>
<c:if test='${article.secretYn == "Y"}'>비밀글</c:if>
<c:if test='${article.secretYn != "Y"}'>일반</c:if>
</td>
<th rowspan="1">제목</th>
<td colspan="1">${article.title}</td>
</tr>
<tr>
<th rowspan="1">질문자</th>
<td colspan="3">${article.regNm}</td>
</tr>
<tr>
<th rowspan="1">질문내용</th>
<td colspan="3">${article.content}</td>
</tr>
<c:if test='${article.secretYn == "Y"}'>
<tr>
<th rowspan="1">답변내용</th>
<td colspan="3">${article.answer}</td>
</tr>
</c:if>
<c:if test="${article.attachFileCnt > 0}">
<tr>
<td colspan="4">
<%
// 파일정보 : 저장파일ID=원파일명
%>
<c:forEach var="attachFile" items="${article.attachFiles }">
<a href="javascript:void(0);" onclick="fn_downloadFile('${attachFile.fileId}', ${attachFile.fileSeq}, '${attachFile.fileName}')">${attachFile.fileName} (${attachFile.fileSize} byte(s))</a><br/>
</c:forEach>
</td>
</tr>
</c:if>
<c:if test="${article.attachFileCnt < 1}">
<td colspan="4">첨부파일 없음
</td>
</c:if>
</table>
<br/>
<!-- 관련 작업 버튼 -->
<button type="button" name="btnList" id="btnList" class="float"
onclick="fn_list()">목록</button>
</form>
<br />
<!-- 첨부파일 다운로드용 폼 -->
<form name="downloadFileForm" id="downloadFileForm"
action="${pageContext.request.contextPath}/fileupload/downloadAttachFile.do"
method="post">
<input type="text" name="subPathKey" id="subPathKey" value="fileupload.bbs.ancmnt.subpath" readonly />
<input type="text" name="fileId" id="fileId" value="" readonly />
<input type="text" name="fileSeq" id="fileSeq" value="" readonly />
<input type="text" name="fileName" id="fileName" value="" readonly />
</form>
</body>
</html>

View File

@ -9,7 +9,8 @@
<li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/bbs/listAncmnts.do';">공지사항(DB)</a></li> <li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/bbs/listAncmnts.do';">공지사항(DB)</a></li>
<li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/board/listFAQs.do';">자주하는질문</a></li> <li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/board/listFAQs.do';">자주하는질문</a></li>
<li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/bbs/listFaqs.do';">자주하는질문(DB)</a></li> <li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/bbs/listFaqs.do';">자주하는질문(DB)</a></li>
<li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/bbs/listQnAs.do';">묻고답하기</a></li> <li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/board/listQnAs.do';">묻고답하기</a></li>
<li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/bbs/listQnas.do';">묻고답하기(DB)</a></li>
<li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/inform/selectNCultureLocationInfo.do';">찾아오시는길</a></li> <li><a href="#" onclick="javascript:location.href='${pageContext.request.contextPath}/inform/selectNCultureLocationInfo.do';">찾아오시는길</a></li>
<!-- 자료검색 --> <!-- 자료검색 -->

View File

@ -79,7 +79,7 @@
}, },
rowDoubleClick : $.noop, rowDoubleClick : $.noop,
noDataContent : "Not found", noDataContent : "검색 결과가 없습니다.",
noDataRowClass : "jsgrid-nodata-row", noDataRowClass : "jsgrid-nodata-row",
heading : true, heading : true,

View File

@ -1 +0,0 @@
Tue Sep 14 2021 08:25:17 GMT+0900 (대한민국 표준시)

View File

@ -1,21 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test</title>
<script src="/nlib/js/jquery/jquery.min.js"></script>
<script src="/nlib/js/nlib.js"></script>
<script>
</script>
</head>
<body>
NLIB
</body>
</html>