diff --git a/egovframe-template-simple-react-contribution/package.json b/egovframe-template-simple-react-contribution/package.json index ee83992..bd8d7f2 100644 --- a/egovframe-template-simple-react-contribution/package.json +++ b/egovframe-template-simple-react-contribution/package.json @@ -25,6 +25,7 @@ "react-csv": "^2.2.2", "react-datepicker": "^4.8.0", "react-dom": "^18.2.0", + "react-drag-drop-files": "^2.3.10", "react-element-to-jsx-string": "^15.0.0", "react-icons": "^4.11.0", "react-loader-spinner": "^5.4.5", diff --git a/egovframe-template-simple-react-contribution/src/components/alert/FormDialog.jsx b/egovframe-template-simple-react-contribution/src/components/alert/FormDialog.jsx index 3913079..5eaf2d3 100644 --- a/egovframe-template-simple-react-contribution/src/components/alert/FormDialog.jsx +++ b/egovframe-template-simple-react-contribution/src/components/alert/FormDialog.jsx @@ -13,8 +13,12 @@ export default function FormDialog( {open, setOpen, title, contentText, children setOpen(true); }; - const handleClose = () => { - setOpen(false); + const handleClose = (event, reason) => { + // background를 click해도 dialog가 사라지지 않도록 한다. + if(reason !== 'backdropClick' && reason !== 'escapeKeyDown') { + // Set 'open' to false, however you would do that with your particular code. + setOpen(false); + } }; return ( diff --git a/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx b/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx new file mode 100644 index 0000000..4cc8a16 --- /dev/null +++ b/egovframe-template-simple-react-contribution/src/components/file/FileDragDrop.jsx @@ -0,0 +1,27 @@ +import React, { useState } from "react"; +import { FileUploader } from "react-drag-drop-files"; + + +/** + * https://www.npmjs.com/package/react-drag-drop-files를 참고해주세요. + * @param {fileTypes} const fileTypes = ["JPG", "PNG", "GIF"]; + * @returns + */ +function FileDragDrop({fileTypes, children, multiple, label, onDrop, handleChange, file, setFile, dropMessageStyle}) { + + return ( + + {children && children} + + ); +} + +export default FileDragDrop; \ No newline at end of file diff --git a/egovframe-template-simple-react-contribution/src/components/list/ListCreateUpdateDelete.jsx b/egovframe-template-simple-react-contribution/src/components/list/ListCreateUpdateDelete.jsx index 09eeb11..27ef71c 100644 --- a/egovframe-template-simple-react-contribution/src/components/list/ListCreateUpdateDelete.jsx +++ b/egovframe-template-simple-react-contribution/src/components/list/ListCreateUpdateDelete.jsx @@ -15,7 +15,8 @@ import AddIcon from '@mui/icons-material/Add'; import styledComponent from "styled-components"; -import * as EgovNet from 'api/egovFetch'; + +import CODE from 'constants/code'; const StyledDiv = styledComponent.div` @@ -67,20 +68,41 @@ const Item = styled(Paper)(({ theme }) => ({ function ListCreateUpdateDelete(props) { - const handleClickOpen = () => { + const handleClickCreate = (e) => { + + const mode = CODE.MODE_CREATE; + + let paramOrgId = props.itemIndex[props.depthSelectedArrayIndex-1]; if( props.depthSelectedArrayIndex === 0 ) { - props.setCreateCondition({...props.createCondition, paramCodeLevel : props.paramCodeLevel, paramOrgId : "00"}); - } else { - if( props.itemIndex[props.depthSelectedArrayIndex-1] === undefined ) { - alert('상위 코드를 선택해주세요.'); - props.setIsPopupOpen(false); - return false; - } - props.setCreateCondition({...props.createCondition, paramCodeLevel : props.paramCodeLevel, paramOrgId : props.itemIndex[props.depthSelectedArrayIndex-1]}); - } + paramOrgId = "00"; + } + if( props.depthSelectedArrayIndex !== 0 && props.itemIndex[props.depthSelectedArrayIndex-1] === undefined ) { + alert('상위 코드를 선택해주세요.'); + props.setIsPopupOpen(false); + return false; + } + + props.setCreateOrModifyCondition({mode, paramCodeLevel : props.paramCodeLevel, paramOrgId}); props.setIsPopupOpen(true); }; + const handleClickModify = (e) => { + + const mode = CODE.MODE_MODIFY; + + let paramOrgId = props.itemIndex[props.depthSelectedArrayIndex-1]; + if( props.depthSelectedArrayIndex === 0 ) { + paramOrgId = "00"; + } + + const dataKey = e.currentTarget.parentNode.parentNode.parentNode.getAttribute('data-key'); + const target = props.items[dataKey]; + + props.setCreateOrModifyCondition({mode, paramCodeLevel : props.paramCodeLevel, paramOrgId, target }); + props.setIsPopupOpen(true); + + }; + const onClickItem = (e, index) => { index = Number(index); // 기존 active를 모두 해제 한다. @@ -107,7 +129,7 @@ function ListCreateUpdateDelete(props) { - + @@ -115,15 +137,13 @@ function ListCreateUpdateDelete(props) { - + {generate( props.items, - { - props.setIsPopupOpen(true); - }}> + { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx index 00ff49b..5390d47 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt.jsx @@ -18,7 +18,7 @@ import { default as EgovLeftNav } from 'components/leftmenu/EgovLeftNavAdmin'; function CommitteeCodeMgt(props) { const [searchCondition, setSearchCondition] = useState({ paramCodeGroup: null, paramCodeLevel: 'LV_01' }); - const [createCondition, setCreateCondition] = useState(); + const [createOrModifyCondition, setCreateOrModifyCondition] = useState(); const [depth01List, setDepth01List] = useState({}); const [depth02List, setDepth02List] = useState({}); @@ -30,7 +30,6 @@ function CommitteeCodeMgt(props) { const [confirm, setConfirm] = React.useState(); - const [editCreateMode, setEditCreateMode] = React.useState(); // 생성 or 수정 여부 @@ -90,15 +89,7 @@ function CommitteeCodeMgt(props) { // eslint-disable-next-line react-hooks/exhaustive-deps }, [searchCondition]); - - - useEffect(function () { - if( typeof createCondition !== 'undefined' ) { - console.log('%o', createCondition); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [createCondition]); - + const requestOptions = { method: "GET", @@ -182,7 +173,7 @@ function CommitteeCodeMgt(props) { if( Number(depthSelectedIndex[depthSelectedArrayIndex]) === Number(deleteItem.orgId) ) { for( let i = depthSelectedArrayIndex + 1; i<4; i++ ) { - //setSearchCondition({...searchCondition, paramCodeLevel : createCondition.paramCodeLevel}); + //setSearchCondition({...searchCondition, paramCodeLevel : createOrModifyCondition.paramCodeLevel}); depthSelectedIndex[i] = undefined; } let forChangeObject = [...depthSelectedIndex]; @@ -199,11 +190,6 @@ function CommitteeCodeMgt(props) { case 2: setDepth04List({}); } - - - - - } @@ -243,16 +229,18 @@ function CommitteeCodeMgt(props) {
{/* */} +

위원회 코드 관리

+ :not(style)': { - mt: 4, + mt: 0, width: 245, }, }} @@ -264,8 +252,8 @@ function CommitteeCodeMgt(props) { itemIndex={depthSelectedIndex} setItemIndex={setDepthSelectedIndex} depthSelectedArrayIndex={0} - createCondition={createCondition} - setCreateCondition={setCreateCondition} + createOrModifyCondition={createOrModifyCondition} + setCreateOrModifyCondition={setCreateOrModifyCondition} paramCodeLevel="LV_01" upParamOrgId="00" nameKey="orgNm" @@ -280,8 +268,8 @@ function CommitteeCodeMgt(props) { itemIndex={depthSelectedIndex} setItemIndex={setDepthSelectedIndex} depthSelectedArrayIndex={1} - createCondition={createCondition} - setCreateCondition={setCreateCondition} + createOrModifyCondition={createOrModifyCondition} + setCreateOrModifyCondition={setCreateOrModifyCondition} searchCondition={searchCondition} setSearchCondition={setSearchCondition} paramCodeLevel="LV_02" @@ -297,8 +285,8 @@ function CommitteeCodeMgt(props) { itemIndex={depthSelectedIndex} setItemIndex={setDepthSelectedIndex} depthSelectedArrayIndex={2} - createCondition={createCondition} - setCreateCondition={setCreateCondition} + createOrModifyCondition={createOrModifyCondition} + setCreateOrModifyCondition={setCreateOrModifyCondition} searchCondition={searchCondition} setSearchCondition={setSearchCondition} paramCodeLevel="LV_03" @@ -314,8 +302,8 @@ function CommitteeCodeMgt(props) { itemIndex={depthSelectedIndex} setItemIndex={setDepthSelectedIndex} depthSelectedArrayIndex={3} - createCondition={createCondition} - setCreateCondition={setCreateCondition} + createOrModifyCondition={createOrModifyCondition} + setCreateOrModifyCondition={setCreateOrModifyCondition} searchCondition={searchCondition} setSearchCondition={setSearchCondition} paramCodeLevel="LV_04" @@ -345,8 +333,7 @@ function CommitteeCodeMgt(props) { diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx index 61ad200..4335814 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/config/CommitteeCodeMgt/CommitteeCodeRegistrationPopup.jsx @@ -1,53 +1,125 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import TextField from '@mui/material/TextField'; import * as EgovNet from 'api/egovFetch'; + +import CODE from 'constants/code'; + import FormDialog from '../../../../components/alert/FormDialog'; function CommitteeCodeRegistrationPopup(props) { + const [inputValues, setInputValues] = useState({}); - const handleClickCreateCommitteeCodeManagement = (createCondition) => { + const [mode, setMode] = useState("등록"); + + useEffect(function () { + + if( typeof props.createOrModifyCondition === "undefined" ) { + return; + } + + if( typeof props.createOrModifyCondition.mode === "undefined" ) { + return; + } - if( createCondition.paramOrgId === undefined ) { + //모드가 변경 되면 값을 초기화 한다. + setInputValues({}); + + if( props.createOrModifyCondition.mode === CODE.MODE_MODIFY ) { + setMode("수정"); + } else if( props.createOrModifyCondition.mode === CODE.MODE_CREATE ) { + setMode("등록"); + } + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.createOrModifyCondition && props.createOrModifyCondition.mode]); + + useEffect(function () { + + if( typeof props.createOrModifyCondition === "undefined" ) { + return; + } + + if( typeof props.createOrModifyCondition.mode === "undefined" ) { + return; + } + + if( props.createOrModifyCondition.mode === CODE.MODE_CREATE ) { + return; + } + + if( typeof props.createOrModifyCondition.target === "undefined" ) { + return; + } + + + + setInputValues({ + ...inputValues, + paramOrgNm : props.createOrModifyCondition.target.orgNm, + paramOrgDesc : props.createOrModifyCondition.target.orgDesc, + }); + + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [props.createOrModifyCondition && props.createOrModifyCondition.target]); + + + + + const handleClickCreateCommitteeCodeManagement = (createOrModifyCondition) => { + + if( createOrModifyCondition.paramOrgId === undefined ) { alert('상위 코드를 선택해주세요.'); props.setOpen(false); return false; } const formData = new FormData(); - for (let key in createCondition) { - formData.append(key, createCondition[key]); + for (let key in createOrModifyCondition) { + formData.append(key, createOrModifyCondition[key]); } + + Object.keys(inputValues).forEach(function(key){ + formData.append(key, inputValues[key]); + }); + const requestOptions = { - method: "POST", + method: props.createOrModifyCondition.mode === CODE.MODE_CREATE ? "POST" : props.createOrModifyCondition.mode === CODE.MODE_MODIFY ? "PUT" : "", body: formData, }; - EgovNet.requestFetch(`/admin/config/committee-code-management`, + let appendRequestURL = ""; + if( props.createOrModifyCondition.mode === CODE.MODE_MODIFY ) { + appendRequestURL = `/${props.createOrModifyCondition.target.orgId}`; + } + const requestURL = "/admin/config/committee-code-management" + appendRequestURL; + EgovNet.requestFetch(requestURL, requestOptions, function (resp) { - //방금 추가한 것만 새로 읽어 드린다. - let paramCodeGroup = props.createCondition.paramOrgId; + //새로 읽어 드린다. + let paramCodeGroup = props.createOrModifyCondition.paramOrgId; if( paramCodeGroup === "00" ) { paramCodeGroup = null; } - props.setSearchCondition({...props.searchCondition, paramCodeGroup, paramCodeLevel : props.createCondition.paramCodeLevel}); + props.setSearchCondition({...props.searchCondition, paramCodeGroup, paramCodeLevel : props.createOrModifyCondition.paramCodeLevel}); props.setOpen(false); } ); } - const handleTextFieldChange = (event) => { - const elName = event.target.getAttribute('name'); - const elValue = event.target.value; - props.setCreateCondition({...props.createCondition, [elName]:elValue}); + const handleTextFieldChange = (e) => { + setInputValues({ + ...inputValues, + [e.target.name]: e.target.value, + }); }; - return ( - {handleClickCreateCommitteeCodeManagement(props.createCondition);}} > + return (// handleClickCreateCommitteeCodeManagement create or modiofy 로 분기처리해야 한다. thkim 20240305 1500 + {handleClickCreateCommitteeCodeManagement(props.createOrModifyCondition);}} > diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx index 05460a2..b75acda 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/contents/PopUp/PopupEditor.jsx @@ -1,6 +1,8 @@ import React, { useState, useEffect } from 'react'; import { Link, useLocation, useNavigate } from 'react-router-dom'; import DatePicker from "react-datepicker"; +import FileDragDrop from "../../../../components/file/FileDragDrop"; +import AttachFileIcon from '@mui/icons-material/AttachFile'; import EgovAttachFile from 'components/EgovAttachFile'; import RichTextEditor from "../../../../components/editor/RichTextEditor"; @@ -19,11 +21,30 @@ const StyledDiv = styled.div` .board_view2 { margin-bottom: 30px; + dl.file-attach-wrapper dd { + padding: 0px; + + + .file_attach { + width: 100%; + label { + width: 100%; + padding: 0px 0px; + div { + padding: 30px 10px; + color: #999; + } + } + } + + } } - `; + + + function PopupEditor(props) { const navigate = useNavigate(); @@ -38,7 +59,7 @@ function PopupEditor(props) { const [schdulBgndeMM, setSchdulBgndeMM] = useState(); const [schdulEnddeHH, setSchdulEnddeHH] = useState(); const [schdulEnddeMM, setSchdulEnddeMM] = useState(); - const [boardAttachFiles, setBoardAttachFiles] = useState(); + const [fileName, setFileName] = useState(); const [confirm, setConfirm] = React.useState(); @@ -118,6 +139,10 @@ function PopupEditor(props) { }); setText(rawDetail.contents); setTextOriginal(rawDetail.contents); + + if( rawDetail.fileName ) { + setFileName(rawDetail.fileName); + } } ); } @@ -139,7 +164,10 @@ function PopupEditor(props) { //게시글 내용 formData.delete("contents"); - formData.append("contents", text); + formData.append("contents", text); + + //첨부파일 + formData.append("file", file); if (formValidator(formData)) { const requestOptions = { @@ -165,9 +193,11 @@ function PopupEditor(props) { if (modeInfo.mode === CODE.MODE_CREATE) { - setConfirm({...confirm, open: true, body: "추가하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:modeInfo.editURL}}); + //setConfirm({...confirm, open: true, body: "추가하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:modeInfo.editURL}}); + requestTask({requestUrl:modeInfo.editURL}); } else if (modeInfo.mode === CODE.MODE_MODIFY) { - setConfirm({...confirm, open: true, body: "수정하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:`${modeInfo.editURL}/${location.state?.popupId}`}}); + //setConfirm({...confirm, open: true, body: "수정하시겠습니까?", yesCallback: requestTask, yesCallbackParams: {requestUrl:`${modeInfo.editURL}/${location.state?.popupId}`}}); + requestTask({requestUrl:`${modeInfo.editURL}/${location.state?.popupId}`}); } } @@ -233,7 +263,25 @@ function PopupEditor(props) { return number < 10 ? "0" + number : number.toString(); } + const fileTypes = ["JPG", "PNG", "GIF", "PDF", "HWP", "HWPX", "ZIP", "JPEG", "MP4", "TXT"]; + const onDrop = (e) => { + //alert('ddd'); + }; + + const [file, setFile] = useState(null); + const handleChange = (file) => { + setFile(file); + }; + + useEffect(function () { + if( file ) { + console.log('%o', file); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [file]); + + const Location = React.memo(function Location() { return (
@@ -263,7 +311,7 @@ function PopupEditor(props) { {/* */}
-

팝업 추가

+

팝업 관리

{/* */}
@@ -315,22 +363,28 @@ function PopupEditor(props) { + +
+
첨부파일
+
+ + +
+ + {file ? file.name : fileName ? fileName : "파일을 마우스로 끌어놓으세요."} +
+
+
+
- { - console.log("====>>> Changed attachfile file = ", attachfile); - const arrayConcat = { ...popupDetail}; // 기존 단일 파일 업로드에서 다중파일 객체 추가로 변환(아래 for문으로) - for ( let i = 0; i < attachfile.length; i++) { - arrayConcat[`file_${i}`] = attachfile[i]; - } - setPopupDetail(arrayConcat); - }} - fnDeleteFile={(deletedFile) => { - console.log("====>>> Delete deletedFile = ", deletedFile); - setBoardAttachFiles(deletedFile); - }} - boardFiles={boardAttachFiles} - mode={props.mode} /> +
{/* */} @@ -339,22 +393,22 @@ function PopupEditor(props) { {/* */} {/* */} -
+
+ +
+
{modeInfo.mode === CODE.MODE_MODIFY && - }
-
- -
{/* */} diff --git a/egovframe-template-simple-react-contribution/src/pages/admin/contents/StandardResearch.jsx b/egovframe-template-simple-react-contribution/src/pages/admin/contents/StandardResearch.jsx index 7d1a67a..69a13ca 100644 --- a/egovframe-template-simple-react-contribution/src/pages/admin/contents/StandardResearch.jsx +++ b/egovframe-template-simple-react-contribution/src/pages/admin/contents/StandardResearch.jsx @@ -14,12 +14,26 @@ import styled from "styled-components"; const StyledDiv = styled.div` .BRD008 { - .head > span:nth-child(3) { - width: 200px; + .head { + span:nth-child(3) { + width: 200px; + } + span:nth-child(4) { + width: 200px; + } } - .result .list_item > div:nth-child(3) { - width: 200px; + .result .list_item { + & > div { + &:nth-child(3) { + width: 200px; + } + &:nth-child(4) { + width: 200px; + } + } } + + } .board-bot { diff --git a/egovframe-template-simple-react-contribution/yarn.lock b/egovframe-template-simple-react-contribution/yarn.lock index 42e9a01..b9950ec 100644 --- a/egovframe-template-simple-react-contribution/yarn.lock +++ b/egovframe-template-simple-react-contribution/yarn.lock @@ -8613,6 +8613,14 @@ react-dom@^18.2.0: loose-envify "^1.1.0" scheduler "^0.23.0" +react-drag-drop-files@^2.3.10: + version "2.3.10" + resolved "https://registry.yarnpkg.com/react-drag-drop-files/-/react-drag-drop-files-2.3.10.tgz#3f6ea316f8ad66a6f76b312cc4108c7c14065b06" + integrity sha512-Fv614W9+OtXFB5O+gjompTxQZLYGO7wJeT4paETGiXtiADB9yPOMGYD4A3PMCTY9Be874/wcpl+2dm3MvCIRzg== + dependencies: + prop-types "^15.7.2" + styled-components "^5.3.0" + react-element-to-jsx-string@^15.0.0: version "15.0.0" resolved "https://registry.npmjs.org/react-element-to-jsx-string/-/react-element-to-jsx-string-15.0.0.tgz" @@ -9604,7 +9612,7 @@ style-loader@^3.3.1: resolved "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz" integrity sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ== -styled-components@^5.3.5: +styled-components@^5.3.0, styled-components@^5.3.5: version "5.3.11" resolved "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz" integrity sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw== diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java index cde6d6c..92412e5 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/AdminConfigController.java @@ -3,6 +3,7 @@ package com.dbnt.kcscbackend.admin.config; import com.dbnt.kcscbackend.admin.config.entity.TcMenu; import com.dbnt.kcscbackend.admin.config.entity.TnPartnerSite; import com.dbnt.kcscbackend.admin.config.model.CreateCommitteeCodeManagementVO; +import com.dbnt.kcscbackend.admin.config.model.SetCommitteeCodeManagementVO; import com.dbnt.kcscbackend.admin.config.service.AdminCommitteeCodeManagementService; import com.dbnt.kcscbackend.commonCode.entity.TcCodeGrp; import com.dbnt.kcscbackend.commonCode.entity.TcCodeItem; @@ -563,4 +564,43 @@ public class AdminConfigController extends BaseController { return resultVO; } + @Operation( + summary = "'위원회 코드 관리' 페이지에서 위원회 코드 수정하는 API", + description = "관리자 단에서 '환경설정' > '위원회코드 관리' 페이지에서 연필 모양 수정 버튼으로 항목 수정하는 API", + tags = {"AdminConfigController"} + ) + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "등록 성공"), + @ApiResponse(responseCode = "403", description = "인가된 사용자가 아님"), + }) + @PutMapping(value = "/committee-code-management/{orgId}") + public ResultVO setCommitteeCodeManagement( + HttpServletRequest request, + @AuthenticationPrincipal LoginVO loginVO, + SetCommitteeCodeManagementVO setCommitteeCodeManagementVO, + @PathVariable("orgId") Long orgId + ) throws Exception { + ResultVO resultVO = new ResultVO(); + + try { + resultVO = adminCommitteeCodeManagementService.setCommitteeCodeManagement(resultVO, request, loginVO, setCommitteeCodeManagementVO, orgId); + } catch (Exception e) { + resultVO.setResultCode(ResponseCode.FAILED.getCode()); + resultVO.setResultMessage(e.getMessage()); + } + + + System.out.println( + "\n--------------------------------------------------------------\n" + + request.getRequestURI() + " OUT:" + + "\n--------------------------------------------------------------\n" + + "resultVO.toString():" + "\n" + + resultVO.toString() + "\n" + + "\n--------------------------------------------------------------\n" + ); + + return resultVO; + + } + } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/model/SetCommitteeCodeManagementVO.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/model/SetCommitteeCodeManagementVO.java new file mode 100644 index 0000000..3edb0b2 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/model/SetCommitteeCodeManagementVO.java @@ -0,0 +1,25 @@ +package com.dbnt.kcscbackend.admin.config.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +import java.io.Serializable; + +@ApiModel(value = "SetCommitteeCodeManagementVO", description = + "관리자 단에서 '환경설정' > '위원회코드 관리' 페이지에서 수정 버튼으로 항목 수정하는 API에 사용된다." +) +@RequiredArgsConstructor +@Getter +@Setter +@ToString +public class SetCommitteeCodeManagementVO extends CreateCommitteeCodeManagementVO implements Serializable { + private static final long serialVersionUID = -603047540959527181L; + + @ApiModelProperty(value = "cmtSeq") + private Long orgId; + +} diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminCommitteeCodeManagementService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminCommitteeCodeManagementService.java index 4d83564..88112ac 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminCommitteeCodeManagementService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/AdminCommitteeCodeManagementService.java @@ -1,6 +1,7 @@ package com.dbnt.kcscbackend.admin.config.service; import com.dbnt.kcscbackend.admin.config.model.CreateCommitteeCodeManagementVO; +import com.dbnt.kcscbackend.admin.config.model.SetCommitteeCodeManagementVO; import com.dbnt.kcscbackend.admin.standardResearch.model.CreateStandardResearchVO; import com.dbnt.kcscbackend.admin.standardResearch.model.UpdateStandardResearchVO; import com.dbnt.kcscbackend.auth.entity.LoginVO; @@ -15,7 +16,8 @@ import javax.servlet.http.HttpServletRequest; public interface AdminCommitteeCodeManagementService { public ResultVO createCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, CreateCommitteeCodeManagementVO createCommitteeCodeManagementVO) throws Exception; public ResultVO getCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long upCmtSeq, String cmtType) throws Exception; - public ResultVO setCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdateStandardResearchVO updateStandardResearchVO, Long popupId) throws Exception; - public ResultVO deleteCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long popupId) throws Exception; + public ResultVO setCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, SetCommitteeCodeManagementVO setCommitteeCodeManagementVO, Long cmtSeq) throws Exception; + public ResultVO deleteCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long cmtSeq) throws Exception; + } \ No newline at end of file diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/impl/AdminCommitteeCodeManagementServiceImpl.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/impl/AdminCommitteeCodeManagementServiceImpl.java index 244a8c8..24a6cbf 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/impl/AdminCommitteeCodeManagementServiceImpl.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/config/service/impl/AdminCommitteeCodeManagementServiceImpl.java @@ -1,6 +1,7 @@ package com.dbnt.kcscbackend.admin.config.service.impl; import com.dbnt.kcscbackend.admin.config.model.CreateCommitteeCodeManagementVO; +import com.dbnt.kcscbackend.admin.config.model.SetCommitteeCodeManagementVO; import com.dbnt.kcscbackend.admin.config.service.AdminCommitteeCodeManagementService; import com.dbnt.kcscbackend.admin.standardResearch.model.CreateStandardResearchVO; import com.dbnt.kcscbackend.admin.standardResearch.model.UpdateStandardResearchVO; @@ -13,6 +14,7 @@ import lombok.RequiredArgsConstructor; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo; import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartHttpServletRequest; @@ -107,8 +109,48 @@ public class AdminCommitteeCodeManagementServiceImpl extends EgovAbstractService } @Override - public ResultVO setCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdateStandardResearchVO updateStandardResearchVO, Long popupId) throws Exception { - return null; + public ResultVO setCommitteeCodeManagement(ResultVO resultVO, HttpServletRequest request, LoginVO user, SetCommitteeCodeManagementVO setCommitteeCodeManagementVO, Long cmtSeq) throws Exception { + System.out.println( + "\n--------------------------------------------------------------\n" + + request.getRequestURI() + " IN:" + + "\n--------------------------------------------------------------\n" + + "setCommitteeCodeManagementVO:" + "\n" + + setCommitteeCodeManagementVO.toString() + "\n" + + "cmtSeq:" + "\n" + + cmtSeq + "\n" + + "\n--------------------------------------------------------------\n" + ); + + // 유효성 검사 실시 + int isValid = tnCmtOrgRepository.spIsValidTnCmtOrgId(cmtSeq.intValue()); + + if( isValid == 0 ) { + throw new Exception("대상이 존재하지 않습니다."); + } + + TnCmtOrg tnCmtOrg = tnCmtOrgRepository.findByCmtSeq(cmtSeq); + + Map response = tnCmtOrgRepository.spUpdateTnCmtOrg( + cmtSeq.intValue(), + setCommitteeCodeManagementVO.getParamOrgNm(), + setCommitteeCodeManagementVO.getParamOrgDesc(), + tnCmtOrg.getCmtOrder(), + user.getId(), + null, + null, + null + ); + + + Map dto = new HashMap(); + dto.put("errorMessage", response.get("_error_message") ); + dto.put("orgId", cmtSeq); + + resultVO.setResult(dto); + resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); + resultVO.setResultMessage(ResponseCode.SUCCESS.getMessage()); + + return resultVO; } @Override diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/controller/PopUpApiController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/controller/PopUpApiController.java index 23c74a8..5e25e94 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/controller/PopUpApiController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/controller/PopUpApiController.java @@ -1,14 +1,9 @@ package com.dbnt.kcscbackend.admin.contents.popUp.controller; -import com.dbnt.kcscbackend.admin.committee.schedules.model.CreateScheduleVO; -import com.dbnt.kcscbackend.admin.committee.schedules.model.UpdateScheduleVO; -import com.dbnt.kcscbackend.admin.committee.schedules.service.EgovIndvdlSchdulManageService; import com.dbnt.kcscbackend.admin.contents.popUp.model.CreatePopupVO; -import com.dbnt.kcscbackend.admin.contents.popUp.model.FileVO; import com.dbnt.kcscbackend.admin.contents.popUp.model.UpdatePopupVO; import com.dbnt.kcscbackend.admin.contents.popUp.service.PopUpApiService; -import com.dbnt.kcscbackend.admin.contents.popUp.utils.EgovFileMngUtil; import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.config.common.ResponseCode; import com.dbnt.kcscbackend.config.common.ResultVO; @@ -26,8 +21,7 @@ import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; -import java.util.List; -import java.util.Map; +import java.util.Enumeration; @Api("PopUpApiController") @@ -38,8 +32,6 @@ public class PopUpApiController { @Resource(name = "popUpApiService") private PopUpApiService popUpApiService; - @Resource(name = "EgovFileMngUtil") - private EgovFileMngUtil fileUtil; @Operation( summary = "'팝업 관리' 페이지에서 목록 불러오는 API", @@ -95,13 +87,14 @@ public class PopUpApiController { HttpServletRequest request, @AuthenticationPrincipal LoginVO loginVO, final MultipartHttpServletRequest multiRequest, - CreatePopupVO createPopupVO + CreatePopupVO createPopupVO, + @RequestParam(required = false) MultipartFile file ) throws Exception { ResultVO resultVO = new ResultVO(); try { - resultVO = popUpApiService.contentsApiPopUpManageCreate(resultVO, request, loginVO, multiRequest, createPopupVO); + resultVO = popUpApiService.contentsApiPopUpManageCreate(resultVO, request, loginVO, multiRequest, createPopupVO, file); } catch (Exception e) { resultVO.setResultCode(ResponseCode.FAILED.getCode()); resultVO.setResultMessage(e.getMessage()); @@ -136,13 +129,14 @@ public class PopUpApiController { HttpServletRequest request, @AuthenticationPrincipal LoginVO loginVO, UpdatePopupVO updatePopupVO, + @RequestParam(required = false) MultipartFile file, @PathVariable("popupId") Long popupId ) throws Exception { ResultVO resultVO = new ResultVO(); try { - resultVO = popUpApiService.contentsApiPopUpManageUpdate(resultVO, request, loginVO, updatePopupVO, popupId); + resultVO = popUpApiService.contentsApiPopUpManageUpdate(resultVO, request, loginVO, updatePopupVO, file, popupId); } catch (Exception e) { resultVO.setResultCode(ResponseCode.FAILED.getCode()); resultVO.setResultMessage(e.getMessage()); diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/CreatePopupVO.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/CreatePopupVO.java index c08d8ba..3cfa5a3 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/CreatePopupVO.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/CreatePopupVO.java @@ -6,8 +6,10 @@ import lombok.Getter; import lombok.RequiredArgsConstructor; import lombok.Setter; import lombok.ToString; +import org.springframework.web.multipart.MultipartFile; import java.io.Serializable; +import java.util.Optional; @ApiModel(value = "CreatePopupVO", description = "관리자 단에서 '컨텐츠 관리' > '팝업 관리' 페이지에서 팝업을 추가하는 API에 사용된다." + "" @@ -28,4 +30,6 @@ public class CreatePopupVO implements Serializable { private String title; @ApiModelProperty(value = "contents") private String contents; + //@ApiModelProperty(value = "file") + //private MultipartFile file; } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/UpdatePopupVO.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/UpdatePopupVO.java index 9408459..0085e64 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/UpdatePopupVO.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/model/UpdatePopupVO.java @@ -12,7 +12,6 @@ import java.io.Serializable; @ApiModel(value = "UpdatePopupVO", description = "관리자 단에서 '컨텐츠 관리' > '팝업 관리' 페이지에서 팝업을 수정하는 API에 사용된다." + "" ) -@RequiredArgsConstructor @Getter @Setter @ToString diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/PopUpApiService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/PopUpApiService.java index dee31af..e01f810 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/PopUpApiService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/PopUpApiService.java @@ -9,15 +9,16 @@ import org.springframework.data.domain.Pageable; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import javax.servlet.http.HttpServletRequest; public interface PopUpApiService { public ResultVO contentsApiPopUpManageList(ResultVO resultVO, HttpServletRequest request, LoginVO user, Pageable pageable) throws Exception; - public ResultVO contentsApiPopUpManageCreate(ResultVO resultVO, HttpServletRequest request, LoginVO user, final MultipartHttpServletRequest multiRequest, CreatePopupVO createPopupVO) throws Exception; + public ResultVO contentsApiPopUpManageCreate(ResultVO resultVO, HttpServletRequest request, LoginVO user, final MultipartHttpServletRequest multiRequest, CreatePopupVO createPopupVO, MultipartFile file) throws Exception; public ResultVO contentsApiPopUpManageRead(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long popupId) throws Exception; - public ResultVO contentsApiPopUpManageUpdate(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdatePopupVO updatePopupVO, Long popupId) throws Exception; + public ResultVO contentsApiPopUpManageUpdate(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdatePopupVO updatePopupVO, MultipartFile file, Long popupId) throws Exception; public ResultVO contentsApiPopUpManageDelete(ResultVO resultVO, HttpServletRequest request, LoginVO user, Long popupId) throws Exception; public ResultVO contentsApiPopUpManageUpdateActivationSwitch(ResultVO resultVO, HttpServletRequest request, LoginVO user, String checked, Long popupId) throws Exception; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/impl/PopUpApiServiceImpl.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/impl/PopUpApiServiceImpl.java index c6664cc..b174159 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/impl/PopUpApiServiceImpl.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/service/impl/PopUpApiServiceImpl.java @@ -6,11 +6,16 @@ import com.dbnt.kcscbackend.admin.contents.popUp.model.FileVO; import com.dbnt.kcscbackend.admin.contents.popUp.model.UpdatePopupVO; import com.dbnt.kcscbackend.admin.contents.popUp.repository.TnPopupMngRepositoryWithoutPopupContents; import com.dbnt.kcscbackend.admin.contents.popUp.service.PopUpApiService; +import com.dbnt.kcscbackend.file.entity.TnAttachFile; +import com.dbnt.kcscbackend.file.repository.TnAttachFileRepository; +import com.dbnt.kcscbackend.file.service.EgovFileMngUtil; import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.commonCode.entity.TnPopupMng; import com.dbnt.kcscbackend.commonCode.repository.TnPopupMngRepository; import com.dbnt.kcscbackend.config.common.ResponseCode; import com.dbnt.kcscbackend.config.common.ResultVO; +import com.dbnt.kcscbackend.file.service.FileService; +import com.dbnt.kcscbackend.util.NetworkUtil; import lombok.RequiredArgsConstructor; import org.egovframe.rte.fdl.cmmn.EgovAbstractServiceImpl; import org.egovframe.rte.ptl.mvc.tags.ui.pagination.PaginationInfo; @@ -19,11 +24,12 @@ import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; +import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.text.SimpleDateFormat; import java.time.format.DateTimeFormatter; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; @@ -34,6 +40,10 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU private final TnPopupMngRepository tnPopupMngRepository; private final TnPopupMngRepositoryWithoutPopupContents tnPopupMngRepositoryWithoutPopupContents; + private final TnAttachFileRepository tnAttachFileRepository; + + private final FileService fileService; + @Override public ResultVO contentsApiPopUpManageList(ResultVO resultVO, HttpServletRequest request, LoginVO user, Pageable pageable) throws Exception { @@ -93,7 +103,7 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU @Override - public ResultVO contentsApiPopUpManageCreate(ResultVO resultVO, HttpServletRequest request, LoginVO user, final MultipartHttpServletRequest multiRequest, CreatePopupVO createPopupVO) throws Exception { + public ResultVO contentsApiPopUpManageCreate(ResultVO resultVO, HttpServletRequest request, LoginVO user, final MultipartHttpServletRequest multiRequest, CreatePopupVO createPopupVO, MultipartFile file) throws Exception { System.out.println( "\n--------------------------------------------------------------\n" + @@ -104,21 +114,14 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU "\n--------------------------------------------------------------\n" ); - // 첨부파일 관련 첨부파일ID 생성 - List _result = null; - String _atchFileId = ""; - final Map files = multiRequest.getFileMap(); - - if (!files.isEmpty()) { - //_atchFileId = fileMngService.insertFileInfs(_result); //파일이 생성되고나면 생성된 첨부파일 ID를 리턴한다. - } + String fileGrpId = fileService.addTnAttachFile(request, user, file, this.getMiddlePath()); Map response = tnPopupMngRepository.spAddTnPopupMng( createPopupVO.getTitle(), createPopupVO.getStartDate(), createPopupVO.getEndDate(), - null, + fileGrpId, createPopupVO.getContents(), "kcsc_admin", null, @@ -169,6 +172,14 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU dto.put("schdulBgnde", tnPopupMng.getPopupStartDate().plusHours(9).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 날짜/시간의 시작 일시 - yyyyMMddHHmmss dto.put("schdulEndde", tnPopupMng.getPopupEndDate().plusHours(9).format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"))); // 날짜/시간의 종료 일시 - yyyyMMddHHmmss + //첨부파일명을 가져온다. + TnAttachFile tnAttachFile = tnAttachFileRepository.findByFileGrpId(tnPopupMng.getFileGrpId()).orElse(null); + + if( tnAttachFile != null ) { + dto.put("fileName", tnAttachFile.getFileOldName()); + } else { + dto.put("fileName", null); + } resultVO.setResult(dto); resultVO.setResultCode(ResponseCode.SUCCESS.getCode()); @@ -178,16 +189,16 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU } @Override - public ResultVO contentsApiPopUpManageUpdate(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdatePopupVO updatePopupVO, Long popupId) throws Exception { + public ResultVO contentsApiPopUpManageUpdate(ResultVO resultVO, HttpServletRequest request, LoginVO user, UpdatePopupVO updatePopupVO, MultipartFile file, Long popupId) throws Exception { System.out.println( "\n--------------------------------------------------------------\n" + - request.getRequestURI() + " IN:" + - "\n--------------------------------------------------------------\n" + - "updatePopupVO:" + "\n" + - updatePopupVO.toString() + "\n" + - "popupId:" + "\n" + - popupId + "\n" + - "\n--------------------------------------------------------------\n" + request.getRequestURI() + " IN:" + + "\n--------------------------------------------------------------\n" + + "updatePopupVO:" + "\n" + + updatePopupVO.toString() + "\n" + + "popupId:" + "\n" + + popupId + "\n" + + "\n--------------------------------------------------------------\n" ); // 유효성 검사 실시 @@ -201,14 +212,16 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU throw new Exception("종료일시는 시작일시보다 앞 설 수 없습니다."); } + String fileGrpId = fileService.addTnAttachFile(request, user, file, this.getMiddlePath()); + Map response = tnPopupMngRepository.spUpdateTnPopupMng( popupId.intValue(), updatePopupVO.getTitle(), updatePopupVO.getStartDate(), updatePopupVO.getEndDate(), - null, + fileGrpId, updatePopupVO.getContents(), - "kcsc_admin", + user.getId(), null, null, null @@ -311,4 +324,24 @@ public class PopUpApiServiceImpl extends EgovAbstractServiceImpl implements PopU } + /** + * 파일이 저장될 중간 경로를 생성한다. + * D:/kcscUploadFiles/XXXX/abc.jpg XXXX에 해당하는 경로다. + * @return 중간 경로 + */ + private String getMiddlePath() { + //파일이 저장될 경로를 생성한다. + String domainPath = "popup"; + Date nowDate = new Date(); + String strNowYyyy = new SimpleDateFormat("yyyy").format(nowDate); + String strNowYyyyMmdd = new SimpleDateFormat("yyyyMMdd").format(nowDate); + String middlePath = domainPath + "/" + strNowYyyy + "/" + strNowYyyyMmdd + "/"; + + return middlePath; + } + + + + + } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standardResearch/AdminStandardResearchController.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standardResearch/AdminStandardResearchController.java index 3154df3..33a8489 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standardResearch/AdminStandardResearchController.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/standardResearch/AdminStandardResearchController.java @@ -1,7 +1,7 @@ package com.dbnt.kcscbackend.admin.standardResearch; -import com.dbnt.kcscbackend.admin.contents.popUp.utils.EgovFileMngUtil; +import com.dbnt.kcscbackend.file.service.EgovFileMngUtil; import com.dbnt.kcscbackend.admin.standardResearch.model.CreateStandardResearchVO; import com.dbnt.kcscbackend.admin.standardResearch.model.UpdateStandardResearchVO; import com.dbnt.kcscbackend.admin.standardResearch.service.AdminStandardResearchService; diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java index a08b36d..11ced52 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/commonCode/repository/TnCmtOrgRepository.java @@ -41,6 +41,26 @@ public interface TnCmtOrgRepository extends JpaRepository spUpdateTnCmtOrg( + @Param("_cmt_seq") Integer cmtSeq, + @Param("_cmt_nm") String cmtNm, + @Param("_cmt_desc") String cmtDesc, + @Param("_cmt_order") Integer cmtOrder, + @Param("_modi_id") String modiId, + @Param("_result_count") Integer resultCount, + @Param("_result_code") String resultCode, + @Param("_error_message") String errorMessage + ); @Query(value = "CALL sp_delete_tn_cmt_org (" + diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/util/EgovStringUtil.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/util/EgovStringUtil.java index c3f256c..3cdc1d9 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/util/EgovStringUtil.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/config/util/EgovStringUtil.java @@ -826,7 +826,6 @@ public class EgovStringUtil { * * @param * @return Timestamp 값 - * @exception MyException * @see */ public static String getTimeStamp() { diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/repository/TnAttachFileRepository.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/repository/TnAttachFileRepository.java index 2dc6ff1..9584ded 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/repository/TnAttachFileRepository.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/repository/TnAttachFileRepository.java @@ -2,10 +2,48 @@ package com.dbnt.kcscbackend.file.repository; import com.dbnt.kcscbackend.file.entity.TnAttachFile; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.jpa.repository.query.Procedure; +import org.springframework.data.repository.query.Param; +import java.util.Map; import java.util.Optional; public interface TnAttachFileRepository extends JpaRepository { Optional findByFileGrpId(String fileGrpId); + + @Procedure("make_file_grp_id") + String makeFileGrpId( String modiId ); + + @Query(value = "CALL sp_add_tn_attach_file (" + + ":_file_grp_id, " + + ":_file_order, " + + ":_file_old_name, " + + ":_file_new_name, " + + ":_file_path, " + + ":_file_size, " + + ":_file_ext, " + + ":_ip_address, " + + ":_modi_id, " + + ":_result_count, " + + ":_result_code, " + + ":_error_message)", + nativeQuery = true) + Map spAddTnAttachFile( + @Param("_file_grp_id") String _file_grp_id, + @Param("_file_order") Integer _file_order, + @Param("_file_old_name") String _file_old_name, + @Param("_file_new_name") String _file_new_name, + @Param("_file_path") String _file_path, + @Param("_file_size") Long _file_size, + @Param("_file_ext") String _file_ext, + @Param("_ip_address") String _ip_address, + @Param("_modi_id") String _modi_id, + @Param("_result_count") Integer resultCount, + @Param("_result_code") String resultCode, + @Param("_error_message") String errorMessage + ); + + } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/utils/EgovFileMngUtil.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/EgovFileMngUtil.java similarity index 79% rename from kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/utils/EgovFileMngUtil.java rename to kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/EgovFileMngUtil.java index e4e312c..17d5056 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/admin/contents/popUp/utils/EgovFileMngUtil.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/EgovFileMngUtil.java @@ -1,6 +1,9 @@ -package com.dbnt.kcscbackend.admin.contents.popUp.utils; +package com.dbnt.kcscbackend.file.service; import com.dbnt.kcscbackend.admin.contents.popUp.model.FileVO; +import com.dbnt.kcscbackend.admin.contents.popUp.utils.EgovStringUtil; +import com.dbnt.kcscbackend.admin.contents.popUp.utils.EgovWebUtil; +import com.dbnt.kcscbackend.config.util.EgovNumberUtil; import lombok.extern.slf4j.Slf4j; import org.egovframe.rte.fdl.idgnr.EgovIdGnrService; import org.egovframe.rte.fdl.property.EgovPropertyService; @@ -12,10 +15,7 @@ import javax.annotation.Resource; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.*; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.Map.Entry; /** @@ -43,6 +43,8 @@ public class EgovFileMngUtil { @Resource(name = "propertiesService") protected EgovPropertyService propertyService; + + /** * 첨부파일에 대한 목록 정보를 취득한다. * @@ -50,87 +52,97 @@ public class EgovFileMngUtil { * @return * @throws Exception */ - public List parseFileInf(Map files, String KeyStr, int fileKeyParam, String atchFileId, String storePath) throws Exception { - int fileKey = fileKeyParam; + public List parseFileInf(Map files, String KeyStr, int fileKeyParam, String middlePath, String storePath) throws Exception { + int fileKey = fileKeyParam; - String storePathString = ""; - String atchFileIdString = ""; - if ("".equals(storePath) || storePath == null) { - storePathString = propertyService.getString("Globals.fileStorePath"); - } else { - storePathString = propertyService.getString(storePath); - } - - atchFileId = atchFileId.replaceAll("\\s", ""); + String storePathString = ""; + String atchFileIdString = ""; - if ("".equals(atchFileId) || atchFileId == null) { - atchFileIdString = "testest_thkim-temp-20240124_1446"; - } else { - atchFileIdString = atchFileId; - } + if ("".equals(storePath) || storePath == null) { + storePathString = propertyService.getString("Globals.fileStorePath"); + } else { + storePathString = propertyService.getString(storePath); + } - File saveFolder = new File(EgovWebUtil.filePathBlackList(storePathString)); + middlePath = middlePath.replaceAll("\\s", ""); - if (!saveFolder.exists() || saveFolder.isFile()) { - saveFolder.mkdirs(); - } + if ("".equals(middlePath) || middlePath == null) { + atchFileIdString = EgovStringUtil.getTimeStamp() + EgovNumberUtil.getRandomNum(0, 9) + EgovNumberUtil.getRandomNum(0, 9) + ""; + } else { + atchFileIdString = middlePath; + } - Iterator> itr = files.entrySet().iterator(); - MultipartFile file; - String filePath = ""; - List result = new ArrayList(); - FileVO fvo; + File saveFolder = new File(EgovWebUtil.filePathBlackList(storePathString)); - while (itr.hasNext()) { - Entry entry = itr.next(); + if (!saveFolder.exists() || saveFolder.isFile()) { + saveFolder.mkdirs(); + } - file = entry.getValue(); - String orginFileName = file.getOriginalFilename(); - - //-------------------------------------- - // 원 파일명이 null인 경우 처리 - //-------------------------------------- - if (orginFileName == null) { - orginFileName = ""; - } - ////------------------------------------ + Iterator> itr = files.entrySet().iterator(); + MultipartFile file; + String filePath = ""; + List result = new ArrayList(); + FileVO fvo; - //-------------------------------------- - // 원 파일명이 없는 경우 처리 - // (첨부가 되지 않은 input file type) - //-------------------------------------- - if ("".equals(orginFileName)) { - continue; - } - ////------------------------------------ - - int index = orginFileName.lastIndexOf("."); - //String fileName = orginFileName.substring(0, index); - String fileExt = orginFileName.substring(index + 1); - String newName = KeyStr + EgovStringUtil.getTimeStamp() + fileKey; - long _size = file.getSize(); + while (itr.hasNext()) { + Entry entry = itr.next(); - if (!"".equals(orginFileName)) { - filePath = storePathString + File.separator + newName; - file.transferTo(new File(EgovWebUtil.filePathBlackList(filePath))); - } - fvo = new FileVO(); - fvo.setFileExtsn(fileExt); - fvo.setFileStreCours(storePathString); - fvo.setFileMg(Long.toString(_size)); - fvo.setOrignlFileNm(orginFileName); - fvo.setStreFileNm(newName); - fvo.setAtchFileId(atchFileIdString); - fvo.setFileSn(String.valueOf(fileKey)); + file = entry.getValue(); + String orginFileName = file.getOriginalFilename(); - //writeFile(file, newName, storePathString); - result.add(fvo); + //-------------------------------------- + // 원 파일명이 null인 경우 처리 + //-------------------------------------- + if (orginFileName == null) { + orginFileName = ""; + } + ////------------------------------------ - fileKey++; - } + //-------------------------------------- + // 원 파일명이 없는 경우 처리 + // (첨부가 되지 않은 input file type) + //-------------------------------------- + if ("".equals(orginFileName)) { + continue; + } + ////------------------------------------ - return result; + int index = orginFileName.lastIndexOf("."); + //String fileName = orginFileName.substring(0, index); + String fileExt = orginFileName.substring(index + 1); + String newName = KeyStr + EgovStringUtil.getTimeStamp() + fileKey; + long _size = file.getSize(); + + if (!"".equals(orginFileName)) { + + filePath = storePathString + File.separator + middlePath + File.separator; + + File savePath = new File(EgovWebUtil.filePathBlackList(filePath)); + if (!savePath.exists() || savePath.isFile()) { + savePath.mkdirs(); + } + + file.transferTo(new File(EgovWebUtil.filePathBlackList(savePath.getAbsolutePath() + File.separator + newName + "." + fileExt))); + } + + + fvo = new FileVO(); + fvo.setFileExtsn(fileExt); + fvo.setFileStreCours(storePathString.replaceAll("\\\\", "/")); + fvo.setFileMg(Long.toString(_size)); + fvo.setOrignlFileNm(orginFileName); + fvo.setStreFileNm(newName); + fvo.setAtchFileId(atchFileIdString.replaceAll("\\\\", "/")); + fvo.setFileSn(String.valueOf(fileKey)); + + //writeFile(file, newName, storePathString); + result.add(fvo); + + fileKey++; + } + + return result; } /** diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/FileService.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/FileService.java index b96b197..3da38f8 100644 --- a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/FileService.java +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/file/service/FileService.java @@ -1,10 +1,22 @@ package com.dbnt.kcscbackend.file.service; +import com.dbnt.kcscbackend.admin.contents.popUp.model.FileVO; +import com.dbnt.kcscbackend.auth.entity.LoginVO; import com.dbnt.kcscbackend.file.entity.TnAttachFile; import com.dbnt.kcscbackend.file.repository.TnAttachFileRepository; +import com.dbnt.kcscbackend.util.NetworkUtil; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; @Service @RequiredArgsConstructor @@ -12,6 +24,9 @@ public class FileService { private final TnAttachFileRepository tnAttachFileRepository; + @Resource(name = "EgovFileMngUtil") + private EgovFileMngUtil fileUtil; + @Transactional public TnAttachFile selectTnAttachFile(TnAttachFile tnAttachFile) { if(tnAttachFile.getFileSeq()!=null){ @@ -24,4 +39,63 @@ public class FileService { tnAttachFileRepository.save(tnAttachFile); return tnAttachFile; } + + + + + + + /** + * TN_ATTACH_FILE table에 insert 후, 파일 그룹 ID를 return 한다. + * TN_ATTACH_FILE 참고. + * @param request + * @param user + * @param file + * @param middlePath 파일이 저장될 중간 경로다. + * D:/kcscUploadFiles/XXXX/abc.jpg XXXX에 해당하는 경로다. + * 참고로 D:/kcscUploadFiles 값은 application-xxx.properties에 있는 Globals.fileStorePath를 통해 얻는다. + * @return 파일 그룹 ID + * @throws Exception + */ + public String addTnAttachFile(HttpServletRequest request, LoginVO user, MultipartFile file, String middlePath) throws Exception { + String ipAddress = NetworkUtil.getClientIpAddress(request); + + String fileGrpId = null; + if( file != null && !file.isEmpty()) { + + Map filesMap = new HashMap(); + filesMap.put("file", file); + + //String fileGrpId = UUID.randomUUID().toString(); + fileGrpId = tnAttachFileRepository.makeFileGrpId(user.getId()); + + List files = fileUtil.parseFileInf(filesMap, "", 0, middlePath, null); + + int nCount = 1; + // 업로드된 file을 tnAttachFile에 insert한다. + for (Iterator iter = files.iterator(); iter.hasNext(); nCount++) { + + FileVO item = iter.next(); + + tnAttachFileRepository.spAddTnAttachFile( + fileGrpId, + nCount, + item.getOrignlFileNm(), + item.getStreFileNm() + "." + item.getFileExtsn(), + (item.getFileStreCours() + File.separator + item.getAtchFileId()).replaceAll("\\\\", "/"), + Long.parseLong(item.getFileMg()), + item.getFileExtsn(), + ipAddress, + user.getId(), + null, + null, + null + ); + + } + } + + return fileGrpId; + } + } diff --git a/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/util/NetworkUtil.java b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/util/NetworkUtil.java new file mode 100644 index 0000000..0d445d1 --- /dev/null +++ b/kcsc-back-end/src/main/java/com/dbnt/kcscbackend/util/NetworkUtil.java @@ -0,0 +1,29 @@ +package com.dbnt.kcscbackend.util; + +import javax.servlet.http.HttpServletRequest; + +public final class NetworkUtil { + private static final String[] HEADERS_TO_TRY = { + "X-Forwarded-For", + "Proxy-Client-IP", + "WL-Proxy-Client-IP", + "HTTP_X_FORWARDED_FOR", + "HTTP_X_FORWARDED", + "HTTP_X_CLUSTER_CLIENT_IP", + "HTTP_CLIENT_IP", + "HTTP_FORWARDED_FOR", + "HTTP_FORWARDED", + "HTTP_VIA", + "REMOTE_ADDR" }; + + public static String getClientIpAddress(HttpServletRequest request) { + for (String header : HEADERS_TO_TRY) { + String ip = request.getHeader(header); + if (ip != null && !ip.isEmpty() && !"unknown".equalsIgnoreCase(ip)) { + return ip; + } + } + + return request.getRemoteAddr(); + } +} diff --git a/kcsc-back-end/src/main/resources/application-dev.properties b/kcsc-back-end/src/main/resources/application-dev.properties index e3b636c..604bda4 100644 --- a/kcsc-back-end/src/main/resources/application-dev.properties +++ b/kcsc-back-end/src/main/resources/application-dev.properties @@ -31,5 +31,5 @@ logging.level.com.atoz_develop.mybatissample.repository=TRACE # File Config Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=D:\\kcsc +Globals.fileStorePath=D:\\kcscUploadFiles Globals.addedOptions=false diff --git a/kcsc-back-end/src/main/resources/application-local.properties b/kcsc-back-end/src/main/resources/application-local.properties index 8117841..20ab5a8 100644 --- a/kcsc-back-end/src/main/resources/application-local.properties +++ b/kcsc-back-end/src/main/resources/application-local.properties @@ -37,5 +37,5 @@ logging.level.com.atoz_develop.mybatissample.repository=TRACE # File Config Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=D:\\kcsc +Globals.fileStorePath=D:\\kcscUploadFiles Globals.addedOptions=false \ No newline at end of file diff --git a/kcsc-back-end/src/main/resources/application-prod.properties b/kcsc-back-end/src/main/resources/application-prod.properties index f2215a0..9756184 100644 --- a/kcsc-back-end/src/main/resources/application-prod.properties +++ b/kcsc-back-end/src/main/resources/application-prod.properties @@ -34,5 +34,5 @@ logging.level.com.atoz_develop.mybatissample.repository=info # File Config Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=C:\\kcsc_web\\uploadedFile +Globals.fileStorePath=D:\\kcscUploadFiles Globals.addedOptions=false diff --git a/kcsc-back-end/src/main/resources/application-test.properties b/kcsc-back-end/src/main/resources/application-test.properties index aa45697..806fec5 100644 --- a/kcsc-back-end/src/main/resources/application-test.properties +++ b/kcsc-back-end/src/main/resources/application-test.properties @@ -34,5 +34,5 @@ logging.level.com.atoz_develop.mybatissample.repository=info # File Config Globals.posblAtchFileSize=5242880 -Globals.fileStorePath=/docker/kcscDev/uploadFiles +Globals.fileStorePath=D:\\kcscUploadFiles Globals.addedOptions=false \ No newline at end of file diff --git a/kcsc-back-end/src/main/resources/application.properties b/kcsc-back-end/src/main/resources/application.properties index df7a240..96c2e7e 100644 --- a/kcsc-back-end/src/main/resources/application.properties +++ b/kcsc-back-end/src/main/resources/application.properties @@ -18,3 +18,8 @@ Globals.admin.allow-ip = 218.49.16.81,218.49.21.183,218.49.16.168,218.49.17.102, #?????? ???? ? #?? : ??? ??? "egovframe"? ????? ???? ????? ????. + + +# filesize limit +spring.servlet.multipart.maxFileSize=10MB +spring.servlet.multipart.maxRequestSize=10MB \ No newline at end of file