강석 최 2022-10-06 18:43:41 +09:00
commit ef44c1564a
14 changed files with 1086 additions and 2 deletions

View File

@ -4,6 +4,7 @@ package com.dbnt.faisp.fipTarget;
import com.dbnt.faisp.authMgt.service.AuthMgtService;
import com.dbnt.faisp.fipTarget.model.PartInfo;
import com.dbnt.faisp.fipTarget.model.PartInfoFile;
import com.dbnt.faisp.fipTarget.model.PartWork;
import com.dbnt.faisp.fipTarget.service.FipTargetService;
import com.dbnt.faisp.organMgt.service.OrganConfigService;
import com.dbnt.faisp.userInfo.model.UserInfo;
@ -78,7 +79,6 @@ public class FipTargetController {
//메뉴권한 확인
String accessAuth = authMgtService.selectAccessConfigList(loginUser.getUserSeq(), "/target/partInfoList").get(0).getAccessAuth();
mav.addObject("accessAuth", accessAuth);
partInfo.setDownOrganCdList(loginUser.getDownOrganCdList());
partInfo.setQueryInfo();
mav.addObject("total", fipTargetService.selectWorkTypeTotal(partInfo));
mav.addObject("partInfoList", fipTargetService.selectPartInfoList(partInfo));
@ -252,7 +252,76 @@ public class FipTargetController {
return "Firefox";
}
//외사분실 운영현황 끝
//외사분실실적 시작
@GetMapping("/partWorkList")
public ModelAndView partWorkList(@AuthenticationPrincipal UserInfo loginUser,PartWork partWork, HttpServletResponse response) {
ModelAndView mav = new ModelAndView("fipTarget/partWorkList");
partWork.setDownOrganCdList(loginUser.getDownOrganCdList());
//메뉴권한 확인
String accessAuth = authMgtService.selectAccessConfigList(loginUser.getUserSeq(), "/target/partWorkList").get(0).getAccessAuth();
mav.addObject("accessAuth", accessAuth);
partWork.setQueryInfo();
mav.addObject("partWorkList", fipTargetService.selectPartWorkList(partWork));
partWork.setContentCnt(fipTargetService.selectPartWorkListCnt(partWork));
partWork.setPaginationInfo();
mav.addObject("uesrId", loginUser.getUserId());
mav.addObject("searchParams", partWork);
return mav;
}
@GetMapping("/partWorkEditModal")
public ModelAndView partWorkEditModal(@AuthenticationPrincipal UserInfo loginUser,PartWork partWork) {
ModelAndView mav = new ModelAndView("fipTarget/partWorkEditModal");
partWork.setDownOrganCdList(loginUser.getDownOrganCdList());
//메뉴권한 확인
String accessAuth = authMgtService.selectAccessConfigList(loginUser.getUserSeq(), "/target/partWorkList").get(0).getAccessAuth();
mav.addObject("accessAuth", accessAuth);
mav.addObject("tnList", fipTargetService.selectTerminalName(partWork));
return mav;
}
@PostMapping("/savePartWork")
public void savePartWork (@AuthenticationPrincipal UserInfo loginUser, PartWork partWork,MultipartHttpServletRequest request){
partWork.setMultipartFileList(request.getMultiFileMap().get("uploadFiles"));
partWork.setWrtNm(loginUser.getUserId());
partWork.setWrtPart(loginUser.getOfcCd());
partWork.setWrtUserSeq(loginUser.getUserSeq());
partWork.setWrtOrgan(loginUser.getOgCd());
partWork.setWrtDt(LocalDateTime.now());
fipTargetService.savePartWork(partWork);
}
@GetMapping("/partWorkView")
public ModelAndView partWorkView(@AuthenticationPrincipal UserInfo loginUser,PartWork partWork) {
ModelAndView mav = new ModelAndView("fipTarget/partWorkModifyModal");
partWork.setDownOrganCdList(loginUser.getDownOrganCdList());
PartWork partWorkView = fipTargetService.selectPartWorkInfo(partWork);
partWorkView.setFileList(fipTargetService.selectPartWorkFile(partWork));
mav.addObject("pwInfo", partWorkView);
//메뉴권한 확인
String accessAuth = authMgtService.selectAccessConfigList(loginUser.getUserSeq(), "/target/partInfoList").get(0).getAccessAuth();
mav.addObject("accessAuth", accessAuth);
mav.addObject("userId", loginUser.getUserId());
return mav;
}
@PostMapping("/updatePartWork")
public PartWork updatePartWork (@AuthenticationPrincipal UserInfo loginUser, PartWork partWork,
MultipartHttpServletRequest request,
@RequestParam(value = "fileSeq", required = false) List < Integer > deleteFileSeq){
partWork.setMultipartFileList(request.getMultiFileMap().get("uploadFiles"));
partWork.setWrtNm(loginUser.getUserId());
partWork.setWrtPart(loginUser.getOfcCd());
partWork.setWrtUserSeq(loginUser.getUserSeq());
partWork.setWrtOrgan(loginUser.getOgCd());
partWork.setWrtDt(LocalDateTime.now());
fipTargetService.updatePartWork(partWork,deleteFileSeq);
return partWork;
}

View File

@ -2,6 +2,7 @@ package com.dbnt.faisp.fipTarget.mapper;
import com.dbnt.faisp.fipTarget.model.PartInfo;
import com.dbnt.faisp.fipTarget.model.PartInfoFile;
import com.dbnt.faisp.fipTarget.model.PartWork;
import com.dbnt.faisp.util.ParamMap;
import org.apache.ibatis.annotations.Mapper;
@ -31,6 +32,14 @@ public interface FipTargetMapper {
String selectPartInfoFirstId(Integer piSeq);
List<ParamMap> selectTerminalName(PartWork partWork);
List<PartWork> selectPartWorkList(PartWork partWork);
Integer selectPartWorkListCnt(PartWork partWork);
PartWork selectPartWorkInfo(PartWork partWork);

View File

@ -0,0 +1,132 @@
package com.dbnt.faisp.fipTarget.model;
import com.dbnt.faisp.config.BaseModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
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.Serializable;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@Getter
@Setter
@Entity
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@IdClass(PartWork.PartWorkId.class)
@Table(name = "part_work")
public class PartWork extends BaseModel implements Serializable{
@Id
@Column(name = "pw_seq")
private Integer pwSeq;
@Id
@Column(name = "pi_seq")
private Integer piSeq;
@Column(name = "work_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private LocalDate workDt;
@Column(name = "work_type")
private String workType;
@Column(name = "work_info")
private String workInfo;
@Column(name = "description")
private String description;
@Column(name = "save_yn")
private String saveYn;
@Column(name = "wrt_organ")
private String wrtOrgan;
@Column(name = "wrt_part")
private String wrtPart;
@Column(name = "wrt_user_seq")
private Integer wrtUserSeq;
@Column(name = "wrt_nm")
private String wrtNm;
@Column(name = "wrt_dt")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm")
private LocalDateTime wrtDt;
@Transient
private List<MultipartFile> multipartFileList;
@Transient
private String excel;
@Transient
private String terminalNm;
@Transient
private String workTypeCh;
@Transient
private String workTypePoci;
@Transient
private String workTypeSri;
@Transient
private String workTypeJi;
@Transient
private String workTypeMt;
@Transient
private String workTypeEtc;
@Transient
private Integer fileCnt;
@Transient
private List<PartWorkFile> fileList;
@Override
public String toString() {
return "PartWork [pwSeq=" + pwSeq + ", piSeq=" + piSeq + ", workDt=" + workDt + ", workType=" + workType
+ ", workInfo=" + workInfo + ", description=" + description + ", saveYn=" + saveYn + ", wrtOrgan="
+ wrtOrgan + ", wrtPart=" + wrtPart + ", wrtUserSeq=" + wrtUserSeq + ", wrtNm=" + wrtNm + ", wrtDt=" + wrtDt
+ ", multipartFileList=" + multipartFileList + ", excel=" + excel + ", fileList=" + fileList + "]";
}
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class PartWorkId implements Serializable {
private Integer pwSeq;
private Integer piSeq;
}
}

View File

@ -0,0 +1,95 @@
package com.dbnt.faisp.fipTarget.model;
import com.dbnt.faisp.config.BaseModel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
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;
import java.util.Date;
@Getter
@Setter
@Entity
@NoArgsConstructor
@DynamicInsert
@DynamicUpdate
@IdClass(PartWorkFile.PartWorkFileId.class)
@Table(name = "part_work_file")
public class PartWorkFile extends BaseModel implements Serializable{
@Id
@Column(name = "file_seq")
private Integer fileSeq;
@Id
@Column(name = "pw_seq")
private Integer pwSeq;
@Id
@Column(name = "pi_seq")
private Integer piSeq;
@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 = "file_path")
private String filePath;
@Override
public String toString() {
return "PartWorkFile [fileSeq=" + fileSeq + ", pwSeq=" + pwSeq + ", piSeq=" + piSeq + ", origNm=" + origNm
+ ", convNm=" + convNm + ", fileExtn=" + fileExtn + ", fileSize=" + fileSize + ", filePath=" + filePath
+ "]";
}
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class PartWorkFileId implements Serializable {
private Integer fileSeq;
private Integer pwSeq;
private Integer piSeq;
}
}

View File

@ -0,0 +1,34 @@
package com.dbnt.faisp.fipTarget.repository;
import com.dbnt.faisp.fipTarget.model.PartInfoFile;
import com.dbnt.faisp.fipTarget.model.PartWorkFile;
import com.dbnt.faisp.publicBoard.model.PublicFile;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PartWorkFileRepository extends JpaRepository<PartWorkFile, PartWorkFile.PartWorkFileId> {
PartWorkFile findTopByPwSeqAndPiSeqOrderByFileSeqDesc(Integer piSeq, Integer piSeq2);
List<PartWorkFile> findByPwSeqAndPiSeqOrderByFileSeqAsc(Integer pwSeq, Integer piSeq);
List<PartWorkFile> findByPwSeqAndPiSeq(Integer pwSeq, Integer piSeq);
}

View File

@ -0,0 +1,23 @@
package com.dbnt.faisp.fipTarget.repository;
import com.dbnt.faisp.fipTarget.model.PartWork;
import org.springframework.data.jpa.repository.JpaRepository;
public interface PartWorkRepository extends JpaRepository<PartWork, PartWork.PartWorkId> {
PartWork findTopByPiSeqOrderByPwSeqDesc(Integer piSeq);
}

View File

@ -11,8 +11,14 @@ import com.dbnt.faisp.fipTarget.model.PartInfo;
import com.dbnt.faisp.fipTarget.model.PartInfo.PartInfoId;
import com.dbnt.faisp.fipTarget.model.PartInfoFile;
import com.dbnt.faisp.fipTarget.model.PartInfoFile.PartInfoFileId;
import com.dbnt.faisp.fipTarget.model.PartWork;
import com.dbnt.faisp.fipTarget.model.PartWork.PartWorkId;
import com.dbnt.faisp.fipTarget.model.PartWorkFile;
import com.dbnt.faisp.fipTarget.model.PartWorkFile.PartWorkFileId;
import com.dbnt.faisp.fipTarget.repository.PartInfoFileRepository;
import com.dbnt.faisp.fipTarget.repository.PartInfoRepository;
import com.dbnt.faisp.fipTarget.repository.PartWorkFileRepository;
import com.dbnt.faisp.fipTarget.repository.PartWorkRepository;
import com.dbnt.faisp.publicBoard.model.PublicFile;
import com.dbnt.faisp.util.ParamMap;
@ -37,6 +43,8 @@ public class FipTargetService extends BaseService {
private final PartInfoRepository partInfoRepository;
private final PartInfoFileRepository partInfoFileRepository;
private final PartWorkRepository partWorkRepository;
private final PartWorkFileRepository partWorkFileRepository;
private final FipTargetMapper fipTargetMapper;
public List<ParamMap> selectPartInfoManagerList(ParamMap param) {
@ -206,6 +214,88 @@ public class FipTargetService extends BaseService {
public String selectPartInfoFirstId(PartInfo partInfo) {
return fipTargetMapper.selectPartInfoFirstId(partInfo.getPiSeq());
}
public List<ParamMap> selectTerminalName(PartWork partWork) {
return fipTargetMapper.selectTerminalName(partWork);
}
@Transactional
public void savePartWork(PartWork partWork) {
PartWork dbPart = partWorkRepository.findTopByPiSeqOrderByPwSeqDesc(partWork.getPiSeq());
if(dbPart == null) {
partWork.setPwSeq(1);
partWorkRepository.save(partWork);
} else {
partWork.setPwSeq(dbPart.getPwSeq()+1);
partWorkRepository.save(partWork);
}
if(partWork.getMultipartFileList()!= null){
saveFilesUpload(partWork.getPwSeq(),partWork.getPiSeq(), partWork.getMultipartFileList());
}
}
private void saveFilesUpload(Integer pwSeq,Integer piSeq, List<MultipartFile> multipartFileList) {
PartWorkFile lastFileInfo = partWorkFileRepository.findTopByPwSeqAndPiSeqOrderByFileSeqDesc(pwSeq,piSeq);
int fileSeq = lastFileInfo==null?1:(lastFileInfo.getFileSeq()+1);
for(MultipartFile file : multipartFileList){
String saveName = UUID.randomUUID().toString();
String path = locationPath+File.separator+"publicFile"+File.separator;
saveFile(file, new File(path+File.separator+saveName));
String originalFilename = file.getOriginalFilename();
int extnIdx = originalFilename.lastIndexOf(".");
PartWorkFile fileInfo = new PartWorkFile();
fileInfo.setFileSeq(fileSeq++);
fileInfo.setPwSeq(pwSeq);
fileInfo.setPiSeq(piSeq);
fileInfo.setOrigNm(originalFilename.substring(0, extnIdx));
fileInfo.setFileExtn(originalFilename.substring(extnIdx+1));
fileInfo.setConvNm(saveName);
fileInfo.setFileSize(calculationSize(file.getSize()));
fileInfo.setFilePath(path);
partWorkFileRepository.save(fileInfo);
}
}
public List<PartWork> selectPartWorkList(PartWork partWork) {
return fipTargetMapper.selectPartWorkList(partWork);
}
public Integer selectPartWorkListCnt(PartWork partWork) {
return fipTargetMapper.selectPartWorkListCnt(partWork);
}
public PartWork selectPartWorkInfo(PartWork partWork) {
return fipTargetMapper.selectPartWorkInfo(partWork);
}
public List<PartWorkFile> selectPartWorkFile(PartWork partWork) {
return partWorkFileRepository.findByPwSeqAndPiSeqOrderByFileSeqAsc(partWork.getPwSeq(),partWork.getPiSeq());
}
@Transactional
public void updatePartWork(PartWork partWork, List<Integer> deleteFileSeq) {
partWorkRepository.save(partWork);
if(deleteFileSeq!=null && deleteFileSeq.size()>0){
deletePartWorkFile(partWork, deleteFileSeq);
}
if(partWork.getMultipartFileList()!= null){
saveFilesUpload(partWork.getPwSeq(),partWork.getPiSeq(), partWork.getMultipartFileList());
}
}
private void deletePartWorkFile(PartWork partWork, List<Integer> deleteFileSeq) {
List<PartWorkFile> partWorkFileList = partWorkFileRepository.findByPwSeqAndPiSeq(partWork.getPwSeq(),partWork.getPiSeq());
for(PartWorkFile file: partWorkFileList ){
if(deleteFileSeq.contains(file.getFileSeq())){
deleteStoredFile(new File(file.getFilePath(), file.getConvNm()));
partWorkFileRepository.delete(file);
}
}
}

View File

@ -319,5 +319,132 @@
order by version_no asc
limit 1
</select>
<select id="selectTerminalName" resultType="com.dbnt.faisp.util.ParamMap" parameterType="PartWork">
select pi.pi_seq,
terminal_nm
from part_info pi,
(select pi_seq,max(version_no) as lastVer
from part_info group by pi_seq) b
where pi.pi_seq = b.pi_seq
and pi.version_no = b.lastVer
and mgt_organ in
<foreach collection="downOrganCdList" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
order by terminal_nm asc
</select>
<select id="selectPartWorkList" resultType="PartWork" parameterType="PartWork">
select pw.pw_seq,
pw.pi_seq ,
pi.terminal_nm,
pw.wrt_nm,
pw.work_dt,
pw.save_yn,
work_type,
case
when pw.work_type = 'CH' then 'O'
end as work_type_ch,
case
when pw.work_type = 'POCI' then 'O'
end as work_type_poci,
case
when pw.work_type = 'SRI' then 'O'
end as work_type_sri,
case
when pw.work_type = 'JI' then 'O'
end as work_type_ji,
case
when pw.work_type = 'MT' then 'O'
end as work_type_mt,
case
when pw.work_type = 'ETC' then 'O'
end as work_type_etc,
pw.description,
(select count(*) from part_work_file pwf where pw.pw_seq = pwf.pw_seq and pw.pi_seq = pwf.pi_seq) as file_cnt,
pw.wrt_dt
from part_work pw,
part_info pi,
(select pi_seq,max(version_no) as lastVer
from part_info group by pi_seq) b
where pw.pi_seq = pi.pi_seq
and pi.pi_seq = b.pi_seq
and pi.version_no = b.lastVer
and pi.mgt_organ in
<foreach collection="downOrganCdList" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
order by wrt_dt desc
limit #{rowCnt} offset #{firstIndex}
</select>
<select id="selectPartWorkListCnt" resultType="int" parameterType="PartWork">
select count(*)
from(
select pw.pw_seq,
pw.pi_seq ,
pi.terminal_nm,
pw.wrt_nm,
pw.work_dt,
pw.save_yn,
work_type,
case
when pw.work_type = 'CH' then 'O'
end as work_type_ch,
case
when pw.work_type = 'POCI' then 'O'
end as work_type_poci,
case
when pw.work_type = 'SRI' then 'O'
end as work_type_sri,
case
when pw.work_type = 'JI' then 'O'
end as work_type_ji,
case
when pw.work_type = 'MT' then 'O'
end as work_type_mt,
case
when pw.work_type = 'ETC' then 'O'
end as work_type_etc,
pw.description,
(select count(*) from part_work_file pwf where pw.pw_seq = pwf.pw_seq and pw.pi_seq = pwf.pi_seq) as file_cnt,
pw.wrt_dt
from part_work pw,
part_info pi,
(select pi_seq,max(version_no) as lastVer
from part_info group by pi_seq) b
where pw.pi_seq = pi.pi_seq
and pi.pi_seq = b.pi_seq
and pi.version_no = b.lastVer
and pi.mgt_organ in
<foreach collection="downOrganCdList" item="item" index="index" separator="," open="(" close=")">
#{item}
</foreach>
order by wrt_dt desc
) a
</select>
<select id="selectPartWorkInfo" resultType="PartWork" parameterType="PartWork">
select pw.pw_seq,
pw.pi_seq ,
pi.terminal_nm,
pw.wrt_nm,
pw.work_dt,
pw.save_yn,
pw.work_info,
work_type,
pw.description,
pw.wrt_dt
from part_work pw,
part_info pi,
(select pi_seq,max(version_no) as lastVer
from part_info group by pi_seq) b
where pw.pi_seq = pi.pi_seq
and pi.pi_seq = b.pi_seq
and pi.version_no = b.lastVer
and pw.pw_seq = #{pwSeq}
and pw.pi_seq = #{piSeq}
</select>
</mapper>

View File

@ -0,0 +1,172 @@
let files = [];
$(document).on('click', '#addPartWork', function (){
$.ajax({
url: '/target/partWorkEditModal',
type: 'GET',
dataType:"html",
success: function(html){
$("#partWorkEditModalEditModalContent").empty().append(html);
$("#partWorkEditModal").modal('show');
setUploadDiv();
$("#workDt").datepicker({
format: "yyyy-mm-dd",
language: "ko"
});
$("#workInfo").summernote({
lang:'ko-KR',
height: 350,
disableDragAndDrop: true,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']]
]
});
},
error:function(){
}
});
})
$(document).on('click', '#saveBtn', function (){
if($('#piSeq').val() == ''){
alert('터미널명을 선택해주세요');
$('#piSeq').focus();
return false;
}
if($('input:radio[name="workType"]:checked').length < 1){
alert('종류를 선택해주세요');
return false;
}
if(confirm("저장하시겠습니까?")){
$('#saveYn').val('Y');
contentFade("in");
savePartWork();
}
})
$(document).on('click', '#temporarySaveBtn', function (){
if($('#piSeq').val() == ''){
alert('터미널명을 선택해주세요');
$('#piSeq').focus();
return false;
}
if($('input:radio[name="workType"]:checked').length < 1){
alert('종류를 선택해주세요');
return false;
}
if(confirm("임시 저장하시겠습니까?")){
$('#saveYn').val('N');
contentFade("in");
savePartWork();
}
})
function savePartWork(){
const formData = new FormData($("#partWorkSaveFm")[0]);
for(const file of files) {
if(!file.isDelete)
formData.append('uploadFiles', file, file.name);
}
$.ajax({
type : 'POST',
data : formData,
url : "/target/savePartWork",
processData: false,
contentType: false,
success : function(result) {
alert("저장되었습니다.");
contentFade("out");
location.reload();
},
error : function(xhr, status) {
alert("저장에 실패하였습니다.")
contentFade("out");
}
})
}
$(document).on('click', '.partWorkTr', function (){
const pwSeq = (Number($(this).find(".pwSeq").val()));
const piSeq = (Number($(this).find(".piSeq").val()));
showModal(pwSeq,piSeq);
})
function showModal(pwSeq,piSeq){
$.ajax({
url: '/target/partWorkView',
data: {
pwSeq: pwSeq,
piSeq: piSeq
},
type: 'GET',
dataType:"html",
success: function(html){
$("#partWorkEditModalEditModalContent").empty().append(html);
$("#partWorkEditModal").modal('show');
setUploadDiv();
$("#mWorkDt").datepicker({
format: "yyyy-mm-dd",
language: "ko"
});
$("#mWorkInfo").summernote({
lang:'ko-KR',
height: 350,
disableDragAndDrop: true,
toolbar: [
['style', ['style']],
['font', ['bold', 'underline', 'clear']],
['color', ['color']],
['para', ['ul', 'ol', 'paragraph']],
['table', ['table']]
]
});
},
error:function(){
}
});
}
$(document).on('click', '#updateBtn', function (){
if(confirm("수정하시겠습니까?")){
contentFade("in");
const formData = new FormData($("#partWorkUpdateFm")[0]);
formData.append('saveYn','Y');
for(const file of files) {
if(!file.isDelete)
formData.append('uploadFiles', file, file.name);
}
$(".text-decoration-line-through").each(function (idx, el){
formData.append('fileSeq', $(el).attr("data-fileseq"));
})
$.ajax({
type : 'POST',
data : formData,
url : "/target/updatePartWork",
processData: false,
contentType: false,
success : function(data) {
alert("수정되었습니다.");
contentFade("out");
showModal(data.pwSeq,data.piSeq);
},
error : function(xhr, status) {
alert("수정에 실패하였습니다.")
contentFade("out");
}
})
}
})
$(document).on('click', '.btn-close', function (){
location.reload();
})
$(document).on('click', '#btn-close', function (){
location.reload();
})

View File

@ -208,7 +208,7 @@ function revisionHistory(trKey,verNo,url){
$("#viewAptDt").datepicker({
format: "yyyy-mm-dd",
language: "ko"
});
});
},
error:function(){

View File

@ -123,6 +123,7 @@
<th>근무방법</th>
<th></th>
<th>비고</th>
</tr>
</thead>
<tbody>
<tr class="partInfoTr" th:each="pi:${partInfoList}">

View File

@ -0,0 +1,84 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<div class="modal-header">
<h5 class="modal-title" id="menuEditModalLabel">외사분실 실적 등록</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body" id="noticeEditBody">
<form action="#" method="post" id="partWorkSaveFm">
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<input type="hidden" id="saveYn" name="saveYn">
<div class="mb-3 row">
<label for="wrtUserNm" class="col-sm-2 col-form-label text-center">터미널명</label>
<div class="col-sm-4">
<select class="form-select form-select-sm" id="piSeq" name="piSeq">
<option value="">선택</option>
<th:block th:each="terminal:${tnList}">
<option th:value="${terminal.pi_seq}" th:text="${terminal.terminal_nm}"></option>
</th:block>
</select>
</div>
<label for="wrtDt" class="col-sm-2 col-form-label text-center">일시</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="workDt" name="workDt" readonly>
</div>
</div>
<div class="mb-3 row">
<label for="title" class="col-sm-2 col-form-label text-center">작성자</label>
<div class="col-sm-4">
<input type="text" class="form-control" value="작성자 자동입력" readonly>
</div>
<label for="wrtDt" class="col-sm-2 col-form-label text-center">작성일</label>
<div class="col-sm-4">
<input type="text" class="form-control" value="자동입력" readonly>
</div>
</div>
<br>
<div class="mb-3 row justify-content-center">
<label class="col-sm-2 col-form-label text-center">종류</label>
<div class="col-sm-12">
<label for="workType" class="col-sm-2 col-form-label text-center">사건처리</label>
<input type="radio" name="workType" value="CH">
<label for="workType" class="col-sm-2 col-form-label text-center">범죄첩보제공</label>
<input type="radio" name="workType" value="POCI">
<label for="workType" class="col-sm-1 col-form-label text-center">SRI</label>
<input type="radio" name="workType" value="SRI">
<label for="workType" class="col-sm-2 col-form-label text-center">합동점검</label>
<input type="radio" name="workType" value="JI">
<label for="workType" class="col-sm-1 col-form-label text-center">회의</label>
<input type="radio" name="workType" value="MT">
<label for="workType" class="col-sm-1 col-form-label text-center">기타</label>
<input type="radio" name="workType" value="ETC">
</div>
</div>
<div class="mb-3 row justify-content-center">
<label for="workInfo" class="col-sm-2 col-form-label text-center">내용</label>
<div class="col-sm-10">
<textarea id="workInfo" name='workInfo' ></textarea>
</div>
</div>
<div class="mb-3 row">
<label for="title" class="col-sm-2 col-form-label text-center">비고</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="description" name="description">
</div>
</div>
<div class="row mb-3">
<label for="fileInputer" class="col-sm-2 col-form-label text-center">업로드 자료</label>
<div class="col-sm-10" style="min-height: 70px;">
<div class="w-100 h-100 border border-info rounded text-center" id="uploadDiv">
<br>파일을 업로드 해주세요.
</div>
</div>
<input type="file" class="d-none" id="fileInputer" multiple>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="saveBtn">저장</button>
<button type="button" class="btn btn-primary" id="temporarySaveBtn">임시저장</button>
</div>
</html>

View File

@ -0,0 +1,159 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{layout/layout}">
<th:block layout:fragment="script">
<script type="text/javascript" th:src="@{/js/fipTarget/partWork.js}"></script>
</th:block>
<div layout:fragment="content">
<main class="pt-3">
<h4>외사 분실 현황</h4>
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<div class="row mx-0">
<div class="col-12 card text-center">
<div class="card-body">
<form id="searchFm" method="get" th:action="@{/target/partInfoList}">
<input type="hidden" name="excel">
<input type="hidden" name="pageIndex" id="pageIndex" th:value="${searchParams.pageIndex}">
<div class="row justify-content-between pe-3 py-1">
<div class="col-auto">
<select class="form-select" name="rowCnt" id="rowCnt">
<th:block th:each="num : ${#numbers.sequence(1,5)}">
<option th:value="${num*10}" th:text="${num*10}" th:selected="${searchParams.rowCnt==num*10}"></option>
</th:block>
</select>
</div>
</div>
</form>
<div class="row justify-content-start">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row">
<input type="hidden" id="selectedKey">
<input type="hidden" id="selectedVerNo">
<table class="table table-striped">
<thead>
<tr>
<th rowspan="2">외사<br>터미널명</th>
<th rowspan="2">작성자</th>
<th rowspan="2">일시</th>
<th colspan="6">종류</th>
<th rowspan="2">비고</th>
<th rowspan="2">첨부파일</th>
<th rowspan="2">최근수정일</th>
</tr>
<tr>
<th>사건처리</th>
<th>범죄첩보제공</th>
<th>SRI</th>
<th>합동점검</th>
<th>회의</th>
<th>기타</th>
</tr>
</thead>
<tbody>
<tr class="partWorkTr" th:each="pw:${partWorkList}">
<th:block th:if="${pw.saveYn eq 'N'} and ${pw.wrtNm eq uesrId}">
<th:block>
<input type="hidden" class="pwSeq" th:value="${pw.pwSeq}">
<input type="hidden" class="piSeq" th:value="${pw.piSeq}">
</th:block>
<td th:text="|[임시]${pw.terminalNm}|"></td>
<td th:text="${pw.wrtNm}"></td>
<td th:text="${pw.workDt}"></td>
<td th:text="${pw.workTypeCh}"></td>
<td th:text="${pw.workTypePoci}"></td>
<td th:text="${pw.workTypeSri}"></td>
<td th:text="${pw.workTypeJi}"></td>
<td th:text="${pw.workTypeMt}"></td>
<td th:text="${pw.workTypeEtc}"></td>
<td th:text="${pw.description}"></td>
<td th:if="${pw.fileCnt > 0}"></td>
<td th:unless="${pw.fileCnt > 0}"></td>
<td th:text="${#temporals.format(pw.wrtDt, 'yyyy-MM-dd HH:mm')}"></td>
</th:block>
<th:block th:unless="${pw.saveYn eq 'N'} and ${pw.wrtNm eq uesrId}">
<th:block th:if="${pw.saveYn eq 'Y'}">
<th:block>
<input type="hidden" class="pwSeq" th:value="${pw.pwSeq}">
<input type="hidden" class="piSeq" th:value="${pw.piSeq}">
</th:block>
<td th:text="${pw.terminalNm}"></td>
<td th:text="${pw.wrtNm}"></td>
<td th:text="${pw.workDt}"></td>
<td th:text="${pw.workTypeCh}"></td>
<td th:text="${pw.workTypePoci}"></td>
<td th:text="${pw.workTypeSri}"></td>
<td th:text="${pw.workTypeJi}"></td>
<td th:text="${pw.workTypeMt}"></td>
<td th:text="${pw.workTypeEtc}"></td>
<td th:text="${pw.description}"></td>
<td th:if="${pw.fileCnt > 0}"></td>
<td th:unless="${pw.fileCnt > 0}"></td>
<td th:text="${#temporals.format(pw.wrtDt, 'yyyy-MM-dd HH:mm')}"></td>
</th:block>
</th:block>
</tr>
</tbody>
</table>
</div>
<div class="row justify-content-center">
<div class="col-auto">
<nav aria-label="Page navigation">
<ul class="pagination">
<th:block th:if="${searchParams.pageIndex>3}">
<li class="page-item" th:data-pageindex="${(searchParams.pageIndex)-3}">
<a class="page-link" href="#" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
</li>
</th:block>
<th:block th:each="num : ${#numbers.sequence(searchParams.startNum, searchParams.endNum)}">
<li class="page-item" th:data-pageindex="${num}" th:classappend="${searchParams.pageIndex==num?'active':''}">
<a class="page-link" href="#" th:text="${num}"></a>
</li>
</th:block>
<th:block th:if="${searchParams.maxNum>searchParams.endNum+2}">
<li class="page-item" th:data-pageindex="${(searchParams.pageIndex)+3}">
<a class="page-link" href="#" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
</li>
</th:block>
</ul>
</nav>
<div class="col-auto">
<input type="button" class="btn btn-success" value="등록" id="addPartWork">
<button id="goExcel">엑셀다운</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<div class="modal fade" id="partWorkEditModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="userEditModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg modal-dialog-scrollable">
<div class="modal-content" id="partWorkEditModalEditModalContent">
<div class="modal-header">
</div>
<div class="modal-body">
<div class="tab-content border border-top-0" id="configInfo">
</div>
</div>
</div>
</div>
</div>
</div>
</html>

View File

@ -0,0 +1,89 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<div class="modal-header">
<h5 class="modal-title" id="menuEditModalLabel">외사분실 실적 상세</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<form action="#" method="post" id="partWorkUpdateFm">
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<input type="hidden" name="pwSeq" th:value="${pwInfo.pwSeq}">
<input type="hidden" name="piSeq" th:value="${pwInfo.piSeq}">
<div class="mb-3 row">
<label for="wrtUserNm" class="col-sm-2 col-form-label text-center">터미널명</label>
<div class="col-sm-4">
<input type="hidden" class="form-control" th:value="${pwInfo.piSeq}" name="piSeq" readonly>
<input type="text" class="form-control" th:value="${pwInfo.terminalNm}" readonly>
</div>
<label for="wrtDt" class="col-sm-2 col-form-label text-center">일시</label>
<div class="col-sm-4">
<input type="text" class="form-control" id="mWorkDt" name="workDt" th:value="${pwInfo.workDt}" readonly>
</div>
</div>
<div class="mb-3 row">
<label for="title" class="col-sm-2 col-form-label text-center">작성자</label>
<div class="col-sm-4">
<input type="text" class="form-control" th:value="${pwInfo.wrtNm}" readonly>
</div>
<label for="wrtDt" class="col-sm-2 col-form-label text-center">최종수정일</label>
<div class="col-sm-4">
<input type="text" class="form-control" th:value="${#temporals.format(pwInfo.wrtDt, 'yyyy-MM-dd HH:mm')}" readonly>
</div>
</div>
<br>
<div class="mb-3 row justify-content-center">
<label class="col-sm-2 col-form-label text-center">종류</label>
<div class="col-sm-12">
<label for="workType" class="col-sm-2 col-form-label text-center">사건처리</label>
<input type="radio" name="workType" value="CH" th:checked="${pwInfo.workType eq 'CH'}">
<label for="workType" class="col-sm-2 col-form-label text-center">범죄첩보제공</label>
<input type="radio" name="workType" value="POCI" th:checked="${pwInfo.workType eq 'POCI'}">
<label for="workType" class="col-sm-1 col-form-label text-center">SRI</label>
<input type="radio" name="workType" value="SRI" th:checked="${pwInfo.workType eq 'SRI'}">
<label for="workType" class="col-sm-2 col-form-label text-center">합동점검</label>
<input type="radio" name="workType" value="JI" th:checked="${pwInfo.workType eq 'JI'}">
<label for="workType" class="col-sm-1 col-form-label text-center">회의</label>
<input type="radio" name="workType" value="MT" th:checked="${pwInfo.workType eq 'MT'}">
<label for="workType" class="col-sm-1 col-form-label text-center">기타</label>
<input type="radio" name="workType" value="ETC" th:checked="${pwInfo.workType eq 'ETC'}">
</div>
</div>
<div class="mb-3 row justify-content-center">
<label for="workInfo" class="col-sm-2 col-form-label text-center">내용</label>
<div class="col-sm-10">
<textarea id="mWorkInfo" name='workInfo' th:utext="${pwInfo.workInfo}"></textarea>
</div>
</div>
<div class="mb-3 row">
<label for="title" class="col-sm-2 col-form-label text-center">비고</label>
<div class="col-sm-10">
<input type="text" class="form-control" id="mDescription" name="description" th:value="${pwInfo.description}">
</div>
</div>
<div class="row mb-3">
<label for="fileInputer" class="col-sm-2 col-form-label text-center">업로드 자료</label>
<div class="col-sm-10" style="min-height: 70px;">
<div class="w-100 h-100 border border-info rounded text-center" id="uploadDiv">
<th:block th:if="${#arrays.isEmpty(pwInfo.fileList)}">
<br>파일을 업로드 해주세요.
</th:block>
<th:block th:unless="${#arrays.isEmpty(pwInfo.fileList)}">
<div class='row-col-6' th:each="infoFile:${pwInfo.fileList}">
<span th:data-fileseq="${infoFile.fileSeq}" th:text="|${infoFile.origNm}.${infoFile.fileExtn} ${infoFile.fileSize}|"></span>
<a href='#' class='fileDownPartInfo text-decoration-none' th:data-fileSeq="${infoFile.fileSeq}" th:data-pwSeq="${infoFile.pwSeq}" th:data-piSeq="${infoFile.piSeq}">다운</a>
<a href='#' class='uploadedFileDelete text-danger text-decoration-none'>삭제</a>
</div>
</th:block>
</div>
</div>
<input type="file" class="d-none" id="fileInputer" multiple>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" id="btn-close" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="updateBtn">수정</button>
</div>
</html>