fix : 모니터링 청산보고 중간저장

master
TaehunPark 2023-02-08 11:24:51 +09:00
parent 06db5a413c
commit b01b021370
8 changed files with 468 additions and 41 deletions

View File

@ -1,6 +1,7 @@
package com.dbnt.faisp.main.fpiMgt.monitoring;
import com.dbnt.faisp.main.authMgt.service.AuthMgtService;
import com.dbnt.faisp.main.codeMgt.service.CodeMgtService;
import com.dbnt.faisp.main.fpiMgt.affairPlan.model.PlanApprv;
import com.dbnt.faisp.main.fpiMgt.affairPlan.model.PlanBoard;
import com.dbnt.faisp.main.fpiMgt.intelligenceNetwork.model.OperationPlan;
@ -25,6 +26,7 @@ import java.util.List;
public class MonitoringController { // 첩보수집활동 > 해양외사모니터링
private final MonitoringService monitoringService;
private final AuthMgtService authMgtService;
private final CodeMgtService codeMgtService;
@GetMapping("/designationList/{type}")
public ModelAndView designationList(@AuthenticationPrincipal UserInfo loginUser,@PathVariable("type") String type, MonitoringDesignation md){
@ -251,6 +253,8 @@ public class MonitoringController { // 첩보수집활동 > 해양외사모니
}
mr.setWrtUserSeq(loginUser.getUserSeq());
mav.addObject("mr", mr);
mav.addObject("categoryList", codeMgtService.selectCodeMgtList("RIC"));
mav.addObject("codeList", codeMgtService.selectCodeMgtList("RID"));
return mav;
}

View File

@ -0,0 +1,64 @@
package com.dbnt.faisp.main.fpiMgt.monitoring.model;
import com.dbnt.faisp.config.FileInfo;
import lombok.*;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.multipart.MultipartFile;
import javax.persistence.*;
import java.io.File;
import java.io.Serializable;
import java.time.LocalDate;
import java.util.List;
@Getter
@Setter
@Entity
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@Table(name = "monitoring_result_file")
@IdClass(MonitoringReport.MonitoringReportId.class)
public class MonitoringReport extends FileInfo {
@Id
@Column(name = "mr_key")
private Integer mrKey;
@Id
@Column(name = "info_seq")
private Integer infoSeq;
@Column(name = "contact_date")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate contactDate;
@Column(name = "write_date")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate writeDate;
@Column(name = "report_title")
private String reportTitle;
@Column(name = "orig_nm")
private String origNm;
@Column(name = "conv_nm")
private String convNm;
@Column(name = "file_extn")
private String fileExtn;
@Column(name = "file_size")
private String fileSize;
@Column(name = "save_path")
private String savePath;
@Transient
private File file;
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class MonitoringReportId implements Serializable {
private Integer mrKey;
private Integer infoSeq;
}
}

View File

@ -34,6 +34,8 @@ public class MonitoringResult extends BaseModel {
private Integer mdKey;
@Column(name = "mr_title")
private String mrTitle;
@Column(name = "clear_title")
private String clearTitle;
@Column(name = "mr_sdate")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate mrSdate;
@ -72,6 +74,10 @@ public class MonitoringResult extends BaseModel {
@Transient
private List<MonitoringResultInfo> resultInfoList;
@Transient
private List<MonitoringResultClearInfo> clearInfoList;
@Transient
private List<MonitoringReport> reportList;
@Transient
private List<MultipartFile> multipartFileList;
@Transient
@DateTimeFormat(pattern = "yyyy-MM-dd")

View File

@ -0,0 +1,45 @@
package com.dbnt.faisp.main.fpiMgt.monitoring.model;
import lombok.*;
import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;
import org.springframework.format.annotation.DateTimeFormat;
import javax.persistence.*;
import java.io.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Getter
@Setter
@Entity
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@Table(name = "monitoring_result_clear_info")
@IdClass(MonitoringResultClearInfo.MonitoringResultClearInfoId.class)
public class MonitoringResultClearInfo {
@Id
@Column(name = "mr_key")
private Integer mrKey;
@Id
@Column(name = "info_seq")
private Integer infoSeq;
@Column(name = "use_catg")
private String useCatg;
@Column(name = "use_detail")
private String useDetail;
@Column(name = "price")
private Integer price;
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class MonitoringResultClearInfoId implements Serializable {
private Integer mrKey;
private Integer infoSeq;
}
}

View File

@ -0,0 +1,17 @@
package com.dbnt.faisp.main.fpiMgt.monitoring.repository;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringReport;
import org.springframework.data.jpa.repository.JpaRepository;
import java.util.List;
import java.util.Optional;
public interface MonitoringReportRepository extends JpaRepository<MonitoringReport, MonitoringReport.MonitoringReportId> {
void deleteByMrKey(Integer mrKey);
}

View File

@ -19,6 +19,7 @@ import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringDesignation;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringDesignationApprv;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringDesignationFile;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringDesignationFile.monitoringDesignationFileId;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringReport;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringResult;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringResultApprv;
import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringResultFile;
@ -27,6 +28,7 @@ import com.dbnt.faisp.main.fpiMgt.monitoring.model.MonitoringResultInfo;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringDesignationApprvRepository;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringDesignationFileRepository;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringDesignationRepository;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringReportRepository;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringResultApprvRepository;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringResultFileRepository;
import com.dbnt.faisp.main.fpiMgt.monitoring.repository.MonitoringResultInfoRepository;
@ -55,6 +57,7 @@ public class MonitoringService extends BaseService {
private final MonitoringResultApprvRepository monitoringResultApprvRepository;
private final MonitoringResultFileRepository monitoringResultFileRepository;
private final MonitoringResultInfoRepository monitoringResultInfoRepository;
private final MonitoringReportRepository monitoringReportRepository;
private final MonitoringMapper monitoringMapper;
@Transactional
@ -166,6 +169,9 @@ public class MonitoringService extends BaseService {
if (mr.getResultInfoList() != null){
saveResultInfoList(mrKey, mr.getResultInfoList());
}
if (mr.getReportList() != null){
saveReportList(mrKey, mr.getReportList());
}
if(mr.getMrState().equals("DST002")){
//작성완료일 때 계장 결재 사용자에게 알림 발송.
userAlarmService.sendAlarmToApprvUser(mrKey, mr.getWrtOrgan(), "APC003", 37, "해양외사 모니터링 모니터링보고에 결재대기 문서가 있습니다.");
@ -214,6 +220,25 @@ public class MonitoringService extends BaseService {
monitoringResultInfoRepository.saveAll(resultInfoList);
}
private void saveReportList(Integer mrKey, List<MonitoringReport> reportList){
//monitoringReportRepository.deleteByMrKey(mrKey);
for(MonitoringReport info: reportList){
MultipartFile file = (MultipartFile) info.getFile();
String saveName = UUID.randomUUID().toString();
String path = locationPath+monitoringPath;
saveFile(file, new File(path+File.separator+saveName));
String originalFilename = file.getOriginalFilename();
int extnIdx = originalFilename.lastIndexOf(".");
info.setMrKey(mrKey);
info.setOrigNm(originalFilename.substring(0, extnIdx));
info.setFileExtn(originalFilename.substring(extnIdx+1));
info.setConvNm(saveName);
info.setFileSize(calculationSize(file.getSize()));
info.setSavePath(path);
monitoringReportRepository.save(info);
}
}
public List<MonitoringResult> selectResultList(MonitoringResult mr) {
return monitoringMapper.selectResultList(mr);
}

View File

@ -92,6 +92,21 @@ $(document).on('click', '#resultInfoAddBtn', function (){
});
})
$(document).on('click', '#clearInfoAddBtn', function (){
const infoFm = $("#clearIinfoFmOrigin").children().clone();
$("#clearInfoRow").append(infoFm);
})
$(document).on('click', '#monitoringInfoAddBtn', function (){
const infoFm = $("#monitoringInfoFmOrigin").children().clone();
$("#monitoringInfoRow").append(infoFm);
infoFm.find(".contactDate,.writeDate").datepicker({
format: "yyyy-mm-dd",
language: "ko",
autoclose: true
});
})
$(document).on('click', '#editBtn', function (){
$("#resultViewModal").modal('hide');
getResultEditModal($(this).attr("data-mrkey"));
@ -153,6 +168,14 @@ function saveResult(mrState){
formData.append('resultInfoList['+(idx)+'].contactEtime', $(div).find(".contactEtime").val());
formData.append('resultInfoList['+(idx)+'].contactInfo', $(div).find(".contactInfo").val());
});
$.each($("#monitoringInfoRow").find(".infoRow"), function (idx, div){
formData.append('reportList['+(idx)+'].infoSeq', idx+1);
formData.append('reportList['+(idx)+'].contactDate', $(div).find(".contactDate").val());
formData.append('reportList['+(idx)+'].writeDate', $(div).find(".writeDate").val());
formData.append('reportList['+(idx)+'].reportTitle', $(div).find(".reportTitle").val());
formData.append('reportList['+(idx)+'].file', $(div).find(".file").val());
});
$.ajax({
type : 'POST',
@ -224,3 +247,10 @@ $(document).on('click', '.rowDeleteBtn', function (){
$(this).parents(".infoRow").remove();
})
$(document).on('click', '.rowDeleteBtn2', function (){
$(this).parents(".clearInfoRow").remove();
})
$(document).on('click', '.rowDeleteBtn3', function (){
$(this).parents(".monitoringInfoRow").remove();
})

View File

@ -16,6 +16,20 @@
<input type="hidden" name="wrtUserGrd" th:value="${mr.wrtUserGrd}">
<input type="hidden" name="wrtUserNm" th:value="${mr.wrtUserNm}">
<input type="hidden" name="wrtDt" th:value="${#temporals.format(mr.wrtDt, 'yyyy-MM-dd HH:mm')}">
<ul class="nav nav-tabs" id="userTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="clearReportTab" data-bs-toggle="tab" data-bs-target="#clearReportTabPanel" type="button" role="tab" aria-controls="clearReportTabPanel" aria-selected="true">청산보고서</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="resultReportTab" data-bs-toggle="tab" data-bs-target="#resultReportTabPanel" type="button" role="tab" aria-controls="resultReportTabPanel" aria-selected="false">결과보고서</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="affairListTab" data-bs-toggle="tab" data-bs-target="#affairListTabPanel" type="button" role="tab" aria-controls="affairListTabPanel" aria-selected="false">모니터링보고서목록&증빙자료</button>
</li>
</ul>
<br>
<div class="tab-content bg-white border border-top-0" id="configInfo">
<div class="tab-pane fade p-2 show active" id="clearReportTabPanel" role="tabpanel" aria-labelledby="clearReportTab" tabindex="0">
<div class="row mb-1">
<label class="col-sm-1 col-form-label col-form-label-sm text-center">작성자</label>
<div class="col-sm-2">
@ -26,25 +40,21 @@
<input type="text" class="form-control form-control-sm" placeholder="작성일 자동입력" readonly>
</div>
</div>
<hr>
<div class="row mb-1">
<label class="col-sm-1 col-form-label col-form-label-sm text-center">기간</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mrSdate" name="mrSdate" th:value="${mr.mrSdate}">
</div>
~
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mrEdate" name="mrEdate" th:value="${mr.mrEdate}">
<label for="workDateSelectorDiv" class="col-sm-2 col-form-label col-form-label-sm text-center">사업기간</label>
<div class="col-sm-4">
<div class="input-group w-auto input-daterange" id="workDateSelectorDiv">
<input type="text" class="form-control form-control-sm" id="mrSdate" name="mrSdate" readonly>
<input type="text" class="form-control form-control-sm" id="mrEdate" name="mrEdate" readonly>
</div>
</div>
</div>
<hr>
<div class="row mb-1">
<label class="col-sm-1 col-form-label col-form-label-sm text-center">제목</label>
<div class="col-sm-11">
<input type="text" class="form-control form-control-sm" id="mrTitle" name="mrTitle" th:value="${mr.mrTitle}">
<label for="clearTitle" class="col-sm-2 col-form-label col-form-label-sm text-center">제목</label>
<div class="col-sm-10">
<input type="text" class="form-control form-control-sm" id="clearTitle" name="clearTitle">
</div>
</div>
<hr>
<div class="row mb-1">
<h6 class="text-center">모니터링<br>대상</h6>
<div class="text-end">
@ -91,7 +101,130 @@
</div>
</div>
</th:block>
<hr>
<div class="row mb-1">
<label for="usePrice" class="col-sm-2 col-form-label col-form-label-sm text-center">집행액</label>
<div class="col-sm-4">
<div class="row">
<div class="col-auto me-0">
<input type="number" class="form-control form-control-sm" id="mrPrice" name="mrPrice">
</div>
<label for="usePrice" class="col-sm-auto col-form-label col-form-label-sm"></label>
</div>
</div>
</div>
<div class="row mb-1 justify-content-center">
<label for="clearInfoAddBtn" class="col-sm-2 col-form-label col-form-label-sm text-center">세부<br>집행내역</label>
<div class="col-sm-10">
<div class="row">
<div class="col-3">구분</div>
<div class="col-3">상세</div>
<div class="col-5">금액</div>
</div>
<hr class="my-1">
<div class="row">
<div class="col-12" id="clearInfoRow">
<th:block th:each="info:${mr.clearInfoList}">
<div class="row my-1 clearInfoRow">
<div class="col-3">
<select class="form-select form-select-sm useCatg">
<option value="">선택</option>
<th:block th:each="category:${categoryList}">
<option th:value="${category.itemCd}" th:text="${category.itemValue}"></option>
</th:block>
</select>
</div>
<div class="col-3">
<select class="form-select form-select-sm useDetail">
<option value="">선택</option>
<th:block th:each="code:${codeList}">
<option th:value="${code.itemCd}" th:text="${code.itemValue}"></option>
</th:block>
</select>
</div>
<div class="col-5">
<div class="row">
<div class="col-7 pe-0">
<input type="number" class="form-control form-control-sm price">
</div>
<label class="col-auto"></label>
<div class="col-auto">
<button type="button" class="btn btn-sm btn-outline-danger rowDeleteBtn2"><i class="bi bi-x"></i></button>
</div>
</div>
</div>
</div>
</th:block>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<button type="button" class="btn btn-sm btn-outline-primary" id="clearInfoAddBtn"><i class="bi bi-plus-lg"></i></button>
</div>
</div>
</div>
</div>
</div>
<div class="tab-pane fade p-2" id="resultReportTabPanel" role="tabpanel" aria-labelledby="resultReportTab" tabindex="0">
<div class="row mb-1">
<label class="col-sm-1 col-form-label col-form-label-sm text-center">기간</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" th:value="${mr.mrSdate}" disabled>
</div>
~
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" th:value="${mr.mrEdate}" disabled>
</div>
</div>
<div class="row mb-1">
<label class="col-sm-1 col-form-label col-form-label-sm text-center">제목</label>
<div class="col-sm-11">
<input type="text" class="form-control form-control-sm" id="mrTitle" name="mrTitle" th:value="${mr.mrTitle}">
</div>
</div>
<div class="row mb-1">
<h6 class="text-center">모니터링<br>대상</h6>
</div>
<th:block th:if="${mr.mrKey eq null}">
<div class="row mb-1">
<label for="opName" class="col-sm-1 col-form-label col-form-label-sm text-center">대상지정일</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdDt" disabled>
</div>
<label for="opName" class="col-sm-1 col-form-label col-form-label-sm text-center">성명</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdName" disabled>
</div>
<label for="opBirth" class="col-sm-1 col-form-label col-form-label-sm text-center">국적</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdNationality" disabled>
</div>
<label for="opPosition" class="col-sm-1 col-form-label col-form-label-sm text-center">소속·계급</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdRank" disabled>
</div>
</div>
</th:block>
<th:block th:unless="${mr.mrKey eq null}">
<div class="row mb-1">
<label for="opName" class="col-sm-1 col-form-label col-form-label-sm text-center">대상지정일</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdDt" th:value="${mr.md.mdDt}" disabled>
</div>
<label for="opName" class="col-sm-1 col-form-label col-form-label-sm text-center">성명</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdName" th:value="${mr.md.mdName}" disabled>
</div>
<label for="opBirth" class="col-sm-1 col-form-label col-form-label-sm text-center">국적</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdNationality" th:value="${mr.md.mdNationality}" disabled>
</div>
<label for="opPosition" class="col-sm-1 col-form-label col-form-label-sm text-center">소속·계급</label>
<div class="col-sm-2">
<input type="text" class="form-control form-control-sm" id="mdRank" th:value="${mr.md.mdRank}" disabled>
</div>
</div>
</th:block>
<div class="row mb-1 justify-content-center">
<label for="resultInfoRow" class="col-sm-1 col-form-label col-form-label-sm text-center">활동내용</label>
<div class="col-sm-11">
@ -131,14 +264,61 @@
</div>
</div>
</div>
<hr>
<div class="row mb-1">
<label for="fireExtensionReason" class="col-sm-1 col-form-label col-form-label-sm text-center">집행예산</label>
<div class="col-sm-3">
<input type="number" class="form-control form-control-sm" id="mrPrice" name="mrPrice" th:value="${mr.mrPrice}">
<label for="usePrice" class="col-sm-2 col-form-label col-form-label-sm text-center">집행액</label>
<div class="col-sm-4">
<div class="row">
<div class="col-auto me-0">
<input type="number" class="form-control form-control-sm" disabled>
</div>
<label for="usePrice" class="col-sm-auto col-form-label col-form-label-sm"></label>
</div>
</div>
</div>
</div>
<div class="tab-pane fade p-2" id="affairListTabPanel" role="tabpanel" aria-labelledby="affairListTab" tabindex="0">
<div class="row mb-1 justify-content-center">
<label for="resultInfoRow" class="col-sm-1 col-form-label col-form-label-sm text-center">모니터링<br>보고서</label>
<div class="col-sm-11">
<div class="row">
<div class="col-2">접촉일</div>
<div class="col-2">작성일</div>
<div class="col-3">제목</div>
<div class="col-3">첨부파일</div>
<div class="col-1"></div>
</div>
<hr class="my-1">
<div class="row">
<div class="col-12" id="monitoringInfoRow">
<th:block th:each="info:${mr.reportList}">
<div class="row my-1 infoRow">
<div class="col-2">
<input type="text" class="form-control form-control-sm contactDate" placeholder="YYYY-MM-DD" readonly>
</div>
<div class="col-2">
<input type="text" class="form-control form-control-sm writeDate" placeholder="YYYY-MM-DD" readonly>
</div>
<div class="col-3">
<input type="text" class="form-control form-control-sm reportTitle">
</div>
<div class="col-3">
<input class="file" type="file">
</div>
<div class="col-1">
<button type="button" class="btn btn-sm btn-outline-danger rowDeleteBtn3"><i class="bi bi-x"></i></button>
</div>
</div>
</th:block>
</div>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<button type="button" class="btn btn-sm btn-outline-primary" id="monitoringInfoAddBtn"><i class="bi bi-plus-lg"></i></button>
</div>
</div>
</div>
</div>
<hr>
<div class="row mb-3">
<label for="fileInputer" class="col-sm-1 col-form-label col-form-label-sm text-center">증빙자료</label>
<div class="col-sm-11" style="min-height: 70px;">
@ -156,7 +336,10 @@
</div>
<input type="file" class="d-none" id="fileInputer" multiple>
</div>
</div>
</div>
</form>
<div class="d-none" id="infoFmOrigin">
<div class="row my-1 infoRow" id="infoFm">
<div class="col-2">
@ -176,6 +359,59 @@
</div>
</div>
</div>
<div class="d-none" id="clearIinfoFmOrigin">
<div class="row my-1 clearInfoRow" id="clearInfoFm">
<div class="col-3">
<select class="form-select form-select-sm useCatg">
<option value="">선택</option>
<th:block th:each="category:${categoryList}">
<option th:value="${category.itemCd}" th:text="${category.itemValue}"></option>
</th:block>
</select>
</div>
<div class="col-3">
<select class="form-select form-select-sm useDetail">
<option value="">선택</option>
<th:block th:each="code:${codeList}">
<option th:value="${code.itemCd}" th:text="${code.itemValue}"></option>
</th:block>
</select>
</div>
<div class="col-5">
<div class="row">
<div class="col-7 pe-0">
<input type="number" class="form-control form-control-sm price">
</div>
<label class="col-auto"></label>
<div class="col-auto">
<button type="button" class="btn btn-sm btn-outline-danger rowDeleteBtn2"><i class="bi bi-x"></i></button>
</div>
</div>
</div>
</div>
</div>
<div class="d-none" id="monitoringInfoFmOrigin">
<div class="row my-1 infoRow" id="monitoringnfoFm">
<div class="col-2">
<input type="text" class="form-control form-control-sm contactDate" placeholder="YYYY-MM-DD" readonly>
</div>
<div class="col-2">
<input type="text" class="form-control form-control-sm writeDate" placeholder="YYYY-MM-DD" readonly>
</div>
<div class="col-3">
<input type="text" class="form-control form-control-sm reportTitle">
</div>
<div class="col-3">
<input class="file" type="file">
</div>
<div class="col-1">
<button type="button" class="btn btn-sm btn-outline-danger rowDeleteBtn3"><i class="bi bi-x"></i></button>
</div>
</div>
</div>
</div>
<div class="modal-footer justify-content-between bg-light">
<div class="col-auto">