강석 최 2022-09-20 15:05:19 +09:00
commit 0d676856c8
13 changed files with 725 additions and 0 deletions

View File

@ -0,0 +1,81 @@
package com.dbnt.faisp.equip;
import com.dbnt.faisp.authMgt.service.AuthMgtService;
import com.dbnt.faisp.equip.model.Equip;
import com.dbnt.faisp.equip.service.EquipService;
import com.dbnt.faisp.organMgt.service.OrganConfigService;
import com.dbnt.faisp.translator.model.Translator;
import com.dbnt.faisp.translator.model.TranslatorCrr;
import com.dbnt.faisp.translator.service.TranslatorService;
import com.dbnt.faisp.userInfo.model.UserInfo;
import com.dbnt.faisp.util.ParamMap;
import com.dbnt.faisp.util.Utils;
import lombok.RequiredArgsConstructor;
import java.io.IOException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.servlet.ModelAndView;
@RestController
@RequiredArgsConstructor
@RequestMapping("/equip")
public class EquipController {
private final AuthMgtService authMgtService;
private final TranslatorService translatorSevice;
private final OrganConfigService organConfigService;
private final EquipService equipService;
@GetMapping("/equipStatus")
public ModelAndView equipStatus() {
ModelAndView mav = new ModelAndView("equip/equipStatus");
return mav;
}
@GetMapping("/equipEditModal")
public ModelAndView equipEditModal() {
ModelAndView mav = new ModelAndView("equip/equipEditModal");
return mav;
}
@GetMapping("/equipTypeSelecBox")
public ModelAndView equipTypeSelecBox(String equType) {
System.out.println("@@"+equType);
ModelAndView mav = new ModelAndView("equip/equipTypeSelecBox");
mav.addObject("equType", equType);
return mav;
}
@PostMapping("/saveEquip")
public void saveEquip(@AuthenticationPrincipal UserInfo loginUser,Equip equip, MultipartHttpServletRequest request){
equip.setWrtNm(loginUser.getUserId());
equip.setMgtOrgan(loginUser.getOgCd());
equip.setWrtOrgan(loginUser.getOgCd());
equip.setWrtDt(LocalDateTime.now());
equipService.saveEquip(equip,request);
}
}

View File

@ -0,0 +1,17 @@
package com.dbnt.faisp.equip.mapper;
import com.dbnt.faisp.translator.model.Translator;
import com.dbnt.faisp.translator.model.TranslatorCrr;
import com.dbnt.faisp.userInfo.model.UserInfo;
import com.dbnt.faisp.util.ParamMap;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface EquipMapper {
}

View File

@ -0,0 +1,86 @@
package com.dbnt.faisp.equip.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(Equip.EquipId.class)
@Table(name = "equ_mgt")
public class Equip extends BaseModel implements Serializable{
@Id
@Column(name = "equ_key")
private Integer equKey;
@Id
@Column(name = "version_no")
private Integer versionNo;
@Column(name = "mgt_organ")
private String mgtOrgan;
@Column(name = "equ_type")
private String equType;
@Column(name = "detail_type")
private String detailType;
@Column(name = "stored_year")
private String storedYear;
@Column(name = "mgt_type")
private String mgtType;
@Column(name = "item_qty")
private Integer itemQty;
@Column(name = "item_condition")
private String itemCondition;
@Column(name = "note")
private String note;
@Column(name = "wrt_organ")
private String wrtOrgan;
@Column(name = "wrt_nm")
private String wrtNm;
@Column(name = "wrt_dt")
private LocalDateTime wrtDt;
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class EquipId implements Serializable {
private Integer equKey;
private Integer versionNo;
}
@Override
public String toString() {
return "Equip [equKey=" + equKey + ", versionNo=" + versionNo + ", mgtOrgan=" + mgtOrgan + ", equType=" + equType
+ ", detailType=" + detailType + ", storedYear=" + storedYear + ", mgtType=" + mgtType + ", itemQty="
+ itemQty + ", itemCondition=" + itemCondition + ", note=" + note + ", wrtOrgan=" + wrtOrgan + ", wrtNm="
+ wrtNm + ", wrtDt=" + wrtDt + "]";
}
}

View File

@ -0,0 +1,80 @@
package com.dbnt.faisp.equip.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(EquipFile.EquipFileId.class)
@Table(name = "equ_file")
public class EquipFile extends BaseModel implements Serializable{
@Id
@Column(name = "file_seq")
private Integer fileSeq;
@Id
@Column(name = "equ_key")
private Integer equKey;
@Id
@Column(name = "version_no")
private Integer versionNo;
@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;
@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class EquipFileId implements Serializable {
private Integer fileSeq;
private Integer equKey;
private Integer versionNo;
}
@Override
public String toString() {
return "EquipFile [fileSeq=" + fileSeq + ", equKey=" + equKey + ", versionNo=" + versionNo + ", origNm=" + origNm
+ ", convNm=" + convNm + ", fileExtn=" + fileExtn + ", fileSize=" + fileSize + ", filePath=" + filePath
+ "]";
}
}

View File

@ -0,0 +1,14 @@
package com.dbnt.faisp.equip.repository;
import com.dbnt.faisp.equip.model.EquipFile;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EquipFileRepository extends JpaRepository<EquipFile, EquipFile.EquipFileId> {
}

View File

@ -0,0 +1,15 @@
package com.dbnt.faisp.equip.repository;
import com.dbnt.faisp.equip.model.Equip;
import org.springframework.data.jpa.repository.JpaRepository;
public interface EquipRepository extends JpaRepository<Equip, Equip.EquipId> {
Equip findFirstByOrderByEquKeyDesc();
}

View File

@ -0,0 +1,118 @@
package com.dbnt.faisp.equip.service;
import com.dbnt.faisp.equip.mapper.EquipMapper;
import com.dbnt.faisp.equip.model.Equip;
import com.dbnt.faisp.equip.model.EquipFile;
import com.dbnt.faisp.equip.repository.EquipFileRepository;
import com.dbnt.faisp.equip.repository.EquipRepository;
import com.dbnt.faisp.translator.mapper.TranslatorMapper;
import com.dbnt.faisp.translator.model.Translator;
import com.dbnt.faisp.translator.model.Translator.TranslatorId;
import com.dbnt.faisp.translator.model.TranslatorCrr;
import com.dbnt.faisp.translator.repository.TranslatorCareerRepository;
import com.dbnt.faisp.translator.repository.TranslatorRepository;
import com.dbnt.faisp.util.ParamMap;
import com.dbnt.faisp.util.Utils;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.core.env.Environment;
import java.io.File;
import java.time.LocalDateTime;
import java.util.*;
@Service
@RequiredArgsConstructor
public class EquipService {
@Value("${spring.servlet.multipart.location}")
protected String locationPath;
private final EquipRepository equipRepository;
private final EquipFileRepository equipFileRepository;
private final EquipMapper equipMapper;
@Transactional
public void saveEquip(Equip equip, MultipartHttpServletRequest request) {
Equip dbEquip = equipRepository.findFirstByOrderByEquKeyDesc();
try {
if(dbEquip == null) {
equip.setEquKey(1);
equip.setVersionNo(1);
equipRepository.save(equip);
} else {
equip.setEquKey(dbEquip.getEquKey()+1);
equip.setVersionNo(1);
equipRepository.save(equip);
}
saveFile(equip,request);
} catch (Exception e) {
e.printStackTrace();
}
}
public void saveFile(Equip equip, MultipartHttpServletRequest mRequest) throws Exception {
try {
String path = locationPath;
String FileSize;
File dir = new File(path);
if(!dir.exists()) dir.mkdir();
List<MultipartFile> mFiles = mRequest.getFiles("file");
for(int i = 0; i < mFiles.size(); i++) {
MultipartFile mFile = mFiles.get(i);
FileSize = calculationSize(mFile.getSize());
if(!"".equals(mFile.getOriginalFilename())){
String fileName = mFile.getOriginalFilename();
if(fileName.contains("\\")){
String notSecuredFileName = fileName.substring(fileName.lastIndexOf("\\") +1);
fileName = ("".equals(notSecuredFileName) || null == notSecuredFileName) ? fileName : notSecuredFileName;
};
String fileExt = Utils.getFileExtention(fileName);
String saveName = Utils.generationSaveName() + "." + fileExt;
FileCopyUtils.copy(mFile.getBytes(), new File(path, saveName));
EquipFile equipFile = new EquipFile();
equipFile.setFileSeq(1);
equipFile.setEquKey(equip.getEquKey());
equipFile.setVersionNo(equip.getVersionNo());
equipFile.setOrigNm(fileName);
equipFile.setConvNm(saveName);
equipFile.setFileExtn(fileExt);
equipFile.setFilePath(path);
equipFile.setFileSize(FileSize);
System.out.println(equipFile);
equipFileRepository.save(equipFile);
}
}
} catch (Exception e) {
throw e;
}
}
private String calculationSize(double fileSize){
String[] units = {"bytes", "KB", "MB", "GB", "TB", "PB"};
double unitSelector = Math.floor(Math.log(fileSize)/Math.log(1024));
if(fileSize>0){
return Math.round((fileSize/Math.pow(1024, unitSelector))*100)/100d+" "+units[(int)unitSelector];
}else{
return "";
}
}
}

View File

@ -113,6 +113,21 @@ public class Utils {
}
}
public static String getFileExtention(final String filename) {
if(null == filename || "".equals(filename)) return "";
return -1 < filename.lastIndexOf(".") ? filename.substring(filename.lastIndexOf(".") + 1).toLowerCase() : "";
}
public static String generationSaveName() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Utils.getTimeStampString("yyyyMMdd_HHmmss_SSS");
}
public static void listToExcel(List<ParamMap> list, HttpServletResponse response, String[] headers, String[] headerNames, String[] columnType, String sheetName, String excelFileName) throws IOException {
if(Utils.isNotEmpty(list)) {
// 메모리에 100개의 행을 유지합니다. 행의 수가 넘으면 디스크에 적습니다.

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dbnt.faisp.equip.mapper.EquipMapper">
</mapper>

View File

@ -0,0 +1,60 @@
$(document).on('click', '#addEquip', function (){
$.ajax({
url: '/equip/equipEditModal',
type: 'GET',
dataType:"html",
success: function(html){
$("#equipEditModalContent").empty().append(html)
$("#equipEditModal").modal('show')
},
error:function(){
}
});
})
$(document).on('change', '#equType', function (){
const equType = $(this).val();
$.ajax({
url: '/equip/equipTypeSelecBox',
data: {
equType,
},
type: 'GET',
dataType:"html",
success: function(html){
console.log(html);
$("#detailType").empty().append(html)
},
error:function(){
}
});
$(document).on('click', '#saveEquip', function (){
if(confirm("저장하시겠습니까?")){
let ajaxUrl = "/equip/saveEquip";
const formData = new FormData($("#equipEditForm")[0]);
contentFade("in");
$.ajax({
type : 'POST',
data : formData,
url : ajaxUrl,
processData: false,
contentType: false,
success : function() {
alert("저장되었습니다.");
location.reload();
contentFade("out");
},
error : function(xhr, status) {
alert("저장에 실패하였습니다.")
contentFade("out");
}
})
}
})
});

View File

@ -0,0 +1,74 @@
<!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 id="equipEditForm" th:action="@{/equip/saveEquip}" method="post" enctype="multipart/form-data">
<input type="hidden" name="_csrf_header" th:value="${_csrf.headerName}"/>
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
<div class="row mb-3">
<label for="cat1Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">분류</label>
<div class="col-sm-6">
<select class="form-select form-select-sm" id="equType" name="equType">
<option value="">-분류 선택-</option>
<th:block th:each="commonCode:${session.commonCode.get('IT')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}"></option>
</th:block>
</select>
</div>
</div>
<div class="row mb-3">
<label for="cat2Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">세부분류</label>
<div class="col-sm-6">
<select class="form-select form-select-sm" id="detailType" name="detailType">
<option value="">-세부분류 선택-</option>
</select>
</div>
</div>
<div class="row mb-3">
<label for="cat3Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">취득연도</label>
<div class="col-sm-6">
<input type="text" name="storedYear">
</div>
</div>
<div class="row mb-3">
<label for="cat3Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">보유량</label>
<div class="col-sm-6">
<input type="number" name="itemQty" placeholder="수량 직접입력">
</div>
</div>
<div class="row mb-3">
<label for="cat2Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">상태</label>
<div class="col-sm-6">
<select class="form-select form-select-sm" name="item_condition">
<option value="">상태 선택</option>
<th:block th:each="commonCode:${session.commonCode.get('LGG')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}"></option>
</th:block>
</select>
</div>
</div>
<div class="row mb-3">
<label for="cat3Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">비고</label>
<div class="col-sm-6">
<input type="text" name="note">
</div>
</div>
<div class="row mb-3">
<label for="cat3Cd" class="col-sm-4 col-form-label col-form-label-sm text-center">장비사진</label>
<div class="col-sm-6">
<input type="file" name="file">
</div>
</div>
</form>
</div>
<div class="modal-footer justify-content-between">
<div class="col-auto">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="saveEquip">저장</button>
</div>
</div>
</html>

View File

@ -0,0 +1,149 @@
<!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/equip/equip.js}"></script>
</th:block>
<div layout:fragment="content">
<main class="pt-3">
<h4>외사장비 현황</h4>
<ul class="nav nav-tabs" id="boardTab" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active" id="contentTab" data-bs-toggle="tab" data-bs-target="#contentDiv" type="button" role="tab">장비현황</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link" id="logTab" data-bs-toggle="tab" data-bs-target="#logDiv" type="button" role="tab">수정이력</button>
</li>
</ul>
<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 method="get" th:action="@{/userMgt/userMgtPage}">
<input type="hidden" name="userStatus" id="userStatus" >
<div class="row justify-content-between pe-3 py-1">
<div class="col-auto">
<div class="row justify-content-end">
<div class="col-auto">
<select class="form-select form-select-sm" name="ogCd">
<option value="">관서 선택</option>
<th:block th:each="commonCode:${session.commonCode.get('OG')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}"></option>
</th:block>
</select>
</div>
<div class="col-auto">
<select class="form-select form-select-sm" name="ofcCd">
<option value="">부서 선택</option>
<th:block th:each="commonCode:${session.commonCode.get('OFC')}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}"></option>
</th:block>
</select>
</div>
<div class="col-auto">
<input type="text" class="form-control form-control-sm" name="userNm" placeholder="사용자명">
</div>
<div class="col-auto">
<input type="text" class="form-control form-control-sm" name="userId" placeholder="사용자 아이디">
</div>
<input type="submit" class="btn btn-sm btn-primary col-auto" id="searchBtn" value="검색">
</div>
</div>
</div>
</form>
<div class="row justify-content-start">
<div class="col-12">
<div class="card">
<div class="card-body">
<div class="row">
<table class="table table-striped">
<thead>
<tr>
<th colspan="5"></th>
<th colspan="5">중부</th>
<th colspan="7">서해</th>
<th colspan="6">남해</th>
<th colspan="5">동해</th>
<th colspan="3">제주</th>
</tr>
<tr>
<th>연번</th>
<th>분류</th>
<th>세부분류</th>
<th>총계</th>
<th>본청</th>
<th colspan="25"></th>
</tr>
<tr>
<th colspan="5"></th>
<th></th>
<th>인천서</th>
<th>평택서</th>
<th>태안서</th>
<th>보령서</th>
<th></th>
<th>목포서</th>
<th>부안서</th>
<th>군산서</th>
<th>여수</th>
<th>완도서</th>
<th></th>
<th>울산서</th>
<th>부산서</th>
<th>창원서</th>
<th>통영서</th>
<th>사천서</th>
<th></th>
<th>속초서</th>
<th>동해서</th>
<th>울진서</th>
<th>포항서</th>
<th></th>
<th>제주서</th>
<th>서귀포서</th>
</tr>
</thead>
<tbody>
<tr class="">
</tr>
</tbody>
</table>
</div>
<div class="col-auto">
<input type="button" class="btn btn-success" value="등록" id="addEquip">
</div>
<div class="row justify-content-center">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</main>
<div class="modal fade" id="equipEditModal" 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="equipEditModalContent">
<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">
<div class="tab-content border border-top-0" id="configInfo">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn" id="deleteBtn" style='background-color : red;float:left;'>삭제</button>
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">닫기</button>
<button type="button" class="btn btn-primary" id="updateBtn">저장</button>
</div>
</div>
</div>
</div>
</div>
</html>

View File

@ -0,0 +1,7 @@
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<option value="">-세부분류 선택-</option>
<th:block th:each="commonCode:${session.commonCode.get(equType)}">
<option th:value="${commonCode.itemCd}" th:text="${commonCode.itemValue}"></option>
</th:block>
</html>