전송모듈 수정 및 출근_test 진행중

This commit is contained in:
hehihoho3@gmail.com 2024-11-05 10:11:49 +09:00
parent aacbcaa6e9
commit 3c94a2ff8c
29 changed files with 648 additions and 265 deletions

View File

@ -171,6 +171,11 @@
<artifactId>HikariCP</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
<build>

View File

@ -23,7 +23,7 @@ public abstract class AbstractAgentService<T, M> implements AgentService<T> {
for (int i = 0; i < sendCnt; i++) {
T paramVO = createCopy(agentVO, i);
T paramVO = createCopy(agentVO, i, sendCnt);
agentVOL.add(paramVO);
}
@ -73,7 +73,7 @@ public abstract class AbstractAgentService<T, M> implements AgentService<T> {
protected abstract int countByCondition(T agentVO);
protected abstract int parseSendCount(T agentVO);
protected abstract T createCopy(T originalVO, int index);
protected abstract T createCopy(T originalVO, int index, int sendCnt);
protected abstract void insertBatch(List<T> batchList);
private void logBatchProgress(int i, int totalBatches) {

View File

@ -7,9 +7,11 @@ import com.itn.admin.agent.client.one.service.AgentCOneService;
import com.itn.admin.cmn.msg.RestResponse;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@ -52,26 +54,30 @@ public class AgentCOneServiceImpl extends AbstractAgentService<AgentCOneVO, Agen
@Override
protected int parseSendCount(AgentCOneVO agentVO) {
try {
return (agentVO.getSendCnt() != null && !agentVO.getSendCnt().isEmpty()) ? Integer.parseInt(agentVO.getSendCnt()) : 0;
return StringUtils.isNotEmpty(agentVO.getSendCnt()) ? Integer.parseInt(agentVO.getSendCnt()) : 0;
} catch (NumberFormatException e) {
return 0;
}
}
@Override
protected AgentCOneVO createCopy(AgentCOneVO originalVO, int index) {
protected AgentCOneVO createCopy(AgentCOneVO originalVO, int index, int sendCnt) {
if (!originalVO.getMessage().startsWith("ITN")) {
return originalVO;
}
// if (!originalVO.getMessage().startsWith("ITN")) {
// return originalVO;
// }
AgentCOneVO paramVO = new AgentCOneVO();
String msgType = originalVO.getMsgType();
paramVO.setMsgType(msgType);
paramVO.setSendStatus(originalVO.getSendStatus());
paramVO.setRecvPhone(modifyPhoneNumber(originalVO.getRecvPhone(), index));
paramVO.setSendPhone(modifyPhoneNumber(originalVO.getSendPhone(), index));
if(sendCnt < 2){
paramVO.setRecvPhone(originalVO.getRecvPhone());
}else{
paramVO.setRecvPhone(modifyPhoneNumber(originalVO.getRecvPhone(), index));
}
paramVO.setSendPhone(originalVO.getSendPhone());
paramVO.setFileName01(originalVO.getFileName01());
paramVO.setFileName02(originalVO.getFileName02());
@ -93,16 +99,28 @@ public class AgentCOneServiceImpl extends AbstractAgentService<AgentCOneVO, Agen
private String modifyPhoneNumber(String phone, int index) {
// 휴대폰 번호는 010-XXXX-YYYY 형식으로 가정
String prefix = phone.substring(0, 4); // "010-" 부분
String middle = phone.substring(4, 8); // "XXXX" 부분
String suffix = phone.substring(8); // "YYYY" 부분
// 중간 부분 숫자 수정
int middleNumber = Integer.parseInt(middle);
middleNumber = (middleNumber + index) % 10000; // 0000~9999 사이의 값으로 제한
middle = String.format("%04d", middleNumber); // 자리 숫자로 포맷
return prefix + middle + suffix;
// String prefix = phone.substring(0, 4); // "010-" 부분
// String middle = phone.substring(4, 8); // "XXXX" 부분
// String suffix = phone.substring(8); // "YYYY" 부분
//
// // 중간 부분 숫자 수정
// int middleNumber = Integer.parseInt(middle);
// middleNumber = (middleNumber + index) % 10000; // 0000~9999 사이의 값으로 제한
// middle = String.format("%04d", middleNumber); // 자리 숫자로 포맷
//
// return prefix + middle + suffix;
// 인덱스를 번호 리스트 길이에 맞게 순환시키기 위해 모듈러 연산 사용
int adjustedIndex = index % PHONE_NUMBER_LIST.size();
return PHONE_NUMBER_LIST.get(adjustedIndex);
}
// 번호 목록을 리스트로 저장
private static final List<String> PHONE_NUMBER_LIST = Arrays.asList(
"01057559725", "01093414986", "01041101024",
"01057058729", "01030266269", "01063170383",
"01066137278", "01023221941", "01087872615",
"01083584250", "01071101861", "01073859908",
"01034910882", "01051842895", "01094597958"
);
}

View File

@ -2,9 +2,9 @@ package com.itn.admin.agent.client.one.web;
import com.itn.admin.agent.client.one.mapper.domain.AgentCOneVO;
import com.itn.admin.agent.client.one.service.AgentCOneService;
import com.itn.admin.agent.client.three.mapper.domain.AgentCThreeVO;
import com.itn.admin.cmn.msg.RestResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
@ -18,6 +18,7 @@ import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
@RestController
public class AgentCOneRestController {
@ -26,6 +27,8 @@ public class AgentCOneRestController {
private final String UPLOAD_DIR = "/home/mjon_client_agent_1/mmsfile";
@Value("${agent.file.dir.path}")
private String AGENT_FILE_PATH;
@Autowired
public void setAgentService(AgentCOneService agentCOneService) {
@ -132,16 +135,34 @@ public class AgentCOneRestController {
private String uploadSingleFile(MultipartFile file) throws IOException {
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
Path uploadPath = Paths.get(UPLOAD_DIR);
// 업로드된 파일의 이름을 가져옵니다.
String originalFileName = StringUtils.cleanPath(file.getOriginalFilename());
// 파일의 확장자를 추출합니다. 파일 이름에서 마지막 "." 이후 부분을 확장자로 간주합니다.
String fileExtension = "";
int dotIndex = originalFileName.lastIndexOf(".");
if (dotIndex > 0) {
fileExtension = originalFileName.substring(dotIndex);
}
// 고유한 파일명을 생성합니다.
String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
// 파일이 업로드될 경로를 설정합니다.
Path uploadPath = Paths.get(AGENT_FILE_PATH);
// 해당 경로가 존재하지 않으면 디렉터리를 생성합니다.
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
Path filePath = uploadPath.resolve(fileName);
// 파일을 저장할 최종 경로를 생성합니다.
Path filePath = uploadPath.resolve(uniqueFileName);
// 파일을 업로드 경로에 복사합니다. 이미 파일이 존재하면 대체합니다.
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
return fileName;
// 업로드된 고유한 파일명을 반환합니다.
return uniqueFileName;
}
}

View File

@ -7,9 +7,11 @@ import com.itn.admin.agent.client.two.mapper.AgentCTwoMapper;
import com.itn.admin.agent.client.two.service.AgentCTwoService;
import jakarta.annotation.PostConstruct;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@ -57,26 +59,31 @@ public class AgentCTwoServiceImpl extends AbstractAgentService<AgentCTwoVO, Agen
@Override
protected int parseSendCount(AgentCTwoVO agentVO) {
try {
return (agentVO.getSendCnt() != null && !agentVO.getSendCnt().isEmpty()) ? Integer.parseInt(agentVO.getSendCnt()) : 0;
return StringUtils.isNotEmpty(agentVO.getSendCnt()) ? Integer.parseInt(agentVO.getSendCnt()) : 0;
} catch (NumberFormatException e) {
return 0;
}
}
@Override
protected AgentCTwoVO createCopy(AgentCTwoVO originalVO, int index) {
protected AgentCTwoVO createCopy(AgentCTwoVO originalVO, int index, int sendCnt) {
if (!originalVO.getMessage().startsWith("ITN")) {
return originalVO;
}
// if (!originalVO.getMessage().startsWith("ITN")) {
// return originalVO;
// }
AgentCTwoVO paramVO = new AgentCTwoVO();
String msgType = originalVO.getMsgType();
paramVO.setMsgType(msgType);
paramVO.setSendStatus(originalVO.getSendStatus());
paramVO.setRecvPhone(modifyPhoneNumber(originalVO.getRecvPhone(), index));
paramVO.setSendPhone(modifyPhoneNumber(originalVO.getSendPhone(), index));
if(sendCnt < 2){
paramVO.setRecvPhone(originalVO.getRecvPhone());
}else{
paramVO.setRecvPhone(modifyPhoneNumber(originalVO.getRecvPhone(), index));
}
// paramVO.setSendPhone(modifyPhoneNumber(originalVO.getSendPhone(), index));
paramVO.setSendPhone(originalVO.getSendPhone());
paramVO.setFileName01(originalVO.getFileName01());
paramVO.setFileName02(originalVO.getFileName02());
@ -96,17 +103,18 @@ public class AgentCTwoServiceImpl extends AbstractAgentService<AgentCTwoVO, Agen
private String modifyPhoneNumber(String phone, int index) {
// 휴대폰 번호는 010-XXXX-YYYY 형식으로 가정
String prefix = phone.substring(0, 4); // "010-" 부분
String middle = phone.substring(4, 8); // "XXXX" 부분
String suffix = phone.substring(8); // "YYYY" 부분
// 중간 부분 숫자 수정
int middleNumber = Integer.parseInt(middle);
middleNumber = (middleNumber + index) % 10000; // 0000~9999 사이의 값으로 제한
middle = String.format("%04d", middleNumber); // 자리 숫자로 포맷
return prefix + middle + suffix;
// 인덱스를 번호 리스트 길이에 맞게 순환시키기 위해 모듈러 연산 사용
int adjustedIndex = index % PHONE_NUMBER_LIST.size();
return PHONE_NUMBER_LIST.get(adjustedIndex);
}
// 번호 목록을 리스트로 저장
private static final List<String> PHONE_NUMBER_LIST = Arrays.asList(
"01057559725", "01093414986", "01041101024",
"01057058729", "01030266269", "01063170383",
"01066137278", "01023221941", "01087872615",
"01083584250", "01071101861", "01073859908",
"01034910882", "01051842895", "01094597958"
);
}

View File

@ -1,11 +1,10 @@
package com.itn.admin.agent.client.two.web;
import com.itn.admin.agent.client.one.mapper.domain.AgentCOneVO;
import com.itn.admin.agent.client.three.mapper.domain.AgentCThreeVO;
import com.itn.admin.agent.client.two.mapper.domain.AgentCTwoVO;
import com.itn.admin.agent.client.two.service.AgentCTwoService;
import com.itn.admin.cmn.msg.RestResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.StringUtils;
@ -17,11 +16,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
@RestController
public class AgentCTwoRestController {
@ -30,6 +25,8 @@ public class AgentCTwoRestController {
private final String UPLOAD_DIR = "/home/mjon_client_agent_2/mmsfile";
@Value("${agent.file.dir.path}")
private String AGENT_FILE_PATH;
@Autowired
public void setAgentService(AgentCTwoService agentCTwoService) {
@ -48,9 +45,8 @@ public class AgentCTwoRestController {
* client db에 insert 됐는지 확인 count
* */
@PostMapping("/agent/two/findByInsertCnt")
public ResponseEntity<RestResponse> findByInsertCnt(@RequestParam String message) throws Exception {
AgentCTwoVO agentCTwoVO = new AgentCTwoVO();
agentCTwoVO.setMessage(message);
public ResponseEntity<RestResponse> findByInsertCnt(@RequestBody AgentCTwoVO agentCTwoVO) throws Exception {
System.out.println("message : "+ agentCTwoVO.getMessage());
return ResponseEntity.ok().body(agentCTwoService.findByInsertCnt(agentCTwoVO));
}
@ -114,17 +110,35 @@ public class AgentCTwoRestController {
}
private String uploadSingleFile(MultipartFile file) throws IOException {
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
Path uploadPath = Paths.get(UPLOAD_DIR);
// 업로드된 파일의 이름을 가져옵니다.
String originalFileName = StringUtils.cleanPath(file.getOriginalFilename());
// 파일의 확장자를 추출합니다. 파일 이름에서 마지막 "." 이후 부분을 확장자로 간주합니다.
String fileExtension = "";
int dotIndex = originalFileName.lastIndexOf(".");
if (dotIndex > 0) {
fileExtension = originalFileName.substring(dotIndex);
}
// 고유한 파일명을 생성합니다.
String uniqueFileName = UUID.randomUUID().toString() + fileExtension;
// 파일이 업로드될 경로를 설정합니다.
Path uploadPath = Paths.get(AGENT_FILE_PATH);
// 해당 경로가 존재하지 않으면 디렉터리를 생성합니다.
if (!Files.exists(uploadPath)) {
Files.createDirectories(uploadPath);
}
Path filePath = uploadPath.resolve(fileName);
// 파일을 저장할 최종 경로를 생성합니다.
Path filePath = uploadPath.resolve(uniqueFileName);
// 파일을 업로드 경로에 복사합니다. 이미 파일이 존재하면 대체합니다.
Files.copy(file.getInputStream(), filePath, StandardCopyOption.REPLACE_EXISTING);
return fileName;
// 업로드된 고유한 파일명을 반환합니다.
return uniqueFileName;
}

View File

@ -0,0 +1,28 @@
package com.itn.admin.commute.mapper.domain;
import lombok.*;
import java.io.Serializable;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
@ToString
public class ItnCommuteGroupVO implements Serializable {
private static final long serialVersionUID = 1L;
private Integer commuteGroupId; // 그룹 아이디
private String workDt; // 근무 날짜
private String approver; // 승인자
private String approverDt; // 승인 일지
private String frstRegisterId; // 최초 등록자 ID
private String frstRegistPnttm; // 최초 등록 일자
private String lastUpdusrId; // 최종 수정자 ID
private String lastUpdtPnttm; // 최종 수정 일자
}

View File

@ -0,0 +1,31 @@
package com.itn.admin.commute.mapper.domain;
import lombok.*;
import java.io.Serializable;
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
@ToString
public class ItnCommuteVO implements Serializable {
private static final long serialVersionUID = 1L;
private String commuteId; // 아이디
private String name; // 이름
private String category; // 구분
private String workDt; // 근무일자
private String startTime; // 출근시간
private String startRslt; // 출근결과
private String endTime; // 퇴근시간
private String endRslt; // 퇴근결과
private String transferDt; // 이관일시
private String approver; // 승인자
private String approverDt; // 승인일시
}

View File

@ -7,8 +7,8 @@ import java.util.stream.Stream;
public enum UserEnum {
user1("&@~PYfUBsF+m99kduT53j1Stw==","조용준", "본부장")
,user2("&@~C33DuWpcSL7Krvh2zAByUQ==","박진순", "")
,user3("&@~9+BQUtRi1cuWOaIqeCYdAA==","우영두", "")
,user2("&@~C33DuWpcSL7Krvh2zAByUQ==","박진순", "")
,user3("&@~9+BQUtRi1cuWOaIqeCYdAA==","우영두", "")
,user4("&@~peUfyxpLvs6RN9X4waktzQ==","원영현", "과장")
,user5("&@~tBRefZ81JCbrXNyRkjZNGQ==","이호영", "대리")
,user6("&@~X0eEqUF71/pD/Z0KPKysrA==","이지우", "대리")
@ -19,7 +19,7 @@ public enum UserEnum {
,user11("&@~E8RB3p27IfRVEhNefMu2Vw==","김보미", "대리")
,user12("&@~47amAycYJ4ZT8BZDi6a2sA==","이설희", "주임")
,user13("&@~KPBL+GIy7i2agV7V57MZWg==","정다은", "대리")
,user15("&@~S6vaRrMJmeRjp0T8z+/ybg==","강민경", "")
,user15("&@~S6vaRrMJmeRjp0T8z+/ybg==","강민경", "")
,user16("&@~7mpJXFU+euFUNEdHmHLQVQ==","정수빈", "대리")
,user17("&@~+BL2FKvmIQc/jIyHvz0jew==","박은지", "주임")

View File

@ -9,4 +9,6 @@ public interface CommuteService {
Map<String, Object> getList(CommuteVO commuteVO);
Map<String, Object> transfer(CommuteVO commuteVO);
}

View File

@ -2,8 +2,10 @@ package com.itn.admin.commute.service.impl;
import com.itn.admin.commute.mapper.CommuteMapper;
import com.itn.admin.commute.mapper.domain.CommuteVO;
import com.itn.admin.commute.mapper.domain.ItnCommuteGroupVO;
import com.itn.admin.commute.mapper.domain.UserEnum;
import com.itn.admin.commute.service.CommuteService;
import com.itn.admin.itn.commute.mapper.ItnCommuteMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
@ -27,11 +29,64 @@ public class CommuteServiceImpl implements CommuteService {
@Autowired
CommuteMapper commuteMapper;
@Autowired
ItnCommuteMapper itnCommuteMapper;
private static final int PAGE_SIZE = 5;
public Map<String, Object> getList(CommuteVO commuteVO) {
List<CommuteVO> commuteList = makeList(commuteVO);
// controller에 return
Map<String, Object> map = new HashMap<String, Object>();
map.put("resultList", commuteList);
map.put("commuteVO", commuteVO);
return map;
}
@Override
public Map<String, Object> transfer(CommuteVO commuteVO) {
List<CommuteVO> commuteList = makeList(commuteVO);
String startDate = commuteList.get(0).getStartDate();
Boolean startDateYN = false;
for (CommuteVO tt : commuteList){
if(StringUtils.isNotEmpty(tt.getStartDate())){
startDateYN = true;
}
}
if(!startDateYN){
}
String wordDt = startDate.split(" ")[0];
Integer groupId = itnCommuteMapper.findByCommuteGroupIdFromItnCommuteWhereWordDt(wordDt);
// groupId가 없으면 groupId insert
if(groupId == null) {
ItnCommuteGroupVO itnGroupVO = new ItnCommuteGroupVO();
itnCommuteMapper.insertCommuteGroup(itnGroupVO);
groupId = itnGroupVO.getCommuteGroupId();
}
// controller에 return
Map<String, Object> map = new HashMap<String, Object>();
map.put("resultList", commuteList);
map.put("commuteVO", commuteVO);
return map;
}
public List<CommuteVO> makeList(CommuteVO commuteVO){
if(StringUtils.isNotEmpty(commuteVO.getSearchYear())){
@ -69,7 +124,10 @@ public class CommuteServiceImpl implements CommuteService {
commuteVO.setEndDate(commuteVO.getSearchYear()+"-"+commuteVO.getSearchMonth()+"-"+commuteVO.getSearchDay()+" 23:59:59");
// 테이블명 생성
String tableNmM = commuteVO.getSearchMonth().length() <2 ? "0"+commuteVO.getSearchMonth() : commuteVO.getSearchMonth();
String tableNmM = commuteVO.getSearchMonth().length() <2
? "0"+commuteVO.getSearchMonth()
: commuteVO.getSearchMonth();
commuteVO.setTableNm("t_lg"+commuteVO.getSearchYear()+tableNmM);
List<CommuteVO> commuteList = new ArrayList<>();
@ -104,9 +162,9 @@ public class CommuteServiceImpl implements CommuteService {
});
commuteList.forEach(t-> {
t.setFirstActivityTime(t.getFirstActivityTime().split(" ")[1]);
t.setLastActivityTime(t.getLastActivityTime().split(" ")[1]);
});
t.setFirstActivityTime(t.getFirstActivityTime().split(" ")[1]);
t.setLastActivityTime(t.getLastActivityTime().split(" ")[1]);
});
// 출근안한사람 체크하기
for (UserEnum user : UserEnum.values()) {
@ -133,16 +191,10 @@ public class CommuteServiceImpl implements CommuteService {
commuteList.forEach(commute -> System.out.println(commute.toString()));
commuteList.removeIf(t -> "유인식".equals(t.getUsrid())
|| "itn6".equals(t.getUsrid())
|| "itn6".equals(t.getUsrid())
);
// controller에 return
Map<String, Object> map = new HashMap<String, Object>();
map.put("resultList", commuteList);
map.put("commuteVO", commuteVO);
return map;
return commuteList;
}
public static String getRandomTime(String start, String end) {

View File

@ -1,6 +1,7 @@
package com.itn.admin.commute.web;
import com.itn.admin.commute.mapper.domain.CommuteVO;
import com.itn.admin.commute.mapper.domain.ItnCommuteVO;
import com.itn.admin.commute.service.CommuteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@ -29,23 +30,18 @@ public class CommuteController {
model.addAttribute("list", resultMap.get("resultList"));
model.addAttribute("commuteVO", resultMap.get("commuteVO"));
return "commute/list";
return "commute/list_backup";
}
// @GetMapping(value = "/{pageNumber}")
// public String list(@ModelAttribute CommuteVO commuteVO, Model model) {
// Page<CommuteVO> page = commuteService.getList(commuteVO);
@GetMapping(value = "1")
public String list_test(@ModelAttribute("commuteVO") ItnCommuteVO itnCommuteVO, Model model) {
// Map<String, Object> resultMap = commuteService.getList(itnCommuteVO);
//
// int current = page.getNumber() + 1;
// int begin = Math.max(1, current - 5);
// int end = Math.min(begin + 10, page.getTotalPages());
//
// model.addAttribute("list", page);
// model.addAttribute("beginIndex", begin);
// model.addAttribute("endIndex", end);
// model.addAttribute("currentIndex", current);
//
// return "customers/list";
//
// }
// model.addAttribute("list", resultMap.get("resultList"));
// model.addAttribute("commuteVO", resultMap.get("commuteVO"));
return "commute/list";
}
}

View File

@ -24,32 +24,9 @@ public class CommuteRestController {
this.commuteService = commuteService;
}
@GetMapping(value = "/api/commute/list")
@GetMapping(value = "/api/commute/transfer")
public ResponseEntity<RestResponse> list(@ModelAttribute("commuteVO") CommuteVO commuteVO, Model model) {
Map<String, Object> resultMap = commuteService.getList(commuteVO);
// model.addAttribute("list", resultMap.get("resultList"));
// model.addAttribute("commuteVO", resultMap.get("commuteVO"));
Map<String, Object> resultMap = commuteService.transfer(commuteVO);
return ResponseEntity.ok().body(new RestResponse(HttpStatus.OK,"성공적으로 조회했습니다.",resultMap));
}
// @GetMapping(value = "/{pageNumber}")
// public String list(@ModelAttribute CommuteVO commuteVO, Model model) {
// Page<CommuteVO> page = commuteService.getList(commuteVO);
//
// int current = page.getNumber() + 1;
// int begin = Math.max(1, current - 5);
// int end = Math.min(begin + 10, page.getTotalPages());
//
// model.addAttribute("list", page);
// model.addAttribute("beginIndex", begin);
// model.addAttribute("endIndex", end);
// model.addAttribute("currentIndex", current);
//
// return "customers/list";
//
// }
}

View File

@ -1,7 +1,10 @@
package com.itn.admin.itn.commute.mapper;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteVO;
import com.itn.admin.commute.mapper.domain.ItnCommuteGroupVO;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Options;
import java.util.List;
@ -19,5 +22,11 @@ import java.util.List;
@Mapper
public interface ItnCommuteMapper {
List<ItnCommuteVO> findAll(ItnCommuteVO itnCommuteVO);
List<ItnCommuteBackVO> findAll(ItnCommuteBackVO itnCommuteBackVO);
Integer findByCommuteGroupIdFromItnCommuteWhereWordDt(String wordDt);
@Insert("INSERT INTO itn_commute_group (work_dt) VALUES (NOW())")
@Options(useGeneratedKeys = true, keyProperty = "commuteGroupId")
void insertCommuteGroup(ItnCommuteGroupVO itnGroupVO);
}

View File

@ -10,7 +10,7 @@ import java.io.Serializable;
@Getter
@Setter
@ToString
public class ItnCommuteVO implements Serializable {
public class ItnCommuteBackVO implements Serializable {
private static final long serialVersionUID = 1L;

View File

@ -1,6 +1,6 @@
package com.itn.admin.itn.commute.service;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteVO;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO;
import java.util.Map;
@ -8,5 +8,5 @@ import java.util.Map;
public interface ItnCommuteService {
Map<String, Object> getList(ItnCommuteVO itnCommuteVO);
Map<String, Object> getList(ItnCommuteBackVO itnCommuteBackVO);
}

View File

@ -1,7 +1,7 @@
package com.itn.admin.itn.commute.service.impl;
import com.itn.admin.itn.commute.mapper.ItnCommuteMapper;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteVO;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO;
import com.itn.admin.itn.commute.service.ItnCommuteService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
@ -26,17 +26,17 @@ public class ItnCommuteServiceImpl implements ItnCommuteService {
private static final int PAGE_SIZE = 5;
public Map<String, Object> getList(ItnCommuteVO itnCommuteVO) {
public Map<String, Object> getList(ItnCommuteBackVO itnCommuteBackVO) {
Random random = new Random(); // Random 객체 생성
// controller에 return
Map<String, Object> map = new HashMap<String, Object>();
List<ItnCommuteVO> resultList = itnCommuteMapper.findAll(itnCommuteVO);
List<ItnCommuteBackVO> resultList = itnCommuteMapper.findAll(itnCommuteBackVO);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss"); // 시간 형식 패턴
for (ItnCommuteVO result : resultList) {
for (ItnCommuteBackVO result : resultList) {
// 출근 시간에 랜덤 추가
if(StringUtils.isEmpty(result.getCommuteStartTime()))
continue;

View File

@ -1,12 +1,11 @@
package com.itn.admin.itn.commute.web;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteVO;
import com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO;
import com.itn.admin.itn.commute.service.ItnCommuteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
@ -34,16 +33,16 @@ public class ItnCommuteController {
}
// CommuteVO 생성
ItnCommuteVO itnCommuteVO = ItnCommuteVO.builder()
ItnCommuteBackVO itnCommuteBackVO = ItnCommuteBackVO.builder()
.startDate(startDate)
.endDate(endDate)
.build();
Map<String, Object> resultMap = commuteService.getList(itnCommuteVO);
Map<String, Object> resultMap = commuteService.getList(itnCommuteBackVO);
model.addAttribute("list", resultMap.get("resultList"));
model.addAttribute("commuteVO", itnCommuteVO);
model.addAttribute("commuteVO", itnCommuteBackVO);
model.addAttribute("startDate", startDate);
model.addAttribute("endDate", endDate);

View File

@ -0,0 +1 @@
agent.file.dir.path=X:\\agent_file

View File

@ -0,0 +1 @@
agent.file.dir.path=/home/docker/tomcat_8081_to_8089_2022_0712/kcc_adr_volume/agent_file

View File

@ -9,7 +9,7 @@ mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
server.servlet.session.timeout=30m
server.servlet.session.timeout=120m
#sql \ucd9c\ub825 log \uc124\uc815
logging.level.jdbc.sqlonly=info
@ -83,4 +83,7 @@ spring.mjagent.server.datasource.hikari.maximum-pool-size=4
logging.config=classpath:logback-spring.xml
logging.config=classpath:logback-spring.xml
log.config.path=/data/tomcat/tomcat_api_9100_2023_0711/logs
log.config.filename=mjonApi_log
logging.level.root=INFO

View File

@ -22,18 +22,22 @@
<configuration scan="true" scanPeriod="30 seconds">
<!--springProfile 태그를 사용하면 logback 설정파일에서 복수개의 프로파일을 설정할 수 있다.-->
<springProfile name="dev">
<property resource="logback-dev.properties"/>
</springProfile>
<springProfile name="prod">
<property resource="logback-prod.properties"/>
</springProfile>
<!-- <springProfile name="dev">-->
<!-- <property resource="logback-dev.properties"/>-->
<!-- </springProfile>-->
<!-- <springProfile name="prod">-->
<!-- <property resource="logback-prod.properties"/>-->
<!-- </springProfile>-->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
<property name="LOG_PATTERN" value="%clr(%d{yyMMdd HH:mm:ss}){green} %clr([%-5level]){cyan} [%thread] %clr([%logger{1}:%line]){magenta} - %msg%n"/>
<!-- <property name="LOG_PATTERN" value="%clr(%d{yyMMdd HH:mm:ss}){green} %clr([%-5level]){cyan} [%thread] %clr([%logger{1}:%line]){magenta} - %msg%n"/>-->
<property name="LOG_PATTERN"
value="[%d{yyyy-MM-dd HH:mm:ss}:%-4relative] %green([%thread]) %highlight(%-5level) %boldWhite([%C.%M:%yellow(%L)]) - %msg%n%ex"/>
<property name="LOG_DIR" value="${log.config.path}"/>
<property name="ERR_LOG_FILE_NAME" value="err_log"/><!-- err log file name -->

View File

@ -1,9 +0,0 @@
#???? ??
log.config.path=/data/tomcat/tomcat_api_9100_2023_0711/logs
#???? ??
log.config.filename=mjonApi_log
logging.level.root=INFO
#logging.level.root=DEBUG

View File

@ -5,7 +5,7 @@
<mapper namespace="com.itn.admin.itn.commute.mapper.ItnCommuteMapper">
<select id="findAll" parameterType="itnCommuteVO" resultType="itnCommuteVO">
<select id="findAll" parameterType="itnCommuteBackVO" resultType="itnCommuteBackVO">
SELECT
commute_id AS commuteId,
@ -15,7 +15,7 @@
commute_start_time AS commuteStartTime,
commute_end_time AS commuteEndTime
FROM
itn_commute
itn_commute_back
WHERE
1=1
<if test="startDate != null and startDate != ''">
@ -24,5 +24,17 @@
</select>
<select id="findByCommuteGroupIdFromItnCommuteWhereWordDt" parameterType="String" resultType="Integer">
SELECT
commute_group_id
FROM
itn_commute
WHERE
word_dt = #{wordDt}
limit 1
</select>
</mapper>

View File

@ -15,6 +15,7 @@
<!-- 별칭 -->
<typeAliases>
<typeAlias type="com.itn.admin.commute.mapper.domain.CommuteVO" alias="commuteVO"/>
<typeAlias type="com.itn.admin.commute.mapper.domain.ItnCommuteVO" alias="itnCommuteVO"/>
<typeAlias type="com.itn.admin.itn.dict.mapper.domain.DictionaryVO" alias="dictionaryVO"/>
<typeAlias type="com.itn.admin.itn.mjon.spam.mapper.domain.SpamVO" alias="spamVO"/>
<typeAlias type="com.itn.admin.itn.user.mapper.domain.UserVO" alias="userVO"/>
@ -25,7 +26,7 @@
<typeAlias type="com.itn.admin.itn.code.mapper.domain.CodeVO" alias="codeVO"/>
<typeAlias type="com.itn.admin.itn.code.mapper.domain.CodeDetailVO" alias="codeDetailVO"/>
<typeAlias type="com.itn.admin.itn.commute.mapper.domain.ItnCommuteVO" alias="itnCommuteVO"/>
<typeAlias type="com.itn.admin.itn.commute.mapper.domain.ItnCommuteBackVO" alias="itnCommuteBackVO"/>
</typeAliases>
<!-- <environments default="development">-->

View File

@ -49,8 +49,8 @@ $(function () {
var $subject = $(tagId + ' .subject');
// 기본 전화번호 설정
$recvPhone.val('01012345678');
$sendPhone.val('01043219876');
$recvPhone.val('01083584250');
$sendPhone.val('01083584250');
// 메시지 타입에 따른 메시지 설정
var msgType = $msgType.val();

View File

@ -675,14 +675,14 @@
// 파일명만 formData에 추가
// 파일명 formData에 추가
if (response.data.fileName01) {
formData.append("fileName01", response.data.fileName01);
if (response.data.fileNames.fileName01) {
formData.append("fileName01", response.data.fileNames.fileName01);
}
if (response.data.fileName02) {
formData.append("fileName02", response.data.fileName02);
if (response.data.fileNames.fileName02) {
formData.append("fileName02", response.data.fileNames.fileName02);
}
if (response.data.fileName03) {
formData.append("fileName03", response.data.fileName03);
if (response.data.fileNames.fileName03) {
formData.append("fileName03", response.data.fileNames.fileName03);
}
var jsonObject = {};
@ -691,10 +691,10 @@
jsonObject[key] = value;
}
});
if(jsonObject['recvPhone'] === ""){
alert('정보를 입력하거나 예시입력을 클릭해주세요.')
return false;
}
// if(jsonObject['recvPhone'] === ""){
// alert('정보를 입력하거나 예시입력을 클릭해주세요.')
// return false;
// }
console.log('one jsonObject send : ', jsonObject);
@ -761,7 +761,6 @@
fileUploadForm.append("fileName02", formData.get("fileName02"));
fileUploadForm.append("fileName03", formData.get("fileName03"));
$.ajax({
type: "POST",
url: "/agent/two/uploadFiles",
@ -792,10 +791,10 @@
jsonObject[key] = value;
}
});
if(jsonObject['recvPhone'] === ""){
alert('정보를 입력하거나 예시입력을 클릭해주세요.')
return false;
}
// if(jsonObject['recvPhone'] === ""){
// alert('정보를 입력하거나 예시입력을 클릭해주세요.')
// return false;
// }

View File

@ -5,6 +5,7 @@
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="layout">
<head>
<!-- layout.html 에 들어간 head 부분을 제외하고 개별 파일에만 적용되는 head 부분 추가 -->
<title>직원 출퇴근 관리</title>
@ -16,6 +17,65 @@
<script>
</script>
<style>
.attendance-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed; /* 고정된 너비를 위한 설정 */
}
.attendance-table th, .attendance-table td {
border: 1px solid #dee2e6;
padding: 8px;
text-align: center;
vertical-align: middle;
}
.attendance-table thead th {
background-color: #f4f6f9;
font-weight: bold;
}
.attendance-table tbody tr:nth-child(even) {
background-color: #f9f9f9;
}
.attendance-table tbody tr:hover {
background-color: #e9ecef;
}
.attendance-table th {
position: sticky;
top: 0;
z-index: 1;
}
/* 순번과 이름 컬럼을 강조 */
.attendance-table tbody td:nth-child(1), /* 순번 열 */
.attendance-table tbody td:nth-child(2) { /* 이름 열 */
font-weight: bold;
background-color: #f1f1f1; /* 약간 연한 배경색 */
}
/* 열 너비 조정 */
.attendance-table th:nth-child(1),
.attendance-table td:nth-child(1) {
width: 5%;
}
.attendance-table th:nth-child(2),
.attendance-table td:nth-child(2) {
width: 10%;
}
/* 이름과 퇴근시간(전일) 사이 경계선 굵게 설정 */
.attendance-table th:nth-child(2),
.attendance-table td:nth-child(2) {
border-right: 2px solid #dee2e6; /* 이름 열의 오른쪽 테두리 굵게 */
}
</style>
</head>
<body layout:fragment="body">
@ -56,83 +116,58 @@
<div class="card">
<div class="card-header">
<h3 class="card-title">목록</h3>
<h3 class="card-title">출퇴근 관리</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
<form th:id="searchForm" th:name="searchForm" th:action="@{/commute/list}" >
<div class="row">
<div class="col-sm-6" style="max-width: 10%;">
<!-- select -->
<div class="form-group">
<label></label>
<select th:name="searchYear" th:id="searchYear" class="form-control">
<option th:each="year : ${#numbers.sequence(2023, 2022 + 40)}"
th:value="${year}"
th:text="${year}"
th:selected="${year.toString() == commuteVO.searchYear}"></option>
</select>
</div>
</div>
<div class="col-sm-6" style="max-width: 10%;">
<div class="form-group">
<label></label>
<select th:name="searchMonth" th:id="searchMonth" class="form-control">
<option th:each="month : ${#numbers.sequence(1, 12)}"
th:value="${month}"
th:text="${month}"
th:selected="${month.toString() == commuteVO.searchMonth}"></option>
</select>
</div>
</div>
<div class="col-sm-6" style="max-width: 10%;">
<div class="form-group">
<label></label>
<select th:name="searchDay" th:id="searchDay" class="form-control">
<option th:each="day : ${#numbers.sequence(1, 31)}"
th:value="${day}"
th:text="${day}"
th:selected="${day.toString() == commuteVO.searchDay}"></option>
</select>
</div>
</div>
</div>
</form>
<table id="commuteTb" class="table table-bordered table-striped">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>직위</th>
<th>출근</th>
<th>비고</th>
<th>퇴근</th>
<th>비고</th>
</tr>
</thead>
<tbody>
<tr th:each="row, stat : ${list}">
<td th:text="${commuteVO.searchYear + '-' + commuteVO.searchMonth + '-' + commuteVO.searchDay}"></td>
<td th:text="${row.usrid}"></td>
<td th:text="${row.pstn}"></td>
<td th:text="${row.firstActivityTime}"></td>
<td th:text="${row.firstActivityTimeMemo}"></td>
<td th:text="${row.lastActivityTime}"></td>
<td th:text="${row.LastActivityTimeMemo}"></td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>출근</th>
<th>직위</th>
<th>비고</th>
<th>퇴근</th>
<th>비고</th>
</tr>
</tfoot>
</table>
<table class="attendance-table">
<thead>
<tr>
<th>순번</th>
<th>이름</th>
<th>퇴근시간(전일)</th>
<th>결과</th>
<th>출근(당일)</th>
<th>결과</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>박성경</td>
<td>2012.11.02 04:38:30</td>
<td>미인식</td>
<td>2012.11.02 04:38:30</td>
<td>미인식</td>
</tr>
<tr>
<td>2</td>
<td>박성경</td>
<td>2012.11.02 06:47:02</td>
<td></td>
<td>2012.11.02 07:01:10</td>
<td></td>
</tr>
<tr>
<td>3</td>
<td>박성경</td>
<td>2012.11.02 07:01:10</td>
<td></td>
<td>2012.11.02 07:01:10</td>
<td>연차(오전)</td>
</tr>
<tr>
<td>4</td>
<td>박성경</td>
<td>2012.11.02 07:03:21</td>
<td></td>
<td>2012.11.02 07:05:39</td>
<td></td>
</tr>
<!-- 나머지 행들도 동일한 형식으로 추가 -->
</tbody>
</table>
</div>
<!-- /.card-body -->
</div>
@ -163,37 +198,10 @@
</div>
<!-- ./wrapper -->
<!-- DataTables & Plugins -->
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
<script>
$(function () {
$("#commuteTb").DataTable({
"responsive": true
, "lengthChange": false
, "autoWidth": false
, "pageLength": 20
, "buttons": ["copy", { extend: 'csv', charset: 'UTF-8', bom: true }
, "excel", "pdf", "print", "colvis"]
}).buttons().container().appendTo('#commuteTb_wrapper .col-md-6:eq(0)');
});
$( document ).ready( function() {
$('#searchDay, #searchMonth, #searchYear').on('change', function (){
$('#searchForm').submit();
});
} );
</script>
</body>

View File

@ -0,0 +1,203 @@
<!DOCTYPE html>
<!-- 관련 Namespace 선언 및 layout:decorate 추가 -->
<html lang="en"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="layout">
<head>
<!-- layout.html 에 들어간 head 부분을 제외하고 개별 파일에만 적용되는 head 부분 추가 -->
<title>직원 출퇴근 관리</title>
<!-- 필요하다면 개별 파일에 사용될 css/js 선언 -->
<link rel="stylesheet" th:href="@{/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css}">
<link rel="stylesheet" th:href="@{/plugins/datatables-responsive/css/responsive.bootstrap4.min.css}">
<link rel="stylesheet" th:href="@{/plugins/datatables-buttons/css/buttons.bootstrap4.min.css}">
<script>
</script>
</head>
<body layout:fragment="body">
<div class="wrapper">
<div th:replace="~{fragments/top_nav :: topFragment}"/>
<!-- Main Sidebar Container -->
<aside class="main-sidebar sidebar-dark-primary elevation-4"
th:insert="~{fragments/mainsidebar :: sidebarFragment}">
</aside>
<!-- Content Wrapper. Contains page content -->
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<div class="content-header">
<div class="container-fluid">
<div class="row mb-2">
<div class="col-sm-6">
<h1 class="m-0">출퇴근 관리</h1>
</div><!-- /.col -->
<div class="col-sm-6">
<ol class="breadcrumb float-sm-right">
<li class="breadcrumb-item"><a href="#">Home</a></li>
<li class="breadcrumb-item active">출퇴근 관리</li>
</ol>
</div><!-- /.col -->
</div><!-- /.row -->
</div><!-- /.container-fluid -->
</div>
<!-- /.content-header -->
<!-- Main content -->
<section class="content">
<div class="container-fluid">
<div class="row">
<div class="col-12">
<!-- /.card -->
<div class="card">
<div class="card-header">
<h3 class="card-title">목록</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
<form th:id="searchForm" th:name="searchForm" th:action="@{/commute/list}" >
<div class="row">
<div class="col-sm-6" style="max-width: 10%;">
<!-- select -->
<div class="form-group">
<label></label>
<select th:name="searchYear" th:id="searchYear" class="form-control">
<option th:each="year : ${#numbers.sequence(2023, 2022 + 40)}"
th:value="${year}"
th:text="${year}"
th:selected="${year.toString() == commuteVO.searchYear}"></option>
</select>
</div>
</div>
<div class="col-sm-6" style="max-width: 10%;">
<div class="form-group">
<label></label>
<select th:name="searchMonth" th:id="searchMonth" class="form-control">
<option th:each="month : ${#numbers.sequence(1, 12)}"
th:value="${month}"
th:text="${month}"
th:selected="${month.toString() == commuteVO.searchMonth}"></option>
</select>
</div>
</div>
<div class="col-sm-6" style="max-width: 10%;">
<div class="form-group">
<label></label>
<select th:name="searchDay" th:id="searchDay" class="form-control">
<option th:each="day : ${#numbers.sequence(1, 31)}"
th:value="${day}"
th:text="${day}"
th:selected="${day.toString() == commuteVO.searchDay}"></option>
</select>
</div>
</div>
</div>
</form>
<table id="commuteTb" class="table table-bordered table-striped">
<thead>
<tr>
<th></th>
<th>Name</th>
<th>직위</th>
<th>출근</th>
<th>비고</th>
<th>퇴근</th>
<th>비고</th>
</tr>
</thead>
<tbody>
<tr th:each="row, stat : ${list}">
<td th:text="${commuteVO.searchYear + '-' + commuteVO.searchMonth + '-' + commuteVO.searchDay}"></td>
<td th:text="${row.usrid}"></td>
<td th:text="${row.pstn}"></td>
<td th:text="${row.firstActivityTime}"></td>
<td th:text="${row.firstActivityTimeMemo}"></td>
<td th:text="${row.lastActivityTime}"></td>
<td th:text="${row.LastActivityTimeMemo}"></td>
</tr>
</tbody>
<tfoot>
<tr>
<th></th>
<th>Name</th>
<th>출근</th>
<th>직위</th>
<th>비고</th>
<th>퇴근</th>
<th>비고</th>
</tr>
</tfoot>
</table>
</div>
<!-- /.card-body -->
</div>
<!-- /.card -->
</div>
<!-- /.col -->
</div>
<!-- /.row -->
</div>
<!-- /.container-fluid -->
</section>
<!-- /Main content -->
</div>
<!-- /.content-wrapper -->
<footer class="main-footer"
th:insert="~{fragments/footer :: footerFragment}">
</footer>
<!-- Control Sidebar -->
<aside class="control-sidebar control-sidebar-dark">
<!-- Control sidebar content goes here -->
</aside>
<!-- /.control-sidebar -->
</div>
<!-- ./wrapper -->
<!-- DataTables & Plugins -->
<script th:src="@{/plugins/datatables/jquery.dataTables.min.js}"></script>
<script th:src="@{/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js}"></script>
<script th:src="@{/plugins/datatables-responsive/js/dataTables.responsive.min.js}"></script>
<script th:src="@{/plugins/datatables-responsive/js/responsive.bootstrap4.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/dataTables.buttons.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.bootstrap4.min.js}"></script>
<script th:src="@{/plugins/jszip/jszip.min.js}"></script>
<script th:src="@{/plugins/pdfmake/pdfmake.min.js}"></script>
<script th:src="@{/plugins/pdfmake/vfs_fonts.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.html5.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.print.min.js}"></script>
<script th:src="@{/plugins/datatables-buttons/js/buttons.colVis.min.js}"></script>
<script>
$(function () {
$("#commuteTb").DataTable({
"responsive": true
, "lengthChange": false
, "autoWidth": false
, "pageLength": 20
, "buttons": ["copy", { extend: 'csv', charset: 'UTF-8', bom: true }
, "excel", "pdf", "print", "colvis"]
}).buttons().container().appendTo('#commuteTb_wrapper .col-md-6:eq(0)');
});
$( document ).ready( function() {
$('#searchDay, #searchMonth, #searchYear').on('change', function (){
$('#searchForm').submit();
});
} );
</script>
</body>
</html>